glimmer 0.4.9 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/README.markdown +324 -59
  3. data/lib/glimmer.rb +54 -63
  4. data/lib/glimmer/data_binding/list_selection_binding.rb +52 -0
  5. data/lib/glimmer/{swt → data_binding}/model_binding.rb +33 -5
  6. data/lib/glimmer/{swt → data_binding}/observable.rb +6 -3
  7. data/lib/glimmer/{swt → data_binding}/observable_array.rb +3 -1
  8. data/lib/glimmer/{swt → data_binding}/observable_model.rb +3 -2
  9. data/lib/glimmer/data_binding/observable_widget.rb +17 -0
  10. data/lib/glimmer/{swt → data_binding}/observer.rb +3 -3
  11. data/lib/glimmer/{shine.rb → data_binding/shine.rb} +2 -2
  12. data/lib/glimmer/{swt → data_binding}/table_items_binding.rb +12 -11
  13. data/lib/glimmer/{swt → data_binding}/tree_items_binding.rb +15 -12
  14. data/lib/glimmer/{swt → data_binding}/widget_binding.rb +2 -1
  15. data/lib/glimmer/dsl.rb +26 -0
  16. data/lib/glimmer/dsl/async_exec_expression.rb +12 -0
  17. data/lib/glimmer/dsl/bind_expression.rb +44 -0
  18. data/lib/glimmer/dsl/color_expression.rb +28 -0
  19. data/lib/glimmer/dsl/column_properties_expression.rb +22 -0
  20. data/lib/glimmer/dsl/combo_selection_data_binding_expression.rb +40 -0
  21. data/lib/glimmer/dsl/custom_widget_expression.rb +35 -0
  22. data/lib/glimmer/dsl/data_binding_expression.rb +33 -0
  23. data/lib/glimmer/dsl/display_expression.rb +12 -0
  24. data/lib/glimmer/dsl/engine.rb +80 -0
  25. data/lib/glimmer/dsl/exec_expression.rb +23 -0
  26. data/lib/glimmer/dsl/expression.rb +44 -0
  27. data/lib/glimmer/dsl/expression_handler.rb +48 -0
  28. data/lib/glimmer/dsl/layout_data_expression.rb +24 -0
  29. data/lib/glimmer/dsl/layout_expression.rb +26 -0
  30. data/lib/glimmer/dsl/list_selection_data_binding_expression.rb +42 -0
  31. data/lib/glimmer/dsl/observe_expression.rb +27 -0
  32. data/lib/glimmer/dsl/parent_expression.rb +12 -0
  33. data/lib/glimmer/dsl/property_expression.rb +20 -0
  34. data/lib/glimmer/dsl/shell_expression.rb +15 -0
  35. data/lib/glimmer/dsl/static_expression.rb +38 -0
  36. data/lib/glimmer/dsl/swt_expression.rb +23 -0
  37. data/lib/glimmer/dsl/sync_exec_expression.rb +13 -0
  38. data/lib/glimmer/dsl/tab_item_expression.rb +31 -0
  39. data/lib/glimmer/dsl/table_items_data_binding_expression.rb +29 -0
  40. data/lib/glimmer/dsl/tree_items_data_binding_expression.rb +30 -0
  41. data/lib/glimmer/dsl/tree_properties_expression.rb +24 -0
  42. data/lib/glimmer/dsl/widget_expression.rb +26 -0
  43. data/lib/glimmer/dsl/widget_listener_expression.rb +27 -0
  44. data/lib/glimmer/error.rb +6 -0
  45. data/lib/glimmer/invalid_keyword_error.rb +6 -0
  46. data/lib/glimmer/launcher.rb +39 -23
  47. data/lib/glimmer/swt/color_proxy.rb +48 -0
  48. data/lib/glimmer/swt/display_proxy.rb +49 -0
  49. data/lib/glimmer/swt/font_proxy.rb +72 -0
  50. data/lib/glimmer/swt/layout_data_proxy.rb +73 -0
  51. data/lib/glimmer/swt/{g_layout.rb → layout_proxy.rb} +24 -25
  52. data/lib/glimmer/swt/packages.rb +13 -0
  53. data/lib/glimmer/swt/shell_proxy.rb +108 -0
  54. data/lib/glimmer/swt/{g_swt.rb → swt_proxy.rb} +12 -5
  55. data/lib/glimmer/swt/tab_item_proxy.rb +59 -0
  56. data/lib/glimmer/swt/widget_listener_proxy.rb +17 -0
  57. data/lib/glimmer/swt/widget_proxy.rb +366 -0
  58. data/lib/glimmer/{swt → ui}/custom_shell.rb +4 -4
  59. data/lib/glimmer/{swt → ui}/custom_widget.rb +67 -51
  60. data/lib/glimmer/{swt → ui}/video.rb +13 -13
  61. data/lib/glimmer/{swt → util}/proc_tracker.rb +1 -1
  62. data/vendor/swt/linux/swt.jar +0 -0
  63. data/vendor/swt/mac/swt.jar +0 -0
  64. data/vendor/swt/windows/swt.jar +0 -0
  65. metadata +66 -70
  66. data/lib/glimmer/command_handler.rb +0 -15
  67. data/lib/glimmer/command_handler_chain_factory.rb +0 -32
  68. data/lib/glimmer/command_handler_chain_link.rb +0 -25
  69. data/lib/glimmer/command_handlers.rb +0 -46
  70. data/lib/glimmer/ext/module.rb +0 -20
  71. data/lib/glimmer/parent.rb +0 -7
  72. data/lib/glimmer/swt/command_handlers/bind_command_handler.rb +0 -56
  73. data/lib/glimmer/swt/command_handlers/color_command_handler.rb +0 -30
  74. data/lib/glimmer/swt/command_handlers/combo_selection_data_binding_command_handler.rb +0 -44
  75. data/lib/glimmer/swt/command_handlers/custom_widget_command_handler.rb +0 -26
  76. data/lib/glimmer/swt/command_handlers/data_binding_command_handler.rb +0 -40
  77. data/lib/glimmer/swt/command_handlers/display_command_handler.rb +0 -20
  78. data/lib/glimmer/swt/command_handlers/layout_command_handler.rb +0 -27
  79. data/lib/glimmer/swt/command_handlers/layout_data_command_handler.rb +0 -27
  80. data/lib/glimmer/swt/command_handlers/list_selection_data_binding_command_handler.rb +0 -49
  81. data/lib/glimmer/swt/command_handlers/observe_command_handler.rb +0 -35
  82. data/lib/glimmer/swt/command_handlers/property_command_handler.rb +0 -24
  83. data/lib/glimmer/swt/command_handlers/shell_command_handler.rb +0 -20
  84. data/lib/glimmer/swt/command_handlers/tab_item_command_handler.rb +0 -34
  85. data/lib/glimmer/swt/command_handlers/table_column_properties_data_binding_command_handler.rb +0 -29
  86. data/lib/glimmer/swt/command_handlers/table_items_data_binding_command_handler.rb +0 -34
  87. data/lib/glimmer/swt/command_handlers/tree_items_data_binding_command_handler.rb +0 -33
  88. data/lib/glimmer/swt/command_handlers/tree_properties_data_binding_command_handler.rb +0 -29
  89. data/lib/glimmer/swt/command_handlers/widget_command_handler.rb +0 -27
  90. data/lib/glimmer/swt/command_handlers/widget_listener_command_handler.rb +0 -48
  91. data/lib/glimmer/swt/g_color.rb +0 -41
  92. data/lib/glimmer/swt/g_display.rb +0 -36
  93. data/lib/glimmer/swt/g_font.rb +0 -71
  94. data/lib/glimmer/swt/g_layout_data.rb +0 -56
  95. data/lib/glimmer/swt/g_runnable.rb +0 -15
  96. data/lib/glimmer/swt/g_shell.rb +0 -106
  97. data/lib/glimmer/swt/g_tab_item_composite.rb +0 -41
  98. data/lib/glimmer/swt/g_widget.rb +0 -349
  99. data/lib/glimmer/swt/g_widget_listener.rb +0 -12
  100. data/lib/glimmer/swt/list_selection_binding.rb +0 -47
  101. data/lib/glimmer/swt_packages.rb +0 -15
  102. data/lib/glimmer/xml/command_handlers/html_command_handler.rb +0 -50
  103. data/lib/glimmer/xml/command_handlers/xml_command_handler.rb +0 -23
  104. data/lib/glimmer/xml/command_handlers/xml_name_space_command_handler.rb +0 -36
  105. data/lib/glimmer/xml/command_handlers/xml_tag_command_handler.rb +0 -28
  106. data/lib/glimmer/xml/command_handlers/xml_text_command_handler.rb +0 -24
  107. data/lib/glimmer/xml/depth_first_search_iterator.rb +0 -20
  108. data/lib/glimmer/xml/name_space_visitor.rb +0 -21
  109. data/lib/glimmer/xml/node.rb +0 -84
  110. data/lib/glimmer/xml/node_visitor.rb +0 -13
  111. data/lib/glimmer/xml/xml_visitor.rb +0 -63
  112. data/lib/glimmer/xml_command_handlers.rb +0 -18
