glimmer-dsl-opal 0.7.1 → 0.8.0

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +45 -0
  3. data/README.md +453 -48
  4. data/VERSION +1 -1
  5. data/lib/display.rb +31 -0
  6. data/lib/glimmer-dsl-opal.rb +15 -36
  7. data/lib/glimmer-dsl-opal/ext/class.rb +10 -0
  8. data/lib/glimmer-dsl-opal/ext/file.rb +29 -0
  9. data/lib/glimmer-dsl-opal/ext/struct.rb +37 -0
  10. data/lib/glimmer-dsl-opal/samples/elaborate/contact_manager.rb +50 -23
  11. data/lib/glimmer-dsl-opal/samples/elaborate/login.rb +22 -5
  12. data/lib/glimmer-dsl-opal/samples/hello/hello_browser.rb +24 -1
  13. data/lib/glimmer-dsl-opal/samples/hello/hello_button.rb +46 -0
  14. data/lib/glimmer-dsl-opal/samples/hello/hello_computed.rb +27 -0
  15. data/lib/glimmer-dsl-opal/samples/hello/hello_custom_shell.rb +7 -7
  16. data/lib/glimmer-dsl-opal/samples/hello/hello_list_multi_selection.rb +62 -32
  17. data/lib/glimmer-dsl-opal/samples/hello/hello_list_single_selection.rb +47 -22
  18. data/lib/glimmer-dsl-opal/samples/hello/hello_message_box.rb +37 -0
  19. data/lib/glimmer-dsl-opal/samples/hello/hello_pop_up_context_menu.rb +84 -0
  20. data/lib/glimmer-dsl-opal/samples/hello/hello_table.rb +2 -2
  21. data/lib/glimmer/data_binding/observable_element.rb +1 -1
  22. data/lib/glimmer/data_binding/table_items_binding.rb +3 -3
  23. data/lib/glimmer/dsl/opal/custom_widget_expression.rb +6 -0
  24. data/lib/glimmer/dsl/opal/dsl.rb +2 -0
  25. data/lib/glimmer/dsl/opal/menu_bar_expression.rb +54 -0
  26. data/lib/glimmer/dsl/opal/menu_expression.rb +61 -0
  27. data/lib/glimmer/dsl/opal/widget_expression.rb +3 -2
  28. data/lib/glimmer/dsl/opal/widget_listener_expression.rb +2 -2
  29. data/lib/glimmer/swt/combo_proxy.rb +40 -1
  30. data/lib/glimmer/swt/control_editor.rb +2 -1
  31. data/lib/glimmer/swt/custom/checkbox_group.rb +2 -2
  32. data/lib/glimmer/swt/custom/radio_group.rb +2 -2
  33. data/lib/glimmer/swt/date_time_proxy.rb +66 -1
  34. data/lib/glimmer/swt/event_listener_proxy.rb +14 -4
  35. data/lib/glimmer/swt/font_proxy.rb +4 -4
  36. data/lib/glimmer/swt/grid_layout_proxy.rb +21 -12
  37. data/lib/glimmer/swt/label_proxy.rb +17 -6
  38. data/lib/glimmer/swt/layout_data_proxy.rb +10 -7
  39. data/lib/glimmer/swt/list_proxy.rb +33 -0
  40. data/lib/glimmer/swt/menu_item_proxy.rb +87 -0
  41. data/lib/glimmer/swt/menu_proxy.rb +162 -0
  42. data/lib/glimmer/swt/message_box_proxy.rb +53 -67
  43. data/lib/glimmer/swt/property_owner.rb +2 -0
  44. data/lib/glimmer/swt/radio_proxy.rb +1 -1
  45. data/lib/glimmer/swt/shell_proxy.rb +32 -187
  46. data/lib/glimmer/swt/tab_folder_proxy.rb +43 -0
  47. data/lib/glimmer/swt/table_column_proxy.rb +4 -3
  48. data/lib/glimmer/swt/table_editor.rb +2 -2
  49. data/lib/glimmer/swt/table_item_proxy.rb +15 -5
  50. data/lib/glimmer/swt/table_proxy.rb +34 -12
  51. data/lib/glimmer/swt/text_proxy.rb +1 -1
  52. data/lib/glimmer/swt/widget_proxy.rb +335 -38
  53. data/lib/glimmer/ui/custom_shell.rb +9 -7
  54. data/lib/glimmer/ui/custom_widget.rb +3 -3
  55. data/lib/os.rb +36 -0
  56. metadata +36 -3
