glimmer-dsl-swt 4.18.4.8 → 4.18.5.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +70 -0
- data/README.md +24 -11
- data/VERSION +1 -1
- data/bin/glimmer +3 -3
- data/docs/reference/GLIMMER_CONFIGURATION.md +7 -3
- data/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md +353 -145
- data/docs/reference/GLIMMER_SAMPLES.md +207 -41
- data/glimmer-dsl-swt.gemspec +33 -15
- data/lib/ext/glimmer/config.rb +3 -7
- data/lib/glimmer/data_binding/list_selection_binding.rb +13 -7
- data/lib/glimmer/data_binding/table_items_binding.rb +22 -17
- data/lib/glimmer/data_binding/tree_items_binding.rb +19 -15
- data/lib/glimmer/data_binding/widget_binding.rb +13 -15
- data/lib/glimmer/dsl/swt/{file_dialog_expression.rb → auto_exec_expression.rb} +6 -18
- data/lib/glimmer/dsl/swt/checkbox_group_selection_data_binding_expression.rb +9 -6
- data/lib/glimmer/dsl/swt/color_expression.rb +1 -1
- data/lib/glimmer/dsl/swt/combo_selection_data_binding_expression.rb +16 -14
- data/lib/glimmer/dsl/swt/custom_widget_expression.rb +4 -1
- data/lib/glimmer/dsl/swt/data_binding_expression.rb +2 -2
- data/lib/glimmer/dsl/swt/dialog_expression.rb +18 -9
- data/lib/glimmer/dsl/swt/dsl.rb +1 -0
- data/lib/glimmer/dsl/swt/exec_expression.rb +1 -1
- data/lib/glimmer/dsl/swt/font_expression.rb +1 -1
- data/lib/glimmer/dsl/swt/image_expression.rb +18 -3
- data/lib/glimmer/dsl/swt/list_selection_data_binding_expression.rb +11 -8
- data/lib/glimmer/dsl/swt/pixel_expression.rb +1 -1
- data/lib/glimmer/dsl/swt/radio_group_selection_data_binding_expression.rb +9 -5
- data/lib/glimmer/dsl/swt/shape_expression.rb +1 -1
- data/lib/glimmer/dsl/swt/shell_expression.rb +5 -2
- data/lib/glimmer/dsl/swt/widget_expression.rb +8 -4
- data/lib/glimmer/launcher.rb +3 -0
- data/lib/glimmer/rake_task/scaffold.rb +3 -0
- data/lib/glimmer/swt/color_proxy.rb +1 -1
- data/lib/glimmer/swt/custom/code_text.rb +33 -11
- data/lib/glimmer/swt/custom/drawable.rb +50 -2
- data/lib/glimmer/swt/custom/radio_group.rb +2 -1
- data/lib/glimmer/swt/custom/shape.rb +166 -34
- data/lib/glimmer/{dsl/swt/directory_dialog_expression.rb → swt/custom/shape/arc.rb} +15 -20
- data/lib/glimmer/swt/custom/shape/focus.rb +43 -0
- data/lib/glimmer/swt/custom/shape/image.rb +86 -0
- data/lib/glimmer/swt/custom/shape/line.rb +58 -0
- data/lib/glimmer/swt/custom/shape/oval.rb +43 -0
- data/lib/glimmer/swt/custom/shape/point.rb +52 -0
- data/lib/glimmer/swt/custom/shape/polygon.rb +73 -0
- data/lib/glimmer/swt/custom/shape/polyline.rb +73 -0
- data/lib/glimmer/swt/custom/shape/rectangle.rb +87 -0
- data/lib/glimmer/swt/custom/shape/text.rb +73 -0
- data/lib/glimmer/swt/date_time_proxy.rb +9 -3
- data/lib/glimmer/swt/dialog_proxy.rb +92 -0
- data/lib/glimmer/swt/display_proxy.rb +62 -2
- data/lib/glimmer/swt/expand_item_proxy.rb +18 -12
- data/lib/glimmer/swt/font_proxy.rb +13 -7
- data/lib/glimmer/swt/image_proxy.rb +16 -5
- data/lib/glimmer/swt/layout_data_proxy.rb +21 -15
- data/lib/glimmer/swt/layout_proxy.rb +19 -15
- data/lib/glimmer/swt/menu_proxy.rb +2 -2
- data/lib/glimmer/swt/message_box_proxy.rb +21 -7
- data/lib/glimmer/swt/properties.rb +3 -0
- data/lib/glimmer/swt/proxy_properties.rb +145 -0
- data/lib/glimmer/swt/scrolled_composite_proxy.rb +20 -7
- data/lib/glimmer/swt/shell_proxy.rb +96 -80
- data/lib/glimmer/swt/swt_proxy.rb +17 -0
- data/lib/glimmer/swt/tab_item_proxy.rb +6 -3
- data/lib/glimmer/swt/table_proxy.rb +32 -11
- data/lib/glimmer/swt/transform_proxy.rb +26 -38
- data/lib/glimmer/swt/tree_proxy.rb +11 -16
- data/lib/glimmer/swt/widget_listener_proxy.rb +6 -2
- data/lib/glimmer/swt/widget_proxy.rb +194 -137
- data/lib/glimmer/ui.rb +5 -0
- data/lib/glimmer/ui/custom_shell.rb +13 -7
- data/lib/glimmer/ui/custom_widget.rb +4 -5
- data/samples/elaborate/contact_manager.rb +7 -7
- data/samples/elaborate/login.rb +25 -21
- data/samples/elaborate/mandelbrot_fractal.rb +346 -39
- data/samples/elaborate/meta_sample.rb +1 -1
- data/samples/elaborate/tetris.rb +1 -0
- data/samples/elaborate/tic_tac_toe.rb +16 -14
- data/samples/elaborate/tic_tac_toe/board.rb +5 -5
- data/samples/elaborate/tic_tac_toe/cell.rb +5 -5
- data/samples/hello/hello_button.rb +7 -7
- data/samples/hello/hello_canvas.rb +145 -41
- data/samples/hello/hello_checkbox.rb +16 -14
- data/samples/hello/hello_checkbox_group.rb +11 -9
- data/samples/hello/hello_color_dialog.rb +66 -0
- data/samples/hello/hello_combo.rb +14 -12
- data/samples/hello/hello_computed.rb +7 -7
- data/samples/hello/hello_cursor.rb +58 -0
- data/samples/hello/hello_custom_shell.rb +17 -21
- data/samples/hello/hello_custom_widget.rb +4 -6
- data/samples/hello/hello_date_time.rb +14 -12
- data/samples/hello/hello_directory_dialog.rb +7 -7
- data/samples/hello/hello_expand_bar.rb +8 -8
- data/samples/hello/hello_file_dialog.rb +7 -7
- data/samples/hello/hello_font_dialog.rb +82 -0
- data/samples/hello/hello_group.rb +18 -16
- data/samples/hello/hello_list_multi_selection.rb +13 -11
- data/samples/hello/hello_list_single_selection.rb +13 -11
- data/samples/hello/hello_progress_bar.rb +125 -0
- data/samples/hello/hello_radio.rb +18 -16
- data/samples/hello/hello_radio_group.rb +14 -12
- data/samples/hello/hello_spinner.rb +7 -7
- data/samples/hello/hello_tab.rb +5 -5
- data/samples/hello/hello_table.rb +10 -5
- data/samples/hello/hello_tree.rb +485 -0
- metadata +30 -23
- data/lib/glimmer/swt/directory_dialog_proxy.rb +0 -65
- data/lib/glimmer/swt/file_dialog_proxy.rb +0 -66
@@ -49,10 +49,27 @@ module Glimmer
|
|
49
49
|
def extra_styles
|
50
50
|
EXTRA_STYLES
|
51
51
|
end
|
52
|
+
|
53
|
+
def cursor_styles
|
54
|
+
SWT.constants.select {|c| c.to_s.start_with?('CURSOR_')}
|
55
|
+
end
|
56
|
+
|
57
|
+
def color_styles
|
58
|
+
SWT.constants.select {|c| c.to_s.start_with?('COLOR_')}
|
59
|
+
end
|
60
|
+
|
61
|
+
def cursor_options
|
62
|
+
cursor_styles.map {|c| c.to_s.sub('CURSOR_', '').downcase}.map(&:to_sym)
|
63
|
+
end
|
64
|
+
|
65
|
+
def color_options
|
66
|
+
color_styles.map {|c| c.to_s.sub('COLOR_', '').downcase}.map(&:to_sym)
|
67
|
+
end
|
52
68
|
end
|
53
69
|
|
54
70
|
EXTRA_STYLES = {
|
55
71
|
NO_RESIZE: self[:shell_trim, :resize!, :max!],
|
72
|
+
WINDOW_TRIM: self[:shell_trim],
|
56
73
|
}
|
57
74
|
end
|
58
75
|
end
|
@@ -49,6 +49,7 @@ module Glimmer
|
|
49
49
|
@widget_proxy = SWT::WidgetProxy.new('tab_item', parent, style)
|
50
50
|
@swt_tab_item = @widget_proxy.swt_widget
|
51
51
|
@swt_tab_item.control = swt_widget
|
52
|
+
# parent.pack # TODO auto fix the tab folder to avoid having to do this manually (including maintaining bounds and minimum size of shell)
|
52
53
|
end
|
53
54
|
|
54
55
|
def has_attribute?(attribute_name, *args)
|
@@ -82,9 +83,11 @@ module Glimmer
|
|
82
83
|
end
|
83
84
|
|
84
85
|
def dispose
|
85
|
-
|
86
|
-
|
87
|
-
|
86
|
+
auto_exec do
|
87
|
+
swt_tab_item.setControl(nil)
|
88
|
+
swt_widget.dispose
|
89
|
+
swt_tab_item.dispose
|
90
|
+
end
|
88
91
|
end
|
89
92
|
end
|
90
93
|
end
|
@@ -266,15 +266,21 @@ module Glimmer
|
|
266
266
|
end
|
267
267
|
|
268
268
|
def items
|
269
|
-
|
269
|
+
auto_exec do
|
270
|
+
swt_widget.get_items
|
271
|
+
end
|
270
272
|
end
|
271
273
|
|
272
274
|
def model_binding
|
273
|
-
|
275
|
+
auto_exec do
|
276
|
+
swt_widget.data
|
277
|
+
end
|
274
278
|
end
|
275
279
|
|
276
280
|
def table_items_binding
|
277
|
-
|
281
|
+
auto_exec do
|
282
|
+
swt_widget.get_data('table_items_binding')
|
283
|
+
end
|
278
284
|
end
|
279
285
|
|
280
286
|
def sort_block=(comparator)
|
@@ -313,7 +319,10 @@ module Glimmer
|
|
313
319
|
|
314
320
|
# Sorts by specified TableColumnProxy object. If nil, it uses the table default sort instead.
|
315
321
|
def sort_by_column!(table_column_proxy=nil)
|
316
|
-
index =
|
322
|
+
index = nil
|
323
|
+
auto_exec do
|
324
|
+
index = swt_widget.columns.to_a.index(table_column_proxy.swt_widget) unless table_column_proxy.nil?
|
325
|
+
end
|
317
326
|
new_sort_property = table_column_proxy.nil? ? @sort_property : table_column_proxy.sort_property || [column_properties[index]]
|
318
327
|
return if table_column_proxy.nil? && new_sort_property.nil? && @sort_block.nil? && @sort_by_block.nil?
|
319
328
|
if new_sort_property && table_column_proxy.nil? && new_sort_property.size == 1 && (index = column_sort_properties.index(new_sort_property))
|
@@ -330,12 +339,16 @@ module Glimmer
|
|
330
339
|
end
|
331
340
|
|
332
341
|
@sort_direction = @sort_direction.nil? || @sort_property.first != new_sort_property.first || @sort_direction == :descending ? :ascending : :descending
|
333
|
-
|
342
|
+
auto_exec do
|
343
|
+
swt_widget.sort_direction = @sort_direction == :ascending ? SWTProxy[:up] : SWTProxy[:down]
|
344
|
+
end
|
334
345
|
|
335
346
|
@sort_property = [new_sort_property].flatten.compact
|
336
347
|
table_column_index = column_properties.index(new_sort_property.to_s.to_sym)
|
337
348
|
table_column_proxy ||= table_column_proxies[table_column_index] if table_column_index
|
338
|
-
|
349
|
+
auto_exec do
|
350
|
+
swt_widget.sort_column = table_column_proxy.swt_widget if table_column_proxy
|
351
|
+
end
|
339
352
|
|
340
353
|
if table_column_proxy
|
341
354
|
@sort_by_block = nil
|
@@ -405,14 +418,18 @@ module Glimmer
|
|
405
418
|
|
406
419
|
def cells
|
407
420
|
column_count = @table.column_properties.size
|
408
|
-
|
421
|
+
auto_exec do
|
422
|
+
swt_widget.items.map {|item| column_count.times.map {|i| item.get_text(i)} }
|
423
|
+
end
|
409
424
|
end
|
410
425
|
|
411
426
|
# Performs a search for table items matching block condition
|
412
427
|
# If no condition block is passed, returns all table items
|
413
428
|
# Returns a Java TableItem array to easily set as selection on org.eclipse.swt.Table if needed
|
414
429
|
def search(&condition)
|
415
|
-
|
430
|
+
auto_exec do
|
431
|
+
swt_widget.getItems.select {|item| condition.nil? || condition.call(item)}.to_java(TableItem)
|
432
|
+
end
|
416
433
|
end
|
417
434
|
|
418
435
|
# Returns all table items including descendants
|
@@ -454,7 +471,9 @@ module Glimmer
|
|
454
471
|
end
|
455
472
|
|
456
473
|
def edit_selected_table_item(column_index, before_write: nil, after_write: nil, after_cancel: nil)
|
457
|
-
|
474
|
+
auto_exec do
|
475
|
+
edit_table_item(swt_widget.getSelection.first, column_index, before_write: before_write, after_write: after_write, after_cancel: after_cancel)
|
476
|
+
end
|
458
477
|
end
|
459
478
|
|
460
479
|
def edit_table_item(table_item, column_index, before_write: nil, after_write: nil, after_cancel: nil, write_on_cancel: false)
|
@@ -512,7 +531,9 @@ module Glimmer
|
|
512
531
|
model.send("#{model_editing_property}=", new_value) # makes table update itself, so must search for selected table item again
|
513
532
|
# Table refresh happens here because of model update triggering observers, so must retrieve table item again
|
514
533
|
edited_table_item = search { |ti| ti.getData == model }.first
|
515
|
-
|
534
|
+
auto_exec do
|
535
|
+
swt_widget.showItem(edited_table_item)
|
536
|
+
end
|
516
537
|
@table_editor_widget_proxy&.swt_widget&.dispose
|
517
538
|
@table_editor_widget_proxy = nil
|
518
539
|
if after_write&.arity == 0
|
@@ -524,7 +545,7 @@ module Glimmer
|
|
524
545
|
end
|
525
546
|
end
|
526
547
|
end
|
527
|
-
|
548
|
+
|
528
549
|
content {
|
529
550
|
@table_editor_widget_proxy = TableProxy::editors.symbolize_keys[editor_widget][:editor_gui].call(editor_widget_args, model, model_editing_property, self)
|
530
551
|
}
|
@@ -37,32 +37,36 @@ module Glimmer
|
|
37
37
|
attr_reader :swt_transform, :parent
|
38
38
|
|
39
39
|
def initialize(parent, *args, swt_transform: nil, multiply: false)
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
if
|
44
|
-
args.
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
40
|
+
Glimmer::SWT::DisplayProxy.instance.auto_exec do
|
41
|
+
@parent = parent
|
42
|
+
@multiply = multiply
|
43
|
+
if swt_transform.nil?
|
44
|
+
if !args.first.is_a?(Display) && !args.first.is_a?(DisplayProxy)
|
45
|
+
args.prepend DisplayProxy.instance.swt_display
|
46
|
+
end
|
47
|
+
if args.first.is_a?(DisplayProxy)
|
48
|
+
args[0] = args[0].swt_display
|
49
|
+
end
|
50
|
+
if args.last.is_a?(TransformProxy)
|
51
|
+
args[-1] = args[-1].swt_transform
|
52
|
+
end
|
53
|
+
if args.last.nil? || args.last.is_a?(Transform)
|
54
|
+
@swt_transform = args.last
|
55
|
+
@parent&.set_attribute('transform', self)
|
56
|
+
else
|
57
|
+
@swt_transform = Transform.new(*args)
|
58
|
+
end
|
55
59
|
else
|
56
|
-
@swt_transform =
|
60
|
+
@swt_transform = swt_transform
|
57
61
|
end
|
58
|
-
else
|
59
|
-
@swt_transform = swt_transform
|
60
62
|
end
|
61
63
|
end
|
62
64
|
|
63
65
|
def post_add_content
|
64
66
|
if @multiply
|
65
|
-
|
67
|
+
Glimmer::SWT::DisplayProxy.instance.auto_exec {
|
68
|
+
@parent.multiply(@swt_transform)
|
69
|
+
}
|
66
70
|
else
|
67
71
|
@parent&.set_attribute('transform', self)
|
68
72
|
end
|
@@ -72,28 +76,12 @@ module Glimmer
|
|
72
76
|
Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::SWT::TransformExpression.new, &block)
|
73
77
|
end
|
74
78
|
|
75
|
-
def
|
76
|
-
@swt_transform
|
77
|
-
end
|
78
|
-
|
79
|
-
def set_attribute(attribute_name, *args)
|
80
|
-
if @swt_transform.respond_to?(attribute_name)
|
81
|
-
@swt_transform.send(attribute_name, *args)
|
82
|
-
elsif @swt_transform.respond_to?(attribute_setter(attribute_name))
|
83
|
-
@swt_transform.send(attribute_setter(attribute_name), *args)
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def get_attribute(attribute_name)
|
88
|
-
if @swt_transform.respond_to?(attribute_getter(attribute_name))
|
89
|
-
@swt_transform.send(attribute_getter(attribute_name))
|
90
|
-
else
|
91
|
-
@swt_transform.send(attribute_name)
|
92
|
-
end
|
79
|
+
def proxy_source_object
|
80
|
+
@swt_transform
|
93
81
|
end
|
94
82
|
|
95
83
|
def method_missing(method_name, *args, &block)
|
96
|
-
result = @swt_transform.send(method_name, *args, &block)
|
84
|
+
result = Glimmer::SWT::DisplayProxy.instance.auto_exec { @swt_transform.send(method_name, *args, &block) }
|
97
85
|
result.nil? ? self : result
|
98
86
|
rescue => e
|
99
87
|
Glimmer::Config.logger.debug {"Neither MessageBoxProxy nor #{@swt_transform.class.name} can handle the method ##{method}"}
|
@@ -42,7 +42,8 @@ module Glimmer
|
|
42
42
|
# Returns a Java TreeItem array to easily set as selection on org.eclipse.swt.Tree if needed
|
43
43
|
def depth_first_search(&condition)
|
44
44
|
found = []
|
45
|
-
|
45
|
+
first_item = DisplayProxy.instance.auto_exec { swt_widget.getItems.first }
|
46
|
+
recursive_depth_first_search(first_item, found, &condition)
|
46
47
|
found.to_java(TreeItem)
|
47
48
|
end
|
48
49
|
|
@@ -51,18 +52,6 @@ module Glimmer
|
|
51
52
|
depth_first_search
|
52
53
|
end
|
53
54
|
|
54
|
-
def widget_property_listener_installers
|
55
|
-
super.merge({
|
56
|
-
Java::OrgEclipseSwtWidgets::Tree => {
|
57
|
-
selection: lambda do |observer|
|
58
|
-
on_widget_selected { |selection_event|
|
59
|
-
observer.call(@swt_widget.getSelection)
|
60
|
-
}
|
61
|
-
end
|
62
|
-
},
|
63
|
-
})
|
64
|
-
end
|
65
|
-
|
66
55
|
def edit_in_progress?
|
67
56
|
!!@edit_in_progress
|
68
57
|
end
|
@@ -127,8 +116,10 @@ module Glimmer
|
|
127
116
|
|
128
117
|
def recursive_depth_first_search(tree_item, found, &condition)
|
129
118
|
return if tree_item.nil?
|
130
|
-
found << tree_item if condition.nil? || condition.call(tree_item)
|
131
|
-
|
119
|
+
found << tree_item if condition.nil? || DisplayProxy.instance.auto_exec {condition.call(tree_item)}
|
120
|
+
# return if found.any? && !has_style?(:multi) # TODO inspect if this is a good optimization when needed
|
121
|
+
tree_items = DisplayProxy.instance.auto_exec {tree_item.getItems}
|
122
|
+
tree_items.each do |child_tree_item|
|
132
123
|
recursive_depth_first_search(child_tree_item, found, &condition)
|
133
124
|
end
|
134
125
|
end
|
@@ -136,7 +127,11 @@ module Glimmer
|
|
136
127
|
def property_type_converters
|
137
128
|
super.merge({
|
138
129
|
selection: lambda do |value|
|
139
|
-
|
130
|
+
if value.is_a?(Array)
|
131
|
+
depth_first_search {|ti| value.include?(ti.getData) }
|
132
|
+
else
|
133
|
+
depth_first_search {|ti| ti.getData == value}
|
134
|
+
end
|
140
135
|
end,
|
141
136
|
})
|
142
137
|
end
|
@@ -53,9 +53,13 @@ module Glimmer
|
|
53
53
|
@swt_display.removeListener(@event_type, @swt_listener)
|
54
54
|
end
|
55
55
|
elsif @event_type
|
56
|
-
|
56
|
+
DisplayProxy.instance.auto_exec do
|
57
|
+
@swt_widget.removeListener(@event_type, @swt_listener)
|
58
|
+
end
|
57
59
|
else
|
58
|
-
|
60
|
+
DisplayProxy.instance.auto_exec do
|
61
|
+
@swt_widget.send(widget_remove_listener_method, @swt_listener)
|
62
|
+
end
|
59
63
|
end
|
60
64
|
end
|
61
65
|
alias unregister deregister # TODO consider dropping unregister (and in Observer too)
|
@@ -26,7 +26,7 @@ require 'glimmer/swt/swt_proxy'
|
|
26
26
|
require 'glimmer/swt/display_proxy'
|
27
27
|
require 'glimmer/swt/dnd_proxy'
|
28
28
|
require 'glimmer/swt/image_proxy'
|
29
|
-
require 'glimmer/swt/
|
29
|
+
require 'glimmer/swt/proxy_properties'
|
30
30
|
require 'glimmer/swt/custom/drawable'
|
31
31
|
|
32
32
|
# TODO refactor to make file smaller and extract sub-widget-proxies out of this
|
@@ -44,13 +44,13 @@ module Glimmer
|
|
44
44
|
# Follows the Proxy Design Pattern
|
45
45
|
class WidgetProxy
|
46
46
|
include Packages
|
47
|
-
include
|
47
|
+
include ProxyProperties
|
48
48
|
include Custom::Drawable
|
49
49
|
|
50
50
|
DEFAULT_STYLES = {
|
51
51
|
'arrow' => [:arrow],
|
52
52
|
'button' => [:push],
|
53
|
-
'canvas' => [:double_buffered],
|
53
|
+
'canvas' => ([:double_buffered] if OS.windows?),
|
54
54
|
'checkbox' => [:check],
|
55
55
|
'check' => [:check],
|
56
56
|
'drag_source' => [:drop_copy],
|
@@ -112,13 +112,15 @@ module Glimmer
|
|
112
112
|
# Instantiates the right WidgetProxy subclass for passed in keyword
|
113
113
|
# Args are: keyword, parent, swt_widget_args (including styles)
|
114
114
|
def create(*init_args, swt_widget: nil)
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
115
|
+
DisplayProxy.instance.auto_exec do
|
116
|
+
return swt_widget.get_data('proxy') if swt_widget&.get_data('proxy')
|
117
|
+
keyword, parent, args = init_args
|
118
|
+
selected_widget_proxy_class = widget_proxy_class(keyword || underscored_widget_name(swt_widget))
|
119
|
+
if init_args.empty?
|
120
|
+
selected_widget_proxy_class.new(swt_widget: swt_widget)
|
121
|
+
else
|
122
|
+
selected_widget_proxy_class.new(*init_args)
|
123
|
+
end
|
122
124
|
end
|
123
125
|
end
|
124
126
|
|
@@ -149,31 +151,33 @@ module Glimmer
|
|
149
151
|
#
|
150
152
|
# Styles is a comma separate list of symbols representing SWT styles in lower case
|
151
153
|
def initialize(*init_args, swt_widget: nil)
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
@swt_widget
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
on_widget_disposed
|
174
|
-
|
175
|
-
|
176
|
-
|
154
|
+
auto_exec do
|
155
|
+
@image_double_buffered = !!(init_args&.last&.include?(:image_double_buffered) && init_args&.last&.delete(:image_double_buffered))
|
156
|
+
if swt_widget.nil?
|
157
|
+
underscored_widget_name, parent, args = init_args
|
158
|
+
@parent_proxy = parent
|
159
|
+
styles, extra_options = extract_args(underscored_widget_name, args)
|
160
|
+
swt_widget_class = self.class.swt_widget_class_for(underscored_widget_name)
|
161
|
+
@swt_widget = swt_widget_class.new(@parent_proxy.swt_widget, style(underscored_widget_name, styles), *extra_options)
|
162
|
+
else
|
163
|
+
@swt_widget = swt_widget
|
164
|
+
underscored_widget_name = self.class.underscored_widget_name(@swt_widget)
|
165
|
+
parent_proxy_class = self.class.widget_proxy_class(self.class.underscored_widget_name(@swt_widget.parent))
|
166
|
+
parent = swt_widget.parent
|
167
|
+
@parent_proxy = parent&.get_data('proxy') || parent_proxy_class.new(swt_widget: parent)
|
168
|
+
end
|
169
|
+
if @swt_widget&.get_data('proxy').nil?
|
170
|
+
@swt_widget.set_data('proxy', self)
|
171
|
+
DEFAULT_INITIALIZERS[underscored_widget_name.to_s.to_sym]&.call(@swt_widget)
|
172
|
+
@parent_proxy.post_initialize_child(self)
|
173
|
+
end
|
174
|
+
@keyword = underscored_widget_name.to_s
|
175
|
+
if respond_to?(:on_widget_disposed)
|
176
|
+
on_widget_disposed {
|
177
|
+
clear_shapes
|
178
|
+
deregister_shape_painting
|
179
|
+
}
|
180
|
+
end
|
177
181
|
end
|
178
182
|
end
|
179
183
|
|
@@ -219,81 +223,77 @@ module Glimmer
|
|
219
223
|
[args, extra_options]
|
220
224
|
end
|
221
225
|
end
|
222
|
-
|
223
|
-
def has_attribute_getter?(attribute_getter_name, *args)
|
224
|
-
attribute_getter_name = attribute_getter_name.to_s.underscore
|
225
|
-
return false unless !attribute_getter_name.end_with?('=') && !attribute_getter_name.start_with?('set_')
|
226
|
-
args.empty? && swt_widget.respond_to?(attribute_getter_name)
|
227
|
-
end
|
228
226
|
|
229
|
-
def
|
230
|
-
|
231
|
-
underscored_attribute_setter_name = attribute_setter_name.underscore
|
232
|
-
return false unless attribute_setter_name.end_with?('=') || (attribute_setter_name.start_with?('set_') && !args.empty?)
|
233
|
-
attribute_name = underscored_attribute_setter_name.sub(/^set_/, '').sub(/=$/, '')
|
234
|
-
has_attribute?(attribute_name, *args)
|
227
|
+
def proxy_source_object
|
228
|
+
@swt_widget
|
235
229
|
end
|
236
|
-
|
230
|
+
|
237
231
|
def has_attribute?(attribute_name, *args)
|
238
232
|
# TODO test that attribute getter responds too
|
239
233
|
widget_custom_attribute = widget_custom_attribute_mapping[attribute_name.to_s]
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
234
|
+
auto_exec do
|
235
|
+
if widget_custom_attribute
|
236
|
+
@swt_widget.respond_to?(widget_custom_attribute[:setter][:name])
|
237
|
+
else
|
238
|
+
super
|
239
|
+
end
|
244
240
|
end
|
245
241
|
end
|
246
242
|
|
247
243
|
def set_attribute(attribute_name, *args)
|
248
244
|
# TODO Think about widget subclasses overriding set_attribute to add more attributes vs adding as Ruby attributes directly
|
249
245
|
widget_custom_attribute = widget_custom_attribute_mapping[attribute_name.to_s]
|
250
|
-
|
251
|
-
|
252
|
-
widget_custom_attribute[:setter][:invoker].call(@swt_widget, args)
|
253
|
-
elsif @swt_widget.respond_to?(attribute_setter(attribute_name))
|
254
|
-
@swt_widget.send(attribute_setter(attribute_name), *args) unless @swt_widget.send(attribute_getter(attribute_name)) == args.first
|
255
|
-
elsif @swt_widget.respond_to?(ruby_attribute_setter(attribute_name))
|
256
|
-
@swt_widget.send(ruby_attribute_setter(attribute_name), args)
|
257
|
-
else
|
258
|
-
send(ruby_attribute_setter(attribute_name), args)
|
246
|
+
auto_exec do
|
247
|
+
apply_property_type_converters(normalized_attribute(attribute_name), args)
|
259
248
|
end
|
249
|
+
swt_widget_operation = false
|
250
|
+
result = nil
|
251
|
+
auto_exec do
|
252
|
+
result = if widget_custom_attribute
|
253
|
+
swt_widget_operation = true
|
254
|
+
widget_custom_attribute[:setter][:invoker].call(@swt_widget, args)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
result = super unless swt_widget_operation
|
258
|
+
result
|
260
259
|
end
|
261
260
|
|
262
261
|
def get_attribute(attribute_name)
|
263
262
|
widget_custom_attribute = widget_custom_attribute_mapping[attribute_name.to_s]
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
263
|
+
swt_widget_operation = false
|
264
|
+
result = nil
|
265
|
+
auto_exec do
|
266
|
+
result = if widget_custom_attribute
|
267
|
+
swt_widget_operation = true
|
268
|
+
if widget_custom_attribute[:getter][:invoker]
|
269
|
+
widget_custom_attribute[:getter][:invoker].call(@swt_widget, [])
|
270
|
+
else
|
271
|
+
@swt_widget.send(widget_custom_attribute[:getter][:name])
|
272
|
+
end
|
269
273
|
end
|
270
|
-
elsif @swt_widget.respond_to?(attribute_getter(attribute_name))
|
271
|
-
@swt_widget.send(attribute_getter(attribute_name))
|
272
|
-
elsif @swt_widget.respond_to?(ruby_attribute_getter(attribute_name))
|
273
|
-
@swt_widget.send(ruby_attribute_getter(attribute_name))
|
274
|
-
elsif @swt_widget.respond_to?(attribute_name)
|
275
|
-
@swt_widget.send(attribute_name)
|
276
|
-
elsif respond_to?(ruby_attribute_getter(attribute_name))
|
277
|
-
send(ruby_attribute_getter(attribute_name))
|
278
|
-
else
|
279
|
-
send(attribute_name)
|
280
274
|
end
|
275
|
+
result = super unless swt_widget_operation
|
276
|
+
result
|
281
277
|
end
|
282
278
|
|
283
279
|
def pack_same_size
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
@swt_widget.
|
291
|
-
|
292
|
-
|
280
|
+
auto_exec do
|
281
|
+
bounds = @swt_widget.getBounds
|
282
|
+
listener = on_control_resized {
|
283
|
+
@swt_widget.setSize(bounds.width, bounds.height)
|
284
|
+
@swt_widget.setLocation(bounds.x, bounds.y)
|
285
|
+
}
|
286
|
+
if @swt_widget.is_a?(Composite)
|
287
|
+
@swt_widget.layout(true, true)
|
288
|
+
else
|
289
|
+
@swt_widget.pack(true)
|
290
|
+
end
|
291
|
+
@swt_widget.removeControlListener(listener.swt_listener)
|
293
292
|
end
|
294
|
-
@swt_widget.removeControlListener(listener.swt_listener)
|
295
293
|
end
|
296
294
|
|
295
|
+
# these work in tandem with the property_type_converters
|
296
|
+
# sometimes, they are specified in subclasses instead
|
297
297
|
def widget_property_listener_installers
|
298
298
|
@swt_widget_property_listener_installers ||= {
|
299
299
|
Java::OrgEclipseSwtWidgets::Control => {
|
@@ -334,6 +334,17 @@ module Glimmer
|
|
334
334
|
}
|
335
335
|
end,
|
336
336
|
},
|
337
|
+
Java::OrgEclipseSwtWidgets::Tree => {
|
338
|
+
:selection => lambda do |observer|
|
339
|
+
on_widget_selected { |selection_event|
|
340
|
+
if has_style?(:multi)
|
341
|
+
observer.call(@swt_widget.getSelection.map(&:get_data))
|
342
|
+
else
|
343
|
+
observer.call(@swt_widget.getSelection.first&.get_data)
|
344
|
+
end
|
345
|
+
}
|
346
|
+
end,
|
347
|
+
},
|
337
348
|
Java::OrgEclipseSwtWidgets::Text => {
|
338
349
|
:text => lambda do |observer|
|
339
350
|
on_modify_text { |modify_event|
|
@@ -546,25 +557,37 @@ module Glimmer
|
|
546
557
|
@flyweight_swt_widget_classes ||= {}
|
547
558
|
end
|
548
559
|
|
560
|
+
# delegates to DisplayProxy
|
549
561
|
def async_exec(&block)
|
550
562
|
DisplayProxy.instance.async_exec(&block)
|
551
563
|
end
|
552
564
|
|
565
|
+
# delegates to DisplayProxy
|
553
566
|
def sync_exec(&block)
|
554
567
|
DisplayProxy.instance.sync_exec(&block)
|
555
568
|
end
|
556
569
|
|
570
|
+
# delegates to DisplayProxy
|
557
571
|
def timer_exec(delay_in_millis, &block)
|
558
572
|
DisplayProxy.instance.timer_exec(delay_in_millis, &block)
|
559
573
|
end
|
560
574
|
|
575
|
+
# delegates to DisplayProxy
|
576
|
+
def auto_exec(override_sync_exec: nil, override_async_exec: nil, &block)
|
577
|
+
DisplayProxy.instance.auto_exec(override_sync_exec: override_sync_exec, override_async_exec: override_async_exec, &block)
|
578
|
+
end
|
579
|
+
|
561
580
|
def has_style?(style)
|
562
581
|
comparison = interpret_style(style)
|
563
|
-
|
582
|
+
auto_exec do
|
583
|
+
(@swt_widget.style & comparison) == comparison
|
584
|
+
end
|
564
585
|
end
|
565
586
|
|
566
587
|
def dispose
|
567
|
-
|
588
|
+
auto_exec do
|
589
|
+
@swt_widget.dispose
|
590
|
+
end
|
568
591
|
end
|
569
592
|
|
570
593
|
def disposed?
|
@@ -574,15 +597,19 @@ module Glimmer
|
|
574
597
|
# TODO Consider renaming these methods as they are mainly used for data-binding
|
575
598
|
|
576
599
|
def can_add_observer?(property_name)
|
577
|
-
|
600
|
+
auto_exec do
|
601
|
+
@swt_widget.class.ancestors.map {|ancestor| widget_property_listener_installers[ancestor]}.compact.map(&:keys).flatten.map(&:to_s).include?(property_name.to_s)
|
602
|
+
end
|
578
603
|
end
|
579
604
|
|
580
605
|
# Used for data-binding only. Consider renaming or improving to avoid the confusion it causes
|
581
606
|
def add_observer(observer, property_name)
|
582
607
|
if !observer.respond_to?(:binding_options) || !observer.binding_options[:read_only]
|
583
|
-
|
584
|
-
|
585
|
-
|
608
|
+
auto_exec do
|
609
|
+
property_listener_installers = @swt_widget.class.ancestors.map {|ancestor| widget_property_listener_installers[ancestor]}.compact
|
610
|
+
widget_listener_installers = property_listener_installers.map{|installer| installer[property_name.to_s.to_sym]}.compact if !property_listener_installers.empty?
|
611
|
+
widget_listener_installers.to_a.first&.call(observer)
|
612
|
+
end
|
586
613
|
end
|
587
614
|
end
|
588
615
|
|
@@ -597,7 +624,7 @@ module Glimmer
|
|
597
624
|
end
|
598
625
|
|
599
626
|
def ensure_drop_target_proxy(style=[])
|
600
|
-
@drop_target_proxy ||=
|
627
|
+
@drop_target_proxy ||= WidgetProxy.new('drop_target', self, style).tap do |proxy|
|
601
628
|
proxy.set_attribute(:transfer, :text)
|
602
629
|
proxy.on_drag_enter { |event|
|
603
630
|
event.detail = DNDProxy[:drop_copy]
|
@@ -608,7 +635,7 @@ module Glimmer
|
|
608
635
|
# TODO eliminate duplication in the following methods perhaps by relying on exceptions
|
609
636
|
|
610
637
|
def can_handle_observation_request?(observation_request)
|
611
|
-
observation_request = observation_request
|
638
|
+
observation_request = normalize_observation_request(observation_request)
|
612
639
|
if observation_request.start_with?('on_swt_')
|
613
640
|
constant_name = observation_request.sub(/^on_swt_/, '')
|
614
641
|
SWTProxy.has_constant?(constant_name)
|
@@ -619,13 +646,15 @@ module Glimmer
|
|
619
646
|
end
|
620
647
|
|
621
648
|
def can_handle_drag_observation_request?(observation_request)
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
649
|
+
auto_exec do
|
650
|
+
return false unless swt_widget.is_a?(Control)
|
651
|
+
potential_drag_source = @drag_source_proxy.nil?
|
652
|
+
ensure_drag_source_proxy
|
653
|
+
@drag_source_proxy.can_handle_observation_request?(observation_request).tap do |result|
|
654
|
+
if potential_drag_source && !result
|
655
|
+
@drag_source_proxy.swt_widget.dispose
|
656
|
+
@drag_source_proxy = nil
|
657
|
+
end
|
629
658
|
end
|
630
659
|
end
|
631
660
|
rescue => e
|
@@ -634,19 +663,21 @@ module Glimmer
|
|
634
663
|
end
|
635
664
|
|
636
665
|
def can_handle_drop_observation_request?(observation_request)
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
666
|
+
auto_exec do
|
667
|
+
return false unless swt_widget.is_a?(Control)
|
668
|
+
potential_drop_target = @drop_target_proxy.nil?
|
669
|
+
ensure_drop_target_proxy
|
670
|
+
@drop_target_proxy.can_handle_observation_request?(observation_request).tap do |result|
|
671
|
+
if potential_drop_target && !result
|
672
|
+
@drop_target_proxy.swt_widget.dispose
|
673
|
+
@drop_target_proxy = nil
|
674
|
+
end
|
644
675
|
end
|
645
676
|
end
|
646
677
|
end
|
647
678
|
|
648
679
|
def handle_observation_request(observation_request, &block)
|
649
|
-
observation_request = observation_request
|
680
|
+
observation_request = normalize_observation_request(observation_request)
|
650
681
|
if observation_request.start_with?('on_swt_')
|
651
682
|
constant_name = observation_request.sub(/^on_swt_/, '')
|
652
683
|
add_swt_event_listener(constant_name, &block)
|
@@ -664,30 +695,26 @@ module Glimmer
|
|
664
695
|
end
|
665
696
|
|
666
697
|
def content(&block)
|
667
|
-
|
698
|
+
auto_exec do
|
699
|
+
Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::SWT::WidgetExpression.new, &block)
|
700
|
+
end
|
668
701
|
end
|
669
702
|
|
670
703
|
def method_missing(method, *args, &block)
|
704
|
+
# TODO push most of this logic down to Properties (and perhaps create Listeners module as well)
|
671
705
|
if can_handle_observation_request?(method)
|
672
706
|
handle_observation_request(method, &block)
|
673
|
-
elsif has_attribute_setter?(method, *args)
|
674
|
-
set_attribute(method, *args)
|
675
|
-
elsif has_attribute_getter?(method, *args)
|
676
|
-
get_attribute(method, *args)
|
677
707
|
else
|
678
|
-
|
708
|
+
super
|
679
709
|
end
|
680
|
-
rescue => e
|
681
|
-
Glimmer::Config.logger.debug { "Neither WidgetProxy nor #{swt_widget.class.name} can handle the method ##{method}" }
|
682
|
-
Glimmer::Config.logger.debug { e.full_message }
|
683
|
-
super
|
684
|
-
# TODO consider get_attribute too
|
685
710
|
end
|
686
711
|
|
687
712
|
def respond_to?(method, *args, &block)
|
688
|
-
super
|
689
|
-
|
690
|
-
|
713
|
+
result = super
|
714
|
+
return true if result
|
715
|
+
auto_exec do
|
716
|
+
can_handle_observation_request?(method)
|
717
|
+
end
|
691
718
|
end
|
692
719
|
|
693
720
|
private
|
@@ -713,16 +740,26 @@ module Glimmer
|
|
713
740
|
# add_listener knowing it will be called for sure afterwards
|
714
741
|
|
715
742
|
def can_add_listener?(underscored_listener_name)
|
716
|
-
|
743
|
+
auto_exec do
|
744
|
+
!self.class.find_listener(@swt_widget.getClass, underscored_listener_name).empty?
|
745
|
+
end
|
717
746
|
end
|
718
747
|
|
719
748
|
def add_listener(underscored_listener_name, &block)
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
749
|
+
auto_exec do
|
750
|
+
widget_add_listener_method, listener_class, listener_method = self.class.find_listener(@swt_widget.getClass, underscored_listener_name)
|
751
|
+
widget_listener_proxy = nil
|
752
|
+
safe_block = lambda do |*args|
|
753
|
+
begin
|
754
|
+
block.call(*args) unless @swt_widget.isDisposed
|
755
|
+
rescue => e
|
756
|
+
Glimmer::Config.logger.error {e}
|
757
|
+
end
|
758
|
+
end
|
759
|
+
listener = listener_class.new(listener_method => safe_block)
|
760
|
+
@swt_widget.send(widget_add_listener_method, listener)
|
761
|
+
WidgetListenerProxy.new(swt_widget: @swt_widget, swt_listener: listener, widget_add_listener_method: widget_add_listener_method, swt_listener_class: listener_class, swt_listener_method: listener_method)
|
762
|
+
end
|
726
763
|
end
|
727
764
|
|
728
765
|
# Looks through SWT class add***Listener methods till it finds one for which
|
@@ -772,16 +809,22 @@ module Glimmer
|
|
772
809
|
end
|
773
810
|
|
774
811
|
def add_swt_event_listener(swt_constant, &block)
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
812
|
+
auto_exec do
|
813
|
+
event_type = SWTProxy[swt_constant]
|
814
|
+
widget_listener_proxy = nil
|
815
|
+
safe_block = lambda { |*args| block.call(*args) unless @swt_widget.isDisposed }
|
816
|
+
@swt_widget.addListener(event_type, &safe_block)
|
817
|
+
widget_listener_proxy = WidgetListenerProxy.new(swt_widget: @swt_widget, swt_listener: @swt_widget.getListeners(event_type).last, event_type: event_type, swt_constant: swt_constant)
|
818
|
+
end
|
780
819
|
end
|
781
820
|
|
782
821
|
def widget_custom_attribute_mapping
|
783
822
|
# TODO scope per widget class type just like other mappings
|
784
823
|
@swt_widget_custom_attribute_mapping ||= {
|
824
|
+
'window' => {
|
825
|
+
getter: {name: 'getShell'},
|
826
|
+
setter: {name: 'getShell', invoker: lambda { |widget, args| @swt_widget.getShell }}, # No Op
|
827
|
+
},
|
785
828
|
'focus' => {
|
786
829
|
getter: {name: 'isFocusControl'},
|
787
830
|
setter: {name: 'setFocus', invoker: lambda { |widget, args| @swt_widget.setFocus if args.first }},
|
@@ -834,6 +877,14 @@ module Glimmer
|
|
834
877
|
ensure_drop_target_proxy
|
835
878
|
@drop_target_proxy.set_attribute(:drop_target_effect, args)
|
836
879
|
end
|
880
|
+
|
881
|
+
def normalize_observation_request(observation_request)
|
882
|
+
observation_request = observation_request.to_s
|
883
|
+
if @swt_widget.is_a?(Shell) && observation_request.downcase.include?('window')
|
884
|
+
observation_request = observation_request.sub('window', 'shell').sub('Window', 'Shell')
|
885
|
+
end
|
886
|
+
observation_request
|
887
|
+
end
|
837
888
|
|
838
889
|
def apply_property_type_converters(attribute_name, args)
|
839
890
|
value = args
|
@@ -849,6 +900,8 @@ module Glimmer
|
|
849
900
|
color_converter = lambda do |value|
|
850
901
|
if value.is_a?(Symbol) || value.is_a?(String)
|
851
902
|
ColorProxy.new(value).swt_color
|
903
|
+
elsif value.is_a?(RGB)
|
904
|
+
ColorProxy.new(value.red, value.green, value.blue).swt_color
|
852
905
|
else
|
853
906
|
value
|
854
907
|
end
|
@@ -887,7 +940,7 @@ module Glimmer
|
|
887
940
|
while last_image_number != image_number
|
888
941
|
last_image_number = image_number
|
889
942
|
sync_exec {
|
890
|
-
redraw
|
943
|
+
redraw unless disposed?
|
891
944
|
}
|
892
945
|
delayTime = loader.data[image_number].delayTime.to_f / 100.0
|
893
946
|
sleep(delayTime)
|
@@ -918,7 +971,7 @@ module Glimmer
|
|
918
971
|
foreground: color_converter,
|
919
972
|
link_foreground: color_converter,
|
920
973
|
font: lambda do |value|
|
921
|
-
if value.is_a?(Hash)
|
974
|
+
if value.is_a?(Hash) || value.is_a?(FontData)
|
922
975
|
font_properties = value
|
923
976
|
FontProxy.new(self, font_properties).swt_font
|
924
977
|
else
|
@@ -936,6 +989,10 @@ module Glimmer
|
|
936
989
|
items: lambda do |value|
|
937
990
|
value.to_java :string
|
938
991
|
end,
|
992
|
+
selection: lambda do |value|
|
993
|
+
value = value.to_f if swt_widget.is_a?(Spinner)
|
994
|
+
value
|
995
|
+
end,
|
939
996
|
text: lambda do |value|
|
940
997
|
value.to_s
|
941
998
|
end,
|