glimmer 0.7.4 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/{README.markdown → README.md} +210 -104
- data/VERSION +1 -1
- data/lib/glimmer/data_binding/table_items_binding.rb +1 -0
- data/lib/glimmer/data_binding/tree_items_binding.rb +30 -12
- data/lib/glimmer/dsl/swt/dialog_expression.rb +26 -0
- data/lib/glimmer/launcher.rb +18 -10
- data/lib/glimmer/rake_task.rb +3 -3
- data/lib/glimmer/scaffold.rb +208 -68
- data/lib/glimmer/swt/display_proxy.rb +14 -0
- data/lib/glimmer/swt/menu_proxy.rb +17 -0
- data/lib/glimmer/swt/shell_proxy.rb +1 -26
- data/lib/glimmer/swt/tab_item_proxy.rb +6 -0
- data/lib/glimmer/swt/tree_proxy.rb +97 -1
- data/lib/glimmer/swt/widget_listener_proxy.rb +21 -4
- data/lib/glimmer/swt/widget_proxy.rb +46 -25
- data/lib/glimmer/ui/custom_widget.rb +13 -6
- metadata +7 -36
@@ -16,6 +16,8 @@ module Glimmer
|
|
16
16
|
class DisplayProxy
|
17
17
|
include_package 'org.eclipse.swt.widgets'
|
18
18
|
|
19
|
+
OBSERVED_MENU_ITEMS = ['about', 'preferences']
|
20
|
+
|
19
21
|
class << self
|
20
22
|
# Returns singleton instance
|
21
23
|
def instance(*args)
|
@@ -52,6 +54,9 @@ module Glimmer
|
|
52
54
|
if observation_request.start_with?('on_event_')
|
53
55
|
constant_name = observation_request.sub(/^on_event_/, '')
|
54
56
|
SWTProxy.has_constant?(constant_name)
|
57
|
+
elsif observation_request.start_with?('on_')
|
58
|
+
event_name = observation_request.sub(/^on_/, '')
|
59
|
+
OBSERVED_MENU_ITEMS.include?(event_name)
|
55
60
|
else
|
56
61
|
false
|
57
62
|
end
|
@@ -61,6 +66,15 @@ module Glimmer
|
|
61
66
|
if observation_request.start_with?('on_event_')
|
62
67
|
constant_name = observation_request.sub(/^on_event_/, '')
|
63
68
|
add_swt_event_listener(constant_name, &block)
|
69
|
+
elsif observation_request.start_with?('on_')
|
70
|
+
event_name = observation_request.sub(/^on_/, '')
|
71
|
+
if OBSERVED_MENU_ITEMS.include?(event_name)
|
72
|
+
if OS.mac?
|
73
|
+
system_menu = swt_display.getSystemMenu
|
74
|
+
menu_item = system_menu.getItems.find {|menu_item| menu_item.getID == SWTProxy["ID_#{event_name.upcase}"]}
|
75
|
+
menu_item.addListener(SWTProxy[:Selection], &block)
|
76
|
+
end
|
77
|
+
end
|
64
78
|
end
|
65
79
|
end
|
66
80
|
|
@@ -79,6 +79,23 @@ module Glimmer
|
|
79
79
|
super(attribute_name)
|
80
80
|
end
|
81
81
|
end
|
82
|
+
|
83
|
+
def can_handle_observation_request?(observation_request, super_only: false)
|
84
|
+
super_result = super(observation_request)
|
85
|
+
if observation_request.start_with?('on_') && !super_result && !super_only
|
86
|
+
return menu_item_proxy.can_handle_observation_request?(observation_request)
|
87
|
+
else
|
88
|
+
super_result
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def handle_observation_request(observation_request, &block)
|
93
|
+
if can_handle_observation_request?(observation_request, super_only: true)
|
94
|
+
super
|
95
|
+
else
|
96
|
+
menu_item_proxy.handle_observation_request(observation_request, &block)
|
97
|
+
end
|
98
|
+
end
|
82
99
|
end
|
83
100
|
end
|
84
101
|
end
|
@@ -14,7 +14,6 @@ module Glimmer
|
|
14
14
|
|
15
15
|
WIDTH_MIN = 130
|
16
16
|
HEIGHT_MIN = 0
|
17
|
-
OBSERVED_MENU_ITEMS = ['about', 'preferences']
|
18
17
|
|
19
18
|
attr_reader :opened_before
|
20
19
|
alias opened_before? opened_before
|
@@ -47,7 +46,7 @@ module Glimmer
|
|
47
46
|
Thread.new do
|
48
47
|
sleep(0.25)
|
49
48
|
async_exec do
|
50
|
-
@swt_widget.setActive
|
49
|
+
@swt_widget.setActive unless @swt_widget.isDisposed
|
51
50
|
end
|
52
51
|
end
|
53
52
|
end
|
@@ -128,30 +127,6 @@ module Glimmer
|
|
128
127
|
end
|
129
128
|
end
|
130
129
|
|
131
|
-
def can_handle_observation_request?(observation_request)
|
132
|
-
result = false
|
133
|
-
if observation_request.start_with?('on_')
|
134
|
-
event_name = observation_request.sub(/^on_/, '')
|
135
|
-
result = OBSERVED_MENU_ITEMS.include?(event_name)
|
136
|
-
end
|
137
|
-
result || super
|
138
|
-
end
|
139
|
-
|
140
|
-
def handle_observation_request(observation_request, &block)
|
141
|
-
if observation_request.start_with?('on_')
|
142
|
-
event_name = observation_request.sub(/^on_/, '')
|
143
|
-
if OBSERVED_MENU_ITEMS.include?(event_name)
|
144
|
-
if OS.mac?
|
145
|
-
system_menu = DisplayProxy.instance.swt_display.getSystemMenu
|
146
|
-
menu_item = system_menu.getItems.find {|menu_item| menu_item.getID == SWTProxy["ID_#{event_name.upcase}"]}
|
147
|
-
menu_item.addListener(SWTProxy[:Selection], &block)
|
148
|
-
end
|
149
|
-
else
|
150
|
-
super
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
130
|
def add_observer(observer, property_name)
|
156
131
|
case property_name.to_s
|
157
132
|
when 'visible?' #TODO see if you must handle non-? version and/or move elsewhere
|
@@ -3,22 +3,118 @@ require 'glimmer/swt/widget_proxy'
|
|
3
3
|
module Glimmer
|
4
4
|
module SWT
|
5
5
|
class TreeProxy < Glimmer::SWT::WidgetProxy
|
6
|
+
include Glimmer
|
7
|
+
|
8
|
+
attr_reader :tree_editor, :tree_editor_text_proxy
|
9
|
+
attr_accessor :tree_properties
|
10
|
+
|
11
|
+
def initialize(underscored_widget_name, parent, args)
|
12
|
+
super
|
13
|
+
@tree_editor = TreeEditor.new(swt_widget)
|
14
|
+
@tree_editor.horizontalAlignment = SWTProxy[:left]
|
15
|
+
@tree_editor.grabHorizontal = true
|
16
|
+
@tree_editor.minimumHeight = 20
|
17
|
+
end
|
18
|
+
|
6
19
|
# Performs depth first search for tree items matching block condition
|
7
|
-
#
|
20
|
+
# If no condition block is passed, returns all tree items
|
21
|
+
# Returns a Java TreeItem array to easily set as selection on org.eclipse.swt.Tree if needed
|
8
22
|
def depth_first_search(&condition)
|
9
23
|
found = []
|
10
24
|
recursive_depth_first_search(swt_widget.getItems.first, found, &condition)
|
11
25
|
found.to_java(TreeItem)
|
12
26
|
end
|
27
|
+
|
28
|
+
# Returns all tree items including descendants
|
29
|
+
def all_tree_items
|
30
|
+
depth_first_search
|
31
|
+
end
|
13
32
|
|
33
|
+
def widget_property_listener_installers
|
34
|
+
super.merge({
|
35
|
+
Java::OrgEclipseSwtWidgets::Tree => {
|
36
|
+
selection: lambda do |observer|
|
37
|
+
on_widget_selected { |selection_event|
|
38
|
+
observer.call(@swt_widget.getSelection)
|
39
|
+
}
|
40
|
+
end
|
41
|
+
},
|
42
|
+
})
|
43
|
+
end
|
44
|
+
|
45
|
+
def edit_in_progress?
|
46
|
+
!!@edit_in_progress
|
47
|
+
end
|
48
|
+
|
49
|
+
def edit_selected_tree_item(before_write: nil, after_write: nil, after_cancel: nil)
|
50
|
+
edit_tree_item(swt_widget.getSelection.first, before_write: before_write, after_write: after_write, after_cancel: after_cancel)
|
51
|
+
end
|
52
|
+
|
53
|
+
def edit_tree_item(tree_item, before_write: nil, after_write: nil, after_cancel: nil)
|
54
|
+
return if tree_item.nil?
|
55
|
+
content {
|
56
|
+
@tree_editor_text_proxy = text {
|
57
|
+
focus true
|
58
|
+
text tree_item.getText
|
59
|
+
action_taken = false
|
60
|
+
cancel = lambda {
|
61
|
+
@tree_editor_text_proxy.swt_widget.dispose
|
62
|
+
@tree_editor_text_proxy = nil
|
63
|
+
after_cancel&.call
|
64
|
+
@edit_in_progress = false
|
65
|
+
}
|
66
|
+
action = lambda { |event|
|
67
|
+
if !action_taken && !@edit_in_progress
|
68
|
+
action_taken = true
|
69
|
+
@edit_in_progress = true
|
70
|
+
new_text = @tree_editor_text_proxy.swt_widget.getText
|
71
|
+
if new_text == tree_item.getText
|
72
|
+
cancel.call
|
73
|
+
else
|
74
|
+
before_write&.call
|
75
|
+
tree_item.setText(new_text)
|
76
|
+
model = tree_item.getData
|
77
|
+
model.send("#{tree_properties[:text]}=", new_text) # makes tree update itself, so must search for selected tree item again
|
78
|
+
edited_tree_item = depth_first_search { |ti| ti.getData == model }.first
|
79
|
+
swt_widget.showItem(edited_tree_item)
|
80
|
+
@tree_editor_text_proxy.swt_widget.dispose
|
81
|
+
@tree_editor_text_proxy = nil
|
82
|
+
after_write&.call(edited_tree_item)
|
83
|
+
@edit_in_progress = false
|
84
|
+
end
|
85
|
+
end
|
86
|
+
}
|
87
|
+
on_focus_lost(&action)
|
88
|
+
on_key_pressed { |key_event|
|
89
|
+
if key_event.keyCode == swt(:cr)
|
90
|
+
action.call(key_event)
|
91
|
+
elsif key_event.keyCode == swt(:esc)
|
92
|
+
cancel.call
|
93
|
+
end
|
94
|
+
}
|
95
|
+
}
|
96
|
+
@tree_editor_text_proxy.swt_widget.selectAll
|
97
|
+
}
|
98
|
+
@tree_editor.setEditor(@tree_editor_text_proxy.swt_widget, tree_item);
|
99
|
+
end
|
100
|
+
|
14
101
|
private
|
15
102
|
|
16
103
|
def recursive_depth_first_search(tree_item, found, &condition)
|
104
|
+
return if tree_item.nil?
|
17
105
|
found << tree_item if condition.nil? || condition.call(tree_item)
|
18
106
|
tree_item.getItems.each do |child_tree_item|
|
19
107
|
recursive_depth_first_search(child_tree_item, found, &condition)
|
20
108
|
end
|
21
109
|
end
|
110
|
+
|
111
|
+
def property_type_converters
|
112
|
+
super.merge({
|
113
|
+
selection: lambda do |value|
|
114
|
+
depth_first_search {|ti| ti.getData == value}
|
115
|
+
end,
|
116
|
+
})
|
117
|
+
end
|
22
118
|
end
|
23
119
|
end
|
24
120
|
end
|
@@ -5,12 +5,29 @@ module Glimmer
|
|
5
5
|
# Follows the Proxy Design Pattern
|
6
6
|
class WidgetListenerProxy
|
7
7
|
|
8
|
-
attr_reader :swt_listener
|
8
|
+
attr_reader :swt_widget, :swt_listener, :widget_add_listener_method, :swt_listener_class, :swt_listener_method, :event_type, :swt_constant
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
def initialize(swt_listener)
|
10
|
+
def initialize(swt_widget:, swt_listener:, widget_add_listener_method: nil, swt_listener_class: nil, swt_listener_method: nil, event_type: nil, swt_constant: nil)
|
11
|
+
@swt_widget = swt_widget
|
13
12
|
@swt_listener = swt_listener
|
13
|
+
@widget_add_listener_method = widget_add_listener_method
|
14
|
+
@swt_listener_class = swt_listener_class
|
15
|
+
@swt_listener_method = swt_listener_method
|
16
|
+
@event_type = event_type
|
17
|
+
@swt_constant = swt_constant
|
18
|
+
end
|
19
|
+
|
20
|
+
def widget_remove_listener_method
|
21
|
+
@widget_add_listener_method.sub('add', 'remove')
|
22
|
+
end
|
23
|
+
|
24
|
+
def unregister
|
25
|
+
# TODO consider renaming to deregister (and in Observer too)
|
26
|
+
if @event_type
|
27
|
+
@swt_widget.removeListener(@event_type, @swt_listener)
|
28
|
+
else
|
29
|
+
@swt_widget.send(widget_remove_listener_method, @swt_listener)
|
30
|
+
end
|
14
31
|
end
|
15
32
|
end
|
16
33
|
end
|
@@ -5,6 +5,8 @@ require 'glimmer/swt/font_proxy'
|
|
5
5
|
require 'glimmer/swt/swt_proxy'
|
6
6
|
require 'glimmer/data_binding/observable_widget'
|
7
7
|
|
8
|
+
# TODO refactor to make file smaller and extract sub-widget-proxies out of this
|
9
|
+
|
8
10
|
module Glimmer
|
9
11
|
module SWT
|
10
12
|
# Proxy for SWT Widget objects
|
@@ -23,6 +25,7 @@ module Glimmer
|
|
23
25
|
DEFAULT_STYLES = {
|
24
26
|
"text" => [:border],
|
25
27
|
"table" => [:border],
|
28
|
+
"tree" => [:virtual, :border, :h_scroll, :v_scroll],
|
26
29
|
"spinner" => [:border],
|
27
30
|
"styled_text" => [:border],
|
28
31
|
"list" => [:border, :v_scroll],
|
@@ -31,17 +34,17 @@ module Glimmer
|
|
31
34
|
}
|
32
35
|
|
33
36
|
DEFAULT_INITIALIZERS = {
|
34
|
-
"composite" =>
|
37
|
+
"composite" => lambda do |composite|
|
35
38
|
composite.setLayout(GridLayout.new)
|
36
39
|
end,
|
37
|
-
"table" =>
|
40
|
+
"table" => lambda do |table|
|
38
41
|
table.setHeaderVisible(true)
|
39
42
|
table.setLinesVisible(true)
|
40
43
|
end,
|
41
|
-
"table_column" =>
|
44
|
+
"table_column" => lambda do |table_column|
|
42
45
|
table_column.setWidth(80)
|
43
46
|
end,
|
44
|
-
"group" =>
|
47
|
+
"group" => lambda do |group|
|
45
48
|
group.setLayout(GridLayout.new)
|
46
49
|
end,
|
47
50
|
}
|
@@ -119,7 +122,7 @@ module Glimmer
|
|
119
122
|
def widget_property_listener_installers
|
120
123
|
@swt_widget_property_listener_installers ||= {
|
121
124
|
Java::OrgEclipseSwtWidgets::Control => {
|
122
|
-
:focus =>
|
125
|
+
:focus => lambda do |observer|
|
123
126
|
on_focus_gained { |focus_event|
|
124
127
|
observer.call(true)
|
125
128
|
}
|
@@ -129,12 +132,12 @@ module Glimmer
|
|
129
132
|
end,
|
130
133
|
},
|
131
134
|
Java::OrgEclipseSwtWidgets::Text => {
|
132
|
-
:text =>
|
135
|
+
:text => lambda do |observer|
|
133
136
|
on_modify_text { |modify_event|
|
134
137
|
observer.call(@swt_widget.getText)
|
135
138
|
}
|
136
139
|
end,
|
137
|
-
:caret_position =>
|
140
|
+
:caret_position => lambda do |observer|
|
138
141
|
on_event_keydown { |event|
|
139
142
|
observer.call(@swt_widget.getCaretPosition)
|
140
143
|
}
|
@@ -148,7 +151,21 @@ module Glimmer
|
|
148
151
|
observer.call(@swt_widget.getCaretPosition)
|
149
152
|
}
|
150
153
|
end,
|
151
|
-
:
|
154
|
+
:selection => lambda do |observer|
|
155
|
+
on_event_keydown { |event|
|
156
|
+
observer.call(@swt_widget.getSelection)
|
157
|
+
}
|
158
|
+
on_event_keyup { |event|
|
159
|
+
observer.call(@swt_widget.getSelection)
|
160
|
+
}
|
161
|
+
on_event_mousedown { |event|
|
162
|
+
observer.call(@swt_widget.getSelection)
|
163
|
+
}
|
164
|
+
on_event_mouseup { |event|
|
165
|
+
observer.call(@swt_widget.getSelection)
|
166
|
+
}
|
167
|
+
end,
|
168
|
+
:selection_count => lambda do |observer|
|
152
169
|
on_event_keydown { |event|
|
153
170
|
observer.call(@swt_widget.getSelectionCount)
|
154
171
|
}
|
@@ -162,7 +179,7 @@ module Glimmer
|
|
162
179
|
observer.call(@swt_widget.getSelectionCount)
|
163
180
|
}
|
164
181
|
end,
|
165
|
-
:top_index =>
|
182
|
+
:top_index => lambda do |observer|
|
166
183
|
@last_top_index = @swt_widget.getTopIndex
|
167
184
|
on_paint_control { |event|
|
168
185
|
if @swt_widget.getTopIndex != @last_top_index
|
@@ -173,33 +190,33 @@ module Glimmer
|
|
173
190
|
end,
|
174
191
|
},
|
175
192
|
Java::OrgEclipseSwtCustom::StyledText => {
|
176
|
-
:text =>
|
193
|
+
:text => lambda do |observer|
|
177
194
|
on_modify_text { |modify_event|
|
178
195
|
observer.call(@swt_widget.getText)
|
179
196
|
}
|
180
197
|
end,
|
181
198
|
},
|
182
199
|
Java::OrgEclipseSwtWidgets::Button => {
|
183
|
-
:selection =>
|
200
|
+
:selection => lambda do |observer|
|
184
201
|
on_widget_selected { |selection_event|
|
185
202
|
observer.call(@swt_widget.getSelection)
|
186
203
|
}
|
187
204
|
end
|
188
205
|
},
|
189
206
|
Java::OrgEclipseSwtWidgets::MenuItem => {
|
190
|
-
:selection =>
|
207
|
+
:selection => lambda do |observer|
|
191
208
|
on_widget_selected { |selection_event|
|
192
209
|
observer.call(@swt_widget.getSelection)
|
193
210
|
}
|
194
211
|
end
|
195
212
|
},
|
196
213
|
Java::OrgEclipseSwtWidgets::Spinner => {
|
197
|
-
:selection =>
|
214
|
+
:selection => lambda do |observer|
|
198
215
|
on_widget_selected { |selection_event|
|
199
216
|
observer.call(@swt_widget.getSelection)
|
200
217
|
}
|
201
218
|
end
|
202
|
-
}
|
219
|
+
},
|
203
220
|
}
|
204
221
|
end
|
205
222
|
|
@@ -321,10 +338,12 @@ module Glimmer
|
|
321
338
|
end
|
322
339
|
|
323
340
|
def add_listener(underscored_listener_name, &block)
|
324
|
-
widget_add_listener_method, listener_class, listener_method = self.class.find_listener(@swt_widget.getClass, underscored_listener_name)
|
325
|
-
|
341
|
+
widget_add_listener_method, listener_class, listener_method = self.class.find_listener(@swt_widget.getClass, underscored_listener_name)
|
342
|
+
widget_listener_proxy = nil
|
343
|
+
safe_block = lambda { |event| block.call(event) unless @swt_widget.isDisposed }
|
344
|
+
listener = listener_class.new(listener_method => safe_block)
|
326
345
|
@swt_widget.send(widget_add_listener_method, listener)
|
327
|
-
WidgetListenerProxy.new(listener)
|
346
|
+
widget_listener_proxy = WidgetListenerProxy.new(swt_widget: @swt_widget, swt_listener: listener, widget_add_listener_method: widget_add_listener_method, swt_listener_class: listener_class, swt_listener_method: listener_method)
|
328
347
|
end
|
329
348
|
|
330
349
|
# Looks through SWT class add***Listener methods till it finds one for which
|
@@ -375,8 +394,10 @@ module Glimmer
|
|
375
394
|
|
376
395
|
def add_swt_event_listener(swt_constant, &block)
|
377
396
|
event_type = SWTProxy[swt_constant]
|
378
|
-
|
379
|
-
|
397
|
+
widget_listener_proxy = nil
|
398
|
+
safe_block = lambda { |event| block.call(event) unless @swt_widget.isDisposed }
|
399
|
+
@swt_widget.addListener(event_type, &safe_block)
|
400
|
+
widget_listener_proxy = WidgetListenerProxy.new(swt_widget: @swt_widget, swt_listener: @swt_widget.getListeners(event_type).last, event_type: event_type, swt_constant: swt_constant)
|
380
401
|
end
|
381
402
|
|
382
403
|
def widget_custom_attribute_mapping
|
@@ -409,7 +430,7 @@ module Glimmer
|
|
409
430
|
end
|
410
431
|
|
411
432
|
def property_type_converters
|
412
|
-
color_converter =
|
433
|
+
color_converter = lambda do |value|
|
413
434
|
if value.is_a?(Symbol) || value.is_a?(String)
|
414
435
|
ColorProxy.new(value).swt_color
|
415
436
|
else
|
@@ -419,7 +440,7 @@ module Glimmer
|
|
419
440
|
# TODO consider detecting type on widget method and automatically invoking right converter (e.g. :to_s for String, :to_i for Integer)
|
420
441
|
@property_type_converters ||= {
|
421
442
|
:background => color_converter,
|
422
|
-
:background_image =>
|
443
|
+
:background_image => lambda do |value|
|
423
444
|
if value.is_a?(String)
|
424
445
|
if value.start_with?('uri:classloader')
|
425
446
|
value = value.sub(/^uri\:classloader\:\//, '')
|
@@ -440,7 +461,7 @@ module Glimmer
|
|
440
461
|
end
|
441
462
|
end,
|
442
463
|
:foreground => color_converter,
|
443
|
-
:font =>
|
464
|
+
:font => lambda do |value|
|
444
465
|
if value.is_a?(Hash)
|
445
466
|
font_properties = value
|
446
467
|
FontProxy.new(self, font_properties).swt_font
|
@@ -448,17 +469,17 @@ module Glimmer
|
|
448
469
|
value
|
449
470
|
end
|
450
471
|
end,
|
451
|
-
:items =>
|
472
|
+
:items => lambda do |value|
|
452
473
|
value.to_java :string
|
453
474
|
end,
|
454
|
-
:text =>
|
475
|
+
:text => lambda do |value|
|
455
476
|
if swt_widget.is_a?(Browser)
|
456
477
|
value.to_s
|
457
478
|
else
|
458
479
|
value.to_s
|
459
480
|
end
|
460
481
|
end,
|
461
|
-
:visible =>
|
482
|
+
:visible => lambda do |value|
|
462
483
|
!!value
|
463
484
|
end,
|
464
485
|
}
|