fidgit 0.0.2alpha
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.
- data/.gitignore +8 -0
- data/.rspec +2 -0
- data/COPYING.txt +674 -0
- data/Gemfile +4 -0
- data/README.textile +138 -0
- data/Rakefile +38 -0
- data/config/default_schema.yml +180 -0
- data/examples/_all_examples.rb +9 -0
- data/examples/align_example.rb +56 -0
- data/examples/button_and_toggle_button_example.rb +27 -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 +17 -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 +30 -0
- data/examples/splash_example.rb +42 -0
- data/examples/text_area_example.rb +28 -0
- data/fidgit.gemspec +28 -0
- data/lib/fidgit.rb +4 -0
- data/lib/fidgit/chingu_ext/window.rb +6 -0
- data/lib/fidgit/clipboard.rb +23 -0
- data/lib/fidgit/cursor.rb +38 -0
- data/lib/fidgit/elements/button.rb +68 -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 +85 -0
- data/lib/fidgit/elements/composite.rb +17 -0
- data/lib/fidgit/elements/container.rb +187 -0
- data/lib/fidgit/elements/element.rb +252 -0
- data/lib/fidgit/elements/file_browser.rb +152 -0
- data/lib/fidgit/elements/grid_packer.rb +219 -0
- data/lib/fidgit/elements/group.rb +66 -0
- data/lib/fidgit/elements/horizontal_packer.rb +12 -0
- data/lib/fidgit/elements/label.rb +77 -0
- data/lib/fidgit/elements/list.rb +47 -0
- data/lib/fidgit/elements/menu_pane.rb +149 -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 +75 -0
- data/lib/fidgit/elements/scroll_bar.rb +114 -0
- data/lib/fidgit/elements/scroll_window.rb +92 -0
- data/lib/fidgit/elements/slider.rb +119 -0
- data/lib/fidgit/elements/text_area.rb +351 -0
- data/lib/fidgit/elements/toggle_button.rb +67 -0
- data/lib/fidgit/elements/tool_tip.rb +35 -0
- data/lib/fidgit/elements/vertical_packer.rb +12 -0
- data/lib/fidgit/event.rb +99 -0
- data/lib/fidgit/gosu_ext/color.rb +123 -0
- data/lib/fidgit/history.rb +85 -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 +42 -0
- data/lib/fidgit/states/file_dialog.rb +24 -0
- data/lib/fidgit/states/gui_state.rb +301 -0
- data/lib/fidgit/states/message_dialog.rb +61 -0
- data/lib/fidgit/thumbnail.rb +29 -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/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/label_spec.rb +49 -0
- data/spec/fidgit/event_spec.rb +149 -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/helpers/tex_play_helper.rb +9 -0
- data/spec/fidgit/history_spec.rb +144 -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
- data/spec/fidgit/thumbnail_spec.rb +50 -0
- metadata +177 -0
@@ -0,0 +1,219 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Fidgit
|
4
|
+
# A vertically aligned element packing container.
|
5
|
+
|
6
|
+
class GridPacker < Packer
|
7
|
+
# @return [Integer]
|
8
|
+
attr_reader :num_rows
|
9
|
+
# @return [Integer]
|
10
|
+
attr_reader :num_columns
|
11
|
+
|
12
|
+
# @note Currently only supports +num_columns+ mode (not +num_rows+).
|
13
|
+
#
|
14
|
+
# @param (see Packer#initialize)
|
15
|
+
#
|
16
|
+
# @option (see Packer#initialize)
|
17
|
+
# @option options [Integer] :num_columns Maximum number of columns to use (incompatible with :num_rows)
|
18
|
+
# @option options [Integer] :num_rows Maximum number of rows to use (incompatible with :num_columns)
|
19
|
+
def initialize(options = {})
|
20
|
+
options = {
|
21
|
+
cell_border_color: default(:cell_border_color),
|
22
|
+
cell_background_color: default(:cell_background_color),
|
23
|
+
cell_border_thickness: default(:cell_border_thickness),
|
24
|
+
}.merge! options
|
25
|
+
|
26
|
+
@num_columns = options[:num_columns]
|
27
|
+
@num_rows = options[:num_rows]
|
28
|
+
raise ArgumentError, "options :num_rows and :num_columns are not compatible" if @num_rows and @num_columns
|
29
|
+
|
30
|
+
@cell_border_color = options[:cell_border_color].dup
|
31
|
+
@cell_border_thickness = options[:cell_border_thickness]
|
32
|
+
@cell_background_color = options[:cell_background_color].dup
|
33
|
+
|
34
|
+
@type = @num_rows ? :fixed_rows : :fixed_columns
|
35
|
+
|
36
|
+
super options
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
def layout
|
41
|
+
rearrange
|
42
|
+
repack
|
43
|
+
end
|
44
|
+
|
45
|
+
protected
|
46
|
+
# Rearrange the cells based on changes to the number of rows/columns or adding/removing elements.
|
47
|
+
def rearrange
|
48
|
+
# Calculate the number of the dynamic dimension.
|
49
|
+
case @type
|
50
|
+
when :fixed_rows
|
51
|
+
@num_columns = (size / @num_rows.to_f).ceil
|
52
|
+
when :fixed_columns
|
53
|
+
@num_rows = (size / @num_columns.to_f).ceil
|
54
|
+
end
|
55
|
+
|
56
|
+
# Create an array containing all the rows.
|
57
|
+
@rows = case @type
|
58
|
+
when :fixed_rows
|
59
|
+
# Rearrange the list, arranged by columns, into rows.
|
60
|
+
rows = Array.new(@num_rows) { [] }
|
61
|
+
@children.each_with_index do |child, i|
|
62
|
+
rows[i % @num_rows].push child
|
63
|
+
end
|
64
|
+
rows
|
65
|
+
when :fixed_columns
|
66
|
+
@children.each_slice(@num_columns).to_a
|
67
|
+
end
|
68
|
+
|
69
|
+
nil
|
70
|
+
end
|
71
|
+
|
72
|
+
protected
|
73
|
+
# Repack all the elements into their positions.
|
74
|
+
def repack
|
75
|
+
@widths = Array.new(@num_columns, 0)
|
76
|
+
@heights = Array.new(@num_rows, 0)
|
77
|
+
|
78
|
+
filled_columns = []
|
79
|
+
filled_rows = []
|
80
|
+
|
81
|
+
# Calculate the maximum widths of each column and the maximum height of each row.
|
82
|
+
@rows.each_with_index do |row, row_num|
|
83
|
+
row.each_with_index do |element, column_num|
|
84
|
+
fills = (element.align_h == :fill)
|
85
|
+
@widths[column_num] = [fills ? 0 : element.outer_width, @widths[column_num] || 0].max
|
86
|
+
filled_columns.push fills
|
87
|
+
|
88
|
+
fills = (element.align_v == :fill)
|
89
|
+
@heights[row_num] = [fills ? 0 : element.outer_height, @heights[row_num] || 0].max
|
90
|
+
filled_rows.push fills
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Expand the size of each filled column to make the minimum size required.
|
95
|
+
num_filled_columns = filled_columns.select {|value| value }.count
|
96
|
+
if num_filled_columns > 0
|
97
|
+
total_width = @widths.inject(0, :+) + (padding_left + padding_right) + ((@num_columns - 1) * spacing_h)
|
98
|
+
if total_width < min_width
|
99
|
+
extra_width = total_width / num_filled_columns
|
100
|
+
filled_columns.each_with_index do |filled, i|
|
101
|
+
@widths[i] += extra_width if filled
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Expand the size of each filled row to make the minimum size required.
|
107
|
+
num_filled_rows = filled_rows.select {|value| value }.count
|
108
|
+
if num_filled_rows > 0
|
109
|
+
total_height = @heights.inject(0, :+) + (padding_left + padding_right) + ((@num_rows - 1) * spacing_v)
|
110
|
+
if total_height < min_height
|
111
|
+
extra_height = total_height / num_filled_rows
|
112
|
+
filled_rows.each_with_index do |filled, i|
|
113
|
+
@heights[i] += extra_height if filled
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Actually place all the elements into the grid positions, modified by valign and align.
|
119
|
+
current_y = y + padding_top
|
120
|
+
@rows.each_with_index do |row, row_num|
|
121
|
+
current_x = x + padding_left
|
122
|
+
|
123
|
+
row.each_with_index do |element, column_num|
|
124
|
+
element.x = current_x + element.border_thickness
|
125
|
+
|
126
|
+
case element.align_h # Take horizontal alignment into consideration.
|
127
|
+
when :fill
|
128
|
+
if element.width < @widths[column_num]
|
129
|
+
element.width = @widths[column_num]
|
130
|
+
element.send :repack if element.is_a? GridPacker
|
131
|
+
end
|
132
|
+
when :center
|
133
|
+
element.x += (@widths[column_num] - element.width) / 2
|
134
|
+
when :right
|
135
|
+
element.x += @widths[column_num] - element.width
|
136
|
+
end
|
137
|
+
|
138
|
+
current_x += @widths[column_num]
|
139
|
+
current_x += spacing_h unless column_num == @num_columns - 1
|
140
|
+
|
141
|
+
element.y = current_y + element.border_thickness
|
142
|
+
|
143
|
+
case element.align_v # Take horizontal alignment into consideration.
|
144
|
+
when :fill
|
145
|
+
if element.height < @heights[row_num]
|
146
|
+
element.height = @heights[row_num]
|
147
|
+
element.send :repack if element.is_a? GridPacker
|
148
|
+
end
|
149
|
+
when :center
|
150
|
+
element.y += (@heights[row_num] - element.height) / 2
|
151
|
+
when :bottom
|
152
|
+
element.y += @heights[row_num] - element.height
|
153
|
+
else
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
self.width = current_x - x + padding_left if row_num == 0
|
158
|
+
|
159
|
+
current_y += @heights[row_num] unless row.empty?
|
160
|
+
current_y += spacing_h unless row_num == num_rows - 1
|
161
|
+
end
|
162
|
+
|
163
|
+
self.height = current_y - y + padding_top
|
164
|
+
|
165
|
+
nil
|
166
|
+
end
|
167
|
+
|
168
|
+
protected
|
169
|
+
# @yield The rectangle of each cell within the grid.
|
170
|
+
# @yieldparam [Number] x
|
171
|
+
# @yieldparam [Number] y
|
172
|
+
# @yieldparam [Number] width
|
173
|
+
# @yieldparam [Number] height
|
174
|
+
def each_cell_rect
|
175
|
+
x = self.x + padding_left
|
176
|
+
|
177
|
+
@widths.each_with_index do |width, column_num|
|
178
|
+
y = self.y + padding_top
|
179
|
+
|
180
|
+
@heights.each_with_index do |height, row_num|
|
181
|
+
yield x, y, width, height if @rows[row_num][column_num]
|
182
|
+
y += height + spacing_v
|
183
|
+
end
|
184
|
+
|
185
|
+
x += width + spacing_h
|
186
|
+
end
|
187
|
+
|
188
|
+
nil
|
189
|
+
end
|
190
|
+
|
191
|
+
protected
|
192
|
+
def draw_background
|
193
|
+
super
|
194
|
+
|
195
|
+
# Draw the cell backgrounds.
|
196
|
+
unless @cell_background_color.transparent?
|
197
|
+
each_cell_rect do |x, y, width, height|
|
198
|
+
draw_rect x, y, width, height, z, @cell_background_color
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
nil
|
203
|
+
end
|
204
|
+
|
205
|
+
protected
|
206
|
+
def draw_border
|
207
|
+
super
|
208
|
+
|
209
|
+
# Draw the cell borders.
|
210
|
+
if @cell_border_thickness > 0 and not @cell_border_color.transparent?
|
211
|
+
each_cell_rect do |x, y, width, height|
|
212
|
+
draw_frame x, y, width, height, @cell_border_thickness, z, @cell_border_color
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
nil
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Fidgit
|
4
|
+
class Group < Packer
|
5
|
+
attr_reader :selected
|
6
|
+
|
7
|
+
event :changed
|
8
|
+
|
9
|
+
def value; @selected ? @selected.value : nil; end
|
10
|
+
|
11
|
+
# @example
|
12
|
+
# group do
|
13
|
+
# pack :horizontal do
|
14
|
+
# radio_button 1, text: '1', checked: true
|
15
|
+
# radio_button 2, text: '2'
|
16
|
+
# subscribe :changed do |sender, value|
|
17
|
+
# puts value
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# @param (see Packer#initialize)
|
23
|
+
#
|
24
|
+
# @option (see Packer#initialize)
|
25
|
+
def initialize(options = {}, &block)
|
26
|
+
super(options)
|
27
|
+
|
28
|
+
@selected = nil
|
29
|
+
@buttons = []
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_button(button)
|
33
|
+
@buttons.push button
|
34
|
+
self.value = button.value if button.checked?
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
|
38
|
+
def remove_button(button)
|
39
|
+
self.value = nil if button == @selected
|
40
|
+
@buttons.delete button
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
|
44
|
+
# @example
|
45
|
+
# @my_group = group do
|
46
|
+
# pack :horizontal do
|
47
|
+
# radio_button(1, text: '1', checked: true)
|
48
|
+
# radio_button(2, text: '2')
|
49
|
+
# end
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# # later
|
53
|
+
# @my_group.value = 2
|
54
|
+
def value=(value)
|
55
|
+
if value != self.value
|
56
|
+
button = @buttons.find { |b| b.value == value }
|
57
|
+
@selected.uncheck if @selected and @selected.checked?
|
58
|
+
@selected = button
|
59
|
+
@selected.check if @selected and not @selected.checked?
|
60
|
+
publish :changed, self.value
|
61
|
+
end
|
62
|
+
|
63
|
+
value
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Fidgit
|
4
|
+
class Label < Element
|
5
|
+
attr_accessor :color, :background_color, :border_color
|
6
|
+
attr_reader :text, :icon
|
7
|
+
|
8
|
+
def text=(value)
|
9
|
+
@text = value
|
10
|
+
recalc
|
11
|
+
nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def icon=(value)
|
15
|
+
@icon = value
|
16
|
+
recalc
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
|
20
|
+
# @param (see Element#initialize)
|
21
|
+
# @param [String] text The string to display in the label.
|
22
|
+
#
|
23
|
+
# @option (see Element#initialize)
|
24
|
+
# @option options [Fidgit::Thumbnail, Gosu::Image, nil] :icon (nil)
|
25
|
+
def initialize(text, options = {})
|
26
|
+
options = {
|
27
|
+
color: default(:color),
|
28
|
+
background_color: default(:background_color),
|
29
|
+
border_color: default(:border_color),
|
30
|
+
}.merge! options
|
31
|
+
|
32
|
+
@text = text.dup
|
33
|
+
@icon = options[:icon]
|
34
|
+
@color = options[:color].dup
|
35
|
+
|
36
|
+
super(options)
|
37
|
+
end
|
38
|
+
|
39
|
+
def draw_foreground
|
40
|
+
current_x = x + padding_left
|
41
|
+
if @icon
|
42
|
+
@icon.draw(current_x, y + padding_top, z)
|
43
|
+
current_x += @icon.width + padding_left
|
44
|
+
end
|
45
|
+
|
46
|
+
unless @text.empty?
|
47
|
+
font.draw(@text, current_x, y + padding_top, z, 1, 1, @color)
|
48
|
+
end
|
49
|
+
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
def layout
|
55
|
+
if @icon
|
56
|
+
if @text.empty?
|
57
|
+
rect.width = [padding_left + @icon.width + padding_right, width].max
|
58
|
+
rect.height = [padding_top + @icon.height + padding_bottom, height].max
|
59
|
+
else
|
60
|
+
# Todo: Use padding_h inside here? Probably by making this a Composite.
|
61
|
+
rect.width = [padding_left + @icon.width + [padding_left + padding_right].max + font.text_width(@text) + padding_right, width].max
|
62
|
+
rect.height = [padding_top + [@icon.height, font_size].max + padding_bottom, height].max
|
63
|
+
end
|
64
|
+
else
|
65
|
+
if @text.empty?
|
66
|
+
rect.width = [padding_left + padding_right, width].max
|
67
|
+
rect.height = [padding_top + padding_bottom, height].max
|
68
|
+
else
|
69
|
+
rect.width = [padding_left + font.text_width(@text) + padding_right, width].max
|
70
|
+
rect.height = [padding_top + font_size + padding_bottom, height].max
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
nil
|
75
|
+
end
|
76
|
+
end
|
77
|
+
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 = pack :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,149 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Fidgit
|
4
|
+
class MenuPane < Composite
|
5
|
+
# An item within the menu.
|
6
|
+
class Item < Button
|
7
|
+
attr_reader :value, :shortcut
|
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 [Boolean] :enabled (true)
|
14
|
+
# @option options [String] :shortcut ('')
|
15
|
+
def initialize(text, value, options = {})
|
16
|
+
options = {
|
17
|
+
enabled: true,
|
18
|
+
border_color: default(:border_color),
|
19
|
+
}.merge! options
|
20
|
+
|
21
|
+
@value = value
|
22
|
+
@enabled = [true, false].include?(options[:enabled]) ? options[:enabled] : true
|
23
|
+
@shortcut = options[:shortcut] || ''
|
24
|
+
|
25
|
+
super(text, options)
|
26
|
+
end
|
27
|
+
|
28
|
+
def draw_foreground
|
29
|
+
super
|
30
|
+
unless @shortcut.empty?
|
31
|
+
font.draw_rel("#{@shortcut}", rect.right - padding_right, y + ((height - font_size) / 2).floor, z, 1, 0, 1, 1, color)
|
32
|
+
end
|
33
|
+
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
|
37
|
+
protected
|
38
|
+
def layout
|
39
|
+
super
|
40
|
+
rect.width += font.text_width(" #{@shortcut}") unless @shortcut.empty?
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class Separator < Label
|
46
|
+
# @param (see Item#initialize)
|
47
|
+
#
|
48
|
+
# @option (see Item#initialize)
|
49
|
+
def initialize(options = {})
|
50
|
+
options = {
|
51
|
+
height: default(:line_height),
|
52
|
+
background_color: default(:background_color),
|
53
|
+
padding: 0,
|
54
|
+
}.merge! options
|
55
|
+
|
56
|
+
super '', options
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
event :selected
|
61
|
+
|
62
|
+
def index(value); @items.index find(value); end
|
63
|
+
def size; @items.size; end
|
64
|
+
def [](index); @items[index]; end
|
65
|
+
|
66
|
+
# @option (see Composite#initialize)
|
67
|
+
# @option options [Float] :x (cursor x, if in a GuiState)
|
68
|
+
# @option options [Float] :y (cursor y, if in a GuiState)
|
69
|
+
# @option options [Boolean] :show (true) Whether to show immediately (show later with #show).
|
70
|
+
def initialize(options = {}, &block)
|
71
|
+
options = {
|
72
|
+
background_color: default(:color),
|
73
|
+
z: Float::INFINITY,
|
74
|
+
show: true,
|
75
|
+
}.merge! options
|
76
|
+
|
77
|
+
state = $window.current_game_state
|
78
|
+
if state.is_a? GuiState
|
79
|
+
cursor = $window.current_game_state.cursor
|
80
|
+
options = {
|
81
|
+
x: cursor.x,
|
82
|
+
y: cursor.y,
|
83
|
+
}.merge! options
|
84
|
+
end
|
85
|
+
|
86
|
+
super(options)
|
87
|
+
|
88
|
+
@items = pack :vertical, spacing: 0, padding: 0
|
89
|
+
|
90
|
+
if options[:show] and state.is_a? GuiState
|
91
|
+
show
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def find(value)
|
96
|
+
@items.find {|c| c.value == value }
|
97
|
+
end
|
98
|
+
|
99
|
+
def separator(options = {})
|
100
|
+
options[:z] = z
|
101
|
+
|
102
|
+
Separator.new({ parent: @items }.merge!(options))
|
103
|
+
end
|
104
|
+
|
105
|
+
def item(text, value, options = {}, &block)
|
106
|
+
options[:z] = z
|
107
|
+
item = Item.new(text, value, { parent: @items }.merge!(options), &block)
|
108
|
+
|
109
|
+
item.subscribe :left_mouse_button, method(:item_selected)
|
110
|
+
item.subscribe :right_mouse_button, method(:item_selected)
|
111
|
+
|
112
|
+
item
|
113
|
+
end
|
114
|
+
|
115
|
+
def item_selected(sender, x, y)
|
116
|
+
publish(:selected, sender.value)
|
117
|
+
|
118
|
+
$window.game_state_manager.current_game_state.hide_menu
|
119
|
+
|
120
|
+
nil
|
121
|
+
end
|
122
|
+
|
123
|
+
def show
|
124
|
+
$window.game_state_manager.current_game_state.show_menu self
|
125
|
+
nil
|
126
|
+
end
|
127
|
+
|
128
|
+
protected
|
129
|
+
def layout
|
130
|
+
super
|
131
|
+
|
132
|
+
if @items
|
133
|
+
# Ensure the menu can't go over the edge of the screen. If it can't be avoided, align with left edge of screen.
|
134
|
+
rect.x = [[x, $window.width - width - padding_right].min, 0].max
|
135
|
+
rect.y = [[y, $window.height - height - padding_bottom].min, 0].max
|
136
|
+
|
137
|
+
# Move the actual list if the menu has moved to keep on the screen.
|
138
|
+
@items.x = x + padding_left
|
139
|
+
@items.y = y + padding_top
|
140
|
+
|
141
|
+
# Ensure that all items are of the same width.
|
142
|
+
max_width = @items.each.to_a.map {|c| c.width }.max || 0
|
143
|
+
@items.each {|c| c.rect.width = max_width }
|
144
|
+
end
|
145
|
+
|
146
|
+
nil
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|