@@ -72,7 +72,7 @@ module Glimmer
72
72
  doit
73
73
  }
74
74
  }
75
- }
75
+ },
76
76
  }
77
77
  end
78
78
 
@@ -23,16 +23,20 @@ require 'glimmer/swt/event_listener_proxy'
23
23
  require 'glimmer/swt/property_owner'
24
24
  require 'glimmer/swt/swt_proxy'
25
25
 
26
+ # TODO implement menu (which delays building it till render using add_content_on_render)
27
+
26
28
  module Glimmer
27
29
  module SWT
28
30
  class WidgetProxy
29
31
  include Glimmer
30
32
  include PropertyOwner
31
33
 
32
- attr_reader :parent, :args, :path, :children, :enabled, :foreground, :background, :font, :focus, :disposed?, :rendered
34
+ attr_reader :parent, :args, :path, :children, :enabled, :foreground, :background, :font, :focus, :disposed?, :rendered, :menu_requested
35
+ attr_accessor :menu
33
36
  alias isDisposed disposed?
34
37
  alias is_disposed disposed?
35
38
  alias rendered? rendered
39
+ alias menu_requested? menu_requested
36
40
 
37
41
  class << self
38
42
  # Factory Method that translates a Glimmer DSL keyword into a WidgetProxy object
@@ -76,7 +80,7 @@ module Glimmer
76
80
  end
77
81
 
78
82
  DEFAULT_INITIALIZERS = {
79
- "composite" => lambda do |composite_proxy|
83
+ composite: lambda do |composite_proxy|
80
84
  if composite_proxy.layout.nil?
81
85
  layout = GridLayoutProxy.new(composite_proxy, [])
82
86
  composite_proxy.layout = layout
@@ -84,18 +88,18 @@ module Glimmer
84
88
  layout.margin_height = 15
85
89
  end
86
90
  end,
87
- # "scrolled_composite" => lambda do |scrolled_composite|
91
+ # scrolled_composite: lambda do |scrolled_composite|
88
92
  # scrolled_composite.expand_horizontal = true
89
93
  # scrolled_composite.expand_vertical = true
90
94
  # end,
91
- # "table" => lambda do |table|
95
+ # table: lambda do |table|
92
96
  # table.setHeaderVisible(true)
93
97
  # table.setLinesVisible(true)
94
98
  # end,
95
- "table_column" => lambda do |table_column_proxy|
99
+ table_column: lambda do |table_column_proxy|
96
100
  table_column_proxy.width = 80
97
101
  end,
98
- # "group" => lambda do |group_proxy|
102
+ # group: lambda do |group_proxy|
99
103
  # group_proxy.layout = GridLayoutProxy.new(group_proxy, []) if group.layout.nil?
100
104
  # end,
101
105
  }
@@ -107,7 +111,7 @@ module Glimmer
107
111
  @children = Set.new # TODO consider moving to composite
108
112
  @enabled = true
109
113
  @data = {}
110
- DEFAULT_INITIALIZERS[self.class.underscored_widget_name(self)]&.call(self)
114
+ DEFAULT_INITIALIZERS[self.class.underscored_widget_name(self).to_s.to_sym]&.call(self)
111
115
  @parent.post_initialize_child(self) # TODO rename to post_initialize_child to be closer to glimmer-dsl-swt terminology
112
116
  end
113
117
 
@@ -124,7 +128,19 @@ module Glimmer
124
128
 
