glimmer 0.4.8 → 0.4.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.markdown +237 -94
- data/bin/girb_runner.rb +2 -0
- data/lib/glimmer.rb +1 -0
- data/lib/glimmer/command_handler.rb +5 -0
- data/lib/glimmer/command_handler_chain_link.rb +5 -4
- data/lib/glimmer/command_handlers.rb +2 -0
- data/lib/glimmer/swt/command_handlers/custom_widget_command_handler.rb +4 -2
- data/lib/glimmer/swt/command_handlers/data_binding_command_handler.rb +0 -1
- data/lib/glimmer/swt/command_handlers/observe_command_handler.rb +35 -0
- data/lib/glimmer/swt/command_handlers/property_command_handler.rb +4 -4
- data/lib/glimmer/swt/command_handlers/widget_listener_command_handler.rb +12 -9
- data/lib/glimmer/swt/custom_shell.rb +45 -0
- data/lib/glimmer/swt/custom_widget.rb +73 -9
- data/lib/glimmer/swt/g_display.rb +8 -0
- data/lib/glimmer/swt/g_font.rb +3 -7
- data/lib/glimmer/swt/g_layout.rb +1 -1
- data/lib/glimmer/swt/g_layout_data.rb +1 -1
- data/lib/glimmer/swt/g_shell.rb +57 -5
- data/lib/glimmer/swt/g_widget.rb +111 -28
- data/lib/glimmer/swt/list_selection_binding.rb +3 -5
- data/lib/glimmer/swt/model_binding.rb +10 -22
- data/lib/glimmer/swt/observable_array.rb +2 -2
- data/lib/glimmer/swt/observable_model.rb +4 -6
- data/lib/glimmer/swt/observer.rb +23 -25
- data/lib/glimmer/swt/table_items_binding.rb +3 -5
- data/lib/glimmer/swt/tree_items_binding.rb +3 -5
- data/lib/glimmer/swt/widget_binding.rb +3 -5
- data/lib/glimmer/swt_packages.rb +1 -0
- data/lib/glimmer/xml/node.rb +1 -1
- metadata +18 -2
data/bin/girb_runner.rb
CHANGED
data/lib/glimmer.rb
CHANGED
@@ -8,6 +8,7 @@ require "facets"
|
|
8
8
|
require "super_module"
|
9
9
|
require "logger"
|
10
10
|
require "java"
|
11
|
+
require "nested_inherited_jruby_include_package"
|
11
12
|
require_relative "glimmer/parent"
|
12
13
|
require_relative "glimmer/swt_packages" #TODO move into SWT namespace
|
13
14
|
require_relative "glimmer/swt/custom_widget"
|
@@ -1,8 +1,13 @@
|
|
1
1
|
module Glimmer
|
2
|
+
# rename to keyword handler
|
3
|
+
|
2
4
|
module CommandHandler
|
3
5
|
def can_handle?(parent, command_symbol, *args, &block)
|
4
6
|
raise "must be implemented by a class"
|
5
7
|
end
|
8
|
+
|
9
|
+
# TODO rename do_handle to just handle
|
10
|
+
|
6
11
|
def do_handle(parent, command_symbol, *args, &block)
|
7
12
|
raise "must be implemented by a class"
|
8
13
|
end
|
@@ -14,10 +14,11 @@ module Glimmer
|
|
14
14
|
return @next_chain_link.handle(parent, command_symbol, *args, &block)
|
15
15
|
else
|
16
16
|
# TODO see if we need a better response here (e.g. dev mode error raising vs production mode silent failure)
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
message = "Glimmer keyword #{command_symbol} with args #{args} cannot be handled"
|
18
|
+
message += " inside parent #{parent.inspect}" if parent
|
19
|
+
message += "! Check the validity of the code."
|
20
|
+
# Glimmer.logger.error message
|
21
|
+
raise message
|
21
22
|
end
|
22
23
|
end
|
23
24
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative "command_handler_chain_factory"
|
2
|
+
require_relative "swt/command_handlers/observe_command_handler"
|
2
3
|
require_relative "swt/command_handlers/color_command_handler"
|
3
4
|
require_relative "swt/command_handlers/display_command_handler"
|
4
5
|
require_relative "swt/command_handlers/shell_command_handler"
|
@@ -22,6 +23,7 @@ require_relative "swt/command_handlers/custom_widget_command_handler"
|
|
22
23
|
module Glimmer
|
23
24
|
# edit to add more command handlers and extend Glimmer
|
24
25
|
CommandHandlerChainFactory.def_dsl(:swt,
|
26
|
+
SWT::CommandHandlers::ObserveCommandHandler.new,
|
25
27
|
SWT::CommandHandlers::DisplayCommandHandler.new,
|
26
28
|
SWT::CommandHandlers::ShellCommandHandler.new,
|
27
29
|
SWT::CommandHandlers::LayoutDataCommandHandler.new,
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require File.dirname(__FILE__) + "/../../command_handler"
|
2
2
|
require File.dirname(__FILE__) + "/../custom_widget"
|
3
|
+
require File.dirname(__FILE__) + "/../custom_shell"
|
3
4
|
require File.dirname(__FILE__) + "/../g_widget"
|
4
5
|
|
5
6
|
module Glimmer
|
@@ -9,8 +10,9 @@ module Glimmer
|
|
9
10
|
include CommandHandler
|
10
11
|
|
11
12
|
def can_handle?(parent, command_symbol, *args, &block)
|
12
|
-
|
13
|
-
|
13
|
+
custom_widget_class = CustomWidget.for(command_symbol)
|
14
|
+
custom_widget_class and
|
15
|
+
(parent.is_a?(GWidget) || parent.is_a?(CustomWidget) || custom_widget_class.ancestors.include?(CustomShell))
|
14
16
|
end
|
15
17
|
|
16
18
|
def do_handle(parent, command_symbol, *args, &block)
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../../command_handler"
|
2
|
+
|
3
|
+
module Glimmer
|
4
|
+
module SWT
|
5
|
+
module CommandHandlers
|
6
|
+
class ObserveCommandHandler
|
7
|
+
REGEX_NESTED_OR_INDEXED_PROPERTY = /([^\[]+)(\[[^\]]+\])?/
|
8
|
+
include CommandHandler
|
9
|
+
|
10
|
+
def can_handle?(parent, command_symbol, *args, &block)
|
11
|
+
command_symbol.to_s == "observe" and
|
12
|
+
(
|
13
|
+
(
|
14
|
+
(args.size == 2) and
|
15
|
+
(
|
16
|
+
args[1].is_a?(Symbol) or
|
17
|
+
args[1].is_a?(String)
|
18
|
+
)
|
19
|
+
)
|
20
|
+
) and
|
21
|
+
!block.nil?
|
22
|
+
end
|
23
|
+
|
24
|
+
def do_handle(parent, command_symbol, *args, &block)
|
25
|
+
observer = Observer.proc(&block)
|
26
|
+
if args[1].to_s.match(REGEX_NESTED_OR_INDEXED_PROPERTY)
|
27
|
+
observer.observe(ModelBinding.new(args[0], args[1]))
|
28
|
+
else
|
29
|
+
observer.observe(args[0], args[1])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -8,10 +8,10 @@ module Glimmer
|
|
8
8
|
|
9
9
|
def can_handle?(parent, command_symbol, *args, &block)
|
10
10
|
parent.respond_to?(:set_attribute) and
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
parent.respond_to?(:has_attribute?) and
|
12
|
+
args.size > 0 and
|
13
|
+
block == nil and
|
14
|
+
parent.has_attribute?(command_symbol, *args)
|
15
15
|
end
|
16
16
|
|
17
17
|
def do_handle(parent, command_symbol, *args, &block)
|
@@ -5,6 +5,8 @@ require File.dirname(__FILE__) + "/../custom_widget"
|
|
5
5
|
module Glimmer
|
6
6
|
module SWT
|
7
7
|
module CommandHandlers
|
8
|
+
# TODO rename to observation command handler (or keyword handler)
|
9
|
+
|
8
10
|
class WidgetListenerCommandHandler
|
9
11
|
include CommandHandler
|
10
12
|
|
@@ -14,18 +16,19 @@ module Glimmer
|
|
14
16
|
widget_parentage = (parent.is_a?(GWidget) || parent.is_a?(CustomWidget))
|
15
17
|
Glimmer.logger.debug "parent is a widget: #{widget_parentage}"
|
16
18
|
return unless widget_parentage
|
17
|
-
Glimmer.logger.debug "
|
18
|
-
return unless command_symbol.to_s
|
19
|
-
Glimmer.logger.debug "
|
20
|
-
return unless
|
21
|
-
Glimmer.logger.debug "
|
22
|
-
return unless
|
23
|
-
|
24
|
-
|
19
|
+
Glimmer.logger.debug "keyword starts with on_: #{command_symbol.to_s.start_with?('on_')}"
|
20
|
+
return unless command_symbol.to_s.start_with?('on_')
|
21
|
+
Glimmer.logger.debug "args are empty?: #{args.empty?}"
|
22
|
+
return unless args.empty?
|
23
|
+
Glimmer.logger.debug "block exists?: #{!block.nil?}"
|
24
|
+
return unless !block.nil?
|
25
|
+
result = parent.can_handle_observation_request?(command_symbol.to_s)
|
26
|
+
Glimmer.logger.debug "can add listener? #{result}"
|
27
|
+
result
|
25
28
|
end
|
26
29
|
|
27
30
|
def do_handle(parent, command_symbol, *args, &block)
|
28
|
-
parent.
|
31
|
+
parent.handle_observation_request(command_symbol.to_s, &block)
|
29
32
|
ListenerParent.new #TODO refactor and move to models
|
30
33
|
end
|
31
34
|
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'super_module'
|
2
|
+
|
3
|
+
module Glimmer
|
4
|
+
module SWT
|
5
|
+
module CustomShell
|
6
|
+
include SuperModule
|
7
|
+
include Glimmer::SWT::CustomWidget
|
8
|
+
|
9
|
+
def initialize(parent, *swt_constants, options, &content)
|
10
|
+
super
|
11
|
+
raise 'Invalid custom shell body root! Must be a shell or another custom shell.' unless body_root.is_a?(GShell) || body_root.is_a?(CustomShell)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Classes may override
|
15
|
+
def open
|
16
|
+
body_root.open
|
17
|
+
end
|
18
|
+
|
19
|
+
# DO NOT OVERRIDE. JUST AN ALIAS FOR `#open`. OVERRIDE `#open` INSTEAD.
|
20
|
+
def show
|
21
|
+
open
|
22
|
+
end
|
23
|
+
|
24
|
+
def close
|
25
|
+
body_root.close
|
26
|
+
end
|
27
|
+
|
28
|
+
def hide
|
29
|
+
body_root.hide
|
30
|
+
end
|
31
|
+
|
32
|
+
def visible?
|
33
|
+
body_root.visible?
|
34
|
+
end
|
35
|
+
|
36
|
+
def center
|
37
|
+
body_root.center
|
38
|
+
end
|
39
|
+
|
40
|
+
def start_event_loop
|
41
|
+
body_root.start_event_loop
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -58,6 +58,16 @@ module Glimmer
|
|
58
58
|
end_eval
|
59
59
|
end
|
60
60
|
end
|
61
|
+
|
62
|
+
def before_body(&block)
|
63
|
+
@before_body_blocks ||= []
|
64
|
+
@before_body_blocks << block
|
65
|
+
end
|
66
|
+
|
67
|
+
def after_body(&block)
|
68
|
+
@after_body_blocks ||= []
|
69
|
+
@after_body_blocks << block
|
70
|
+
end
|
61
71
|
end
|
62
72
|
|
63
73
|
attr_reader :body_root, :widget, :parent, :swt_style, :options, :content
|
@@ -68,7 +78,9 @@ module Glimmer
|
|
68
78
|
options ||= {}
|
69
79
|
@options = self.class.options.merge(options)
|
70
80
|
@content = ProcTracker.new(content) if content
|
81
|
+
execute_hooks('before_body')
|
71
82
|
@body_root = body
|
83
|
+
execute_hooks('after_body')
|
72
84
|
@widget = @body_root.widget
|
73
85
|
end
|
74
86
|
|
@@ -76,16 +88,26 @@ module Glimmer
|
|
76
88
|
raise 'Not implemented!'
|
77
89
|
end
|
78
90
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
91
|
+
def can_handle_observation_request?(observation_request)
|
92
|
+
result = false
|
93
|
+
if observation_request.start_with?('on_updated_')
|
94
|
+
property = observation_request.sub(/^on_updated_/, '')
|
95
|
+
result = can_add_observer?(property)
|
96
|
+
end
|
97
|
+
result || body_root&.can_handle_observation_request?(observation_request)
|
83
98
|
end
|
84
99
|
|
85
|
-
|
100
|
+
def handle_observation_request(observation_request, &block)
|
101
|
+
if observation_request.start_with?('on_updated_')
|
102
|
+
property = observation_request.sub(/^on_updated_/, '')
|
103
|
+
add_observer(Observer::Proc.new(&block), property) if can_add_observer?(property)
|
104
|
+
else
|
105
|
+
body_root.handle_observation_request(observation_request, &block)
|
106
|
+
end
|
107
|
+
end
|
86
108
|
|
87
|
-
def
|
88
|
-
@body_root.
|
109
|
+
def can_add_observer?(attribute_name)
|
110
|
+
respond_to?(attribute_name) || @body_root.can_add_observer?(attribute_name)
|
89
111
|
end
|
90
112
|
|
91
113
|
def add_observer(observer, attribute_name)
|
@@ -121,11 +143,53 @@ module Glimmer
|
|
121
143
|
"#{attribute_name}="
|
122
144
|
end
|
123
145
|
|
146
|
+
# TODO see if it is worth it to eliminate duplication of method_missing
|
147
|
+
# from GWidget using a module
|
148
|
+
|
149
|
+
def method_missing(method, *args, &block)
|
150
|
+
method_name = method.to_s
|
151
|
+
if can_handle_observation_request?(method_name)
|
152
|
+
handle_observation_request(method_name, &block)
|
153
|
+
else
|
154
|
+
super
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
124
158
|
def process_block(block)
|
125
159
|
if block.source_location == @content&.__getobj__.source_location
|
126
|
-
@content.call unless @content.called?
|
160
|
+
@content.call(self) unless @content.called?
|
127
161
|
else
|
128
|
-
block.call
|
162
|
+
block.call(self)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def has_style?(style)
|
167
|
+
(swt_style & GSWT[style]) == GSWT[style]
|
168
|
+
end
|
169
|
+
|
170
|
+
# TODO see if it is worth it to eliminate duplication of async_exec/sync_exec
|
171
|
+
# delegation to GDisplay, via a module
|
172
|
+
|
173
|
+
def async_exec(&block)
|
174
|
+
GDisplay.instance.async_exec(&block)
|
175
|
+
end
|
176
|
+
|
177
|
+
def sync_exec(&block)
|
178
|
+
GDisplay.instance.sync_exec(&block)
|
179
|
+
end
|
180
|
+
|
181
|
+
def add_content(&block)
|
182
|
+
body_root.add_content(&block)
|
183
|
+
end
|
184
|
+
|
185
|
+
private
|
186
|
+
|
187
|
+
def execute_hooks(hook_name)
|
188
|
+
self.class.instance_variable_get("@#{hook_name}_blocks")&.each_with_index do |hook_block, i|
|
189
|
+
hook_block_number = i + 1
|
190
|
+
self.class.define_method("__#{hook_name}#{hook_block_number}", hook_block)
|
191
|
+
send("__#{hook_name}#{hook_block_number}")
|
192
|
+
self.class.send(:undef_method, "__#{hook_name}#{hook_block_number}")
|
129
193
|
end
|
130
194
|
end
|
131
195
|
end
|
data/lib/glimmer/swt/g_font.rb
CHANGED
@@ -7,8 +7,6 @@ module Glimmer
|
|
7
7
|
FONT_STYLES = [:normal, :bold, :italic]
|
8
8
|
include_package 'org.eclipse.swt.graphics'
|
9
9
|
|
10
|
-
extend Glimmer
|
11
|
-
|
12
10
|
attr_reader :g_widget
|
13
11
|
attr_accessor :display
|
14
12
|
|
@@ -17,11 +15,9 @@ module Glimmer
|
|
17
15
|
@instances ||= {}
|
18
16
|
unless @instances[g_widget]
|
19
17
|
@instances[g_widget] = new(g_widget)
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
}
|
24
|
-
}
|
18
|
+
g_widget.on_widget_disposed do |dispose_event|
|
19
|
+
@instances.delete(g_widget)
|
20
|
+
end
|
25
21
|
end
|
26
22
|
@instances[g_widget]
|
27
23
|
end
|
data/lib/glimmer/swt/g_layout.rb
CHANGED
data/lib/glimmer/swt/g_shell.rb
CHANGED
@@ -10,7 +10,8 @@ module Glimmer
|
|
10
10
|
include_package 'org.eclipse.swt.layout'
|
11
11
|
include_package 'org.eclipse.swt.widgets'
|
12
12
|
|
13
|
-
attr_reader :display
|
13
|
+
attr_reader :display, :opened_before
|
14
|
+
alias opened_before? opened_before
|
14
15
|
|
15
16
|
# Instantiates shell with same arguments expected by SWT Shell
|
16
17
|
def initialize(*args)
|
@@ -37,10 +38,44 @@ module Glimmer
|
|
37
38
|
|
38
39
|
# Opens shell and starts SWT's UI thread event loop
|
39
40
|
def open
|
40
|
-
@
|
41
|
-
|
42
|
-
|
43
|
-
|
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
|
44
79
|
end
|
45
80
|
|
46
81
|
def start_event_loop
|
@@ -49,6 +84,23 @@ module Glimmer
|
|
49
84
|
end
|
50
85
|
@display.dispose
|
51
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
|
52
104
|
end
|
53
105
|
end
|
54
106
|
end
|