glimmer 0.7.4 → 0.7.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.markdown +58 -5
- data/VERSION +1 -1
- data/lib/glimmer/data_binding/table_items_binding.rb +1 -0
- data/lib/glimmer/data_binding/tree_items_binding.rb +27 -12
- data/lib/glimmer/launcher.rb +5 -0
- 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 +32 -25
- data/lib/glimmer/ui/custom_widget.rb +4 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 711519083aeec2914eccf820d3c43a799b2f688f04f7ae99403bee8a1bd0985c
|
4
|
+
data.tar.gz: f9121704b98f1f0186be043275873d80c15cd93427b6bfc5580473c379135d0b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cfa41f350b10c401ab3da3bcb8ddd065a53742771b09569f9502c0b57b492637a1d1333ebe8fc1123813772ed016d64130093c5f78518a196b8cf813446dc51b
|
7
|
+
data.tar.gz: 85fae54ea7fdaa91f709bae749725f4b8b2bd3cd6c7c23889e1a812a0f5739f8d659e699fc8cb6d75fb6914bcde1f4ab9ff7145e60150732692d9a9d9d729773
|
data/README.markdown
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
-
# Glimmer 0.7.
|
1
|
+
# Glimmer 0.7.5 Beta (Desktop Development Library for Ruby)
|
2
2
|
[![Gem Version](https://badge.fury.io/rb/glimmer.svg)](http://badge.fury.io/rb/glimmer)
|
3
3
|
[![Coverage Status](https://coveralls.io/repos/github/AndyObtiva/glimmer/badge.svg?branch=master)](https://coveralls.io/github/AndyObtiva/glimmer?branch=master)
|
4
4
|
|
5
5
|
Glimmer is a native-UI cross-platform desktop development library written in Ruby. Glimmer's main innovation is a JRuby DSL that enables productive and efficient authoring of desktop application user-interfaces while relying on the robust Eclipse SWT library. Glimmer additionally innovates by having built-in data-binding support to greatly facilitate synchronizing the UI with domain models. As a result, that achieves true decoupling of object oriented components, enabling developers to solve business problems without worrying about UI concerns, or alternatively drive development UI-first, and then write clean business models test-first afterwards.
|
6
6
|
|
7
|
+
[<img src="https://covers.oreillystatic.com/images/9780596519650/lrg.jpg" width=105 /><br />
|
8
|
+
Featured in<br />JRuby Cookbook](http://shop.oreilly.com/product/9780596519650.do)
|
9
|
+
|
7
10
|
## Examples
|
8
11
|
|
9
12
|
### Hello, World!
|
@@ -71,7 +74,7 @@ NOTE: Glimmer is in beta mode. Please help make better by adopting for small or
|
|
71
74
|
## Table of Contents
|
72
75
|
|
73
76
|
<!-- TOC START min:1 max:3 link:true asterisk:false update:true -->
|
74
|
-
- [Glimmer 0.7.
|
77
|
+
- [Glimmer 0.7.5 Beta (JRuby Desktop UI DSL + Data-Binding)](#glimmer-058-beta-jruby-desktop-ui-dsl--data-binding)
|
75
78
|
- [Examples](#examples)
|
76
79
|
- [Hello World](#hello-world)
|
77
80
|
- [Tic Tac Toe](#tic-tac-toe)
|
@@ -164,7 +167,7 @@ Please follow these instructions to make the `glimmer` command available on your
|
|
164
167
|
|
165
168
|
Run this command to install directly:
|
166
169
|
```
|
167
|
-
jgem install glimmer -v 0.7.
|
170
|
+
jgem install glimmer -v 0.7.5
|
168
171
|
```
|
169
172
|
|
170
173
|
`jgem` is JRuby's version of `gem` command.
|
@@ -175,7 +178,7 @@ Otherwise, you may also run `jruby -S gem install ...`
|
|
175
178
|
|
176
179
|
Add the following to `Gemfile`:
|
177
180
|
```
|
178
|
-
gem 'glimmer', '~> 0.7.
|
181
|
+
gem 'glimmer', '~> 0.7.5'
|
179
182
|
```
|
180
183
|
|
181
184
|
And, then run:
|
@@ -734,6 +737,7 @@ Glimmer ships with SWT style **smart defaults** so you wouldn't have to set them
|
|
734
737
|
|
735
738
|
- `text(:border)`
|
736
739
|
- `table(:border)`
|
740
|
+
- `tree(:border, :virtual, :v_scroll, :h_scroll)`
|
737
741
|
- `spinner(:border)`
|
738
742
|
- `list(:border, :v_scroll)`
|
739
743
|
- `button(:push)`
|
@@ -1075,7 +1079,7 @@ https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/
|
|
1075
1079
|
|
1076
1080
|
Data-binding is done with `bind` command following widget property to bind and taking model and bindable attribute as arguments.
|
1077
1081
|
|
1078
|
-
|
1082
|
+
#### General data-binding examples:
|
1079
1083
|
|
1080
1084
|
`text bind(contact, :first_name)`
|
1081
1085
|
|
@@ -1098,6 +1102,10 @@ This example also specifies a converter on read of the model property, but via a
|
|
1098
1102
|
|
1099
1103
|
This is a block shortcut version of the syntax above it. It facilitates formatting model data for read-only widgets since it's a very common view concern. It also saves the developer from having to create a separate formatter/presenter for the model when the view can be an active view that handles common simple formatting operations directly.
|
1100
1104
|
|
1105
|
+
`text bind(contact, 'address.street', read_only: true)
|
1106
|
+
|
1107
|
+
This is read-ohly data-binding. It doesn't update contact.address.street when widget text property is changed.
|
1108
|
+
|
1101
1109
|
`text bind(contact, 'addresses[1].street')`
|
1102
1110
|
|
1103
1111
|
This example binds the text property of a widget like `label` to the nested indexed address street of a contact. This is called nested indexed property data binding.
|
@@ -1116,6 +1124,8 @@ This example demonstrates nested indexed computed value data binding whereby the
|
|
1116
1124
|
|
1117
1125
|
Example from [samples/hello/hello_combo.rb](samples/hello_combo.rb) sample (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
1118
1126
|
|
1127
|
+
#### Combo
|
1128
|
+
|
1119
1129
|
![Hello Combo](images/glimmer-hello-combo.png)
|
1120
1130
|
|
1121
1131
|
![Hello Combo](images/glimmer-hello-combo-expanded.png)
|
@@ -1159,6 +1169,8 @@ HelloCombo.new.launch
|
|
1159
1169
|
|
1160
1170
|
`combo` widget is data-bound to the country of a person. Note that it expects `person` object to have `:country` attribute and `:country_options` attribute containing all available countries.
|
1161
1171
|
|
1172
|
+
#### List
|
1173
|
+
|
1162
1174
|
Example from [samples/hello/hello_list_single_selection.rb](samples/hello_list_single_selection.rb) sample:
|
1163
1175
|
|
1164
1176
|
![Hello List Single Selection](images/glimmer-hello-list-single-selection.png)
|
@@ -1240,6 +1252,45 @@ Note that in all the data-binding examples above, there was also an observer att
|
|
1240
1252
|
|
1241
1253
|
You may learn more about Glimmer's data-binding syntax by reading the [Eclipse Zone Tutorial](http://eclipse.dzone.com/articles/an-introduction-glimmer) mentioned in resources and opening up the samples under the [samples](samples) directory.
|
1242
1254
|
|
1255
|
+
#### Tree
|
1256
|
+
|
1257
|
+
The SWT Tree widget visualizes a tree data-structure, such as an employment or composition hierarchy.
|
1258
|
+
|
1259
|
+
To data-bind a Tree, you need the root model, the children querying method, and the text display attribute on each child.
|
1260
|
+
|
1261
|
+
This involves using the `bind` keyword mentioned above in addition to a special `tree_properties` keyword that takes the children and text attribute methods.
|
1262
|
+
|
1263
|
+
Example:
|
1264
|
+
|
1265
|
+
```ruby
|
1266
|
+
shell {
|
1267
|
+
@tree = tree {
|
1268
|
+
items bind(company, :owner), tree_properties(children: :coworkers, text: :name)
|
1269
|
+
selection bind(company, :selected_coworker)
|
1270
|
+
}
|
1271
|
+
}
|
1272
|
+
```
|
1273
|
+
|
1274
|
+
The code above includes two data-bindings:
|
1275
|
+
- Tree `items`, which first bind to the root node (company.owner), and then dig down via `coworkers` `children` method, using the `name` `text` attribute for displaying each tree item.
|
1276
|
+
- Tree `selection`, which binds the single tree item selected by the user to the attribute denoted by the `bind` keyword
|
1277
|
+
|
1278
|
+
Additionally, Tree `items` data-binding automatically stores each node model unto the SWT TreeItem object via `setData` method. This enables things like searchability.
|
1279
|
+
|
1280
|
+
The tree widget in Glimmer is represented by a subclass of `WidgetProxy` called `TreeProxy`.
|
1281
|
+
TreeProxy includes a `depth_first_search` method that takes a block to look for a tree item.
|
1282
|
+
|
1283
|
+
Example:
|
1284
|
+
|
1285
|
+
```ruby
|
1286
|
+
found_array = @tree.depth_first_search { |tree_item| tree_item.getData == company.owner }
|
1287
|
+
```
|
1288
|
+
|
1289
|
+
This finds the root node. The array is a Java array. This enables easy passing of it to SWT `Tree#setSelection` method, which expects a Java array of `TreeItem` objects.
|
1290
|
+
|
1291
|
+
To edit a tree, you must invoke `TreeProxy#edit_selected_tree_item` or `TreeProxy#edit_tree_item`. This automatically leverages the SWT TreeEditor custom class behind the scenes, displaying
|
1292
|
+
a text widget to the user to change the selected or passed tree item text into something else. It automatically persists the change to `items` data-bound model on ENTER/FOCUS-OUT or cancels on ESC/NO-CHANGE.
|
1293
|
+
|
1243
1294
|
### Observer
|
1244
1295
|
|
1245
1296
|
Glimmer comes with `Observer` module, which is used internally for data-binding, but can also be used externally for custom use of the Observer Pattern. It is hidden when observing widgets, and used explicitly when observing models.
|
@@ -2198,6 +2249,8 @@ Exec failed with code 2 command [[/usr/bin/SetFile, -c, icnC, /var/folders/4_/g1
|
|
2198
2249
|
* [InfoQ Article](http://www.infoq.com/news/2008/02/glimmer-jruby-swt)
|
2199
2250
|
* [RubyConf 2008 Video](https://confreaks.tv/videos/rubyconf2008-desktop-development-with-glimmer)
|
2200
2251
|
* [Code Blog](http://andymaleh.blogspot.com/search/label/Glimmer)
|
2252
|
+
* [JRuby Cookbook by Justin Edelson & Henry Liu](http://shop.oreilly.com/product/9780596519650.do)
|
2253
|
+
|
2201
2254
|
|
2202
2255
|
## Feature Suggestions
|
2203
2256
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.7.
|
1
|
+
0.7.5
|
@@ -17,7 +17,12 @@ module Glimmer
|
|
17
17
|
@tree = parent
|
18
18
|
@model_binding = model_binding
|
19
19
|
@tree_properties = [tree_properties].flatten.first.to_h
|
20
|
-
|
20
|
+
if @tree.respond_to?(:tree_properties=)
|
21
|
+
@tree.tree_properties = @tree_properties
|
22
|
+
else # assume custom widget
|
23
|
+
@tree.body_root.tree_properties = @tree_properties
|
24
|
+
end
|
25
|
+
call
|
21
26
|
model = model_binding.base_model
|
22
27
|
observe(model, model_binding.property_name_expression)
|
23
28
|
@tree.on_widget_disposed do |dispose_event|
|
@@ -25,27 +30,37 @@ module Glimmer
|
|
25
30
|
end
|
26
31
|
end
|
27
32
|
|
28
|
-
def call(
|
29
|
-
|
30
|
-
observe(model_tree_root_node, @tree_properties[:text])
|
31
|
-
observe(model_tree_root_node, @tree_properties[:children])
|
32
|
-
@model_tree_root_node = model_tree_root_node
|
33
|
-
end
|
33
|
+
def call(new_value=nil)
|
34
|
+
@model_tree_root_node = @model_binding.evaluate_property
|
34
35
|
populate_tree(@model_tree_root_node, @tree, @tree_properties)
|
35
36
|
end
|
36
37
|
|
37
38
|
def populate_tree(model_tree_root_node, parent, tree_properties)
|
39
|
+
# TODO make it change things by delta instead of removing all
|
40
|
+
selected_tree_item_model = parent.swt_widget.getSelection.map(&:getData).first
|
41
|
+
parent.all_tree_items.each do |tree_item|
|
42
|
+
tree_item.getData('observer_registrations').each do |key, observer_registration|
|
43
|
+
observer_registration.unregister
|
44
|
+
end
|
45
|
+
end
|
38
46
|
parent.swt_widget.removeAll
|
39
47
|
populate_tree_node(model_tree_root_node, parent.swt_widget, tree_properties)
|
48
|
+
tree_item_to_select = parent.depth_first_search {|ti| ti.getData == selected_tree_item_model}
|
49
|
+
parent.swt_widget.setSelection(tree_item_to_select)
|
40
50
|
end
|
41
51
|
|
42
52
|
def populate_tree_node(model_tree_node, parent, tree_properties)
|
43
|
-
|
44
|
-
|
45
|
-
|
53
|
+
return if model_tree_node.nil?
|
54
|
+
# TODO anticipate default tree properties if none were passed (like literal values text and children)
|
55
|
+
tree_item = TreeItem.new(parent, SWT::SWTProxy[:none])
|
56
|
+
observer_registrations = @tree_properties.reduce({}) do |hash, key_value_pair|
|
57
|
+
hash.merge(key_value_pair.first => observe(model_tree_node, key_value_pair.last))
|
58
|
+
end
|
59
|
+
tree_item.setData('observer_registrations', observer_registrations)
|
60
|
+
tree_item.setData(model_tree_node)
|
61
|
+
tree_item.setText((model_tree_node && model_tree_node.send(tree_properties[:text])).to_s)
|
46
62
|
[model_tree_node && model_tree_node.send(tree_properties[:children])].flatten.to_a.compact.each do |child|
|
47
|
-
|
48
|
-
populate_tree_node(child, table_item, tree_properties)
|
63
|
+
populate_tree_node(child, tree_item, tree_properties)
|
49
64
|
end
|
50
65
|
end
|
51
66
|
end
|
data/lib/glimmer/launcher.rb
CHANGED
@@ -116,6 +116,11 @@ module Glimmer
|
|
116
116
|
end
|
117
117
|
end
|
118
118
|
end
|
119
|
+
|
120
|
+
attr_reader :application_paths
|
121
|
+
attr_reader :env_vars
|
122
|
+
attr_reader :glimmer_options
|
123
|
+
attr_reader :jruby_options
|
119
124
|
|
120
125
|
def initialize(raw_options)
|
121
126
|
@application_paths = extract_application_paths(raw_options)
|
@@ -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,7 @@ module Glimmer
|
|
148
151
|
observer.call(@swt_widget.getCaretPosition)
|
149
152
|
}
|
150
153
|
end,
|
151
|
-
:selection_count =>
|
154
|
+
:selection_count => lambda do |observer|
|
152
155
|
on_event_keydown { |event|
|
153
156
|
observer.call(@swt_widget.getSelectionCount)
|
154
157
|
}
|
@@ -162,7 +165,7 @@ module Glimmer
|
|
162
165
|
observer.call(@swt_widget.getSelectionCount)
|
163
166
|
}
|
164
167
|
end,
|
165
|
-
:top_index =>
|
168
|
+
:top_index => lambda do |observer|
|
166
169
|
@last_top_index = @swt_widget.getTopIndex
|
167
170
|
on_paint_control { |event|
|
168
171
|
if @swt_widget.getTopIndex != @last_top_index
|
@@ -173,33 +176,33 @@ module Glimmer
|
|
173
176
|
end,
|
174
177
|
},
|
175
178
|
Java::OrgEclipseSwtCustom::StyledText => {
|
176
|
-
:text =>
|
179
|
+
:text => lambda do |observer|
|
177
180
|
on_modify_text { |modify_event|
|
178
181
|
observer.call(@swt_widget.getText)
|
179
182
|
}
|
180
183
|
end,
|
181
184
|
},
|
182
185
|
Java::OrgEclipseSwtWidgets::Button => {
|
183
|
-
:selection =>
|
186
|
+
:selection => lambda do |observer|
|
184
187
|
on_widget_selected { |selection_event|
|
185
188
|
observer.call(@swt_widget.getSelection)
|
186
189
|
}
|
187
190
|
end
|
188
191
|
},
|
189
192
|
Java::OrgEclipseSwtWidgets::MenuItem => {
|
190
|
-
:selection =>
|
193
|
+
:selection => lambda do |observer|
|
191
194
|
on_widget_selected { |selection_event|
|
192
195
|
observer.call(@swt_widget.getSelection)
|
193
196
|
}
|
194
197
|
end
|
195
198
|
},
|
196
199
|
Java::OrgEclipseSwtWidgets::Spinner => {
|
197
|
-
:selection =>
|
200
|
+
:selection => lambda do |observer|
|
198
201
|
on_widget_selected { |selection_event|
|
199
202
|
observer.call(@swt_widget.getSelection)
|
200
203
|
}
|
201
204
|
end
|
202
|
-
}
|
205
|
+
},
|
203
206
|
}
|
204
207
|
end
|
205
208
|
|
@@ -321,10 +324,12 @@ module Glimmer
|
|
321
324
|
end
|
322
325
|
|
323
326
|
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
|
-
|
327
|
+
widget_add_listener_method, listener_class, listener_method = self.class.find_listener(@swt_widget.getClass, underscored_listener_name)
|
328
|
+
widget_listener_proxy = nil
|
329
|
+
safe_block = lambda { |event| block.call(event) unless @swt_widget.isDisposed }
|
330
|
+
listener = listener_class.new(listener_method => safe_block)
|
326
331
|
@swt_widget.send(widget_add_listener_method, listener)
|
327
|
-
WidgetListenerProxy.new(listener)
|
332
|
+
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
333
|
end
|
329
334
|
|
330
335
|
# Looks through SWT class add***Listener methods till it finds one for which
|
@@ -375,8 +380,10 @@ module Glimmer
|
|
375
380
|
|
376
381
|
def add_swt_event_listener(swt_constant, &block)
|
377
382
|
event_type = SWTProxy[swt_constant]
|
378
|
-
|
379
|
-
|
383
|
+
widget_listener_proxy = nil
|
384
|
+
safe_block = lambda { |event| block.call(event) unless @swt_widget.isDisposed }
|
385
|
+
@swt_widget.addListener(event_type, &safe_block)
|
386
|
+
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
387
|
end
|
381
388
|
|
382
389
|
def widget_custom_attribute_mapping
|
@@ -409,7 +416,7 @@ module Glimmer
|
|
409
416
|
end
|
410
417
|
|
411
418
|
def property_type_converters
|
412
|
-
color_converter =
|
419
|
+
color_converter = lambda do |value|
|
413
420
|
if value.is_a?(Symbol) || value.is_a?(String)
|
414
421
|
ColorProxy.new(value).swt_color
|
415
422
|
else
|
@@ -419,7 +426,7 @@ module Glimmer
|
|
419
426
|
# TODO consider detecting type on widget method and automatically invoking right converter (e.g. :to_s for String, :to_i for Integer)
|
420
427
|
@property_type_converters ||= {
|
421
428
|
:background => color_converter,
|
422
|
-
:background_image =>
|
429
|
+
:background_image => lambda do |value|
|
423
430
|
if value.is_a?(String)
|
424
431
|
if value.start_with?('uri:classloader')
|
425
432
|
value = value.sub(/^uri\:classloader\:\//, '')
|
@@ -440,7 +447,7 @@ module Glimmer
|
|
440
447
|
end
|
441
448
|
end,
|
442
449
|
:foreground => color_converter,
|
443
|
-
:font =>
|
450
|
+
:font => lambda do |value|
|
444
451
|
if value.is_a?(Hash)
|
445
452
|
font_properties = value
|
446
453
|
FontProxy.new(self, font_properties).swt_font
|
@@ -448,17 +455,17 @@ module Glimmer
|
|
448
455
|
value
|
449
456
|
end
|
450
457
|
end,
|
451
|
-
:items =>
|
458
|
+
:items => lambda do |value|
|
452
459
|
value.to_java :string
|
453
460
|
end,
|
454
|
-
:text =>
|
461
|
+
:text => lambda do |value|
|
455
462
|
if swt_widget.is_a?(Browser)
|
456
463
|
value.to_s
|
457
464
|
else
|
458
465
|
value.to_s
|
459
466
|
end
|
460
467
|
end,
|
461
|
-
:visible =>
|
468
|
+
:visible => lambda do |value|
|
462
469
|
!!value
|
463
470
|
end,
|
464
471
|
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AndyMaleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-05-
|
11
|
+
date: 2020-05-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|