glimmer 0.3.5 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/README.markdown +94 -32
  3. data/lib/glimmer.rb +4 -6
  4. data/lib/glimmer/command_handler.rb +10 -0
  5. data/lib/glimmer/command_handler_chain_factory.rb +32 -0
  6. data/lib/glimmer/command_handler_chain_link.rb +21 -0
  7. data/lib/{command_handlers.rb → glimmer/command_handlers.rb} +21 -17
  8. data/lib/glimmer/command_handlers/bind_command_handler.rb +51 -0
  9. data/lib/glimmer/command_handlers/color_command_handler.rb +26 -0
  10. data/lib/glimmer/command_handlers/combo_selection_data_binding_command_handler.rb +40 -0
  11. data/lib/glimmer/command_handlers/data_binding_command_handler.rb +69 -0
  12. data/lib/glimmer/command_handlers/display_command_handler.rb +16 -0
  13. data/lib/glimmer/command_handlers/list_selection_data_binding_command_handler.rb +45 -0
  14. data/lib/glimmer/command_handlers/models/g_color.rb +34 -0
  15. data/lib/glimmer/command_handlers/models/g_display.rb +26 -0
  16. data/lib/glimmer/command_handlers/models/g_font.rb +62 -0
  17. data/lib/glimmer/command_handlers/models/g_runnable.rb +13 -0
  18. data/lib/glimmer/command_handlers/models/g_shell.rb +27 -0
  19. data/lib/glimmer/command_handlers/models/g_swt.rb +22 -0
  20. data/lib/glimmer/command_handlers/models/g_tab_item_composite.rb +33 -0
  21. data/lib/glimmer/command_handlers/models/g_widget.rb +199 -0
  22. data/lib/glimmer/command_handlers/models/g_widget_listener.rb +11 -0
  23. data/lib/glimmer/command_handlers/models/list_selection_binding.rb +47 -0
  24. data/lib/glimmer/command_handlers/models/model_binding.rb +206 -0
  25. data/lib/glimmer/command_handlers/models/observable.rb +11 -0
  26. data/lib/glimmer/command_handlers/models/observable_array.rb +104 -0
  27. data/lib/glimmer/command_handlers/models/observable_model.rb +105 -0
  28. data/lib/glimmer/command_handlers/models/observer.rb +115 -0
  29. data/lib/glimmer/command_handlers/models/table_items_binding.rb +45 -0
  30. data/lib/glimmer/command_handlers/models/tree_items_binding.rb +49 -0
  31. data/lib/glimmer/command_handlers/models/widget_binding.rb +29 -0
  32. data/lib/glimmer/command_handlers/shell_command_handler.rb +17 -0
  33. data/lib/glimmer/command_handlers/tab_item_command_handler.rb +21 -0
  34. data/lib/glimmer/command_handlers/table_column_properties_data_binding_command_handler.rb +25 -0
  35. data/lib/glimmer/command_handlers/table_items_data_binding_command_handler.rb +30 -0
  36. data/lib/glimmer/command_handlers/tree_items_data_binding_command_handler.rb +29 -0
  37. data/lib/glimmer/command_handlers/tree_properties_data_binding_command_handler.rb +25 -0
  38. data/lib/glimmer/command_handlers/widget_command_handler.rb +22 -0
  39. data/lib/glimmer/command_handlers/widget_listener_command_handler.rb +39 -0
  40. data/lib/glimmer/command_handlers/widget_method_command_handler.rb +21 -0
  41. data/lib/glimmer/parent.rb +7 -0
  42. data/lib/{shine.rb → glimmer/shine.rb} +1 -1
  43. data/lib/glimmer/swt_packages.rb +13 -0
  44. data/lib/{xml_command_handlers.rb → glimmer/xml_command_handlers.rb} +10 -8
  45. data/lib/glimmer/xml_command_handlers/html_command_handler.rb +47 -0
  46. data/lib/glimmer/xml_command_handlers/models/depth_first_search_iterator.rb +19 -0
  47. data/lib/glimmer/xml_command_handlers/models/name_space_visitor.rb +20 -0
  48. data/lib/glimmer/xml_command_handlers/models/node.rb +82 -0
  49. data/lib/glimmer/xml_command_handlers/models/node_visitor.rb +11 -0
  50. data/lib/glimmer/xml_command_handlers/models/xml_visitor.rb +61 -0
  51. data/lib/glimmer/xml_command_handlers/xml_command_handler.rb +20 -0
  52. data/lib/glimmer/xml_command_handlers/xml_name_space_command_handler.rb +33 -0
  53. data/lib/glimmer/xml_command_handlers/xml_tag_command_handler.rb +25 -0
  54. data/lib/glimmer/xml_command_handlers/xml_text_command_handler.rb +21 -0
  55. metadata +53 -54
  56. data/lib/command_handler.rb +0 -8
  57. data/lib/command_handler_chain_factory.rb +0 -30
  58. data/lib/command_handler_chain_link.rb +0 -19
  59. data/lib/command_handlers/bind_command_handler.rb +0 -49
  60. data/lib/command_handlers/color_command_handler.rb +0 -24
  61. data/lib/command_handlers/combo_selection_data_binding_command_handler.rb +0 -38
  62. data/lib/command_handlers/data_binding_command_handler.rb +0 -67
  63. data/lib/command_handlers/list_selection_data_binding_command_handler.rb +0 -43
  64. data/lib/command_handlers/models/block_observer.rb +0 -14
  65. data/lib/command_handlers/models/list_selection_binding.rb +0 -45
  66. data/lib/command_handlers/models/model_binding.rb +0 -205
  67. data/lib/command_handlers/models/observable.rb +0 -9
  68. data/lib/command_handlers/models/observable_array.rb +0 -102
  69. data/lib/command_handlers/models/observable_model.rb +0 -103
  70. data/lib/command_handlers/models/observer.rb +0 -88
  71. data/lib/command_handlers/models/r_color.rb +0 -32
  72. data/lib/command_handlers/models/r_font.rb +0 -60
  73. data/lib/command_handlers/models/r_runnable.rb +0 -11
  74. data/lib/command_handlers/models/r_shell.rb +0 -24
  75. data/lib/command_handlers/models/r_swt.rb +0 -18
  76. data/lib/command_handlers/models/r_tab_item_composite.rb +0 -31
  77. data/lib/command_handlers/models/r_widget.rb +0 -183
  78. data/lib/command_handlers/models/r_widget_listener.rb +0 -9
  79. data/lib/command_handlers/models/table_items_binding.rb +0 -43
  80. data/lib/command_handlers/models/tree_items_binding.rb +0 -47
  81. data/lib/command_handlers/models/widget_binding.rb +0 -27
  82. data/lib/command_handlers/shell_command_handler.rb +0 -15
  83. data/lib/command_handlers/tab_item_command_handler.rb +0 -19
  84. data/lib/command_handlers/table_column_properties_data_binding_command_handler.rb +0 -23
  85. data/lib/command_handlers/table_items_data_binding_command_handler.rb +0 -28
  86. data/lib/command_handlers/tree_items_data_binding_command_handler.rb +0 -27
  87. data/lib/command_handlers/tree_properties_data_binding_command_handler.rb +0 -23
  88. data/lib/command_handlers/widget_command_handler.rb +0 -20
  89. data/lib/command_handlers/widget_listener_command_handler.rb +0 -37
  90. data/lib/command_handlers/widget_method_command_handler.rb +0 -19
  91. data/lib/parent.rb +0 -5
  92. data/lib/string.rb +0 -8
  93. data/lib/swt_packages.rb +0 -11
  94. data/lib/symbol.rb +0 -10
  95. data/lib/xml_command_handlers/html_command_handler.rb +0 -45
  96. data/lib/xml_command_handlers/models/depth_first_search_iterator.rb +0 -17
  97. data/lib/xml_command_handlers/models/name_space_visitor.rb +0 -18
  98. data/lib/xml_command_handlers/models/node.rb +0 -80
  99. data/lib/xml_command_handlers/models/node_visitor.rb +0 -9
  100. data/lib/xml_command_handlers/models/xml_visitor.rb +0 -59
  101. data/lib/xml_command_handlers/xml_command_handler.rb +0 -18
  102. data/lib/xml_command_handlers/xml_name_space_command_handler.rb +0 -31
  103. data/lib/xml_command_handlers/xml_tag_command_handler.rb +0 -23
  104. data/lib/xml_command_handlers/xml_text_command_handler.rb +0 -19
