glimmer 0.4.8 → 0.4.9
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.
- 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
|