glimmer-dsl-opal 0.26.2 → 0.28.1

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.
@@ -4,22 +4,6 @@ require 'glimmer/swt/swt_proxy'
4
4
  module Glimmer
5
5
  module SWT
6
6
  class DisplayProxy < WidgetProxy
7
- JS_KEY_CODE_TO_SWT_KEY_CODE_MAP = {
8
- 16 => SWTProxy[:shift],
9
- 17 => SWTProxy[:ctrl],
10
- 18 => SWTProxy[:alt],
11
- 37 => SWTProxy[:arrow_left],
12
- 38 => SWTProxy[:arrow_up],
13
- 39 => SWTProxy[:arrow_right],
14
- 40 => SWTProxy[:arrow_down],
15
- }
16
-
17
- JS_LOCATION_TO_SWT_KEY_LOCATION_MAP = {
18
- 1 => SWTProxy[:left],
19
- 2 => SWTProxy[:right],
20
- }
21
-
22
-
23
7
  class << self
24
8
  def instance
25
9
  @instance ||= new
@@ -102,99 +86,6 @@ module Glimmer
102
86
  # sync_exec kept for API compatibility reasons
103
87
  alias sync_exec async_exec
104
88
 
105
- def observation_request_to_event_mapping
106
- {
107
- 'on_swt_keydown' => [
108
- {
109
- event: 'keypress',
110
- event_handler: -> (event_listener) {
111
- -> (event) {
112
- event.singleton_class.define_method(:character) do
113
- which || key_code
114
- end
115
- event.define_singleton_method(:keyCode) {
116
- JS_KEY_CODE_TO_SWT_KEY_CODE_MAP[event.which] || event.which
117
- }
118
- event.define_singleton_method(:key_code, &event.method(:keyCode))
119
- event.define_singleton_method(:character) {event.which.chr}
120
- event.define_singleton_method(:stateMask) do
121
- state_mask = 0
122
- state_mask |= SWTProxy[:alt] if event.alt_key
123
- state_mask |= SWTProxy[:ctrl] if event.ctrl_key
124
- state_mask |= SWTProxy[:shift] if event.shift_key
125
- state_mask |= SWTProxy[:command] if event.meta_key
126
- state_mask
127
- end
128
- event.define_singleton_method(:state_mask, &event.method(:stateMask))
129
- doit = true
130
- event.define_singleton_method(:doit=) do |value|
131
- doit = value
132
- end
133
- event.define_singleton_method(:doit) { doit }
134
- event_listener.call(event)
135
-
136
- # TODO Fix doit false, it's not stopping input
137
- unless doit
138
- event.prevent
139
- event.prevent_default
140
- event.stop_propagation
141
- event.stop_immediate_propagation
142
- end
143
-
144
- doit
145
- }
146
- }
147
- },
148
- {
149
- event: 'keydown',
150
- event_handler: -> (event_listener) {
151
- -> (event) {
152
- original_event = event
153
- event = ::Event.new(event)
154
- event.define_singleton_method(:keyLocation) do
155
- key_location = `#{original_event}.location`
156
- JS_LOCATION_TO_SWT_KEY_LOCATION_MAP[key_location]
157
- end
158
- event.define_singleton_method(:key_location, &event.method(:keyLocation))
159
- event.define_singleton_method(:character) do
160
- which || key_code
161
- end
162
- event.define_singleton_method(:keyCode) {
163
- JS_KEY_CODE_TO_SWT_KEY_CODE_MAP[event.which] || event.which
164
- }
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) if event.which != 13 && (event.which == 127 || event.which <= 40)
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
- doit
191
- }
192
- }
193
- }
194
- ]
195
- }
196
- end
197
-
198
89
  private
199
90
 
200
91
  def async_exec_queues
@@ -1,5 +1,7 @@
1
1
  module Glimmer
2
2
  module SWT
3
+ # emulating org.eclipse.swt.graphics.Point
3
4
  Point = Struct.new(:x, :y)
5
+ # TODO alias as org.eclipse.swt.graphics.Point
4
6
  end