125
129
  # Executes at the closing of a parent widget curly braces after all children/properties have been added/set
126
130
  def post_add_content
127
- # No Op by default
131
+ if !menu.nil? && !is_a?(MenuProxy) && !is_a?(MenuItemProxy)
132
+ on_mouse_down { |mouse_event|
133
+ if mouse_event.button == 3 # right-click
134
+ @menu_requested = true
135
+ dom_element.css('position', 'relative')
136
+ menu&.render
137
+ menu.dom_element.css('position', 'absolute')
138
+ menu.dom_element.css('left', mouse_event.x - parent.layout&.margin_width.to_i) # TODO - parent.layout&.margin_left.to_i)
139
+ menu.dom_element.css('top', mouse_event.y - parent.layout&.margin_height.to_i - 5) # TODO - parent.layout&.margin_top.to_i)
140
+ @menu_requested = false
141
+ end
142
+ }
143
+ end
128
144
  end
129
145
 
130
146
  def set_data(key=nil, value)
@@ -148,18 +164,20 @@ module Glimmer
148
164
  Document.find(path).remove
149
165
  parent&.post_dispose_child(self)
150
166
  # TODO fire on_widget_disposed listener
167
+ # children.each(:dispose) # TODO enable this safely
151
168
  @disposed = true
152
169
  end
153
170
 
154
171
  def remove_all_listeners
155
- observation_request_to_event_mapping.keys.each do |keyword|
156
- [observation_request_to_event_mapping[keyword]].flatten.each do |mapping|
157
- @observation_requests[keyword].to_a.each do |event_listener|
172
+ effective_observation_request_to_event_mapping.keys.each do |keyword|
173
+ effective_observation_request_to_event_mapping[keyword].to_collection.each do |mapping|
174
+ observation_requests[keyword].to_a.each do |event_listener|
158
175
  event = mapping[:event]
159
176
  event_handler = mapping[:event_handler]
160
177
  event_element_css_selector = mapping[:event_element_css_selector]
161
178
  the_listener_dom_element = event_element_css_selector ? Element[event_element_css_selector] : listener_dom_element
162
179
  the_listener_dom_element.off(event)
180
+ # TODO improve to precisely remove the listeners that were added, no more no less. (or use the event_listener_proxies method instead or in collaboration)
163
181
  end
164
182
  end
165
183
  end
@@ -215,27 +233,26 @@ module Glimmer
215
233
  Document.find(parent_path)
216
234
  end
217
235
 
218
- def render(custom_parent_dom_element = nil)
236
+ def render(custom_parent_dom_element: nil, brand_new: false)
219
237
  the_parent_dom_element = custom_parent_dom_element || parent_dom_element
220
238
  old_element = dom_element
221
- brand_new = @dom.nil? || old_element.empty?
222
- build_dom(!custom_parent_dom_element) # TODO handle custom parent layout by passing parent instead of parent dom element
239
+ brand_new = @dom.nil? || old_element.empty? || brand_new
240
+ build_dom(layout: !custom_parent_dom_element) # TODO handle custom parent layout by passing parent instead of parent dom element
223
241
  if brand_new
224
242
  the_parent_dom_element.append(@dom)
225
243
  else
226
244
  old_element.replace_with(@dom)
227
245
  end
228
- @observation_requests&.clone&.each do |keyword, event_listener_set|
246
+ observation_requests&.each do |keyword, event_listener_set|
229
247
  event_listener_set.each do |event_listener|
230
- @observation_requests[keyword].delete(event_listener)
231
- handle_observation_request(keyword, &event_listener)
248
+ handle_observation_request(keyword, event_listener)
232
249
  end
233
250
  end
234
251
  children.each do |child|
235
252
  child.render
236
253
  end
237
254
  @rendered = true
238
- content_on_render_blocks.each { |content_block| content(&content_block) }
255
+ content_on_render_blocks.each { |content_block| content(&content_block) } unless skip_content_on_render_blocks?
239
256
  end
240
257
  alias redraw render
