glimmer-dsl-opal 0.25.4 → 0.26.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -1
  3. data/README.md +40 -5
  4. data/VERSION +1 -1
  5. data/lib/glimmer/dsl/opal/menu_expression.rb +0 -3
  6. data/lib/glimmer/swt/combo_proxy.rb +0 -39
  7. data/lib/glimmer/swt/control_editor.rb +2 -2
  8. data/lib/glimmer/swt/date_time_proxy.rb +0 -37
  9. data/lib/glimmer/swt/dialog_proxy.rb +11 -4
  10. data/lib/glimmer/swt/display_proxy.rb +1 -83
  11. data/lib/glimmer/swt/shell_proxy.rb +28 -1
  12. data/lib/glimmer/swt/spinner_proxy.rb +0 -39
  13. data/lib/glimmer/swt/table_item_proxy.rb +0 -20
  14. data/lib/glimmer/swt/table_proxy.rb +4 -0
  15. data/lib/glimmer/swt/text_proxy.rb +1 -39
  16. data/lib/glimmer/swt/widget_proxy.rb +177 -58
  17. data/lib/glimmer/ui/custom_shell.rb +2 -0
  18. data/lib/glimmer/ui/custom_widget.rb +2 -0
  19. data/lib/glimmer-dsl-opal/samples/elaborate/tetris/model/block.rb +48 -0
  20. data/lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb +275 -0
  21. data/lib/glimmer-dsl-opal/samples/elaborate/tetris/model/past_game.rb +39 -0
  22. data/lib/glimmer-dsl-opal/samples/elaborate/tetris/model/tetromino.rb +329 -0
  23. data/lib/glimmer-dsl-opal/samples/elaborate/tetris/view/block.rb +36 -0
  24. data/lib/glimmer-dsl-opal/samples/elaborate/tetris/view/high_score_dialog.rb +122 -0
  25. data/lib/glimmer-dsl-opal/samples/elaborate/tetris/view/playfield.rb +56 -0
  26. data/lib/glimmer-dsl-opal/samples/elaborate/tetris/view/score_lane.rb +83 -0
  27. data/lib/glimmer-dsl-opal/samples/elaborate/tetris/view/tetris_menu_bar.rb +136 -0
  28. data/lib/glimmer-dsl-opal/samples/elaborate/tetris.rb +155 -0
  29. data/lib/glimmer-dsl-opal.rb +1 -0
  30. metadata +12 -2
@@ -153,45 +153,6 @@ module Glimmer
153
153
  }
154
154
  }
155
155
  },
156
- 'on_key_pressed' => {
157
- event: 'keydown',
158
- event_handler: -> (event_listener) {
159
- -> (event) {
160
- @last_key_pressed_event = event
161
- self.text = event.target.value
162
- # TODO generalize this solution to all widgets that support key presses
163
- # TODO support event.location once DOM3 is supported by opal-jquery
164
- event.define_singleton_method(:keyCode) {event.which}
165
- event.define_singleton_method(:key_code, &event.method(:keyCode))
166
- event.define_singleton_method(:character) {event.which.chr}
167
- event.define_singleton_method(:stateMask) do
168
- state_mask = 0
169
- state_mask |= SWTProxy[:alt] if event.alt_key
170
- state_mask |= SWTProxy[:ctrl] if event.ctrl_key
171
- state_mask |= SWTProxy[:shift] if event.shift_key
172
- state_mask |= SWTProxy[:command] if event.meta_key
173
- state_mask
174
- end
175
- event.define_singleton_method(:state_mask, &event.method(:stateMask))
176
- doit = true
177
- event.define_singleton_method(:doit=) do |value|
178
- doit = value
179
- end
180
- event.define_singleton_method(:doit) { doit }
181
- event_listener.call(event)
182
-
183
- # TODO Fix doit false, it's not stopping input
184
- unless doit
185
- event.prevent
186
- event.prevent_default
187
- event.stop_propagation
188
- event.stop_immediate_propagation
189
- end
190
-
191
- doit
192
- }
193
- }
194
- },
195
156
  }
