glimmer 0.1.8.470 → 0.1.9.470
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/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
|