glimmer 0.1.8.470 → 0.1.9.470
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -2
- data/README.markdown +2 -2
- data/TODO.md +7 -1
- data/VERSION +1 -1
- data/bin/girb +4 -2
- data/bin/girb_runner.rb +0 -4
- data/glimmer.gemspec +14 -9
- data/lib/command_handlers.rb +4 -0
- data/lib/command_handlers/RELEASE.md +12 -0
- data/lib/command_handlers/bind_command_handler.rb +27 -12
- data/lib/command_handlers/data_binding_command_handler.rb +16 -9
- data/lib/command_handlers/models/observable_array.rb +14 -13
- data/lib/command_handlers/models/observable_model.rb +11 -10
- data/lib/command_handlers/models/tree_items_updater.rb +40 -0
- data/lib/command_handlers/table_column_properties_data_binding_command_handler.rb +6 -4
- data/lib/command_handlers/table_items_data_binding_command_handler.rb +4 -3
- data/lib/command_handlers/tree_items_data_binding_command_handler.rb +27 -0
- data/lib/command_handlers/tree_properties_data_binding_command_handler.rb +23 -0
- data/samples/login.rb +26 -26
- data/spec/lib/glimmer__data_binding__spec.rb +1 -1
- data/spec/lib/glimmer__tree_data_binding__spec.rb +113 -0
- data/spec/spec_helper.rb +1 -0
- metadata +13 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0067b97cd354df28d0f9c07542c18c86fbd0862d2d14791c49488a1bd999715d
|
4
|
+
data.tar.gz: 6f6107572403c58148bbb9e5eb6613c5252c264373bbc3c8bd2bae2305fd9e76
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9162f6be53c6cf3a5641e137ad112f2711a9d332fc8e3cfda52579fe0286505103b93d4f4f16952358ead6ffc1915cf90b93b38af548d88b38ccb828666dcac1
|
7
|
+
data.tar.gz: fa1841ff34f94cef66485767670a564d21c50d93f9c3a99a39653914385205bcbe1abca03b351697e776e9222ae3fe5741aefcf98d9214a4c7d8bb6416237e1e
|
data/Gemfile
CHANGED
@@ -4,12 +4,12 @@ gem 'facets', '3.1.0'
|
|
4
4
|
gem 'os', '1.0.0'
|
5
5
|
|
6
6
|
group :development do
|
7
|
-
gem "rspec", "~> 3.5.0"
|
8
7
|
gem "rspec-mocks", "~> 3.5.0"
|
8
|
+
gem "rspec", "~> 3.5.0"
|
9
9
|
gem "rdoc", "~> 2.3.0"
|
10
10
|
gem "bundler", "~> 1.0"
|
11
11
|
gem "jeweler", "~> 2.3.0"
|
12
12
|
gem "coveralls", "= 0.8.5", require: false
|
13
13
|
gem "simplecov", "~> 0.10.0", require: nil
|
14
|
-
gem "puts_debuggerer", "0.
|
14
|
+
gem "puts_debuggerer", "~> 0.7.1"
|
15
15
|
end
|
data/README.markdown
CHANGED
@@ -26,7 +26,7 @@ Please follow these instructions to make the `glimmer` command available on your
|
|
26
26
|
|
27
27
|
Add the following to `Gemfile`:
|
28
28
|
```
|
29
|
-
gem 'glimmer', '~> 0.1.
|
29
|
+
gem 'glimmer', '~> 0.1.9.470'
|
30
30
|
```
|
31
31
|
|
32
32
|
And, then run:
|
@@ -38,7 +38,7 @@ bundle install
|
|
38
38
|
|
39
39
|
Run this command to get directly:
|
40
40
|
```
|
41
|
-
gem install glimmer -v 0.1.
|
41
|
+
gem install glimmer -v 0.1.9.470
|
42
42
|
```
|
43
43
|
|
44
44
|
## Usage
|
data/TODO.md
CHANGED
@@ -2,5 +2,11 @@
|
|
2
2
|
|
3
3
|
Here is a list of tasks to do (please delete once done):
|
4
4
|
|
5
|
-
* Support Tree databinding
|
5
|
+
* Support Tree databinding (bidirectional)
|
6
|
+
* Figure out what is missing from table databinding (bidirectional?)
|
6
7
|
* Explore rewriting shine with Ruby 2 support
|
8
|
+
* Add a startup progress dialog (consider Glimmer branding)
|
9
|
+
* Externalize constants to make easily configurable
|
10
|
+
* Extract ListenerParent into its own file from WidgetListenerCommandHandler
|
11
|
+
* Nested databinding support
|
12
|
+
* Enhance XML DSL support (special characters, CDATA, escaped characters (#, {, }, .))
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.9.470
|
data/bin/girb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
|
2
|
+
require 'os'
|
3
|
+
require_relative '../lib/glimmer_application'
|
4
|
+
additional_options = OS.mac? ? "-J-XstartOnFirstThread" : ""
|
5
|
+
system "ruby #{additional_options} -J-classpath \"#{GlimmerApplication::SWT_JAR_FILE}\" -S irb -r #{File.expand_path(File.join(__FILE__, '..', 'girb_runner.rb'))}"
|
data/bin/girb_runner.rb
CHANGED
data/glimmer.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: glimmer 0.1.
|
5
|
+
# stub: glimmer 0.1.9.470 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "glimmer".freeze
|
9
|
-
s.version = "0.1.
|
9
|
+
s.version = "0.1.9.470"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["AndyMaleh".freeze]
|
14
|
-
s.date = "2017-07-
|
14
|
+
s.date = "2017-07-26"
|
15
15
|
s.description = "JRuby DSL that enables easy and efficient authoring of user-interfaces using the robust platform-independent Eclipse SWT library".freeze
|
16
16
|
s.email = "andy.am@gmail.com".freeze
|
17
17
|
s.executables = ["glimmer".freeze, "girb".freeze]
|
@@ -39,6 +39,7 @@ Gem::Specification.new do |s|
|
|
39
39
|
"lib/command_handler_chain_factory.rb",
|
40
40
|
"lib/command_handler_chain_link.rb",
|
41
41
|
"lib/command_handlers.rb",
|
42
|
+
"lib/command_handlers/RELEASE.md",
|
42
43
|
"lib/command_handlers/bind_command_handler.rb",
|
43
44
|
"lib/command_handlers/combo_selection_data_binding_command_handler.rb",
|
44
45
|
"lib/command_handlers/data_binding_command_handler.rb",
|
@@ -54,11 +55,14 @@ Gem::Specification.new do |s|
|
|
54
55
|
"lib/command_handlers/models/r_widget_listener.rb",
|
55
56
|
"lib/command_handlers/models/r_widget_packages.rb",
|
56
57
|
"lib/command_handlers/models/table_items_updater.rb",
|
58
|
+
"lib/command_handlers/models/tree_items_updater.rb",
|
57
59
|
"lib/command_handlers/models/widget_observer.rb",
|
58
60
|
"lib/command_handlers/shell_command_handler.rb",
|
59
61
|
"lib/command_handlers/tab_item_command_handler.rb",
|
60
62
|
"lib/command_handlers/table_column_properties_data_binding_command_handler.rb",
|
61
63
|
"lib/command_handlers/table_items_data_binding_command_handler.rb",
|
64
|
+
"lib/command_handlers/tree_items_data_binding_command_handler.rb",
|
65
|
+
"lib/command_handlers/tree_properties_data_binding_command_handler.rb",
|
62
66
|
"lib/command_handlers/widget_command_handler.rb",
|
63
67
|
"lib/command_handlers/widget_listener_command_handler.rb",
|
64
68
|
"lib/command_handlers/widget_method_command_handler.rb",
|
@@ -101,6 +105,7 @@ Gem::Specification.new do |s|
|
|
101
105
|
"spec/lib/glimmer__shine_data_binding__spec.rb",
|
102
106
|
"spec/lib/glimmer__tab_item__spec.rb",
|
103
107
|
"spec/lib/glimmer__table_data_binding__spec.rb",
|
108
|
+
"spec/lib/glimmer__tree_data_binding__spec.rb",
|
104
109
|
"spec/lib/glimmer_spec.rb",
|
105
110
|
"spec/lib/xml/glimmer_xml_spec.rb",
|
106
111
|
"spec/samples/contactmanager/contact_manager_presenter_spec.rb",
|
@@ -118,37 +123,37 @@ Gem::Specification.new do |s|
|
|
118
123
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
119
124
|
s.add_runtime_dependency(%q<facets>.freeze, ["= 3.1.0"])
|
120
125
|
s.add_runtime_dependency(%q<os>.freeze, ["= 1.0.0"])
|
121
|
-
s.add_development_dependency(%q<rspec>.freeze, ["~> 3.5.0"])
|
122
126
|
s.add_development_dependency(%q<rspec-mocks>.freeze, ["~> 3.5.0"])
|
127
|
+
s.add_development_dependency(%q<rspec>.freeze, ["~> 3.5.0"])
|
123
128
|
s.add_development_dependency(%q<rdoc>.freeze, ["~> 2.3.0"])
|
124
129
|
s.add_development_dependency(%q<bundler>.freeze, ["~> 1.0"])
|
125
130
|
s.add_development_dependency(%q<jeweler>.freeze, ["~> 2.3.0"])
|
126
131
|
s.add_development_dependency(%q<coveralls>.freeze, ["= 0.8.5"])
|
127
132
|
s.add_development_dependency(%q<simplecov>.freeze, ["~> 0.10.0"])
|
128
|
-
s.add_development_dependency(%q<puts_debuggerer>.freeze, ["
|
133
|
+
s.add_development_dependency(%q<puts_debuggerer>.freeze, ["~> 0.7.1"])
|
129
134
|
else
|
130
135
|
s.add_dependency(%q<facets>.freeze, ["= 3.1.0"])
|
131
136
|
s.add_dependency(%q<os>.freeze, ["= 1.0.0"])
|
132
|
-
s.add_dependency(%q<rspec>.freeze, ["~> 3.5.0"])
|
133
137
|
s.add_dependency(%q<rspec-mocks>.freeze, ["~> 3.5.0"])
|
138
|
+
s.add_dependency(%q<rspec>.freeze, ["~> 3.5.0"])
|
134
139
|
s.add_dependency(%q<rdoc>.freeze, ["~> 2.3.0"])
|
135
140
|
s.add_dependency(%q<bundler>.freeze, ["~> 1.0"])
|
136
141
|
s.add_dependency(%q<jeweler>.freeze, ["~> 2.3.0"])
|
137
142
|
s.add_dependency(%q<coveralls>.freeze, ["= 0.8.5"])
|
138
143
|
s.add_dependency(%q<simplecov>.freeze, ["~> 0.10.0"])
|
139
|
-
s.add_dependency(%q<puts_debuggerer>.freeze, ["
|
144
|
+
s.add_dependency(%q<puts_debuggerer>.freeze, ["~> 0.7.1"])
|
140
145
|
end
|
141
146
|
else
|
142
147
|
s.add_dependency(%q<facets>.freeze, ["= 3.1.0"])
|
143
148
|
s.add_dependency(%q<os>.freeze, ["= 1.0.0"])
|
144
|
-
s.add_dependency(%q<rspec>.freeze, ["~> 3.5.0"])
|
145
149
|
s.add_dependency(%q<rspec-mocks>.freeze, ["~> 3.5.0"])
|
150
|
+
s.add_dependency(%q<rspec>.freeze, ["~> 3.5.0"])
|
146
151
|
s.add_dependency(%q<rdoc>.freeze, ["~> 2.3.0"])
|
147
152
|
s.add_dependency(%q<bundler>.freeze, ["~> 1.0"])
|
148
153
|
s.add_dependency(%q<jeweler>.freeze, ["~> 2.3.0"])
|
149
154
|
s.add_dependency(%q<coveralls>.freeze, ["= 0.8.5"])
|
150
155
|
s.add_dependency(%q<simplecov>.freeze, ["~> 0.10.0"])
|
151
|
-
s.add_dependency(%q<puts_debuggerer>.freeze, ["
|
156
|
+
s.add_dependency(%q<puts_debuggerer>.freeze, ["~> 0.7.1"])
|
152
157
|
end
|
153
158
|
end
|
154
159
|
|
data/lib/command_handlers.rb
CHANGED
@@ -5,6 +5,8 @@ require File.dirname(__FILE__) + "/command_handlers/bind_command_handler"
|
|
5
5
|
require File.dirname(__FILE__) + "/command_handlers/tab_item_command_handler"
|
6
6
|
require File.dirname(__FILE__) + "/command_handlers/combo_selection_data_binding_command_handler"
|
7
7
|
require File.dirname(__FILE__) + "/command_handlers/list_selection_data_binding_command_handler"
|
8
|
+
require File.dirname(__FILE__) + "/command_handlers/tree_items_data_binding_command_handler"
|
9
|
+
require File.dirname(__FILE__) + "/command_handlers/tree_properties_data_binding_command_handler"
|
8
10
|
require File.dirname(__FILE__) + "/command_handlers/table_items_data_binding_command_handler"
|
9
11
|
require File.dirname(__FILE__) + "/command_handlers/table_column_properties_data_binding_command_handler"
|
10
12
|
require File.dirname(__FILE__) + "/command_handlers/data_binding_command_handler"
|
@@ -19,6 +21,8 @@ CommandHandlerChainFactory.def_dsl(:swt,
|
|
19
21
|
TabItemCommandHandler.new,
|
20
22
|
ComboSelectionDataBindingCommandHandler.new,
|
21
23
|
ListSelectionDataBindingCommandHandler.new,
|
24
|
+
TreeItemsDataBindingCommandHandler.new,
|
25
|
+
TreePropertiesDataBindingCommandHandler.new,
|
22
26
|
TableItemsDataBindingCommandHandler.new,
|
23
27
|
TableColumnPropertiesDataBindingCommandHandler.new,
|
24
28
|
DataBindingCommandHandler.new,
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# Release Notes
|
2
|
+
|
3
|
+
** 0.1.9.470 **
|
4
|
+
- Support Tree data-binding (read-only from model to tree)
|
5
|
+
|
6
|
+
** 0.1.8.470 **
|
7
|
+
- girb support
|
8
|
+
|
9
|
+
** 0.1.5.470 **
|
10
|
+
- Glimmer now uses a Ruby Logger in debug mode to provide helpful debugging information
|
11
|
+
- Glimmer has a smart new Ruby shell script for executing applications
|
12
|
+
- Glimmer now downloads swt.jar automatically when missing (e.g. 1st run) on Mac, Windows, and Linux, and for x86 and x86-64 CPU architectures.
|
@@ -2,25 +2,40 @@ require File.dirname(__FILE__) + "/../command_handler"
|
|
2
2
|
require File.dirname(__FILE__) + "/models/r_widget"
|
3
3
|
require File.dirname(__FILE__) + "/models/model_observer"
|
4
4
|
|
5
|
+
# Responsible for setting up the return value of the bind keyword (command symbol)
|
6
|
+
# as a ModelObserver. It is then used by another command handler like
|
7
|
+
# DataBindingCommandHandler for text and selection properties on Text and Spinner
|
8
|
+
# or TableItemsDataBindingCommandHandler for items in a Table
|
5
9
|
class BindCommandHandler
|
6
10
|
include CommandHandler
|
7
|
-
|
11
|
+
|
8
12
|
include_package 'org.eclipse.swt.widgets'
|
9
13
|
|
10
14
|
def can_handle?(parent, command_symbol, *args, &block)
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
(
|
16
|
+
parent.is_a?(RWidget) and
|
17
|
+
command_symbol.to_s == "bind" and
|
18
|
+
(
|
19
|
+
(
|
20
|
+
(args.size == 2) and
|
21
|
+
(
|
22
|
+
args[1].is_a?(Symbol) or
|
23
|
+
args[1].is_a?(String)
|
24
|
+
)
|
25
|
+
) or
|
26
|
+
(
|
27
|
+
(args.size == 3) and
|
28
|
+
(args[1].is_a?(Symbol) or args[1].is_a?(String)) and
|
29
|
+
(args[2].is_a?(Symbol) or args[2].is_a?(String))
|
30
|
+
)
|
31
|
+
) and
|
32
|
+
block == nil
|
33
|
+
)
|
19
34
|
end
|
20
|
-
|
35
|
+
|
21
36
|
def do_handle(parent, command_symbol, *args, &block)
|
22
37
|
property_type = args[2] if (args.size == 3)
|
23
38
|
ModelObserver.new(args[0], args[1].to_s, property_type)
|
24
39
|
end
|
25
|
-
|
26
|
-
end
|
40
|
+
|
41
|
+
end
|
@@ -4,12 +4,19 @@ require File.dirname(__FILE__) + "/models/observable_model"
|
|
4
4
|
require File.dirname(__FILE__) + "/models/model_observer"
|
5
5
|
require File.dirname(__FILE__) + "/models/widget_observer"
|
6
6
|
|
7
|
-
|
7
|
+
# Responsible for wiring two-way data-binding for text and selection properties
|
8
|
+
# on Text, Button, and Spinner widgets.
|
9
|
+
# Does so by using the output of the bind(model, property) command in the form
|
10
|
+
# of a ModelObserver, which is then connected to an anonymous widget observer
|
11
|
+
# (aka widget_data_binder as per widget_data_binders array)
|
12
|
+
#
|
13
|
+
# Depends on BindCommandHandler
|
14
|
+
class DataBindingCommandHandler
|
8
15
|
extend Glimmer
|
9
16
|
include CommandHandler
|
10
|
-
|
17
|
+
|
11
18
|
include_package 'org.eclipse.swt.widgets'
|
12
|
-
|
19
|
+
|
13
20
|
@@widget_data_binders = {
|
14
21
|
Java::OrgEclipseSwtWidgets::Text => {
|
15
22
|
:text => Proc.new do |rwidget, model_observer|
|
@@ -38,14 +45,14 @@ class DataBindingCommandHandler
|
|
38
45
|
}
|
39
46
|
end
|
40
47
|
}
|
41
|
-
}
|
42
|
-
|
48
|
+
}
|
49
|
+
|
43
50
|
def can_handle?(parent, command_symbol, *args, &block)
|
44
|
-
parent.is_a?(RWidget) and
|
51
|
+
(parent.is_a?(RWidget) and
|
45
52
|
args.size == 1 and
|
46
|
-
args[0].is_a?(ModelObserver)
|
53
|
+
args[0].is_a?(ModelObserver))
|
47
54
|
end
|
48
|
-
|
55
|
+
|
49
56
|
def do_handle(parent, command_symbol, *args, &block)
|
50
57
|
model_observer = args[0]
|
51
58
|
widget_observer = WidgetObserver.new(parent, command_symbol.to_s)
|
@@ -57,5 +64,5 @@ class DataBindingCommandHandler
|
|
57
64
|
widget_data_binder = widget_data_binder_map[command_symbol.to_s.to_sym] if widget_data_binder_map
|
58
65
|
widget_data_binder.call(parent, model_observer) if widget_data_binder
|
59
66
|
end
|
60
|
-
|
67
|
+
|
61
68
|
end
|
@@ -1,9 +1,10 @@
|
|
1
|
+
require 'set'
|
1
2
|
module ObservableArray
|
2
|
-
|
3
|
+
|
3
4
|
def add_observer(element_properties, observer)
|
4
5
|
property_observer_list << observer
|
5
6
|
each do |element|
|
6
|
-
element_properties.each do |property|
|
7
|
+
[element_properties].flatten.each do |property|
|
7
8
|
element.extend(ObservableModel) unless element.is_a?(ObservableModel)
|
8
9
|
element.add_observer(property, observer)
|
9
10
|
end
|
@@ -11,30 +12,30 @@ module ObservableArray
|
|
11
12
|
end
|
12
13
|
|
13
14
|
def property_observer_list
|
14
|
-
@property_observer_list =
|
15
|
+
@property_observer_list = Set.new unless @property_observer_list
|
15
16
|
@property_observer_list
|
16
17
|
end
|
17
|
-
|
18
|
+
|
18
19
|
def notify_observers
|
19
20
|
property_observer_list.each {|observer| observer.update}
|
20
21
|
end
|
21
|
-
|
22
|
+
|
22
23
|
def self.extend_object(array)
|
23
24
|
array.instance_eval("alias original_add <<")
|
24
25
|
array.instance_eval <<-end_eval, __FILE__, __LINE__
|
25
|
-
def <<(value)
|
26
|
-
self.original_add(value)
|
27
|
-
notify_observers
|
26
|
+
def <<(value)
|
27
|
+
self.original_add(value)
|
28
|
+
notify_observers
|
28
29
|
end
|
29
30
|
end_eval
|
30
|
-
|
31
|
+
|
31
32
|
notify_observers_on_invokation(array, "delete", 1)
|
32
33
|
notify_observers_on_invokation(array, "delete_at", 1)
|
33
34
|
notify_observers_on_invokation(array, "clear")
|
34
|
-
|
35
|
+
|
35
36
|
super
|
36
37
|
end
|
37
|
-
|
38
|
+
|
38
39
|
def self.notify_observers_on_invokation(model, method, argument_count=0)
|
39
40
|
model.instance_eval "alias original_#{method} #{method}\n"
|
40
41
|
arguments = ""
|
@@ -44,8 +45,8 @@ module ObservableArray
|
|
44
45
|
arguments = arguments[0..-2]
|
45
46
|
model.instance_eval <<-end_eval, __FILE__, __LINE__
|
46
47
|
def #{method}(#{arguments})
|
47
|
-
self.original_#{method}(#{arguments})
|
48
|
-
notify_observers
|
48
|
+
self.original_#{method}(#{arguments})
|
49
|
+
notify_observers
|
49
50
|
end
|
50
51
|
end_eval
|
51
52
|
end
|
@@ -1,5 +1,6 @@
|
|
1
|
+
require 'set'
|
1
2
|
module ObservableModel
|
2
|
-
|
3
|
+
|
3
4
|
def add_observer(property_name, observer)
|
4
5
|
property_observer_list(property_name) << observer
|
5
6
|
end
|
@@ -8,16 +9,16 @@ module ObservableModel
|
|
8
9
|
@property_observers = Hash.new unless @property_observers
|
9
10
|
@property_observers
|
10
11
|
end
|
11
|
-
|
12
|
+
|
12
13
|
def property_observer_list(property_name)
|
13
|
-
property_observer_hash[property_name.to_sym] =
|
14
|
+
property_observer_hash[property_name.to_sym] = Set.new unless property_observer_hash[property_name.to_sym]
|
14
15
|
property_observer_hash[property_name.to_sym]
|
15
16
|
end
|
16
|
-
|
17
|
+
|
17
18
|
def notify_observers(property_name)
|
18
19
|
property_observer_list(property_name).each {|observer| observer.update(send(property_name))}
|
19
20
|
end
|
20
|
-
|
21
|
+
|
21
22
|
class Updater
|
22
23
|
def initialize(property_name, observable_model)
|
23
24
|
@property_name = property_name
|
@@ -27,33 +28,33 @@ module ObservableModel
|
|
27
28
|
@observable_model.notify_observers(@property_name)
|
28
29
|
end
|
29
30
|
end
|
30
|
-
|
31
|
+
|
31
32
|
def self.extend_object(model)
|
32
33
|
super
|
33
34
|
model.methods.each do |method|
|
34
35
|
self.add_method_observers(model, method)
|
35
36
|
end
|
36
37
|
end
|
37
|
-
|
38
|
+
|
38
39
|
def self.add_method_observers(model, method)
|
39
40
|
setter_method_pattern = /^(\w+=)$/
|
40
41
|
if (method.match(setter_method_pattern))
|
41
42
|
getter_method = method[0, method.length - 1]
|
42
43
|
getter_value = model.send(getter_method)
|
43
|
-
if (getter_value.is_a?(Array) and
|
44
|
+
if (getter_value.is_a?(Array) and
|
44
45
|
!getter_value.is_a?(ObservableArray))
|
45
46
|
getter_value.extend(ObservableArray)
|
46
47
|
getter_value.add_observer([], Updater.new(getter_method, model))
|
47
48
|
end
|
48
49
|
model.instance_eval "alias original_#{method} #{method}\n"
|
49
50
|
model.instance_eval <<-end_eval, __FILE__, __LINE__
|
50
|
-
def #{method}(value)
|
51
|
+
def #{method}(value)
|
51
52
|
self.original_#{method}(value)
|
52
53
|
notify_observers('#{getter_method}')
|
53
54
|
if (value.is_a?(Array) and !value.is_a?(ObservableArray))
|
54
55
|
value.extend(ObservableArray)
|
55
56
|
value.add_observer([], ObservableModel::Updater.new('#{getter_method}', self))
|
56
|
-
end
|
57
|
+
end
|
57
58
|
end
|
58
59
|
end_eval
|
59
60
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/observable_array"
|
2
|
+
require File.dirname(__FILE__) + "/observable_model"
|
3
|
+
|
4
|
+
class TreeItemsUpdater
|
5
|
+
include_package 'org.eclipse.swt'
|
6
|
+
include_package 'org.eclipse.swt.widgets'
|
7
|
+
|
8
|
+
def initialize(parent, model_observer, tree_properties)
|
9
|
+
@tree = parent
|
10
|
+
@model_observer = model_observer
|
11
|
+
@tree_properties = [tree_properties].flatten.first.to_h
|
12
|
+
update(@model_observer.evaluate_property)
|
13
|
+
model = model_observer.model
|
14
|
+
model.extend(ObservableModel) unless model.is_a?(ObservableModel)
|
15
|
+
model.add_observer(model_observer.property_name, self)
|
16
|
+
end
|
17
|
+
def update(model_tree_root_node=nil)
|
18
|
+
if model_tree_root_node and model_tree_root_node.respond_to?(@tree_properties[:children])
|
19
|
+
model_tree_root_node.extend(ObservableModel) unless model_tree_root_node.is_a?(ObservableModel)
|
20
|
+
model_tree_root_node.add_observer(@tree_properties[:text], self)
|
21
|
+
model_tree_root_node.add_observer(@tree_properties[:children], self)
|
22
|
+
@model_tree_root_node = model_tree_root_node
|
23
|
+
end
|
24
|
+
populate_tree(@model_tree_root_node, @tree, @tree_properties)
|
25
|
+
end
|
26
|
+
def populate_tree(model_tree_root_node, parent, tree_properties)
|
27
|
+
parent.widget.removeAll
|
28
|
+
populate_tree_node(model_tree_root_node, parent.widget, tree_properties)
|
29
|
+
end
|
30
|
+
def populate_tree_node(model_tree_node, parent, tree_properties)
|
31
|
+
table_item = TreeItem.new(parent, SWT::NONE)
|
32
|
+
table_item.setText((model_tree_node && model_tree_node.send(tree_properties[:text])).to_s)
|
33
|
+
[model_tree_node && model_tree_node.send(tree_properties[:children])].flatten.to_a.compact.each do |child|
|
34
|
+
child.extend(ObservableModel) unless child.is_a?(ObservableModel)
|
35
|
+
child.add_observer(@tree_properties[:text], self)
|
36
|
+
populate_tree_node(child, table_item, tree_properties)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -1,9 +1,11 @@
|
|
1
1
|
require File.dirname(__FILE__) + "/../command_handler"
|
2
2
|
require File.dirname(__FILE__) + "/models/r_widget"
|
3
3
|
|
4
|
+
# Responsible for providing a readable keyword (command symbol) to capture
|
5
|
+
# and return column properties for use in TreeItemsDataBindingCommandHandler
|
4
6
|
class TableColumnPropertiesDataBindingCommandHandler
|
5
7
|
include CommandHandler
|
6
|
-
|
8
|
+
|
7
9
|
include_package 'org.eclipse.swt'
|
8
10
|
include_package 'org.eclipse.swt.widgets'
|
9
11
|
|
@@ -13,9 +15,9 @@ class TableColumnPropertiesDataBindingCommandHandler
|
|
13
15
|
command_symbol.to_s == "column_properties" and
|
14
16
|
block == nil
|
15
17
|
end
|
16
|
-
|
18
|
+
|
17
19
|
def do_handle(parent, command_symbol, *args, &block)
|
18
20
|
args
|
19
21
|
end
|
20
|
-
|
21
|
-
end
|
22
|
+
|
23
|
+
end
|
@@ -2,9 +2,10 @@ require File.dirname(__FILE__) + "/../command_handler"
|
|
2
2
|
require File.dirname(__FILE__) + "/models/r_widget"
|
3
3
|
require File.dirname(__FILE__) + "/models/table_items_updater"
|
4
4
|
|
5
|
+
#Depends on BindCommandHandler and TableColumnPropertiesDataBindingCommandHandler
|
5
6
|
class TableItemsDataBindingCommandHandler
|
6
7
|
include CommandHandler
|
7
|
-
|
8
|
+
|
8
9
|
include_package 'org.eclipse.swt.widgets'
|
9
10
|
|
10
11
|
def can_handle?(parent, command_symbol, *args, &block)
|
@@ -17,11 +18,11 @@ class TableItemsDataBindingCommandHandler
|
|
17
18
|
args[1].is_a?(Array) and
|
18
19
|
block == nil
|
19
20
|
end
|
20
|
-
|
21
|
+
|
21
22
|
def do_handle(parent, command_symbol, *args, &block)
|
22
23
|
model_observer = args[0]
|
23
24
|
column_properties = args[1]
|
24
25
|
TableItemsUpdater.new(parent, model_observer, column_properties)
|
25
26
|
end
|
26
27
|
|
27
|
-
end
|
28
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../command_handler"
|
2
|
+
require File.dirname(__FILE__) + "/models/r_widget"
|
3
|
+
require File.dirname(__FILE__) + "/models/tree_items_updater"
|
4
|
+
|
5
|
+
class TreeItemsDataBindingCommandHandler
|
6
|
+
include CommandHandler
|
7
|
+
|
8
|
+
include_package 'org.eclipse.swt.widgets'
|
9
|
+
|
10
|
+
def can_handle?(parent, command_symbol, *args, &block)
|
11
|
+
(parent.is_a?(RWidget)) and
|
12
|
+
(parent.widget.is_a?(Tree)) and
|
13
|
+
(command_symbol.to_s == "items") and
|
14
|
+
(args.size == 2) and
|
15
|
+
(args[0].is_a?(ModelObserver)) and
|
16
|
+
(!args[0].evaluate_property.is_a?(Array)) and
|
17
|
+
(args[1].is_a?(Array) && !args[1].empty? && args[1].first.is_a?(Hash)) and
|
18
|
+
(block == nil)
|
19
|
+
end
|
20
|
+
|
21
|
+
def do_handle(parent, command_symbol, *args, &block)
|
22
|
+
model_observer = args[0]
|
23
|
+
tree_properties = args[1]
|
24
|
+
TreeItemsUpdater.new(parent, model_observer, tree_properties)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../command_handler"
|
2
|
+
require File.dirname(__FILE__) + "/models/r_widget"
|
3
|
+
|
4
|
+
# Responsible for providing a readable keyword (command symbol) to capture
|
5
|
+
# and return tree properties for use in TreeItemsDataBindingCommandHandler
|
6
|
+
class TreePropertiesDataBindingCommandHandler
|
7
|
+
include CommandHandler
|
8
|
+
|
9
|
+
include_package 'org.eclipse.swt'
|
10
|
+
include_package 'org.eclipse.swt.widgets'
|
11
|
+
|
12
|
+
def can_handle?(parent, command_symbol, *args, &block)
|
13
|
+
parent.is_a?(RWidget) and
|
14
|
+
parent.widget.is_a?(Tree) and
|
15
|
+
command_symbol.to_s == "tree_properties" and
|
16
|
+
block == nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def do_handle(parent, command_symbol, *args, &block)
|
20
|
+
args
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
data/samples/login.rb
CHANGED
@@ -4,81 +4,81 @@ require_relative "../lib/glimmer"
|
|
4
4
|
|
5
5
|
#Presents login screen data
|
6
6
|
class LoginPresenter
|
7
|
-
|
7
|
+
|
8
8
|
attr_accessor :user_name
|
9
9
|
attr_accessor :password
|
10
10
|
attr_accessor :status
|
11
|
-
|
11
|
+
|
12
12
|
def initialize
|
13
13
|
@user_name = ""
|
14
14
|
@password = ""
|
15
15
|
@status = "Logged Out"
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
def status=(status)
|
19
19
|
@status = status
|
20
|
-
|
21
|
-
#TODO add feature to bind dependent properties to master property
|
22
|
-
notify_observers("logged_in")
|
20
|
+
|
21
|
+
#TODO add feature to bind dependent properties to master property (2017-07-25 nested data binding)
|
22
|
+
notify_observers("logged_in")
|
23
23
|
notify_observers("logged_out")
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def logged_in
|
27
27
|
self.status == "Logged In"
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
def logged_out
|
31
31
|
!self.logged_in
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
def login
|
35
35
|
self.status = "Logged In"
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
def logout
|
39
39
|
self.user_name = ""
|
40
40
|
self.password = ""
|
41
41
|
self.status = "Logged Out"
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
end
|
45
45
|
|
46
46
|
#Login screen
|
47
47
|
class Login
|
48
48
|
include_package 'org.eclipse.swt'
|
49
49
|
include_package 'org.eclipse.swt.layout'
|
50
|
-
|
50
|
+
|
51
51
|
include Glimmer
|
52
|
-
|
52
|
+
|
53
53
|
def launch
|
54
54
|
presenter = LoginPresenter.new
|
55
55
|
@shell = shell {
|
56
56
|
text "Login"
|
57
|
-
composite {
|
57
|
+
composite {
|
58
58
|
layout GridLayout.new(2, false) #two columns with differing widths
|
59
|
-
|
59
|
+
|
60
60
|
label { text "Username:" } # goes in column 1
|
61
61
|
text { # goes in column 2
|
62
|
-
text bind(presenter, :user_name)
|
62
|
+
text bind(presenter, :user_name)
|
63
63
|
enabled bind(presenter, :logged_out)
|
64
|
-
}
|
65
|
-
|
66
|
-
label { text "Password:" }
|
64
|
+
}
|
65
|
+
|
66
|
+
label { text "Password:" }
|
67
67
|
text(:password, :border) {
|
68
|
-
text bind(presenter, :password)
|
68
|
+
text bind(presenter, :password)
|
69
69
|
enabled bind(presenter, :logged_out)
|
70
70
|
}
|
71
|
-
|
72
|
-
label { text "Status:" }
|
71
|
+
|
72
|
+
label { text "Status:" }
|
73
73
|
label { text bind(presenter, :status) }
|
74
|
-
|
75
|
-
button {
|
74
|
+
|
75
|
+
button {
|
76
76
|
text "Login"
|
77
77
|
enabled bind(presenter, :logged_out)
|
78
78
|
on_widget_selected { presenter.login }
|
79
79
|
}
|
80
|
-
|
81
|
-
button {
|
80
|
+
|
81
|
+
button {
|
82
82
|
text "Logout"
|
83
83
|
enabled bind(presenter, :logged_in)
|
84
84
|
on_widget_selected { presenter.logout }
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Glimmer Tree Data Binding" do
|
4
|
+
include Glimmer
|
5
|
+
|
6
|
+
include_package 'org.eclipse.swt'
|
7
|
+
include_package 'org.eclipse.swt.widgets'
|
8
|
+
include_package 'org.eclipse.swt.layout'
|
9
|
+
|
10
|
+
before do
|
11
|
+
dsl :swt
|
12
|
+
end
|
13
|
+
|
14
|
+
after do
|
15
|
+
@target.display.dispose if @target && @target.display
|
16
|
+
end
|
17
|
+
|
18
|
+
class Person
|
19
|
+
attr_accessor :name, :age, :adult, :people
|
20
|
+
end
|
21
|
+
|
22
|
+
class Manager < Person
|
23
|
+
def initialize
|
24
|
+
@people = []
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_accessor :people
|
28
|
+
end
|
29
|
+
|
30
|
+
class Company
|
31
|
+
def initialize
|
32
|
+
@owner = []
|
33
|
+
end
|
34
|
+
|
35
|
+
attr_accessor :owner
|
36
|
+
end
|
37
|
+
|
38
|
+
it "data binds text widget to a string property" do
|
39
|
+
person1 = Person.new
|
40
|
+
person1.name = "Bruce Ting"
|
41
|
+
person1.age = 45
|
42
|
+
person1.adult = true
|
43
|
+
|
44
|
+
person2 = Person.new
|
45
|
+
person2.name = "Julia Fang"
|
46
|
+
person2.age = 17
|
47
|
+
person2.adult = false
|
48
|
+
|
49
|
+
manager = Manager.new
|
50
|
+
manager.name = "Tim Harkins"
|
51
|
+
manager.age = 79
|
52
|
+
manager.adult = true
|
53
|
+
manager.people << person1
|
54
|
+
manager.people << person2
|
55
|
+
|
56
|
+
company = Company.new
|
57
|
+
company.owner = manager
|
58
|
+
|
59
|
+
@target = shell {
|
60
|
+
@tree = tree(:virtual, :border) {
|
61
|
+
items bind(company, :owner), tree_properties(children: :people, text: :name)
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
expect(@tree.widget.getItems.size).to eq(1)
|
66
|
+
|
67
|
+
rootNode = @tree.widget.getItems[0]
|
68
|
+
expect(rootNode.getText()).to eq("Tim Harkins")
|
69
|
+
|
70
|
+
expect(rootNode.getItems.size).to eq(2)
|
71
|
+
node1 = rootNode.getItems[0]
|
72
|
+
node2 = rootNode.getItems[1]
|
73
|
+
expect(node1.getText()).to eq("Bruce Ting")
|
74
|
+
expect(node2.getText()).to eq("Julia Fang")
|
75
|
+
|
76
|
+
manager.name = "Tim Lee Harkins"
|
77
|
+
|
78
|
+
rootNode = @tree.widget.getItems[0]
|
79
|
+
expect(rootNode.getText()).to eq("Tim Lee Harkins")
|
80
|
+
|
81
|
+
person1.name = "Bruce A. Ting"
|
82
|
+
node1 = @tree.widget.getItems.first.getItems.first
|
83
|
+
expect(node1.getText()).to eq("Bruce A. Ting")
|
84
|
+
|
85
|
+
person2.name = "Julia Katherine Fang"
|
86
|
+
node2 = @tree.widget.getItems.first.getItems.last
|
87
|
+
expect(node2.getText()).to eq("Julia Katherine Fang")
|
88
|
+
|
89
|
+
person3 = Person.new
|
90
|
+
person3.name = "Bob David Kennith"
|
91
|
+
person3.age = 37
|
92
|
+
person3.adult = true
|
93
|
+
|
94
|
+
manager.people << person3
|
95
|
+
manager.people = manager.people
|
96
|
+
|
97
|
+
rootNode = @tree.widget.getItems.first
|
98
|
+
expect(rootNode.getItems.size).to eq(3)
|
99
|
+
node3 = rootNode.getItems.last
|
100
|
+
expect(node3.getText()).to eq("Bob David Kennith")
|
101
|
+
|
102
|
+
manager.people.delete_at(0)
|
103
|
+
|
104
|
+
rootNode = @tree.widget.getItems.first
|
105
|
+
expect(rootNode.getItems.size).to eq(2)
|
106
|
+
node1 = rootNode.getItems.first
|
107
|
+
node2 = rootNode.getItems.last
|
108
|
+
expect(node1.getText()).to eq("Julia Katherine Fang")
|
109
|
+
expect(node2.getText()).to eq("Bob David Kennith")
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -13,6 +13,7 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
13
13
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'samples'))
|
14
14
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
15
15
|
require 'glimmer'
|
16
|
+
require 'puts_debuggerer'
|
16
17
|
# This file was generated by the `rspec --init` command. Conventionally, all
|
17
18
|
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
18
19
|
# The generated `.rspec` file contains `--require spec_helper` which will cause
|
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.1.
|
4
|
+
version: 0.1.9.470
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AndyMaleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-07-
|
11
|
+
date: 2017-07-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,7 +44,7 @@ dependencies:
|
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: 3.5.0
|
47
|
-
name: rspec
|
47
|
+
name: rspec-mocks
|
48
48
|
prerelease: false
|
49
49
|
type: :development
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -58,7 +58,7 @@ dependencies:
|
|
58
58
|
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: 3.5.0
|
61
|
-
name: rspec
|
61
|
+
name: rspec
|
62
62
|
prerelease: false
|
63
63
|
type: :development
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -139,17 +139,17 @@ dependencies:
|
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
requirement: !ruby/object:Gem::Requirement
|
141
141
|
requirements:
|
142
|
-
- -
|
142
|
+
- - "~>"
|
143
143
|
- !ruby/object:Gem::Version
|
144
|
-
version: 0.
|
144
|
+
version: 0.7.1
|
145
145
|
name: puts_debuggerer
|
146
146
|
prerelease: false
|
147
147
|
type: :development
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- -
|
150
|
+
- - "~>"
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version: 0.
|
152
|
+
version: 0.7.1
|
153
153
|
description: JRuby DSL that enables easy and efficient authoring of user-interfaces
|
154
154
|
using the robust platform-independent Eclipse SWT library
|
155
155
|
email: andy.am@gmail.com
|
@@ -180,6 +180,7 @@ files:
|
|
180
180
|
- lib/command_handler_chain_factory.rb
|
181
181
|
- lib/command_handler_chain_link.rb
|
182
182
|
- lib/command_handlers.rb
|
183
|
+
- lib/command_handlers/RELEASE.md
|
183
184
|
- lib/command_handlers/bind_command_handler.rb
|
184
185
|
- lib/command_handlers/combo_selection_data_binding_command_handler.rb
|
185
186
|
- lib/command_handlers/data_binding_command_handler.rb
|
@@ -195,11 +196,14 @@ files:
|
|
195
196
|
- lib/command_handlers/models/r_widget_listener.rb
|
196
197
|
- lib/command_handlers/models/r_widget_packages.rb
|
197
198
|
- lib/command_handlers/models/table_items_updater.rb
|
199
|
+
- lib/command_handlers/models/tree_items_updater.rb
|
198
200
|
- lib/command_handlers/models/widget_observer.rb
|
199
201
|
- lib/command_handlers/shell_command_handler.rb
|
200
202
|
- lib/command_handlers/tab_item_command_handler.rb
|
201
203
|
- lib/command_handlers/table_column_properties_data_binding_command_handler.rb
|
202
204
|
- lib/command_handlers/table_items_data_binding_command_handler.rb
|
205
|
+
- lib/command_handlers/tree_items_data_binding_command_handler.rb
|
206
|
+
- lib/command_handlers/tree_properties_data_binding_command_handler.rb
|
203
207
|
- lib/command_handlers/widget_command_handler.rb
|
204
208
|
- lib/command_handlers/widget_listener_command_handler.rb
|
205
209
|
- lib/command_handlers/widget_method_command_handler.rb
|
@@ -242,6 +246,7 @@ files:
|
|
242
246
|
- spec/lib/glimmer__shine_data_binding__spec.rb
|
243
247
|
- spec/lib/glimmer__tab_item__spec.rb
|
244
248
|
- spec/lib/glimmer__table_data_binding__spec.rb
|
249
|
+
- spec/lib/glimmer__tree_data_binding__spec.rb
|
245
250
|
- spec/lib/glimmer_spec.rb
|
246
251
|
- spec/lib/xml/glimmer_xml_spec.rb
|
247
252
|
- spec/samples/contactmanager/contact_manager_presenter_spec.rb
|