glimmer-dsl-swt 4.18.2.2 → 4.18.3.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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +53 -0
  3. data/README.md +213 -32
  4. data/VERSION +1 -1
  5. data/glimmer-dsl-swt.gemspec +19 -6
  6. data/lib/ext/glimmer/config.rb +24 -7
  7. data/lib/glimmer/data_binding/widget_binding.rb +14 -4
  8. data/lib/glimmer/dsl/swt/color_expression.rb +4 -4
  9. data/lib/glimmer/dsl/swt/data_binding_expression.rb +3 -3
  10. data/lib/glimmer/dsl/swt/display_expression.rb +3 -3
  11. data/lib/glimmer/dsl/swt/dsl.rb +1 -0
  12. data/lib/glimmer/dsl/swt/multiply_expression.rb +53 -0
  13. data/lib/glimmer/dsl/swt/property_expression.rb +4 -2
  14. data/lib/glimmer/dsl/swt/shape_expression.rb +2 -4
  15. data/lib/glimmer/dsl/swt/transform_expression.rb +55 -0
  16. data/lib/glimmer/dsl/swt/widget_expression.rb +2 -1
  17. data/lib/glimmer/rake_task/scaffold.rb +4 -3
  18. data/lib/glimmer/swt/color_proxy.rb +28 -6
  19. data/lib/glimmer/swt/custom/drawable.rb +8 -0
  20. data/lib/glimmer/swt/custom/shape.rb +66 -26
  21. data/lib/glimmer/swt/directory_dialog_proxy.rb +3 -3
  22. data/lib/glimmer/swt/display_proxy.rb +26 -5
  23. data/lib/glimmer/swt/file_dialog_proxy.rb +3 -3
  24. data/lib/glimmer/swt/layout_data_proxy.rb +3 -3
  25. data/lib/glimmer/swt/shell_proxy.rb +17 -5
  26. data/lib/glimmer/swt/transform_proxy.rb +109 -0
  27. data/lib/glimmer/swt/widget_listener_proxy.rb +14 -5
  28. data/lib/glimmer/swt/widget_proxy.rb +35 -26
  29. data/lib/glimmer/ui/custom_shell.rb +17 -3
  30. data/lib/glimmer/ui/custom_widget.rb +66 -45
  31. data/samples/elaborate/meta_sample.rb +102 -24
  32. data/samples/elaborate/tetris.rb +137 -0
  33. data/samples/elaborate/tetris/model/block.rb +48 -0
  34. data/samples/elaborate/tetris/model/game.rb +226 -0
  35. data/samples/elaborate/tetris/model/tetromino.rb +316 -0
  36. data/samples/elaborate/tetris/view/block.rb +70 -0
  37. data/samples/elaborate/tetris/view/game_over_dialog.rb +68 -0
  38. data/samples/elaborate/tetris/view/playfield.rb +56 -0
  39. data/samples/elaborate/tetris/view/score_lane.rb +87 -0
  40. data/samples/elaborate/tetris/view/tetris_menu_bar.rb +72 -0
  41. data/samples/elaborate/tic_tac_toe.rb +4 -4
  42. data/samples/hello/hello_canvas_transform.rb +40 -0
  43. data/samples/hello/hello_link.rb +1 -1
  44. metadata +17 -4
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2007-2021 Andy Maleh
2
- #
2
+ #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining
4
4
  # a copy of this software and associated documentation files (the
5
5
  # "Software"), to deal in the Software without restriction, including
@@ -7,10 +7,10 @@
7
7
  # distribute, sublicense, and/or sell copies of the Software, and to
8
8
  # permit persons to whom the Software is furnished to do so, subject to
9
9
  # the following conditions:
10
- #
10
+ #
11
11
  # The above copyright notice and this permission notice shall be
12
12
  # included in all copies or substantial portions of the Software.
13
- #
13
+ #
14
14
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
15
  # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
16
  # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -28,9 +28,20 @@ module Glimmer
