glimmer-dsl-libui 0.4.14 → 0.4.18

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +30 -0
  3. data/README.md +170 -60
  4. data/VERSION +1 -1
  5. data/bin/girb +0 -0
  6. data/examples/basic_table.rb +1 -1
  7. data/examples/basic_table_button.rb +0 -1
  8. data/examples/cpu_percentage.rb +1 -1
  9. data/examples/custom_draw_text.rb +14 -7
  10. data/examples/custom_draw_text2.rb +15 -8
  11. data/examples/editable_column_table.rb +5 -0
  12. data/examples/form_table.rb +9 -3
  13. data/examples/form_table2.rb +12 -6
  14. data/examples/form_table3.rb +9 -3
  15. data/examples/form_table4.rb +9 -3
  16. data/examples/form_table5.rb +9 -3
  17. data/examples/meta_example.rb +3 -1
  18. data/glimmer-dsl-libui.gemspec +0 -0
  19. data/icons/blank.png +0 -0
  20. data/lib/glimmer/dsl/libui/dsl.rb +1 -0
  21. data/lib/glimmer/dsl/libui/operation_expression.rb +47 -0
  22. data/lib/glimmer/dsl/libui/property_expression.rb +2 -2
  23. data/lib/glimmer/libui/attributed_string.rb +17 -8
  24. data/lib/glimmer/libui/control_proxy/area_proxy.rb +17 -17
  25. data/lib/glimmer/libui/control_proxy/box.rb +1 -0
  26. data/lib/glimmer/libui/control_proxy/column/background_color_column_proxy.rb +6 -0
  27. data/lib/glimmer/libui/control_proxy/column/button_column_proxy.rb +6 -28
  28. data/lib/glimmer/libui/control_proxy/column/checkbox_column_proxy.rb +6 -0
  29. data/lib/glimmer/libui/control_proxy/column/checkbox_text_color_column_proxy.rb +6 -0
  30. data/lib/glimmer/libui/control_proxy/column/checkbox_text_column_proxy.rb +6 -0
  31. data/lib/glimmer/libui/control_proxy/column/image_column_proxy.rb +6 -0
  32. data/lib/glimmer/libui/control_proxy/column/image_text_color_column_proxy.rb +6 -0
  33. data/lib/glimmer/libui/control_proxy/column/image_text_column_proxy.rb +6 -0
  34. data/lib/glimmer/libui/control_proxy/column/progress_bar_column_proxy.rb +6 -0
  35. data/lib/glimmer/libui/control_proxy/column/text_color_column_proxy.rb +6 -0
  36. data/lib/glimmer/libui/control_proxy/column/text_column_proxy.rb +6 -0
  37. data/lib/glimmer/libui/control_proxy/column.rb +7 -0
  38. data/lib/glimmer/libui/control_proxy/form_proxy.rb +1 -0
  39. data/lib/glimmer/libui/control_proxy/image_proxy.rb +3 -0
  40. data/lib/glimmer/libui/control_proxy/menu_item_proxy/quit_menu_item_proxy.rb +18 -9
  41. data/lib/glimmer/libui/control_proxy/open_type_features_proxy.rb +11 -2
  42. data/lib/glimmer/libui/control_proxy/open_type_tag_proxy.rb +2 -0
  43. data/lib/glimmer/libui/control_proxy/path_proxy.rb +8 -4
  44. data/lib/glimmer/libui/control_proxy/table_proxy.rb +59 -34
  45. data/lib/glimmer/libui/control_proxy/text_proxy.rb +2 -0
  46. data/lib/glimmer/libui/control_proxy/window_proxy.rb +34 -35
  47. data/lib/glimmer/libui/control_proxy.rb +45 -9
  48. data/lib/glimmer/libui/data_bindable.rb +1 -1
  49. data/lib/glimmer/libui/shape.rb +1 -0
  50. data/lib/glimmer/libui.rb +1 -0
  51. data/lib/glimmer-dsl-libui.rb +6 -0
  52. metadata +21 -5
@@ -22,6 +22,7 @@ class CustomDrawText
22
22
  @area.queue_redraw_all
23
23
  end
24
24
  }
