glimmer 0.4.7 → 0.4.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.markdown +95 -45
- data/bin/girb +2 -1
- data/bin/girb_runner.rb +1 -0
- data/lib/glimmer.rb +11 -0
- data/lib/glimmer/command_handler_chain_link.rb +4 -2
- data/lib/glimmer/swt/command_handlers/custom_widget_command_handler.rb +1 -1
- data/lib/glimmer/swt/custom_widget.rb +21 -8
- data/lib/glimmer/swt/g_color.rb +2 -0
- data/lib/glimmer/swt/g_shell.rb +4 -0
- data/lib/glimmer/swt/model_binding.rb +5 -0
- data/lib/glimmer/swt/observable_model.rb +3 -0
- data/lib/glimmer/swt/observer.rb +9 -0
- data/lib/glimmer/swt/video.rb +133 -0
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e11298f6aa21de3c113c3c9169df23a9181b2501e7d33e7fc62e3d18dec37f8
|
4
|
+
data.tar.gz: eca26276e4afebd498174332cc7360044afffe71d48663ca3d95feb657b17b57
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cff2e454cdc6100893a100bdb5fd6e0b1b300f6c384f4c8a9722deb677d3cf83fd86f14462e7661b9523b06df43c93f6e1499bb5ab1ea77dfa0283a6c64537d2
|
7
|
+
data.tar.gz: 820f9b260ce6c068ccf69274c73074739b983047050c517b0c511d992d903ff66e904f283224a5b837d29da69cd03f5549e6d36434bbe8fe702edef67df5ea29
|
data/README.markdown
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Glimmer 0.4.
|
1
|
+
# Glimmer 0.4.8 Beta (JRuby Desktop UI DSL + Data-Binding)
|
2
2
|
[![Coverage Status](https://coveralls.io/repos/github/AndyObtiva/glimmer/badge.svg?branch=master)](https://coveralls.io/github/AndyObtiva/glimmer?branch=master)
|
3
3
|
|
4
4
|
Glimmer is a cross-platform Ruby desktop development library. Glimmer's main innovation is a JRuby DSL that enables easy and efficient authoring of desktop application user-interfaces while relying on the robust platform-independent Eclipse SWT library. Glimmer additionally innovates by having built-in desktop UI 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 components test-first afterward.
|
@@ -26,13 +26,14 @@ glimmer samples/hello_world.rb
|
|
26
26
|
|
27
27
|
Glimmer app:
|
28
28
|
|
29
|
-
![Hello World](
|
29
|
+
![Hello World](images/glimmer-hello-world.png)
|
30
30
|
|
31
31
|
### Tic Tac Toe
|
32
32
|
|
33
33
|
Glimmer code (from `samples/tictactoe/tic_tac_toe.rb`):
|
34
34
|
|
35
35
|
```ruby
|
36
|
+
# ...
|
36
37
|
shell {
|
37
38
|
text "Tic-Tac-Toe"
|
38
39
|
composite {
|
@@ -51,6 +52,7 @@ shell {
|
|
51
52
|
}
|
52
53
|
}
|
53
54
|
}
|
55
|
+
# ...
|
54
56
|
```
|
55
57
|
|
56
58
|
Run:
|
@@ -61,7 +63,7 @@ glimmer samples/tictactoe/tic_tac_toe.rb
|
|
61
63
|
|
62
64
|
Glimmer app:
|
63
65
|
|
64
|
-
![Tic Tac Toe](
|
66
|
+
![Tic Tac Toe](images/glimmer-tic-tac-toe.png)
|
65
67
|
|
66
68
|
NOTE: Glimmer is in beta mode. Please help make better by adopting for small or low risk projects and providing feedback.
|
67
69
|
|
@@ -105,14 +107,14 @@ Please follow these instructions to make the `glimmer` command available on your
|
|
105
107
|
|
106
108
|
Run this command to install directly:
|
107
109
|
```
|
108
|
-
jgem install glimmer -v 0.4.
|
110
|
+
jgem install glimmer -v 0.4.8
|
109
111
|
```
|
110
112
|
|
111
113
|
### Option 2: Bundler
|
112
114
|
|
113
115
|
Add the following to `Gemfile`:
|
114
116
|
```
|
115
|
-
gem 'glimmer', '~> 0.4.
|
117
|
+
gem 'glimmer', '~> 0.4.8'
|
116
118
|
```
|
117
119
|
|
118
120
|
And, then run:
|
@@ -120,7 +122,7 @@ And, then run:
|
|
120
122
|
bundle install
|
121
123
|
```
|
122
124
|
|
123
|
-
## Glimmer
|
125
|
+
## Glimmer Command
|
124
126
|
|
125
127
|
Usage:
|
126
128
|
```
|
@@ -132,10 +134,14 @@ the glimmer ruby gem and SWT jar dependency.
|
|
132
134
|
|
133
135
|
Example:
|
134
136
|
```
|
135
|
-
glimmer hello_world.rb
|
137
|
+
glimmer samples/hello_world.rb
|
136
138
|
```
|
137
139
|
This runs the Glimmer application hello_world.rb
|
138
140
|
|
141
|
+
## Girb (Glimmer irb) Command
|
142
|
+
|
143
|
+
With Glimmer installed, you may want to run `girb` instead of standard `irb` to have SWT preloaded and the Glimmer library required and included for quick Glimmer coding/testing.
|
144
|
+
|
139
145
|
## Glimmer DSL Syntax
|
140
146
|
|
141
147
|
### Widgets
|
@@ -146,7 +152,7 @@ https://www.eclipse.org/swt/widgets/
|
|
146
152
|
|
147
153
|
This screenshot taken from the link above should give a glimpse of how SWT widgets look and feel:
|
148
154
|
|
149
|
-
![SWT Widgets](
|
155
|
+
![SWT Widgets](images/glimmer-swt-widgets.png)
|
150
156
|
|
151
157
|
In Glimmer DSL, widgets are declared with lowercase underscored names mirroring their SWT names minus the package name:
|
152
158
|
|
@@ -165,11 +171,9 @@ In Glimmer DSL, widgets are declared with lowercase underscored names mirroring
|
|
165
171
|
|
166
172
|
A **widget** name is followed by a Ruby block that contains the widget **properties** and **content**. Optionally, an SWT **style** ***argument*** may also be passed (see [next section](#widget-styles) for details).
|
167
173
|
|
168
|
-
For example, if we were to revisit `hello_world.rb` above:
|
174
|
+
For example, if we were to revisit `samples/hello_world.rb` above:
|
169
175
|
|
170
176
|
```ruby
|
171
|
-
include Glimmer
|
172
|
-
|
173
177
|
shell {
|
174
178
|
text "Glimmer"
|
175
179
|
label {
|
@@ -183,10 +187,12 @@ Note that `shell` instantiates the outer shell **widget**, in other words, the w
|
|
183
187
|
`shell` is then followed by a ***block*** that contains
|
184
188
|
|
185
189
|
```ruby
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
+
# ...
|
191
|
+
text "Glimmer" # text property of shell
|
192
|
+
label { # label widget declaration
|
193
|
+
text "Hello World!" # text property of label
|
194
|
+
}
|
195
|
+
# ...
|
190
196
|
```
|
191
197
|
|
192
198
|
The first line declares a **property** called `text`, which sets the title of the shell (window) to `"Glimmer"`. **Properties** always have ***arguments***, such as the text `"Glimmer"` in this case, and do **NOT** have a ***block***.
|
@@ -200,19 +206,20 @@ After it is declared, a `shell` must be opened with the `#open` method, which ca
|
|
200
206
|
```ruby
|
201
207
|
@shell = shell {
|
202
208
|
# properties and content
|
209
|
+
# ...
|
203
210
|
}
|
204
211
|
@shell.open
|
205
212
|
```
|
206
213
|
|
207
214
|
It is centered upon initial display and has a minimum width of 130 (can be re-centered when needed with `@shell.center` method after capturing `shell` in a `@shell` variable as per samples)
|
208
215
|
|
209
|
-
Check out the [samples](
|
216
|
+
Check out the [samples](samples) directory for more examples.
|
210
217
|
|
211
|
-
Example from [hello_tab.rb](
|
218
|
+
Example from [hello_tab.rb](samples/hello_tab.rb) sample:
|
212
219
|
|
213
|
-
![Hello Tab 1](
|
220
|
+
![Hello Tab 1](images/glimmer-hello-tab1.png)
|
214
221
|
|
215
|
-
![Hello Tab 2](
|
222
|
+
![Hello Tab 2](images/glimmer-hello-tab2.png)
|
216
223
|
|
217
224
|
```ruby
|
218
225
|
shell {
|
@@ -234,7 +241,46 @@ shell {
|
|
234
241
|
}.open
|
235
242
|
```
|
236
243
|
|
237
|
-
|
244
|
+
#### Video Widget
|
245
|
+
|
246
|
+
![Video Widget](images/glimmer-video-widget.png)
|
247
|
+
|
248
|
+
Glimmer comes with a video widget not in SWT. It comes with very basic video functionality at the moment, such as autoplay by default, displaying controls, looping, and setting background.
|
249
|
+
|
250
|
+
Attributes (passed in an options hash as arguments to video widget):
|
251
|
+
- `autoplay` (true [default] or false): plays video automatically as soon as loaded
|
252
|
+
- `controls` (true [default] or false): displays controls
|
253
|
+
- `looped` (true or false [default]): plays video in looped mode
|
254
|
+
- `background` (Glimmer color [default: white]): sets background color just like with any other widget
|
255
|
+
- `fit_to_width` (true [default] or false): fits video width to widget allotted width regardless of video's original size. Maintains video aspect ratio.
|
256
|
+
- `fit_to_height` (true [default] or false): fits video height to widget allotted height regardless of video's original size. Maintains video aspect ratio.
|
257
|
+
- `offset_x` (integer [default: 0]): offset from left border. Could be a negative number if you want to show only an area of the video. Useful when fit_to_width is false to pick an area of the video to display.
|
258
|
+
- `offset_y` (integer [default: 0]): offset from top border. Could be a negative number if you want to show only an area of the video. Useful when fit_to_height is false to pick an area of the video to display.
|
259
|
+
|
260
|
+
Methods:
|
261
|
+
- `play`: plays video
|
262
|
+
- `pause`: pauses video
|
263
|
+
|
264
|
+
Example ([samples/video/hello_video.rb](samples/video/hello_video.rb)):
|
265
|
+
|
266
|
+
```ruby
|
267
|
+
# ...
|
268
|
+
shell {
|
269
|
+
video(file: video_file)
|
270
|
+
}.open
|
271
|
+
```
|
272
|
+
|
273
|
+
Example ([samples/video/hello_looped_video_with_black_background.rb](samples/video/hello_looped_video_with_black_background.rb)):
|
274
|
+
|
275
|
+
```ruby
|
276
|
+
# ...
|
277
|
+
shell {
|
278
|
+
minimum_size 1024, 640
|
279
|
+
video(file: video_file, looped: true, background: :black)
|
280
|
+
}.open
|
281
|
+
```
|
282
|
+
|
283
|
+
#### Browser Widget
|
238
284
|
|
239
285
|
Glimmer supports SWT Browser widget, which can load URLs (including media) or render HTML (useful in embedding videos). It can even be instrumented with JavaScript when needed (though highly discouraged except for rare cases when leveraging a pre-existing web codebase in a desktop app).
|
240
286
|
|
@@ -242,10 +288,11 @@ Example loading a URL:
|
|
242
288
|
|
243
289
|
```ruby
|
244
290
|
shell {
|
291
|
+
minimum_size 1024, 860
|
245
292
|
browser {
|
246
|
-
url 'http://
|
293
|
+
url 'http://brightonresort.com/about'
|
247
294
|
}
|
248
|
-
}
|
295
|
+
}.open
|
249
296
|
```
|
250
297
|
|
251
298
|
Example rendering HTML with an embedded video:
|
@@ -258,7 +305,7 @@ shell {
|
|
258
305
|
<head>
|
259
306
|
</head>
|
260
307
|
<body>
|
261
|
-
<video id="
|
308
|
+
<video id="video" width="100%" height="100%">
|
262
309
|
<source src="file://#{video_file}" type="video/mp4">
|
263
310
|
Your browser does not support the video tag.
|
264
311
|
</video>
|
@@ -266,10 +313,10 @@ shell {
|
|
266
313
|
</html>
|
267
314
|
HTML
|
268
315
|
on_completed { # on load of the page execute this JavaScript
|
269
|
-
@browser.widget.execute("document.getElementById('
|
316
|
+
@browser.widget.execute("document.getElementById('video').play()")
|
270
317
|
}
|
271
318
|
}
|
272
|
-
}
|
319
|
+
}.open
|
273
320
|
```
|
274
321
|
|
275
322
|
### Widget Styles
|
@@ -320,13 +367,13 @@ You may check out all available `SWT` styles here:
|
|
320
367
|
|
321
368
|
https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/SWT.html
|
322
369
|
|
323
|
-
|
370
|
+
#### Advanced case outside of standard Glimmer DSL
|
324
371
|
|
325
372
|
When building a widget-related SWT object manually (e.g. `GridData.new(...)`), you are expected to use `SWT::CONSTANT` directly or BIT-OR a few SWT constants together like `SWT::BORDER | SWT::V_SCROLL`.
|
326
373
|
|
327
374
|
Glimmer facilitates that with `GSWT` class by allowing you to pass multiple styles as an argument array of symbols instead of dealing with BIT-OR. For example: `GSWT[:border, :v_scroll]`
|
328
375
|
|
329
|
-
|
376
|
+
#### Non-resizable Window
|
330
377
|
|
331
378
|
SWT Shell widget by default is resizable. To make it non-resizable, one must pass a complicated style bit concoction like `GSWT[:shell_trim] & (~GSWT[:resize]) & (~GSWT[:max])`.
|
332
379
|
|
@@ -460,7 +507,7 @@ composite {
|
|
460
507
|
}
|
461
508
|
```
|
462
509
|
|
463
|
-
Here is a more sophisticated example taken from [hello_computed.rb](
|
510
|
+
Here is a more sophisticated example taken from [hello_computed.rb](samples/hellocomputed/hello_computed.rb) sample:
|
464
511
|
```ruby
|
465
512
|
shell {
|
466
513
|
text "Hello Computed"
|
@@ -617,11 +664,11 @@ The 5th example demonstrates computed value data binding whereby the value of `n
|
|
617
664
|
|
618
665
|
The 6th example demonstrates nested indexed computed value data binding whereby the value of `profiles[0].name` depends on changes to both nested `profiles[0].first_name` and `profiles[0].last_name`.
|
619
666
|
|
620
|
-
Example from [hello_combo.rb](
|
667
|
+
Example from [hello_combo.rb](samples/hello_combo.rb) sample:
|
621
668
|
|
622
|
-
![Hello Combo](
|
669
|
+
![Hello Combo](images/glimmer-hello-combo.png)
|
623
670
|
|
624
|
-
![Hello Combo](
|
671
|
+
![Hello Combo](images/glimmer-hello-combo-expanded.png)
|
625
672
|
|
626
673
|
```ruby
|
627
674
|
class Person
|
@@ -662,9 +709,9 @@ HelloCombo.new.launch
|
|
662
709
|
|
663
710
|
`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.
|
664
711
|
|
665
|
-
Example from [hello_list_single_selection.rb](
|
712
|
+
Example from [hello_list_single_selection.rb](samples/hello_list_single_selection.rb) sample:
|
666
713
|
|
667
|
-
![Hello List Single Selection](
|
714
|
+
![Hello List Single Selection](images/glimmer-hello-list-single-selection.png)
|
668
715
|
|
669
716
|
```ruby
|
670
717
|
shell {
|
@@ -686,7 +733,7 @@ shell {
|
|
686
733
|
|
687
734
|
Nonetheless, in the next example, a multi-selection list is declared instead allowing data-binding of multiple selection values to the bindable attribute on the model.
|
688
735
|
|
689
|
-
![Hello List Multi Selection](
|
736
|
+
![Hello List Multi Selection](images/glimmer-hello-list-multi-selection.png)
|
690
737
|
|
691
738
|
```ruby
|
692
739
|
class Person
|
@@ -739,7 +786,7 @@ The Glimmer code is not much different from above except for passing the `:multi
|
|
739
786
|
|
740
787
|
Note that in all the data-binding examples above, there was also an observer attached to the `button` widget to trigger an action on the model, which in turn triggers a data-binding update on the `list` or `combo`. Observers will be discussed in more details in the [next section](#observer).
|
741
788
|
|
742
|
-
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](
|
789
|
+
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.
|
743
790
|
|
744
791
|
### Observer
|
745
792
|
|
@@ -869,6 +916,7 @@ Definition:
|
|
869
916
|
```ruby
|
870
917
|
class RedLabel
|
871
918
|
include Glimmer::SWT::CustomWidget
|
919
|
+
|
872
920
|
def body
|
873
921
|
label(swt_style) {
|
874
922
|
background :red
|
@@ -895,6 +943,7 @@ Definition:
|
|
895
943
|
module Red
|
896
944
|
class Composite
|
897
945
|
include Glimmer::SWT::CustomWidget
|
946
|
+
|
898
947
|
def body
|
899
948
|
composite(swt_style) {
|
900
949
|
background :red
|
@@ -917,12 +966,16 @@ shell {
|
|
917
966
|
|
918
967
|
Notice how `Red::Composite` became `red__composite` with double-underscore, which is how Glimmer Custom Widgets signify namespaces by convention.
|
919
968
|
|
920
|
-
Custom Widgets have the following attributes available to call from inside the `#body` method:
|
969
|
+
Custom Widgets have the following attributes (attribute readers) available to call from inside the `#body` method:
|
921
970
|
- `#parent`: Glimmer object parenting custom widget
|
922
971
|
- `#swt_style`: SWT style integer. Can be useful if you want to allow consumers to customize a widget inside the custom widget body
|
923
|
-
- `#options`: a hash of options passed in parentheses when declaring a custom widget (useful for passing in model data) (e.g. `calendar(events: events)`). Custom widget class can declare option names (array) with `.options` method as shown below (not to be confused with `#options` instance method for retrieving options hash containing names & values)
|
972
|
+
- `#options`: a hash of options passed in parentheses when declaring a custom widget (useful for passing in model data) (e.g. `calendar(events: events)`). Custom widget class can declare option names (array) with `.options` method as shown below, which generates attribute readers for every option (not to be confused with `#options` instance method for retrieving options hash containing names & values)
|
924
973
|
- `#content`: nested block underneath custom widget. It will be automatically called at the end of processing the custom widget body. Alternatively, the custom widget body may call `content.call` at the place where the content is needed to show up as shown in the following example.
|
925
974
|
|
975
|
+
Additionally, custom widgets can call the following class methods:
|
976
|
+
- `.options`: declares a list of options by taking an option name array (symbols/strings). This generates option attribute readers (e.g. `options :orientation, :bg_color` generates `#orientation` and `#bg_color` attribute readers)
|
977
|
+
- `.option`: declares a single option taking option name and default value as arguments (also generates an attribute reader just like `.options`)
|
978
|
+
|
926
979
|
**Content/Options Example:**
|
927
980
|
|
928
981
|
Definition:
|
@@ -931,6 +984,7 @@ class Sandwich
|
|
931
984
|
include Glimmer::SWT::CustomWidget
|
932
985
|
|
933
986
|
options :orientation, :bg_color
|
987
|
+
option :fg_color, :black
|
934
988
|
|
935
989
|
def body
|
936
990
|
composite(swt_style) { # gets custom widget style
|
@@ -968,7 +1022,7 @@ The following additional attributes may be called from outside a custom widget i
|
|
968
1022
|
|
969
1023
|
## Samples
|
970
1024
|
|
971
|
-
Check the [samples](
|
1025
|
+
Check the [samples](samples) directory for examples on how to write Glimmer applications. To run a sample, make sure to install the `glimmer` gem first and then use the `glimmer` command to run it (alternatively, you may clone the repo, follow [CONTRIBUTING.md](CONTRIBUTING.md) instructions, and run samples locally with development glimmer command: `bin/glimmer --dev`).
|
972
1026
|
|
973
1027
|
Examples:
|
974
1028
|
|
@@ -1029,10 +1083,6 @@ This allows you to call SWT Java classes from Ruby without mentioning package na
|
|
1029
1083
|
|
1030
1084
|
For example, after imports, `org.eclipse.swt.graphics.Color` can be referenced by just `Color`
|
1031
1085
|
|
1032
|
-
## Girb (Glimmer irb)
|
1033
|
-
|
1034
|
-
With Glimmer installed, you may run want to run `girb` instead of standard `irb` to have SWT preloaded and the Glimmer library required and included for quick Glimmer coding/testing.
|
1035
|
-
|
1036
1086
|
## Logging
|
1037
1087
|
|
1038
1088
|
Glimmer comes with a Ruby Logger accessible via `Glimmer.logger`
|
@@ -1095,15 +1145,15 @@ jruby -J-XstartOnFirstThread -J-classpath "path_to/swt.jar" -r glimmer -S applic
|
|
1095
1145
|
|
1096
1146
|
These features have been suggested. You might see them in a future version of Glimmer. You are welcome to contribute more feature suggestions.
|
1097
1147
|
|
1098
|
-
[TODO.md](
|
1148
|
+
[TODO.md](TODO.md)
|
1099
1149
|
|
1100
1150
|
## Change Log
|
1101
1151
|
|
1102
|
-
[CHANGELOG.md](
|
1152
|
+
[CHANGELOG.md](CHANGELOG.md)
|
1103
1153
|
|
1104
1154
|
## Contributing
|
1105
1155
|
|
1106
|
-
[CONTRIBUTING.md](
|
1156
|
+
[CONTRIBUTING.md](CONTRIBUTING.md)
|
1107
1157
|
|
1108
1158
|
## Contributors
|
1109
1159
|
|
data/bin/girb
CHANGED
data/bin/girb_runner.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
include Glimmer
|
data/lib/glimmer.rb
CHANGED
@@ -11,9 +11,11 @@ require "java"
|
|
11
11
|
require_relative "glimmer/parent"
|
12
12
|
require_relative "glimmer/swt_packages" #TODO move into SWT namespace
|
13
13
|
require_relative "glimmer/swt/custom_widget"
|
14
|
+
require_relative 'glimmer/swt/video' # TODO offload to a custom widget directory
|
14
15
|
require_relative "glimmer/ext/module"
|
15
16
|
|
16
17
|
module Glimmer
|
18
|
+
REGEX_METHODS_EXCLUDED = /^(to_|\[)/
|
17
19
|
#TODO make it configurable to include or not include
|
18
20
|
include SwtPackages
|
19
21
|
def self.included(klass)
|
@@ -30,12 +32,21 @@ module Glimmer
|
|
30
32
|
@@logger
|
31
33
|
end
|
32
34
|
|
35
|
+
# TODO calling original method_missing after aliasing for cases where method_missing is not needed, like known excluded symbols
|
36
|
+
|
37
|
+
alias method_missing_without_glimmer method_missing
|
33
38
|
def self.method_missing(method_symbol, *args, &block)
|
39
|
+
if method_symbol.to_s.match(REGEX_METHODS_EXCLUDED)
|
40
|
+
return method_missing_without_glimmer(method_symbol, *args, &block)
|
41
|
+
end
|
34
42
|
Glimmer.logger.debug "method: " + method_symbol.to_s + " and args: " + args.to_s
|
35
43
|
command_handler_chain = CommandHandlerChainFactory.chain
|
36
44
|
return_value = command_handler_chain.handle(@@parent_stack.last, method_symbol, *args, &block)
|
37
45
|
add_contents(return_value, &block)
|
38
46
|
return return_value
|
47
|
+
# rescue => e
|
48
|
+
# Glimmer.logger.error e.message
|
49
|
+
# method_missing_without_glimmer(method_symbol, *args, &block)
|
39
50
|
end
|
40
51
|
|
41
52
|
# TODO come up with a better public name for this and put on gwidgets directly
|
@@ -14,8 +14,10 @@ module Glimmer
|
|
14
14
|
return @next_chain_link.handle(parent, command_symbol, *args, &block)
|
15
15
|
else
|
16
16
|
# TODO see if we need a better response here (e.g. dev mode error raising vs production mode silent failure)
|
17
|
-
Glimmer.logger.error "Command: #{command_symbol} cannot be handled!"
|
18
|
-
|
17
|
+
# Glimmer.logger.error "Command: #{command_symbol} cannot be handled!"
|
18
|
+
Glimmer.logger.debug "Command: #{command_symbol} cannot be handled!"
|
19
|
+
# raise "Command: #{command_symbol} cannot be handled!"
|
20
|
+
nil
|
19
21
|
end
|
20
22
|
end
|
21
23
|
end
|
@@ -14,7 +14,7 @@ module Glimmer
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def do_handle(parent, command_symbol, *args, &block)
|
17
|
-
options = args.
|
17
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
18
18
|
Glimmer.logger.debug "Custom widget #{command_symbol} styles are: [" + args.inspect + "] and options are: #{options}"
|
19
19
|
CustomWidget.for(command_symbol).new(parent, *args, options, &block)
|
20
20
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'set'
|
2
|
-
|
3
1
|
require_relative 'proc_tracker'
|
4
2
|
require_relative 'observable_model'
|
5
3
|
|
@@ -34,17 +32,25 @@ module Glimmer
|
|
34
32
|
# Can be called multiple times to set more options additively.
|
35
33
|
# When passed no arguments, it returns list of all option names captured so far
|
36
34
|
def options(*new_options)
|
37
|
-
new_options = new_options.compact.map(&:to_s)
|
35
|
+
new_options = new_options.compact.map(&:to_s).map(&:to_sym)
|
38
36
|
if new_options.empty?
|
39
|
-
@options ||=
|
37
|
+
@options ||= {} # maps options to defaults
|
40
38
|
else
|
41
|
-
|
39
|
+
new_options = new_options.reduce({}) {|new_options, new_option| new_options.merge(new_option => nil)}
|
40
|
+
@options = options.merge(new_options)
|
42
41
|
def_option_attr_readers(new_options)
|
43
42
|
end
|
44
43
|
end
|
45
44
|
|
45
|
+
def option(new_option, new_option_default = nil)
|
46
|
+
new_option = new_option.to_s.to_sym
|
47
|
+
new_options = {new_option => new_option_default}
|
48
|
+
@options = options.merge(new_options)
|
49
|
+
def_option_attr_readers(new_options)
|
50
|
+
end
|
51
|
+
|
46
52
|
def def_option_attr_readers(new_options)
|
47
|
-
new_options.each do |option|
|
53
|
+
new_options.each do |option, default|
|
48
54
|
class_eval <<-end_eval, __FILE__, __LINE__
|
49
55
|
def #{option}
|
50
56
|
options[:#{option}]
|
@@ -59,7 +65,8 @@ module Glimmer
|
|
59
65
|
def initialize(parent, *swt_constants, options, &content)
|
60
66
|
@parent = parent
|
61
67
|
@swt_style = GSWT[*swt_constants]
|
62
|
-
|
68
|
+
options ||= {}
|
69
|
+
@options = self.class.options.merge(options)
|
63
70
|
@content = ProcTracker.new(content) if content
|
64
71
|
@body_root = body
|
65
72
|
@widget = @body_root.widget
|
@@ -75,12 +82,18 @@ module Glimmer
|
|
75
82
|
@body_root.can_add_listener?(underscored_listener_name)
|
76
83
|
end
|
77
84
|
|
85
|
+
# TODO clean up difference between add_listener and add_observer
|
86
|
+
|
78
87
|
def add_listener(underscored_listener_name, &block)
|
79
88
|
@body_root.add_listener(underscored_listener_name, &block)
|
80
89
|
end
|
81
90
|
|
82
91
|
def add_observer(observer, attribute_name)
|
83
|
-
|
92
|
+
if respond_to?(attribute_name)
|
93
|
+
super
|
94
|
+
else
|
95
|
+
@body_root.add_observer(observer, attribute_name)
|
96
|
+
end
|
84
97
|
end
|
85
98
|
|
86
99
|
def has_attribute?(attribute_name, *args)
|
data/lib/glimmer/swt/g_color.rb
CHANGED
@@ -11,6 +11,8 @@ module Glimmer
|
|
11
11
|
class << self
|
12
12
|
include_package 'org.eclipse.swt'
|
13
13
|
|
14
|
+
# TODO consider refactoring to simply for and returning GColor instead for consistency
|
15
|
+
|
14
16
|
def color_for(display = nil, standard_color)
|
15
17
|
standard_color = "color_#{standard_color}".to_sym unless standard_color.to_s.include?('color_')
|
16
18
|
display ||= GDisplay.instance.display
|
data/lib/glimmer/swt/g_shell.rb
CHANGED
@@ -160,8 +160,13 @@ module Glimmer
|
|
160
160
|
nested_property_observer.observe(model)
|
161
161
|
parent_observer.add_dependent([parent_model, parent_property_name] => [nested_property_observer, model, nil])
|
162
162
|
else
|
163
|
+
# pd property_name, announcer: '[NESTED]', header: true
|
164
|
+
# pd model, announcer: '[NESTED]'
|
165
|
+
# pd nested_property_observer, announcer: '[NESTED]'
|
163
166
|
nested_property_observer.observe(model, property_name)
|
167
|
+
# pd 'DONE ADDING OBSERVER', announcer: '[NESTED]'
|
164
168
|
parent_observer.add_dependent([parent_model, parent_property_name] => [nested_property_observer, model, property_name])
|
169
|
+
# pd 'DONE ADDING DEPENDENT', announcer: '[NESTED]'
|
165
170
|
end
|
166
171
|
end
|
167
172
|
end
|
@@ -21,6 +21,9 @@ module Glimmer
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def add_observer(observer, property_name)
|
24
|
+
# pd property_name, announcer: '[ADD_OBSERVER]'
|
25
|
+
# pd observer, announcer: '[ADD_OBSERVER]'
|
26
|
+
# pd has_observer?(observer, property_name)
|
24
27
|
return observer if has_observer?(observer, property_name)
|
25
28
|
property_observer_list(property_name) << observer
|
26
29
|
add_property_writer_observers(property_name)
|
data/lib/glimmer/swt/observer.rb
CHANGED
@@ -52,15 +52,24 @@ module Glimmer
|
|
52
52
|
# registers observer in an observable on a property (optional)
|
53
53
|
# observer maintains registration list to unregister later
|
54
54
|
def register(observable, property = nil)
|
55
|
+
# pd property, announcer: '[OBSERVE]', header: true
|
56
|
+
# pd observable, announcer: '[OBSERVE]'
|
57
|
+
# pd self, announcer: '[OBSERVE]'
|
55
58
|
unless observable.is_a?(Observable)
|
59
|
+
# pd 'not an observable'
|
56
60
|
# TODO refactor code to be more smart/polymorphic/automated and honor open/closed principle
|
57
61
|
if observable.is_a?(Array)
|
62
|
+
# pd 'array'
|
58
63
|
observable.extend(ObservableArray)
|
59
64
|
else
|
65
|
+
# pd 'not array'
|
60
66
|
observable.extend(ObservableModel)
|
61
67
|
end
|
62
68
|
end
|
69
|
+
# pd 'adding observer', announcer: '[OBSERVE]'
|
70
|
+
# pd [self, property], announcer: '[OBSERVE]'
|
63
71
|
observable.add_observer(*[self, property].compact)
|
72
|
+
# pd 'adding registration', announcer: '[OBSERVE]'
|
64
73
|
[observable, property].tap do |registration|
|
65
74
|
self.registrations << registration
|
66
75
|
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require_relative 'custom_widget'
|
2
|
+
require_relative 'g_color'
|
3
|
+
|
4
|
+
#TODO display progress wheel while loading video
|
5
|
+
|
6
|
+
module Glimmer
|
7
|
+
module SWT
|
8
|
+
class Video
|
9
|
+
PROPERTIES_OBSERVED = [
|
10
|
+
'playing',
|
11
|
+
'paused',
|
12
|
+
'ended',
|
13
|
+
'started',
|
14
|
+
'remaining',
|
15
|
+
'current_time',
|
16
|
+
]
|
17
|
+
|
18
|
+
include_package 'org.eclipse.swt.browser'
|
19
|
+
|
20
|
+
include Glimmer::SWT::CustomWidget
|
21
|
+
|
22
|
+
options :file, :url
|
23
|
+
option :autoplay, true
|
24
|
+
option :controls, true
|
25
|
+
option :looped, false
|
26
|
+
option :background, :white
|
27
|
+
option :fit_to_width, true
|
28
|
+
option :fit_to_height, true
|
29
|
+
option :offset_x, 0
|
30
|
+
option :offset_y, 0
|
31
|
+
|
32
|
+
alias autoplay? autoplay
|
33
|
+
alias controls? controls
|
34
|
+
alias looped? looped
|
35
|
+
alias fit_to_width? fit_to_width
|
36
|
+
alias fit_to_height? fit_to_height
|
37
|
+
|
38
|
+
def body
|
39
|
+
browser {
|
40
|
+
text <<~HTML
|
41
|
+
<html>
|
42
|
+
<head>
|
43
|
+
<style id="style">
|
44
|
+
body {
|
45
|
+
margin: 0;
|
46
|
+
padding: 0;
|
47
|
+
}
|
48
|
+
</style>
|
49
|
+
<style id="style-body-background">
|
50
|
+
body {
|
51
|
+
background: #{browser_body_background};
|
52
|
+
}
|
53
|
+
</style>
|
54
|
+
<style id="style-body-offset-x">
|
55
|
+
body {
|
56
|
+
margin-left: #{browser_body_offset_x}px;
|
57
|
+
}
|
58
|
+
</style>
|
59
|
+
<style id="style-body-offset-y">
|
60
|
+
body {
|
61
|
+
margin-top: #{browser_body_offset_y}px;
|
62
|
+
}
|
63
|
+
</style>
|
64
|
+
</head>
|
65
|
+
<body>
|
66
|
+
<video id="video" #{browser_video_width} #{browser_video_height} #{browser_video_loop} #{browser_video_controls} #{browser_video_autoplay}>
|
67
|
+
<source id="source" src="#{source}" type="video/mp4">
|
68
|
+
Your browser does not support the video tag.
|
69
|
+
</video>
|
70
|
+
</body>
|
71
|
+
</html>
|
72
|
+
HTML
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
def source
|
77
|
+
file ? "file://#{file}" : url
|
78
|
+
end
|
79
|
+
|
80
|
+
def play
|
81
|
+
video_action('play')
|
82
|
+
end
|
83
|
+
|
84
|
+
def pause
|
85
|
+
video_action('pause')
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def video_action(action)
|
91
|
+
widget.execute("document.getElementById('video').#{action}()")
|
92
|
+
end
|
93
|
+
|
94
|
+
def browser_video_autoplay
|
95
|
+
'autoplay' if autoplay?
|
96
|
+
end
|
97
|
+
|
98
|
+
def browser_video_controls
|
99
|
+
'controls' if controls?
|
100
|
+
end
|
101
|
+
|
102
|
+
def browser_video_loop
|
103
|
+
'loop' if looped?
|
104
|
+
end
|
105
|
+
|
106
|
+
def browser_video_width
|
107
|
+
"width='100%'" if fit_to_width
|
108
|
+
end
|
109
|
+
|
110
|
+
def browser_video_height
|
111
|
+
"height='100%'" if fit_to_height
|
112
|
+
end
|
113
|
+
|
114
|
+
def browser_body_background
|
115
|
+
color = background
|
116
|
+
if color.is_a?(Symbol) || color.is_a?(String)
|
117
|
+
color = GColor.color_for(parent.widget.getDisplay, color)
|
118
|
+
elsif color.is_a?(GColor)
|
119
|
+
color = color.color
|
120
|
+
end
|
121
|
+
"rgba(#{color.getRed}, #{color.getGreen}, #{color.getBlue}, #{color.getAlpha})"
|
122
|
+
end
|
123
|
+
|
124
|
+
def browser_body_offset_x
|
125
|
+
offset_x
|
126
|
+
end
|
127
|
+
|
128
|
+
def browser_body_offset_y
|
129
|
+
offset_y
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
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.4.
|
4
|
+
version: 0.4.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AndyMaleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-03-
|
11
|
+
date: 2020-03-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
requirements:
|
44
44
|
- - '='
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: 1.3.
|
46
|
+
version: 1.3.1
|
47
47
|
name: super_module
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
@@ -51,7 +51,7 @@ dependencies:
|
|
51
51
|
requirements:
|
52
52
|
- - '='
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 1.3.
|
54
|
+
version: 1.3.1
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
@@ -164,6 +164,7 @@ files:
|
|
164
164
|
- LICENSE.txt
|
165
165
|
- README.markdown
|
166
166
|
- bin/girb
|
167
|
+
- bin/girb_runner.rb
|
167
168
|
- bin/glimmer
|
168
169
|
- lib/glimmer.rb
|
169
170
|
- lib/glimmer/command_handler.rb
|
@@ -213,6 +214,7 @@ files:
|
|
213
214
|
- lib/glimmer/swt/proc_tracker.rb
|
214
215
|
- lib/glimmer/swt/table_items_binding.rb
|
215
216
|
- lib/glimmer/swt/tree_items_binding.rb
|
217
|
+
- lib/glimmer/swt/video.rb
|
216
218
|
- lib/glimmer/swt/widget_binding.rb
|
217
219
|
- lib/glimmer/swt_packages.rb
|
218
220
|
- lib/glimmer/xml/command_handlers/html_command_handler.rb
|