28
28
  #
29
29
  # Invoking `#swt_color` returns the SWT Color object wrapped by this proxy
30
30
  #
31
- # Follows the Proxy Design Pattern
31
+ # Follows the Proxy Design Pattern and Flyweight Design Pattern (caching memoization)
32
32
  class ColorProxy
33
33
  include_package 'org.eclipse.swt.graphics'
34
+
35
+ class << self
36
+ def flyweight(*args)
37
+ flyweight_color_proxies[args] ||= new(*args)
38
+ end
39
+
40
+ # Flyweight Design Pattern memoization cache. Can be cleared if memory is needed.
41
+ def flyweight_color_proxies
42
+ @flyweight_color_proxies ||= {}
43
+ end
44
+ end
34
45
 
35
46
  # Initializes a proxy for an SWT Color object
36
47
  #
@@ -49,6 +60,7 @@ module Glimmer
49
60
  #
50
61
  def initialize(*args)
51
62
  @args = args
63
+ ensure_arg_values_within_valid_bounds
52
64
  end
53
65
 
54
66
  def swt_color
@@ -64,7 +76,7 @@ module Glimmer
64
76
  end
65
77
  when 3..4
66
78
  red, green, blue, alpha = @args
67
- @swt_color = Color.new(DisplayProxy.instance.swt_display, *[red, green, blue, alpha].compact)
79
+ @swt_color = Color.new(*[red, green, blue, alpha].compact)
68
80
  end
69
81
  end
70
82
  @swt_color
@@ -79,7 +91,17 @@ module Glimmer
79
91
 
80
92
  def respond_to?(method, *args, &block)
81
93
  super || swt_color.respond_to?(method, *args, &block)
82
- end
94
+ end
95
+
96
+ private
97
+
98
+ def ensure_arg_values_within_valid_bounds
99
+ if @args.to_a.size >= 3
100
+ @args = @args.map do |value|
101
+ [[value, 255].min, 0].max
102
+ end
103
+ end
104
+ end
83
105
  end
84
106
  end
85
107
  end
@@ -34,6 +34,14 @@ module Glimmer
34
34
  shapes.delete(shape)
35
35
  end
36
36
  end
37
+
38
+ def resetup_shape_paint_listeners
39
+ # TODO consider performance optimization relating to order of shape rendering (affecting only further shapes not previous ones)
40
+ shapes.each do |shape|
41
+ shape.paint_listener_proxy&.unregister
42
+ shape.setup_paint_listener
43
+ end
44
+ end
37
45
  end
38
46
 
39
47
  end
@@ -24,6 +24,7 @@ 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
@@ -43,7 +44,17 @@ module Glimmer
43
44
  end
44
45
 
45
46
  def gc_instance_methods
46
- org.eclipse.swt.graphics.GC.instance_methods.map(&:to_s)
47
+ @gc_instance_methods ||= org.eclipse.swt.graphics.GC.instance_methods.map(&:to_s)
48
+ end
49
+
50
+ def keywords
51
+ @keywords ||= gc_instance_methods.select do |method_name|
52
+ !method_name.end_with?('=') && (method_name.start_with?('draw_') || method_name.start_with?('fill_'))
53
+ end.reject do |method_name|
54
+ gc_instance_methods.include?("#{method_name}=") || gc_instance_methods.include?("set_#{method_name}")
55
+ end.map do |method_name|
56
+ method_name.gsub(/(draw|fill|gradient|round)_/, '')
57
+ end.uniq.compact.to_a
47
58
  end
48
59
 
49
60
  def arg_options(args, extract: false)
@@ -53,11 +64,19 @@ module Glimmer
53
64
  end
54
65
 
55
66
  def method_name(keyword, args)
