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.
Files changed (87) hide show
  1. data/.gitignore +8 -0
  2. data/.rspec +2 -0
  3. data/COPYING.txt +674 -0
  4. data/Gemfile +4 -0
  5. data/README.textile +138 -0
  6. data/Rakefile +38 -0
  7. data/config/default_schema.yml +180 -0
  8. data/examples/_all_examples.rb +9 -0
  9. data/examples/align_example.rb +56 -0
  10. data/examples/button_and_toggle_button_example.rb +27 -0
  11. data/examples/color_picker_example.rb +17 -0
  12. data/examples/color_well_example.rb +25 -0
  13. data/examples/combo_box_example.rb +24 -0
  14. data/examples/file_dialog_example.rb +42 -0
  15. data/examples/grid_packer_example.rb +29 -0
  16. data/examples/helpers/example_window.rb +17 -0
  17. data/examples/label_example.rb +17 -0
  18. data/examples/list_example.rb +23 -0
  19. data/examples/media/images/head_icon.png +0 -0
  20. data/examples/menu_pane_example.rb +27 -0
  21. data/examples/message_dialog_example.rb +65 -0
  22. data/examples/radio_button_example.rb +37 -0
  23. data/examples/readme_example.rb +32 -0
  24. data/examples/scroll_window_example.rb +49 -0
  25. data/examples/slider_example.rb +30 -0
  26. data/examples/splash_example.rb +42 -0
  27. data/examples/text_area_example.rb +28 -0
  28. data/fidgit.gemspec +28 -0
  29. data/lib/fidgit.rb +4 -0
  30. data/lib/fidgit/chingu_ext/window.rb +6 -0
  31. data/lib/fidgit/clipboard.rb +23 -0
  32. data/lib/fidgit/cursor.rb +38 -0
  33. data/lib/fidgit/elements/button.rb +68 -0
  34. data/lib/fidgit/elements/color_picker.rb +63 -0
  35. data/lib/fidgit/elements/color_well.rb +39 -0
  36. data/lib/fidgit/elements/combo_box.rb +85 -0
  37. data/lib/fidgit/elements/composite.rb +17 -0
  38. data/lib/fidgit/elements/container.rb +187 -0
  39. data/lib/fidgit/elements/element.rb +252 -0
  40. data/lib/fidgit/elements/file_browser.rb +152 -0
  41. data/lib/fidgit/elements/grid_packer.rb +219 -0
  42. data/lib/fidgit/elements/group.rb +66 -0
  43. data/lib/fidgit/elements/horizontal_packer.rb +12 -0
  44. data/lib/fidgit/elements/label.rb +77 -0
  45. data/lib/fidgit/elements/list.rb +47 -0
  46. data/lib/fidgit/elements/menu_pane.rb +149 -0
  47. data/lib/fidgit/elements/packer.rb +42 -0
  48. data/lib/fidgit/elements/radio_button.rb +86 -0
  49. data/lib/fidgit/elements/scroll_area.rb +75 -0
  50. data/lib/fidgit/elements/scroll_bar.rb +114 -0
  51. data/lib/fidgit/elements/scroll_window.rb +92 -0
  52. data/lib/fidgit/elements/slider.rb +119 -0
  53. data/lib/fidgit/elements/text_area.rb +351 -0
  54. data/lib/fidgit/elements/toggle_button.rb +67 -0
  55. data/lib/fidgit/elements/tool_tip.rb +35 -0
  56. data/lib/fidgit/elements/vertical_packer.rb +12 -0
  57. data/lib/fidgit/event.rb +99 -0
  58. data/lib/fidgit/gosu_ext/color.rb +123 -0
  59. data/lib/fidgit/history.rb +85 -0
  60. data/lib/fidgit/redirector.rb +83 -0
  61. data/lib/fidgit/schema.rb +123 -0
  62. data/lib/fidgit/selection.rb +106 -0
  63. data/lib/fidgit/standard_ext/hash.rb +21 -0
  64. data/lib/fidgit/states/dialog_state.rb +42 -0
  65. data/lib/fidgit/states/file_dialog.rb +24 -0
  66. data/lib/fidgit/states/gui_state.rb +301 -0
  67. data/lib/fidgit/states/message_dialog.rb +61 -0
  68. data/lib/fidgit/thumbnail.rb +29 -0
  69. data/lib/fidgit/version.rb +5 -0
  70. data/lib/fidgit/window.rb +19 -0
  71. data/media/images/arrow.png +0 -0
  72. data/media/images/file_directory.png +0 -0
  73. data/media/images/file_file.png +0 -0
  74. data/media/images/pixel.png +0 -0
  75. data/spec/fidgit/elements/helpers/helper.rb +3 -0
  76. data/spec/fidgit/elements/label_spec.rb +49 -0
  77. data/spec/fidgit/event_spec.rb +149 -0
  78. data/spec/fidgit/gosu_ext/color_spec.rb +130 -0
  79. data/spec/fidgit/gosu_ext/helpers/helper.rb +3 -0
  80. data/spec/fidgit/helpers/helper.rb +4 -0
  81. data/spec/fidgit/helpers/tex_play_helper.rb +9 -0
  82. data/spec/fidgit/history_spec.rb +144 -0
  83. data/spec/fidgit/redirector_spec.rb +78 -0
  84. data/spec/fidgit/schema_spec.rb +67 -0
  85. data/spec/fidgit/schema_test.yml +32 -0
  86. data/spec/fidgit/thumbnail_spec.rb +50 -0
  87. metadata +177 -0
