glimmer-dsl-libui 0.4.2 → 0.4.6

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -0
  3. data/README.md +1359 -200
  4. data/VERSION +1 -1
  5. data/examples/basic_entry.rb +27 -24
  6. data/examples/basic_entry2.rb +31 -0
  7. data/examples/color_button.rb +18 -13
  8. data/examples/color_button2.rb +14 -0
  9. data/examples/dynamic_area.rb +77 -90
  10. data/examples/dynamic_area2.rb +14 -12
  11. data/examples/dynamic_area3.rb +90 -0
  12. data/examples/dynamic_area4.rb +95 -0
  13. data/examples/font_button.rb +17 -12
  14. data/examples/font_button2.rb +18 -0
  15. data/examples/form.rb +42 -30
  16. data/examples/form2.rb +37 -0
  17. data/examples/form_table.rb +100 -87
  18. data/examples/form_table2.rb +93 -0
  19. data/examples/histogram.rb +93 -91
  20. data/examples/histogram2.rb +109 -0
  21. data/examples/login.rb +45 -39
  22. data/examples/login2.rb +55 -0
  23. data/examples/login3.rb +65 -0
  24. data/examples/login4.rb +61 -0
  25. data/examples/login5.rb +43 -0
  26. data/examples/meta_example.rb +9 -6
  27. data/examples/method_based_custom_keyword.rb +8 -15
  28. data/examples/method_based_custom_keyword2.rb +97 -0
  29. data/examples/timer.rb +28 -31
  30. data/examples/timer2.rb +129 -0
  31. data/glimmer-dsl-libui.gemspec +0 -0
  32. data/lib/glimmer/dsl/libui/data_binding_expression.rb +4 -6
  33. data/lib/glimmer/libui/attributed_string.rb +3 -0
  34. data/lib/glimmer/libui/control_proxy/color_button_proxy.rb +5 -0
  35. data/lib/glimmer/libui/control_proxy/entry_proxy.rb +5 -0
  36. data/lib/glimmer/libui/control_proxy/font_button_proxy.rb +4 -0
  37. data/lib/glimmer/libui/control_proxy/multiline_entry_proxy.rb +5 -0
  38. data/lib/glimmer/libui/control_proxy/slider_proxy.rb +38 -0
  39. data/lib/glimmer/libui/control_proxy/spinbox_proxy.rb +38 -0
  40. data/lib/glimmer/libui/control_proxy.rb +4 -0
  41. data/lib/glimmer/libui/data_bindable.rb +39 -0
  42. data/lib/glimmer/libui/shape.rb +2 -0
  43. metadata +19 -2
data/examples/timer.rb CHANGED
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  require 'glimmer-dsl-libui'
4
2
 
5
3
  class Timer
@@ -9,9 +7,12 @@ class Timer
9
7
  MINUTE_MAX = 59
10
8
  HOUR_MAX = 23
11
9
 
10
+ attr_accessor :hour, :min, :sec, :started, :played
11
+
12
12
  def initialize
13
13
  @pid = nil
14
14
  @alarm_file = File.expand_path('../sounds/AlanWalker-Faded.mid', __dir__)
15
+ @hour = @min = @sec = 0
15
16
  at_exit { stop_alarm }
16
17
  setup_timer
17
18
  create_gui
@@ -41,31 +42,29 @@ class Timer
41
42
  unless @setup_timer
42
43
  Glimmer::LibUI.timer(1) do
43
44
  if @started
44
- seconds = @sec_spinbox.value
45
- minutes = @min_spinbox.value
46
- hours = @hour_spinbox.value
45
+ seconds = @sec
46
+ minutes = @min
47
+ hours = @hour
47
48
  if seconds > 0
48
- @sec_spinbox.value = seconds -= 1
49
+ self.sec = seconds -= 1
49
50
  end
50
51
  if seconds == 0
51
52
  if minutes > 0
52
- @min_spinbox.value = minutes -= 1
53
- @sec_spinbox.value = seconds = SECOND_MAX
53
+ self.min = minutes -= 1
54
+ self.sec = seconds = SECOND_MAX
54
55
  end
