glimmer-dsl-swt 4.18.2.3 → 4.18.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +59 -0
  3. data/README.md +267 -39
  4. data/VERSION +1 -1
  5. data/glimmer-dsl-swt.gemspec +14 -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/dsl.rb +1 -0
  11. data/lib/glimmer/dsl/swt/multiply_expression.rb +53 -0
  12. data/lib/glimmer/dsl/swt/property_expression.rb +4 -2
  13. data/lib/glimmer/dsl/swt/shape_expression.rb +2 -4
  14. data/lib/glimmer/dsl/swt/transform_expression.rb +55 -0
  15. data/lib/glimmer/dsl/swt/widget_expression.rb +2 -1
  16. data/lib/glimmer/swt/color_proxy.rb +28 -6
  17. data/lib/glimmer/swt/custom/drawable.rb +8 -0
  18. data/lib/glimmer/swt/custom/shape.rb +66 -26
  19. data/lib/glimmer/swt/directory_dialog_proxy.rb +3 -3
  20. data/lib/glimmer/swt/display_proxy.rb +25 -4
  21. data/lib/glimmer/swt/file_dialog_proxy.rb +3 -3
  22. data/lib/glimmer/swt/layout_data_proxy.rb +3 -3
  23. data/lib/glimmer/swt/shell_proxy.rb +20 -5
  24. data/lib/glimmer/swt/table_proxy.rb +19 -4
  25. data/lib/glimmer/swt/transform_proxy.rb +109 -0
  26. data/lib/glimmer/swt/widget_listener_proxy.rb +14 -5
  27. data/lib/glimmer/swt/widget_proxy.rb +31 -20
  28. data/lib/glimmer/ui/custom_shell.rb +13 -11
  29. data/lib/glimmer/ui/custom_widget.rb +68 -44
  30. data/samples/elaborate/meta_sample.rb +81 -24
  31. data/samples/elaborate/tetris.rb +102 -47
  32. data/samples/elaborate/tetris/model/block.rb +2 -2
  33. data/samples/elaborate/tetris/model/game.rb +236 -74
  34. data/samples/elaborate/tetris/model/past_game.rb +26 -0
  35. data/samples/elaborate/tetris/model/tetromino.rb +123 -35
  36. data/samples/elaborate/tetris/view/block.rb +34 -9
  37. data/samples/elaborate/tetris/view/high_score_dialog.rb +114 -0
  38. data/samples/elaborate/tetris/view/playfield.rb +12 -5
  39. data/samples/elaborate/tetris/view/score_lane.rb +87 -0
  40. data/samples/elaborate/tetris/view/tetris_menu_bar.rb +123 -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 +12 -4
@@ -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,8 +39,20 @@ 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
@@ -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,14 +109,20 @@ 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
+ alias nested nested?
121
+
122
+ def disposed?
123
+ swt_widget.isDisposed
111
124
  end
125
+ alias disposed disposed?
112
126
 
113
127
  def hide
114
128
  @swt_widget.setVisible(false)
@@ -117,6 +131,7 @@ module Glimmer
117
131
  def visible?
118
132
  @swt_widget.isDisposed ? false : @swt_widget.isVisible
119
133
  end
134
+ alias visible visible?
120
135
 
121
136
  # Setting to true opens/shows shell. Setting to false hides the shell.
122
137
  def visible=(visibility)
@@ -265,6 +265,10 @@ 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
@@ -445,7 +449,6 @@ module Glimmer
445
449
  end
446
450
 
447
451
  def edit_table_item(table_item, column_index, before_write: nil, after_write: nil, after_cancel: nil)
448
- require 'facets/hash/symbolize_keys'
449
452
  return if table_item.nil?
450
453
  model = table_item.data
451
454
  property = column_properties[column_index]
@@ -467,7 +470,11 @@ module Glimmer
467
470
  @cancel_in_progress = true
468
471
  @table_editor_widget_proxy&.swt_widget&.dispose
469
472
  @table_editor_widget_proxy = nil
470
- after_cancel&.call
473
+ if after_cancel&.arity == 0
474
+ after_cancel&.call
475
+ else
476
+ after_cancel&.call(table_item)
477
+ end
471
478
  @edit_in_progress = false
472
479
  @cancel_in_progress = false
473
480
  @cancel_edit = nil
@@ -484,14 +491,22 @@ module Glimmer
484
491
  if new_value == model.send(model_editing_property)
485
492
  @cancel_edit.call
486
493
  else
487
- before_write&.call
494
+ if before_write&.arity == 0
495
+ before_write&.call
496
+ else
497
+ before_write&.call(edited_table_item)
498
+ end
488
499
  model.send("#{model_editing_property}=", new_value) # makes table update itself, so must search for selected table item again
489
500
  # Table refresh happens here because of model update triggering observers, so must retrieve table item again
490
501
  edited_table_item = search { |ti| ti.getData == model }.first
491
502
  swt_widget.showItem(edited_table_item)
492
503
  @table_editor_widget_proxy&.swt_widget&.dispose
493
504
  @table_editor_widget_proxy = nil
494
- after_write&.call(edited_table_item)
505
+ if after_write&.arity == 0
506
+ after_write&.call
507
+ else
508
+ after_write&.call(edited_table_item)
509
+ end
495
510
  @edit_in_progress = false
496
511
  end
497
512
  end
@@ -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