glimmer-dsl-opal 0.7.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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'