glimmer-dsl-opal 0.26.0 → 0.27.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0deb6c6d04586f92d01c22a4228072fcfa145359121f33d92265c580fc1abd91
4
- data.tar.gz: fc11c74ce51115dc92548debd2bf3a1d590ba638915de71f33455ee62a82c5fb
3
+ metadata.gz: 885895f5a47d453757426eb0b05e0b413972ef5b11f5c9045c8df92c4c1cd03d
4
+ data.tar.gz: a33b454cd1229e8b6d640d31f55379875fdde969b3634ef85e524496b277117f
5
5
  SHA512:
6
- metadata.gz: e7849b84f8ee8c749c69636abbe7490a3ac2585957fa7c526b1a2a322eb40d7d1bfdba66e344c8f1f3b76095fb1a2ed5210ae62c08db093828be823f10fd9e33
7
- data.tar.gz: 12125b86cdd30f321311e3909b8f50e4383eb2fea2938b4983d02a5860f0d3a056d50dce9d94abe7a68f557d1c374d998e3fcfb25de90edc1d3b936cc033f1b6
6
+ metadata.gz: dad2612713d1ebcc95cc08fc0bdaddbb45a9f07032af5e583da857adba54327752f853d8f28bfd76d545c7271e9be86e825d42d600c798775328864e8d651927
7
+ data.tar.gz: 037c3e6f77c68a8edf343b3323b543f708adf5f41dffb03944148670ac46aa786cafbecb12675c24a5d4c5e3242ff2929886214d6ea43d9017de588ddc5db486
data/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.27.0
4
+
5
+ - Hello, Text!
6
+ - Support unbordered `text` widget if SWT style `:none` was passed
7
+ - Support `:center`, `:left`, `:right` SWT styles for `text` widget
8
+ - Support `:read_only` SWT style for `text` widget
9
+ - Support `text` widget `on_verify_text` `event.doit = false` cancellation feature
10
+
11
+ ## 0.26.3
12
+
13
+ - Support key_event.key_location in all key capturing widgets, not just display
14
+
15
+ ## 0.26.2
16
+
17
+ - Support key_event.key_location to distinguish between left and right alt/shift/command/ctrl buttons
18
+ - Use right/left alt/shift keys in Tetris for rotate right and rotate left
19
+
20
+ ## 0.26.1
21
+
22
+ - Support display on_swt_keydown event keyCode/key_code values for arrow keys and alt/shift/ctrl
23
+ - Use arrow keys for movement in Tetris
24
+ - Use alt/shift keys for rotate right in Tetris
25
+
3
26
  ## 0.26.0
4
27
 
5
28
  - Tetris elaborate sample (minimal initial version of the one in Glimmer DSL for SWT)
data/README.md CHANGED
@@ -145,7 +145,7 @@ Hello, Table! Game Booked
145
145
 
146
146
  NOTE: Glimmer DSL for Opal is an alpha project. Please help make better by contributing, adopting for small or low risk projects, and providing feedback. It is still an early alpha, so the more feedback and issues you report the better.
147
147
 
148
- **Alpha Version** 0.25.4 only supports bare-minimum capabilities for the included [samples](https://github.com/AndyObtiva/glimmer-dsl-opal#samples) (originally written for [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt))
148
+ **Alpha Version** 0.27.0 only supports bare-minimum capabilities for the included [samples](https://github.com/AndyObtiva/glimmer-dsl-opal#samples) (originally written for [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt))
149
149
 
150
150
  Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
151
151
  - [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)
@@ -269,7 +269,7 @@ gem 'opal', '1.0.5'
269
269
  gem 'opal-rails', '1.1.2'
270
270
  gem 'opal-async', '~> 1.4.0'
271
271
  gem 'opal-jquery', '~> 0.4.4'
272
- gem 'glimmer-dsl-opal', '~> 0.25.4'
272
+ gem 'glimmer-dsl-opal', '~> 0.27.0'
273
273
  gem 'glimmer-dsl-xml', '~> 1.2.0', require: false
274
274
  gem 'glimmer-dsl-css', '~> 1.2.0', require: false
275
275
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.26.0
1
+ 0.27.0
@@ -28,7 +28,7 @@ module Glimmer
28
28
  attr_reader :closeable_children
29
29
 
30
30
  def initialize(parent, args, block)
31
- @closeable_children = args.detect { |arg| SWTProxy[:close] == SWTProxy[arg] }
31
+ @closeable_children = !!args.detect { |arg| SWTProxy[arg] == SWTProxy[:close] }
32
32
  super(parent, args, block)
33
33
  end
34
34
 
@@ -55,45 +55,6 @@ module Glimmer
55
55
  }
56
56
  }