55
56
  if minutes == 0
56
57
  if hours > 0
57
- @hour_spinbox.value = hours -= 1
58
- @min_spinbox.value = minutes = MINUTE_MAX
59
- @sec_spinbox.value = seconds = SECOND_MAX
58
+ self.hour = hours -= 1
59
+ self.min = minutes = MINUTE_MAX
60
+ self.sec = seconds = SECOND_MAX
60
61
  end
61
62
  if hours == 0 && minutes == 0 && seconds == 0
62
- @start_button.enabled = true
63
- @stop_button.enabled = false
64
- @started = false
63
+ self.started = false
65
64
  unless @played
66
65
  play_alarm
67
66
  msg_box('Alarm', 'Countdown Is Finished!')
68
- @played = true
67
+ self.played = true
69
68
  end
70
69
  end
71
70
  end
@@ -83,42 +82,40 @@ class Timer
83
82
  group('Countdown') {
84
83
  vertical_box {
85
84
  horizontal_box {
86
- @hour_spinbox = spinbox(0, HOUR_MAX) {
85
+ spinbox(0, HOUR_MAX) {
87
86
  stretchy false
88
- value 0
87
+ value <=> [self, :hour]
89
88
  }
90
89
  label(':') {
91
90
  stretchy false
92
91
  }
93
- @min_spinbox = spinbox(0, MINUTE_MAX) {
92
+ spinbox(0, MINUTE_MAX) {
94
93
  stretchy false
95
- value 0
94
+ value <=> [self, :min]
96
95
  }
97
96
  label(':') {
98
97
  stretchy false
99
98
  }
100
- @sec_spinbox = spinbox(0, SECOND_MAX) {
99
+ spinbox(0, SECOND_MAX) {
101
100
  stretchy false
102
- value 0
101
+ value <=> [self, :sec]
103
102
  }
104
103
  }
105
104
  horizontal_box {
106
- @start_button = button('Start') {
105
+ button('Start') {
106
+ enabled <= [self, :started, on_read: :!]
107
+
107
108
  on_clicked do
108
- @start_button.enabled = false
109
- @stop_button.enabled = true
110
- @started = true
111
- @played = false
109
+ self.started = true
110
+ self.played = false
112
111
  end
113
112
  }
114
113
 
115
- @stop_button = button('Stop') {
116
- enabled false
114
+ button('Stop') {
115
+ enabled <= [self, :started]
117
116
 
118
117
  on_clicked do
119
- @start_button.enabled = true
120
- @stop_button.enabled = false
121
- @started = false
118
+ self.started = false
122
119
  end
123
120
  }
124
121
  }
@@ -0,0 +1,129 @@
1
+ require 'glimmer-dsl-libui'
2
+
3
+ class Timer
4
+ include Glimmer
5
+
6
+ SECOND_MAX = 59
7
+ MINUTE_MAX = 59
8
+ HOUR_MAX = 23
9
+
10
+ def initialize
11
+ @pid = nil
12
+ @alarm_file = File.expand_path('../sounds/AlanWalker-Faded.mid', __dir__)
13
+ at_exit { stop_alarm }
14
+ setup_timer
15
+ create_gui
16
+ end
17
+
18
+ def stop_alarm
19
+ if @pid
20
+ Process.kill(:SIGKILL, @pid) if @th.alive?
21
+ @pid = nil
22
+ end
23
+ end
24
+
25
+ def play_alarm
26
+ stop_alarm
27
+ if @pid.nil?
28
+ begin
29
+ @pid = spawn "timidity -G 0.0-10.0 #{@alarm_file}"
30
+ @th = Process.detach @pid
31
+ rescue Errno::ENOENT
32
+ warn 'Timidty++ not found. Please install Timidity++.'
33
+ warn 'https://sourceforge.net/projects/timidity/'
34
+ end
35
+ end
36
+ end
37
+
38
+ def setup_timer
39
+ unless @setup_timer
40
+ Glimmer::LibUI.timer(1) do
41
+ if @started
42
+ seconds = @sec_spinbox.value
43
+ minutes = @min_spinbox.value
44
+ hours = @hour_spinbox.value
45
+ if seconds > 0
46
+ @sec_spinbox.value = seconds -= 1
47
+ end
48
+ if seconds == 0
49
+ if minutes > 0
50
+ @min_spinbox.value = minutes -= 1
51
+ @sec_spinbox.value = seconds = SECOND_MAX
52
+ end
53
+ if minutes == 0
54
+ if hours > 0
55
+ @hour_spinbox.value = hours -= 1
56
+ @min_spinbox.value = minutes = MINUTE_MAX
57
+ @sec_spinbox.value = seconds = SECOND_MAX
58
+ end
59
+ if hours == 0 && minutes == 0 && seconds == 0
60
+ @start_button.enabled = true
61
+ @stop_button.enabled = false
62
+ @started = false
63
+ unless @played
64
+ play_alarm
65
+ msg_box('Alarm', 'Countdown Is Finished!')
66
+ @played = true
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ @setup_timer = true
74
+ end
75
+ end
76
+
77
+ def create_gui
78
+ window('Timer') {
79
+ margined true
80
+
81
+ group('Countdown') {
82
+ vertical_box {
83
+ horizontal_box {
84
+ @hour_spinbox = spinbox(0, HOUR_MAX) {
85
+ stretchy false
86
+ value 0
87
+ }
88
+ label(':') {
89
+ stretchy false
90
+ }
91
+ @min_spinbox = spinbox(0, MINUTE_MAX) {
92
+ stretchy false
93
+ value 0
94
+ }
95
+ label(':') {
96
+ stretchy false
97
+ }
98
+ @sec_spinbox = spinbox(0, SECOND_MAX) {
99
+ stretchy false
100
+ value 0
101
+ }
102
+ }
103
+ horizontal_box {
104
+ @start_button = button('Start') {
105
+ on_clicked do
106
+ @start_button.enabled = false
107
+ @stop_button.enabled = true
108
+ @started = true
109
+ @played = false
110
+ end
111
+ }
112
+
113
+ @stop_button = button('Stop') {
114
+ enabled false
115
+
116
+ on_clicked do
117
+ @start_button.enabled = true
118
+ @stop_button.enabled = false
119
+ @started = false
120
+ end
121
+ }
122
+ }
123
+ }
124
+ }
125
+ }.show
126
+ end
127
+ end
128
+
129
+ Timer.new
Binary file
@@ -30,16 +30,14 @@ module Glimmer
30
30
  class DataBindingExpression < Expression
31
31
  def can_interpret?(parent, keyword, *args, &block)
32
32
  args.size == 1 and
33
- args[0].is_a?(DataBinding::ModelBinding)
33
+ args[0].is_a?(DataBinding::ModelBinding) and
34
+ parent.respond_to?(:data_bind)
34
35
  end
35
36
 
36
37
  def interpret(parent, keyword, *args, &block)
38
+ property = keyword
37
39
  model_binding = args[0]
38
- model_attribute_observer = Glimmer::DataBinding::Observer.proc do
39
- parent.send("#{keyword}=", model_binding.evaluate_property)
40
- end
41
- model_attribute_observer.observe(model_binding)
42
- model_attribute_observer.call # initial update
40
+ parent.data_bind(property, model_binding)
43
41
  end
44
42
  end
45
43
  end
@@ -23,10 +23,13 @@ require 'glimmer/libui/control_proxy'
23
23
  require 'glimmer/libui/control_proxy/area_proxy'
24
24
  require 'glimmer/libui/parent'
25
25
  require 'glimmer/libui/control_proxy/transformable'
26
+ require 'glimmer/libui/data_bindable'
26
27
 
27
28
  module Glimmer
28
29
  module LibUI
29
30
  class AttributedString
31
+ include DataBindable
32
+
30
33
  attr_reader :keyword, :parent_proxy, :args
31
34
  attr_accessor :block
32
35
 
@@ -113,6 +113,11 @@ module Glimmer
113
113
  Fiddle.free @alpha unless @alpha.nil?
114
114
  super
115
115
  end
116
+
117
+ def data_bind(property, model_binding)
118
+ super
119
+ handle_listener('on_changed') { model_binding.call(color) } if property == 'color'
120
+ end
116
121
  end
117
122
  end
118
123
  end
@@ -28,6 +28,11 @@ module Glimmer
28
28
  #
29
29
  # Follows the Proxy Design Pattern
30
30
  class EntryProxy < ControlProxy
31
+ def data_bind(property, model_binding)
32
+ super
33
+ handle_listener('on_changed') { model_binding.call(text) } if property == 'text'
34
+ end
35
+
31
36
  def libui_api_keyword
32
37
  'entry'
33
38
  end
@@ -64,6 +64,10 @@ module Glimmer
64
64
  ::LibUI.free_font_button_font(@font_descriptor) unless @font_descriptor.nil?
65
65
  super
66
66
  end
67
+
68
+ def data_bind(property, model_binding)
69
+ handle_listener('on_changed') { model_binding.call(font) } if property == 'font'
70
+ end
67
71
  end
68
72
  end
69
73
  end
@@ -28,6 +28,11 @@ module Glimmer
28
28
  #
29
29
  # Follows the Proxy Design Pattern
30
30
  class MultilineEntryProxy < ControlProxy
31
+ def data_bind(property, model_binding)
32
+ super
33
+ handle_listener('on_changed') { model_binding.call(text) } if property == 'text'
34
+ end
35
+
31
36
  def libui_api_keyword
32
37
  'multiline_entry'
33
38
  end
@@ -0,0 +1,38 @@
1
+ # Copyright (c) 2021 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require 'glimmer/libui/control_proxy'
23
+
24
+ module Glimmer
25
+ module LibUI
26
+ class ControlProxy
27
+ # Proxy for LibUI slider objects
28
+ #
29
+ # Follows the Proxy Design Pattern
30
+ class SliderProxy < ControlProxy
31
+ def data_bind(property, model_binding)
32
+ super
33
+ handle_listener('on_changed') { model_binding.call(value) } if property == 'value'
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ # Copyright (c) 2021 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require 'glimmer/libui/control_proxy'
23
+
24
+ module Glimmer
25
+ module LibUI
26
+ class ControlProxy
27
+ # Proxy for LibUI spinbox objects
28
+ #
29
+ # Follows the Proxy Design Pattern
30
+ class SpinboxProxy < ControlProxy
31
+ def data_bind(property, model_binding)
32
+ super
33
+ handle_listener('on_changed') { model_binding.call(value) } if property == 'value'
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -19,6 +19,8 @@
19
19
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
20
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
+ require 'glimmer/libui/data_bindable'
23
+
22
24
  module Glimmer
23
25
  module LibUI
24
26
  # Proxy for LibUI control objects
@@ -101,6 +103,8 @@ module Glimmer
101
103
  end
102
104
  end
103
105
 
106
+ include DataBindable
107
+
104
108
  KEYWORD_ALIASES = {
105
109
  'msg_box' => 'message_box',
106
110
  'msg_box_error' => 'message_box_error',
@@ -0,0 +1,39 @@
1
+ # Copyright (c) 2021 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ module Glimmer
23
+ module LibUI
24
+ # Parent controls and shapes who have children and add child post_initialize_child
25
+ module DataBindable
26
+ # Data-binds model to update view.
27
+ # Subclasses can override to do inverse data-binding by observing view control for property changes and updating model binding accordingly
28
+ def data_bind(property, model_binding)
29
+ model_attribute_observer = Glimmer::DataBinding::Observer.proc do
30
+ new_value = model_binding.evaluate_property
31
+ send("#{property}=", new_value) unless send(property) == new_value
32
+ end
33
+ model_attribute_observer.observe(model_binding)
34
+ model_attribute_observer.call # initial update
35
+ model_attribute_observer
36
+ end
37
+ end
38
+ end
39
+ end
@@ -22,6 +22,7 @@
22
22
  require 'glimmer/libui/parent'
23
23
  require 'glimmer/libui/control_proxy/area_proxy'
24
24
  require 'glimmer/libui/control_proxy/path_proxy'
25
+ require 'glimmer/libui/data_bindable'
25
26
 
26
27
  module Glimmer
27
28
  module LibUI
@@ -64,6 +65,7 @@ module Glimmer
64
65
  end
65
66
 
66
67
  include Parent
68
+ include DataBindable
67
69
 
68
70
  attr_reader :parent, :args, :keyword, :block
69
71
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer-dsl-libui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Maleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-26 00:00:00.000000000 Z
11
+ date: 2021-11-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer
@@ -223,6 +223,7 @@ files:
223
223
  - examples/basic_draw_text.rb
224
224
  - examples/basic_draw_text2.rb
225
225
  - examples/basic_entry.rb
226
+ - examples/basic_entry2.rb
226
227
  - examples/basic_image.rb
227
228
  - examples/basic_image2.rb
228
229
  - examples/basic_image3.rb
@@ -246,6 +247,7 @@ files:
246
247
  - examples/basic_window2.rb
247
248
  - examples/button_counter.rb
248
249
  - examples/color_button.rb
250
+ - examples/color_button2.rb
249
251
  - examples/color_the_circles.rb
250
252
  - examples/control_gallery.rb
251
253
  - examples/custom_draw_text.rb
@@ -253,16 +255,27 @@ files:
253
255
  - examples/date_time_picker.rb
254
256
  - examples/dynamic_area.rb
255
257
  - examples/dynamic_area2.rb
258
+ - examples/dynamic_area3.rb
259
+ - examples/dynamic_area4.rb
256
260
  - examples/editable_column_table.rb
257
261
  - examples/editable_table.rb
258
262
  - examples/font_button.rb
263
+ - examples/font_button2.rb
259
264
  - examples/form.rb
265
+ - examples/form2.rb
260
266
  - examples/form_table.rb
267
+ - examples/form_table2.rb
261
268
  - examples/grid.rb
262
269
  - examples/histogram.rb
270
+ - examples/histogram2.rb
263
271
  - examples/login.rb
272
+ - examples/login2.rb
273
+ - examples/login3.rb
274
+ - examples/login4.rb
275
+ - examples/login5.rb
264
276
  - examples/meta_example.rb
265
277
  - examples/method_based_custom_keyword.rb
278
+ - examples/method_based_custom_keyword2.rb
266
279
  - examples/midi_player.rb
267
280
  - examples/simple_notepad.rb
268
281
  - examples/snake.rb
@@ -281,6 +294,7 @@ files:
281
294
  - examples/tic_tac_toe/board.rb
282
295
  - examples/tic_tac_toe/cell.rb
283
296
  - examples/timer.rb
297
+ - examples/timer2.rb
284
298
  - glimmer-dsl-libui.gemspec
285
299
  - icons/glimmer.png
286
300
  - lib/glimmer-dsl-libui.rb
@@ -358,12 +372,15 @@ files:
358
372
  - lib/glimmer/libui/control_proxy/open_type_tag_proxy.rb
359
373
  - lib/glimmer/libui/control_proxy/path_proxy.rb
360
374
  - lib/glimmer/libui/control_proxy/radio_buttons_proxy.rb
375
+ - lib/glimmer/libui/control_proxy/slider_proxy.rb
376
+ - lib/glimmer/libui/control_proxy/spinbox_proxy.rb
361
377
  - lib/glimmer/libui/control_proxy/tab_item_proxy.rb
362
378
  - lib/glimmer/libui/control_proxy/table_proxy.rb
363
379
  - lib/glimmer/libui/control_proxy/text_proxy.rb
364
380
  - lib/glimmer/libui/control_proxy/transformable.rb
365
381
  - lib/glimmer/libui/control_proxy/triple_column.rb
366
382
  - lib/glimmer/libui/control_proxy/window_proxy.rb
383
+ - lib/glimmer/libui/data_bindable.rb
367
384
  - lib/glimmer/libui/image_path_renderer.rb
368
385
  - lib/glimmer/libui/parent.rb
369
386
  - lib/glimmer/libui/shape.rb