196
157
  end
197
158
 
@@ -59,26 +59,6 @@ module Glimmer
59
59
  @text_array ||= []
60
60
  end
61
61
 
62
- def get_data(key = nil)
63
- if key.nil?
64
- @data
65
- else
66
- data_hash[key]
67
- end
68
- end
69
-
70
- def set_data(key = nil, data_value)
71
- if key.nil?
72
- @data = data_value
73
- else
74
- data_hash[key] = data_value
75
- end
76
- end
77
-
78
- def data_hash
79
- @data_hash ||= {}
80
- end
81
-
82
62
  def parent_path
83
63
  parent.items_path
84
64
  end
@@ -61,6 +61,10 @@ module Glimmer
61
61
  on_focus_lost {
62
62
  table_proxy.finish_edit!
63
63
  }
64
+ on_modify_text do |event|
65
+ # No Op, just record @text changes on key up
66
+ # TODO find a better solution than this in the future
67
+ end
64
68
  on_key_pressed { |key_event|
65
69
  if key_event.keyCode == swt(:cr)
66
70
  table_proxy.finish_edit!
@@ -21,6 +21,7 @@ module Glimmer
21
21
  event_handler: -> (event_listener) {
22
22
  -> (event) {
23
23
  # TODO consider unifying this event handler with on_key_pressed by relying on its result instead of hooking another keyup event
24
+ # TODO add all attributes for on_modify_text modify event
24
25
  if @last_key_pressed_event.nil? || @last_key_pressed_event.doit
25
26
  @text = event.target.value
26
27
  event_listener.call(event)
@@ -34,45 +35,6 @@ module Glimmer
34
35
  }
35
36
  }
36
37
  },
37
- 'on_key_pressed' => {
38
- event: 'keydown',
39
- event_handler: -> (event_listener) {
40
- -> (event) {
41
- @last_key_pressed_event = event
42
- @text = event.target.value
43
- # TODO generalize this solution to all widgets that support key presses
44
- # TODO support event.location once DOM3 is supported by opal-jquery
45
- event.define_singleton_method(:keyCode) {event.which}
46
- event.define_singleton_method(:key_code, &event.method(:keyCode))
47
- event.define_singleton_method(:character) {event.which.chr}
48
- event.define_singleton_method(:stateMask) do
49
- state_mask = 0
50
- state_mask |= SWTProxy[:alt] if event.alt_key
51
- state_mask |= SWTProxy[:ctrl] if event.ctrl_key
52
- state_mask |= SWTProxy[:shift] if event.shift_key
53
- state_mask |= SWTProxy[:command] if event.meta_key
54
- state_mask
55
- end
56
- event.define_singleton_method(:state_mask, &event.method(:stateMask))
57
- doit = true
58
- event.define_singleton_method(:doit=) do |value|
59
- doit = value
60
- end
61
- event.define_singleton_method(:doit) { doit }
62
- event_listener.call(event)
63
-
64
- # TODO Fix doit false, it's not stopping input
65
- unless doit
66
- event.prevent
67
- event.prevent_default
68
- event.stop_propagation
69
- event.stop_immediate_propagation
70
- end
71
-
72
- doit
73
- }
74
- }
75
- },
76
38
  }
77
39
  end
78
40
 
@@ -31,6 +31,25 @@ module Glimmer
31
31
  include Glimmer
32
32
  include PropertyOwner
33
33
 