241
258
 
@@ -243,6 +260,10 @@ module Glimmer
243
260
  @content_on_render_blocks ||= []
244
261
  end
245
262
 
263
+ def skip_content_on_render_blocks?
264
+ false
265
+ end
266
+
246
267
  def add_content_on_render(&content_block)
247
268
  if rendered?
248
269
  content_block.call
@@ -251,7 +272,7 @@ module Glimmer
251
272
  end
252
273
  end
253
274
 
254
- def build_dom(layout=true)
275
+ def build_dom(layout: true)
255
276
  # TODO consider passing parent element instead and having table item include a table cell widget only for opal
256
277
  @dom = nil
257
278
  @dom = dom
@@ -268,6 +289,260 @@ module Glimmer
268
289
  {}
269
290
  end
270
291
 
292
+ def effective_observation_request_to_event_mapping
293
+ default_observation_request_to_event_mapping.merge(observation_request_to_event_mapping)
294
+ end
295
+
296
+ def default_observation_request_to_event_mapping
297
+ mouse_event_handler = -> (event_listener) {
298
+ -> (event) {
299
+ # TODO generalize this solution to all widgets that support key presses
300
+ # TODO support event.location once DOM3 is supported by opal-jquery
301
+ event.define_singleton_method(:button, &event.method(:which))
302
+ event.define_singleton_method(:count) {1} # TODO support double-click count of 2 in the future by using ondblclick
303
+ event.define_singleton_method(:x, &event.method(:page_x))
304
+ event.define_singleton_method(:y, &event.method(:page_y))
305
+ doit = true
306
+ event.define_singleton_method(:doit=) do |value|
307
+ doit = value
308
+ end
309
+ event.define_singleton_method(:doit) { doit }
310
+
311
+ if event.which == 1
312
+ # event.prevent # TODO consider if this is needed
313
+ event_listener.call(event)
314
+ end
315
+
316
+ # TODO Imlement doit properly for all different kinds of events
317
+ # unless doit
318
+ # event.prevent
319
+ # event.stop
320
+ # event.stop_immediate
321
+ # end
322
+ }
323
+ }
324
+ context_menu_handler = -> (event_listener) {
325
+ -> (event) {
326
+ # TODO generalize this solution to all widgets that support key presses
327
+ # TODO support event.location once DOM3 is supported by opal-jquery
328
+ event.define_singleton_method(:button, &event.method(:which))
329
+ event.define_singleton_method(:count) {1} # TODO support double-click count of 2 in the future by using ondblclick
330
+ event.define_singleton_method(:x, &event.method(:page_x))
331
+ event.define_singleton_method(:y, &event.method(:page_y))
332
+ doit = true
333
+ event.define_singleton_method(:doit=) do |value|
334
+ doit = value
335
+ end
336
+ event.define_singleton_method(:doit) { doit }
337
+
338
+ if event.which == 3
339
+ event.prevent
340
+ event_listener.call(event)
341
+ end
342
+
343
+ # TODO Imlement doit properly for all different kinds of events
344
+ # unless doit
345
+ # event.prevent
346
+ # event.stop
347
+ # event.stop_immediate
348
+ # end
349
+ }
350
+ }
351
+ {
352
+ 'on_focus_gained' => {
353
+ event: 'focus',
354
+ },
355
+ 'on_focus_lost' => {
356
+ event: 'blur',
357
+ },
358
+ 'on_mouse_up' => [
359
+ {
360
+ event: 'mouseup',
361
+ event_handler: mouse_event_handler,
362
+ },
363
+ {
364
+ event: 'contextmenu',
365
+ event_handler: context_menu_handler,
366
+ },
367
+ ],
368
+ 'on_mouse_down' => [
369
+ {
370
+ event: 'mousedown',
371
+ event_handler: mouse_event_handler,
372
+ },
373
+ {
374
+ event: 'contextmenu',
375
+ event_handler: context_menu_handler,
376
+ },
377
+ ],
378
+ 'on_swt_mouseup' => [
379
+ {
380
+ event: 'mouseup',
381
+ event_handler: mouse_event_handler,
382
+ },
383
+ {
384
+ event: 'contextmenu',
385
+ event_handler: context_menu_handler,
386
+ },
387
+ ],
388
+ 'on_swt_mousedown' => [
389
+ {
390
+ event: 'mousedown',
391
+ event_handler: mouse_event_handler,
392
+ },
393
+ {
394
+ event: 'contextmenu',
395
+ event_handler: context_menu_handler,
396
+ },
397
+ ],
398
+ 'on_key_pressed' => {
399
+ event: 'keypress',
400
+ event_handler: -> (event_listener) {
401
+ -> (event) {
402
+ # TODO generalize this solution to all widgets that support key presses
403
+ # TODO support event.location once DOM3 is supported by opal-jquery
404
+ event.define_singleton_method(:keyCode) {event.which}
405
+ event.define_singleton_method(:key_code, &event.method(:keyCode))
406
+ event.define_singleton_method(:character) {event.which.chr}
407
+ event.define_singleton_method(:stateMask) do
408
+ state_mask = 0
409
+ state_mask |= SWTProxy[:alt] if event.alt_key
410
+ state_mask |= SWTProxy[:ctrl] if event.ctrl_key
411
+ state_mask |= SWTProxy[:shift] if event.shift_key
412
+ state_mask |= SWTProxy[:command] if event.meta_key
413
+ state_mask
414
+ end
415
+ event.define_singleton_method(:state_mask, &event.method(:stateMask))
416
+ doit = true
417
+ event.define_singleton_method(:doit=) do |value|
418
+ doit = value
419
+ end
420
+ event.define_singleton_method(:doit) { doit }
421
+ event_listener.call(event)
422
+
423
+ # TODO Fix doit false, it's not stopping input
424
+ unless doit
425
+ event.prevent
426
+ event.prevent_default
427
+ event.stop_propagation
428
+ event.stop_immediate_propagation
429
+ end
430
+
431
+ doit
432
+ }
433
+ } },
434
+ 'on_key_released' => {
435
+ event: 'keydown',
436
+ event_handler: -> (event_listener) {
437
+ -> (event) {
438
+ # TODO generalize this solution to all widgets that support key presses
439
+ # TODO support event.location once DOM3 is supported by opal-jquery
440
+ event.define_singleton_method(:keyCode) {event.which}
441
+ event.define_singleton_method(:key_code, &event.method(:keyCode))
442
+ event.define_singleton_method(:character) {event.which.chr}
443
+ event.define_singleton_method(:stateMask) do
444
+ state_mask = 0
445
+ state_mask |= SWTProxy[:alt] if event.alt_key
446
+ state_mask |= SWTProxy[:ctrl] if event.ctrl_key
447
+ state_mask |= SWTProxy[:shift] if event.shift_key
448
+ state_mask |= SWTProxy[:command] if event.meta_key
449
+ state_mask
450
+ end
451
+ event.define_singleton_method(:state_mask, &event.method(:stateMask))
452
+ doit = true
453
+ event.define_singleton_method(:doit=) do |value|
454
+ doit = value
455
+ end
456
+ event.define_singleton_method(:doit) { doit }
457
+ event_listener.call(event)
458
+
459
+ # TODO Fix doit false, it's not stopping input
460
+ unless doit
461
+ event.prevent
462
+ event.prevent_default
463
+ event.stop_propagation
464
+ event.stop_immediate_propagation
465
+ end
466
+
467
+ doit
468
+ }
469
+ } },
470
+ 'on_swt_keydown' => {
471
+ event: 'keypress',
472
+ event_handler: -> (event_listener) {
473
+ -> (event) {
474
+ # TODO generalize this solution to all widgets that support key presses
475
+ # TODO support event.location once DOM3 is supported by opal-jquery
476
+ event.define_singleton_method(:keyCode) {event.which}
477
+ event.define_singleton_method(:key_code, &event.method(:keyCode))
478
+ event.define_singleton_method(:character) {event.which.chr}
479
+ event.define_singleton_method(:stateMask) do
480
+ state_mask = 0
481
+ state_mask |= SWTProxy[:alt] if event.alt_key
482
+ state_mask |= SWTProxy[:ctrl] if event.ctrl_key
483
+ state_mask |= SWTProxy[:shift] if event.shift_key
484
+ state_mask |= SWTProxy[:command] if event.meta_key
485
+ state_mask
486
+ end
487
+ event.define_singleton_method(:state_mask, &event.method(:stateMask))
488
+ doit = true
489
+ event.define_singleton_method(:doit=) do |value|
490
+ doit = value
491
+ end
492
+ event.define_singleton_method(:doit) { doit }
493
+ event_listener.call(event)
494
+
495
+ # TODO Fix doit false, it's not stopping input
496
+ unless doit
497
+ event.prevent
498
+ event.prevent_default
499
+ event.stop_propagation
500
+ event.stop_immediate_propagation
501
+ end
502
+
503
+ doit
504
+ }
505
+ } },
506
+ 'on_swt_keyup' => {
507
+ event: 'keydown',
508
+ event_handler: -> (event_listener) {
509
+ -> (event) {
510
+ # TODO generalize this solution to all widgets that support key presses
511
+ # TODO support event.location once DOM3 is supported by opal-jquery
512
+ event.define_singleton_method(:keyCode) {event.which}
513
+ event.define_singleton_method(:key_code, &event.method(:keyCode))
514
+ event.define_singleton_method(:character) {event.which.chr}
515
+ event.define_singleton_method(:stateMask) do
516
+ state_mask = 0
517
+ state_mask |= SWTProxy[:alt] if event.alt_key
518
+ state_mask |= SWTProxy[:ctrl] if event.ctrl_key
519
+ state_mask |= SWTProxy[:shift] if event.shift_key
520
+ state_mask |= SWTProxy[:command] if event.meta_key
521
+ state_mask
522
+ end
523
+ event.define_singleton_method(:state_mask, &event.method(:stateMask))
524
+ doit = true
525
+ event.define_singleton_method(:doit=) do |value|
526
+ doit = value
527
+ end
528
+ event.define_singleton_method(:doit) { doit }
529
+ event_listener.call(event)
530
+
531
+ # TODO Fix doit false, it's not stopping input
532
+ unless doit
533
+ event.prevent
534
+ event.prevent_default
535
+ event.stop_propagation
536
+ event.stop_immediate_propagation
537
+ end
538
+
539
+ doit
540
+ }
541
+ }
542
+ },
543
+ }
544
+ end
545
+
271
546
  def name