56
- keyword = keyword.to_s
57
- gradient = 'gradient_' if arg_options(args)[:gradient]
58
- round = 'round_' if arg_options(args)[:round]
59
- gc_instance_method_name_prefix = !['polyline', 'point', 'image', 'focus'].include?(keyword) && (arg_options(args)[:fill] || arg_options(args)[:gradient]) ? 'fill_' : 'draw_'
60
- "#{gc_instance_method_name_prefix}#{gradient}#{round}#{keyword}"
67
+ method_arg_options = arg_options(args)
68
+ unless flyweight_method_names.keys.include?([keyword, method_arg_options])
69
+ keyword = keyword.to_s
70
+ gradient = 'gradient_' if method_arg_options[:gradient]
71
+ round = 'round_' if method_arg_options[:round]
72
+ gc_instance_method_name_prefix = !['polyline', 'point', 'image', 'focus'].include?(keyword) && (method_arg_options[:fill] || method_arg_options[:gradient]) ? 'fill_' : 'draw_'
73
+ flyweight_method_names[[keyword, method_arg_options]] = "#{gc_instance_method_name_prefix}#{gradient}#{round}#{keyword}"
74
+ end
75
+ flyweight_method_names[[keyword, method_arg_options]]
76
+ end
77
+
78
+ def flyweight_method_names
79
+ @flyweight_method_names ||= {}
61
80
  end
62
81
  end
63
82
 
@@ -92,27 +111,12 @@ module Glimmer
92
111
  end
93
112
 
94
113
  def post_add_content
95
- event_handler = lambda do |event|
96
- @properties['background'] = [@parent.background] if fill? && !@properties.keys.map(&:to_s).include?('background')
97
- @properties['foreground'] = [@parent.foreground] if draw? && !@properties.keys.map(&:to_s).include?('foreground')
98
- @properties.each do |property, args|
99
- method_name = attribute_setter(property)
100
- apply_property_arg_conversions(method_name, args)
101
- event.gc.send(method_name, *args)
102
- end
103
- apply_shape_arg_conversions(@method_name, @args)
104
- apply_shape_arg_defaults(@method_name, @args)
105
- tolerate_shape_extra_args(@method_name, @args)
106
- event.gc.send(@method_name, *@args)
107
- end
108
- if parent.respond_to?(:swt_display)
109
- @paint_listener_proxy = @parent.on_swt_paint(&event_handler)
110
- else
111
- @paint_listener_proxy = @parent.on_paint_control(&event_handler)
112
- end
114
+ setup_paint_listener
115
+ @content_added = true
113
116
  end
114
117
 
115
- def apply_property_arg_conversions(method_name, args)
118
+ def apply_property_arg_conversions(method_name, property, args)
119
+ args = args.dup
116
120
  the_java_method = org.eclipse.swt.graphics.GC.java_class.declared_instance_methods.detect {|m| m.name == method_name}
117
121
  if (args.first.is_a?(Symbol) || args.first.is_a?(String))
118
122
  if the_java_method.parameter_types.first == Color.java_class
@@ -131,6 +135,9 @@ module Glimmer
131
135
  if args.first.is_a?(FontProxy)
132
136
  args[0] = args[0].swt_font
133
137
  end
138
+ if args.first.is_a?(TransformProxy)
139
+ args[0] = args[0].swt_transform
140
+ end
134
141
  if ['setBackgroundPattern', 'setForegroundPattern'].include?(method_name.to_s)
135
142
  args.each_with_index do |arg, i|
136
143
  if arg.is_a?(Symbol) || arg.is_a?(String)
@@ -143,6 +150,7 @@ module Glimmer
143
150
  args[0] = org.eclipse.swt.graphics.Pattern.new(*new_args)
144
151
  args[1..-1] = []
145
152
  end
153
+ args
146
154
  end
147
155
 
148
156
  def apply_shape_arg_conversions(method_name, args)
@@ -185,11 +193,43 @@ module Glimmer
185
193
 
186
194
  def set_attribute(attribute_name, *args)
187
195
  @properties[attribute_name] = args