57
57
  },
58
- 'on_key_pressed' => {
59
- event: 'keydown',
60
- event_handler: -> (event_listener) {
61
- -> (event) {
62
- @last_key_pressed_event = event
63
- @text = event.target.value
64
- # TODO generalize this solution to all widgets that support key presses
65
- # TODO support event.location once DOM3 is supported by opal-jquery
66
- event.define_singleton_method(:keyCode) {event.which}
67
- event.define_singleton_method(:key_code, &event.method(:keyCode))
68
- event.define_singleton_method(:character) {event.which.chr}
69
- event.define_singleton_method(:stateMask) do
70
- state_mask = 0
71
- state_mask |= SWTProxy[:alt] if event.alt_key
72
- state_mask |= SWTProxy[:ctrl] if event.ctrl_key
73
- state_mask |= SWTProxy[:shift] if event.shift_key
74
- state_mask |= SWTProxy[:command] if event.meta_key
75
- state_mask
76
- end
77
- event.define_singleton_method(:state_mask, &event.method(:stateMask))
78
- doit = true
79
- event.define_singleton_method(:doit=) do |value|
80
- doit = value
81
- end
82
- event.define_singleton_method(:doit) { doit }
83
- event_listener.call(event)
84
-
85
- # TODO Fix doit false, it's not stopping input
86
- unless doit
87
- event.prevent
88
- event.prevent_default
89
- event.stop_propagation
90
- event.stop_immediate_propagation
91
- end
92
-
93
- doit
94
- }
95
- }
96
- },
97
58
  }
98
59
  end
99
60
 
@@ -136,43 +136,6 @@ module Glimmer
136
136
  }
137
137
  },
138
138
  ],
139
- 'on_key_pressed' => {
140
- event: 'keydown',
141
- event_handler: -> (event_listener) {
142
- -> (event) {
143
- # TODO generalize this solution to all widgets that support key presses
144
- # TODO support event.location once DOM3 is supported by opal-jquery
145
- event.define_singleton_method(:keyCode) {event.which}
146
- event.define_singleton_method(:key_code, &event.method(:keyCode))
147
- event.define_singleton_method(:character) {event.which.chr}
148
- event.define_singleton_method(:stateMask) do
149
- state_mask = 0
150
- state_mask |= SWTProxy[:alt] if event.alt_key
151
- state_mask |= SWTProxy[:ctrl] if event.ctrl_key
152
- state_mask |= SWTProxy[:shift] if event.shift_key
153
- state_mask |= SWTProxy[:command] if event.meta_key
154
- state_mask
155
- end
156
- event.define_singleton_method(:state_mask, &event.method(:stateMask))
157
- doit = true
158
- event.define_singleton_method(:doit=) do |value|
159
- doit = value
160
- end
161
- event.define_singleton_method(:doit) { doit }
162
- event_listener.call(event)
163
-
164
- # TODO Fix doit false, it's not stopping input
165
- unless doit
166
- event.prevent
167
- event.prevent_default
168
- event.stop_propagation
169
- event.stop_immediate_propagation
170
- end
171
-
172
- doit
173
- }
174
- }
175
- },
176
139
  }
177
140
  end
178
141
 
@@ -1,4 +1,5 @@
1
1
  require 'glimmer/swt/widget_proxy'
2
+ require 'glimmer/swt/swt_proxy'
2
3
 
3
4
  module Glimmer
4
5
  module SWT
@@ -85,91 +86,6 @@ module Glimmer
85
86
  # sync_exec kept for API compatibility reasons
86
87
  alias sync_exec async_exec
87
88
 