272
547
  self.class.name.split('::').last.underscore.sub(/_proxy$/, '').gsub('_', '-')
273
548
  end
@@ -339,6 +614,14 @@ module Glimmer
339
614
  Document.find(listener_path)
340
615
  end
341
616
 
617
+ def observation_requests
618
+ @observation_requests ||= {}
619
+ end
620
+
621
+ def event_listener_proxies
622
+ @event_listener_proxies ||= []
623
+ end
624
+
342
625
  def can_handle_observation_request?(observation_request)
343
626
  # TODO sort this out for Opal
344
627
  observation_request = observation_request.to_s
@@ -352,29 +635,40 @@ module Glimmer
352
635
  end
353
636
  end
354
637
 
355
- def handle_observation_request(keyword, &event_listener)
356
- return unless observation_request_to_event_mapping.keys.include?(keyword)
357
- @observation_requests ||= {}
358
- @observation_requests[keyword] ||= Set.new
638
+ def handle_observation_request(keyword, original_event_listener)
639
+ return unless effective_observation_request_to_event_mapping.keys.include?(keyword)
359
640
  event = nil
360
641
  delegate = nil
361
- [observation_request_to_event_mapping[keyword]].flatten.each do |mapping|
362
- @observation_requests[keyword] << event_listener
642
+ effective_observation_request_to_event_mapping[keyword].to_collection.each do |mapping|
643
+ observation_requests[keyword] ||= Set.new
644
+ observation_requests[keyword] << original_event_listener
363
645
  event = mapping[:event]