25
+
25
26
  color_button { |cb|
26
27
  label 'Color'
27
28
 
@@ -30,14 +31,18 @@ class CustomDrawText
30
31
  @area.queue_redraw_all
31
32
  end
32
33
  }
33
- color_button { |cb|
34
- label 'Background'
35
-
36
- on_changed do
37
- @background = cb.color
38
- @area.queue_redraw_all
39
- end
40
- }
34
+
35
+ unless OS.windows?
36
+ color_button { |cb|
37
+ label 'Background'
38
+
39
+ on_changed do
40
+ @background = cb.color
41
+ @area.queue_redraw_all
42
+ end
43
+ }
44
+ end
45
+
41
46
  combobox { |c|
42
47
  label 'Underline'
43
48
  items Glimmer::LibUI.enum_symbols(:underline).map(&:to_s).map {|word| word.split('_').map(&:capitalize).join(' ')}
@@ -48,6 +53,7 @@ class CustomDrawText
48
53
  @area.queue_redraw_all
49
54
  end
50
55
  }
56
+
51
57
  combobox { |c|
52
58
  label 'Underline Built-In Color'
53
59
  items Glimmer::LibUI.enum_symbols(:underline_color).map(&:to_s).map(&:capitalize)
@@ -64,6 +70,7 @@ class CustomDrawText
64
70
  @area.queue_redraw_all
65
71
  end
66
72
  }
73
+
67
74
  @underline_custom_color_button = color_button {
68
75
  label 'Underline Custom Color'
69
76
 
@@ -22,6 +22,11 @@ window('Editable column animal sounds', 400, 200) {
22
22
  }
23
23
 
24
24
  cell_rows data
25
+
26
+ on_edited do |row, row_data| # only fires on direct table editing
27
+ puts "Row #{row} edited: #{row_data}"
28
+ $stdout.flush
29
+ end
25
30
  }
26
31
  }
27
32
 
@@ -18,7 +18,7 @@ class FormTable
18
18
  end
19
19
 
20
20
  def launch
