colstrom-fidgit 0.2.7
Sign up to get free protection for your applications and to get access to all the features.
- 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,52 @@
|
|
1
|
+
module Fidgit
|
2
|
+
# A modal dialog.
|
3
|
+
# @abstract
|
4
|
+
class DialogState < GuiState
|
5
|
+
DEFAULT_BACKGROUND_COLOR = Gosu::Color.rgb(75, 75, 75)
|
6
|
+
DEFAULT_BORDER_COLOR = Gosu::Color.rgb(255, 255, 255)
|
7
|
+
|
8
|
+
DEFAULT_SHADOW_COLOR = Gosu::Color.rgba(0, 0, 0, 100)
|
9
|
+
DEFAULT_SHADOW_OFFSET = 8
|
10
|
+
|
11
|
+
def initialize(options = {})
|
12
|
+
# @option options [Gosu::Color] :shadow_color (transparent black) Color of the shadow.
|
13
|
+
# @option options [Gosu::Color] :shadow_offset (8) Distance shadow is offset to bottom and left.
|
14
|
+
# @option options [Gosu::Color] :shadow_full (false) Shadow fills whole screen. Ignores :shadow_offset option if true.
|
15
|
+
options = {
|
16
|
+
shadow_color: DEFAULT_SHADOW_COLOR,
|
17
|
+
shadow_offset: DEFAULT_SHADOW_OFFSET,
|
18
|
+
shadow_full: false,
|
19
|
+
}.merge! options
|
20
|
+
|
21
|
+
@shadow_color = options[:shadow_color].dup
|
22
|
+
@shadow_offset = options[:shadow_offset]
|
23
|
+
@shadow_full = options[:shadow_full]
|
24
|
+
|
25
|
+
super()
|
26
|
+
end
|
27
|
+
|
28
|
+
def draw
|
29
|
+
$window.game_state_manager.previous_game_state.draw # Keep the underlying state being shown.
|
30
|
+
$window.flush
|
31
|
+
|
32
|
+
if @shadow_full
|
33
|
+
draw_rect 0, 0, $window.width, $window.height, -Float::INFINITY, @shadow_color
|
34
|
+
elsif @shadow_offset > 0
|
35
|
+
dialog = container[0]
|
36
|
+
draw_rect dialog.x + @shadow_offset, dialog.y + @shadow_offset, dialog.width, dialog.height, -Float::INFINITY, @shadow_color
|
37
|
+
end
|
38
|
+
|
39
|
+
super
|
40
|
+
end
|
41
|
+
|
42
|
+
def show
|
43
|
+
$window.game_state_manager.push(self, finalize: false) unless $window.game_state_manager.game_states.include? self
|
44
|
+
nil
|
45
|
+
end
|
46
|
+
|
47
|
+
def hide
|
48
|
+
$window.game_state_manager.pop(setup: false) if $window.game_state_manager.current == self
|
49
|
+
nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Fidgit
|
2
|
+
# A simple dialog that manages a message with a set of buttons beneath it.
|
3
|
+
class FileDialog < DialogState
|
4
|
+
def initialize(type, options = {}, &block)
|
5
|
+
options = {
|
6
|
+
show: true,
|
7
|
+
background_color: DEFAULT_BACKGROUND_COLOR,
|
8
|
+
border_color: DEFAULT_BORDER_COLOR,
|
9
|
+
}.merge! options
|
10
|
+
|
11
|
+
super(options)
|
12
|
+
|
13
|
+
vertical align: :center, padding: 0 do |packer|
|
14
|
+
FileBrowser.new(type, { parent: packer }.merge!(options)) do |sender, result, file_name|
|
15
|
+
hide
|
16
|
+
block.call result, file_name if block
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
show if options[:show]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,331 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
module Fidgit
|
5
|
+
class GuiState < Chingu::GameState
|
6
|
+
# A 1x1 white pixel used for drawing.
|
7
|
+
PIXEL_IMAGE = 'pixel.png'
|
8
|
+
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
def_delegators :@container, :horizontal, :vertical, :grid
|
12
|
+
|
13
|
+
# The Container that contains all the elements for this GuiState.
|
14
|
+
# @return [Packer]
|
15
|
+
attr_reader :container
|
16
|
+
|
17
|
+
# The element with focus.
|
18
|
+
# @return [Element]
|
19
|
+
attr_reader :focus
|
20
|
+
|
21
|
+
# The Cursor.
|
22
|
+
# @return [Cursor]
|
23
|
+
def cursor; @@cursor; end
|
24
|
+
|
25
|
+
# Sets the focus to a particular element.
|
26
|
+
def focus=(element)
|
27
|
+
@focus.publish :blur if @focus and element
|
28
|
+
@focus = element
|
29
|
+
end
|
30
|
+
|
31
|
+
# Delay, in ms, before a tool-tip will appear.
|
32
|
+
def tool_tip_delay
|
33
|
+
500 # TODO: configure this.
|
34
|
+
end
|
35
|
+
|
36
|
+
# Show a file_dialog.
|
37
|
+
# (see FileDialog#initialize)
|
38
|
+
def file_dialog(type, options = {}, &block)
|
39
|
+
FileDialog.new(type, options, &block)
|
40
|
+
end
|
41
|
+
|
42
|
+
# (see MenuPane#initialize)
|
43
|
+
def menu(options = {}, &block); MenuPane.new(options, &block); end
|
44
|
+
|
45
|
+
# (see MessageDialog#initialize)
|
46
|
+
def message(text, options = {}, &block); MessageDialog.new(text, options, &block); end
|
47
|
+
|
48
|
+
# (see Container#clear)
|
49
|
+
def clear(*args, &block); @container.clear(*args, &block); end
|
50
|
+
|
51
|
+
def initialize
|
52
|
+
# The container is where the user puts their content.
|
53
|
+
@container = MainPacker.new
|
54
|
+
@menu = nil
|
55
|
+
@last_cursor_pos = [-1, -1]
|
56
|
+
@mouse_over = nil
|
57
|
+
|
58
|
+
unless defined? @@draw_pixel
|
59
|
+
media_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'media'))
|
60
|
+
Gosu::Image.autoload_dirs << File.join(media_dir, 'images')
|
61
|
+
Gosu::Sample.autoload_dirs << File.join(media_dir, 'sounds')
|
62
|
+
|
63
|
+
@@draw_pixel = Gosu::Image.new($window, File.join(media_dir, 'images', PIXEL_IMAGE), true) # Must be tileable or it will blur.
|
64
|
+
@@cursor = Cursor.new
|
65
|
+
end
|
66
|
+
|
67
|
+
@min_drag_distance = 0
|
68
|
+
|
69
|
+
super()
|
70
|
+
|
71
|
+
add_inputs(
|
72
|
+
left_mouse_button: ->{ redirect_mouse_button(:left) },
|
73
|
+
holding_left_mouse_button: ->{ redirect_holding_mouse_button(:left) },
|
74
|
+
released_left_mouse_button: ->{ redirect_released_mouse_button(:left) },
|
75
|
+
|
76
|
+
middle_mouse_button: ->{ redirect_mouse_button(:middle) },
|
77
|
+
holding_middle_mouse_button: ->{ redirect_holding_mouse_button(:middle) },
|
78
|
+
released_middle_mouse_button: ->{ redirect_released_mouse_button(:middle) },
|
79
|
+
|
80
|
+
right_mouse_button: ->{ redirect_mouse_button(:right) },
|
81
|
+
holding_right_mouse_button: ->{ redirect_holding_mouse_button(:right) },
|
82
|
+
released_right_mouse_button: ->{ redirect_released_mouse_button(:right) },
|
83
|
+
|
84
|
+
mouse_wheel_up: :redirect_mouse_wheel_up,
|
85
|
+
mouse_wheel_down: :redirect_mouse_wheel_down,
|
86
|
+
|
87
|
+
x: -> { if @focus and (holding_any?(:left_control, :right_control)) then @focus.cut end },
|
88
|
+
c: -> { if @focus and (holding_any?(:left_control, :right_control)) then @focus.copy end },
|
89
|
+
v: -> { if @focus and (holding_any?(:left_control, :right_control)) then @focus.paste end }
|
90
|
+
)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Internationalisation helper.
|
94
|
+
def t(*args); I18n.t(*args); end
|
95
|
+
|
96
|
+
# Clear the data which is specific to the current $window.
|
97
|
+
def self.clear
|
98
|
+
remove_class_variable '@@cursor' if defined? @@cursor
|
99
|
+
remove_class_variable '@@draw_pixel' if defined? @@draw_pixel
|
100
|
+
end
|
101
|
+
|
102
|
+
def update
|
103
|
+
cursor.update
|
104
|
+
@tool_tip.update if @tool_tip
|
105
|
+
@menu.update if @menu
|
106
|
+
@container.update
|
107
|
+
|
108
|
+
# Check menu first, then other elements.
|
109
|
+
new_mouse_over = @menu.hit_element(cursor.x, cursor.y) if @menu
|
110
|
+
new_mouse_over = @container.hit_element(cursor.x, cursor.y) unless new_mouse_over
|
111
|
+
|
112
|
+
if new_mouse_over
|
113
|
+
new_mouse_over.publish :enter if new_mouse_over != @mouse_over
|
114
|
+
new_mouse_over.publish :hover, cursor.x, cursor.y
|
115
|
+
end
|
116
|
+
|
117
|
+
@mouse_over.publish :leave if @mouse_over and new_mouse_over != @mouse_over
|
118
|
+
|
119
|
+
@mouse_over = new_mouse_over
|
120
|
+
|
121
|
+
# Check if the mouse has moved, and no menu is shown, so we can show a tooltip.
|
122
|
+
if [cursor.x, cursor.y] == @last_cursor_pos and (not @menu)
|
123
|
+
if @mouse_over and (Gosu::milliseconds - @mouse_moved_at) > tool_tip_delay
|
124
|
+
if text = @mouse_over.tip and not text.empty?
|
125
|
+
@tool_tip ||= ToolTip.new
|
126
|
+
@tool_tip.text = text
|
127
|
+
@tool_tip.x = cursor.x
|
128
|
+
@tool_tip.y = cursor.y + cursor.height # Place the tip beneath the cursor.
|
129
|
+
else
|
130
|
+
@tool_tip = nil
|
131
|
+
@mouse_moved_at = Gosu::milliseconds
|
132
|
+
end
|
133
|
+
end
|
134
|
+
else
|
135
|
+
@tool_tip = nil
|
136
|
+
@mouse_moved_at = Gosu::milliseconds
|
137
|
+
end
|
138
|
+
|
139
|
+
# The element that grabs input.
|
140
|
+
@active_element = @dragging_element || @focus || @mouse_over
|
141
|
+
|
142
|
+
@last_cursor_pos = [cursor.x, cursor.y]
|
143
|
+
|
144
|
+
super
|
145
|
+
end
|
146
|
+
|
147
|
+
def write_tree
|
148
|
+
puts "=== #{self.class} ==="
|
149
|
+
indent = " "
|
150
|
+
@container.write_tree(indent)
|
151
|
+
@menu.write_tree(indent) if @menu
|
152
|
+
@tool_tip.write_tree(indent) if @tool_tip
|
153
|
+
end
|
154
|
+
|
155
|
+
def draw
|
156
|
+
@container.draw
|
157
|
+
@menu.draw if @menu
|
158
|
+
@tool_tip.draw if @tool_tip
|
159
|
+
cursor.draw
|
160
|
+
|
161
|
+
super
|
162
|
+
end
|
163
|
+
|
164
|
+
def setup
|
165
|
+
super
|
166
|
+
|
167
|
+
@tool_tip = nil
|
168
|
+
@mouse_over = nil # Element the mouse is hovering over.
|
169
|
+
@mouse_down_on = Hash.new # Element that each button was pressed over.
|
170
|
+
@mouse_down_pos = Hash.new # Position that each button was pressed down at.
|
171
|
+
@drag_button = nil
|
172
|
+
@dragging_element = nil
|
173
|
+
@focus = nil
|
174
|
+
@mouse_moved_at = Gosu::milliseconds
|
175
|
+
|
176
|
+
nil
|
177
|
+
end
|
178
|
+
|
179
|
+
def finalize
|
180
|
+
unset_mouse_over
|
181
|
+
|
182
|
+
if @focus
|
183
|
+
@focus.publish :blur
|
184
|
+
@focus = nil
|
185
|
+
end
|
186
|
+
|
187
|
+
@tool_tip = nil
|
188
|
+
|
189
|
+
nil
|
190
|
+
end
|
191
|
+
|
192
|
+
# Called by active elements when they are disabled.
|
193
|
+
def unset_mouse_over
|
194
|
+
@mouse_over.publish :leave if @mouse_over
|
195
|
+
@mouse_over = nil
|
196
|
+
end
|
197
|
+
|
198
|
+
# Set the menu pane to be displayed.
|
199
|
+
#
|
200
|
+
# @param [MenuPane] menu Menu to display.
|
201
|
+
# @return nil
|
202
|
+
def show_menu(menu)
|
203
|
+
hide_menu if @menu
|
204
|
+
@menu = menu
|
205
|
+
|
206
|
+
nil
|
207
|
+
end
|
208
|
+
|
209
|
+
# Hides the currently shown menu, if any.
|
210
|
+
# @return nil
|
211
|
+
def hide_menu
|
212
|
+
@menu = nil
|
213
|
+
|
214
|
+
nil
|
215
|
+
end
|
216
|
+
|
217
|
+
# Flush all pending drawing to the screen.
|
218
|
+
def flush
|
219
|
+
$window.flush
|
220
|
+
end
|
221
|
+
|
222
|
+
# Draw a filled rectangle.
|
223
|
+
def draw_rect(x, y, width, height, z, color, mode = :default)
|
224
|
+
@@draw_pixel.draw x, y, z, width, height, color, mode
|
225
|
+
|
226
|
+
nil
|
227
|
+
end
|
228
|
+
|
229
|
+
# Draw an unfilled rectangle.
|
230
|
+
def draw_frame(x, y, width, height, thickness, z, color, mode = :default)
|
231
|
+
draw_rect(x - thickness, y, thickness, height, z, color, mode) # left
|
232
|
+
draw_rect(x - thickness, y - thickness, width + thickness * 2, thickness, z, color, mode) # top (full)
|
233
|
+
draw_rect(x + width, y, thickness, height, z, color, mode) # right
|
234
|
+
draw_rect(x - thickness, y + height, width + thickness * 2, thickness, z, color, mode) # bottom (full)
|
235
|
+
|
236
|
+
nil
|
237
|
+
end
|
238
|
+
|
239
|
+
def distance(x1, y1, x2, y2)
|
240
|
+
Gosu.distance(x1, y1, x2, y2)
|
241
|
+
end
|
242
|
+
|
243
|
+
def show
|
244
|
+
$window.game_state_manager.push self unless $window.game_state_manager.game_states.include? self
|
245
|
+
nil
|
246
|
+
end
|
247
|
+
|
248
|
+
def hide
|
249
|
+
$window.game_state_manager.pop if $window.game_state_manager.current == self
|
250
|
+
nil
|
251
|
+
end
|
252
|
+
|
253
|
+
protected
|
254
|
+
def redirect_mouse_button(button)
|
255
|
+
# Ensure that if the user clicks away from a menu, it is automatically closed.
|
256
|
+
hide_menu unless @menu and @menu == @mouse_over
|
257
|
+
|
258
|
+
# Blur if clicking outside the focused element.
|
259
|
+
if @focus and @mouse_over != @focus
|
260
|
+
@focus.publish :blur
|
261
|
+
@focus = nil
|
262
|
+
end
|
263
|
+
|
264
|
+
# Publish :left_mouse_button for the element that is clicked.
|
265
|
+
if @mouse_over
|
266
|
+
@mouse_down_pos[button] = [cursor.x, cursor.y]
|
267
|
+
@mouse_down_on[button] = @mouse_over
|
268
|
+
@mouse_over.publish :"#{button}_mouse_button", *@mouse_down_pos[button]
|
269
|
+
else
|
270
|
+
@mouse_down_pos[button] = nil
|
271
|
+
@mouse_down_on[button] = nil
|
272
|
+
end
|
273
|
+
|
274
|
+
nil
|
275
|
+
end
|
276
|
+
|
277
|
+
protected
|
278
|
+
def redirect_released_mouse_button(button)
|
279
|
+
# Ensure that if the user clicks away from a menu, it is automatically closed.
|
280
|
+
hide_menu if @menu and @mouse_over != @menu
|
281
|
+
|
282
|
+
if @mouse_over
|
283
|
+
@mouse_over.publish :"released_#{button}_mouse_button", cursor.x, cursor.y
|
284
|
+
@mouse_over.publish :"clicked_#{button}_mouse_button", cursor.x, cursor.y if @mouse_over == @mouse_down_on[button]
|
285
|
+
end
|
286
|
+
|
287
|
+
if @dragging_element and @drag_button == button
|
288
|
+
@dragging_element.publish :end_drag, cursor.x, cursor.y, @drag_button, @mouse_over
|
289
|
+
@dragging_element = nil
|
290
|
+
@drag_button = nil
|
291
|
+
end
|
292
|
+
|
293
|
+
@mouse_down_on[button] = nil
|
294
|
+
@mouse_down_pos[button] = nil
|
295
|
+
|
296
|
+
nil
|
297
|
+
end
|
298
|
+
|
299
|
+
protected
|
300
|
+
def redirect_holding_mouse_button(button)
|
301
|
+
if not @dragging_element and @mouse_down_on[button] and @mouse_down_on[button].drag?(button) and
|
302
|
+
distance(*@mouse_down_pos[button], cursor.x, cursor.y) > @min_drag_distance
|
303
|
+
@drag_button = button
|
304
|
+
@dragging_element = @mouse_down_on[button]
|
305
|
+
@dragging_element.publish :begin_drag, *@mouse_down_pos[button], :left
|
306
|
+
end
|
307
|
+
|
308
|
+
if @dragging_element
|
309
|
+
if @drag_button == button
|
310
|
+
@dragging_element.publish :update_drag, cursor.x, cursor.y
|
311
|
+
end
|
312
|
+
else
|
313
|
+
@mouse_over.publish :"holding_#{button}_mouse_button", cursor.x, cursor.y if @mouse_over
|
314
|
+
end
|
315
|
+
|
316
|
+
nil
|
317
|
+
end
|
318
|
+
|
319
|
+
protected
|
320
|
+
def redirect_mouse_wheel_up
|
321
|
+
@active_element.publish :mouse_wheel_up, cursor.x, cursor.y if @active_element
|
322
|
+
nil
|
323
|
+
end
|
324
|
+
|
325
|
+
protected
|
326
|
+
def redirect_mouse_wheel_down
|
327
|
+
@active_element.publish :mouse_wheel_down, cursor.x, cursor.y if @active_element
|
328
|
+
nil
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
|
2
|
+
module Fidgit
|
3
|
+
# A simple dialog that manages a message with a set of buttons beneath it.
|
4
|
+
class MessageDialog < DialogState
|
5
|
+
VALID_TYPES = [:ok, :ok_cancel, :yes_no, :yes_no_cancel, :quit_cancel, :quit_save_cancel]
|
6
|
+
|
7
|
+
attr_reader :type
|
8
|
+
|
9
|
+
# @param [String] message
|
10
|
+
#
|
11
|
+
# @option options [Symbol] :type (:ok) One from :ok, :ok_cancel, :yes_no, :yes_no_cancel, :quit_cancel or :quit_save_cancel
|
12
|
+
# @option options [String] :ok_text ("OK")
|
13
|
+
# @option options [String] :yes_text ("Yes")
|
14
|
+
# @option options [String] :no_text ("No")
|
15
|
+
# @option options [String] :cancel_text ("Cancel")
|
16
|
+
# @option options [String] :save_text ("Save")
|
17
|
+
# @option options [String] :quit_text ("Quit")
|
18
|
+
# @option options [Boolean] :show (true) Whether to show the message immediately (otherwise need to use #show later).
|
19
|
+
#
|
20
|
+
# @yield when the dialog is closed.
|
21
|
+
# @yieldparam [Symbol] result :ok, :yes, :no, :quit, :save or :cancel, depending on the button pressed.
|
22
|
+
def initialize(message, options = {}, &block)
|
23
|
+
options = {
|
24
|
+
type: :ok,
|
25
|
+
ok_text: "OK",
|
26
|
+
yes_text: "Yes",
|
27
|
+
no_text: "No",
|
28
|
+
quit_text: "Quit",
|
29
|
+
save_text: "Save",
|
30
|
+
cancel_text: "Cancel",
|
31
|
+
show: true,
|
32
|
+
background_color: DEFAULT_BACKGROUND_COLOR,
|
33
|
+
border_color: DEFAULT_BORDER_COLOR,
|
34
|
+
width: $window.width / 2
|
35
|
+
}.merge! options
|
36
|
+
|
37
|
+
@type = options[:type]
|
38
|
+
raise ArgumentError, ":type must be one of #{VALID_TYPES}, not #{@type}" unless VALID_TYPES.include? @type
|
39
|
+
|
40
|
+
super(options)
|
41
|
+
|
42
|
+
# Dialog is forced to the centre.
|
43
|
+
options[:align_h] = options[:align_v] = :center
|
44
|
+
|
45
|
+
vertical options do
|
46
|
+
text_area(text: message, enabled: false, width: options[:width] - padding_left - padding_right)
|
47
|
+
|
48
|
+
horizontal align_h: :center do
|
49
|
+
@type.to_s.split('_').each do |type|
|
50
|
+
button(options[:"#{type}_text"]) do
|
51
|
+
hide
|
52
|
+
block.call type.to_sym if block
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
show if options[:show]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|