glimmer 0.1.0.0
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.
- data/COPYING.LGPL +504 -0
- data/README +27 -0
- data/samples/contactmanager/contact.rb +12 -0
- data/samples/contactmanager/contact_manager.rb +65 -0
- data/samples/contactmanager/contact_manager_presenter.rb +23 -0
- data/samples/contactmanager/contact_repository.rb +27 -0
- data/samples/hello_world.rb +26 -0
- data/samples/login.rb +97 -0
- data/samples/tictactoe/tic_tac_toe.rb +67 -0
- data/samples/tictactoe/tic_tac_toe_board.rb +149 -0
- data/src/command_handler.rb +11 -0
- data/src/command_handler_chain_factory.rb +23 -0
- data/src/command_handler_chain_link.rb +22 -0
- data/src/command_handlers.rb +26 -0
- data/src/command_handlers/bind_command_handler.rb +29 -0
- data/src/command_handlers/data_binding_command_handler.rb +64 -0
- data/src/command_handlers/models/model_observer.rb +25 -0
- data/src/command_handlers/models/observable_array.rb +46 -0
- data/src/command_handlers/models/observable_model.rb +35 -0
- data/src/command_handlers/models/r_runnable.rb +14 -0
- data/src/command_handlers/models/r_shell.rb +27 -0
- data/src/command_handlers/models/r_widget.rb +146 -0
- data/src/command_handlers/models/r_widget_listener.rb +12 -0
- data/src/command_handlers/models/r_widget_packages.rb +9 -0
- data/src/command_handlers/models/table_items_updater.rb +39 -0
- data/src/command_handlers/models/widget_observer.rb +23 -0
- data/src/command_handlers/shell_command_handler.rb +18 -0
- data/src/command_handlers/swt_constant_command_handler.rb +22 -0
- data/src/command_handlers/table_column_properties_data_binding_command_handler.rb +24 -0
- data/src/command_handlers/table_items_data_binding_command_handler.rb +30 -0
- data/src/command_handlers/widget_command_handler.rb +26 -0
- data/src/command_handlers/widget_listener_command_handler.rb +35 -0
- data/src/command_handlers/widget_method_command_handler.rb +22 -0
- data/src/glimmer.rb +45 -0
- data/src/parent.rb +8 -0
- data/src/shine.rb +24 -0
- data/src/swt.rb +10 -0
- data/src/xml.rb +10 -0
- data/src/xml_command_handlers.rb +18 -0
- data/src/xml_command_handlers/html_command_handler.rb +49 -0
- data/src/xml_command_handlers/models/depth_first_search_iterator.rb +20 -0
- data/src/xml_command_handlers/models/name_space_visitor.rb +21 -0
- data/src/xml_command_handlers/models/node.rb +83 -0
- data/src/xml_command_handlers/models/node_visitor.rb +12 -0
- data/src/xml_command_handlers/models/xml_visitor.rb +62 -0
- data/src/xml_command_handlers/xml_command_handler.rb +22 -0
- data/src/xml_command_handlers/xml_name_space_command_handler.rb +34 -0
- data/src/xml_command_handlers/xml_tag_command_handler.rb +26 -0
- data/src/xml_command_handlers/xml_text_command_handler.rb +22 -0
- data/test/glimmer_constant_test.rb +36 -0
- data/test/glimmer_data_binding_test.rb +236 -0
- data/test/glimmer_listeners_test.rb +61 -0
- data/test/glimmer_shine_data_binding_test.rb +88 -0
- data/test/glimmer_table_data_binding_test.rb +135 -0
- data/test/glimmer_test.rb +233 -0
- data/test/observable_model_test.rb +27 -0
- data/test/r_widget_test.rb +52 -0
- data/test/samples/contactmanager/contact_manager_presenter_test.rb +60 -0
- data/test/samples/tictactoe/tic_tac_toe_test.rb +265 -0
- data/test/xml/glimmer_xml_test.rb +163 -0
- metadata +126 -0
@@ -0,0 +1,11 @@
|
|
1
|
+
# Copyright (C) 2007-2008 Annas Al Maleh
|
2
|
+
# Licensed under the LGPL. See /COPYING.LGPL for more details.
|
3
|
+
|
4
|
+
module CommandHandler
|
5
|
+
def can_handle?(parent, command_symbol, *args, &block)
|
6
|
+
raise "must be implemented by a class"
|
7
|
+
end
|
8
|
+
def do_handle(parent, command_symbol, *args, &block)
|
9
|
+
raise "must be implemented by a class"
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Copyright (C) 2007-2008 Annas Al Maleh
|
2
|
+
# Licensed under the LGPL. See /COPYING.LGPL for more details.
|
3
|
+
|
4
|
+
require File.dirname(__FILE__) + "/command_handler_chain_link"
|
5
|
+
|
6
|
+
class CommandHandlerChainFactory
|
7
|
+
@@last_chain_link = nil
|
8
|
+
@@chain = nil
|
9
|
+
|
10
|
+
def self.set_command_handlers(*command_handler_array)
|
11
|
+
command_handler_array.each do |command_handler|
|
12
|
+
puts "Loading #{command_handler.class.to_s}..."
|
13
|
+
chain_link = CommandHandlerChainLink.new(command_handler)
|
14
|
+
@@last_chain_link.chain_to(chain_link) if @@last_chain_link
|
15
|
+
@@last_chain_link = chain_link
|
16
|
+
@@chain = chain_link unless @@chain
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.chain
|
21
|
+
@@chain
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Copyright (C) 2007-2008 Annas Al Maleh
|
2
|
+
# Licensed under the LGPL. See /COPYING.LGPL for more details.
|
3
|
+
|
4
|
+
class CommandHandlerChainLink
|
5
|
+
def initialize(command_handler)
|
6
|
+
@command_handler = command_handler
|
7
|
+
end
|
8
|
+
def chain_to(next_chain_link)
|
9
|
+
@next_chain_link = next_chain_link
|
10
|
+
end
|
11
|
+
def handle(parent, command_symbol, *args, &block)
|
12
|
+
if (@command_handler.can_handle?(parent, command_symbol, *args, &block))
|
13
|
+
puts "#{@command_handler.class.to_s} will handle command: #{command_symbol} with arguments #{args}"
|
14
|
+
return @command_handler.do_handle(parent, command_symbol, *args, &block)
|
15
|
+
elsif @next_chain_link
|
16
|
+
return @next_chain_link.handle(parent, command_symbol, *args, &block)
|
17
|
+
else
|
18
|
+
puts "Command: #{command_symbol} cannot be handled!"
|
19
|
+
return nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Copyright (C) 2007-2008 Annas Al Maleh
|
2
|
+
# Licensed under the LGPL. See /COPYING.LGPL for more details.
|
3
|
+
|
4
|
+
require File.dirname(__FILE__) + "/command_handler_chain_factory"
|
5
|
+
require File.dirname(__FILE__) + "/command_handlers/shell_command_handler"
|
6
|
+
require File.dirname(__FILE__) + "/command_handlers/widget_listener_command_handler"
|
7
|
+
require File.dirname(__FILE__) + "/command_handlers/bind_command_handler"
|
8
|
+
require File.dirname(__FILE__) + "/command_handlers/table_items_data_binding_command_handler"
|
9
|
+
require File.dirname(__FILE__) + "/command_handlers/table_column_properties_data_binding_command_handler"
|
10
|
+
require File.dirname(__FILE__) + "/command_handlers/data_binding_command_handler"
|
11
|
+
require File.dirname(__FILE__) + "/command_handlers/widget_method_command_handler"
|
12
|
+
require File.dirname(__FILE__) + "/command_handlers/widget_command_handler"
|
13
|
+
require File.dirname(__FILE__) + "/command_handlers/swt_constant_command_handler"
|
14
|
+
|
15
|
+
# edit to add more command handlers and extend Glimmer
|
16
|
+
CommandHandlerChainFactory.set_command_handlers(
|
17
|
+
ShellCommandHandler.new,
|
18
|
+
WidgetListenerCommandHandler.new,
|
19
|
+
BindCommandHandler.new,
|
20
|
+
TableItemsDataBindingCommandHandler.new,
|
21
|
+
TableColumnPropertiesDataBindingCommandHandler.new,
|
22
|
+
DataBindingCommandHandler.new,
|
23
|
+
WidgetMethodCommandHandler.new,
|
24
|
+
WidgetCommandHandler.new,
|
25
|
+
SwtConstantCommandHandler.new #at the bottom to avoid stealing commands from other command handlers
|
26
|
+
)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Copyright (C) 2007-2008 Annas Al Maleh
|
2
|
+
# Licensed under the LGPL. See /COPYING.LGPL for more details.
|
3
|
+
|
4
|
+
require File.dirname(__FILE__) + "/../command_handler"
|
5
|
+
require File.dirname(__FILE__) + "/models/r_widget"
|
6
|
+
require File.dirname(__FILE__) + "/models/model_observer"
|
7
|
+
|
8
|
+
class BindCommandHandler
|
9
|
+
include CommandHandler
|
10
|
+
|
11
|
+
include_package 'org.eclipse.swt.widgets'
|
12
|
+
|
13
|
+
def can_handle?(parent, command_symbol, *args, &block)
|
14
|
+
parent.is_a?(RWidget) and
|
15
|
+
command_symbol.to_s == "bind" and
|
16
|
+
(((args.size == 2) and
|
17
|
+
(args[1].is_a?(Symbol) or args[1].is_a?(String))) or
|
18
|
+
((args.size == 3) and
|
19
|
+
(args[1].is_a?(Symbol) or args[1].is_a?(String)) and
|
20
|
+
(args[2].is_a?(Symbol) or args[2].is_a?(String)))) and
|
21
|
+
block == nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def do_handle(parent, command_symbol, *args, &block)
|
25
|
+
property_type = args[2] if (args.size == 3)
|
26
|
+
ModelObserver.new(args[0], args[1].to_s, property_type)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# Copyright (C) 2007-2008 Annas Al Maleh
|
2
|
+
# Licensed under the LGPL. See /COPYING.LGPL for more details.
|
3
|
+
|
4
|
+
require File.dirname(__FILE__) + "/../command_handler"
|
5
|
+
require File.dirname(__FILE__) + "/models/r_widget"
|
6
|
+
require File.dirname(__FILE__) + "/models/observable_model"
|
7
|
+
require File.dirname(__FILE__) + "/models/model_observer"
|
8
|
+
require File.dirname(__FILE__) + "/models/widget_observer"
|
9
|
+
|
10
|
+
class DataBindingCommandHandler
|
11
|
+
extend Glimmer
|
12
|
+
include CommandHandler
|
13
|
+
|
14
|
+
include_package 'org.eclipse.swt.widgets'
|
15
|
+
|
16
|
+
@@widget_data_binders = {
|
17
|
+
Java::OrgEclipseSwtWidgets::Text => {
|
18
|
+
:text => Proc.new do |rwidget, model_observer|
|
19
|
+
add_contents(rwidget) {
|
20
|
+
on_modify_text { |modify_event|
|
21
|
+
model_observer.update(rwidget.widget.getText)
|
22
|
+
}
|
23
|
+
}
|
24
|
+
end,
|
25
|
+
},
|
26
|
+
Java::OrgEclipseSwtWidgets::Button => {
|
27
|
+
:selection => Proc.new do |rwidget, model_observer|
|
28
|
+
add_contents(rwidget) {
|
29
|
+
on_widget_selected { |selection_event|
|
30
|
+
model_observer.update(rwidget.widget.getSelection)
|
31
|
+
}
|
32
|
+
}
|
33
|
+
end
|
34
|
+
},
|
35
|
+
Java::OrgEclipseSwtWidgets::Spinner => {
|
36
|
+
:selection => Proc.new do |rwidget, model_observer|
|
37
|
+
add_contents(rwidget) {
|
38
|
+
on_widget_selected { |selection_event|
|
39
|
+
model_observer.update(rwidget.widget.getSelection)
|
40
|
+
}
|
41
|
+
}
|
42
|
+
end
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
def can_handle?(parent, command_symbol, *args, &block)
|
47
|
+
parent.is_a?(RWidget) and
|
48
|
+
args.size == 1 and
|
49
|
+
args[0].is_a?(ModelObserver)
|
50
|
+
end
|
51
|
+
|
52
|
+
def do_handle(parent, command_symbol, *args, &block)
|
53
|
+
model_observer = args[0]
|
54
|
+
widget_observer = WidgetObserver.new(parent, command_symbol.to_s)
|
55
|
+
widget_observer.update(model_observer.evaluate_property)
|
56
|
+
model = model_observer.model
|
57
|
+
model.extend ObservableModel unless model.is_a?(ObservableModel)
|
58
|
+
model.add_observer(model_observer.property_name, widget_observer)
|
59
|
+
widget_data_binder_map = @@widget_data_binders[parent.widget.class]
|
60
|
+
widget_data_binder = widget_data_binder_map[command_symbol.to_s.to_sym] if widget_data_binder_map
|
61
|
+
widget_data_binder.call(parent, model_observer) if widget_data_binder
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Copyright (C) 2007-2008 Annas Al Maleh
|
2
|
+
# Licensed under the LGPL. See /COPYING.LGPL for more details.
|
3
|
+
|
4
|
+
class ModelObserver
|
5
|
+
attr_reader :model, :property_name, :property_type
|
6
|
+
@@property_type_converters = {
|
7
|
+
:undefined => Proc.new { |value| value },
|
8
|
+
:fixnum => Proc.new { |string_value| string_value.to_i }
|
9
|
+
#TODO check what other types are needed
|
10
|
+
}
|
11
|
+
def initialize(model, property_name, property_type)
|
12
|
+
property_type = :undefined unless property_type
|
13
|
+
@model = model
|
14
|
+
@property_name = property_name
|
15
|
+
@property_type = property_type
|
16
|
+
end
|
17
|
+
def update(value)
|
18
|
+
converted_value = @@property_type_converters[@property_type].call(value)
|
19
|
+
@model.send(@property_name + "=", converted_value) unless evaluate_property == converted_value
|
20
|
+
end
|
21
|
+
def evaluate_property
|
22
|
+
@model.send(@property_name)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# Copyright (C) 2007-2008 Annas Al Maleh
|
2
|
+
# Licensed under the LGPL. See /COPYING.LGPL for more details.
|
3
|
+
|
4
|
+
module ObservableArray
|
5
|
+
|
6
|
+
def add_observer(element_properties, observer)
|
7
|
+
property_observer_list << observer
|
8
|
+
each do |element|
|
9
|
+
element_properties.each do |property|
|
10
|
+
element.extend(ObservableModel) unless element.is_a?(ObservableModel)
|
11
|
+
element.add_observer(property, observer)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def property_observer_list
|
17
|
+
@property_observer_list = [] unless @property_observer_list
|
18
|
+
@property_observer_list
|
19
|
+
end
|
20
|
+
|
21
|
+
def notify_observers
|
22
|
+
property_observer_list.each {|observer| observer.update}
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.extend_object(array)
|
26
|
+
array.instance_eval("alias original_add <<")
|
27
|
+
array.instance_eval "def <<(value) \n self.original_add(value); notify_observers; \nend"
|
28
|
+
|
29
|
+
notify_observers_on_invokation(array, "delete", 1)
|
30
|
+
notify_observers_on_invokation(array, "delete_at", 1)
|
31
|
+
notify_observers_on_invokation(array, "clear")
|
32
|
+
|
33
|
+
super
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.notify_observers_on_invokation(model, method, argument_count=0)
|
37
|
+
model.instance_eval "alias original_#{method} #{method}\n"
|
38
|
+
arguments = ""
|
39
|
+
for index in 1..argument_count
|
40
|
+
arguments += "argument" + index.to_s + ","
|
41
|
+
end
|
42
|
+
arguments = arguments[0..-2]
|
43
|
+
model.instance_eval "def #{method}(#{arguments}) \n self.original_#{method}(#{arguments}); notify_observers; \nend"
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# Copyright (C) 2007-2008 Annas Al Maleh
|
2
|
+
# Licensed under the LGPL. See /COPYING.LGPL for more details.
|
3
|
+
|
4
|
+
module ObservableModel
|
5
|
+
|
6
|
+
def add_observer(property_name, observer)
|
7
|
+
property_observer_list(property_name) << observer
|
8
|
+
end
|
9
|
+
|
10
|
+
def property_observer_hash
|
11
|
+
@property_observers = Hash.new unless @property_observers
|
12
|
+
@property_observers
|
13
|
+
end
|
14
|
+
|
15
|
+
def property_observer_list(property_name)
|
16
|
+
property_observer_hash[property_name.to_sym] = [] unless property_observer_hash[property_name.to_sym]
|
17
|
+
property_observer_hash[property_name.to_sym]
|
18
|
+
end
|
19
|
+
|
20
|
+
def notify_observers(property_name)
|
21
|
+
property_observer_list(property_name).each {|observer| observer.update(send(property_name))}
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.extend_object(model)
|
25
|
+
super
|
26
|
+
model.methods.each do |method|
|
27
|
+
setter_method_pattern = /^\w+=$/
|
28
|
+
if (method.match(setter_method_pattern))
|
29
|
+
getter_method = method[0, method.length - 1]
|
30
|
+
model.instance_eval "alias original_#{method} #{method}\n"
|
31
|
+
model.instance_eval "def #{method}(value) \n self.original_#{method}(value); notify_observers('#{getter_method}'); \nend"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Copyright (C) 2007-2008 Annas Al Maleh
|
2
|
+
# Licensed under the LGPL. See /COPYING.LGPL for more details.
|
3
|
+
|
4
|
+
require File.dirname(__FILE__) + "/r_widget"
|
5
|
+
|
6
|
+
class RShell < RWidget
|
7
|
+
include_package 'org.eclipse.swt.layout'
|
8
|
+
include_package 'org.eclipse.swt.widgets'
|
9
|
+
|
10
|
+
attr_reader :display
|
11
|
+
|
12
|
+
def initialize(display = Display.new)
|
13
|
+
@display = display
|
14
|
+
@widget = Shell.new(@display)
|
15
|
+
@widget.setLayout(FillLayout.new)
|
16
|
+
end
|
17
|
+
|
18
|
+
def open
|
19
|
+
@widget.pack
|
20
|
+
@widget.open
|
21
|
+
until @widget.isDisposed
|
22
|
+
@display.sleep unless @display.readAndDispatch
|
23
|
+
end
|
24
|
+
@display.dispose
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# Copyright (C) 2007-2008 Annas Al Maleh
|
2
|
+
# Licensed under the LGPL. See /COPYING.LGPL for more details.
|
3
|
+
|
4
|
+
require File.dirname(__FILE__) + "/r_widget_listener"
|
5
|
+
require File.dirname(__FILE__) + "/r_runnable"
|
6
|
+
|
7
|
+
class RWidget
|
8
|
+
require File.dirname(__FILE__) + "/r_widget_packages"
|
9
|
+
|
10
|
+
include Parent
|
11
|
+
|
12
|
+
attr_reader :widget
|
13
|
+
|
14
|
+
#TODO externalize
|
15
|
+
@@default_styles = {
|
16
|
+
"text" => SWT::BORDER,
|
17
|
+
"table" => SWT::BORDER,
|
18
|
+
"spinner" => SWT::BORDER,
|
19
|
+
"button" => SWT::PUSH,
|
20
|
+
}
|
21
|
+
|
22
|
+
#TODO externalize
|
23
|
+
@@default_initializers = {
|
24
|
+
"composite" => Proc.new {|composite| composite.setLayout(GridLayout.new) },
|
25
|
+
"table" => Proc.new do |table|
|
26
|
+
table.setHeaderVisible(true)
|
27
|
+
table.setLinesVisible(true)
|
28
|
+
end,
|
29
|
+
"table_column" => Proc.new { |table_column| table_column.setWidth(80) },
|
30
|
+
"group" => Proc.new {|group| group.setLayout(GridLayout.new) },
|
31
|
+
}
|
32
|
+
|
33
|
+
def initialize(underscored_widget_name, parent, style, &contents)
|
34
|
+
style = default_style(underscored_widget_name) unless style
|
35
|
+
@widget = eval underscored_widget_name.to_s.camelcase(true) + '.new(parent, style)'
|
36
|
+
@@default_initializers[underscored_widget_name].call(@widget) if @@default_initializers[underscored_widget_name]
|
37
|
+
end
|
38
|
+
|
39
|
+
def default_style(underscored_widget_name)
|
40
|
+
style = @@default_styles[underscored_widget_name] if @@default_styles[underscored_widget_name]
|
41
|
+
style = SWT::NONE unless style
|
42
|
+
style
|
43
|
+
end
|
44
|
+
|
45
|
+
def respond_to?(method_symbol, *args)
|
46
|
+
@widget.respond_to?("set" + method_symbol.to_s.camelcase(true), args)
|
47
|
+
end
|
48
|
+
|
49
|
+
def method_missing(method_symbol, *args)
|
50
|
+
statement_to_eval = "@widget.send('set' + method_symbol.to_s.camelcase(true)"
|
51
|
+
statement_to_eval << expand_arguments(args)
|
52
|
+
statement_to_eval << ")"
|
53
|
+
eval statement_to_eval
|
54
|
+
end
|
55
|
+
|
56
|
+
def expand_arguments(args)
|
57
|
+
expanded_args = ""
|
58
|
+
index = 0
|
59
|
+
args.each do
|
60
|
+
expanded_args << ", args[#{index}]"
|
61
|
+
index += 1
|
62
|
+
end
|
63
|
+
expanded_args
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.widget_exists?(underscored_widget_name)
|
67
|
+
begin
|
68
|
+
eval underscored_widget_name.camelcase(true)
|
69
|
+
true
|
70
|
+
rescue NameError
|
71
|
+
false
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def widget_listener_exists?(underscored_listener_name)
|
76
|
+
listener_method_name = underscored_listener_name.camelcase()
|
77
|
+
@widget.getClass.getMethods.each do |widget_method|
|
78
|
+
if widget_method.getName.match(/add.*Listener/)
|
79
|
+
widget_method.getParameterTypes.each do |listener_type|
|
80
|
+
listener_type.getMethods.each do |listener_method|
|
81
|
+
if (listener_method.getName.match(listener_method_name))
|
82
|
+
return true
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
return false
|
89
|
+
end
|
90
|
+
|
91
|
+
def can_add_listener?(underscored_listener_name)
|
92
|
+
listener_method_name = underscored_listener_name.camelcase()
|
93
|
+
@widget.getClass.getMethods.each do |widget_method|
|
94
|
+
if widget_method.getName.match(/add.*Listener/)
|
95
|
+
widget_method.getParameterTypes.each do |listener_type|
|
96
|
+
listener_type.getMethods.each do |listener_method|
|
97
|
+
if (listener_method.getName.match(listener_method_name))
|
98
|
+
return true
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
return false
|
105
|
+
end
|
106
|
+
|
107
|
+
def add_listener(underscored_listener_name, &block)
|
108
|
+
listener_method_name = underscored_listener_name.camelcase()
|
109
|
+
@widget.getClass.getMethods.each do |widget_method|
|
110
|
+
if widget_method.getName.match(/add.*Listener/)
|
111
|
+
widget_method.getParameterTypes.each do |listener_type|
|
112
|
+
listener_type.getMethods.each do |listener_method|
|
113
|
+
if (listener_method.getName.match(listener_method_name))
|
114
|
+
listener_class = Class.new(Object)
|
115
|
+
listener_class.send :include, (eval listener_type.to_s)
|
116
|
+
listener = listener_class.new
|
117
|
+
listener_type.getMethods.each do |t_method|
|
118
|
+
eval "def listener.#{t_method.getName}(event) end"
|
119
|
+
end
|
120
|
+
def listener.block=(block)
|
121
|
+
@block = block
|
122
|
+
end
|
123
|
+
listener.block=block
|
124
|
+
eval "def listener.#{listener_method.getName}(event) @block.call(event) if @block end"
|
125
|
+
@widget.send(widget_method.getName, listener)
|
126
|
+
return RWidgetListener.new(listener)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def process_block(block)
|
135
|
+
block.call(@widget)
|
136
|
+
end
|
137
|
+
|
138
|
+
def async_exec(&block)
|
139
|
+
@widget.getDisplay.asyncExec(RRunnable.new(&block))
|
140
|
+
end
|
141
|
+
|
142
|
+
def sync_exec(&block)
|
143
|
+
@widget.getDisplay.syncExec(RRunnable.new(&block))
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|