21
- window('Contacts', 600, 600) { |w|
21
+ window('Contacts', 600, 600) {
22
22
  margined true
23
23
 
24
24
  vertical_box {
@@ -56,8 +56,8 @@ class FormTable
56
56
 
57
57
  on_clicked do
58
58
  new_row = [name, email, phone, city, state]
59
- if new_row.include?('')
60
- msg_box_error(w, 'Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
59
+ if new_row.map(&:to_s).include?('')
60
+ msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
61
61
  else
62
62
  @contacts << Contact.new(*new_row) # automatically inserts a row into the table due to explicit data-binding
63
63
  @unfiltered_contacts = @contacts.dup
@@ -102,6 +102,12 @@ class FormTable
102
102
 
103
103
  on_changed do |row, type, row_data|
104
104
  puts "Row #{row} #{type}: #{row_data}"
105
+ $stdout.flush # for Windows
106
+ end
107
+
108
+ on_edited do |row, row_data| # only fires on direct table editing
109
+ puts "Row #{row} edited: #{row_data}"
110
+ $stdout.flush # for Windows
105
111
  end
106
112
  }
107
113
  }
@@ -1,7 +1,7 @@
1
1
  require 'glimmer-dsl-libui'
2
2
 
3
3
  class FormTable
4
- Contact = Struct.new(:name, :email, :phone, :city, :state)
4
+ Contact = Struct.new(:name, :email, :phone, :city, :state_province)
5
5
 
6
6
  include Glimmer
7
7
 
@@ -18,7 +18,7 @@ class FormTable
18
18
  end
19
19
 
20
20
  def launch
21
- window('Contacts', 600, 600) { |w|
21
+ window('Contacts', 600, 600) {
22
22
  margined true
23
23
 
24
24
  vertical_box {
@@ -56,8 +56,8 @@ class FormTable
56
56
 
57
57
  on_clicked do
58
58
  new_row = [name, email, phone, city, state]
59
- if new_row.include?('')
60
- msg_box_error(w, 'Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
59
+ if new_row.map(&:to_s).include?('')
60
+ msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
61
61
  else
62
62
  @contacts << Contact.new(*new_row) # automatically inserts a row into the table due to implicit data-binding
63
63
  @unfiltered_contacts = @contacts.dup
@@ -95,13 +95,19 @@ class FormTable
95
95
  text_column('Email')
96
96
  text_column('Phone')
97
97
  text_column('City')
98
- text_column('State/Province')
98
+ text_column('State')
99
99
 
100
100
  editable true
101
- cell_rows <=> [self, :contacts, column_attributes: {'State/Province' => :state}] # explicit data-binding to Model Array with column_attributes mapping for a specific column
101
+ cell_rows <=> [self, :contacts, column_attributes: {'State' => :state_province}] # explicit data-binding to Model Array with column_attributes mapping for a specific column
102
102
 
103
103
  on_changed do |row, type, row_data|
104
104
  puts "Row #{row} #{type}: #{row_data}"
105
+ $stdout.flush # for Windows
106
+ end
107
+
108
+ on_edited do |row, row_data| # only fires on direct table editing
109
+ puts "Row #{row} edited: #{row_data}"
110
+ $stdout.flush # for Windows
105
111
  end
106
112
  }
107
113
  }
@@ -19,7 +19,7 @@ class FormTable
19
19
  end
20
20
 
21
21
  def launch
22
- window('Contacts', 600, 600) { |w|
22
+ window('Contacts', 600, 600) {
23
23
  margined true
24
24
 
25
25
  vertical_box {
@@ -57,8 +57,8 @@ class FormTable
57
57
 
58
58
  on_clicked do
59
59
  new_row = [name, email, phone, city, state]
60
- if new_row.include?('')
61
- msg_box_error(w, 'Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
60
+ if new_row.map(&:to_s).include?('')
61
+ msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
62
62
  else
63
63
  @contacts << Contact.new(*new_row) # automatically inserts a row into the table due to implicit data-binding
64
64
  @unfiltered_contacts = @contacts.dup
@@ -103,6 +103,12 @@ class FormTable
103
103
 
104
104
  on_changed do |row, type, row_data|
105
105
  puts "Row #{row} #{type}: #{row_data}"
106
+ $stdout.flush # for Windows
107
+ end
108
+
109
+ on_edited do |row, row_data| # only fires on direct table editing
110
+ puts "Row #{row} edited: #{row_data}"
111
+ $stdout.flush # for Windows
106
112
  end
107
113
  }
108
114
  }
@@ -16,7 +16,7 @@ class FormTable
16
16
  end
17
17
 
18
18
  def launch
19
- window('Contacts', 600, 600) { |w|
19
+ window('Contacts', 600, 600) {
20
20
  margined true
21
21
 
22
22
  vertical_box {
@@ -54,8 +54,8 @@ class FormTable
54
54
 
55
55
  on_clicked do
56
56
  new_row = [name, email, phone, city, state]
57
- if new_row.include?('')
58
- msg_box_error(w, 'Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
57
+ if new_row.map(&:to_s).include?('')
58
+ msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
59
59
  else
60
60
  data << new_row # automatically inserts a row into the table due to implicit data-binding
61
61
  @unfiltered_data = data.dup
@@ -100,6 +100,12 @@ class FormTable
100
100
 
101
101
  on_changed do |row, type, row_data|
102
102
  puts "Row #{row} #{type}: #{row_data}"
103
+ $stdout.flush # for Windows
104
+ end
105
+
106
+ on_edited do |row, row_data| # only fires on direct table editing
107
+ puts "Row #{row} edited: #{row_data}"
108
+ $stdout.flush # for Windows
103
109
  end
104
110
  }
105
111
  }
@@ -10,7 +10,7 @@ data = [
10
10
  ['Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA'],
11
11
  ]
12
12
 
13
- window('Contacts', 600, 600) { |w|
13
+ window('Contacts', 600, 600) {
14
14
  margined true
15
15
 
16
16
  vertical_box {
@@ -43,8 +43,8 @@ window('Contacts', 600, 600) { |w|
43
43
 
44
44
  on_clicked do
45
45
  new_row = [@name_entry.text, @email_entry.text, @phone_entry.text, @city_entry.text, @state_entry.text]
46
- if new_row.include?('')
47
- msg_box_error(w, 'Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
46
+ if new_row.map(&:to_s).include?('')
47
+ msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
48
48
  else
49
49
  data << new_row # automatically inserts a row into the table due to implicit data-binding
50
50
  @unfiltered_data = data.dup
@@ -88,6 +88,12 @@ window('Contacts', 600, 600) { |w|
88
88
 
89
89
  on_changed do |row, type, row_data|
90
90
  puts "Row #{row} #{type}: #{row_data}"
91
+ $stdout.flush # for Windows
92
+ end
93
+
94
+ on_edited do |row, row_data| # only fires on direct table editing
95
+ puts "Row #{row} edited: #{row_data}"
96
+ $stdout.flush # for Windows
91
97
  end
92
98
  }
93
99
  }
@@ -180,7 +180,9 @@ class MetaExample
180
180
  }
181
181
  button('Reset') {
182
182
  on_clicked do
183
- self.code_text = File.read(file_path_for(selected_example))
183
+ version_number = @version_spinbox.value == 1 ? '' : @version_spinbox.value
184
+ example = "#{selected_example}#{version_number}"
185
+ self.code_text = File.read(file_path_for(example))
184
186
  end
185
187
  }
186
188
  }
Binary file
data/icons/blank.png ADDED
Binary file
@@ -41,6 +41,7 @@ module Glimmer
41
41
  shine_data_binding
42
42
  property
43
43
  string
44
+ operation
44
45
  control
45
46
  shape
46
47
  ]
@@ -0,0 +1,47 @@
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/dsl/expression'
23
+ require 'glimmer/libui/control_proxy'
24
+ require 'glimmer/libui/shape'
25
+ require 'glimmer/libui/attributed_string'
26
+
27
+ module Glimmer
28
+ module DSL
29
+ module Libui
30
+ class OperationExpression < Expression
31
+ def can_interpret?(parent, keyword, *args, &block)
32
+ (
33
+ parent.is_a?(Glimmer::LibUI::ControlProxy) or
34
+ parent.is_a?(Glimmer::LibUI::Shape) or
35
+ parent.is_a?(Glimmer::LibUI::AttributedString)
36
+ ) and
37
+ block.nil? and
38
+ parent.respond_to?(keyword, *args)
39
+ end
40
+
41
+ def interpret(parent, keyword, *args, &block)
42
+ parent.send(keyword, *args)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -35,11 +35,11 @@ module Glimmer
35
35
  parent.is_a?(Glimmer::LibUI::AttributedString)
36
36
  ) and
37
37
  block.nil? and
38
- parent.respond_to?(keyword, *args)
38
+ parent.respond_to?("#{keyword}=", *args)
39
39
  end
40
40
 
41
41
  def interpret(parent, keyword, *args, &block)
42
- parent.send(keyword, *args)
42
+ parent.send("#{keyword}=", *args)
43
43
  end
44
44
  end
45
45
  end
@@ -22,7 +22,6 @@
22
22
  require 'glimmer/libui/control_proxy'
23
23
  require 'glimmer/libui/control_proxy/area_proxy'
24
24
  require 'glimmer/libui/parent'
25
- require 'glimmer/libui/control_proxy/transformable'
26
25
  require 'glimmer/libui/data_bindable'
27
26
 
28
27
  module Glimmer
@@ -48,7 +47,7 @@ module Glimmer
48
47
  @string
49
48
  else
50
49
  @string = value
51
- redraw
50
+ request_auto_redraw
52
51
  end
53
52
  end
54
53
  alias string= string
@@ -59,7 +58,7 @@ module Glimmer
59
58
  @font
60
59
  else
61
60
  @font = value
62
- redraw
61
+ request_auto_redraw
63
62
  end
64
63
  end
65
64
  alias font= font
@@ -70,7 +69,7 @@ module Glimmer
70
69
  @color
71
70
  else
72
71
  @color = Glimmer::LibUI.interpret_color(value)
73
- redraw
72
+ request_auto_redraw
74
73
  end
75
74
  end
76
75
  alias color= color
@@ -81,7 +80,7 @@ module Glimmer
81
80
  @background
82
81
  else
83
82
  @background = Glimmer::LibUI.interpret_color(value)
84
- redraw
83
+ request_auto_redraw
85
84
  end
86
85
  end
87
86
  alias background= background
@@ -92,7 +91,7 @@ module Glimmer
92
91
  @underline
93
92
  else
94
93
  @underline = value
95
- redraw
94
+ request_auto_redraw
96
95
  end
97
96
  end
98
97
  alias underline= underline
@@ -103,7 +102,7 @@ module Glimmer
103
102
  @underline_color
104
103
  else
105
104
  @underline_color = value
106
- redraw
105
+ request_auto_redraw
107
106
  end
108
107
  end
109
108
  alias underline_color= underline_color
@@ -114,12 +113,21 @@ module Glimmer
114
113
  @open_type_features
115
114
  else
116
115
  @open_type_features = value
117
- redraw
116
+ request_auto_redraw
118
117
  end
119
118
  end
120
119
  alias open_type_features= open_type_features
121
120
  alias set_open_type_features open_type_features
122
121
 
122
+ def remove_open_type_features
123
+ return if @removing_open_type_features
124
+ @removing_open_type_features = true
125
+ @open_type_features&.destroy
126
+ @open_type_features = nil
127
+ request_auto_redraw
128
+ @removing_open_type_features = false
129
+ end
130
+
123
131
  def post_add_content(block = nil)
124
132
  block ||= @block
125
133
  block_result = block&.call
@@ -189,6 +197,7 @@ module Glimmer
189
197
  end
190
198
 
191
199
  def destroy
200
+ return if ControlProxy.main_window_proxy&.destroying?
192
201
  open_type_features.destroy unless open_type_features.nil?
193
202
  @parent_proxy&.children&.delete(self)
194
203
  end
@@ -36,9 +36,9 @@ module Glimmer
36
36
  attr_accessor :current_area_draw_params
37
37
  end
38
38
 
39
- LISTENERS = ['on_draw', 'on_mouse_event', 'on_mouse_move', 'on_mouse_down', 'on_mouse_up', 'on_mouse_drag_start', 'on_mouse_drag', 'on_mouse_drop', 'on_mouse_crossed', 'on_mouse_enter', 'on_mouse_exit', 'on_drag_broken', 'on_key_event', 'on_key_down', 'on_key_up']
39
+ CUSTOM_LISTENER_NAMES = ['on_draw', 'on_mouse_event', 'on_mouse_move', 'on_mouse_down', 'on_mouse_up', 'on_mouse_drag_start', 'on_mouse_drag', 'on_mouse_drop', 'on_mouse_crossed', 'on_mouse_enter', 'on_mouse_exit', 'on_drag_broken', 'on_key_event', 'on_key_down', 'on_key_up']
40
40
 
41
- LISTENER_ALIASES = {
41
+ CUSTOM_LISTENER_NAME_ALIASES = {
42
42
  on_drawn: 'on_draw',
43
43
  on_mouse_moved: 'on_mouse_move',
44
44
  on_mouse_drag_started: 'on_mouse_drag_start',
@@ -105,7 +105,7 @@ module Glimmer
105
105
 
106
106
  def draw(area_draw_params)
107
107
  children.dup.each {|child| child.draw(area_draw_params)}
108
- on_draw.each {|listener| listener.call(area_draw_params)}
108
+ notify_custom_listeners('on_draw', area_draw_params)
109
109
  end
110
110
 
111
111
  def redraw
@@ -156,37 +156,37 @@ module Glimmer
156
156
  @area_handler.MouseEvent = fiddle_closure_block_caller(0, [1, 1, 1]) do |_, _, area_mouse_event|
157
157
  area_mouse_event = ::LibUI::FFI::AreaMouseEvent.new(area_mouse_event)
158
158
  area_mouse_event = area_mouse_event_hash(area_mouse_event)
159
- on_mouse_event.each { |listener| listener.call(area_mouse_event)}
160
- on_mouse_move.each { |listener| listener.call(area_mouse_event)} if area_mouse_event[:x].between?(0, area_mouse_event[:area_width]) && area_mouse_event[:y].between?(0, area_mouse_event[:area_height])
159
+ notify_custom_listeners('on_mouse_event', area_mouse_event)
160
+ notify_custom_listeners('on_mouse_move', area_mouse_event) if area_mouse_event[:x].between?(0, area_mouse_event[:area_width]) && area_mouse_event[:y].between?(0, area_mouse_event[:area_height])
161
161
  unless @last_area_mouse_event.nil?
162
- on_mouse_down.each { |listener| listener.call(area_mouse_event)} if area_mouse_event[:down] > 0 && @last_area_mouse_event[:down] == 0
163
- on_mouse_up.each { |listener| listener.call(area_mouse_event)} if area_mouse_event[:up] > 0 && @last_area_mouse_event[:up] == 0
164
- on_mouse_drag_start.each { |listener| listener.call(area_mouse_event)} if area_mouse_event[:held] > 0 && @last_area_mouse_event[:held] == 0
165
- on_mouse_drag.each { |listener| listener.call(area_mouse_event)} if area_mouse_event[:held] > 0
166
- on_mouse_drop.each { |listener| listener.call(area_mouse_event)} if area_mouse_event[:held] == 0 && @last_area_mouse_event[:held] > 0
162
+ notify_custom_listeners('on_mouse_down', area_mouse_event) if area_mouse_event[:down] > 0 && @last_area_mouse_event[:down] == 0
163
+ notify_custom_listeners('on_mouse_up', area_mouse_event) if area_mouse_event[:up] > 0 && @last_area_mouse_event[:up] == 0
164
+ notify_custom_listeners('on_mouse_drag_start', area_mouse_event) if area_mouse_event[:held] > 0 && @last_area_mouse_event[:held] == 0
165
+ notify_custom_listeners('on_mouse_drag', area_mouse_event) if area_mouse_event[:held] > 0
166
+ notify_custom_listeners('on_mouse_drop', area_mouse_event) if area_mouse_event[:held] == 0 && @last_area_mouse_event[:held] > 0
167
167
  end
168
168
  @last_area_mouse_event = area_mouse_event
169
169
  end
170
170
  @area_handler.MouseCrossed = fiddle_closure_block_caller(0, [1, 1, 4]) do |_, _, left|
171
171
  left = Glimmer::LibUI.integer_to_boolean(left)
172
- on_mouse_crossed.each { |listener| listener.call(left) }
172
+ notify_custom_listeners('on_mouse_crossed', left)
173
173
  if left
174
- on_mouse_exit.each { |listener| listener.call(left) }
174
+ notify_custom_listeners('on_mouse_exit', left)
175
175
  else
176
- on_mouse_enter.each { |listener| listener.call(left) }
176
+ notify_custom_listeners('on_mouse_enter', left)
177
177
  end
178
178
  end
179
179
  @area_handler.DragBroken = fiddle_closure_block_caller(0, [1, 1]) do |_, _|
180
- on_drag_broken.each { |listener| listener.call }
180
+ notify_custom_listeners('on_drag_broken')
181
181
  end
182
182
  @area_handler.KeyEvent = fiddle_closure_block_caller(0, [1, 1, 1]) do |_, _, area_key_event|
183
183
  area_key_event = ::LibUI::FFI::AreaKeyEvent.new(area_key_event)
184
184
  area_key_event = area_key_event_hash(area_key_event)
185
- on_key_event.each { |listener| listener.call(area_key_event) }
185
+ notify_custom_listeners('on_key_event', area_key_event)
186
186
  if area_key_event[:up]
187
- on_key_up.each { |listener| listener.call(area_key_event) }
187
+ notify_custom_listeners('on_key_up', area_key_event)
188
188
  else
189
- on_key_down.each { |listener| listener.call(area_key_event) }
189
+ notify_custom_listeners('on_key_down', area_key_event)
190
190
  end
191
191
  end
192
192
  @listeners_installed = true
@@ -42,6 +42,7 @@ module Glimmer
42
42
  end
43
43
 
44
44
  def destroy_child(child)
45
+ child.deregister_all_custom_listeners
45
46
  ::LibUI.send("box_delete", @libui, children.index(child))
46
47
  ControlProxy.control_proxies.delete(child)
47
48
  end
@@ -30,6 +30,12 @@ module Glimmer
30
30
  #
31
31
  # Follows the Proxy Design Pattern
32
32
  class BackgroundColorColumnProxy < ControlProxy
33
+ class << self
34
+ def default_value
35
+ :white
36
+ end
37
+ end
38
+
33
39
  include Column
34
40
 
35
41
  def name
@@ -31,39 +31,17 @@ module Glimmer
31
31
  #
32
32
  # Follows the Proxy Design Pattern
33
33
  class ButtonColumnProxy < ControlProxy
34
- include Column
35
- include EnableableColumn
36
-
37
- def on_clicked(&block)
38
- # TODO consider generalizing into custom listeners and moving to ControlProxy
39
- @on_clicked_procs ||= []
40
- if block.nil?
41
- @on_clicked_procs
42
- else
43
- @on_clicked_procs << block
44
- block
34
+ class << self
35
+ def default_value
36
+ ''
45
37
  end
46
38
  end
47
39
 
48
- def can_handle_listener?(listener_name)
49
- listener_name == 'on_clicked' || super
50
- end
40
+ include Column
41
+ include EnableableColumn
51
42
 
52
- def handle_listener(listener_name, &listener)
53
- case listener_name
54
- when 'on_clicked'
55
- on_clicked(&listener)
56
- else
57
- super
58
- end
59
- end
43
+ CUSTOM_LISTENER_NAMES = ['on_clicked']
60
44
 
61
- def notify_listeners(listener_name, *args)
62
- @on_clicked_procs&.each do |on_clicked_proc|
63
- on_clicked_proc.call(*args)
64
- end
65
- end
66
-
67
45
  private
68
46
 
69
47
  def build_control
@@ -31,6 +31,12 @@ module Glimmer
31
31
  #
32
32
  # Follows the Proxy Design Pattern
33
33
  class CheckboxColumnProxy < ControlProxy
34
+ class << self
35
+ def default_value
36
+ false
37
+ end
38
+ end
39
+
34
40
  include Column
35
41
  include EditableColumn
36
42
 
@@ -32,6 +32,12 @@ module Glimmer
32
32
  #
33
33
  # Follows the Proxy Design Pattern
34
34
  class CheckboxTextColorColumnProxy < ControlProxy
35
+ class << self
36
+ def default_value
37
+ [false, '', :black]
38
+ end
39
+ end
40
+
35
41
  include Column
36
42
  include TripleColumn
37
43
  include EditableColumn
@@ -32,6 +32,12 @@ module Glimmer
32
32
  #
33
33
  # Follows the Proxy Design Pattern
34
34
  class CheckboxTextColumnProxy < ControlProxy
35
+ class << self
36
+ def default_value
37
+ [false, '']
38
+ end
39
+ end
40
+
35
41
  include Column
36
42
  include DualColumn
37
43
  include EditableColumn
@@ -30,6 +30,12 @@ module Glimmer
30
30
  #
31
31
  # Follows the Proxy Design Pattern
32
32
  class ImageColumnProxy < ControlProxy
33
+ class << self
34
+ def default_value
35
+ Glimmer::LibUI::ICON
36
+ end
37
+ end
38
+
33
39
  include Column
34
40
 
35
41
  private
@@ -32,6 +32,12 @@ module Glimmer
32
32
  #
33
33
  # Follows the Proxy Design Pattern
34
34
  class ImageTextColorColumnProxy < ControlProxy
35
+ class << self
36
+ def default_value
37
+ [Glimmer::LibUI::ICON, '', :black]
38
+ end
39
+ end
40
+
35
41
  include Column
36
42
  include TripleColumn
37
43
  include EditableColumn
@@ -32,6 +32,12 @@ module Glimmer
32
32
  #
33
33
  # Follows the Proxy Design Pattern
34
34
  class ImageTextColumnProxy < ControlProxy
35
+ class << self
36
+ def default_value
37
+ [Glimmer::LibUI::ICON, '']
38
+ end
39
+ end
40
+
35
41
  include Column
36
42
  include DualColumn
37
43
  include EditableColumn
@@ -30,6 +30,12 @@ module Glimmer
30
30
  #
31
31
  # Follows the Proxy Design Pattern
32
32
  class ProgressBarColumnProxy < ControlProxy
33
+ class << self
34
+ def default_value
35
+ 0
36
+ end
37
+ end
38
+
33
39
  include Column
34
40
 
35
41
  private