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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -0
- data/README.md +170 -60
- data/VERSION +1 -1
- data/bin/girb +0 -0
- data/examples/basic_table.rb +1 -1
- data/examples/basic_table_button.rb +0 -1
- data/examples/cpu_percentage.rb +1 -1
- data/examples/custom_draw_text.rb +14 -7
- data/examples/custom_draw_text2.rb +15 -8
- data/examples/editable_column_table.rb +5 -0
- data/examples/form_table.rb +9 -3
- data/examples/form_table2.rb +12 -6
- data/examples/form_table3.rb +9 -3
- data/examples/form_table4.rb +9 -3
- data/examples/form_table5.rb +9 -3
- data/examples/meta_example.rb +3 -1
- data/glimmer-dsl-libui.gemspec +0 -0
- data/icons/blank.png +0 -0
- data/lib/glimmer/dsl/libui/dsl.rb +1 -0
- data/lib/glimmer/dsl/libui/operation_expression.rb +47 -0
- data/lib/glimmer/dsl/libui/property_expression.rb +2 -2
- data/lib/glimmer/libui/attributed_string.rb +17 -8
- data/lib/glimmer/libui/control_proxy/area_proxy.rb +17 -17
- data/lib/glimmer/libui/control_proxy/box.rb +1 -0
- data/lib/glimmer/libui/control_proxy/column/background_color_column_proxy.rb +6 -0
- data/lib/glimmer/libui/control_proxy/column/button_column_proxy.rb +6 -28
- data/lib/glimmer/libui/control_proxy/column/checkbox_column_proxy.rb +6 -0
- data/lib/glimmer/libui/control_proxy/column/checkbox_text_color_column_proxy.rb +6 -0
- data/lib/glimmer/libui/control_proxy/column/checkbox_text_column_proxy.rb +6 -0
- data/lib/glimmer/libui/control_proxy/column/image_column_proxy.rb +6 -0
- data/lib/glimmer/libui/control_proxy/column/image_text_color_column_proxy.rb +6 -0
- data/lib/glimmer/libui/control_proxy/column/image_text_column_proxy.rb +6 -0
- data/lib/glimmer/libui/control_proxy/column/progress_bar_column_proxy.rb +6 -0
- data/lib/glimmer/libui/control_proxy/column/text_color_column_proxy.rb +6 -0
- data/lib/glimmer/libui/control_proxy/column/text_column_proxy.rb +6 -0
- data/lib/glimmer/libui/control_proxy/column.rb +7 -0
- data/lib/glimmer/libui/control_proxy/form_proxy.rb +1 -0
- data/lib/glimmer/libui/control_proxy/image_proxy.rb +3 -0
- data/lib/glimmer/libui/control_proxy/menu_item_proxy/quit_menu_item_proxy.rb +18 -9
- data/lib/glimmer/libui/control_proxy/open_type_features_proxy.rb +11 -2
- data/lib/glimmer/libui/control_proxy/open_type_tag_proxy.rb +2 -0
- data/lib/glimmer/libui/control_proxy/path_proxy.rb +8 -4
- data/lib/glimmer/libui/control_proxy/table_proxy.rb +59 -34
- data/lib/glimmer/libui/control_proxy/text_proxy.rb +2 -0
- data/lib/glimmer/libui/control_proxy/window_proxy.rb +34 -35
- data/lib/glimmer/libui/control_proxy.rb +45 -9
- data/lib/glimmer/libui/data_bindable.rb +1 -1
- data/lib/glimmer/libui/shape.rb +1 -0
- data/lib/glimmer/libui.rb +1 -0
- data/lib/glimmer-dsl-libui.rb +6 -0
- metadata +21 -5
@@ -24,6 +24,13 @@ module Glimmer
|
|
24
24
|
class ControlProxy
|
25
25
|
# Common logic for all column proxy objects
|
26
26
|
module Column
|
27
|
+
class << self
|
28
|
+
# subclasses may override to provide a valid default value like a blank image for image columns and false for checkbox
|
29
|
+
def default_value
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
27
34
|
def initialize(keyword, parent, args, &block)
|
28
35
|
@keyword = keyword
|
29
36
|
@parent_proxy = parent
|
@@ -52,6 +52,7 @@ module Glimmer
|
|
52
52
|
|
53
53
|
include Parent
|
54
54
|
prepend Transformable
|
55
|
+
include Equalizer.new(:options, :data)
|
55
56
|
|
56
57
|
attr_reader :data, :pixels, :shapes, :options
|
57
58
|
|
@@ -179,6 +180,8 @@ module Glimmer
|
|
179
180
|
end
|
180
181
|
|
181
182
|
def destroy
|
183
|
+
return if ControlProxy.main_window_proxy&.destroying?
|
184
|
+
deregister_all_custom_listeners
|
182
185
|
@parent_proxy&.children&.delete(self)
|
183
186
|
ControlProxy.control_proxies.delete(self)
|
184
187
|
end
|
@@ -35,29 +35,38 @@ module Glimmer
|
|
35
35
|
|
36
36
|
def handle_listener(listener_name, &listener)
|
37
37
|
if listener_name == 'on_clicked'
|
38
|
-
@
|
39
|
-
|
38
|
+
@on_clicked_listeners ||= []
|
39
|
+
@on_clicked_listeners << listener
|
40
|
+
@default_behavior_listener ||= Proc.new do
|
41
|
+
return_value = nil
|
42
|
+
@on_clicked_listeners.each do |l|
|
43
|
+
return_value = l.call(self)
|
44
|
+
break if return_value.is_a?(Numeric)
|
45
|
+
end
|
40
46
|
if return_value.is_a?(Numeric)
|
41
47
|
return_value
|
42
48
|
else
|
43
|
-
destroy
|
49
|
+
ControlProxy.main_window_proxy&.destroy
|
44
50
|
::LibUI.quit
|
45
51
|
0
|
46
52
|
end
|
53
|
+
end.tap do |default_behavior_listener|
|
54
|
+
::LibUI.on_should_quit(&default_behavior_listener)
|
47
55
|
end
|
48
|
-
::LibUI.on_should_quit(&@default_behavior_listener)
|
49
56
|
end
|
50
57
|
end
|
58
|
+
|
59
|
+
def destroy
|
60
|
+
@on_clicked_listeners&.clear
|
61
|
+
super
|
62
|
+
end
|
51
63
|
|
52
64
|
private
|
53
65
|
|
54
66
|
def build_control
|
55
67
|
@libui = @parent_proxy.append_quit_item(*@args)
|
56
|
-
|
57
|
-
|
58
|
-
::LibUI.quit
|
59
|
-
0
|
60
|
-
end
|
68
|
+
# setup default on_clicked listener if no on_clicked listeners are setup
|
69
|
+
handle_listener('on_clicked') {} if @on_clicked_listeners.nil? || @on_clicked_listeners.empty?
|
61
70
|
end
|
62
71
|
end
|
63
72
|
end
|
@@ -33,15 +33,24 @@ module Glimmer
|
|
33
33
|
include Parent
|
34
34
|
|
35
35
|
def destroy
|
36
|
+
return if ControlProxy.main_window_proxy&.destroying?
|
37
|
+
return if @destroying
|
38
|
+
@destroying = true
|
39
|
+
deregister_all_custom_listeners
|
36
40
|
::LibUI.free_open_type_features(@libui)
|
37
|
-
@parent_proxy&.
|
41
|
+
@parent_proxy&.remove_open_type_features
|
38
42
|
ControlProxy.control_proxies.delete(self)
|
43
|
+
@destroying = false
|
39
44
|
end
|
40
45
|
|
41
46
|
def redraw
|
42
|
-
@parent_proxy
|
47
|
+
@parent_proxy&.redraw
|
43
48
|
end
|
44
49
|
|
50
|
+
def request_auto_redraw
|
51
|
+
@parent_proxy&.request_auto_redraw
|
52
|
+
end
|
53
|
+
|
45
54
|
private
|
46
55
|
|
47
56
|
def build_control
|
@@ -31,6 +31,8 @@ module Glimmer
|
|
31
31
|
# Follows the Proxy Design Pattern
|
32
32
|
class OpenTypeTagProxy < ControlProxy
|
33
33
|
def destroy
|
34
|
+
return if ControlProxy.main_window_proxy&.destroying?
|
35
|
+
deregister_all_custom_listeners
|
34
36
|
@parent_proxy&.children&.delete(self)
|
35
37
|
ControlProxy.control_proxies.delete(self)
|
36
38
|
end
|
@@ -70,7 +70,8 @@ module Glimmer
|
|
70
70
|
else
|
71
71
|
new_color = Glimmer::LibUI.interpret_color(args)
|
72
72
|
if new_color != @fill
|
73
|
-
|
73
|
+
# TODO consider replacing unobserve with observer_registration.deregister
|
74
|
+
@fill_observer&.unobserve(@fill, attribute_writer_type: [:attribute=, :set_attribute]) if @fill
|
74
75
|
@fill = new_color
|
75
76
|
request_auto_redraw
|
76
77
|
end
|
@@ -79,7 +80,7 @@ module Glimmer
|
|
79
80
|
@fill_observer ||= Glimmer::DataBinding::Observer.proc do
|
80
81
|
request_auto_redraw
|
81
82
|
end
|
82
|
-
@fill_observer.observe(@fill)
|
83
|
+
@fill_observer.observe(@fill, attribute_writer_type: [:attribute=, :set_attribute])
|
83
84
|
end
|
84
85
|
end
|
85
86
|
alias fill= fill
|
@@ -98,7 +99,8 @@ module Glimmer
|
|
98
99
|
else
|
99
100
|
new_color = Glimmer::LibUI.interpret_color(args)
|
100
101
|
if new_color != @stroke
|
101
|
-
|
102
|
+
# TODO consider replacing unobserve with observer_registration.deregister
|
103
|
+
@stroke_observer&.unobserve(@stroke, attribute_writer_type: [:attribute=, :set_attribute]) if @stroke
|
102
104
|
@stroke = Glimmer::LibUI.interpret_color(args)
|
103
105
|
request_auto_redraw
|
104
106
|
end
|
@@ -107,7 +109,7 @@ module Glimmer
|
|
107
109
|
@stroke_observer ||= Glimmer::DataBinding::Observer.proc do
|
108
110
|
request_auto_redraw
|
109
111
|
end
|
110
|
-
@stroke_observer.observe(@stroke)
|
112
|
+
@stroke_observer.observe(@stroke, attribute_writer_type: [:attribute=, :set_attribute])
|
111
113
|
end
|
112
114
|
end
|
113
115
|
alias stroke= stroke
|
@@ -140,6 +142,8 @@ module Glimmer
|
|
140
142
|
end
|
141
143
|
|
142
144
|
def destroy
|
145
|
+
return if ControlProxy.main_window_proxy&.destroying?
|
146
|
+
deregister_all_custom_listeners
|
143
147
|
@parent_proxy&.children&.delete(self)
|
144
148
|
ControlProxy.control_proxies.delete(self)
|
145
149
|
end
|
@@ -36,7 +36,7 @@ module Glimmer
|
|
36
36
|
class TableProxy < ControlProxy
|
37
37
|
include Glimmer::FiddleConsumer
|
38
38
|
|
39
|
-
|
39
|
+
CUSTOM_LISTENER_NAMES = ['on_changed', 'on_edited']
|
40
40
|
|
41
41
|
attr_reader :model_handler, :model, :table_params, :columns, :column_attributes
|
42
42
|
|
@@ -48,6 +48,8 @@ module Glimmer
|
|
48
48
|
@enabled = true
|
49
49
|
@columns = []
|
50
50
|
@cell_rows = []
|
51
|
+
@last_cell_rows = []
|
52
|
+
register_cell_rows_observer
|
51
53
|
window_proxy.on_destroy do
|
52
54
|
# the following unless condition is an exceptional condition stumbled upon that fails freeing the table model
|
53
55
|
::LibUI.free_table_model(@model) unless @destroyed && parent_proxy.is_a?(Box)
|
@@ -75,7 +77,8 @@ module Glimmer
|
|
75
77
|
|
76
78
|
def destroy
|
77
79
|
super
|
78
|
-
|
80
|
+
# TODO consider replacing unobserve with observer_registration.deregister
|
81
|
+
@cell_rows_observer&.unobserve(self, :cell_rows, recursive: true, ignore_frozen: true, attribute_writer_type: [:attribute=, :set_attribute])
|
79
82
|
@destroyed = true
|
80
83
|
end
|
81
84
|
|
@@ -86,31 +89,6 @@ module Glimmer
|
|
86
89
|
if rows != @cell_rows
|
87
90
|
@cell_rows = rows
|
88
91
|
@cell_rows = @cell_rows.to_a if @cell_rows.is_a?(Enumerator)
|
89
|
-
@last_cell_rows ||= array_deep_clone(@cell_rows)
|
90
|
-
@cell_rows_observer ||= Glimmer::DataBinding::Observer.proc do |new_cell_rows|
|
91
|
-
if @cell_rows.size < @last_cell_rows.size && @last_cell_rows.include_all?(*@cell_rows)
|
92
|
-
@last_cell_rows.array_diff_indexes(@cell_rows).reverse.each do |row|
|
93
|
-
::LibUI.table_model_row_deleted(model, row)
|
94
|
-
on_changed.each {|listener| listener.call(row, :deleted, @last_cell_rows[row])}
|
95
|
-
end
|
96
|
-
elsif @cell_rows.size > @last_cell_rows.size && @cell_rows.include_all?(*@last_cell_rows)
|
97
|
-
@cell_rows.array_diff_indexes(@last_cell_rows).each do |row|
|
98
|
-
::LibUI.table_model_row_inserted(model, row)
|
99
|
-
on_changed.each {|listener| listener.call(row, :inserted, @cell_rows[row])}
|
100
|
-
end
|
101
|
-
else
|
102
|
-
@cell_rows.each_with_index do |new_row_data, row|
|
103
|
-
if new_row_data != @last_cell_rows[row]
|
104
|
-
::LibUI.table_model_row_changed(model, row)
|
105
|
-
on_changed.each {|listener| listener.call(row, :changed, @cell_rows[row])}
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
@last_last_cell_rows = array_deep_clone(@last_cell_rows)
|
110
|
-
@last_cell_rows = array_deep_clone(@cell_rows)
|
111
|
-
end.tap do |cell_rows_observer|
|
112
|
-
cell_rows_observer.observe(self, :cell_rows, recursive: true)
|
113
|
-
end
|
114
92
|
end
|
115
93
|
@cell_rows
|
116
94
|
end
|
@@ -153,13 +131,13 @@ module Glimmer
|
|
153
131
|
new_value = new_value.to_a if new_value.is_a?(Enumerator)
|
154
132
|
if model_binding.binding_options[:column_attributes] || (!new_value.empty? && !new_value.first.is_a?(Array))
|
155
133
|
@model_attribute_array_observer_registration&.deregister
|
156
|
-
@model_attribute_array_observer_registration = model_attribute_observer.observe(new_value, @column_attributes)
|
134
|
+
@model_attribute_array_observer_registration = model_attribute_observer.observe(new_value, @column_attributes, ignore_frozen: true, attribute_writer_type: [:attribute=, :set_attribute])
|
157
135
|
model_attribute_observer.add_dependent(model_attribute_observer_registration => @model_attribute_array_observer_registration)
|
158
136
|
end
|
159
137
|
# TODO look if multiple notifications are happening as a result of observing array and observing model binding
|
160
138
|
send("#{property}=", new_value) unless @last_cell_rows == new_value
|
161
139
|
end
|
162
|
-
model_attribute_observer_registration = model_attribute_observer.observe(model_binding)
|
140
|
+
model_attribute_observer_registration = model_attribute_observer.observe(model_binding, attribute_writer_type: [:attribute=, :set_attribute])
|
163
141
|
model_attribute_observer.call # initial update
|
164
142
|
data_binding_model_attribute_observer_registrations << model_attribute_observer_registration
|
165
143
|
model_attribute_observer
|
@@ -208,9 +186,11 @@ module Glimmer
|
|
208
186
|
when Column::TextColumnProxy, Column::ButtonColumnProxy, Column::TextColorColumnProxy, :text
|
209
187
|
::LibUI.new_table_value_string((expanded_cell_rows[row] && expanded_cell_rows[row][column]).to_s)
|
210
188
|
when Column::ImageColumnProxy, Column::ImageTextColumnProxy, Column::ImageTextColorColumnProxy
|
211
|
-
|
212
|
-
|
213
|
-
|
189
|
+
if OS.windows? && row == cell_rows.count
|
190
|
+
img = Glimmer::LibUI::ICON
|
191
|
+
else
|
192
|
+
img = expanded_cell_rows[row][column]
|
193
|
+
end
|
214
194
|
img = ControlProxy::ImageProxy.create('image', nil, img) if img.is_a?(Array)
|
215
195
|
img = ControlProxy::ImageProxy.create('image', nil, [img]) if img.is_a?(String)
|
216
196
|
img = img.respond_to?(:libui) ? img.libui : img
|
@@ -270,7 +250,7 @@ module Glimmer
|
|
270
250
|
@cell_rows[row].send(attribute)[1] = ::LibUI.table_value_string(val).to_s
|
271
251
|
end
|
272
252
|
when Column::ButtonColumnProxy
|
273
|
-
@columns[column].
|
253
|
+
@columns[column].notify_custom_listeners('on_clicked', row)
|
274
254
|
when Column::CheckboxColumnProxy
|
275
255
|
column = @columns[column].index
|
276
256
|
@cell_rows[row] ||= []
|
@@ -292,7 +272,7 @@ module Glimmer
|
|
292
272
|
@cell_rows[row].send(attribute)[0] = ::LibUI.table_value_int(val).to_i == 1
|
293
273
|
end
|
294
274
|
end
|
295
|
-
on_edited
|
275
|
+
notify_custom_listeners('on_edited', row, @cell_rows[row])
|
296
276
|
end
|
297
277
|
|
298
278
|
@model = ::LibUI.new_table_model(@model_handler)
|
@@ -308,12 +288,57 @@ module Glimmer
|
|
308
288
|
@libui.tap do
|
309
289
|
@columns.each {|column| column.respond_to?(:build_control, true) && column.send(:build_control) }
|
310
290
|
end
|
291
|
+
|
292
|
+
if !@applied_windows_fix && OS.windows?
|
293
|
+
@applied_windows_fix = true
|
294
|
+
apply_windows_fix
|
295
|
+
end
|
311
296
|
end
|
312
297
|
|
313
298
|
def next_column_index
|
314
299
|
@next_column_index ||= -1
|
315
300
|
@next_column_index += 1
|
316
301
|
end
|
302
|
+
|
303
|
+
def register_cell_rows_observer
|
304
|
+
@cell_rows_observer = Glimmer::DataBinding::Observer.proc do |new_cell_rows|
|
305
|
+
if @cell_rows.size < @last_cell_rows.size && @last_cell_rows.include_all?(*@cell_rows)
|
306
|
+
@last_cell_rows.array_diff_indexes(@cell_rows).reverse.each do |row|
|
307
|
+
::LibUI.table_model_row_deleted(model, row) if model && row
|
308
|
+
notify_custom_listeners('on_changed', row, :deleted, @last_cell_rows[row])
|
309
|
+
end
|
310
|
+
elsif @cell_rows.size > @last_cell_rows.size && @cell_rows.include_all?(*@last_cell_rows)
|
311
|
+
@cell_rows.array_diff_indexes(@last_cell_rows).each do |row|
|
312
|
+
::LibUI.table_model_row_inserted(model, row) if model && row
|
313
|
+
notify_custom_listeners('on_changed', row, :inserted, @cell_rows[row])
|
314
|
+
end
|
315
|
+
else
|
316
|
+
@cell_rows.each_with_index do |new_row_data, row|
|
317
|
+
if new_row_data != @last_cell_rows[row]
|
318
|
+
::LibUI.table_model_row_changed(model, row) if model && row
|
319
|
+
notify_custom_listeners('on_changed', row, :changed, @cell_rows[row])
|
320
|
+
end
|
321
|
+
end
|
322
|
+
end
|
323
|
+
@last_last_cell_rows = array_deep_clone(@last_cell_rows)
|
324
|
+
@last_cell_rows = array_deep_clone(@cell_rows)
|
325
|
+
if !@applied_windows_fix_on_first_cell_rows_update && OS.windows?
|
326
|
+
@applied_windows_fix_on_first_cell_rows_update = true
|
327
|
+
apply_windows_fix
|
328
|
+
end
|
329
|
+
end
|
330
|
+
@cell_rows_observer_registration = @cell_rows_observer.observe(self, :cell_rows, recursive: true, ignore_frozen: true, attribute_writer_type: [:attribute=, :set_attribute])
|
331
|
+
end
|
332
|
+
|
333
|
+
def apply_windows_fix
|
334
|
+
Glimmer::LibUI.queue_main do
|
335
|
+
new_row = @columns&.select {|column| column.is_a?(Column)}&.map {|column| column.class.default_value}
|
336
|
+
if new_row
|
337
|
+
@cell_rows << new_row
|
338
|
+
@cell_rows.pop
|
339
|
+
end
|
340
|
+
end
|
341
|
+
end
|
317
342
|
end
|
318
343
|
end
|
319
344
|
end
|
@@ -29,6 +29,10 @@ module Glimmer
|
|
29
29
|
#
|
30
30
|
# Follows the Proxy Design Pattern
|
31
31
|
class WindowProxy < ControlProxy
|
32
|
+
CUSTOM_LISTENER_NAMES = ['on_destroy']
|
33
|
+
CUSTOM_LISTENER_NAME_ALIASES = {
|
34
|
+
on_destroyed: 'on_destroy',
|
35
|
+
}
|
32
36
|
DEFAULT_TITLE = ''
|
33
37
|
DEFAULT_WIDTH = 190
|
34
38
|
DEFAULT_HEIGHT = 150
|
@@ -44,22 +48,20 @@ module Glimmer
|
|
44
48
|
end
|
45
49
|
|
46
50
|
def destroy
|
51
|
+
return if @destroying
|
52
|
+
@destroying = true
|
53
|
+
@on_closing_listeners&.clear
|
47
54
|
super
|
48
55
|
ControlProxy.image_proxies.each { |image_proxy| ::LibUI.free_image(image_proxy.libui) unless image_proxy.area_image? }
|
49
|
-
|
56
|
+
notify_custom_listeners('on_destroy', self)
|
57
|
+
deregister_custom_listeners('on_destroy')
|
58
|
+
@destroying = false
|
50
59
|
end
|
51
60
|
|
52
|
-
def
|
53
|
-
|
54
|
-
@on_destroy_procs ||= []
|
55
|
-
if block.nil?
|
56
|
-
@on_destroy_procs
|
57
|
-
else
|
58
|
-
@on_destroy_procs << block
|
59
|
-
block
|
60
|
-
end
|
61
|
+
def destroying?
|
62
|
+
@destroying
|
61
63
|
end
|
62
|
-
|
64
|
+
|
63
65
|
def show
|
64
66
|
super
|
65
67
|
unless @shown_at_least_once
|
@@ -69,29 +71,29 @@ module Glimmer
|
|
69
71
|
end
|
70
72
|
end
|
71
73
|
|
72
|
-
def can_handle_listener?(listener_name)
|
73
|
-
listener_name == 'on_destroy' || super
|
74
|
-
end
|
75
|
-
|
76
74
|
def handle_listener(listener_name, &listener)
|
77
75
|
case listener_name
|
78
|
-
when '
|
79
|
-
|
80
|
-
|
81
|
-
default_behavior_listener
|
82
|
-
|
83
|
-
|
84
|
-
return_value =
|
85
|
-
if return_value.is_a?(Numeric)
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
76
|
+
when 'on_closing'
|
77
|
+
@on_closing_listeners ||= []
|
78
|
+
@on_closing_listeners << listener
|
79
|
+
@default_behavior_listener ||= Proc.new do
|
80
|
+
return_value = nil
|
81
|
+
@on_closing_listeners.each do |l|
|
82
|
+
return_value = l.call(self)
|
83
|
+
break if return_value.is_a?(Numeric)
|
84
|
+
end
|
85
|
+
if return_value.is_a?(Numeric)
|
86
|
+
return_value
|
87
|
+
else
|
88
|
+
destroy
|
89
|
+
::LibUI.quit
|
90
|
+
0
|
92
91
|
end
|
92
|
+
end.tap do |default_behavior_listener|
|
93
|
+
super(listener_name, &default_behavior_listener)
|
93
94
|
end
|
94
|
-
|
95
|
+
else
|
96
|
+
super
|
95
97
|
end
|
96
98
|
end
|
97
99
|
|
@@ -168,11 +170,8 @@ module Glimmer
|
|
168
170
|
@height = construction_args[2]
|
169
171
|
@libui = ControlProxy.new_control(@keyword, construction_args)
|
170
172
|
@libui.tap do
|
171
|
-
|
172
|
-
|
173
|
-
::LibUI.quit
|
174
|
-
0
|
175
|
-
end
|
173
|
+
# setup default on_closing listener if no on_closing listeners are setup
|
174
|
+
handle_listener('on_closing') {} if @on_closing_listeners.nil? || @on_closing_listeners.empty?
|
176
175
|
end
|
177
176
|
end
|
178
177
|
end
|
@@ -169,31 +169,49 @@ module Glimmer
|
|
169
169
|
def handle_listener(listener_name, &listener)
|
170
170
|
safe_listener = Proc.new { listener.call(self) }
|
171
171
|
if ::LibUI.respond_to?("#{libui_api_keyword}_#{listener_name}")
|
172
|
-
|
172
|
+
if listeners[listener_name].nil?
|
173
|
+
::LibUI.send("#{libui_api_keyword}_#{listener_name}", @libui) do
|
174
|
+
listeners_for(listener_name).map { |listener| listener.call }.last
|
175
|
+
end
|
176
|
+
end
|
177
|
+
listeners_for(listener_name) << safe_listener
|
173
178
|
elsif ::LibUI.respond_to?("control_#{listener_name}")
|
174
|
-
|
179
|
+
if listeners[listener_name].nil?
|
180
|
+
::LibUI.send("control_#{listener_name}", @libui) do
|
181
|
+
listeners_for(listener_name).map { |listener| listener.call }.last
|
182
|
+
end
|
183
|
+
end
|
184
|
+
listeners_for(listener_name) << safe_listener
|
175
185
|
elsif has_custom_listener?(listener_name)
|
176
186
|
handle_custom_listener(listener_name, &listener)
|
177
187
|
end
|
178
188
|
end
|
179
189
|
|
190
|
+
def listeners
|
191
|
+
@listeners ||= {}
|
192
|
+
end
|
193
|
+
|
194
|
+
def listeners_for(listener_name)
|
195
|
+
listeners[listener_name] ||= []
|
196
|
+
end
|
197
|
+
|
180
198
|
def has_custom_listener?(listener_name)
|
181
199
|
listener_name = listener_name.to_s
|
182
|
-
|
200
|
+
custom_listener_names.include?(listener_name) || custom_listener_name_aliases.stringify_keys.keys.include?(listener_name)
|
183
201
|
end
|
184
202
|
|
185
|
-
def
|
186
|
-
self.class.constants.include?(:
|
203
|
+
def custom_listener_names
|
204
|
+
self.class.constants.include?(:CUSTOM_LISTENER_NAMES) ? self.class::CUSTOM_LISTENER_NAMES : []
|
187
205
|
end
|
188
206
|
|
189
|
-
def
|
190
|
-
self.class.constants.include?(:
|
207
|
+
def custom_listener_name_aliases
|
208
|
+
self.class.constants.include?(:CUSTOM_LISTENER_NAME_ALIASES) ? self.class::CUSTOM_LISTENER_NAME_ALIASES : {}
|
191
209
|
end
|
192
210
|
|
193
211
|
def handle_custom_listener(listener_name, &listener)
|
194
212
|
listener_name = listener_name.to_s
|
195
|
-
listener_name =
|
196
|
-
instance_variable_name = "@#{listener_name}_procs"
|
213
|
+
listener_name = custom_listener_name_aliases.stringify_keys[listener_name] || listener_name
|
214
|
+
instance_variable_name = "@#{listener_name}_procs" # TODO ensure clearing custom listeners on destroy of a control
|
197
215
|
instance_variable_set(instance_variable_name, []) if instance_variable_get(instance_variable_name).nil?
|
198
216
|
if listener.nil?
|
199
217
|
instance_variable_get(instance_variable_name)
|
@@ -203,6 +221,21 @@ module Glimmer
|
|
203
221
|
end
|
204
222
|
end
|
205
223
|
|
224
|
+
def notify_custom_listeners(listener_name, *args)
|
225
|
+
handle_custom_listener(listener_name).each do |listener|
|
226
|
+
listener.call(*args)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def deregister_custom_listeners(listener_name)
|
231
|
+
handle_custom_listener(listener_name).clear
|
232
|
+
end
|
233
|
+
|
234
|
+
# deregisters all custom listeners except on_destroy, which can only be deregistered after destruction of a control, using deregister_custom_listeners
|
235
|
+
def deregister_all_custom_listeners
|
236
|
+
(custom_listener_names - ['on_destroy']).each { |listener_name| deregister_custom_listeners(listener_name) }
|
237
|
+
end
|
238
|
+
|
206
239
|
def respond_to?(method_name, *args, &block)
|
207
240
|
respond_to_libui?(method_name, *args, &block) ||
|
208
241
|
(
|
@@ -289,6 +322,8 @@ module Glimmer
|
|
289
322
|
end
|
290
323
|
|
291
324
|
def destroy
|
325
|
+
# TODO exclude menus from this initial return
|
326
|
+
return if !is_a?(ControlProxy::WindowProxy) && ControlProxy.main_window_proxy&.destroying?
|
292
327
|
data_binding_model_attribute_observer_registrations.each(&:deregister)
|
293
328
|
if parent_proxy.nil?
|
294
329
|
default_destroy
|
@@ -302,6 +337,7 @@ module Glimmer
|
|
302
337
|
end
|
303
338
|
|
304
339
|
def default_destroy
|
340
|
+
deregister_all_custom_listeners
|
305
341
|
send_to_libui('destroy')
|
306
342
|
ControlProxy.control_proxies.delete(self)
|
307
343
|
end
|
@@ -46,7 +46,7 @@ module Glimmer
|
|
46
46
|
new_value = model_binding.evaluate_property
|
47
47
|
send("#{property}=", new_value) unless send(property) == new_value
|
48
48
|
end
|
49
|
-
observer_registration = model_attribute_observer.observe(model_binding)
|
49
|
+
observer_registration = model_attribute_observer.observe(model_binding, attribute_writer_type: [:attribute=, :set_attribute])
|
50
50
|
model_attribute_observer.call # initial update
|
51
51
|
data_binding_model_attribute_observer_registrations << observer_registration
|
52
52
|
observer_registration
|
data/lib/glimmer/libui/shape.rb
CHANGED
data/lib/glimmer/libui.rb
CHANGED
data/lib/glimmer-dsl-libui.rb
CHANGED
@@ -28,6 +28,7 @@ require 'glimmer'
|
|
28
28
|
# require 'super_module'
|
29
29
|
require 'color'
|
30
30
|
require 'os'
|
31
|
+
require 'equalizer'
|
31
32
|
require 'array_include_methods'
|
32
33
|
require 'facets/hash/stringify_keys'
|
33
34
|
require 'facets/string/underscore'
|
@@ -46,3 +47,8 @@ Glimmer::Config.excluded_keyword_checkers << lambda do |method_symbol, *args|
|
|
46
47
|
end
|
47
48
|
|
48
49
|
::LibUI.init
|
50
|
+
# begin
|
51
|
+
# PutsDebuggerer.printer = lambda { |m| puts m; $stdout.flush}
|
52
|
+
# rescue
|
53
|
+
##### No Op if puts_debuggerer is not loaded
|
54
|
+
# end
|