88
- def observation_request_to_event_mapping
89
- {
90
- 'on_swt_keydown' => [
91
- {
92
- event: 'keypress',
93
- event_handler: -> (event_listener) {
94
- -> (event) {
95
- event.singleton_class.define_method(:character) do
96
- which || key_code
97
- end
98
- event.define_singleton_method(:keyCode) {event.which}
99
- event.define_singleton_method(:key_code, &event.method(:keyCode))
100
- # TODO support alt/ctrl/shift/command & arrow keys in keyCode
101
- event.define_singleton_method(:character) {event.which.chr}
102
- event.define_singleton_method(:stateMask) do
103
- state_mask = 0
104
- state_mask |= SWTProxy[:alt] if event.alt_key
105
- state_mask |= SWTProxy[:ctrl] if event.ctrl_key
106
- state_mask |= SWTProxy[:shift] if event.shift_key
107
- state_mask |= SWTProxy[:command] if event.meta_key
108
- state_mask
109
- end
110
- event.define_singleton_method(:state_mask, &event.method(:stateMask))
111
- doit = true
112
- event.define_singleton_method(:doit=) do |value|
113
- doit = value
114
- end
115
- event.define_singleton_method(:doit) { doit }
116
- event_listener.call(event)
117
-
118
- # TODO Fix doit false, it's not stopping input
119
- unless doit
120
- event.prevent
121
- event.prevent_default
122
- event.stop_propagation
123
- event.stop_immediate_propagation
124
- end
125
-
126
- doit
127
- }
128
- }
129
- },
130
- {
131
- event: 'keydown',
132
- event_handler: -> (event_listener) {
133
- -> (event) {
134
- event.singleton_class.define_method(:character) do
135
- which || key_code
136
- end
137
- event.define_singleton_method(:keyCode) {event.which}
138
- event.define_singleton_method(:key_code, &event.method(:keyCode))
139
- # TODO support alt/ctrl/shift/command & arrow keys in keyCode
140
- event.define_singleton_method(:character) {event.which.chr}
141
- event.define_singleton_method(:stateMask) do
142
- state_mask = 0
143
- state_mask |= SWTProxy[:alt] if event.alt_key
144
- state_mask |= SWTProxy[:ctrl] if event.ctrl_key
145
- state_mask |= SWTProxy[:shift] if event.shift_key
146
- state_mask |= SWTProxy[:command] if event.meta_key
147
- state_mask
148
- end
149
- event.define_singleton_method(:state_mask, &event.method(:stateMask))
150
- doit = true
151
- event.define_singleton_method(:doit=) do |value|
152
- doit = value
153
- end
154
- event.define_singleton_method(:doit) { doit }
155
- event_listener.call(event) if event.key_code != 13 && (event.key_code == 127 || event.key_code <= 31)
156
-
157
- # TODO Fix doit false, it's not stopping input
158
- unless doit
159
- event.prevent
160
- event.prevent_default
161
- event.stop_propagation
162
- event.stop_immediate_propagation
163
- end
164
-
165
- doit
166
- }
167
- }
168
- }
169
- ]
170
- }
171
- end
172
-
173
89
  private
174
90
 
175
91
  def async_exec_queues
