glimmer-dsl-swt 4.18.2.5 → 4.18.3.4
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 +56 -0
- data/README.md +344 -35
- data/VERSION +1 -1
- data/glimmer-dsl-swt.gemspec +13 -7
- data/lib/ext/glimmer/config.rb +24 -7
- data/lib/glimmer/data_binding/table_items_binding.rb +8 -5
- data/lib/glimmer/data_binding/widget_binding.rb +22 -4
- data/lib/glimmer/dsl/swt/dsl.rb +1 -0
- data/lib/glimmer/dsl/swt/image_expression.rb +14 -6
- data/lib/glimmer/dsl/swt/layout_data_expression.rb +4 -4
- data/lib/glimmer/dsl/swt/layout_expression.rb +5 -3
- data/lib/glimmer/dsl/swt/multiply_expression.rb +53 -0
- data/lib/glimmer/dsl/swt/property_expression.rb +4 -2
- data/{samples/elaborate/tetris/view/game_over_dialog.rb → lib/glimmer/dsl/swt/transform_expression.rb} +29 -46
- data/lib/glimmer/swt/custom/drawable.rb +4 -3
- data/lib/glimmer/swt/custom/shape.rb +37 -14
- data/lib/glimmer/swt/directory_dialog_proxy.rb +3 -3
- data/lib/glimmer/swt/display_proxy.rb +26 -5
- data/lib/glimmer/swt/file_dialog_proxy.rb +3 -3
- data/lib/glimmer/swt/image_proxy.rb +68 -1
- data/lib/glimmer/swt/shell_proxy.rb +23 -3
- data/lib/glimmer/swt/table_proxy.rb +31 -7
- data/lib/glimmer/swt/transform_proxy.rb +109 -0
- data/lib/glimmer/swt/widget_listener_proxy.rb +14 -5
- data/lib/glimmer/swt/widget_proxy.rb +7 -3
- data/lib/glimmer/ui/custom_shell.rb +11 -9
- data/lib/glimmer/ui/custom_widget.rb +32 -17
- data/samples/elaborate/meta_sample.rb +81 -24
- data/samples/elaborate/tetris.rb +146 -42
- data/samples/elaborate/tetris/model/game.rb +258 -137
- data/samples/elaborate/tetris/model/past_game.rb +26 -0
- data/samples/elaborate/tetris/model/tetromino.rb +45 -29
- data/samples/elaborate/tetris/view/block.rb +8 -13
- data/samples/elaborate/tetris/view/high_score_dialog.rb +133 -0
- data/samples/elaborate/tetris/view/playfield.rb +1 -1
- data/samples/elaborate/tetris/view/score_lane.rb +11 -11
- data/samples/elaborate/tetris/view/tetris_menu_bar.rb +139 -0
- data/samples/elaborate/tic_tac_toe.rb +4 -4
- data/samples/hello/hello_canvas.rb +4 -4
- data/samples/hello/hello_canvas_animation.rb +3 -3
- data/samples/hello/hello_canvas_transform.rb +40 -0
- data/samples/hello/hello_link.rb +1 -1
- metadata +11 -5
@@ -35,11 +35,12 @@ module Glimmer
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
def
|
39
|
-
# TODO consider performance
|
38
|
+
def resetup_shape_painting
|
39
|
+
# TODO consider performance optimization relating to order of shape rendering (affecting only further shapes not previous ones)
|
40
|
+
reset_gc if respond_to?(:reset_gc)
|
40
41
|
shapes.each do |shape|
|
41
42
|
shape.paint_listener_proxy&.unregister
|
42
|
-
shape.
|
43
|
+
shape.setup_painting
|
43
44
|
end
|
44
45
|
end
|
45
46
|
end
|
@@ -24,12 +24,12 @@ require 'glimmer/swt/swt_proxy'
|
|
24
24
|
require 'glimmer/swt/display_proxy'
|
25
25
|
require 'glimmer/swt/color_proxy'
|
26
26
|
require 'glimmer/swt/font_proxy'
|
27
|
+
require 'glimmer/swt/transform_proxy'
|
27
28
|
|
28
29
|
module Glimmer
|
29
30
|
module SWT
|
30
31
|
module Custom
|
31
32
|
# Represents a shape (graphics) to be drawn on a control/widget/canvas/display
|
32
|
-
# swt_widget returns the parent (e.g. a `canvas` WidgetProxy), equivalent to `parent.swt_widget`
|
33
33
|
# That is because Shape is drawn on a parent as graphics and doesn't have an SWT widget for itself
|
34
34
|
class Shape
|
35
35
|
include Packages
|
@@ -77,9 +77,11 @@ module Glimmer
|
|
77
77
|
def flyweight_method_names
|
78
78
|
@flyweight_method_names ||= {}
|
79
79
|
end
|
80
|
+
|
81
|
+
|
80
82
|
end
|
81
83
|
|
82
|
-
attr_reader :parent, :name, :args, :options, :
|
84
|
+
attr_reader :parent, :name, :args, :options, :paint_listener_proxy
|
83
85
|
|
84
86
|
def initialize(parent, keyword, *args, &property_block)
|
85
87
|
@parent = parent
|
@@ -87,7 +89,6 @@ module Glimmer
|
|
87
89
|
@method_name = self.class.method_name(keyword, args)
|
88
90
|
@options = self.class.arg_options(args, extract: true)
|
89
91
|
@args = args
|
90
|
-
@swt_widget = parent.respond_to?(:swt_display) ? parent.swt_display : parent.swt_widget
|
91
92
|
@properties = {}
|
92
93
|
@parent.shapes << self
|
93
94
|
post_add_content if property_block.nil?
|
@@ -110,11 +111,13 @@ module Glimmer
|
|
110
111
|
end
|
111
112
|
|
112
113
|
def post_add_content
|
113
|
-
|
114
|
+
amend_method_name_options_based_on_properties
|
115
|
+
setup_painting
|
114
116
|
@content_added = true
|
115
117
|
end
|
116
118
|
|
117
119
|
def apply_property_arg_conversions(method_name, property, args)
|
120
|
+
args = args.dup
|
118
121
|
the_java_method = org.eclipse.swt.graphics.GC.java_class.declared_instance_methods.detect {|m| m.name == method_name}
|
119
122
|
if (args.first.is_a?(Symbol) || args.first.is_a?(String))
|
120
123
|
if the_java_method.parameter_types.first == Color.java_class
|
@@ -133,6 +136,9 @@ module Glimmer
|
|
133
136
|
if args.first.is_a?(FontProxy)
|
134
137
|
args[0] = args[0].swt_font
|
135
138
|
end
|
139
|
+
if args.first.is_a?(TransformProxy)
|
140
|
+
args[0] = args[0].swt_transform
|
141
|
+
end
|
136
142
|
if ['setBackgroundPattern', 'setForegroundPattern'].include?(method_name.to_s)
|
137
143
|
args.each_with_index do |arg, i|
|
138
144
|
if arg.is_a?(Symbol) || arg.is_a?(String)
|
@@ -145,7 +151,7 @@ module Glimmer
|
|
145
151
|
args[0] = org.eclipse.swt.graphics.Pattern.new(*new_args)
|
146
152
|
args[1..-1] = []
|
147
153
|
end
|
148
|
-
|
154
|
+
args
|
149
155
|
end
|
150
156
|
|
151
157
|
def apply_shape_arg_conversions(method_name, args)
|
@@ -181,6 +187,15 @@ module Glimmer
|
|
181
187
|
args[the_java_method_arg_count..-1] = []
|
182
188
|
end
|
183
189
|
end
|
190
|
+
|
191
|
+
def amend_method_name_options_based_on_properties
|
192
|
+
if @properties.keys.map(&:to_s).include?('background') && !@properties.keys.map(&:to_s).include?('foreground')
|
193
|
+
@options[:fill] = true
|
194
|
+
elsif @properties.keys.map(&:to_s).include?('foreground') && !@properties.keys.map(&:to_s).include?('background')
|
195
|
+
@options[:fill] = false
|
196
|
+
end
|
197
|
+
@method_name = self.class.method_name(@name, @args + [@options])
|
198
|
+
end
|
184
199
|
|
185
200
|
def has_attribute?(attribute_name, *args)
|
186
201
|
self.class.gc_instance_methods.include?(attribute_setter(attribute_name))
|
@@ -188,32 +203,40 @@ module Glimmer
|
|
188
203
|
|
189
204
|
def set_attribute(attribute_name, *args)
|
190
205
|
@properties[attribute_name] = args
|
191
|
-
if @content_added
|
192
|
-
@parent.
|
206
|
+
if @content_added && !@parent.is_disposed
|
207
|
+
@parent.resetup_shape_painting
|
193
208
|
@parent.redraw
|
194
209
|
end
|
195
210
|
end
|
196
|
-
|
211
|
+
|
197
212
|
def get_attribute(attribute_name)
|
198
213
|
@properties.symbolize_keys[attribute_name.to_s.to_sym]
|
199
214
|
end
|
200
215
|
|
201
|
-
def
|
216
|
+
def setup_painting
|
217
|
+
# TODO consider moving this method to parent (making the logic polymorphic)
|
218
|
+
return if @parent.is_disposed
|
202
219
|
if parent.respond_to?(:swt_display)
|
203
220
|
@paint_listener_proxy = @parent.on_swt_paint(&method(:paint))
|
204
|
-
|
221
|
+
elsif parent.respond_to?(:swt_image)
|
222
|
+
paint(parent) # treat parent as paint event since you don't do repaints with images, it's a one time deal.
|
223
|
+
elsif parent.respond_to?(:swt_widget)
|
205
224
|
@paint_listener_proxy = @parent.on_paint_control(&method(:paint))
|
206
225
|
end
|
207
226
|
end
|
208
227
|
|
209
228
|
def paint(paint_event)
|
210
229
|
@properties['background'] = [@parent.background] if fill? && !@properties.keys.map(&:to_s).include?('background')
|
211
|
-
@properties['foreground'] = [@parent.foreground] if draw? && !@properties.keys.map(&:to_s).include?('foreground')
|
212
|
-
@properties['font'] = [@parent.font] if draw? && !@properties.keys.map(&:to_s).include?('font')
|
230
|
+
@properties['foreground'] = [@parent.foreground] if @parent.respond_to?(:foreground) && draw? && !@properties.keys.map(&:to_s).include?('foreground')
|
231
|
+
@properties['font'] = [@parent.font] if @parent.respond_to?(:font) && draw? && !@properties.keys.map(&:to_s).include?('font')
|
232
|
+
@properties['transform'] = [nil] if @parent.respond_to?(:transform) && !@properties.keys.map(&:to_s).include?('transform')
|
213
233
|
@properties.each do |property, args|
|
214
234
|
method_name = attribute_setter(property)
|
215
|
-
apply_property_arg_conversions(method_name, property, args)
|
216
|
-
paint_event.gc.send(method_name, *
|
235
|
+
converted_args = apply_property_arg_conversions(method_name, property, args)
|
236
|
+
paint_event.gc.send(method_name, *converted_args)
|
237
|
+
if property == 'transform' && args.first.is_a?(TransformProxy)
|
238
|
+
args.first.swt_transform.dispose
|
239
|
+
end
|
217
240
|
end
|
218
241
|
apply_shape_arg_conversions(@method_name, @args)
|
219
242
|
apply_shape_arg_defaults(@method_name, @args)
|
@@ -47,13 +47,13 @@ module Glimmer
|
|
47
47
|
style_arg_last_index = args.index(style_args.last)
|
48
48
|
args[style_arg_start_index..style_arg_last_index] = SWTProxy[style_args]
|
49
49
|
end
|
50
|
+
if args.first.respond_to?(:swt_widget) && args.first.swt_widget.is_a?(Shell)
|
51
|
+
args[0] = args[0].swt_widget
|
52
|
+
end
|
50
53
|
if !args.first.is_a?(Shell)
|
51
54
|
current_shell = DisplayProxy.instance.swt_display.shells.first
|
52
55
|
args.unshift(current_shell.nil? ? ShellProxy.new : current_shell)
|
53
56
|
end
|
54
|
-
if args.first.is_a?(ShellProxy)
|
55
|
-
args[0] = args[0].swt_widget
|
56
|
-
end
|
57
57
|
parent = args[0]
|
58
58
|
@parent_proxy = parent.is_a?(Shell) ? ShellProxy.new(swt_widget: parent) : parent
|
59
59
|
@swt_widget = DirectoryDialog.new(*args)
|
@@ -39,8 +39,20 @@ module Glimmer
|
|
39
39
|
include_package 'org.eclipse.swt.widgets'
|
40
40
|
|
41
41
|
include Custom::Drawable
|
42
|
-
|
43
|
-
OBSERVED_MENU_ITEMS = ['about', 'preferences']
|
42
|
+
|
43
|
+
OBSERVED_MENU_ITEMS = ['about', 'preferences', 'quit']
|
44
|
+
|
45
|
+
class FilterListener
|
46
|
+
include org.eclipse.swt.widgets.Listener
|
47
|
+
|
48
|
+
def initialize(&listener_block)
|
49
|
+
@listener_block = listener_block
|
50
|
+
end
|
51
|
+
|
52
|
+
def handleEvent(event)
|
53
|
+
@listener_block.call(event)
|
54
|
+
end
|
55
|
+
end
|
44
56
|
|
45
57
|
class << self
|
46
58
|
# Returns singleton instance
|
@@ -111,7 +123,7 @@ module Glimmer
|
|
111
123
|
observation_request = observation_request.to_s
|
112
124
|
if observation_request.start_with?('on_swt_')
|
113
125
|
constant_name = observation_request.sub(/^on_swt_/, '')
|
114
|
-
|
126
|
+
add_swt_event_filter(constant_name, &block)
|
115
127
|
elsif observation_request.start_with?('on_')
|
116
128
|
event_name = observation_request.sub(/^on_/, '')
|
117
129
|
if OBSERVED_MENU_ITEMS.include?(event_name)
|
@@ -124,10 +136,19 @@ module Glimmer
|
|
124
136
|
end
|
125
137
|
end
|
126
138
|
|
127
|
-
def
|
139
|
+
def add_swt_event_filter(swt_constant, &block)
|
128
140
|
event_type = SWTProxy[swt_constant]
|
129
|
-
@swt_display.addFilter(event_type, &block)
|
141
|
+
@swt_display.addFilter(event_type, FilterListener.new(&block))
|
130
142
|
#WidgetListenerProxy.new(@swt_display.getListeners(event_type).last)
|
143
|
+
WidgetListenerProxy.new(
|
144
|
+
swt_display: @swt_display,
|
145
|
+
event_type: event_type,
|
146
|
+
filter: true,
|
147
|
+
swt_listener: block,
|
148
|
+
widget_add_listener_method: 'addFilter',
|
149
|
+
swt_listener_class: FilterListener,
|
150
|
+
swt_listener_method: 'handleEvent'
|
151
|
+
)
|
131
152
|
end
|
132
153
|
end
|
133
154
|
end
|
@@ -48,13 +48,13 @@ module Glimmer
|
|
48
48
|
style_arg_last_index = args.index(style_args.last)
|
49
49
|
args[style_arg_start_index..style_arg_last_index] = SWTProxy[style_args]
|
50
50
|
end
|
51
|
+
if args.first.respond_to?(:swt_widget) && args.first.swt_widget.is_a?(Shell)
|
52
|
+
args[0] = args[0].swt_widget
|
53
|
+
end
|
51
54
|
if !args.first.is_a?(Shell)
|
52
55
|
current_shell = DisplayProxy.instance.swt_display.shells.first
|
53
56
|
args.unshift(current_shell.nil? ? ShellProxy.new : current_shell)
|
54
57
|
end
|
55
|
-
if args.first.is_a?(ShellProxy)
|
56
|
-
args[0] = args[0].swt_widget
|
57
|
-
end
|
58
58
|
parent = args[0]
|
59
59
|
@parent_proxy = parent.is_a?(Shell) ? ShellProxy.new(swt_widget: parent) : parent
|
60
60
|
@swt_widget = FileDialog.new(*args)
|
@@ -19,6 +19,9 @@
|
|
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 'glimmer/swt/custom/drawable'
|
23
|
+
require 'glimmer/swt/properties'
|
24
|
+
|
22
25
|
module Glimmer
|
23
26
|
module SWT
|
24
27
|
# Proxy for org.eclipse.swt.graphics.Image
|
@@ -27,6 +30,9 @@ module Glimmer
|
|
27
30
|
#
|
28
31
|
# Follows the Proxy Design Pattern
|
29
32
|
class ImageProxy
|
33
|
+
include Custom::Drawable
|
34
|
+
include Properties
|
35
|
+
|
30
36
|
class << self
|
31
37
|
def create(*args)
|
32
38
|
if args.size == 1 && args.first.is_a?(ImageProxy)
|
@@ -37,6 +43,7 @@ module Glimmer
|
|
37
43
|
end
|
38
44
|
end
|
39
45
|
|
46
|
+
include_package 'org.eclipse.swt.widgets'
|
40
47
|
include_package 'org.eclipse.swt.graphics'
|
41
48
|
|
42
49
|
attr_reader :file_path, :jar_file_path, :image_data, :swt_image
|
@@ -46,8 +53,13 @@ module Glimmer
|
|
46
53
|
# Takes the same args as the SWT Image class
|
47
54
|
# Alternatively, takes a file path string or a uri:classloader file path string (generated by JRuby when invoking `File.expand_path` inside a JAR file)
|
48
55
|
# and returns an image object.
|
49
|
-
def initialize(*args)
|
56
|
+
def initialize(*args, &content)
|
50
57
|
@args = args
|
58
|
+
@parent_proxy = nil
|
59
|
+
if @args.first.is_a?(WidgetProxy)
|
60
|
+
@parent_proxy = @args.shift
|
61
|
+
@parent = @parent_proxy.swt_widget
|
62
|
+
end
|
51
63
|
options = @args.last.is_a?(Hash) ? @args.delete_at(-1) : {}
|
52
64
|
options[:swt_image] = @args.first if @args.size == 1 && @args.first.is_a?(Image)
|
53
65
|
@file_path = @args.first if @args.size == 1 && @args.first.is_a?(String)
|
@@ -55,6 +67,9 @@ module Glimmer
|
|
55
67
|
if options&.keys&.include?(:swt_image)
|
56
68
|
@swt_image = options[:swt_image]
|
57
69
|
@original_image_data = @image_data = @swt_image.image_data
|
70
|
+
elsif args.size == 1 && args.first.is_a?(ImageProxy)
|
71
|
+
@swt_image = @args.first.swt_image
|
72
|
+
@original_image_data = @image_data = @swt_image.image_data
|
58
73
|
elsif @file_path
|
59
74
|
@original_image_data = @image_data = ImageData.new(input_stream || @file_path)
|
60
75
|
@swt_image = Image.new(DisplayProxy.instance.swt_display, @image_data)
|
@@ -64,9 +79,15 @@ module Glimmer
|
|
64
79
|
width = (@image_data.width.to_f / @image_data.height.to_f)*height.to_f if !height.nil? && width.nil?
|
65
80
|
scale_to(width, height) unless width.nil? || height.nil?
|
66
81
|
else
|
82
|
+
@args.prepend(DisplayProxy.instance.swt_display) unless @args.first.is_a?(Display)
|
67
83
|
@swt_image = Image.new(*@args)
|
68
84
|
@original_image_data = @image_data = @swt_image.image_data
|
69
85
|
end
|
86
|
+
post_add_content if content.nil?
|
87
|
+
end
|
88
|
+
|
89
|
+
def post_add_content
|
90
|
+
@parent&.image = swt_image
|
70
91
|
end
|
71
92
|
|
72
93
|
def input_stream
|
@@ -91,6 +112,52 @@ module Glimmer
|
|
91
112
|
self
|
92
113
|
end
|
93
114
|
|
115
|
+
def gc
|
116
|
+
@gc ||= reset_gc
|
117
|
+
end
|
118
|
+
|
119
|
+
def reset_gc
|
120
|
+
@gc = org.eclipse.swt.graphics.GC.new(swt_image)
|
121
|
+
end
|
122
|
+
|
123
|
+
def has_attribute?(attribute_name, *args)
|
124
|
+
@swt_image.respond_to?(attribute_setter(attribute_name), args) || respond_to?(ruby_attribute_setter(attribute_name), args)
|
125
|
+
end
|
126
|
+
|
127
|
+
def set_attribute(attribute_name, *args)
|
128
|
+
# TODO consider refactoring/unifying this code with WidgetProxy and elsewhere
|
129
|
+
if args.count == 1
|
130
|
+
if args.first.is_a?(Symbol) || args.first.is_a?(String)
|
131
|
+
args[0] = ColorProxy.new(args.first).swt_color
|
132
|
+
end
|
133
|
+
if args.first.is_a?(ColorProxy)
|
134
|
+
args[0] = args.first.swt_color
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
if @swt_image.respond_to?(attribute_setter(attribute_name))
|
139
|
+
@swt_image.send(attribute_setter(attribute_name), *args) unless @swt_image.send(attribute_getter(attribute_name)) == args.first
|
140
|
+
elsif @swt_image.respond_to?(ruby_attribute_setter(attribute_name))
|
141
|
+
@swt_image.send(ruby_attribute_setter(attribute_name), args)
|
142
|
+
else
|
143
|
+
send(ruby_attribute_setter(attribute_name), args)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def get_attribute(attribute_name)
|
148
|
+
if @swt_image.respond_to?(attribute_getter(attribute_name))
|
149
|
+
@swt_image.send(attribute_getter(attribute_name))
|
150
|
+
elsif @swt_image.respond_to?(ruby_attribute_getter(attribute_name))
|
151
|
+
@swt_image.send(ruby_attribute_getter(attribute_name))
|
152
|
+
elsif @swt_image.respond_to?(attribute_name)
|
153
|
+
@swt_image.send(attribute_name)
|
154
|
+
elsif respond_to?(ruby_attribute_getter(attribute_name))
|
155
|
+
send(ruby_attribute_getter(attribute_name))
|
156
|
+
else
|
157
|
+
send(attribute_name)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
94
161
|
def method_missing(method, *args, &block)
|
95
162
|
swt_image.send(method, *args, &block)
|
96
163
|
rescue => e
|
@@ -45,11 +45,17 @@ module Glimmer
|
|
45
45
|
if swt_widget
|
46
46
|
@swt_widget = swt_widget
|
47
47
|
else
|
48
|
-
if args.first.is_a?(
|
48
|
+
if args.first.respond_to?(:swt_widget) && args.first.swt_widget.is_a?(Shell)
|
49
49
|
@parent_proxy = args[0]
|
50
50
|
args[0] = args[0].swt_widget
|
51
51
|
end
|
52
|
-
style_args = args.select {|arg| arg.is_a?(Symbol) || arg.is_a?(String)}
|
52
|
+
style_args = args.select {|arg| arg.is_a?(Symbol) || arg.is_a?(String)}.map(&:to_sym)
|
53
|
+
fill_screen = nil
|
54
|
+
if style_args.include?(:fill_screen)
|
55
|
+
args.delete(:fill_screen)
|
56
|
+
style_args.delete(:fill_screen)
|
57
|
+
fill_screen = true
|
58
|
+
end
|
53
59
|
if style_args.any?
|
54
60
|
style_arg_start_index = args.index(style_args.first)
|
55
61
|
style_arg_last_index = args.index(style_args.last)
|
@@ -67,6 +73,7 @@ module Glimmer
|
|
67
73
|
# TODO make this an option not the default
|
68
74
|
shell_swt_display = Glimmer::SWT::DisplayProxy.instance.swt_display
|
69
75
|
on_swt_show do
|
76
|
+
@swt_widget.set_size(@display.bounds.width, @display.bounds.height) if fill_screen
|
70
77
|
Thread.new do
|
71
78
|
sleep(0.25)
|
72
79
|
shell_swt_display.async_exec do
|
@@ -110,14 +117,27 @@ module Glimmer
|
|
110
117
|
def nested?
|
111
118
|
!swt_widget&.parent.nil?
|
112
119
|
end
|
120
|
+
alias nested nested?
|
121
|
+
|
122
|
+
def disposed?
|
123
|
+
swt_widget.isDisposed
|
124
|
+
end
|
125
|
+
alias disposed disposed?
|
113
126
|
|
127
|
+
# Hides shell. Automatically checks if widget is disposed to avoid crashing.
|
114
128
|
def hide
|
115
|
-
@swt_widget.setVisible(false)
|
129
|
+
@swt_widget.setVisible(false) unless @swt_widget.isDisposed
|
130
|
+
end
|
131
|
+
|
132
|
+
# Closes shell. Automatically checks if widget is disposed to avoid crashing.
|
133
|
+
def close
|
134
|
+
@swt_widget.close unless @swt_widget.isDisposed
|
116
135
|
end
|
117
136
|
|
118
137
|
def visible?
|
119
138
|
@swt_widget.isDisposed ? false : @swt_widget.isVisible
|
120
139
|
end
|
140
|
+
alias visible visible?
|
121
141
|
|
122
142
|
# Setting to true opens/shows shell. Setting to false hides the shell.
|
123
143
|
def visible=(visibility)
|
@@ -265,10 +265,18 @@ module Glimmer
|
|
265
265
|
end
|
266
266
|
end
|
267
267
|
|
268
|
+
def items
|
269
|
+
swt_widget.get_items
|
270
|
+
end
|
271
|
+
|
268
272
|
def model_binding
|
269
273
|
swt_widget.data
|
270
274
|
end
|
271
275
|
|
276
|
+
def table_items_binding
|
277
|
+
swt_widget.get_data('table_items_binding')
|
278
|
+
end
|
279
|
+
|
272
280
|
def sort_block=(comparator)
|
273
281
|
@sort_block = comparator
|
274
282
|
end
|
@@ -353,9 +361,9 @@ module Glimmer
|
|
353
361
|
@additional_sort_properties = args unless args.empty?
|
354
362
|
end
|
355
363
|
|
356
|
-
def sort!
|
364
|
+
def sort!(internal_sort: false)
|
357
365
|
return unless sort_property && (sort_type || sort_block || sort_by_block)
|
358
|
-
array = model_binding.evaluate_property
|
366
|
+
original_array = array = model_binding.evaluate_property
|
359
367
|
array = array.sort_by(&:hash) # this ensures consistent subsequent sorting in case there are equivalent sorts to avoid an infinite loop
|
360
368
|
# Converting value to_s first to handle nil cases. Should work with numeric, boolean, and date fields
|
361
369
|
if sort_block
|
@@ -379,7 +387,12 @@ module Glimmer
|
|
379
387
|
end
|
380
388
|
end
|
381
389
|
sorted_array = sorted_array.reverse if sort_direction == :descending
|
382
|
-
model_binding.
|
390
|
+
if model_binding.binding_options.symbolize_keys[:read_only_sort]
|
391
|
+
table_items_binding.call(sorted_array, internal_sort: true) unless internal_sort
|
392
|
+
else
|
393
|
+
model_binding.call(sorted_array)
|
394
|
+
end
|
395
|
+
sorted_array
|
383
396
|
end
|
384
397
|
|
385
398
|
def editor=(args)
|
@@ -445,7 +458,6 @@ module Glimmer
|
|
445
458
|
end
|
446
459
|
|
447
460
|
def edit_table_item(table_item, column_index, before_write: nil, after_write: nil, after_cancel: nil)
|
448
|
-
require 'facets/hash/symbolize_keys'
|
449
461
|
return if table_item.nil?
|
450
462
|
model = table_item.data
|
451
463
|
property = column_properties[column_index]
|
@@ -467,7 +479,11 @@ module Glimmer
|
|
467
479
|
@cancel_in_progress = true
|
468
480
|
@table_editor_widget_proxy&.swt_widget&.dispose
|
469
481
|
@table_editor_widget_proxy = nil
|
470
|
-
after_cancel&.
|
482
|
+
if after_cancel&.arity == 0
|
483
|
+
after_cancel&.call
|
484
|
+
else
|
485
|
+
after_cancel&.call(table_item)
|
486
|
+
end
|
471
487
|
@edit_in_progress = false
|
472
488
|
@cancel_in_progress = false
|
473
489
|
@cancel_edit = nil
|
@@ -484,14 +500,22 @@ module Glimmer
|
|
484
500
|
if new_value == model.send(model_editing_property)
|
485
501
|
@cancel_edit.call
|
486
502
|
else
|
487
|
-
before_write&.
|
503
|
+
if before_write&.arity == 0
|
504
|
+
before_write&.call
|
505
|
+
else
|
506
|
+
before_write&.call(edited_table_item)
|
507
|
+
end
|
488
508
|
model.send("#{model_editing_property}=", new_value) # makes table update itself, so must search for selected table item again
|
489
509
|
# Table refresh happens here because of model update triggering observers, so must retrieve table item again
|
490
510
|
edited_table_item = search { |ti| ti.getData == model }.first
|
491
511
|
swt_widget.showItem(edited_table_item)
|
492
512
|
@table_editor_widget_proxy&.swt_widget&.dispose
|
493
513
|
@table_editor_widget_proxy = nil
|
494
|
-
after_write&.
|
514
|
+
if after_write&.arity == 0
|
515
|
+
after_write&.call
|
516
|
+
else
|
517
|
+
after_write&.call(edited_table_item)
|
518
|
+
end
|
495
519
|
@edit_in_progress = false
|
496
520
|
end
|
497
521
|
end
|