196
+ if @content_added && !@parent.is_disposed
197
+ @parent.resetup_shape_paint_listeners
198
+ @parent.redraw
199
+ end
188
200
  end
189
-
201
+
190
202
  def get_attribute(attribute_name)
191
203
  @properties.symbolize_keys[attribute_name.to_s.to_sym]
192
204
  end
205
+
206
+ def setup_paint_listener
207
+ return if @parent.is_disposed
208
+ if parent.respond_to?(:swt_display)
209
+ @paint_listener_proxy = @parent.on_swt_paint(&method(:paint))
210
+ elsif parent.respond_to?(:swt_widget)
211
+ @paint_listener_proxy = @parent.on_paint_control(&method(:paint))
212
+ end
213
+ end
214
+
215
+ def paint(paint_event)
216
+ @properties['background'] = [@parent.background] if fill? && !@properties.keys.map(&:to_s).include?('background')
217
+ @properties['foreground'] = [@parent.foreground] if draw? && !@properties.keys.map(&:to_s).include?('foreground')
218
+ @properties['font'] = [@parent.font] if draw? && !@properties.keys.map(&:to_s).include?('font')
219
+ @properties['transform'] = [nil] if !@properties.keys.map(&:to_s).include?('transform')
220
+ @properties.each do |property, args|
221
+ method_name = attribute_setter(property)
222
+ converted_args = apply_property_arg_conversions(method_name, property, args)
223
+ paint_event.gc.send(method_name, *converted_args)
224
+ if property == 'transform' && args.first.is_a?(TransformProxy)
225
+ args.first.swt_transform.dispose
226
+ end
227
+ end
228
+ apply_shape_arg_conversions(@method_name, @args)
229
+ apply_shape_arg_defaults(@method_name, @args)
230
+ tolerate_shape_extra_args(@method_name, @args)
231
+ paint_event.gc.send(@method_name, *@args)
232
+ end
193
233
 
194
234
  end
195
235
 
@@ -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,13 +39,25 @@ module Glimmer
39
39
  include_package 'org.eclipse.swt.widgets'
40
40
 
41
41
  include Custom::Drawable
42
-
42
+
43
43
  OBSERVED_MENU_ITEMS = ['about', 'preferences']
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
47
59
  def instance(*args)
48
- if @instance.nil? || @instance.swt_display.isDisposed
60
+ if @instance.nil? || @instance.swt_display.nil? || @instance.swt_display.isDisposed
49
61
  @instance = new(*args)
50
62
  end
51
63
  @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
- add_swt_event_listener(constant_name, &block)
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 add_swt_event_listener(swt_constant, &block)
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)
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2007-2021 Andy Maleh
2
- #
2
+ #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining
4
4
  # a copy of this software and associated documentation files (the
5
5
  # "Software"), to deal in the Software without restriction, including
@@ -7,10 +7,10 @@
7
7
  # distribute, sublicense, and/or sell copies of the Software, and to
8
8
  # permit persons to whom the Software is furnished to do so, subject to
9
9
  # the following conditions:
10
- #
10
+ #
11
11
  # The above copyright notice and this permission notice shall be
12
12
  # included in all copies or substantial portions of the Software.
13
- #
13
+ #
14
14
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
15
  # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
16
  # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -45,10 +45,17 @@ module Glimmer
45
45
  if swt_widget
46
46
  @swt_widget = swt_widget
47
47
  else
48
- if args.first.is_a?(ShellProxy)
48
+ if args.first.respond_to?(:swt_widget) && args.first.swt_widget.is_a?(Shell)
49
+ @parent_proxy = args[0]
49
50
  args[0] = args[0].swt_widget
50
51
  end
51
- 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
52
59
  if style_args.any?
53
60
  style_arg_start_index = args.index(style_args.first)
54
61
  style_arg_last_index = args.index(style_args.last)
@@ -66,6 +73,7 @@ module Glimmer
66
73
  # TODO make this an option not the default