@@ -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
@@ -32,7 +32,24 @@ module 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
@@ -373,7 +390,6 @@ module Glimmer
373
390
  mouse_event_handler = -> (event_listener) {
374
391
  -> (event) {
375
392
  # TODO generalize this solution to all widgets that support key presses
376
- # TODO support event.location once DOM3 is supported by opal-jquery
377
393
  event.define_singleton_method(:widget) {myself}
378
394
  event.define_singleton_method(:button, &event.method(:which))
379
395
  event.define_singleton_method(:count) {1} # TODO support double-click count of 2 in the future by using ondblclick
@@ -401,7 +417,6 @@ module Glimmer
401
417
  mouse_move_event_handler = -> (event_listener) {
402
418
  -> (event) {
403
419
  # TODO generalize this solution to all widgets that support key presses
404
- # TODO support event.location once DOM3 is supported by opal-jquery
405
420
  event.define_singleton_method(:widget) {myself}
406
421
  event.define_singleton_method(:button, &event.method(:which))
407
422
  event.define_singleton_method(:count) {1} # TODO support double-click count of 2 in the future by using ondblclick
@@ -426,7 +441,6 @@ module Glimmer
426
441
  context_menu_handler = -> (event_listener) {
427
442
  -> (event) {
428
443
  # TODO generalize this solution to all widgets that support key presses
429
- # TODO support event.location once DOM3 is supported by opal-jquery
430
444
  event.define_singleton_method(:widget) {myself}
431
445
  event.define_singleton_method(:button, &event.method(:which))
432
446
  event.define_singleton_method(:count) {1} # TODO support double-click count of 2 in the future by using ondblclick
@@ -507,10 +521,15 @@ module Glimmer
507
521
  event: 'keypress',
508
522
  event_handler: -> (event_listener) {
509
523
  -> (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
524
  event.define_singleton_method(:widget) {myself}
513
- 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
+ }
514
533
  event.define_singleton_method(:key_code, &event.method(:keyCode))
515
534
  event.define_singleton_method(:character) {event.which.chr}
516
535
  event.define_singleton_method(:stateMask) do
@@ -541,50 +560,18 @@ module Glimmer
541
560
  }
542
561
  } },
543
562
  'on_key_released' => {
544
- event: 'keydown',
563
+ event: 'keyup',
545
564
  event_handler: -> (event_listener) {
546
565
  -> (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
566
+ event.define_singleton_method(:keyLocation) do
567
+ location = `#{event.to_n}.originalEvent.location`
568
+ JS_LOCATION_TO_SWT_KEY_LOCATION_MAP[location] || location
565
569
  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
570
+ event.define_singleton_method(:key_location, &event.method(:keyLocation))
586
571
  event.define_singleton_method(:widget) {myself}
587
- 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
+ }
588
575
  event.define_singleton_method(:key_code, &event.method(:keyCode))
589
576
  event.define_singleton_method(:character) {event.which.chr}
590
577
  event.define_singleton_method(:stateMask) do
@@ -613,15 +600,108 @@ module Glimmer
613
600
 
614
601
  doit
615
602
  }
616
- } },
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(:widget) {myself}
620
+ event.define_singleton_method(:character) {event.which.chr}
621
+ event.define_singleton_method(:stateMask) do
622
+ state_mask = 0
623
+ state_mask |= SWTProxy[:alt] if event.alt_key
624
+ state_mask |= SWTProxy[:ctrl] if event.ctrl_key
625
+ state_mask |= SWTProxy[:shift] if event.shift_key
626
+ state_mask |= SWTProxy[:command] if event.meta_key
627
+ state_mask
628
+ end
629
+ event.define_singleton_method(:state_mask, &event.method(:stateMask))
630
+ doit = true
631
+ event.define_singleton_method(:doit=) do |value|
632
+ doit = value
633
+ end
634
+ event.define_singleton_method(:doit) { doit }
635
+ event_listener.call(event)
636
+
637
+ # TODO Fix doit false, it's not stopping input
638
+ unless doit
639
+ event.prevent
640
+ event.prevent_default
641
+ event.stop_propagation
642
+ event.stop_immediate_propagation
643
+ end
644
+
645
+ doit
646
+ }
647
+ }
648
+ },
649
+ {
650
+ event: 'keydown',
651
+ event_handler: -> (event_listener) {
652
+ -> (event) {
653
+ event.define_singleton_method(:keyLocation) do
654
+ location = `#{event.to_n}.originalEvent.location`
655
+ JS_LOCATION_TO_SWT_KEY_LOCATION_MAP[location] || location
656
+ end
657
+ event.define_singleton_method(:key_location, &event.method(:keyLocation))
658
+ event.define_singleton_method(:keyCode) {
659
+ JS_KEY_CODE_TO_SWT_KEY_CODE_MAP[event.which] || event.which
660
+ }
661
+ event.define_singleton_method(:key_code, &event.method(:keyCode))
662
+ event.define_singleton_method(:widget) {myself}
663
+ event.define_singleton_method(:character) {event.which.chr}
664
+ event.define_singleton_method(:stateMask) do
665
+ state_mask = 0
666
+ state_mask |= SWTProxy[:alt] if event.alt_key
667
+ state_mask |= SWTProxy[:ctrl] if event.ctrl_key
668
+ state_mask |= SWTProxy[:shift] if event.shift_key
669
+ state_mask |= SWTProxy[:command] if event.meta_key
670
+ state_mask
671
+ end
672
+ event.define_singleton_method(:state_mask, &event.method(:stateMask))
673
+ doit = true
674
+ event.define_singleton_method(:doit=) do |value|
675
+ doit = value
676
+ end
677
+ event.define_singleton_method(:doit) { doit }
678
+ event_listener.call(event) if event.which != 13 && (event.which == 127 || event.which <= 40)
679
+
680
+ # TODO Fix doit false, it's not stopping input
681
+ unless doit
682
+ event.prevent
683
+ event.prevent_default
684
+ event.stop_propagation
685
+ event.stop_immediate_propagation
686
+ end
687
+ doit
688
+ }
689
+ }
690
+ }
691
+ ],
617
692
  'on_swt_keyup' => {
618
- event: 'keydown',
693
+ event: 'keyup',
619
694
  event_handler: -> (event_listener) {
620
695
  -> (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
696
+ event.define_singleton_method(:keyLocation) do
697
+ location = `#{event.to_n}.originalEvent.location`
698
+ JS_LOCATION_TO_SWT_KEY_LOCATION_MAP[location] || location
699
+ end
700
+ event.define_singleton_method(:key_location, &event.method(:keyLocation))
623
701
  event.define_singleton_method(:widget) {myself}
624
- event.define_singleton_method(:keyCode) {event.which}
702
+ event.define_singleton_method(:keyCode) {
703
+ JS_KEY_CODE_TO_SWT_KEY_CODE_MAP[event.which] || event.which
704
+ }
625
705
  event.define_singleton_method(:key_code, &event.method(:keyCode))
626
706
  event.define_singleton_method(:character) {event.which.chr}
627
707
  event.define_singleton_method(:stateMask) do
@@ -19,8 +19,6 @@
19
19
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
20
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
- # require_relative 'bevel'
23
-
24
22
  class Tetris
25
23
  module View
26
24
  class Block
@@ -31,9 +29,6 @@ class Tetris
31
29
  body {
32
30
  canvas { |canvas_proxy|
33
31
  background <= [game_playfield[row][column], :color]
34
- # bevel(size: block_size) {
35
- # base_color <= [game_playfield[row][column], :color]
36
- # }
37
32
  }
38
33
  }
39
34
  end
@@ -29,7 +29,7 @@ class Tetris
29
29
  options :game_playfield, :playfield_width, :playfield_height, :block_size
30
30
 
31
31
  body {
32
- composite((:double_buffered unless OS.mac?)) {
32
+ composite {
33
33
  grid_layout {
34
34
  num_columns playfield_width
35
35
  make_columns_equal_width true
@@ -39,10 +39,6 @@ class Tetris
39
39
  row_layout {
40
40
  type :vertical
41
41
  center true
42
- # fill true
43
- # margin_width 0
44
- # margin_right block_size
45
- # margin_height block_size
46
42
  }
47
43
  label(:center) {
48
44
  text 'Next'
@@ -25,8 +25,11 @@ require_relative 'tetris/view/playfield'
25
25
  require_relative 'tetris/view/score_lane'
26
26
  require_relative 'tetris/view/high_score_dialog'
27
27
  require_relative 'tetris/view/tetris_menu_bar'
28
-
29
- # Tetris App View Custom Shell (represents `tetris` keyword)
28
+ class Event
29
+ def location
30
+ `#@native.location`
31
+ end
32
+ end
30
33
  class Tetris
31
34
  include Glimmer::UI::CustomShell
32
35
 
@@ -49,7 +52,7 @@ class Tetris
49
52
  display {
50
53
  on_swt_keydown do |key_event|
51
54
  case key_event.keyCode
52
- when 'w'.bytes.first
55
+ when swt(:arrow_up), 'w'.bytes.first
53
56
  case game.up_arrow_action
54
57
  when :instant_down
55
58
  game.down!(instant: true)
@@ -58,17 +61,24 @@ class Tetris
58
61
  when :rotate_left
59
62
  game.rotate!(:left)
60
63
  end
61
- when 's'.bytes.first
64
+ when swt(:arrow_down), 's'.bytes.first
62
65
  game.down!
63
- when 'a'.bytes.first
66
+ when swt(:arrow_left), 'a'.bytes.first
64
67
  game.left!
65
- when 'd'.bytes.first
68
+ when swt(:arrow_right), 'd'.bytes.first
66
69
  game.right!
67
70
  when 'q'.bytes.first
68
71
  game.rotate!(:left)
69
72
  when 'e'.bytes.first
70
73
  game.rotate!(:right)
74
+ when swt(:shift), swt(:alt)
75
+ if key_event.keyLocation == swt(:right) # right key
76
+ game.rotate!(:right)
77
+ elsif key_event.keyLocation == swt(:left) # left key
78
+ game.rotate!(:left)
79
+ end
71
80
  end
81
+
72
82
  end
73
83
  }
74
84
  end
@@ -102,8 +112,6 @@ class Tetris
102
112
  }
103
113
 
104
114
  text 'Glimmer Tetris'
105
- # minimum_size 475, 500
106
- # image tetris_icon
107
115
  background rgb(236, 236, 236)
108
116
 
109
117
  tetris_menu_bar(game: game)
@@ -119,30 +127,11 @@ class Tetris
119
127
  }
120
128
  }
121
129
  }
122
-
123
- # def tetris_icon
124
- # icon_block_size = 64
125
- # icon_bevel_size = icon_block_size.to_f / 25.to_f
126
- # icon_bevel_pixel_size = 0.16*icon_block_size.to_f
127
- # icon_size = 8
128
- # icon_pixel_size = icon_block_size * icon_size
129
- # image(icon_pixel_size, icon_pixel_size) {
130
- # icon_size.times { |row|
131
- # icon_size.times { |column|
132
- # colored = row >= 1 && column.between?(1, 6)
133
- # color = colored ? color(([:white] + Model::Tetromino::LETTER_COLORS.values).sample) : color(:white)
134
- # x = column * icon_block_size
135
- # y = row * icon_block_size
136
- # bevel(x: x, y: y, base_color: color, size: icon_block_size)
137
- # }
138
- # }
139
- # }
140
- # end
141
130
 
142
131
  def start_moving_tetrominos_down
143
132
  Async::Task.new do
144
133
  work = lambda do
145
- @game.down! # unless @game.paused?
134
+ @game.down!
146
135
  Async::Task.new(delay: @game.delay * 1000.0, &work) unless @game.game_over? || body_root.disposed?
147
136
  end
148
137
  Async::Task.new(delay: @game.delay * 1000.0, &work)
@@ -158,7 +147,7 @@ class Tetris
158
147
  def show_about_dialog
159
148
  message_box {
160
149
  text 'Glimmer Tetris'
161
- message "Glimmer Tetris\n\nGlimmer DSL for SWT Sample\n\nLeft is A\nRight is D\nDown is S\nUp is W\nRotate Left is Q\nRotate Right is E\n\n for Left, Down, Right, Up\n\nCopyright (c) 2007-2021 Andy Maleh"
150
+ message "Glimmer Tetris\n\nGlimmer DSL for SWT Sample\n\nUse arrow keys for movement\nand right/left alt/shift keys for rotation\nAlternatively:\nLeft is A\nRight is D\nDown is S\nUp is W\nRotate Left is Q\nRotate Right is E\n\n for Left, Down, Right, Up\n\nCopyright (c) 2007-2021 Andy Maleh"
162
151
  }.open
163
152
  end
164
153
  end
@@ -0,0 +1,149 @@
1
+ # Copyright (c) 2020-2021 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ class HelloText
23
+ include Glimmer::UI::CustomShell
24
+
25
+ attr_accessor :default, :no_border, :center, :left, :right, :password, :telephone, :read_only, :wrap, :multi
26
+
27
+ before_body do
28
+ self.default = 'default is :border style'
29
+ self.no_border = 'no border'
30
+ self.center = 'centered'
31
+ self.left = 'left-aligned'
32
+ self.right = 'right-aligned'
33
+ self.password = 'password'
34
+ self.telephone = '555-555-5555'
35
+ self.read_only = 'Telephone area code is 555'
36
+ self.wrap = 'wraps if text content is too long like this example'
37
+ self.multi = "multi-line enables hitting enter,\nbut works like wrap on the web"
38
+ end
39
+
40
+ body {
41
+ shell {
42
+ grid_layout 2, false
43
+
44
+ text 'Hello, Text!'
45
+ minimum_size 350, 100
46
+
47
+ label {
48
+ text 'text'
49
+ }
50
+ text { # includes :border style by default
51
+ layout_data :fill, :center, true, false
52
+ text <=> [self, :default]
53
+ }
54
+
55
+ label {
56
+ text 'text(:none)'
57
+ }
58
+ text(:none) { # no border
59
+ layout_data :fill, :center, true, false
60
+ text <=> [self, :no_border]
61
+ }
62
+
63
+ label {
64
+ text 'text(:center, :border)'
65
+ }
66
+ text(:center, :border) {
67
+ layout_data :fill, :center, true, false
68
+ text <=> [self, :center]
69
+ }
70
+
71
+ label {
72
+ text 'text(:left, :border)'
73
+ }
74
+ text(:left, :border) {
75
+ layout_data :fill, :center, true, false
76
+ text <=> [self, :left]
77
+ }
78
+
79
+ label {
80
+ text 'text(:right, :border)'
81
+ }
82
+ text(:right, :border) {
83
+ layout_data :fill, :center, true, false
84
+ text <=> [self, :right]
85
+ }
86
+
87
+ label {
88
+ text 'text(:password, :border)'
89
+ }
90
+ text(:password, :border) {
91
+ layout_data :fill, :center, true, false
92
+ text <=> [self, :password]
93
+ }
94
+
95
+ label {
96
+ text 'text(:read_only, :border)'
97
+ }
98
+ text(:read_only, :border) {
99
+ layout_data :fill, :center, true, false
100
+ text <=> [self, :read_only]
101
+ }
102
+
103
+ label {
104
+ text 'text with event handlers'
105
+ }
106
+ text {
107
+ layout_data :fill, :center, true, false
108
+ text <=> [self, :telephone]
109
+
110
+ # this event kicks in just after the user typed and before modifying the text attribute value
111
+ on_verify_text do |verify_event|
112
+ new_text = verify_event.widget.text.clone
113
+ # new_text[verify_event.start...verify_event.end] = verify_event.text # Opal does not allow string mutation like JRuby in Glimmer DSL for SWT
114
+ new_text = "#{new_text[0...verify_event.start]}#{verify_event.text}#{new_text[verify_event.end..-1]}"
115
+ verify_event.doit = telephone?(new_text)
116
+ end
117
+
118
+ # this event kicks in just after the text widget is verified and modified
119
+ on_modify_text do |modify_event|
120
+ self.read_only = "Telephone area code is #{modify_event.widget.text.gsub(/[^0-9]/, '')[0...3]}"
121
+ end
122
+ }
123
+
124
+ label {
125
+ text 'text(:wrap, :border)'
126
+ }
127
+ text(:wrap, :border) {
128
+ layout_data(:fill, :center, true, false) {
129
+ width_hint 100
130
+ }
131
+ text <=> [self, :wrap]
132
+ }
133
+
134
+ label {
135
+ text 'text(:multi, :border)'
136
+ }
137
+ text(:multi, :border) {
138
+ layout_data :fill, :center, true, false
139
+ text <=> [self, :multi]
140
+ }
141
+ }
142
+ }
143
+
144
+ def telephone?(text)
145
+ !!text.match(/^\d{0,3}[-.\/]?\d{0,3}[-.\/]?\d{0,4}$/)
146
+ end
147
+ end
148
+
149
+ HelloText.launch
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer-dsl-opal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.26.0
4
+ version: 0.27.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - AndyMaleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-23 00:00:00.000000000 Z
11
+ date: 2021-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer
@@ -328,6 +328,7 @@ files:
328
328
  - lib/glimmer-dsl-opal/samples/hello/hello_tab.rb
329
329
  - lib/glimmer-dsl-opal/samples/hello/hello_table.rb
330
330
  - lib/glimmer-dsl-opal/samples/hello/hello_table/baseball_park.png
331
+ - lib/glimmer-dsl-opal/samples/hello/hello_text.rb
331
332
  - lib/glimmer-dsl-opal/samples/hello/hello_world.rb
332
333
  - lib/glimmer-dsl-opal/samples/hello/images/denmark.png
333
334
  - lib/glimmer-dsl-opal/samples/hello/images/finland.png