glimmer 0.1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|