@@ -0,0 +1,69 @@
1
+ require File.dirname(__FILE__) + "/../command_handler"
2
+ require File.dirname(__FILE__) + "/models/g_widget"
3
+ require File.dirname(__FILE__) + "/models/observable_model"
4
+ require File.dirname(__FILE__) + "/models/model_binding"
5
+ require File.dirname(__FILE__) + "/models/widget_binding"
6
+
7
+ module Glimmer
8
+ # Responsible for wiring two-way data-binding for text and selection properties
9
+ # on Text, Button, and Spinner widgets.
10
+ # Does so by using the output of the bind(model, property) command in the form
11
+ # of a ModelBinding, which is then connected to an anonymous widget observer
12
+ # (aka widget_data_binder as per widget_data_binders array)
13
+ #
14
+ # Depends on BindCommandHandler
15
+ class DataBindingCommandHandler
16
+ extend Glimmer
17
+ include CommandHandler
18
+
19
+ include_package 'org.eclipse.swt.widgets'
20
+
21
+ @@widget_data_binders = {
22
+ Java::OrgEclipseSwtWidgets::Text => {
23
+ :text => Proc.new do |g_widget, model_binding|
24
+ add_contents(g_widget) {
25
+ on_modify_text { |modify_event|
26
+ model_binding.call(g_widget.widget.getText)
27
+ }
28
+ }
29
+ end,
30
+ },
31
+ Java::OrgEclipseSwtWidgets::Button => {
32
+ :selection => Proc.new do |g_widget, model_binding|
33
+ add_contents(g_widget) {
34
+ on_widget_selected { |selection_event|
35
+ model_binding.call(g_widget.widget.getSelection)
36
+ }
37
+ }
38
+ end
39
+ },
40
+ Java::OrgEclipseSwtWidgets::Spinner => {
41
+ :selection => Proc.new do |g_widget, model_binding|
42
+ add_contents(g_widget) {
43
+ on_widget_selected { |selection_event|
44
+ model_binding.call(g_widget.widget.getSelection)
45
+ }
46
+ }
47
+ end
48
+ }
49
+ }
50
+
51
+ def can_handle?(parent, command_symbol, *args, &block)
52
+ (parent.is_a?(GWidget) and
53
+ args.size == 1 and
54
+ args[0].is_a?(ModelBinding))
55
+ end
56
+
57
+ def do_handle(parent, command_symbol, *args, &block)
58
+ model_binding = args[0]
59
+ widget_binding_parameters = [parent, command_symbol.to_s]
60
+ widget_binding = WidgetBinding.new(*widget_binding_parameters)
61
+ widget_binding.call(model_binding.evaluate_property)
62
+ widget_binding.observe(model_binding)
63
+ widget_data_binder_map = @@widget_data_binders[parent.widget.class]
64
+ widget_data_binder = widget_data_binder_map[command_symbol.to_s.to_sym] if widget_data_binder_map
65
+ widget_data_binder.call(parent, model_binding) if widget_data_binder
66
+ end
67
+
68
+ end
69
+ end
@@ -0,0 +1,16 @@
1
+ require File.dirname(__FILE__) + "/../command_handler"
2
+ require File.dirname(__FILE__) + "/models/g_display"
3
+
4
+ module Glimmer
5
+ class DisplayCommandHandler
6
+ include CommandHandler
7
+
8
+ def can_handle?(parent, command_symbol, *args, &block)
9
+ command_symbol.to_s == "display"
10
+ end
11
+
12
+ def do_handle(parent, command_symbol, *args, &block)
13
+ GDisplay.instance(*args)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,45 @@
1
+ require File.dirname(__FILE__) + "/../command_handler"
2
+ require File.dirname(__FILE__) + "/models/g_widget"
3
+ require File.dirname(__FILE__) + "/models/list_selection_binding"
4
+
5
+ module Glimmer
6
+ class ListSelectionDataBindingCommandHandler
7
+ include CommandHandler
8
+ include Glimmer
9
+
10
+ include_package 'org.eclipse.swt.widgets'
11
+
12
+ def can_handle?(parent, command_symbol, *args, &block)
13
+ parent.is_a?(GWidget) and
14
+ parent.widget.is_a?(List) and
15
+ command_symbol.to_s == "selection" and
16
+ args.size == 1 and
17
+ args[0].is_a?(ModelBinding) and
18
+ args[0].evaluate_options_property.is_a?(Array) and
19
+ block == nil
20
+ end
21
+
22
+ def do_handle(parent, command_symbol, *args, &block)
23
+ model_binding = args[0]
24
+ widget_binding = WidgetBinding.new(parent, "items")
25
+ widget_binding.call(model_binding.evaluate_options_property)
26
+ model = model_binding.base_model
27
+ #TODO make this options observer dependent and all similar observers in widget specific data binding handlers
28
+ widget_binding.observe(model, model_binding.options_property_name)
29
+
30
+ property_type = :string
31
+ property_type = :array if parent.has_style?(:multi)
32
+ list_selection_binding = ListSelectionBinding.new(parent, property_type)
33
+ list_selection_binding.call(model_binding.evaluate_property)
34
+ #TODO check if nested data binding works for list widget and other widgets that need custom data binding
35
+ list_selection_binding.observe(model, model_binding.property_name_expression)
36
+
37
+ add_contents(parent) {
38
+ on_widget_selected {
39
+ model_binding.call(list_selection_binding.evaluate_property)
40
+ }
41
+ }
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,34 @@
1
+ require_relative 'g_swt'
2
+
3
+ module Glimmer
4
+ class GColor
5
+ attr_reader :display, :red, :green, :blue, :alpha
6
+
7
+ include_package 'org.eclipse.swt.graphics'
8
+
9
+ class << self
10
+ include_package 'org.eclipse.swt'
11
+
12
+ def for(display, standard_color)
13
+ display.getSystemColor(GSWT[standard_color])
14
+ end
15
+ end
16
+
17
+ def initialize(display, red, green, blue, alpha = nil)
18
+ @display = display
19
+ @red = red
20
+ @green = green
21
+ @blue = blue
22
+ @alpha = alpha
23
+ end
24
+
25
+ def color
26
+ @color ||= Color.new(@display, *[@red, @green, @blue, @alpha].compact)
27
+ end
28
+
29
+ def display=(a_display)
30
+ @display = a_display
31
+ @color = nil
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,26 @@
1
+ module Glimmer
2
+ # Wrapper around SWT Display
3
+ class GDisplay
4
+ include_package 'org.eclipse.swt.widgets'
5
+
6
+ class << self
7
+ def instance(*args)
8
+ if @instance.nil? || @instance.display.isDisposed
9
+ @instance = GDisplay.new(*args)
10
+ end
11
+ @instance
12
+ end
13
+ end
14
+
15
+ # SWT Display object wrapped
16
+ attr_reader :display
17
+
18
+ def initialize(*args)
19
+ @display = Display.new(*args)
20
+ end
21
+
22
+ def dispose
23
+ @display.dispose
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,62 @@
1
+ require_relative 'g_swt'
2
+
3
+ module Glimmer
4
+ class GFont
5
+ include_package 'org.eclipse.swt.graphics'
6
+
7
+ extend Glimmer
8
+
9
+ attr_reader :g_widget
10
+ attr_accessor :display
11
+
12
+ class << self
13
+ def for(g_widget)
14
+ @instances ||= {}
15
+ unless @instances[g_widget]
16
+ @instances[g_widget] = new(g_widget)
17
+ add_contents(g_widget) {
18
+ on_widget_disposed { |dispose_event|
19
+ @instances.delete(g_widget)
20
+ }
21
+ }
22
+ end
23
+ @instances[g_widget]
24
+ end
25
+ end
26
+
27
+ def initialize(g_widget, display = nil)
28
+ @g_widget = g_widget
29
+ @display = display || @g_widget.widget.display
30
+ end
31
+
32
+ def g_widget=(a_widget)
33
+ @g_widget = a_widget
34
+ @font_datum = nil
35
+ end
36
+
37
+ def font_datum
38
+ @font_datum ||= @g_widget.widget.getFont.getFontData[0]
39
+ end
40
+
41
+ def name
42
+ font_datum.getName
43
+ end
44
+
45
+ def height
46
+ font_datum.getHeight
47
+ end
48
+
49
+ def style
50
+ font_datum.getStyle
51
+ end
52
+
53
+ def font(font_properties)
54
+ font_properties[:style] = GSWT[*font_properties[:style]]
55
+ font_data_args = [:name, :height, :style].map do |font_property_name|
56
+ font_properties[font_property_name] || send(font_property_name)
57
+ end
58
+ font_datum = FontData.new(*font_data_args)
59
+ Font.new(@display, font_datum)
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,13 @@
1
+ module Glimmer
2
+ class GRunnable
3
+ include java.lang.Runnable
4
+
5
+ def initialize(&block)
6
+ @block = block
7
+ end
8
+
9
+ def run
10
+ @block.call
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,27 @@
1
+ require_relative 'g_widget'
2
+ require_relative 'g_display'
3
+
4
+ module Glimmer
5
+ class GShell < GWidget
6
+ include_package 'org.eclipse.swt.layout'
7
+ include_package 'org.eclipse.swt.widgets'
8
+
9
+ attr_reader :display
10
+
11
+ def initialize(display = GDisplay.instance.display)
12
+ @display = display
13
+ @widget = Shell.new(@display)
14
+ @widget.setLayout(FillLayout.new)
15
+ end
16
+
17
+ def open
18
+ @widget.pack
19
+ @widget.open
20
+ until @widget.isDisposed
21
+ @display.sleep unless @display.readAndDispatch
22
+ end
23
+ @display.dispose
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ module Glimmer
2
+ class GSWT
3
+ class << self
4
+ java_import 'org.eclipse.swt.SWT'
5
+
6
+ # Gets SWT constants as if calling SWT::CONSTANT where constant is
7
+ # passed in as a lower case symbol
8
+ def [](*symbols)
9
+ symbols.compact.reduce(0) { |output, symbol| output | constant(symbol) }
10
+ end
11
+
12
+ def constant(symbol)
13
+ return symbol if symbol.is_a?(Integer)
14
+ swt_constant_symbol = symbol.to_s.upcase.to_sym
15
+ SWT.const_get(swt_constant_symbol)
16
+ rescue
17
+ swt_constant_symbol = SWT.constants.find {|c| c.to_s.upcase == swt_constant_symbol.to_s}
18
+ SWT.const_get(swt_constant_symbol)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,33 @@
1
+ require File.dirname(__FILE__) + "/g_widget_listener"
2
+ require File.dirname(__FILE__) + "/g_runnable"
3
+
4
+ module Glimmer
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
+ end
33
+ end
@@ -0,0 +1,199 @@
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
+
7
+ module Glimmer
8
+ class GWidget
9
+ include_package 'org.eclipse.swt'
10
+ include_package 'org.eclipse.swt.widgets'
11
+ include_package 'org.eclipse.swt.layout'
12
+ include_package 'org.eclipse.swt.graphics'
13
+ include Parent
14
+
15
+ attr_reader :widget
16
+
17
+ #TODO externalize
18
+ @@default_styles = {
19
+ "text" => GSWT[:border],
20
+ "table" => GSWT[:border],
21
+ "spinner" => GSWT[:border],
22
+ "list" => GSWT[:border, :v_scroll],
23
+ "button" => GSWT[:push],
24
+ }
25
+
26
+ #TODO externalize
27
+ @@default_initializers = {
28
+ "composite" => Proc.new {|composite| composite.setLayout(GridLayout.new) },
29
+ "table" => Proc.new do |table|
30
+ table.setHeaderVisible(true)
31
+ table.setLinesVisible(true)
32
+ end,
33
+ "table_column" => Proc.new { |table_column| table_column.setWidth(80) },
34
+ "group" => Proc.new {|group| group.setLayout(GridLayout.new) },
35
+ }
36
+
37
+ #styles is a comma separate list of symbols representing SWT styles in lower case
38
+ def initialize(underscored_widget_name, parent, styles, &contents)
39
+ @widget = self.class.swt_widget_class_for(underscored_widget_name).new(parent, style(underscored_widget_name, styles))
40
+ @@default_initializers[underscored_widget_name].call(@widget) if @@default_initializers[underscored_widget_name]
41
+ end
42
+
43
+ def has_attribute?(attribute_name, *args)
44
+ @widget.respond_to?(attribute_setter(attribute_name), args)
45
+ end
46
+
47
+ def set_attribute(attribute_name, *args)
48
+ apply_property_type_converters(attribute_name, args)
49
+ @widget.send(attribute_setter(attribute_name), *args)
50
+ end
51
+
52
+ def property_type_converters
53
+ @property_type_converters ||= {
54
+ :text => Proc.new { |value| value.to_s },
55
+ :items => Proc.new { |value| value.to_java :string},
56
+ :visible => Proc.new { |value| !!value},
57
+ :font => Proc.new do |value|
58
+ if value.is_a?(Hash)
59
+ font_properties = value
60
+ GFont.for(self).font(font_properties)
61
+ else
62
+ value
63
+ end
64
+ end,
65
+ }
66
+ end
67
+
68
+ def apply_property_type_converters(attribute_name, args)
69
+ if args.count == 1
70
+ value = args.first
71
+ converter = property_type_converters[attribute_name.to_sym]
72
+ args[0] = converter.call(value) if converter
73
+ end
74
+ if args.count == 1 && (args.first.is_a?(Symbol) || args.first.is_a?(String)) && args.first.to_s.start_with?('color_')
75
+ standard_color = args.first
76
+ args[0] = GColor.for(widget.getDisplay, standard_color)
77
+ elsif args.count == 1 && args.first.is_a?(GColor)
78
+ g_color = args.first
79
+ g_color.display = widget.display if g_color.display.nil? || g_color.display != widget.display
80
+ args[0] = g_color.color
81
+ end
82
+ end
83
+
84
+ def self.widget_exists?(underscored_widget_name)
85
+ begin
86
+ swt_widget_class_for(underscored_widget_name)
87
+ true
88
+ rescue NameError
89
+ false
90
+ end
91
+ end
92
+
93
+ # This supports widgets in and out of basic SWT
94
+ def self.swt_widget_class_for(underscored_widget_name)
95
+ swt_widget_name = underscored_widget_name.camelcase(:upper)
96
+ swt_widget_class = eval(swt_widget_name)
97
+ unless swt_widget_class.ancestors.include?(org.eclipse.swt.widgets.Widget)
98
+ raise NameError, "Class #{swt_widget_class} matching #{underscored_widget_name} is not a subclass of org.eclipse.swt.widgets.Widget"
99
+ end
100
+ swt_widget_class
101
+ end
102
+
103
+ def widget_listener_exists?(underscored_listener_name)
104
+ listener_method_name = underscored_listener_name.listener_method_name(:lower)
105
+ @widget.getClass.getMethods.each do |widget_method|
106
+ if widget_method.getName.match(/add.*Listener/)
107
+ widget_method.getParameterTypes.each do |listener_type|
108
+ listener_type.getMethods.each do |listener_method|
109
+ if (listener_method.getName == listener_method_name)
110
+ return true
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
116
+ return false
117
+ end
118
+
119
+ def can_add_listener?(underscored_listener_name)
120
+ listener_method_name = underscored_listener_name.camelcase(:lower)
121
+ @widget.getClass.getMethods.each do |widget_method|
122
+ if widget_method.getName.match(/add.*Listener/)
123
+ widget_method.getParameterTypes.each do |listener_type|
124
+ listener_type.getMethods.each do |listener_method|
125
+ if (listener_method.getName == listener_method_name)
126
+ return true
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
132
+ return false
133
+ end
134
+
135
+ def add_listener(underscored_listener_name, &block)
136
+ listener_method_name = underscored_listener_name.camelcase(:lower)
137
+ @widget.getClass.getMethods.each do |widget_method|
138
+ if widget_method.getName.match(/add.*Listener/)
139
+ widget_method.getParameterTypes.each do |listener_type|
140
+ listener_type.getMethods.each do |listener_method|
141
+ if (listener_method.getName == listener_method_name)
142
+ listener_class = Class.new(Object)
143
+ listener_class.send :include, (eval listener_type.to_s.sub("interface", ""))
144
+ listener = listener_class.new
145
+ listener_type.getMethods.each do |t_method|
146
+ eval "def listener.#{t_method.getName}(event) end"
147
+ end
148
+ def listener.block=(block)
149
+ @block = block
150
+ end
151
+ listener.block=block
152
+ eval "def listener.#{listener_method.getName}(event) @block.call(event) if @block end"
153
+ @widget.send(widget_method.getName, listener)
154
+ return GWidgetListener.new(listener)
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
161
+
162
+ def process_block(block)
163
+ block.call(@widget)
164
+ end
165
+
166
+ def async_exec(&block)
167
+ @widget.getDisplay.asyncExec(GRunnable.new(&block))
168
+ end
169
+
170
+ def sync_exec(&block)
171
+ @widget.getDisplay.syncExec(GRunnable.new(&block))
172
+ end
173
+
174
+ def has_style?(style)
175
+ (widget.style & GSWT[style]) == GSWT[style]
176
+ end
177
+
178
+ def dispose
179
+ @widget.dispose
180
+ end
181
+
182
+ private
183
+
184
+ def style(underscored_widget_name, styles)
185
+ styles.empty? ? default_style(underscored_widget_name) : GSWT[*styles]
186
+ end
187
+
188
+ def default_style(underscored_widget_name)
189
+ style = @@default_styles[underscored_widget_name] if @@default_styles[underscored_widget_name]
190
+ style = GSWT[:none] unless style
191
+ style
192
+ end
193
+
194
+ def attribute_setter(attribute_name)
195
+ "set#{attribute_name.to_s.camelcase(:upper)}"
196
+ end
197
+
198
+ end
199
+ end