@@ -1,56 +0,0 @@
1
- require_relative '../parent'
2
- require_relative 'g_swt'
3
-
4
- module Glimmer
5
- module SWT
6
- class GLayoutData
7
- include_package 'org.eclipse.swt.layout'
8
-
9
- include Parent
10
-
11
- attr_reader :widget
12
- attr_reader :layout_data
13
-
14
- def initialize(widget, args)
15
- @widget = widget
16
- args = GSWT.constantify_args(args)
17
- begin
18
- @layout_data = swt_layout_data_class.new(*args)
19
- rescue => e
20
- Glimmer.logger.debug "#{e.message}\n#{e.backtrace.join("\n")}"
21
- @layout_data = args.first if args.count == 1
22
- end
23
- @widget.setLayoutData(@layout_data)
24
- end
25
-
26
- def process_block(block)
27
- block.call(self)
28
- end
29
-
30
- def swt_layout_data_class
31
- parent_layout_class_name = @widget.getParent.getLayout.class.name
32
- layout_data_class_name = parent_layout_class_name.sub(/Layout$/, 'Data')
33
- eval(layout_data_class_name)
34
- end
35
-
36
- def has_attribute?(attribute_name, *args)
37
- @layout_data.respond_to?(attribute_setter(attribute_name), args)
38
- end
39
-
40
- def set_attribute(attribute_name, *args)
41
- apply_property_type_converters(attribute_name, args)
42
- @layout_data.send(attribute_setter(attribute_name), *args)
43
- end
44
-
45
- def apply_property_type_converters(attribute_name, args)
46
- if args.count == 1 && GSWT.has_constant?(args.first)
47
- args[0] = GSWT.constant(args.first)
48
- end
49
- end
50
-
51
- def attribute_setter(attribute_name)
52
- "#{attribute_name.to_s.camelcase(:lower)}="
53
- end
54
- end
55
- end
56
- end
@@ -1,15 +0,0 @@
1
- module Glimmer
2
- module SWT
3
- class GRunnable
4
- include java.lang.Runnable
5
-
6
- def initialize(&block)
7
- @block = block
8
- end
9
-
10
- def run
11
- @block.call
12
- end
13
- end
14
- end
15
- end
@@ -1,106 +0,0 @@
1
- require_relative 'g_widget'
2
- require_relative 'g_display'
3
-
4
- module Glimmer
5
- module SWT
6
- class GShell < GWidget
7
- WIDTH_MIN = 130
8
- HEIGHT_MIN = 0
9
-
10
- include_package 'org.eclipse.swt.layout'
11
- include_package 'org.eclipse.swt.widgets'
12
-
13
- attr_reader :display, :opened_before
14
- alias opened_before? opened_before
15
-
16
- # Instantiates shell with same arguments expected by SWT Shell
17
- def initialize(*args)
18
- if !args.first.is_a?(Display) && !args.first.is_a?(Shell)
19
- @display = GDisplay.instance.display
20
- args = [@display] + args
21
- end
22
- args = GSWT.constantify_args(args)
23
- @widget = Shell.new(*args)
24
- @display ||= @widget.getDisplay
25
- @widget.setLayout(FillLayout.new)
26
- @widget.setMinimumSize(WIDTH_MIN, HEIGHT_MIN)
27
- end
28
-
29
- # Centers shell within screen
30
- def center
31
- primary_monitor = @display.getPrimaryMonitor()
32
- monitor_bounds = primary_monitor.getBounds()
33
- shell_bounds = @widget.getBounds()
34
- location_x = monitor_bounds.x + (monitor_bounds.width - shell_bounds.width) / 2
35
- location_y = monitor_bounds.y + (monitor_bounds.height - shell_bounds.height) / 2
36
- @widget.setLocation(location_x, location_y)
37
- end
38
-
39
- # Opens shell and starts SWT's UI thread event loop
40
- def open
41
- if @opened_before
42
- @widget.setVisible(true)
43
- # notify_observers('visible')
44
- else
45
- @opened_before = true
46
- @widget.pack
47
- center
48
- @widget.open
49
- # NOTE: the following line runs after scheduled sync exec events,
50
- # but ensures visible status is only updated upon true visibility
51
- # async_exec do
52
- # notify_observers('visible')
53
- # end
54
- start_event_loop
55
- end
56
- end
57
- alias show open
58
-
59
- def hide
60
- @widget.setVisible(false)
61
- # notify_observers('visible')
62
- end
63
-
64
- def close
65
- @widget.close
66
- # notify_observers('visible')
67
- end
68
-
69
- # TODO implement and notify_observers('visible') based on open and hide
70
-
71
- def visible?
72
- @widget.isDisposed ? false : @widget.isVisible
73
- end
74
-
75
- # TODO evaluate if this is needed
76
-
77
- def visible=(visibility)
78
- visibility ? show : hide
79
- end
80
-
81
- def start_event_loop
82
- until @widget.isDisposed
83
- @display.sleep unless @display.readAndDispatch
84
- end
85
- @display.dispose
86
- end
87
-
88
- def add_observer(observer, property_name)
89
- case property_name.to_s
90
- when 'visible?'
91
- @widget.addListener(GSWT[:show]) do |event|
92
- observer.call(visible?)
93
- end
94
- @widget.addListener(GSWT[:hide]) do |event|
95
- observer.call(visible?)
96
- end
97
- @widget.addListener(GSWT[:close]) do |event|
98
- observer.call(visible?)
99
- end
100
- else
101
- super
102
- end
103
- end
104
- end
105
- end
106
- end
@@ -1,41 +0,0 @@
1
- require File.dirname(__FILE__) + "/g_runnable"
2
-
3
- module Glimmer
4
- module SWT
5
- class GTabItemComposite < GWidget
6
- include_package 'org.eclipse.swt.widgets'
7
-
8
- attr_reader :tab_item
9
- def initialize(tab_item, parent, style, &contents)
10
- super("composite", parent, style, &contents)
11
- @tab_item = tab_item
12
- @tab_item.widget.control = self.widget
13
- end
14
-
15
- def has_attribute?(attribute_name, *args)
16
- if attribute_name.to_s == "text"
17
- true
18
- else
19
- super(attribute_name, *args)
20
- end
21
- end
22
-
23
- def set_attribute(attribute_name, *args)
24
- if attribute_name.to_s == "text"
25
- text_value = args[0]
26
- @tab_item.widget.text = text_value
27
- else
28
- super(attribute_name, *args)
29
- end
30
- end
31
-
32
- def get_attribute(attribute_name)
33
- if attribute_name.to_s == "text"
34
- @tab_item.widget.text
35
- else
36
- super(attribute_name)
37
- end
38
- end
39
- end
40
- end
41
- end
@@ -1,349 +0,0 @@
1
- require_relative 'g_widget_listener'
2
- require_relative 'g_runnable'
3
- require_relative 'g_color'
4
- require_relative 'g_font'
5
- require_relative 'g_swt'
6
- require_relative '../parent'
7
-
8
- module Glimmer
9
- module SWT
10
- class GWidget
11
- include_package 'org.eclipse.swt'
12
- include_package 'org.eclipse.swt.widgets'
13
- include_package 'org.eclipse.swt.layout'
14
- include_package 'org.eclipse.swt.graphics'
15
- include_package 'org.eclipse.swt.browser'
16
-
17
- include Glimmer # TODO consider removing when no longer needed
18
- include Parent
19
-
20
- attr_reader :widget
21
-
22
- #TODO externalize
23
- @@default_styles = {
24
- "text" => GSWT[:border],
25
- "table" => GSWT[:border],
26
- "spinner" => GSWT[:border],
27
- "list" => GSWT[:border, :v_scroll],
28
- "button" => GSWT[:push],
29
- }
30
-
31
- #TODO externalize
32
- @@default_initializers = {
33
- "composite" => Proc.new {|composite| composite.setLayout(GridLayout.new) },
34
- "table" => Proc.new do |table|
35
- table.setHeaderVisible(true)
36
- table.setLinesVisible(true)
37
- end,
38
- "table_column" => Proc.new { |table_column| table_column.setWidth(80) },
39
- "group" => Proc.new {|group| group.setLayout(GridLayout.new) },
40
- }
41
-
42
- #styles is a comma separate list of symbols representing SWT styles in lower case
43
- def initialize(underscored_widget_name, parent, styles, &contents)
44
- @widget = self.class.swt_widget_class_for(underscored_widget_name).new(parent, style(underscored_widget_name, styles))
45
- @@default_initializers[underscored_widget_name].call(@widget) if @@default_initializers[underscored_widget_name]
46
- end
47
-
48
- def widget_custom_attribute_mapping
49
- @widget_custom_attribute_mapping ||= {
50
- 'focus' => {
51
- getter: {name: 'isFocusControl'},
52
- setter: {name: 'setFocus', invoker: lambda { |widget, args| widget.setFocus if args.first }},
53
- }
54
- }
55
- end
56
-
57
- def has_attribute?(attribute_name, *args)
58
- widget_custom_attribute = widget_custom_attribute_mapping[attribute_name.to_s]
59
- if widget_custom_attribute
60
- @widget.respond_to?(widget_custom_attribute[:setter][:name])
61
- else
62
- @widget.respond_to?(attribute_setter(attribute_name), args)
63
- end
64
- end
65
-
66
- def set_attribute(attribute_name, *args)
67
- widget_custom_attribute = widget_custom_attribute_mapping[attribute_name.to_s]
68
- if widget_custom_attribute
69
- widget_custom_attribute[:setter][:invoker].call(@widget, args)
70
- else
71
- apply_property_type_converters(attribute_name, args)
72
- @widget.send(attribute_setter(attribute_name), *args)
73
- end
74
- end
75
-
76
- def get_attribute(attribute_name)
77
- widget_custom_attribute = widget_custom_attribute_mapping[attribute_name.to_s]
78
- if widget_custom_attribute
79
- @widget.send(widget_custom_attribute[:getter][:name])
80
- else
81
- @widget.send(attribute_getter(attribute_name))
82
- end
83
- end
84
-
85
- def property_type_converters
86
- color_converter = Proc.new do |value|
87
- if value.is_a?(Symbol) || value.is_a?(String)
88
- GColor.color_for(widget.getDisplay, value)
89
- else
90
- value
91
- end
92
- end
93
- @property_type_converters ||= {
94
- :text => Proc.new { |value| value.to_s },
95
- :items => Proc.new { |value| value.to_java :string},
96
- :visible => Proc.new { |value| !!value},
97
- :background => color_converter,
98
- :background_image => Proc.new do |value|
99
- if value.is_a?(String)
100
- image_data = ImageData.new(value)
101
- # TODO in the future, look into unregistering this listener when no longer needed
102
- on_event_Resize do |resize_event|
103
- new_image_data = image_data.scaledTo(widget.getSize.x, widget.getSize.y)
104
- widget.getBackgroundImage&.dispose
105
- widget.setBackgroundImage(Image.new(widget.getDisplay, new_image_data))
106
- end
107
- Image.new(widget.getDisplay, image_data)
108
- else
109
- value
110
- end
111
- end,
112
- :foreground => color_converter,
113
- :font => Proc.new do |value|
114
- if value.is_a?(Hash)
115
- font_properties = value
116
- GFont.for(self).font(font_properties)
117
- else
118
- value
119
- end
120
- end,
121
- }
122
- end
123
-
124
- def widget_property_listener_installers
125
- @widget_property_listener_installers ||= {
126
- Java::OrgEclipseSwtWidgets::Control => {
127
- :focus => Proc.new do |observer|
128
- add_contents(self) {
129
- on_focus_gained { |focus_event|
130
- observer.call(true)
131
- }
132
- on_focus_lost { |focus_event|
133
- observer.call(false)
134
- }
135
- }
136
- end,
137
- },
138
- Java::OrgEclipseSwtWidgets::Text => {
139
- :text => Proc.new do |observer|
140
- add_contents(self) {
141
- on_modify_text { |modify_event|
142
- observer.call(widget.getText)
143
- }
144
- }
145
- end,
146
- },
147
- Java::OrgEclipseSwtWidgets::Button => {
148
- :selection => Proc.new do |observer|
149
- add_contents(self) {
150
- on_widget_selected { |selection_event|
151
- observer.call(widget.getSelection)
152
- }
153
- }
154
- end
155
- },
156
- Java::OrgEclipseSwtWidgets::Spinner => {
157
- :selection => Proc.new do |observer|
158
- add_contents(self) {
159
- on_widget_selected { |selection_event|
160
- observer.call(widget.getSelection)
161
- }
162
- }
163
- end
164
- }
165
- }
166
- end
167
-
168
- def apply_property_type_converters(attribute_name, args)
169
- if args.count == 1
170
- value = args.first
171
- converter = property_type_converters[attribute_name.to_sym]
172
- args[0] = converter.call(value) if converter
173
- end
174
- if args.count == 1 && args.first.is_a?(GColor)
175
- g_color = args.first
176
- g_color.display = widget.display if g_color.display.nil? || g_color.display != widget.display
177
- args[0] = g_color.color
178
- end
179
- end
180
-
181
- def self.widget_exists?(underscored_widget_name)
182
- !!swt_widget_class_for(underscored_widget_name)
183
- end
184
-
185
- # This supports widgets in and out of basic SWT
186
- def self.swt_widget_class_for(underscored_widget_name)
187
- swt_widget_name = underscored_widget_name.camelcase(:upper)
188
- swt_widget_class = eval(swt_widget_name)
189
- unless swt_widget_class.ancestors.include?(org.eclipse.swt.widgets.Widget)
190
- Glimmer.logger.debug("Class #{swt_widget_class} matching #{underscored_widget_name} is not a subclass of org.eclipse.swt.widgets.Widget")
191
- return nil
192
- end
193
- swt_widget_class
194
- rescue NameError => e
195
- Glimmer.logger.debug("#{e.message}\n#{e.backtrace.join("\n")}")
196
- nil
197
- rescue => e
198
- Glimmer.logger.debug("#{e.message}\n#{e.backtrace.join("\n")}")
199
- nil
200
- end
201
-
202
- # TODO refactor following methods to eliminate duplication
203
- # perhaps consider relying on raising an exception to avoid checking first
204
- # unless that gives obscure SWT errors
205
- # Otherwise, consider caching results from can_add_lsitener and using them in
206
- # add_listener knowing it will be called for sure afterwards
207
-
208
- def can_add_listener?(underscored_listener_name)
209
- listener_method_name = underscored_listener_name.camelcase(:lower)
210
- @widget.getClass.getMethods.each do |widget_method|
211
- if widget_method.getName.match(/add.*Listener/)
212
- widget_method.getParameterTypes.each do |listener_type|
213
- listener_type.getMethods.each do |listener_method|
214
- if (listener_method.getName == listener_method_name)
215
- return true
216
- end
217
- end
218
- end
219
- end
220
- end
221
- return false
222
- end
223
-
224
- def add_listener(underscored_listener_name, &block)
225
- listener_method_name = underscored_listener_name.camelcase(:lower)
226
- @widget.getClass.getMethods.each do |widget_method|
227
- if widget_method.getName.match(/add.*Listener/)
228
- widget_method.getParameterTypes.each do |listener_type|
229
- listener_type.getMethods.each do |listener_method|
230
- if (listener_method.getName == listener_method_name)
231
- listener_class = Class.new(Object)
232
- listener_class.send :include, (eval listener_type.to_s.sub("interface", ""))
233
- listener = listener_class.new
234
- listener_type.getMethods.each do |t_method|
235
- eval "def listener.#{t_method.getName}(event) end"
236
- end
237
- def listener.block=(block)
238
- @block = block
239
- end
240
- listener.block=block
241
- eval "def listener.#{listener_method.getName}(event) @block.call(event) if @block end"
242
- @widget.send(widget_method.getName, listener)
243
- return GWidgetListener.new(listener)
244
- end
245
- end
246
- end
247
- end
248
- end
249
- end
250
-
251
- def process_block(block)
252
- block.call(self)
253
- end
254
-
255
- def async_exec(&block)
256
- GDisplay.instance.async_exec(&block)
257
- end
258
-
259
- def sync_exec(&block)
260
- GDisplay.instance.sync_exec(&block)
261
- end
262
-
263
- def has_style?(style)
264
- (widget.style & GSWT[style]) == GSWT[style]
265
- end
266
-
267
- def dispose
268
- @widget.dispose
269
- end
270
-
271
- # TODO Consider renaming these methods as they are mainly used for data-binding
272
-
273
- def can_add_observer?(property_name)
274
- @widget.class.ancestors.map {|ancestor| widget_property_listener_installers[ancestor]}.compact.map(&:keys).flatten.map(&:to_s).include?(property_name.to_s)
275
- end
276
-
277
- def add_observer(observer, property_name)
278
- property_listener_installers = @widget.class.ancestors.map {|ancestor| widget_property_listener_installers[ancestor]}.compact
279
- widget_listener_installers = property_listener_installers.map{|installer| installer[property_name.to_s.to_sym]}.compact if !property_listener_installers.empty?
280
- widget_listener_installers.each do |widget_listener_installer|
281
- widget_listener_installer.call(observer)
282
- end
283
- end
284
-
285
- def remove_observer(observer, property_name)
286
- # TODO consider implementing if remove_observer is needed (consumers can remove listener via SWT API)
287
- end
288
-
289
- # TODO eliminate duplication in the following methods perhaps by relying on exceptions
290
-
291
- def can_handle_observation_request?(observation_request)
292
- observation_request = observation_request.to_s
293
- if observation_request.start_with?('on_event_')
294
- constant_name = observation_request.sub(/^on_event_/, '')
295
- GSWT.has_constant?(constant_name)
296
- elsif observation_request.start_with?('on_')
297
- event = observation_request.sub(/^on_/, '')
298
- can_add_listener?(event)
299
- else
300
- false
301
- end
302
- end
303
-
304
- def handle_observation_request(observation_request, &block)
305
- if observation_request.start_with?('on_event_')
306
- constant_name = observation_request.sub(/^on_event_/, '')
307
- @widget.addListener(GSWT[constant_name], &block)
308
- elsif observation_request.start_with?('on_')
309
- event = observation_request.sub(/^on_/, '')
310
- add_listener(event, &block)
311
- end
312
- nil
313
- end
314
-
315
- def method_missing(method, *args, &block)
316
- method_name = method.to_s
317
- if can_handle_observation_request?(method_name)
318
- handle_observation_request(method_name, &block)
319
- else
320
- super
321
- end
322
- end
323
-
324
- def add_content(&block)
325
- Glimmer.add_contents(self, &block)
326
- end
327
-
328
- private
329
-
330
- def style(underscored_widget_name, styles)
331
- styles.empty? ? default_style(underscored_widget_name) : GSWT[*styles]
332
- end
333
-
334
- def default_style(underscored_widget_name)
335
- style = @@default_styles[underscored_widget_name] if @@default_styles[underscored_widget_name]
336
- style = GSWT[:none] unless style
337
- style
338
- end
339
-
340
- def attribute_setter(attribute_name)
341
- "set#{attribute_name.to_s.camelcase(:upper)}"
342
- end
343
-
344
- def attribute_getter(attribute_name)
345
- "get#{attribute_name.to_s.camelcase(:upper)}"
346
- end
347
- end
348
- end
349
- end