1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
# -*- coding: utf-8 -*-
module Plugin::Guide
module InteractiveMixin
def say(message)
self.next {
Plugin[:guide].timeline(:guide) <<
Mikutter::System::Message.new(description: message,
source: "guide",
created: Time.now)
}.extend(InteractiveMixin)
end
def prompt(message, choose = {Plugin[:change_account]._('次へ') => nil})
self.next {
promise = Deferred.new(true).extend(InteractiveMixin)
Plugin[:guide].timeline(:guide) <<
Mikutter::System::Message.new(description: message,
source: "guide",
created: Time.now,
confirm: choose,
confirm_callback: promise)
promise
}
end
def next(&block)
super(&block).extend(InteractiveMixin) end
def trap(&block)
super(&block).extend(InteractiveMixin) end
end
class Interactive < Deferred
include InteractiveMixin
def self.generate
Deferred.new.extend(InteractiveMixin)
end
end
class SubPartsGuide < Gdk::SubParts
Button = Struct.new(:layout, :value, :x, :y, :width, :height)
OutsideOffset = 48 # 最初のボタンの左端との隙間
ButtonLeft = 6 # ボタンの左端と文字の左側の距離
ButtonRight = 6 # ボタンの右端と文字の右側の距離
ButtonTop = 6 # わかるよね
ButtonBottom = 6 # わかるよね
ButtonMargin = 3 # ボタンとボタンの距離
register
def initialize(*args)
super
if message[:confirm]
sid = helper.ssc(:click){ |this, e, x, y|
ofsty = helper.mainpart_height
helper.subparts.each{ |part|
break if part == self
ofsty += part.height }
if ofsty <= y and (ofsty + height) >= y and 1 == e.button
button = generate_buttons.find{|b| b.x < x and x < (b.x+b.width) }
if button
helper.signal_handler_disconnect(sid)
message[:confirm] = nil
helper.reset_height
message[:confirm_callback].call(button.value) end end
false } end
end
def render(context)
if helper.visible? and message and message[:confirm]
context.save{
buttons = generate_buttons(context)
return if not buttons
buttons.each{ |button|
render_outline(context, button.x, button.y, *button.layout.size.map{|_|_/Pango::SCALE})
context.save{
context.translate(button.x + ButtonLeft, button.y + ButtonTop)
context.set_source_rgb(*(UserConfig[:mumble_basic_color] || [0,0,0]).map{ |c| c.to_f / 65536 })
context.show_pango_layout(button.layout) } } } end end
def height
buttons = generate_buttons
return 0 if not buttons
@height ||= (buttons.map{|b|b.layout.size[1]}.max / Pango::SCALE) + ButtonMargin*2 + ButtonTop + ButtonBottom end
private
def generate_buttons(context = Cairo::Context.dummy)
if not message[:confirm]
return nil end
ofst = OutsideOffset + ButtonMargin
message[:confirm].map{ |label, value|
layout = context.create_pango_layout
layout.font_description = helper.font_description(UserConfig[:mumble_basic_font])
layout.text = label
width = layout.size[0]/Pango::SCALE + ButtonLeft + ButtonRight
x = ofst
ofst += width + ButtonMargin
Button.new(layout, value,
x, 0,
width,
layout.size[1]/Pango::SCALE + ButtonTop + ButtonBottom) } end
def render_outline(context, x, y, width, height)
rect = [ButtonMargin + x,
ButtonMargin + y,
width - ButtonMargin*2 + ButtonLeft + ButtonRight,
height - ButtonMargin*2 + ButtonTop + ButtonBottom, 4]
context.save {
context.pseudo_blur(4) {
context.fill {
context.set_source_rgb(0.5, 0.5, 0.5)
context.rounded_rectangle(*rect)
}
}
context.fill {
context.set_source_rgb(1, 0.95, 0.95)
context.rounded_rectangle(*rect)
}
}
end
def message
helper.message end
end
end
|