glimmer-dsl-libui 0.4.11 → 0.4.15

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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -0
  3. data/README.md +473 -57
  4. data/VERSION +1 -1
  5. data/examples/basic_image.rb +5 -3
  6. data/examples/basic_image2.rb +1 -3
  7. data/examples/basic_image3.rb +3 -3
  8. data/examples/basic_image4.rb +0 -3
  9. data/examples/basic_image5.rb +0 -2
  10. data/examples/basic_table_color.rb +104 -26
  11. data/examples/basic_table_color2.rb +2 -14
  12. data/examples/basic_table_color3.rb +37 -0
  13. data/examples/basic_table_image.rb +1 -1
  14. data/examples/basic_table_image2.rb +2 -14
  15. data/examples/basic_table_image3.rb +44 -0
  16. data/examples/basic_table_image_text.rb +1 -2
  17. data/examples/basic_table_image_text2.rb +2 -13
  18. data/examples/basic_table_image_text3.rb +44 -0
  19. data/examples/cpu_percentage.rb +1 -1
  20. data/examples/editable_column_table.rb +5 -0
  21. data/examples/form_table.rb +10 -4
  22. data/examples/form_table2.rb +12 -6
  23. data/examples/form_table3.rb +9 -3
  24. data/examples/form_table4.rb +9 -3
  25. data/examples/form_table5.rb +9 -3
  26. data/examples/meta_example.rb +3 -1
  27. data/glimmer-dsl-libui.gemspec +0 -0
  28. data/lib/glimmer/libui/attributed_string.rb +17 -8
  29. data/lib/glimmer/libui/control_proxy/area_proxy.rb +17 -17
  30. data/lib/glimmer/libui/control_proxy/box.rb +1 -0
  31. data/lib/glimmer/libui/control_proxy/column/background_color_column_proxy.rb +4 -0
  32. data/lib/glimmer/libui/control_proxy/column/button_column_proxy.rb +1 -29
  33. data/lib/glimmer/libui/control_proxy/form_proxy.rb +1 -0
  34. data/lib/glimmer/libui/control_proxy/image_proxy.rb +92 -10
  35. data/lib/glimmer/libui/control_proxy/menu_item_proxy/quit_menu_item_proxy.rb +18 -8
  36. data/lib/glimmer/libui/control_proxy/open_type_features_proxy.rb +11 -2
  37. data/lib/glimmer/libui/control_proxy/open_type_tag_proxy.rb +2 -0
  38. data/lib/glimmer/libui/control_proxy/path_proxy.rb +2 -0
  39. data/lib/glimmer/libui/control_proxy/table_proxy.rb +14 -12
  40. data/lib/glimmer/libui/control_proxy/text_proxy.rb +2 -0
  41. data/lib/glimmer/libui/control_proxy/window_proxy.rb +34 -35
  42. data/lib/glimmer/libui/control_proxy.rb +45 -9
  43. data/lib/glimmer/libui/shape.rb +1 -0
  44. data/lib/glimmer/libui.rb +2 -2
  45. metadata +5 -2
@@ -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
- @on_destroy_procs&.each { |on_destroy_proc| on_destroy_proc.call(self)}
56
+ notify_custom_listeners('on_destroy', self)
57
+ deregister_custom_listeners('on_destroy')
58
+ @destroying = false
50
59
  end
51
60
 
52
- def on_destroy(&block)
53
- # TODO look into a way to generalize this logic for multiple listeners
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 'on_destroy'
79
- on_destroy(&listener)
80
- else
81
- default_behavior_listener = nil
82
- if listener_name == 'on_closing'
83
- default_behavior_listener = Proc.new do
84
- return_value = listener.call(self)
85
- if return_value.is_a?(Numeric)
86
- return_value
87
- else
88
- destroy
89
- ::LibUI.quit
90
- 0
91
- end
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
- super(listener_name, &(default_behavior_listener || listener))
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
- handle_listener('on_closing') do
172
- destroy
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
- ::LibUI.send("#{libui_api_keyword}_#{listener_name}", @libui, &safe_listener)
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
- ::LibUI.send("control_#{listener_name}", @libui, &safe_listener)
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
- custom_listeners.include?(listener_name) || custom_listener_aliases.stringify_keys.keys.include?(listener_name)
200
+ custom_listener_names.include?(listener_name) || custom_listener_name_aliases.stringify_keys.keys.include?(listener_name)
183
201
  end
184
202
 
185
- def custom_listeners
186
- self.class.constants.include?(:LISTENERS) ? self.class::LISTENERS : []
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 custom_listener_aliases
190
- self.class.constants.include?(:LISTENER_ALIASES) ? self.class::LISTENER_ALIASES : {}
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 = custom_listener_aliases.stringify_keys[listener_name] || 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
@@ -116,6 +116,7 @@ module Glimmer
116
116
  end
117
117
 
118
118
  def destroy
119
+ return if ControlProxy.main_window_proxy&.destroying?
119
120
  @parent.children.delete(self)
120
121
  end
121
122
 
data/lib/glimmer/libui.rb CHANGED
@@ -63,7 +63,7 @@ module Glimmer
63
63
  value[:b] = value.delete(:blue) if value[:blue]
64
64
  value[:a] = value.delete(:alpha) if value[:alpha]
65
65
  value
66
- elsif value.is_a?(String) && !value.start_with?('0x') && !value.downcase.match(/^((([1-9a-f]){6})|(([1-9a-f]){3}))$/)
66
+ elsif value.is_a?(String) && !value.start_with?('0x') && !value.start_with?('#') && !value.downcase.match(/^((([1-9a-f]){6})|(([1-9a-f]){3}))$/)
67
67
  color = Color::RGB.extract_colors(value).first
68
68
  color.nil? ? {} : {
69
69
  r: color.red,
@@ -79,11 +79,11 @@ module Glimmer
79
79
 
80
80
  def hex_to_rgb(value)
81
81
  if value.is_a?(String)
82
+ value = "0x#{value[1..-1]}" if value.start_with?('#')
82
83
  if !value.start_with?('0x')
83
84
  value = value.chars.map {|char| [char, char]}.flatten.join if value.length == 3
84
85
  value = "0x#{value}"
85
86
  end
86
- value = "0x#{value[1..-1]}" if value.start_with?('#')
87
87
  value = value.to_i(16)
88
88
  end
89
89
  if value.is_a?(Integer)
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.11
4
+ version: 0.4.15
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-12-01 00:00:00.000000000 Z
11
+ date: 2021-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer
@@ -237,10 +237,13 @@ files:
237
237
  - examples/basic_table_checkbox_text.rb
238
238
  - examples/basic_table_color.rb
239
239
  - examples/basic_table_color2.rb
240
+ - examples/basic_table_color3.rb
240
241
  - examples/basic_table_image.rb
241
242
  - examples/basic_table_image2.rb
243
+ - examples/basic_table_image3.rb
242
244
  - examples/basic_table_image_text.rb
243
245
  - examples/basic_table_image_text2.rb
246
+ - examples/basic_table_image_text3.rb
244
247
  - examples/basic_table_progress_bar.rb
245
248
  - examples/basic_transform.rb
246
249
  - examples/basic_transform2.rb