67
74
  shell_swt_display = Glimmer::SWT::DisplayProxy.instance.swt_display
68
75
  on_swt_show do
76
+ @swt_widget.set_size(@display.bounds.width, @display.bounds.height) if fill_screen
69
77
  Thread.new do
70
78
  sleep(0.25)
71
79
  shell_swt_display.async_exec do
@@ -78,7 +86,7 @@ module Glimmer
78
86
  end
79
87
 
80
88
  # Centers shell within monitor it is in
81
- def center
89
+ def center_within_display
82
90
  primary_monitor = @display.getPrimaryMonitor()
83
91
  monitor_bounds = primary_monitor.getBounds()
84
92
  shell_bounds = @swt_widget.getBounds()
@@ -101,13 +109,17 @@ module Glimmer
101
109
  else
102
110
  @opened_before = true
103
111
  @swt_widget.pack
104
- center
112
+ center_within_display
105
113
  @swt_widget.open
106
114
  end
107
115
  end
108
116
 
109
117
  def nested?
110
- !parent.nil?
118
+ !swt_widget&.parent.nil?
119
+ end
120
+
121
+ def disposed?
122
+ swt_widget.isDisposed
111
123
  end
112
124
 
113
125
  def hide
@@ -0,0 +1,109 @@
1
+ # Copyright (c) 2007-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
+ require 'glimmer/swt/display_proxy'
23
+ require 'glimmer/swt/properties'
24
+ require 'glimmer/swt/custom/shape'
25
+
26
+ module Glimmer
27
+ module SWT
28
+ # Proxy for org.eclipse.swt.graphics.Transform
29
+ #
30
+ # Follows the Proxy Design Pattern
31
+ class TransformProxy
32
+ include Properties
33
+
34
+ include_package 'org.eclipse.swt.graphics'
35
+ include_package 'org.eclipse.swt.widgets'
36
+
37
+ attr_reader :swt_transform, :parent
38
+
39
+ def initialize(parent, *args, swt_transform: nil, multiply: false)
40
+ @parent = parent
41
+ @multiply = multiply
42
+ if swt_transform.nil?
43
+ if !args.first.is_a?(Display) && !args.first.is_a?(DisplayProxy)
44
+ args.prepend DisplayProxy.instance.swt_display
45
+ end
46
+ if args.first.is_a?(DisplayProxy)
47
+ args[0] = args[0].swt_display
48
+ end
49
+ if args.last.is_a?(TransformProxy)
50
+ args[-1] = args[-1].swt_transform
51
+ end
52
+ if args.last.nil? || args.last.is_a?(Transform)
53
+ @swt_transform = args.last
54
+ @parent&.set_attribute('transform', self)
55
+ else
56
+ @swt_transform = Transform.new(*args)
57
+ end
58
+ else
59
+ @swt_transform = swt_transform
60
+ end
61
+ end
62
+
63
+ def post_add_content
64
+ if @multiply
65
+ @parent.multiply(@swt_transform)
66
+ else
67
+ @parent&.set_attribute('transform', self)
68
+ end
69
+ end
70
+
71
+ def content(&block)
72
+ Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::SWT::TransformExpression.new, &block)
73
+ end
74
+
75
+ def has_attribute?(attribute_name, *args)
76
+ @swt_transform.respond_to?(attribute_name) || @swt_transform.respond_to?(attribute_setter(attribute_name))
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
93
+ end
94
+
95
+ def method_missing(method_name, *args, &block)
96
+ result = @swt_transform.send(method_name, *args, &block)
97
+ result.nil? ? self : result
98
+ rescue => e
99
+ Glimmer::Config.logger.debug {"Neither MessageBoxProxy nor #{@swt_transform.class.name} can handle the method ##{method}"}
100
+ super
101
+ end
102
+
103
+ def respond_to?(method, *args, &block)
104
+ super ||
105
+ @swt_transform.respond_to?(method, *args, &block)
106
+ end
107
+ end
108
+ end
109
+ end