34
+ Event = Struct.new(:widget, keyword_init: true)
35
+
36
+ JS_KEY_CODE_TO_SWT_KEY_CODE_MAP = {
37
+ 16 => SWTProxy[:shift],
38
+ 17 => SWTProxy[:ctrl],
39
+ 18 => SWTProxy[:alt],
40
+ 37 => SWTProxy[:arrow_left],
41
+ 38 => SWTProxy[:arrow_up],
42
+ 39 => SWTProxy[:arrow_right],
43
+ 40 => SWTProxy[:arrow_down],
44
+ }
45
+
46
+ JS_LOCATION_TO_SWT_KEY_LOCATION_MAP = {
47
+ 0 => SWTProxy[:none],
48
+ 1 => SWTProxy[:left],
49
+ 2 => SWTProxy[:right],
50
+ 3 => SWTProxy[:keypad],
51
+ }
52
+
34
53
  SWT_CURSOR_TO_CSS_CURSOR_MAP = {
35
54
  wait: 'wait',
36
55
  sizenwse: 'nwse-resize',
@@ -140,7 +159,6 @@ module Glimmer
140
159
  # TODO consider changing children to an array (why is it a Set if order matters?)
141
160
  @children = Set.new # TODO consider moving to composite
142
161
  @enabled = true
143
- @data = {}
144
162
  DEFAULT_INITIALIZERS[self.class.underscored_widget_name(self).to_s.to_sym]&.call(self)
145
163
  @parent.post_initialize_child(self) # TODO rename to post_initialize_child to be closer to glimmer-dsl-swt terminology
146
164
  end
@@ -172,18 +190,30 @@ module Glimmer
172
190
  end
173
191
  end
174
192
 
175
- def set_data(key=nil, value)
176
- @data[key] = value
193
+ def set_data(key = nil, value)
194
+ if key.nil?
195
+ @data = value
196
+ else
197
+ swt_data[key] = value
198
+ end
177
199
  end
178
200
  alias setData set_data
179
201
  alias data= set_data
180
202
 
181
- def get_data(key=nil)
182
- @data[key]
203
+ def get_data(key = nil)
204
+ if key.nil?
205
+ @data
206
+ else
207
+ swt_data[key]
208
+ end
183
209
  end
184
210
  alias getData get_data
185
211
  alias data get_data
186
212
 
213
+ def swt_data
214
+ @swt_data ||= {}
215
+ end
216
+
187
217
  def css_classes
188
218
  dom_element.attr('class').to_s.split
189
219
  end
@@ -192,9 +222,9 @@ module Glimmer
192
222
  remove_all_listeners
193
223
  Document.find(path).remove
194
224
  parent&.post_dispose_child(self)
195
- # TODO fire on_widget_disposed listener
196
225
  # children.each(:dispose) # TODO enable this safely
197
226
  @disposed = true
227
+ listeners_for('widget_disposed').each {|listener| listener.call(Event.new(widget: self))}
198
228
  end
199
229
 
200
230
  def remove_all_listeners
@@ -360,7 +390,6 @@ module Glimmer
360
390
  mouse_event_handler = -> (event_listener) {
361
391
  -> (event) {
362
392
  # TODO generalize this solution to all widgets that support key presses
363
- # TODO support event.location once DOM3 is supported by opal-jquery
364
393
  event.define_singleton_method(:widget) {myself}
365
394
  event.define_singleton_method(:button, &event.method(:which))
366
395
  event.define_singleton_method(:count) {1} # TODO support double-click count of 2 in the future by using ondblclick
@@ -388,7 +417,6 @@ module Glimmer
388
417
  mouse_move_event_handler = -> (event_listener) {
389
418
  -> (event) {
390
419
  # TODO generalize this solution to all widgets that support key presses
391
- # TODO support event.location once DOM3 is supported by opal-jquery
392
420
  event.define_singleton_method(:widget) {myself}
393
421
  event.define_singleton_method(:button, &event.method(:which))
394
422
  event.define_singleton_method(:count) {1} # TODO support double-click count of 2 in the future by using ondblclick
@@ -413,7 +441,6 @@ module Glimmer
413
441
  context_menu_handler = -> (event_listener) {
414
442
  -> (event) {
415
443
  # TODO generalize this solution to all widgets that support key presses
416
- # TODO support event.location once DOM3 is supported by opal-jquery
417
444
  event.define_singleton_method(:widget) {myself}
418
445
  event.define_singleton_method(:button, &event.method(:which))
419
446
  event.define_singleton_method(:count) {1} # TODO support double-click count of 2 in the future by using ondblclick
@@ -494,10 +521,15 @@ module Glimmer
494
521
  event: 'keypress',
495
522
  event_handler: -> (event_listener) {
496
523
  -> (event) {
497
- # TODO generalize this solution to all widgets that support key presses
498
- # TODO support event.location once DOM3 is supported by opal-jquery
499
524
  event.define_singleton_method(:widget) {myself}
500
- event.define_singleton_method(:keyCode) {event.which}
525
+ event.define_singleton_method(:keyLocation) do
526
+ location = `#{event.to_n}.originalEvent.location`
527
+ JS_LOCATION_TO_SWT_KEY_LOCATION_MAP[location] || location
528
+ end
529
+ event.define_singleton_method(:key_location, &event.method(:keyLocation))
530
+ event.define_singleton_method(:keyCode) {
531
+ JS_KEY_CODE_TO_SWT_KEY_CODE_MAP[event.which] || event.which
532
+ }
501
533
  event.define_singleton_method(:key_code, &event.method(:keyCode))
502
534
  event.define_singleton_method(:character) {event.which.chr}
503
535
  event.define_singleton_method(:stateMask) do
@@ -528,50 +560,18 @@ module Glimmer
528
560
  }
529
561
  } },
530
562
  'on_key_released' => {
531
- event: 'keydown',
563
+ event: 'keyup',
532
564
  event_handler: -> (event_listener) {
533
565
  -> (event) {
534
- # TODO generalize this solution to all widgets that support key presses
535
- # TODO support event.location once DOM3 is supported by opal-jquery
536
- event.define_singleton_method(:widget) {myself}
537
- event.define_singleton_method(:keyCode) {event.which}
538
- event.define_singleton_method(:key_code, &event.method(:keyCode))
539
- event.define_singleton_method(:character) {event.which.chr}
540
- event.define_singleton_method(:stateMask) do
541
- state_mask = 0
542
- state_mask |= SWTProxy[:alt] if event.alt_key
543
- state_mask |= SWTProxy[:ctrl] if event.ctrl_key
544
- state_mask |= SWTProxy[:shift] if event.shift_key
545
- state_mask |= SWTProxy[:command] if event.meta_key
546
- state_mask
547
- end
548
- event.define_singleton_method(:state_mask, &event.method(:stateMask))
549
- doit = true
550
- event.define_singleton_method(:doit=) do |value|
551
- doit = value
552
- end
553
- event.define_singleton_method(:doit) { doit }
554
- event_listener.call(event)
555
-
556
- # TODO Fix doit false, it's not stopping input
557
- unless doit
558
- event.prevent
559
- event.prevent_default
560
- event.stop_propagation
561
- event.stop_immediate_propagation
566
+ event.define_singleton_method(:keyLocation) do
567
+ location = `#{event.to_n}.originalEvent.location`
568
+ JS_LOCATION_TO_SWT_KEY_LOCATION_MAP[location] || location
562
569
  end
563
-
564
- doit
565
- }
566
- } },
567
- 'on_swt_keydown' => {
568
- event: 'keypress',
569
- event_handler: -> (event_listener) {
570
- -> (event) {
571
- # TODO generalize this solution to all widgets that support key presses
572
- # TODO support event.location once DOM3 is supported by opal-jquery
570
+ event.define_singleton_method(:key_location, &event.method(:keyLocation))
573
571
  event.define_singleton_method(:widget) {myself}
574
- event.define_singleton_method(:keyCode) {event.which}
572
+ event.define_singleton_method(:keyCode) {
573
+ JS_KEY_CODE_TO_SWT_KEY_CODE_MAP[event.which] || event.which
574
+ }
575
575
  event.define_singleton_method(:key_code, &event.method(:keyCode))
576
576
  event.define_singleton_method(:character) {event.which.chr}
577
577
  event.define_singleton_method(:stateMask) do
@@ -600,15 +600,106 @@ module Glimmer
600
600
 
601
601
  doit
602
602
  }
603
- } },
603
+ }
604
+ },
605
+ 'on_swt_keydown' => [
606
+ {
607
+ event: 'keypress',
608
+ event_handler: -> (event_listener) {
609
+ -> (event) {
610
+ event.define_singleton_method(:keyLocation) do
611
+ location = `#{event.to_n}.originalEvent.location`
612
+ JS_LOCATION_TO_SWT_KEY_LOCATION_MAP[location] || location
613
+ end
614
+ event.define_singleton_method(:key_location, &event.method(:keyLocation))
615
+ event.define_singleton_method(:keyCode) {
616
+ JS_KEY_CODE_TO_SWT_KEY_CODE_MAP[event.which] || event.which
617
+ }
618
+ event.define_singleton_method(:key_code, &event.method(:keyCode))
619
+ event.define_singleton_method(:character) {event.which.chr}
620
+ event.define_singleton_method(:stateMask) do
621
+ state_mask = 0
622
+ state_mask |= SWTProxy[:alt] if event.alt_key
623
+ state_mask |= SWTProxy[:ctrl] if event.ctrl_key
624
+ state_mask |= SWTProxy[:shift] if event.shift_key
625
+ state_mask |= SWTProxy[:command] if event.meta_key
626
+ state_mask
627
+ end
628
+ event.define_singleton_method(:state_mask, &event.method(:stateMask))
629
+ doit = true
630
+ event.define_singleton_method(:doit=) do |value|
631
+ doit = value
632
+ end
633
+ event.define_singleton_method(:doit) { doit }
634
+ event_listener.call(event)
635
+
636
+ # TODO Fix doit false, it's not stopping input
637
+ unless doit
638
+ event.prevent
639
+ event.prevent_default
640
+ event.stop_propagation
641
+ event.stop_immediate_propagation
642
+ end
643
+
644
+ doit
645
+ }
646
+ }
647
+ },
648
+ {
649
+ event: 'keydown',
650
+ event_handler: -> (event_listener) {
651
+ -> (event) {
652
+ event.define_singleton_method(:keyLocation) do
653
+ location = `#{event.to_n}.originalEvent.location`
654
+ JS_LOCATION_TO_SWT_KEY_LOCATION_MAP[location] || location
655
+ end
656
+ event.define_singleton_method(:key_location, &event.method(:keyLocation))
657
+ event.define_singleton_method(:keyCode) {
658
+ JS_KEY_CODE_TO_SWT_KEY_CODE_MAP[event.which] || event.which
659
+ }
660
+ event.define_singleton_method(:key_code, &event.method(:keyCode))
661
+ event.define_singleton_method(:character) {event.which.chr}
662
+ event.define_singleton_method(:stateMask) do
663
+ state_mask = 0
664
+ state_mask |= SWTProxy[:alt] if event.alt_key
665
+ state_mask |= SWTProxy[:ctrl] if event.ctrl_key
666
+ state_mask |= SWTProxy[:shift] if event.shift_key
667
+ state_mask |= SWTProxy[:command] if event.meta_key
668
+ state_mask
669
+ end
670
+ event.define_singleton_method(:state_mask, &event.method(:stateMask))
671
+ doit = true
672
+ event.define_singleton_method(:doit=) do |value|
673
+ doit = value
674
+ end
675
+ event.define_singleton_method(:doit) { doit }
676
+ event_listener.call(event) if event.which != 13 && (event.which == 127 || event.which <= 40)
677
+
678
+ # TODO Fix doit false, it's not stopping input
679
+ unless doit
680
+ event.prevent
681
+ event.prevent_default
682
+ event.stop_propagation
683
+ event.stop_immediate_propagation
684
+ end
685
+ doit
686
+ }
687
+ }
688
+ }
689
+ ],
604
690
  'on_swt_keyup' => {
605
- event: 'keydown',
691
+ event: 'keyup',
606
692
  event_handler: -> (event_listener) {
607
693
  -> (event) {
608
- # TODO generalize this solution to all widgets that support key presses
609
- # TODO support event.location once DOM3 is supported by opal-jquery
694
+ event.define_singleton_method(:keyLocation) do
695
+ location = `#{event.to_n}.originalEvent.location`
696
+ JS_LOCATION_TO_SWT_KEY_LOCATION_MAP[location] || location
697
+ end
698
+ event.define_singleton_method(:key_location, &event.method(:keyLocation))
610
699
  event.define_singleton_method(:widget) {myself}
611
- event.define_singleton_method(:keyCode) {event.which}
700
+ event.define_singleton_method(:keyCode) {
701
+ JS_KEY_CODE_TO_SWT_KEY_CODE_MAP[event.which] || event.which
702
+ }
612
703
  event.define_singleton_method(:key_code, &event.method(:keyCode))
613
704
  event.define_singleton_method(:character) {event.which.chr}
614
705
  event.define_singleton_method(:stateMask) do
@@ -733,6 +824,14 @@ module Glimmer
733
824
  @event_handling_suspended
734
825
  end
735
826
 
827
+ def listeners
828
+ @listeners ||= {}
829
+ end
830
+
831
+ def listeners_for(listener_event)
832
+ listeners[listener_event.to_s] ||= []
833
+ end
834
+
736
835
  def can_handle_observation_request?(observation_request)
737
836
  # TODO sort this out for Opal
738
837
  observation_request = observation_request.to_s
@@ -747,6 +846,15 @@ module Glimmer
747
846
  end
748
847
 
749
848
  def handle_observation_request(keyword, original_event_listener)
849
+ case keyword
850
+ when 'on_widget_disposed'
851
+ listeners_for(keyword.sub(/^on_/, '')) << original_event_listener.to_proc
852
+ else
853
+ handle_javascript_observation_request(keyword, original_event_listener)
854
+ end
855
+ end
856
+
857
+ def handle_javascript_observation_request(keyword, original_event_listener)
750
858
  return unless effective_observation_request_to_event_mapping.keys.include?(keyword)
751
859
  event = nil
752
860
  delegate = nil
@@ -886,6 +994,18 @@ module Glimmer
886
994
  # }
887
995
  # end,
888
996
  # },
997
+ MenuItemProxy => {
998
+ :selection => lambda do |observer|
999
+ on_widget_selected { |selection_event|
1000
+ # TODO look into validity of this and perhaps move toggle logic to MenuItemProxy
1001
+ if check?
1002
+ observer.call(!selection)
1003
+ else
1004
+ observer.call(selection)
1005
+ end
1006
+ }
1007
+ end
1008
+ },
889
1009
  ScaleProxy => {
890
1010
  :selection => lambda do |observer|
891
1011
  on_widget_selected { |selection_event|
@@ -1021,7 +1141,6 @@ require 'glimmer/swt/combo_proxy'
1021
1141
  require 'glimmer/swt/c_combo_proxy'
1022
1142
  require 'glimmer/swt/checkbox_proxy'
1023
1143
  require 'glimmer/swt/composite_proxy'
1024
- require 'glimmer/swt/dialog_proxy'
1025
1144
  require 'glimmer/swt/date_time_proxy'
1026
1145
  require 'glimmer/swt/group_proxy'
1027
1146
  require 'glimmer/swt/label_proxy'