glimmer-dsl-opal 0.26.1 → 0.28.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
575
+ event.define_singleton_method(:keyLocation) do
576
+ location = `#{event.to_n}.originalEvent.location`
577
+ JS_LOCATION_TO_SWT_KEY_LOCATION_MAP[location] || location
560
578
  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
- 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
@@ -1063,6 +1152,7 @@ require 'glimmer/swt/combo_proxy'
1063
1152
  require 'glimmer/swt/c_combo_proxy'
1064
1153
  require 'glimmer/swt/checkbox_proxy'
1065
1154
  require 'glimmer/swt/composite_proxy'
1155
+ require 'glimmer/swt/canvas_proxy'
1066
1156
  require 'glimmer/swt/date_time_proxy'
1067
1157
  require 'glimmer/swt/group_proxy'
1068
1158
  require 'glimmer/swt/label_proxy'