glimmer-dsl-opal 0.7.2 → 0.9.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +41 -0
- data/README.md +745 -82
- data/VERSION +1 -1
- data/lib/glimmer-dsl-opal.rb +14 -1
- data/lib/glimmer-dsl-opal/ext/class.rb +10 -0
- data/lib/{file.rb → glimmer-dsl-opal/ext/file.rb} +0 -0
- data/lib/glimmer-dsl-opal/ext/glimmer/dsl/engine.rb +30 -0
- data/lib/glimmer-dsl-opal/samples/elaborate/contact_manager.rb +50 -23
- data/lib/glimmer-dsl-opal/samples/elaborate/login.rb +22 -5
- data/lib/glimmer-dsl-opal/samples/hello/hello_browser.rb +24 -1
- data/lib/glimmer-dsl-opal/samples/hello/hello_button.rb +46 -0
- data/lib/glimmer-dsl-opal/samples/hello/hello_computed.rb +27 -0
- data/lib/glimmer-dsl-opal/samples/hello/hello_custom_shell.rb +7 -7
- data/lib/glimmer-dsl-opal/samples/hello/hello_list_multi_selection.rb +62 -32
- data/lib/glimmer-dsl-opal/samples/hello/hello_list_single_selection.rb +47 -22
- data/lib/glimmer-dsl-opal/samples/hello/hello_menu_bar.rb +241 -0
- data/lib/glimmer-dsl-opal/samples/hello/hello_message_box.rb +37 -0
- data/lib/glimmer-dsl-opal/samples/hello/hello_pop_up_context_menu.rb +84 -0
- data/lib/glimmer/data_binding/observable_element.rb +1 -1
- data/lib/glimmer/dsl/opal/custom_widget_expression.rb +6 -0
- data/lib/glimmer/dsl/opal/dsl.rb +2 -0
- data/lib/glimmer/dsl/opal/menu_bar_expression.rb +54 -0
- data/lib/glimmer/dsl/opal/menu_expression.rb +61 -0
- data/lib/glimmer/dsl/opal/shell_expression.rb +0 -4
- data/lib/glimmer/dsl/opal/widget_expression.rb +3 -2
- data/lib/glimmer/dsl/opal/widget_listener_expression.rb +2 -2
- data/lib/glimmer/swt/custom/checkbox_group.rb +2 -2
- data/lib/glimmer/swt/custom/radio_group.rb +2 -2
- data/lib/glimmer/swt/date_time_proxy.rb +5 -4
- data/lib/glimmer/swt/display_proxy.rb +4 -4
- data/lib/glimmer/swt/event_listener_proxy.rb +14 -4
- data/lib/glimmer/swt/font_proxy.rb +4 -4
- data/lib/glimmer/swt/grid_layout_proxy.rb +21 -12
- data/lib/glimmer/swt/label_proxy.rb +17 -6
- data/lib/glimmer/swt/latest_message_box_proxy.rb +20 -0
- data/lib/glimmer/swt/layout_data_proxy.rb +6 -6
- data/lib/glimmer/swt/list_proxy.rb +15 -0
- data/lib/glimmer/swt/menu_item_proxy.rb +174 -0
- data/lib/glimmer/swt/menu_proxy.rb +273 -0
- data/lib/glimmer/swt/message_box_proxy.rb +57 -72
- data/lib/glimmer/swt/property_owner.rb +2 -0
- data/lib/glimmer/swt/radio_proxy.rb +1 -1
- data/lib/glimmer/swt/shell_proxy.rb +34 -189
- data/lib/glimmer/swt/tab_folder_proxy.rb +43 -0
- data/lib/glimmer/swt/table_column_proxy.rb +3 -2
- data/lib/glimmer/swt/table_editor.rb +1 -1
- data/lib/glimmer/swt/table_item_proxy.rb +7 -5
- data/lib/glimmer/swt/table_proxy.rb +14 -10
- data/lib/glimmer/swt/widget_proxy.rb +327 -33
- data/lib/glimmer/ui/custom_shell.rb +9 -7
- data/lib/glimmer/ui/custom_widget.rb +3 -3
- metadata +36 -4
@@ -1,8 +1,51 @@
|
|
1
|
+
# Copyright (c) 2020 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
|
+
|
1
22
|
require 'glimmer/swt/widget_proxy'
|
2
23
|
|
3
24
|
module Glimmer
|
4
25
|
module SWT
|
5
26
|
class TabFolderProxy < WidgetProxy
|
27
|
+
STYLE = <<~CSS
|
28
|
+
.tabs .tab.selected {
|
29
|
+
background: rgb(80, 116, 211);
|
30
|
+
color: white;
|
31
|
+
}
|
32
|
+
.tabs .tab {
|
33
|
+
background-color: inherit;
|
34
|
+
float: left;
|
35
|
+
border: none;
|
36
|
+
outline: none;
|
37
|
+
cursor: pointer;
|
38
|
+
padding: 14px 16px;
|
39
|
+
transition: 0.3s;
|
40
|
+
font-size: 17px;
|
41
|
+
}
|
42
|
+
.tabs {
|
43
|
+
overflow: hidden;
|
44
|
+
border: 1px solid #ccc;
|
45
|
+
background-color: #f1f1f1;
|
46
|
+
}
|
47
|
+
CSS
|
48
|
+
|
6
49
|
attr_reader :tabs
|
7
50
|
|
8
51
|
def initialize(parent, args, block)
|
@@ -4,6 +4,8 @@ require 'glimmer/swt/swt_proxy'
|
|
4
4
|
module Glimmer
|
5
5
|
module SWT
|
6
6
|
class TableColumnProxy < WidgetProxy
|
7
|
+
include Glimmer
|
8
|
+
|
7
9
|
STYLE = <<~CSS
|
8
10
|
th.table-column {
|
9
11
|
background: rgb(246, 246, 246);
|
@@ -15,8 +17,7 @@ module Glimmer
|
|
15
17
|
float: right;
|
16
18
|
}
|
17
19
|
CSS
|
18
|
-
|
19
|
-
|
20
|
+
|
20
21
|
attr_accessor :sort_block, :sort_by_block
|
21
22
|
attr_reader :text, :width,
|
22
23
|
:no_sort, :sort_property, :editor
|
@@ -34,7 +34,7 @@ module Glimmer
|
|
34
34
|
@editor_widget = editor_widget
|
35
35
|
@old_value = table_item.cell_dom_element(table_column_index).html
|
36
36
|
table_item.cell_dom_element(table_column_index).html('')
|
37
|
-
editor_widget.render(table_item.cell_dom_element(table_column_index))
|
37
|
+
editor_widget.render(custom_parent_dom_element: table_item.cell_dom_element(table_column_index))
|
38
38
|
# TODO tweak the width perfectly so it doesn't expand the table cell
|
39
39
|
# editor_widget.dom_element.css('width', 'calc(100% - 20px)')
|
40
40
|
editor_widget.dom_element.css('width', "#{minimumWidth}%") # TODO implement property with pixels (and perhaps derive percentage separately from pixels)
|
@@ -39,7 +39,7 @@ module Glimmer
|
|
39
39
|
super(parent, args, block)
|
40
40
|
# TODO check if there is a need to remove this observer when removing widget from table upon items update
|
41
41
|
on_widget_selected { |event|
|
42
|
-
parent.select(parent.index_of(self), event.meta?)
|
42
|
+
parent.select(parent.index_of(self), (event.meta? if event.respond_to?(:meta?)))
|
43
43
|
}
|
44
44
|
end
|
45
45
|
|
@@ -147,10 +147,12 @@ module Glimmer
|
|
147
147
|
end
|
148
148
|
end
|
149
149
|
|
150
|
-
def
|
151
|
-
|
152
|
-
|
153
|
-
|
150
|
+
def observation_request_to_event_mapping
|
151
|
+
{
|
152
|
+
'on_widget_selected' => {
|
153
|
+
event: 'mouseup',
|
154
|
+
}
|
155
|
+
}
|
154
156
|
end
|
155
157
|
|
156
158
|
def max_column_width(column_index)
|
@@ -27,6 +27,16 @@ require 'glimmer/swt/table_editor'
|
|
27
27
|
module Glimmer
|
28
28
|
module SWT
|
29
29
|
class TableProxy < CompositeProxy
|
30
|
+
STYLE = <<~CSS
|
31
|
+
table {
|
32
|
+
border-spacing: 0;
|
33
|
+
}
|
34
|
+
|
35
|
+
table tr th,td {
|
36
|
+
cursor: default;
|
37
|
+
}
|
38
|
+
CSS
|
39
|
+
|
30
40
|
attr_reader :columns, :selection,
|
31
41
|
:sort_type, :sort_column, :sort_property, :sort_block, :sort_by_block, :additional_sort_properties,
|
32
42
|
:editor, :table_editor
|
@@ -128,9 +138,6 @@ module Glimmer
|
|
128
138
|
on_widget_selected {
|
129
139
|
table_proxy.finish_edit!
|
130
140
|
}
|
131
|
-
on_focus_lost {
|
132
|
-
table_proxy.finish_edit!
|
133
|
-
}
|
134
141
|
on_key_pressed { |key_event|
|
135
142
|
if key_event.keyCode == swt(:cr)
|
136
143
|
table_proxy.finish_edit!
|
@@ -153,9 +160,6 @@ module Glimmer
|
|
153
160
|
on_widget_selected {
|
154
161
|
table_proxy.finish_edit!
|
155
162
|
}
|
156
|
-
on_focus_lost {
|
157
|
-
table_proxy.finish_edit!
|
158
|
-
}
|
159
163
|
on_key_pressed { |key_event|
|
160
164
|
if key_event.keyCode == swt(:cr)
|
161
165
|
table_proxy.finish_edit!
|
@@ -362,7 +366,7 @@ module Glimmer
|
|
362
366
|
end
|
363
367
|
|
364
368
|
def sort_property=(new_sort_property)
|
365
|
-
@sort_property =
|
369
|
+
@sort_property = new_sort_property.to_collection
|
366
370
|
end
|
367
371
|
|
368
372
|
def detect_sort_type
|
@@ -383,7 +387,7 @@ module Glimmer
|
|
383
387
|
|
384
388
|
def column_sort_properties
|
385
389
|
column_properties.zip(columns.map(&:sort_property)).map do |pair|
|
386
|
-
|
390
|
+
pair.compact.last.to_collection
|
387
391
|
end
|
388
392
|
end
|
389
393
|
|
@@ -414,7 +418,7 @@ module Glimmer
|
|
414
418
|
end
|
415
419
|
end
|
416
420
|
|
417
|
-
new_sort_property =
|
421
|
+
new_sort_property = new_sort_property.to_collection unless new_sort_property.is_a?(Array)
|
418
422
|
@sort_direction = @sort_direction.nil? || @sort_property.first != new_sort_property.first || @sort_direction == :descending ? :ascending : :descending
|
419
423
|
|
420
424
|
@sort_property = new_sort_property
|
@@ -520,7 +524,7 @@ module Glimmer
|
|
520
524
|
@edit_mode = true
|
521
525
|
|
522
526
|
editor_config = columns[column_index].editor || editor
|
523
|
-
editor_config =
|
527
|
+
editor_config = editor_config.to_collection
|
524
528
|
editor_widget_options = editor_config.last.is_a?(Hash) ? editor_config.last : {}
|
525
529
|
editor_widget_arg_last_index = editor_config.last.is_a?(Hash) ? -2 : -1
|
526
530
|
editor_widget = (editor_config[0] || :text).to_sym
|
@@ -23,16 +23,20 @@ require 'glimmer/swt/event_listener_proxy'
|
|
23
23
|
require 'glimmer/swt/property_owner'
|
24
24
|
require 'glimmer/swt/swt_proxy'
|
25
25
|
|
26
|
+
# TODO implement menu (which delays building it till render using add_content_on_render)
|
27
|
+
|
26
28
|
module Glimmer
|
27
29
|
module SWT
|
28
30
|
class WidgetProxy
|
29
31
|
include Glimmer
|
30
32
|
include PropertyOwner
|
31
33
|
|
32
|
-
attr_reader :parent, :args, :path, :children, :enabled, :foreground, :background, :font, :focus, :disposed?, :rendered
|
34
|
+
attr_reader :parent, :args, :path, :children, :enabled, :foreground, :background, :font, :focus, :disposed?, :rendered, :menu_requested
|
35
|
+
attr_accessor :menu
|
33
36
|
alias isDisposed disposed?
|
34
37
|
alias is_disposed disposed?
|
35
38
|
alias rendered? rendered
|
39
|
+
alias menu_requested? menu_requested
|
36
40
|
|
37
41
|
class << self
|
38
42
|
# Factory Method that translates a Glimmer DSL keyword into a WidgetProxy object
|
@@ -76,7 +80,7 @@ module Glimmer
|
|
76
80
|
end
|
77
81
|
|
78
82
|
DEFAULT_INITIALIZERS = {
|
79
|
-
|
83
|
+
composite: lambda do |composite_proxy|
|
80
84
|
if composite_proxy.layout.nil?
|
81
85
|
layout = GridLayoutProxy.new(composite_proxy, [])
|
82
86
|
composite_proxy.layout = layout
|
@@ -84,18 +88,18 @@ module Glimmer
|
|
84
88
|
layout.margin_height = 15
|
85
89
|
end
|
86
90
|
end,
|
87
|
-
#
|
91
|
+
# scrolled_composite: lambda do |scrolled_composite|
|
88
92
|
# scrolled_composite.expand_horizontal = true
|
89
93
|
# scrolled_composite.expand_vertical = true
|
90
94
|
# end,
|
91
|
-
#
|
95
|
+
# table: lambda do |table|
|
92
96
|
# table.setHeaderVisible(true)
|
93
97
|
# table.setLinesVisible(true)
|
94
98
|
# end,
|
95
|
-
|
99
|
+
table_column: lambda do |table_column_proxy|
|
96
100
|
table_column_proxy.width = 80
|
97
101
|
end,
|
98
|
-
#
|
102
|
+
# group: lambda do |group_proxy|
|
99
103
|
# group_proxy.layout = GridLayoutProxy.new(group_proxy, []) if group.layout.nil?
|
100
104
|
# end,
|
101
105
|
}
|
@@ -107,7 +111,7 @@ module Glimmer
|
|
107
111
|
@children = Set.new # TODO consider moving to composite
|
108
112
|
@enabled = true
|
109
113
|
@data = {}
|
110
|
-
DEFAULT_INITIALIZERS[self.class.underscored_widget_name(self)]&.call(self)
|
114
|
+
DEFAULT_INITIALIZERS[self.class.underscored_widget_name(self).to_s.to_sym]&.call(self)
|
111
115
|
@parent.post_initialize_child(self) # TODO rename to post_initialize_child to be closer to glimmer-dsl-swt terminology
|
112
116
|
end
|
113
117
|
|
@@ -124,7 +128,19 @@ module Glimmer
|
|
124
128
|
|
125
129
|
# Executes at the closing of a parent widget curly braces after all children/properties have been added/set
|
126
130
|
def post_add_content
|
127
|
-
|
131
|
+
if !menu.nil? && !is_a?(MenuProxy) && !is_a?(MenuItemProxy)
|
132
|
+
on_mouse_down { |mouse_event|
|
133
|
+
if mouse_event.button == 3 # right-click
|
134
|
+
@menu_requested = true
|
135
|
+
dom_element.css('position', 'relative')
|
136
|
+
menu&.render
|
137
|
+
menu.dom_element.css('position', 'absolute')
|
138
|
+
menu.dom_element.css('left', mouse_event.x - parent.layout&.margin_width.to_i) # TODO - parent.layout&.margin_left.to_i)
|
139
|
+
menu.dom_element.css('top', mouse_event.y - parent.layout&.margin_height.to_i - 5) # TODO - parent.layout&.margin_top.to_i)
|
140
|
+
@menu_requested = false
|
141
|
+
end
|
142
|
+
}
|
143
|
+
end
|
128
144
|
end
|
129
145
|
|
130
146
|
def set_data(key=nil, value)
|
@@ -148,18 +164,20 @@ module Glimmer
|
|
148
164
|
Document.find(path).remove
|
149
165
|
parent&.post_dispose_child(self)
|
150
166
|
# TODO fire on_widget_disposed listener
|
167
|
+
# children.each(:dispose) # TODO enable this safely
|
151
168
|
@disposed = true
|
152
169
|
end
|
153
170
|
|
154
171
|
def remove_all_listeners
|
155
172
|
effective_observation_request_to_event_mapping.keys.each do |keyword|
|
156
|
-
|
173
|
+
effective_observation_request_to_event_mapping[keyword].to_collection.each do |mapping|
|
157
174
|
observation_requests[keyword].to_a.each do |event_listener|
|
158
175
|
event = mapping[:event]
|
159
176
|
event_handler = mapping[:event_handler]
|
160
177
|
event_element_css_selector = mapping[:event_element_css_selector]
|
161
178
|
the_listener_dom_element = event_element_css_selector ? Element[event_element_css_selector] : listener_dom_element
|
162
179
|
the_listener_dom_element.off(event)
|
180
|
+
# TODO improve to precisely remove the listeners that were added, no more no less. (or use the event_listener_proxies method instead or in collaboration)
|
163
181
|
end
|
164
182
|
end
|
165
183
|
end
|
@@ -173,6 +191,14 @@ module Glimmer
|
|
173
191
|
def element
|
174
192
|
'div'
|
175
193
|
end
|
194
|
+
|
195
|
+
def pack(*args)
|
196
|
+
# No Op (just a shim) TODO consider if it should be implemented
|
197
|
+
end
|
198
|
+
|
199
|
+
def layout(*args)
|
200
|
+
# No Op (just a shim) TODO consider if it should be implemented
|
201
|
+
end
|
176
202
|
|
177
203
|
def enabled=(value)
|
178
204
|
@enabled = value
|
@@ -180,11 +206,13 @@ module Glimmer
|
|
180
206
|
end
|
181
207
|
|
182
208
|
def foreground=(value)
|
209
|
+
value = ColorProxy.new(value) if value.is_a?(String)
|
183
210
|
@foreground = value
|
184
211
|
dom_element.css('color', foreground.to_css) unless foreground.nil?
|
185
212
|
end
|
186
213
|
|
187
214
|
def background=(value)
|
215
|
+
value = ColorProxy.new(value) if value.is_a?(String)
|
188
216
|
@background = value
|
189
217
|
dom_element.css('background-color', background.to_css) unless background.nil?
|
190
218
|
end
|
@@ -215,27 +243,27 @@ module Glimmer
|
|
215
243
|
Document.find(parent_path)
|
216
244
|
end
|
217
245
|
|
218
|
-
def render(custom_parent_dom_element
|
246
|
+
def render(custom_parent_dom_element: nil, brand_new: false)
|
219
247
|
the_parent_dom_element = custom_parent_dom_element || parent_dom_element
|
220
248
|
old_element = dom_element
|
221
|
-
brand_new = @dom.nil? || old_element.empty?
|
222
|
-
build_dom(!custom_parent_dom_element) # TODO handle custom parent layout by passing parent instead of parent dom element
|
249
|
+
brand_new = @dom.nil? || old_element.empty? || brand_new
|
250
|
+
build_dom(layout: !custom_parent_dom_element) # TODO handle custom parent layout by passing parent instead of parent dom element
|
223
251
|
if brand_new
|
224
|
-
the_parent_dom_element.append(@dom)
|
252
|
+
the_parent_dom_element.append(@dom) # TODO make a method attach to allow subclasses to override if needed
|
225
253
|
else
|
226
254
|
old_element.replace_with(@dom)
|
255
|
+
old_element.replace_with(@dom)
|
227
256
|
end
|
228
|
-
observation_requests&.
|
257
|
+
observation_requests&.each do |keyword, event_listener_set|
|
229
258
|
event_listener_set.each do |event_listener|
|
230
|
-
|
231
|
-
handle_observation_request(keyword, &event_listener)
|
259
|
+
handle_observation_request(keyword, event_listener)
|
232
260
|
end
|
233
261
|
end
|
234
262
|
children.each do |child|
|
235
263
|
child.render
|
236
264
|
end
|
237
265
|
@rendered = true
|
238
|
-
content_on_render_blocks.each { |content_block| content(&content_block) }
|
266
|
+
content_on_render_blocks.each { |content_block| content(&content_block) } unless skip_content_on_render_blocks?
|
239
267
|
end
|
240
268
|
alias redraw render
|
241
269
|
|
@@ -243,6 +271,10 @@ module Glimmer
|
|
243
271
|
@content_on_render_blocks ||= []
|
244
272
|
end
|
245
273
|
|
274
|
+
def skip_content_on_render_blocks?
|
275
|
+
false
|
276
|
+
end
|
277
|
+
|
246
278
|
def add_content_on_render(&content_block)
|
247
279
|
if rendered?
|
248
280
|
content_block.call
|
@@ -251,7 +283,7 @@ module Glimmer
|
|
251
283
|
end
|
252
284
|
end
|
253
285
|
|
254
|
-
def build_dom(layout
|
286
|
+
def build_dom(layout: true)
|
255
287
|
# TODO consider passing parent element instead and having table item include a table cell widget only for opal
|
256
288
|
@dom = nil
|
257
289
|
@dom = dom
|
@@ -273,6 +305,60 @@ module Glimmer
|
|
273
305
|
end
|
274
306
|
|
275
307
|
def default_observation_request_to_event_mapping
|
308
|
+
mouse_event_handler = -> (event_listener) {
|
309
|
+
-> (event) {
|
310
|
+
# TODO generalize this solution to all widgets that support key presses
|
311
|
+
# TODO support event.location once DOM3 is supported by opal-jquery
|
312
|
+
event.define_singleton_method(:button, &event.method(:which))
|
313
|
+
event.define_singleton_method(:count) {1} # TODO support double-click count of 2 in the future by using ondblclick
|
314
|
+
event.define_singleton_method(:x, &event.method(:page_x))
|
315
|
+
event.define_singleton_method(:y, &event.method(:page_y))
|
316
|
+
doit = true
|
317
|
+
event.define_singleton_method(:doit=) do |value|
|
318
|
+
doit = value
|
319
|
+
end
|
320
|
+
event.define_singleton_method(:doit) { doit }
|
321
|
+
|
322
|
+
if event.which == 1
|
323
|
+
# event.prevent # TODO consider if this is needed
|
324
|
+
event_listener.call(event)
|
325
|
+
end
|
326
|
+
|
327
|
+
# TODO Imlement doit properly for all different kinds of events
|
328
|
+
# unless doit
|
329
|
+
# event.prevent
|
330
|
+
# event.stop
|
331
|
+
# event.stop_immediate
|
332
|
+
# end
|
333
|
+
}
|
334
|
+
}
|
335
|
+
context_menu_handler = -> (event_listener) {
|
336
|
+
-> (event) {
|
337
|
+
# TODO generalize this solution to all widgets that support key presses
|
338
|
+
# TODO support event.location once DOM3 is supported by opal-jquery
|
339
|
+
event.define_singleton_method(:button, &event.method(:which))
|
340
|
+
event.define_singleton_method(:count) {1} # TODO support double-click count of 2 in the future by using ondblclick
|
341
|
+
event.define_singleton_method(:x, &event.method(:page_x))
|
342
|
+
event.define_singleton_method(:y, &event.method(:page_y))
|
343
|
+
doit = true
|
344
|
+
event.define_singleton_method(:doit=) do |value|
|
345
|
+
doit = value
|
346
|
+
end
|
347
|
+
event.define_singleton_method(:doit) { doit }
|
348
|
+
|
349
|
+
if event.which == 3
|
350
|
+
event.prevent
|
351
|
+
event_listener.call(event)
|
352
|
+
end
|
353
|
+
|
354
|
+
# TODO Imlement doit properly for all different kinds of events
|
355
|
+
# unless doit
|
356
|
+
# event.prevent
|
357
|
+
# event.stop
|
358
|
+
# event.stop_immediate
|
359
|
+
# end
|
360
|
+
}
|
361
|
+
}
|
276
362
|
{
|
277
363
|
'on_focus_gained' => {
|
278
364
|
event: 'focus',
|
@@ -280,6 +366,191 @@ module Glimmer
|
|
280
366
|
'on_focus_lost' => {
|
281
367
|
event: 'blur',
|
282
368
|
},
|
369
|
+
'on_mouse_up' => [
|
370
|
+
{
|
371
|
+
event: 'mouseup',
|
372
|
+
event_handler: mouse_event_handler,
|
373
|
+
},
|
374
|
+
{
|
375
|
+
event: 'contextmenu',
|
376
|
+
event_handler: context_menu_handler,
|
377
|
+
},
|
378
|
+
],
|
379
|
+
'on_mouse_down' => [
|
380
|
+
{
|
381
|
+
event: 'mousedown',
|
382
|
+
event_handler: mouse_event_handler,
|
383
|
+
},
|
384
|
+
{
|
385
|
+
event: 'contextmenu',
|
386
|
+
event_handler: context_menu_handler,
|
387
|
+
},
|
388
|
+
],
|
389
|
+
'on_swt_mouseup' => [
|
390
|
+
{
|
391
|
+
event: 'mouseup',
|
392
|
+
event_handler: mouse_event_handler,
|
393
|
+
},
|
394
|
+
{
|
395
|
+
event: 'contextmenu',
|
396
|
+
event_handler: context_menu_handler,
|
397
|
+
},
|
398
|
+
],
|
399
|
+
'on_swt_mousedown' => [
|
400
|
+
{
|
401
|
+
event: 'mousedown',
|
402
|
+
event_handler: mouse_event_handler,
|
403
|
+
},
|
404
|
+
{
|
405
|
+
event: 'contextmenu',
|
406
|
+
event_handler: context_menu_handler,
|
407
|
+
},
|
408
|
+
],
|
409
|
+
'on_key_pressed' => {
|
410
|
+
event: 'keypress',
|
411
|
+
event_handler: -> (event_listener) {
|
412
|
+
-> (event) {
|
413
|
+
# TODO generalize this solution to all widgets that support key presses
|
414
|
+
# TODO support event.location once DOM3 is supported by opal-jquery
|
415
|
+
event.define_singleton_method(:keyCode) {event.which}
|
416
|
+
event.define_singleton_method(:key_code, &event.method(:keyCode))
|
417
|
+
event.define_singleton_method(:character) {event.which.chr}
|
418
|
+
event.define_singleton_method(:stateMask) do
|
419
|
+
state_mask = 0
|
420
|
+
state_mask |= SWTProxy[:alt] if event.alt_key
|
421
|
+
state_mask |= SWTProxy[:ctrl] if event.ctrl_key
|
422
|
+
state_mask |= SWTProxy[:shift] if event.shift_key
|
423
|
+
state_mask |= SWTProxy[:command] if event.meta_key
|
424
|
+
state_mask
|
425
|
+
end
|
426
|
+
event.define_singleton_method(:state_mask, &event.method(:stateMask))
|
427
|
+
doit = true
|
428
|
+
event.define_singleton_method(:doit=) do |value|
|
429
|
+
doit = value
|
430
|
+
end
|
431
|
+
event.define_singleton_method(:doit) { doit }
|
432
|
+
event_listener.call(event)
|
433
|
+
|
434
|
+
# TODO Fix doit false, it's not stopping input
|
435
|
+
unless doit
|
436
|
+
event.prevent
|
437
|
+
event.prevent_default
|
438
|
+
event.stop_propagation
|
439
|
+
event.stop_immediate_propagation
|
440
|
+
end
|
441
|
+
|
442
|
+
doit
|
443
|
+
}
|
444
|
+
} },
|
445
|
+
'on_key_released' => {
|
446
|
+
event: 'keydown',
|
447
|
+
event_handler: -> (event_listener) {
|
448
|
+
-> (event) {
|
449
|
+
# TODO generalize this solution to all widgets that support key presses
|
450
|
+
# TODO support event.location once DOM3 is supported by opal-jquery
|
451
|
+
event.define_singleton_method(:keyCode) {event.which}
|
452
|
+
event.define_singleton_method(:key_code, &event.method(:keyCode))
|
453
|
+
event.define_singleton_method(:character) {event.which.chr}
|
454
|
+
event.define_singleton_method(:stateMask) do
|
455
|
+
state_mask = 0
|
456
|
+
state_mask |= SWTProxy[:alt] if event.alt_key
|
457
|
+
state_mask |= SWTProxy[:ctrl] if event.ctrl_key
|
458
|
+
state_mask |= SWTProxy[:shift] if event.shift_key
|
459
|
+
state_mask |= SWTProxy[:command] if event.meta_key
|
460
|
+
state_mask
|
461
|
+
end
|
462
|
+
event.define_singleton_method(:state_mask, &event.method(:stateMask))
|
463
|
+
doit = true
|
464
|
+
event.define_singleton_method(:doit=) do |value|
|
465
|
+
doit = value
|
466
|
+
end
|
467
|
+
event.define_singleton_method(:doit) { doit }
|
468
|
+
event_listener.call(event)
|
469
|
+
|
470
|
+
# TODO Fix doit false, it's not stopping input
|
471
|
+
unless doit
|
472
|
+
event.prevent
|
473
|
+
event.prevent_default
|
474
|
+
event.stop_propagation
|
475
|
+
event.stop_immediate_propagation
|
476
|
+
end
|
477
|
+
|
478
|
+
doit
|
479
|
+
}
|
480
|
+
} },
|
481
|
+
'on_swt_keydown' => {
|
482
|
+
event: 'keypress',
|
483
|
+
event_handler: -> (event_listener) {
|
484
|
+
-> (event) {
|
485
|
+
# TODO generalize this solution to all widgets that support key presses
|
486
|
+
# TODO support event.location once DOM3 is supported by opal-jquery
|
487
|
+
event.define_singleton_method(:keyCode) {event.which}
|
488
|
+
event.define_singleton_method(:key_code, &event.method(:keyCode))
|
489
|
+
event.define_singleton_method(:character) {event.which.chr}
|
490
|
+
event.define_singleton_method(:stateMask) do
|
491
|
+
state_mask = 0
|
492
|
+
state_mask |= SWTProxy[:alt] if event.alt_key
|
493
|
+
state_mask |= SWTProxy[:ctrl] if event.ctrl_key
|
494
|
+
state_mask |= SWTProxy[:shift] if event.shift_key
|
495
|
+
state_mask |= SWTProxy[:command] if event.meta_key
|
496
|
+
state_mask
|
497
|
+
end
|
498
|
+
event.define_singleton_method(:state_mask, &event.method(:stateMask))
|
499
|
+
doit = true
|
500
|
+
event.define_singleton_method(:doit=) do |value|
|
501
|
+
doit = value
|
502
|
+
end
|
503
|
+
event.define_singleton_method(:doit) { doit }
|
504
|
+
event_listener.call(event)
|
505
|
+
|
506
|
+
# TODO Fix doit false, it's not stopping input
|
507
|
+
unless doit
|
508
|
+
event.prevent
|
509
|
+
event.prevent_default
|
510
|
+
event.stop_propagation
|
511
|
+
event.stop_immediate_propagation
|
512
|
+
end
|
513
|
+
|
514
|
+
doit
|
515
|
+
}
|
516
|
+
} },
|
517
|
+
'on_swt_keyup' => {
|
518
|
+
event: 'keydown',
|
519
|
+
event_handler: -> (event_listener) {
|
520
|
+
-> (event) {
|
521
|
+
# TODO generalize this solution to all widgets that support key presses
|
522
|
+
# TODO support event.location once DOM3 is supported by opal-jquery
|
523
|
+
event.define_singleton_method(:keyCode) {event.which}
|
524
|
+
event.define_singleton_method(:key_code, &event.method(:keyCode))
|
525
|
+
event.define_singleton_method(:character) {event.which.chr}
|
526
|
+
event.define_singleton_method(:stateMask) do
|
527
|
+
state_mask = 0
|
528
|
+
state_mask |= SWTProxy[:alt] if event.alt_key
|
529
|
+
state_mask |= SWTProxy[:ctrl] if event.ctrl_key
|
530
|
+
state_mask |= SWTProxy[:shift] if event.shift_key
|
531
|
+
state_mask |= SWTProxy[:command] if event.meta_key
|
532
|
+
state_mask
|
533
|
+
end
|
534
|
+
event.define_singleton_method(:state_mask, &event.method(:stateMask))
|
535
|
+
doit = true
|
536
|
+
event.define_singleton_method(:doit=) do |value|
|
537
|
+
doit = value
|
538
|
+
end
|
539
|
+
event.define_singleton_method(:doit) { doit }
|
540
|
+
event_listener.call(event)
|
541
|
+
|
542
|
+
# TODO Fix doit false, it's not stopping input
|
543
|
+
unless doit
|
544
|
+
event.prevent
|
545
|
+
event.prevent_default
|
546
|
+
event.stop_propagation
|
547
|
+
event.stop_immediate_propagation
|
548
|
+
end
|
549
|
+
|
550
|
+
doit
|
551
|
+
}
|
552
|
+
}
|
553
|
+
},
|
283
554
|
}
|
284
555
|
end
|
285
556
|
|
@@ -354,6 +625,14 @@ module Glimmer
|
|
354
625
|
Document.find(listener_path)
|
355
626
|
end
|
356
627
|
|
628
|
+
def observation_requests
|
629
|
+
@observation_requests ||= {}
|
630
|
+
end
|
631
|
+
|
632
|
+
def event_listener_proxies
|
633
|
+
@event_listener_proxies ||= []
|
634
|
+
end
|
635
|
+
|
357
636
|
def can_handle_observation_request?(observation_request)
|
358
637
|
# TODO sort this out for Opal
|
359
638
|
observation_request = observation_request.to_s
|
@@ -367,32 +646,40 @@ module Glimmer
|
|
367
646
|
end
|
368
647
|
end
|
369
648
|
|
370
|
-
def
|
371
|
-
@observation_requests ||= {}
|
372
|
-
end
|
373
|
-
|
374
|
-
def handle_observation_request(keyword, &event_listener)
|
649
|
+
def handle_observation_request(keyword, original_event_listener)
|
375
650
|
return unless effective_observation_request_to_event_mapping.keys.include?(keyword)
|
376
651
|
event = nil
|
377
652
|
delegate = nil
|
378
|
-
|
653
|
+
effective_observation_request_to_event_mapping[keyword].to_collection.each do |mapping|
|
379
654
|
observation_requests[keyword] ||= Set.new
|
380
|
-
observation_requests[keyword] <<
|
655
|
+
observation_requests[keyword] << original_event_listener
|
381
656
|
event = mapping[:event]
|
382
657
|
event_handler = mapping[:event_handler]
|
383
658
|
event_element_css_selector = mapping[:event_element_css_selector]
|
384
|
-
potential_event_listener = event_handler&.call(
|
385
|
-
event_listener = potential_event_listener ||
|
659
|
+
potential_event_listener = event_handler&.call(original_event_listener)
|
660
|
+
event_listener = potential_event_listener || original_event_listener
|
386
661
|
async_event_listener = lambda do |event|
|
387
|
-
|
662
|
+
# TODO look into the issue with using async::task.new here. maybe put it in event listener (like not being able to call preventDefault or return false successfully )
|
663
|
+
# maybe consider pushing inside the widget classes instead where needed only or implement universal doit support correctly to bypass this issue
|
664
|
+
# Async::Task.new do
|
388
665
|
event_listener.call(event)
|
389
|
-
|
666
|
+
# end
|
390
667
|
end
|
391
668
|
the_listener_dom_element = event_element_css_selector ? Element[event_element_css_selector] : listener_dom_element
|
392
|
-
|
669
|
+
unless the_listener_dom_element.empty?
|
670
|
+
the_listener_dom_element.on(event, &async_event_listener)
|
671
|
+
# TODO ensure uniqueness of insertion (perhaps adding equals/hash method to event listener proxy)
|
672
|
+
|
673
|
+
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)
|
674
|
+
end
|
675
|
+
end
|
676
|
+
end
|
677
|
+
|
678
|
+
def remove_event_listener_proxies
|
679
|
+
event_listener_proxies.each do |event_listener_proxy|
|
680
|
+
event_listener_proxy.unregister
|
393
681
|
end
|
394
|
-
|
395
|
-
EventListenerProxy.new(element_proxy: self, event: event, selector: selector, delegate: delegate)
|
682
|
+
event_listener_proxies.clear
|
396
683
|
end
|
397
684
|
|
398
685
|
def add_observer(observer, property_name)
|
@@ -410,12 +697,17 @@ module Glimmer
|
|
410
697
|
|
411
698
|
def method_missing(method, *args, &block)
|
412
699
|
if method.to_s.start_with?('on_')
|
413
|
-
handle_observation_request(method,
|
700
|
+
handle_observation_request(method, block)
|
414
701
|
else
|
415
702
|
super(method, *args, &block)
|
416
703
|
end
|
417
704
|
end
|
418
705
|
|
706
|
+
def swt_widget
|
707
|
+
# only added for compatibility/adaptibility with Glimmer DSL for SWT
|
708
|
+
self
|
709
|
+
end
|
710
|
+
|
419
711
|
def apply_property_type_converters(attribute_name, args)
|
420
712
|
if args.count == 1
|
421
713
|
value = args.first
|
@@ -608,6 +900,8 @@ require 'glimmer/swt/date_time_proxy'
|
|
608
900
|
require 'glimmer/swt/group_proxy'
|
609
901
|
require 'glimmer/swt/label_proxy'
|
610
902
|
require 'glimmer/swt/list_proxy'
|
903
|
+
require 'glimmer/swt/menu_item_proxy'
|
904
|
+
require 'glimmer/swt/menu_proxy'
|
611
905
|
require 'glimmer/swt/radio_proxy'
|
612
906
|
require 'glimmer/swt/tab_folder_proxy'
|
613
907
|
require 'glimmer/swt/tab_item_proxy'
|