@@ -0,0 +1,187 @@
1
+ # encoding: utf-8
2
+
3
+ module Fidgit
4
+ # A container that contains Elements.
5
+ # @abstract
6
+ class Container < Element
7
+ def size; @children.size; end
8
+ def each(&block); @children.each &block; end
9
+ def find(&block); @children.find &block; end
10
+ def index(value); @children.index value; end
11
+ def [](index); @children[index]; end
12
+
13
+ def x=(value)
14
+ each {|c| c.x += value - x }
15
+ super(value)
16
+ end
17
+
18
+ def y=(value)
19
+ each {|c| c.y += value - y }
20
+ super(value)
21
+ end
22
+
23
+ # @param (see Element#initialize)
24
+ #
25
+ # @option (see Element#initialize)
26
+ def initialize(options = {})
27
+ options[:border_color] = default(:debug, :border_color) if Fidgit.debug_mode?
28
+
29
+ @children = []
30
+
31
+ super(options)
32
+ end
33
+
34
+ def add(element)
35
+ element.send :parent=, self
36
+ @children.push element
37
+
38
+ recalc
39
+ nil
40
+ end
41
+
42
+ def remove(element)
43
+ @children.delete element
44
+ element.send :parent=, nil
45
+
46
+ recalc
47
+ nil
48
+ end
49
+
50
+ def insert(position, element)
51
+ @children.insert position, element
52
+ element.send :parent=, self
53
+
54
+ recalc
55
+ nil
56
+ end
57
+
58
+ # Create a button within the container.
59
+ def button(text, options = {}, &block)
60
+ Button.new(text, {parent: self}.merge!(options), &block)
61
+ end
62
+
63
+ # Create a color picker within the container.
64
+ def color_picker(options = {}, &block)
65
+ ColorPicker.new({parent: self}.merge!(options), &block)
66
+ end
67
+
68
+ # Create a color well within the container.
69
+ def color_well(options = {}, &block)
70
+ ColorWell.new({parent: self}.merge!(options), &block)
71
+ end
72
+
73
+ def combo_box(options = {}, &block)
74
+ ComboBox.new({parent: self}.merge!(options), &block)
75
+ end
76
+
77
+ def file_browser(type, options = {}, &block)
78
+ FileBrowser.new(type, {parent: self}.merge!(options), &block)
79
+ end
80
+
81
+ def group(options = {}, &block)
82
+ Group.new({parent: self}.merge!(options), &block)
83
+ end
84
+
85
+ # Create a label within the container.
86
+ def label(text, options = {})
87
+ Label.new(text, {parent: self}.merge!(options))
88
+ end
89
+
90
+ def list(options = {}, &block)
91
+ List.new({parent: self}.merge!(options), &block)
92
+ end
93
+
94
+ def pack(arrangement, options = {}, &block)
95
+ klass = case arrangement
96
+ when :horizontal
97
+ HorizontalPacker
98
+ when :vertical
99
+ VerticalPacker
100
+ when :grid
101
+ GridPacker
102
+ else
103
+ raise ArgumentError, "packing arrangement must be one of :horizontal, :vertical or :grid"
104
+ end
105
+
106
+ klass.new({parent: self}.merge!(options), &block)
107
+ end
108
+
109
+ def radio_button(text, value, options = {}, &block)
110
+ RadioButton.new(text, value, {parent: self}.merge!(options), &block)
111
+ end
112
+
113
+ def scroll_area(options = {}, &block)
114
+ ScrollArea.new({parent: self}.merge!(options), &block)
115
+ end
116
+
117
+ def scroll_window(options = {}, &block)
118
+ ScrollWindow.new({parent: self}.merge!(options), &block)
119
+ end
120
+
121
+ def slider(options = {}, &block)
122
+ Slider.new({parent: self}.merge!(options), &block)
123
+ end
124
+
125
+ def text_area(options = {}, &block)
126
+ TextArea.new({parent: self}.merge!(options), &block)
127
+ end
128
+
129
+ def toggle_button(text, options = {}, &block)
130
+ ToggleButton.new(text, {parent: self}.merge!(options), &block)
131
+ end
132
+
133
+ def clear
134
+ @children.each {|child| child.send :parent=, nil }
135
+ @children.clear
136
+
137
+ recalc
138
+
139
+ nil
140
+ end
141
+
142
+ def update
143
+ each { |c| c.update }
144
+
145
+ nil
146
+ end
147
+
148
+ # Returns the element within this container that was hit,
149
+ # @return [Element, nil] The element hit, otherwise nil.
150
+ def hit_element(x, y)
151
+ @children.reverse_each do |child|
152
+ case child
153
+ when Container, Composite
154
+ if element = child.hit_element(x, y)
155
+ return element
156
+ end
157
+ else
158
+ return child if child.hit?(x, y)
159
+ end
160
+ end
161
+
162
+ self if hit?(x, y)
163
+ end
164
+
165
+ protected
166
+ def draw_foreground
167
+ each { |c| c.draw }
168
+
169
+ font.draw self.class.name, x, y, z if Fidgit.debug_mode?
170
+
171
+ nil
172
+ end
173
+
174
+ protected
175
+ # Any container passed a block will allow you access to its methods.
176
+ def post_init_block(&block)
177
+ case block.arity
178
+ when 1
179
+ yield self
180
+ when 0
181
+ instance_methods_eval &block
182
+ else
183
+ raise "block arity must be 0 or 1"
184
+ end
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,252 @@
1
+ # encoding: utf-8
2
+
3
+ # The Fidgit GUI framework for Gosu.
4
+ module Fidgit
5
+ class << self
6
+ attr_accessor :debug_mode
7
+ end
8
+
9
+ self.debug_mode = false
10
+
11
+ def self.debug_mode?; debug_mode; end
12
+
13
+ # An element within the GUI environment.
14
+ # @abstract
15
+ class Element
16
+ include Event
17
+
18
+ event :left_mouse_button
19
+ event :holding_left_mouse_button
20
+ event :released_left_mouse_button
21
+ event :clicked_left_mouse_button
22
+
23
+ event :right_mouse_button
24
+ event :holding_right_mouse_button
25
+ event :released_right_mouse_button
26
+ event :clicked_right_mouse_button
27
+
28
+ event :mouse_wheel_up
29
+ event :mouse_wheel_down
30
+
31
+ event :enter
32
+ event :hover
33
+ event :leave
34
+
35
+ DEFAULT_SCHEMA_FILE = File.expand_path(File.join(__FILE__, '..', '..', '..', '..', 'config', 'default_schema.yml'))
36
+
37
+ VALID_ALIGN_H = [:left, :center, :right, :fill]
38
+ VALID_ALIGN_V = [:top, :center, :bottom, :fill]
39
+
40
+ attr_reader :z, :tip, :font_size, :padding_top, :padding_right, :padding_bottom, :padding_left, :align_h, :align_v, :parent, :border_thickness
41
+
42
+ attr_accessor :background_color
43
+
44
+ def x; rect.x; end
45
+ def x=(value); rect.x = value; end
46
+
47
+ def y; rect.y; end
48
+ def y=(value); rect.y = value; end
49
+
50
+ # Width not including border.
51
+ def width; rect.width; end
52
+ def width=(value); rect.width = [[value, @width_range.max].min, @width_range.min].max; end
53
+ def min_width; @width_range.min; end
54
+ def max_width; @width_range.max; end
55
+ # Width including border thickness.
56
+ def outer_width; rect.width + @border_thickness * 2; end
57
+
58
+ # Height not including border.
59
+ def height; rect.height; end
60
+ def height=(value); rect.height = [[value, @height_range.max].min, @height_range.min].max; end
61
+ def min_height; @height_range.min; end
62
+ def max_height; @height_range.max; end
63
+ # Height including border thickness.
64
+ def outer_height; rect.height + @border_thickness * 2; end
65
+
66
+ # Can the object be dragged?
67
+ def drag?(button); false; end
68
+
69
+ def enabled?; @enabled; end
70
+ def enabled=(value); @enabled = value; end
71
+
72
+ def font; @font ||= Gosu::Font[@font_name, @font_size]; end
73
+
74
+ def rect; @rect; end; protected :rect
75
+
76
+ def self.schema; @@schema ||= Schema.new(YAML.load(File.read(DEFAULT_SCHEMA_FILE)));; end
77
+
78
+ class << self
79
+ alias_method :original_new, :new
80
+
81
+ def new(*args, &block)
82
+ obj = original_new(*args) # Block should be ignored.
83
+ obj.send :post_init
84
+ obj.send :post_init_block, &block if block_given?
85
+ obj
86
+ end
87
+ end
88
+
89
+ # Get the default value from the schema.
90
+ #
91
+ # @param [Symbol, Array<Symbol>] names
92
+ def default(*names)
93
+ self.class.schema.default(self.class, names)
94
+ end
95
+
96
+ # @param [Element, nil] parent
97
+ #
98
+ # @option options [Number] :x (0)
99
+ # @option options [Number] :y (0)
100
+ # @option options [Number] :z (0)
101
+ #
102
+ # @option options [Number] :width (auto)
103
+ # @option options [Number] :min_width (value of :width option)
104
+ # @option options [Number] :max_width (value of :width option)
105
+ #
106
+ # @option options [Number] :height (auto)
107
+ # @option options [Number] :min_height (value of :height option)
108
+ # @option options [Number] :max_height (value of :height option)
109
+ #
110
+ # @option options [String] :tip ('') Tool-tip text
111
+ # @option options [String] :font_name ('')
112
+ # @option options [String] :font_size (30)
113
+ #
114
+ # @option options [Gosu::Color] :background_color (transparent)
115
+ # @option options [Gosu::Color] :border_color (transparent)
116
+ #
117
+ # @option options [Boolean] :enabled (true)
118
+ #
119
+ # @option options [Number] :padding (4)
120
+ # @option options [Number] :padding_h (:padding option)
121
+ # @option options [Number] :padding_v (:padding option)
122
+ # @option options [Number] :padding_top (:padding_v option)
123
+ # @option options [Number] :padding_right (:padding_h option)
124
+ # @option options [Number] :padding_bottom (:padding_v option)
125
+ # @option options [Number] :padding_left (:padding_h option)
126
+ #
127
+ # @option options [Symbol] :align Align both horizontally and vertically. One of :center, :fill or [<align_v>, <align_h>] such as [:top, :right].
128
+ # @option options [Symbol] :align_h (value or :align else :left) One of :left, :center, :right :fill
129
+ # @option options [Symbol] :align_v (value of :align else :top) One of :top, :center, :bottom, :fill
130
+
131
+ # @yield instance_methods_eval with respect to self.
132
+ def initialize(options = {}, &block)
133
+ options = {
134
+ x: 0,
135
+ y: 0,
136
+ z: 0,
137
+ tip: '',
138
+ font_name: default(:font_name),
139
+ font_size: default(:font_size),
140
+ background_color: default(:background_color),
141
+ border_color: default(:border_color),
142
+ border_thickness: default(:border_thickness),
143
+ enabled: true,
144
+ }.merge! options
145
+
146
+ @enabled = options[:enabled]
147
+
148
+ # Alignment and min/max dimensions.
149
+ @align_h = options[:align_h] || Array(options[:align]).last || default(:align_h)
150
+ raise ArgumentError, "Invalid align_h: #{@align_h}" unless VALID_ALIGN_H.include? @align_h
151
+
152
+ min_width = (options[:min_width] || options[:width] || 0)
153
+ max_width = (options[:max_width] || options[:width] || Float::INFINITY)
154
+ @width_range = min_width..max_width
155
+
156
+ @align_v = options[:align_v] || Array(options[:align]).first || default(:align_v)
157
+ raise ArgumentError, "Invalid align_v: #{@align_v}" unless VALID_ALIGN_V.include? @align_v
158
+
159
+ min_height = (options[:min_height] || options[:height] || 0)
160
+ max_height = (options[:max_height] || options[:height] || Float::INFINITY)
161
+ @height_range = min_height..max_height
162
+
163
+ @background_color = options[:background_color].dup
164
+ @border_color = options[:border_color].dup
165
+ @border_thickness = options[:border_thickness]
166
+
167
+ @padding_top = options[:padding_top] || options[:padding_v] || options[:padding] || default(:padding_top)
168
+ @padding_right = options[:padding_right] || options[:padding_h] || options[:padding] || default(:padding_right)
169
+ @padding_bottom = options[:padding_bottom] || options[:padding_v] || options[:padding] || default(:padding_bottom)
170
+ @padding_left = options[:padding_left] || options[:padding_h] || options[:padding] || default(:padding_left)
171
+ self.parent = options[:parent]
172
+
173
+ @z = options[:z]
174
+ @tip = options[:tip].dup
175
+ @font_name = options[:font_name].dup
176
+ @font_size = options[:font_size]
177
+
178
+ @rect = Chingu::Rect.new(options[:x], options[:y], options[:width] || 0, options[:height] || 0)
179
+ end
180
+
181
+ def recalc
182
+ old_width, old_height = width, height
183
+ layout
184
+ parent.recalc if parent and (width != old_width or height != old_height)
185
+
186
+ nil
187
+ end
188
+
189
+ # Check if a point (screen coordinates) is over the element.
190
+ def hit?(x, y)
191
+ @rect.collide_point?(x, y)
192
+ end
193
+
194
+ # Redraw the element.
195
+ def draw
196
+ draw_background
197
+ draw_border
198
+ draw_foreground
199
+ nil
200
+ end
201
+
202
+ # Update the element.
203
+ def update
204
+ nil
205
+ end
206
+
207
+ def draw_rect(*args)
208
+ $window.current_game_state.draw_rect(*args)
209
+ end
210
+
211
+ def draw_frame(*args)
212
+ $window.current_game_state.draw_frame(*args)
213
+ end
214
+
215
+ protected
216
+ def parent=(parent); @parent = parent; end
217
+
218
+ protected
219
+ def draw_background
220
+ draw_rect(x, y, width, height, z, @background_color) unless @background_color.transparent?
221
+ end
222
+
223
+ protected
224
+ def draw_border
225
+ draw_frame(x, y, width, height, @border_thickness, z, @border_color) if @border_thickness > 0 and not @border_color.transparent?
226
+ end
227
+
228
+ protected
229
+ def draw_foreground
230
+ nil
231
+ end
232
+
233
+ protected
234
+ # Should be overridden in children to recalculate the width and height of the element and, if a container
235
+ # manage the positions of its children.
236
+ def layout
237
+ nil
238
+ end
239
+
240
+ protected
241
+ def post_init
242
+ recalc
243
+ @parent.send :add, self if @parent
244
+ end
245
+
246
+ protected
247
+ # By default, elements do not accept block arguments.
248
+ def post_init_block(&block)
249
+ raise ArgumentError, "does not accept a block"
250
+ end
251
+ end
252
+ end
@@ -0,0 +1,152 @@
1
+ # encoding: utf-8
2
+
3
+ module Fidgit
4
+ class FileBrowser < Composite
5
+ VALID_TYPES = [:open, :save]
6
+
7
+ event :selected
8
+
9
+ attr_reader :pattern, :base_directory
10
+
11
+ def show_extension?; @show_extension; end
12
+ def directory
13
+ dir = File.join(*@directories)
14
+ dir = File.join(@base_directory, dir) unless @base_directory.empty?
15
+ dir
16
+ end
17
+ def file_name; @file_name_text.text; end
18
+ def file_path; File.join(directory, file_name); end
19
+
20
+ # @param [Symbol] type One of :open, :save
21
+ # @option options [String] :base_directory ('') Outermost directory that the browser will see.
22
+ # @option options [String] :directory (current working directory).
23
+ # @option options [String] :file_name ('') Initially selected file in the directory.
24
+ # @option options [String] :pattern ('*.*')
25
+ # @option options [Boolean] :show_extension (true)
26
+ def initialize(type, options = {})
27
+ options = {
28
+ base_directory: '',
29
+ directory: Dir.pwd,
30
+ file_name: '',
31
+ pattern: default(:pattern),
32
+ show_extension: default(:show_extension),
33
+ width: 400,
34
+ save_text: "Save",
35
+ open_text: "Open",
36
+ cancel_text: "Cancel",
37
+ }.merge! options
38
+
39
+ @type = type
40
+ raise ArgumentError, "type must be one of #{VALID_TYPES}, not #{@type}" unless VALID_TYPES.include? @type
41
+
42
+ @pattern = options[:pattern]
43
+ @show_extension = options[:show_extension]
44
+ @base_directory = options[:base_directory].chomp File::SEPARATOR
45
+
46
+ @directories = options[:directory].sub(/^#{@base_directory}/, '').split(File::SEPARATOR)
47
+ if @directories.first == ''
48
+ @directories[0] = File::SEPARATOR
49
+ end
50
+
51
+ super options
52
+
53
+ pack :vertical do
54
+ @nav_buttons = pack :horizontal, padding: 0, spacing: 2
55
+
56
+ @scroll_window = scroll_window(height: 250, width: options[:width]) do
57
+ @files_list = list(width: options[:width]) do
58
+ subscribe :changed do |sender, file_path|
59
+ if file_path
60
+ file_name = File.basename file_path
61
+ if File.directory? file_path
62
+ @directories.push file_name
63
+ create_nav_buttons
64
+ update_files_list
65
+ else
66
+ @file_name_text.text = file_name
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ @file_name_text = text_area(text: options[:file_name], max_height: font_size * 1.5, width: options[:width], border_thickness: 1)
74
+
75
+ create_nav_buttons
76
+
77
+ pack :horizontal, align: :center, padding: 0 do
78
+ @action_button = button(options[:"#{type}_text"]) do
79
+ publish :selected, @type, file_path
80
+ end
81
+
82
+ button(options[:cancel_text]) do
83
+ publish :selected, :cancel, file_path
84
+ end
85
+ end
86
+
87
+ # Ensure that the open/save button is enabled only when the path is sensible.
88
+ @file_name_text.subscribe :changed do |sender, text|
89
+ @action_button.enabled = case @type
90
+ when :open
91
+ File.exists? file_path and not File.directory? file_path
92
+ when :save
93
+ not text.empty?
94
+ end
95
+ end
96
+
97
+ update_files_list
98
+ end
99
+ end
100
+
101
+ protected
102
+ def create_nav_buttons(size = @directories.size)
103
+ @nav_buttons.clear
104
+
105
+ @directories = @directories[0..size]
106
+
107
+ @directories.each_with_index do |dir, i|
108
+ if i < @directories.size - 1
109
+ @nav_buttons.button(dir) do
110
+ create_nav_buttons(i)
111
+ end
112
+ else
113
+ @nav_buttons.label dir, border_color: @@schema.default(Button, :border_color), border_thickness: @@schema.default(Button, :border_thickness)
114
+ end
115
+ end
116
+
117
+ update_files_list
118
+ end
119
+
120
+ protected
121
+ def update_files_list
122
+ @files_list.clear
123
+ @file_name_text.text = ''
124
+ @scroll_window.offset_x = @scroll_window.offset_y = 0
125
+
126
+ # Add folders.
127
+ Dir.glob(File.join(directory, "*")).each do |file_path|
128
+ if File.directory? file_path
129
+ @files_list.item File.basename(file_path), file_path, icon: Gosu::Image["file_directory.png"]
130
+ end
131
+ end
132
+
133
+ # Add files that match the pattern.
134
+ Dir.glob(File.join(directory, pattern)).each do |file_path|
135
+ unless File.directory? file_path
136
+ file_name = if @show_extension
137
+ File.basename(file_path)
138
+ else
139
+ File.basename(file_path, File.extname(file_path))
140
+ end
141
+
142
+ @files_list.item file_name, file_path, icon: Gosu::Image["file_file.png"]
143
+ end
144
+ end
145
+ end
146
+
147
+ protected
148
+ def post_init_block(&block)
149
+ subscribe :selected, &block
150
+ end
151
+ end
152
+ end