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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8f82e6793a331105407650a919d3d973f360c9e0c5e6bd49d185bd44dd9ec745
4
- data.tar.gz: 190ea8ddbe57f41100e9fa539f4e9465b9d621418e3f00e291b91103f04484ce
3
+ metadata.gz: 2e11298f6aa21de3c113c3c9169df23a9181b2501e7d33e7fc62e3d18dec37f8
4
+ data.tar.gz: eca26276e4afebd498174332cc7360044afffe71d48663ca3d95feb657b17b57
5
5
  SHA512:
6
- metadata.gz: b57d3b3d4754fc2d5229c3ec2c2e7518336091b1d305a1d4c2d6b1b601a50245f75340ba2dc213168349408389f324afeeeb734ae81faa2045dd6d6e0e5d7da3
7
- data.tar.gz: b2fd672bed1bf48b99c7e92ad8b82fb910c0d0330b78152fbf3cbe4a6c33e34dae4a0ed945ab2e646492af2daad1f9a224488ee5064a7d4f6650f6238882f86e
6
+ metadata.gz: cff2e454cdc6100893a100bdb5fd6e0b1b300f6c384f4c8a9722deb677d3cf83fd86f14462e7661b9523b06df43c93f6e1499bb5ab1ea77dfa0283a6c64537d2
7
+ data.tar.gz: 820f9b260ce6c068ccf69274c73074739b983047050c517b0c511d992d903ff66e904f283224a5b837d29da69cd03f5549e6d36434bbe8fe702edef67df5ea29
@@ -1,4 +1,4 @@
1
- # Glimmer 0.4.7 Beta (JRuby Desktop UI DSL + Data-Binding)
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](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-hello-world.png)
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](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-tic-tac-toe.png)
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.7
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.7'
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 command
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](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-swt-widgets.png)
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
- text "Glimmer" # text property of shell
187
- label { # label widget declaration
188
- text "Hello World!" # text property of label
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](https://github.com/AndyObtiva/glimmer/tree/master/samples) directory for more examples.
216
+ Check out the [samples](samples) directory for more examples.
210
217
 
211
- Example from [hello_tab.rb](https://github.com/AndyObtiva/glimmer/blob/master/samples/hello_tab.rb) sample:
218
+ Example from [hello_tab.rb](samples/hello_tab.rb) sample:
212
219
 
213
- ![Hello Tab 1](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-hello-tab1.png)
220
+ ![Hello Tab 1](images/glimmer-hello-tab1.png)
214
221
 
215
- ![Hello Tab 2](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-hello-tab2.png)
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
- **Browser Widget**
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://www.google.com'
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="bowling-video" width="100%" height="100%">
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('bowling-video').play()")
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
- **Advanced case outside of standard Glimmer DSL**
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
- **Non-resizable Window**
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](https://github.com/AndyObtiva/glimmer/blob/master/samples/hellocomputed/hello_computed.rb) sample:
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](https://github.com/AndyObtiva/glimmer/blob/master/samples/hello_combo.rb) sample:
667
+ Example from [hello_combo.rb](samples/hello_combo.rb) sample:
621
668
 
622
- ![Hello Combo](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-hello-combo.png)
669
+ ![Hello Combo](images/glimmer-hello-combo.png)
623
670
 
624
- ![Hello Combo](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-hello-combo-expanded.png)
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](https://github.com/AndyObtiva/glimmer/blob/master/samples/hello_list_single_selection.rb) sample:
712
+ Example from [hello_list_single_selection.rb](samples/hello_list_single_selection.rb) sample:
666
713
 
667
- ![Hello List Single Selection](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-hello-list-single-selection.png)
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](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-hello-list-multi-selection.png)
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](https://github.com/AndyObtiva/glimmer/tree/master/samples) directory.
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](https://github.com/AndyObtiva/glimmer/tree/master/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](https://github.com/AndyObtiva/glimmer/blob/master/CONTRIBUTING.md) instructions, and run samples locally with development glimmer command: `bin/glimmer --dev`).
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](https://github.com/AndyObtiva/glimmer/blob/master/TODO.md)
1148
+ [TODO.md](TODO.md)
1099
1149
 
1100
1150
  ## Change Log
1101
1151
 
1102
- [CHANGELOG.md](https://github.com/AndyObtiva/glimmer/blob/master/CHANGELOG.md)
1152
+ [CHANGELOG.md](CHANGELOG.md)
1103
1153
 
1104
1154
  ## Contributing
1105
1155
 
1106
- [CONTRIBUTING.md](https://github.com/AndyObtiva/glimmer/blob/master/CONTRIBUTING.md)
1156
+ [CONTRIBUTING.md](CONTRIBUTING.md)
1107
1157
 
1108
1158
  ## Contributors
1109
1159
 
data/bin/girb CHANGED
@@ -2,4 +2,5 @@
2
2
 
3
3
  require_relative '../lib/glimmer/launcher'
4
4
 
5
- Glimmer::Launcher.new(['irb'] + ARGV).launch
5
+ girb_runner = File.expand_path('../girb_runner.rb', __FILE__)
6
+ Glimmer::Launcher.new(["irb -r #{girb_runner}"] + ARGV).launch
@@ -0,0 +1 @@
1
+ include Glimmer
@@ -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
- return nil
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.pop if args.last.is_a?(Hash)
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 ||= Set.new # class options array
37
+ @options ||= {} # maps options to defaults
40
38
  else
41
- options |= Set[*new_options]
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
- @options = options # instance options hash
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
- @body_root.add_observer(observer, attribute_name)
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)
@@ -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
@@ -40,6 +40,10 @@ module Glimmer
40
40
  @widget.pack
41
41
  center
42
42
  @widget.open
43
+ start_event_loop
44
+ end
45
+
46
+ def start_event_loop
43
47
  until @widget.isDisposed
44
48
  @display.sleep unless @display.readAndDispatch
45
49
  end
@@ -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)
@@ -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.7
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-27 00:00:00.000000000 Z
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.0
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.0
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