5
7
  end
@@ -0,0 +1,7 @@
1
+ module Glimmer
2
+ module SWT
3
+ # emulating org.eclipse.swt.graphics.Rectangle
4
+ Rectangle = Struct.new(:x, :y, :width, :height)
5
+ # TODO alias as org.eclipse.swt.graphics.Rectangle
6
+ end
7
+ end
@@ -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
 
@@ -3,7 +3,26 @@ require 'glimmer/swt/widget_proxy'
3
3
  module Glimmer
4
4
  module SWT
5
5
  class TextProxy < WidgetProxy
6
- attr_reader :text
6
+ attr_reader :text, :border, :left, :center, :right, :read_only, :wrap, :multi
7
+ alias border? border
8
+ alias left? left
9
+ alias center? center
10
+ alias right? right
11
+ alias read_only? read_only
12
+ alias wrap? wrap
13
+ alias multi? multi
14
+
15
+ def initialize(parent, args, block)
16
+ args << :border if args.empty?
17
+ @border = !!args.detect { |arg| SWTProxy[arg] == SWTProxy[:border] }
18
+ @left = !!args.detect { |arg| SWTProxy[arg] == SWTProxy[:left] }
19
+ @center = !!args.detect { |arg| SWTProxy[arg] == SWTProxy[:center] }
20
+ @right = !!args.detect { |arg| SWTProxy[arg] == SWTProxy[:right] }
21
+ @read_only = !!args.detect { |arg| SWTProxy[arg] == SWTProxy[:read_only] }
22
+ @wrap = !!args.detect { |arg| SWTProxy[arg] == SWTProxy[:wrap] }
23
+ @multi = !!args.detect { |arg| SWTProxy[arg] == SWTProxy[:multi] }
24
+ super(parent, args, block)
25
+ end
7
26
 
8
27
  def text=(value)
9
28
  @text = value
@@ -11,81 +30,86 @@ module Glimmer
11
30
  end
12
31
 
13
32
  def element
14
- 'input'
33
+ @wrap || @multi ? 'textarea' : 'input'
15
34
  end
16
35
 
17
36
  def observation_request_to_event_mapping
