colstrom-fidgit 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.rspec +2 -0
- data/CHANGELOG.md +31 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +20 -0
- data/README.md +154 -0
- data/Rakefile +38 -0
- data/config/default_schema.yml +216 -0
- data/examples/_all_examples.rb +9 -0
- data/examples/align_example.rb +56 -0
- data/examples/button_and_toggle_button_example.rb +38 -0
- data/examples/color_picker_example.rb +17 -0
- data/examples/color_well_example.rb +25 -0
- data/examples/combo_box_example.rb +24 -0
- data/examples/file_dialog_example.rb +42 -0
- data/examples/grid_packer_example.rb +29 -0
- data/examples/helpers/example_window.rb +17 -0
- data/examples/label_example.rb +23 -0
- data/examples/list_example.rb +23 -0
- data/examples/media/images/head_icon.png +0 -0
- data/examples/menu_pane_example.rb +27 -0
- data/examples/message_dialog_example.rb +65 -0
- data/examples/radio_button_example.rb +37 -0
- data/examples/readme_example.rb +32 -0
- data/examples/scroll_window_example.rb +49 -0
- data/examples/slider_example.rb +34 -0
- data/examples/splash_example.rb +42 -0
- data/examples/text_area_example.rb +33 -0
- data/fidgit.gemspec +35 -0
- data/lib/fidgit.rb +51 -0
- data/lib/fidgit/chingu_ext/window.rb +6 -0
- data/lib/fidgit/cursor.rb +38 -0
- data/lib/fidgit/elements/button.rb +113 -0
- data/lib/fidgit/elements/color_picker.rb +63 -0
- data/lib/fidgit/elements/color_well.rb +39 -0
- data/lib/fidgit/elements/combo_box.rb +115 -0
- data/lib/fidgit/elements/composite.rb +17 -0
- data/lib/fidgit/elements/container.rb +210 -0
- data/lib/fidgit/elements/element.rb +298 -0
- data/lib/fidgit/elements/file_browser.rb +152 -0
- data/lib/fidgit/elements/grid.rb +227 -0
- data/lib/fidgit/elements/group.rb +64 -0
- data/lib/fidgit/elements/horizontal.rb +12 -0
- data/lib/fidgit/elements/image_frame.rb +65 -0
- data/lib/fidgit/elements/label.rb +85 -0
- data/lib/fidgit/elements/list.rb +47 -0
- data/lib/fidgit/elements/main_packer.rb +25 -0
- data/lib/fidgit/elements/menu_pane.rb +163 -0
- data/lib/fidgit/elements/packer.rb +42 -0
- data/lib/fidgit/elements/radio_button.rb +86 -0
- data/lib/fidgit/elements/scroll_area.rb +68 -0
- data/lib/fidgit/elements/scroll_bar.rb +128 -0
- data/lib/fidgit/elements/scroll_window.rb +83 -0
- data/lib/fidgit/elements/slider.rb +125 -0
- data/lib/fidgit/elements/text_area.rb +494 -0
- data/lib/fidgit/elements/text_line.rb +92 -0
- data/lib/fidgit/elements/toggle_button.rb +67 -0
- data/lib/fidgit/elements/tool_tip.rb +35 -0
- data/lib/fidgit/elements/vertical.rb +12 -0
- data/lib/fidgit/event.rb +159 -0
- data/lib/fidgit/gosu_ext/color.rb +136 -0
- data/lib/fidgit/gosu_ext/gosu_module.rb +25 -0
- data/lib/fidgit/history.rb +91 -0
- data/lib/fidgit/redirector.rb +83 -0
- data/lib/fidgit/schema.rb +123 -0
- data/lib/fidgit/selection.rb +106 -0
- data/lib/fidgit/standard_ext/hash.rb +21 -0
- data/lib/fidgit/states/dialog_state.rb +52 -0
- data/lib/fidgit/states/file_dialog.rb +24 -0
- data/lib/fidgit/states/gui_state.rb +331 -0
- data/lib/fidgit/states/message_dialog.rb +61 -0
- data/lib/fidgit/version.rb +5 -0
- data/lib/fidgit/window.rb +19 -0
- data/media/images/arrow.png +0 -0
- data/media/images/combo_arrow.png +0 -0
- data/media/images/file_directory.png +0 -0
- data/media/images/file_file.png +0 -0
- data/media/images/pixel.png +0 -0
- data/spec/fidgit/elements/helpers/helper.rb +3 -0
- data/spec/fidgit/elements/helpers/tex_play_helper.rb +9 -0
- data/spec/fidgit/elements/image_frame_spec.rb +69 -0
- data/spec/fidgit/elements/label_spec.rb +37 -0
- data/spec/fidgit/event_spec.rb +210 -0
- data/spec/fidgit/gosu_ext/color_spec.rb +130 -0
- data/spec/fidgit/gosu_ext/helpers/helper.rb +3 -0
- data/spec/fidgit/helpers/helper.rb +4 -0
- data/spec/fidgit/history_spec.rb +153 -0
- data/spec/fidgit/redirector_spec.rb +78 -0
- data/spec/fidgit/schema_spec.rb +67 -0
- data/spec/fidgit/schema_test.yml +32 -0
- metadata +320 -0
@@ -0,0 +1,65 @@
|
|
1
|
+
module Fidgit
|
2
|
+
# A wrapper around a Gosu::Image to show it in the GUI.
|
3
|
+
class ImageFrame < Element
|
4
|
+
ENABLED_COLOR = Gosu::Color::WHITE
|
5
|
+
DISABLED_COLOR = Gosu::Color.rgb(150, 150, 150)
|
6
|
+
|
7
|
+
attr_reader :image, :factor_x, :factor_y
|
8
|
+
|
9
|
+
def thumbnail?; @thumbnail; end
|
10
|
+
|
11
|
+
# @param (see Element#initialize)
|
12
|
+
# @param [Gosu::Image] image Gosu image to display.
|
13
|
+
#
|
14
|
+
# @option (see Element#initialize)
|
15
|
+
# @option options [Boolean] :thumbnail (false) Is the image expanded to be square?
|
16
|
+
def initialize(image, options = {})
|
17
|
+
options = {
|
18
|
+
thumbnail: false,
|
19
|
+
factor: 1,
|
20
|
+
}.merge! options
|
21
|
+
|
22
|
+
@thumbnail = options[:thumbnail]
|
23
|
+
@factor_x = options[:factor_x] || options[:factor]
|
24
|
+
@factor_y = options[:factor_y] || options[:factor]
|
25
|
+
|
26
|
+
super(options)
|
27
|
+
|
28
|
+
self.image = image
|
29
|
+
end
|
30
|
+
|
31
|
+
def image=(image)
|
32
|
+
@image = image
|
33
|
+
|
34
|
+
recalc
|
35
|
+
|
36
|
+
image
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def draw_foreground
|
41
|
+
@image.draw(x + padding_left, y + padding_top, z, factor_x, factor_y, enabled? ? ENABLED_COLOR : DISABLED_COLOR) if @image
|
42
|
+
end
|
43
|
+
|
44
|
+
protected
|
45
|
+
def layout
|
46
|
+
if @image
|
47
|
+
if @thumbnail
|
48
|
+
size = [@image.width, @image.height].max
|
49
|
+
rect.width = size * @factor_x
|
50
|
+
rect.height = size * @factor_y
|
51
|
+
else
|
52
|
+
rect.width = @image.width * @factor_x
|
53
|
+
rect.height = @image.height * @factor_y
|
54
|
+
end
|
55
|
+
else
|
56
|
+
rect.width = rect.height = 0
|
57
|
+
end
|
58
|
+
|
59
|
+
rect.width += padding_left + padding_right
|
60
|
+
rect.height += padding_top + padding_bottom
|
61
|
+
|
62
|
+
nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Fidgit
|
4
|
+
class Label < Composite
|
5
|
+
ICON_POSITIONS = [:top, :bottom, :left, :right]
|
6
|
+
|
7
|
+
attr_reader :icon_position
|
8
|
+
|
9
|
+
attr_accessor :background_color, :border_color
|
10
|
+
|
11
|
+
def_delegators :@text, :text, :color, :font, :color=, :text=
|
12
|
+
|
13
|
+
def icon; @icon ? @icon.image : nil; end
|
14
|
+
|
15
|
+
def hit_element(x, y)
|
16
|
+
# The sub-elements should never get events.
|
17
|
+
hit?(x, y) ? self : nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def icon=(icon)
|
21
|
+
raise ArgumentError.new("Icon must be a Gosu::Image") unless icon.is_a? Gosu::Image or icon.nil?
|
22
|
+
|
23
|
+
@contents.remove(@icon) if @icon.image
|
24
|
+
@icon.image = icon
|
25
|
+
position = [:left, :top].include?(icon_position) ? 0 : 1
|
26
|
+
@contents.insert(position, @icon) if @icon.image
|
27
|
+
|
28
|
+
icon
|
29
|
+
end
|
30
|
+
|
31
|
+
# Set the position of the icon, respective to the text.
|
32
|
+
def icon_position=(position)
|
33
|
+
raise ArgumentError.new("icon_position must be one of #{ICON_POSITIONS}") unless ICON_POSITIONS.include? position
|
34
|
+
|
35
|
+
@icon_position = position
|
36
|
+
|
37
|
+
case @icon_position
|
38
|
+
when :top, :bottom
|
39
|
+
@contents.instance_variable_set :@type, :fixed_columns
|
40
|
+
@contents.instance_variable_set :@num_columns, 1
|
41
|
+
when :left, :right
|
42
|
+
@contents.instance_variable_set :@type, :fixed_rows
|
43
|
+
@contents.instance_variable_set :@num_rows, 1
|
44
|
+
end
|
45
|
+
|
46
|
+
self.icon = @icon.image if @icon.image # Force the icon into the correct position.
|
47
|
+
|
48
|
+
position
|
49
|
+
end
|
50
|
+
|
51
|
+
# @param (see Element#initialize)
|
52
|
+
# @param [String] text The string to display in the label.
|
53
|
+
#
|
54
|
+
# @option (see Element#initialize)
|
55
|
+
# @option options [Gosu::Image, nil] :icon (nil)
|
56
|
+
# @option options [:left, :right, :center] :justify (:left) Text justification.
|
57
|
+
def initialize(text, options = {})
|
58
|
+
options = {
|
59
|
+
color: default(:color),
|
60
|
+
justify: default(:justify),
|
61
|
+
background_color: default(:background_color),
|
62
|
+
border_color: default(:border_color),
|
63
|
+
icon_options: {},
|
64
|
+
font_name: default(:font_name),
|
65
|
+
font_height: default(:font_height),
|
66
|
+
icon_position: default(:icon_position),
|
67
|
+
}.merge! options
|
68
|
+
|
69
|
+
super(options)
|
70
|
+
|
71
|
+
# Bit of a fudge since font info is managed circularly here!
|
72
|
+
# By using a grid, we'll be able to turn it around easily (in theory).
|
73
|
+
@contents = grid num_rows: 1, padding: 0, spacing_h: spacing_h, spacing_v: spacing_v, width: options[:width], height: options[:height], z: z do |contents|
|
74
|
+
@text = TextLine.new(text, parent: contents, justify: options[:justify], color: options[:color], padding: 0, z: z,
|
75
|
+
font_name: options[:font_name], font_height: options[:font_height], align_h: :fill, align_v: :center)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Create an image frame, but don't show it unless there is an image in it.
|
79
|
+
@icon = ImageFrame.new(nil, options[:icon_options].merge(z: z, align: :center))
|
80
|
+
@icon.image = options[:icon]
|
81
|
+
|
82
|
+
self.icon_position = options[:icon_position]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Fidgit
|
4
|
+
class List < Composite
|
5
|
+
class Item < RadioButton
|
6
|
+
end
|
7
|
+
|
8
|
+
event :changed
|
9
|
+
|
10
|
+
def size; @items.size; end
|
11
|
+
def clear; @items.clear; end
|
12
|
+
|
13
|
+
def initialize(options = {})
|
14
|
+
options = {
|
15
|
+
background_color: default(:background_color),
|
16
|
+
border_color: default(:border_color),
|
17
|
+
}.merge! options
|
18
|
+
|
19
|
+
super options
|
20
|
+
|
21
|
+
group do
|
22
|
+
subscribe :changed do |sender, value|
|
23
|
+
publish :changed, value
|
24
|
+
end
|
25
|
+
|
26
|
+
@items = vertical spacing: 0
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# @param [String] text
|
31
|
+
# @option options [Gosu::Image] :icon
|
32
|
+
def item(text, value, options = {}, &block)
|
33
|
+
Item.new(text, value, { parent: @items }.merge!(options), &block)
|
34
|
+
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
def layout
|
38
|
+
super
|
39
|
+
if @items
|
40
|
+
max_width = @items.each.to_a.map {|c| c.width }.max || 0
|
41
|
+
@items.each {|c| c.rect.width = max_width }
|
42
|
+
end
|
43
|
+
|
44
|
+
nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative "vertical"
|
2
|
+
|
3
|
+
module Fidgit
|
4
|
+
# Main container that can contains a single "proper" packing element.
|
5
|
+
class MainPacker < Vertical
|
6
|
+
def initialize(options = {})
|
7
|
+
options = {
|
8
|
+
width: $window.width,
|
9
|
+
height: $window.height,
|
10
|
+
}.merge! options
|
11
|
+
|
12
|
+
super options
|
13
|
+
end
|
14
|
+
|
15
|
+
def width; $window.width; end
|
16
|
+
def height; $window.height; end
|
17
|
+
def width=(value); ; end
|
18
|
+
def height=(value); ; end
|
19
|
+
|
20
|
+
def add(element)
|
21
|
+
raise "MainPacker can only contain packing elements" unless element.is_a? Packer
|
22
|
+
super(element)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module Fidgit
|
4
|
+
class MenuPane < Composite
|
5
|
+
# An item within the menu.
|
6
|
+
class Item < Button
|
7
|
+
attr_reader :value, :shortcut_text
|
8
|
+
|
9
|
+
# @param (see Button#initialize)
|
10
|
+
#
|
11
|
+
# @option (see Button#initialize)
|
12
|
+
# @param [any] value Value if the user picks this item
|
13
|
+
# @option options [String] :shortcut_text ('')
|
14
|
+
def initialize(text, value, options = {})
|
15
|
+
options = {
|
16
|
+
enabled: true,
|
17
|
+
border_color: default(:border_color),
|
18
|
+
shortcut_text: '',
|
19
|
+
}.merge! options
|
20
|
+
|
21
|
+
@value = value
|
22
|
+
@shortcut_text = options[:shortcut_text]
|
23
|
+
|
24
|
+
super(text, options)
|
25
|
+
end
|
26
|
+
|
27
|
+
def draw_foreground
|
28
|
+
super
|
29
|
+
|
30
|
+
unless @shortcut_text.empty?
|
31
|
+
font.draw_rel("#{@shortcut_text}", rect.right - padding_right, y + ((height - font.height) / 2).floor, z, 1, 0, 1, 1, color)
|
32
|
+
end
|
33
|
+
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
|
37
|
+
protected
|
38
|
+
def layout
|
39
|
+
super
|
40
|
+
|
41
|
+
# Ignore layout request when asked before TextLine has been created.
|
42
|
+
rect.width += font.text_width(" #{@shortcut_text}") unless @shortcut_text.empty? or @text.nil?
|
43
|
+
|
44
|
+
nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class Separator < Label
|
49
|
+
# @param (see Item#initialize)
|
50
|
+
#
|
51
|
+
# @option (see Item#initialize)
|
52
|
+
def initialize(options = {})
|
53
|
+
options = {
|
54
|
+
height: default(:line_height),
|
55
|
+
background_color: default(:background_color),
|
56
|
+
padding: 0,
|
57
|
+
}.merge! options
|
58
|
+
|
59
|
+
super '', options
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
extend Forwardable
|
64
|
+
|
65
|
+
def_delegators :@items, :each, :clear, :size, :[]
|
66
|
+
|
67
|
+
event :selected
|
68
|
+
|
69
|
+
def index(value); @items.index find(value); end
|
70
|
+
def x=(value); super(value); recalc; end
|
71
|
+
def y=(value); super(value); recalc; end
|
72
|
+
|
73
|
+
# @option (see Composite#initialize)
|
74
|
+
# @option options [Float] :x (cursor x, if in a GuiState)
|
75
|
+
# @option options [Float] :y (cursor y, if in a GuiState)
|
76
|
+
# @option options [Boolean] :show (true) Whether to show immediately (show later with #show).
|
77
|
+
def initialize(options = {}, &block)
|
78
|
+
options = {
|
79
|
+
background_color: default(:color),
|
80
|
+
z: Float::INFINITY,
|
81
|
+
show: true,
|
82
|
+
}.merge! options
|
83
|
+
|
84
|
+
state = $window.current_game_state
|
85
|
+
if state.is_a? GuiState
|
86
|
+
cursor = $window.current_game_state.cursor
|
87
|
+
options = {
|
88
|
+
x: cursor.x,
|
89
|
+
y: cursor.y,
|
90
|
+
}.merge! options
|
91
|
+
end
|
92
|
+
|
93
|
+
@items = nil
|
94
|
+
|
95
|
+
super(options)
|
96
|
+
|
97
|
+
@items = vertical spacing: 0, padding: 0
|
98
|
+
|
99
|
+
if options[:show] and state.is_a? GuiState
|
100
|
+
show
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def find(value)
|
105
|
+
@items.find {|c| c.value == value }
|
106
|
+
end
|
107
|
+
|
108
|
+
def separator(options = {})
|
109
|
+
options[:z] = z
|
110
|
+
|
111
|
+
Separator.new({ parent: @items }.merge!(options))
|
112
|
+
end
|
113
|
+
|
114
|
+
def item(text, value, options = {}, &block)
|
115
|
+
options = options.merge({
|
116
|
+
parent: @items,
|
117
|
+
z: z,
|
118
|
+
})
|
119
|
+
item = Item.new(text, value, options, &block)
|
120
|
+
|
121
|
+
item.subscribe :left_mouse_button, method(:item_selected)
|
122
|
+
item.subscribe :right_mouse_button, method(:item_selected)
|
123
|
+
|
124
|
+
item
|
125
|
+
end
|
126
|
+
|
127
|
+
def item_selected(sender, x, y)
|
128
|
+
publish(:selected, sender.value)
|
129
|
+
|
130
|
+
$window.game_state_manager.current_game_state.hide_menu
|
131
|
+
|
132
|
+
nil
|
133
|
+
end
|
134
|
+
|
135
|
+
def show
|
136
|
+
$window.game_state_manager.current_game_state.show_menu self
|
137
|
+
nil
|
138
|
+
end
|
139
|
+
|
140
|
+
protected
|
141
|
+
def layout
|
142
|
+
super
|
143
|
+
|
144
|
+
if @items
|
145
|
+
# Ensure the menu can't go over the edge of the screen. If it can't be avoided, align with top-left edge of screen.
|
146
|
+
rect.x = [[x, $window.width - width - padding_right].min, 0].max
|
147
|
+
rect.y = [[y, $window.height - height - padding_bottom].min, 0].max
|
148
|
+
|
149
|
+
# Move the actual list if the menu has moved to keep on the screen.
|
150
|
+
@items.x = x + padding_left
|
151
|
+
@items.y = y + padding_top
|
152
|
+
|
153
|
+
# Ensure that all items are of the same width.
|
154
|
+
max_width = @items.map(&:width).max || 0
|
155
|
+
@items.each {|c| c.rect.width = max_width }
|
156
|
+
|
157
|
+
@items.recalc # Move all the items inside the packer to correct ones.
|
158
|
+
end
|
159
|
+
|
160
|
+
nil
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Fidgit
|
4
|
+
# Container that auto-packs elements.
|
5
|
+
#
|
6
|
+
# @abstract
|
7
|
+
class Packer < Container
|
8
|
+
attr_reader :spacing_h, :spacing_v
|
9
|
+
|
10
|
+
# @param (see Container#initialize)
|
11
|
+
#
|
12
|
+
# @option (see Container#initialize)
|
13
|
+
def initialize(options = {})
|
14
|
+
options = {
|
15
|
+
}.merge! options
|
16
|
+
|
17
|
+
@spacing_h = options[:spacing_h] || options[:spacing] || default(:spacing_h)
|
18
|
+
@spacing_v = options[:spacing_v] || options[:spacing] || default(:spacing_v)
|
19
|
+
|
20
|
+
super(options)
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
# Recalculate the size of the container.
|
25
|
+
# Should be overridden by any descendant that manages the positions of its children.
|
26
|
+
def layout
|
27
|
+
# This assumes that the container overlaps all the children.
|
28
|
+
|
29
|
+
# Move all children if we have moved.
|
30
|
+
@children.each.with_index do |child, index|
|
31
|
+
child.x = padding_left + x
|
32
|
+
child.y = padding_top + y
|
33
|
+
end
|
34
|
+
|
35
|
+
# Make us as wrap around the largest child.
|
36
|
+
rect.width = (@children.map {|c| c.width }.max || 0) + padding_left + padding_right
|
37
|
+
rect.height = (@children.map {|c| c.height }.max || 0) + padding_top + padding_bottom
|
38
|
+
|
39
|
+
super
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Fidgit
|
4
|
+
class RadioButton < Button
|
5
|
+
attr_reader :group, :value
|
6
|
+
|
7
|
+
event :changed
|
8
|
+
|
9
|
+
def checked?; @checked; end
|
10
|
+
|
11
|
+
# @param (see Button#initialize)
|
12
|
+
# @param [Object] value
|
13
|
+
#
|
14
|
+
# @option (see Button#initialize)
|
15
|
+
# @option options [Boolean] :checked
|
16
|
+
def initialize(text, value, options = {}, &block)
|
17
|
+
options = {
|
18
|
+
checked: false,
|
19
|
+
checked_border_color: default(:checked, :border_color),
|
20
|
+
}.merge! options
|
21
|
+
|
22
|
+
@checked = options[:checked]
|
23
|
+
@value = value
|
24
|
+
|
25
|
+
super(text, options)
|
26
|
+
|
27
|
+
@checked_border_color = options[:checked_border_color].dup
|
28
|
+
@unchecked_border_color = border_color
|
29
|
+
add_to_group
|
30
|
+
|
31
|
+
@border_color = (checked? ? @checked_border_color : @unchecked_border_color).dup
|
32
|
+
end
|
33
|
+
|
34
|
+
def clicked_left_mouse_button(sender, x, y)
|
35
|
+
super
|
36
|
+
check
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
|
40
|
+
# Check the button and update its group. This may uncheck another button in the group if one is selected.
|
41
|
+
def check
|
42
|
+
return if checked?
|
43
|
+
|
44
|
+
@checked = true
|
45
|
+
@group.value = value
|
46
|
+
@border_color = @checked_border_color.dup
|
47
|
+
publish :changed, @checked
|
48
|
+
|
49
|
+
nil
|
50
|
+
end
|
51
|
+
|
52
|
+
# Uncheck the button and update its group.
|
53
|
+
def uncheck
|
54
|
+
return unless checked?
|
55
|
+
|
56
|
+
@checked = false
|
57
|
+
@group.value = value
|
58
|
+
@border_color = @unchecked_border_color.dup
|
59
|
+
publish :changed, @checked
|
60
|
+
|
61
|
+
nil
|
62
|
+
end
|
63
|
+
|
64
|
+
protected
|
65
|
+
def parent=(parent)
|
66
|
+
@group.remove_button self if @parent
|
67
|
+
super(parent)
|
68
|
+
add_to_group if parent
|
69
|
+
parent
|
70
|
+
end
|
71
|
+
|
72
|
+
protected
|
73
|
+
def add_to_group
|
74
|
+
container = parent
|
75
|
+
while container and not container.is_a? Group
|
76
|
+
container = container.parent
|
77
|
+
end
|
78
|
+
|
79
|
+
raise "#{self.class.name} must be placed inside a group element" unless container
|
80
|
+
|
81
|
+
@group = container
|
82
|
+
@group.add_button self
|
83
|
+
nil
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|