364
646
  event_handler = mapping[:event_handler]
365
647
  event_element_css_selector = mapping[:event_element_css_selector]
366
- potential_event_listener = event_handler&.call(event_listener)
367
- event_listener = potential_event_listener || event_listener
648
+ potential_event_listener = event_handler&.call(original_event_listener)
649
+ event_listener = potential_event_listener || original_event_listener
368
650
  async_event_listener = lambda do |event|
369
- Async::Task.new do
651
+ # TODO look into the issue with using async::task.new here. maybe put it in event listener (like not being able to call preventDefault or return false successfully )
652
+ # maybe consider pushing inside the widget classes instead where needed only or implement universal doit support correctly to bypass this issue
653
+ # Async::Task.new do
370
654
  event_listener.call(event)
371
- end
655
+ # end
372
656
  end
373
657
  the_listener_dom_element = event_element_css_selector ? Element[event_element_css_selector] : listener_dom_element
374
- delegate = the_listener_dom_element.on(event, &async_event_listener)
658
+ unless the_listener_dom_element.empty?
659
+ the_listener_dom_element.on(event, &async_event_listener)
660
+ # TODO ensure uniqueness of insertion (perhaps adding equals/hash method to event listener proxy)
661
+
662
+ event_listener_proxies << EventListenerProxy.new(element_proxy: self, selector: selector, dom_element: the_listener_dom_element, event: event, listener: async_event_listener, original_event_listener: original_event_listener)
663
+ end
664
+ end
665
+ end
666
+
667
+ def remove_event_listener_proxies
668
+ event_listener_proxies.each do |event_listener_proxy|
669
+ event_listener_proxy.unregister
375
670
  end