37
+ myself = self
18
38
  {
19
- 'on_modify_text' => {
20
- event: 'keyup',
21
- event_handler: -> (event_listener) {
22
- -> (event) {
23
- # TODO consider unifying this event handler with on_key_pressed by relying on its result instead of hooking another keyup event
24
- if @last_key_pressed_event.nil? || @last_key_pressed_event.doit
25
- @text = event.target.value
39
+ 'on_verify_text' => [
40
+ {
41
+ event: 'beforeinput',
42
+ event_handler: -> (event_listener) {
43
+ -> (event) {
44
+ event.define_singleton_method(:widget) {myself}
45
+ event.define_singleton_method(:text) {`#{event.to_n}.originalEvent.data` || ''}
46
+ selection_start = `#{event.target}[0].selectionStart`
47
+ selection_end = `#{event.target}[0].selectionEnd`
48
+ if `#{event.to_n}.originalEvent.inputType` == 'deleteContentBackward' && selection_start == selection_end
49
+ selection_start -= 1
50
+ selection_start = 0 if selection_start < 0
51
+ end
52
+ event.define_singleton_method(:start) do
53
+ selection_start
54
+ end
55
+ event.define_singleton_method(:end) {selection_end}
56
+ doit = true
57
+ event.define_singleton_method(:doit=) do |value|
58
+ doit = value
59
+ end
60
+ event.define_singleton_method(:doit) { doit }
26
61
  event_listener.call(event)
27
- else
28
- # TODO Fix doit false, it's not stopping input
29
- event.prevent
30
- event.prevent_default
31
- event.stop_propagation
32
- event.stop_immediate_propagation
33
- end
62
+
63
+ if !doit
64
+ `#{event.to_n}.originalEvent.returnValue = false`
65
+ end
66
+
67
+ doit
68
+ }
69
+ }
70
+ },
71
+ {
72
+ event: 'input',
73
+ event_handler: -> (event_listener) {
74
+ -> (event) {
75
+ event.define_singleton_method(:widget) {myself}
76
+ @text = event.target.value
77
+ }
34
78
  }
35
79
  }
36
- },
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
80
+ ],
81
+ 'on_modify_text' => [
82
+ {
83
+ event: 'input',
84
+ event_handler: -> (event_listener) {
85
+ -> (event) {
86
+ # TODO add all attributes for on_modify_text modify event
87
+ event.define_singleton_method(:widget) {myself}
88
+ @text = event.target.value
89
+ event_listener.call(event)
90
+ }
73
91
  }
74
92
  }
75
- },
93
+ ],
76
94
  }
77
95
  end
78
96
 
79
97
  def dom
80
98
  text_text = @text
81
99
  text_id = id
82
- text_style = css
100
+ text_style = 'min-width: 27px; '
101
+ text_style += 'border: none; ' if !@border
102
+ text_style += 'text-align: left; ' if @left
103
+ text_style += 'text-align: center; ' if @center
104
+ text_style += 'text-align: right; ' if @right
83
105
  text_class = name
84
- options = {type: 'text', id: text_id, style: text_style, class: text_class, value: text_text, style: 'min-width: 27px;'}
106
+ options = {type: 'text', id: text_id, style: text_style, class: text_class, value: text_text}
85
107
  options = options.merge('disabled': 'disabled') unless @enabled
108
+ options = options.merge('readonly': 'readonly') if @read_only
109
+ options = options.merge('contenteditable': 'true')
86
110
  options = options.merge(type: 'password') if has_style?(:password)
87
111
  @dom ||= html {
88
- input(options)
112
+ send(element, options)
89
113
  }.to_s
90
114
  end
91
115
  end
@@ -30,9 +30,26 @@ module Glimmer
30
30
  class WidgetProxy
31
31
  include Glimmer
32
32
  include PropertyOwner
33
-
33
+
34
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
+ }
35
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
+
36
53
  SWT_CURSOR_TO_CSS_CURSOR_MAP = {
37
54
  wait: 'wait',
38
55
  sizenwse: 'nwse-resize',
@@ -141,7 +158,7 @@ module Glimmer
141
158
  @block = block
142
159
  # TODO consider changing children to an array (why is it a Set if order matters?)
143
160
  @children = Set.new # TODO consider moving to composite
144
- @enabled = true
161
+ @enabled = true if @enabled.nil?
145
162
  DEFAULT_INITIALIZERS[self.class.underscored_widget_name(self).to_s.to_sym]&.call(self)
146
163
  @parent.post_initialize_child(self) # TODO rename to post_initialize_child to be closer to glimmer-dsl-swt terminology
147
164
  end
@@ -314,9 +331,10 @@ module Glimmer
314
331
  brand_new = @dom.nil? || old_element.empty? || brand_new
315
332
  build_dom(layout: !custom_parent_dom_element) # TODO handle custom parent layout by passing parent instead of parent dom element
316
333
  if brand_new
317
- the_parent_dom_element.append(@dom) # TODO make a method attach to allow subclasses to override if needed
334
+ # TODO make a method attach to allow subclasses to override if needed
335
+ attach(the_parent_dom_element)
318
336
  else
319
- old_element.replace_with(@dom)
337
+ reattach(old_element)
320
338
  end
321
339
  observation_requests&.each do |keyword, event_listener_set|
322
340
  event_listener_set.each do |event_listener|
@@ -330,6 +348,14 @@ module Glimmer
330
348
  content_on_render_blocks.each { |content_block| content(&content_block) } unless skip_content_on_render_blocks?
331
349
  end
332
350
  alias redraw render
351
+
352
+ def attach(the_parent_dom_element)
353
+ the_parent_dom_element.append(@dom)
354
+ end
355
+
356
+ def reattach(old_element)
357
+ old_element.replace_with(@dom)
358
+ end
333
359
 
334
360
  def content_on_render_blocks
335
361
  @content_on_render_blocks ||= []
@@ -350,7 +376,7 @@ module Glimmer
350
376
  def build_dom(layout: true)
351
377
  # TODO consider passing parent element instead and having table item include a table cell widget only for opal
352
378
  @dom = nil
353
- @dom = dom
379
+ @dom = dom # TODO unify how to build dom for most widgets based on element, id, and name (class)
354
380
  @dom = @parent.get_layout.dom(@dom) if @parent.respond_to?(:layout) && @parent.get_layout
355
381
  @dom
356
382
  end
@@ -373,7 +399,6 @@ module Glimmer
373
399
  mouse_event_handler = -> (event_listener) {
374
400
  -> (event) {
375
401
  # TODO generalize this solution to all widgets that support key presses
376
- # TODO support event.location once DOM3 is supported by opal-jquery
377
402
  event.define_singleton_method(:widget) {myself}
378
403
  event.define_singleton_method(:button, &event.method(:which))
379
404
  event.define_singleton_method(:count) {1} # TODO support double-click count of 2 in the future by using ondblclick
@@ -401,7 +426,6 @@ module Glimmer
401
426
  mouse_move_event_handler = -> (event_listener) {
402
427
  -> (event) {
403
428
  # TODO generalize this solution to all widgets that support key presses
404
- # TODO support event.location once DOM3 is supported by opal-jquery
405
429
  event.define_singleton_method(:widget) {myself}
406
430
  event.define_singleton_method(:button, &event.method(:which))
407
431
  event.define_singleton_method(:count) {1} # TODO support double-click count of 2 in the future by using ondblclick
@@ -426,7 +450,6 @@ module Glimmer
426
450
  context_menu_handler = -> (event_listener) {
427
451
  -> (event) {
428
452
  # TODO generalize this solution to all widgets that support key presses
429
- # TODO support event.location once DOM3 is supported by opal-jquery
430
453
  event.define_singleton_method(:widget) {myself}
431
454
  event.define_singleton_method(:button, &event.method(:which))
432
455
  event.define_singleton_method(:count) {1} # TODO support double-click count of 2 in the future by using ondblclick
@@ -507,10 +530,15 @@ module Glimmer
507
530
  event: 'keypress',
508
531
  event_handler: -> (event_listener) {
509
532
  -> (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
533
  event.define_singleton_method(:widget) {myself}
513
- event.define_singleton_method(:keyCode) {event.which}
534
+ event.define_singleton_method(:keyLocation) do
535
+ location = `#{event.to_n}.originalEvent.location`
536
+ JS_LOCATION_TO_SWT_KEY_LOCATION_MAP[location] || location
537
+ end
538
+ event.define_singleton_method(:key_location, &event.method(:keyLocation))
539
+ event.define_singleton_method(:keyCode) {
540
+ JS_KEY_CODE_TO_SWT_KEY_CODE_MAP[event.which] || event.which
541
+ }
514
542
  event.define_singleton_method(:key_code, &event.method(:keyCode))
515
543
  event.define_singleton_method(:character) {event.which.chr}
516
544
  event.define_singleton_method(:stateMask) do
@@ -541,50 +569,18 @@ module Glimmer
541
569
  }
542
570
  } },
543
571
  'on_key_released' => {
544
- event: 'keydown',
572
+ event: 'keyup',
545
573
  event_handler: -> (event_listener) {
546
574
  -> (event) {
547
- # TODO generalize this solution to all widgets that support key presses
548
- # TODO support event.location once DOM3 is supported by opal-jquery
549
- event.define_singleton_method(:widget) {myself}
550
- event.define_singleton_method(:keyCode) {event.which}
551
- event.define_singleton_method(:key_code, &event.method(:keyCode))
552
- event.define_singleton_method(:character) {event.which.chr}
553
- event.define_singleton_method(:stateMask) do
554
- state_mask = 0
555
- state_mask |= SWTProxy[:alt] if event.alt_key
556
- state_mask |= SWTProxy[:ctrl] if event.ctrl_key
557
- state_mask |= SWTProxy[:shift] if event.shift_key
558
- state_mask |= SWTProxy[:command] if event.meta_key
559
- state_mask
560
- end
561
- event.define_singleton_method(:state_mask, &event.method(:stateMask))
562
- doit = true
563
- event.define_singleton_method(:doit=) do |value|
564
- doit = value
565
- end
566
- event.define_singleton_method(:doit) { doit }
567
- event_listener.call(event)
568
-
569
- # TODO Fix doit false, it's not stopping input
570
- unless doit
571
- event.prevent
572
- event.prevent_default
573
- event.stop_propagation
574
- event.stop_immediate_propagation
575
+ event.define_singleton_method(:keyLocation) do
576
+ location = `#{event.to_n}.originalEvent.location`
577
+ JS_LOCATION_TO_SWT_KEY_LOCATION_MAP[location] || location
575
578
  end
576
-
577
- doit
578
- }
579
- } },
580
- 'on_swt_keydown' => {
581
- event: 'keypress',
582
- event_handler: -> (event_listener) {
583
- -> (event) {
584
- # TODO generalize this solution to all widgets that support key presses
585
- # TODO support event.location once DOM3 is supported by opal-jquery
579
+ event.define_singleton_method(:key_location, &event.method(:keyLocation))
586
580
  event.define_singleton_method(:widget) {myself}
587
- event.define_singleton_method(:keyCode) {event.which}
581
+ event.define_singleton_method(:keyCode) {
582
+ JS_KEY_CODE_TO_SWT_KEY_CODE_MAP[event.which] || event.which
583
+ }
588
584
  event.define_singleton_method(:key_code, &event.method(:keyCode))
589
585
  event.define_singleton_method(:character) {event.which.chr}
590
586
  event.define_singleton_method(:stateMask) do
@@ -613,15 +609,108 @@ module Glimmer
613
609
 
614
610
  doit
615
611
  }
616
- } },
612
+ }
613
+ },
614
+ 'on_swt_keydown' => [
615
+ {
616
+ event: 'keypress',
617
+ event_handler: -> (event_listener) {
618
+ -> (event) {
619
+ event.define_singleton_method(:keyLocation) do
620
+ location = `#{event.to_n}.originalEvent.location`
621
+ JS_LOCATION_TO_SWT_KEY_LOCATION_MAP[location] || location
622
+ end
623
+ event.define_singleton_method(:key_location, &event.method(:keyLocation))
624
+ event.define_singleton_method(:keyCode) {
625
+ JS_KEY_CODE_TO_SWT_KEY_CODE_MAP[event.which] || event.which
626
+ }
627
+ event.define_singleton_method(:key_code, &event.method(:keyCode))
628
+ event.define_singleton_method(:widget) {myself}
629
+ event.define_singleton_method(:character) {event.which.chr}
630
+ event.define_singleton_method(:stateMask) do
631
+ state_mask = 0
632
+ state_mask |= SWTProxy[:alt] if event.alt_key
633
+ state_mask |= SWTProxy[:ctrl] if event.ctrl_key
634
+ state_mask |= SWTProxy[:shift] if event.shift_key
635
+ state_mask |= SWTProxy[:command] if event.meta_key
636
+ state_mask
637
+ end
638
+ event.define_singleton_method(:state_mask, &event.method(:stateMask))
639
+ doit = true
640
+ event.define_singleton_method(:doit=) do |value|
641
+ doit = value
642
+ end
643
+ event.define_singleton_method(:doit) { doit }
644
+ event_listener.call(event)
645
+
646
+ # TODO Fix doit false, it's not stopping input
647
+ unless doit
648
+ event.prevent
649
+ event.prevent_default
650
+ event.stop_propagation
651
+ event.stop_immediate_propagation
652
+ end
653
+
654
+ doit
655
+ }
656
+ }
657
+ },
658
+ {
659
+ event: 'keydown',
660
+ event_handler: -> (event_listener) {
661
+ -> (event) {
662
+ event.define_singleton_method(:keyLocation) do
663
+ location = `#{event.to_n}.originalEvent.location`
664
+ JS_LOCATION_TO_SWT_KEY_LOCATION_MAP[location] || location
665
+ end
666
+ event.define_singleton_method(:key_location, &event.method(:keyLocation))
667
+ event.define_singleton_method(:keyCode) {
668
+ JS_KEY_CODE_TO_SWT_KEY_CODE_MAP[event.which] || event.which
669
+ }
670
+ event.define_singleton_method(:key_code, &event.method(:keyCode))
671
+ event.define_singleton_method(:widget) {myself}
672
+ event.define_singleton_method(:character) {event.which.chr}
673
+ event.define_singleton_method(:stateMask) do
674
+ state_mask = 0
675
+ state_mask |= SWTProxy[:alt] if event.alt_key
676
+ state_mask |= SWTProxy[:ctrl] if event.ctrl_key
677
+ state_mask |= SWTProxy[:shift] if event.shift_key
678
+ state_mask |= SWTProxy[:command] if event.meta_key
679
+ state_mask
680
+ end
681
+ event.define_singleton_method(:state_mask, &event.method(:stateMask))
682
+ doit = true
683
+ event.define_singleton_method(:doit=) do |value|
684
+ doit = value
685
+ end
686
+ event.define_singleton_method(:doit) { doit }
687
+ event_listener.call(event) if event.which != 13 && (event.which == 127 || event.which <= 40)
688
+
689
+ # TODO Fix doit false, it's not stopping input
690
+ unless doit
691
+ event.prevent
692
+ event.prevent_default
693
+ event.stop_propagation
694
+ event.stop_immediate_propagation
695
+ end
696
+ doit
697
+ }
698
+ }
699
+ }
700
+ ],
617
701
  'on_swt_keyup' => {
618
- event: 'keydown',
702
+ event: 'keyup',
619
703
  event_handler: -> (event_listener) {
620
704
  -> (event) {
621
- # TODO generalize this solution to all widgets that support key presses
622
- # TODO support event.location once DOM3 is supported by opal-jquery
705
+ event.define_singleton_method(:keyLocation) do
706
+ location = `#{event.to_n}.originalEvent.location`
707
+ JS_LOCATION_TO_SWT_KEY_LOCATION_MAP[location] || location
708
+ end
709
+ event.define_singleton_method(:key_location, &event.method(:keyLocation))
623
710
  event.define_singleton_method(:widget) {myself}
624
- event.define_singleton_method(:keyCode) {event.which}
711
+ event.define_singleton_method(:keyCode) {
712
+ JS_KEY_CODE_TO_SWT_KEY_CODE_MAP[event.which] || event.which
713
+ }
625
714
  event.define_singleton_method(:key_code, &event.method(:keyCode))
626
715
  event.define_singleton_method(:character) {event.which.chr}
627
716
  event.define_singleton_method(:stateMask) do
@@ -800,11 +889,7 @@ module Glimmer
800
889
  end
801
890
  the_listener_dom_element = event_element_css_selector ? Element[event_element_css_selector] : listener_dom_element
802
891
  unless the_listener_dom_element.empty?
803
- if is_a?(DisplayProxy) && event == 'keydown'
804
- `document.addEventListener('keydown', #{async_event_listener})`
805
- else
806
- the_listener_dom_element.on(event, &async_event_listener)
807
- end
892
+ the_listener_dom_element.on(event, &async_event_listener)
808
893
  # TODO ensure uniqueness of insertion (perhaps adding equals/hash method to event listener proxy)
809
894
 
810
895
  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)
@@ -1067,6 +1152,7 @@ require 'glimmer/swt/combo_proxy'
1067
1152
  require 'glimmer/swt/c_combo_proxy'
1068
1153
  require 'glimmer/swt/checkbox_proxy'
1069
1154
  require 'glimmer/swt/composite_proxy'
1155
+ require 'glimmer/swt/canvas_proxy'
1070
1156
  require 'glimmer/swt/date_time_proxy'
1071
1157
  require 'glimmer/swt/group_proxy'
1072
1158
  require 'glimmer/swt/label_proxy'