376
- # TODO update code below for new WidgetProxy API
377
- EventListenerProxy.new(element_proxy: self, event: event, selector: selector, delegate: delegate)
671
+ event_listener_proxies.clear
378
672
  end
379
673
 
380
674
  def add_observer(observer, property_name)
@@ -392,12 +686,17 @@ module Glimmer
392
686
 
393
687
  def method_missing(method, *args, &block)
394
688
  if method.to_s.start_with?('on_')
395
- handle_observation_request(method, &block)
689
+ handle_observation_request(method, block)
396
690
  else
397
691
  super(method, *args, &block)
398
692
  end
399
693
  end
400
694
 
695
+ def swt_widget
696
+ # only added for compatibility/adaptibility with Glimmer DSL for SWT
697
+ self
698
+ end
699
+
401
700
  def apply_property_type_converters(attribute_name, args)
402
701
  if args.count == 1
403
702
  value = args.first
@@ -555,11 +854,7 @@ module Glimmer
555
854
  TableProxy => {
556
855
  :selection => lambda do |observer|
557
856
  on_widget_selected { |selection_event|
558
- if has_style?(:multi)
559
- observer.call(selection.map(&:get_data))
560
- else
561
- observer.call(selection.first&.get_data)
562
- end
857
+ observer.call(selection_event.table_item.get_data) # TODO ensure selection doesn't conflict with editing
563
858
  }
564
859
  end,
565
860
  },
@@ -594,6 +889,8 @@ require 'glimmer/swt/date_time_proxy'
594
889
  require 'glimmer/swt/group_proxy'
595
890
  require 'glimmer/swt/label_proxy'
596
891
  require 'glimmer/swt/list_proxy'
892
+ require 'glimmer/swt/menu_item_proxy'
893
+ require 'glimmer/swt/menu_proxy'
597
894
  require 'glimmer/swt/radio_proxy'
598
895
  require 'glimmer/swt/tab_folder_proxy'
599
896
  require 'glimmer/swt/tab_item_proxy'