glimmer 0.4.8 → 0.4.9

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: 2e11298f6aa21de3c113c3c9169df23a9181b2501e7d33e7fc62e3d18dec37f8
4
- data.tar.gz: eca26276e4afebd498174332cc7360044afffe71d48663ca3d95feb657b17b57
3
+ metadata.gz: 218ad434685b90c53d096b5ebc117c4eb790f5e724f8bd59d91ea3cc57683b74
4
+ data.tar.gz: a4568fdf1521441848af186a804c54c6ac6c3d29ba6ccabb3c1726630d9067d1
5
5
  SHA512:
6
- metadata.gz: cff2e454cdc6100893a100bdb5fd6e0b1b300f6c384f4c8a9722deb677d3cf83fd86f14462e7661b9523b06df43c93f6e1499bb5ab1ea77dfa0283a6c64537d2
7
- data.tar.gz: 820f9b260ce6c068ccf69274c73074739b983047050c517b0c511d992d903ff66e904f283224a5b837d29da69cd03f5549e6d36434bbe8fe702edef67df5ea29
6
+ metadata.gz: f0f19afe707d602e34a8c47708b40660fb149061a56e00bf3404d100ee12aab2ac9baaaad8a6fd6247a91fafc818d154848feaab1d14b3fab10c1f0d55a4999c
7
+ data.tar.gz: 6f5b8ce1b0562fbef375699f919fbd5cfe3cf746c64f2ef55e4cc50162bfcc4ac33f0d520ec0e8192644ae43e2efaf9fd3155504a1d3140e6dce0b708f2964d6
data/README.markdown CHANGED
@@ -1,4 +1,4 @@
1
- # Glimmer 0.4.8 Beta (JRuby Desktop UI DSL + Data-Binding)
1
+ # Glimmer 0.4.9 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.
@@ -107,14 +107,14 @@ Please follow these instructions to make the `glimmer` command available on your
107
107
 
108
108
  Run this command to install directly:
109
109
  ```
110
- jgem install glimmer -v 0.4.8
110
+ jgem install glimmer -v 0.4.9
111
111
  ```
112
112
 
113
113
  ### Option 2: Bundler
114
114
 
115
115
  Add the following to `Gemfile`:
116
116
  ```
117
- gem 'glimmer', '~> 0.4.8'
117
+ gem 'glimmer', '~> 0.4.9'
118
118
  ```
119
119
 
120
120
  And, then run:
@@ -169,9 +169,11 @@ In Glimmer DSL, widgets are declared with lowercase underscored names mirroring
169
169
  - `combo` instantiates `org.eclipse.swt.widgets.Combo`
170
170
  - `list` instantiates `org.eclipse.swt.widgets.List`
171
171
 
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).
172
+ Every **widget** is sufficiently declared by name, but may optionally be accompanied with:
173
+ - SWT **style** ***argument*** wrapped by parenthesis according to [Glimmer coding style](#glimmer-coding-style) (see [next section](#widget-styles) for details).
174
+ - Ruby block containing **properties** (widget attributes) and **content** (nested widgets)
173
175
 
174
- For example, if we were to revisit `samples/hello_world.rb` above:
176
+ For example, if we were to revisit `samples/hello_world.rb` above (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
175
177
 
176
178
  ```ruby
177
179
  shell {
@@ -189,13 +191,13 @@ Note that `shell` instantiates the outer shell **widget**, in other words, the w
189
191
  ```ruby
190
192
  # ...
191
193
  text "Glimmer" # text property of shell
192
- label { # label widget declaration
194
+ label { # label widget declaration as content of shell
193
195
  text "Hello World!" # text property of label
194
196
  }
195
197
  # ...
196
198
  ```
197
199
 
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
+ The first line declares a **property** called `text`, which sets the title of the shell (window) to `"Glimmer"`. **Properties** always have ***arguments*** (not wrapped by parenthesis according to [Glimmer coding style](#glimmer-coding-style)), such as the text `"Glimmer"` in this case, and do **NOT** have a ***block*** (this distinguishes them from **widget** declarations).
199
201
 
200
202
  The second line declares the `label` **widget**, which is followed by a Ruby **content** ***block*** that contains its `text` **property** with value `"Hello World!"`
201
203
 
@@ -215,7 +217,7 @@ It is centered upon initial display and has a minimum width of 130 (can be re-ce
215
217
 
216
218
  Check out the [samples](samples) directory for more examples.
217
219
 
218
- Example from [hello_tab.rb](samples/hello_tab.rb) sample:
220
+ Example from [hello_tab.rb](samples/hello_tab.rb) sample (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
219
221
 
220
222
  ![Hello Tab 1](images/glimmer-hello-tab1.png)
221
223
 
@@ -241,82 +243,25 @@ shell {
241
243
  }.open
242
244
  ```
243
245
 
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
- ```
246
+ #### `#widget`
282
247
 
283
- #### Browser Widget
284
-
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).
248
+ Glimmer widget objects come with an instance method `#widget` that returns the actual SWT `Widget` object wrapped by the Glimmer widget object. It is useful in cases you'd like to do some custom SWT programming outside of Glimmer.
286
249
 
287
- Example loading a URL:
250
+ Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
288
251
 
289
252
  ```ruby
290
- shell {
291
- minimum_size 1024, 860
292
- browser {
293
- url 'http://brightonresort.com/about'
294
- }
295
- }.open
296
- ```
297
-
298
- Example rendering HTML with an embedded video:
299
-
300
- ```ruby
301
- shell {
302
- @browser = browser {
303
- text <<~HTML
304
- <html>
305
- <head>
306
- </head>
307
- <body>
308
- <video id="video" width="100%" height="100%">
309
- <source src="file://#{video_file}" type="video/mp4">
310
- Your browser does not support the video tag.
311
- </video>
312
- </body>
313
- </html>
314
- HTML
315
- on_completed { # on load of the page execute this JavaScript
316
- @browser.widget.execute("document.getElementById('video').play()")
253
+ @shell = shell {
254
+ button {
255
+ text "Press Me"
256
+ on_widget_selected {
257
+ message_box = MessageBox.new(@shell.widget) # passing SWT Shell widget
258
+ message_box.setText("Surprise")
259
+ message_box.setMessage("You have won $1,000,000!")
260
+ message_box.open
317
261
  }
318
262
  }
319
- }.open
263
+ }
264
+ @shell.open
320
265
  ```
321
266
 
322
267
  ### Widget Styles
@@ -325,34 +270,40 @@ SWT widgets receive `SWT` styles in their constructor as per this guide:
325
270
 
326
271
  https://wiki.eclipse.org/SWT_Widget_Style_Bits
327
272
 
328
- Glimmer DSL facilitates that by passing symbols representing `SWT` constants as widget method arguments (i.e. inside widget `()` parentheses. See example below) in lower case version (e.g. `SWT::MULTI` becomes `:multi`).
273
+ Glimmer DSL facilitates that by passing symbols representing `SWT` constants as widget method arguments (i.e. inside widget `()` parentheses according to [Glimmer coding style](#glimmer-coding-style). See example below) in lower case version (e.g. `SWT::MULTI` becomes `:multi`).
329
274
 
330
275
  These styles customize widget look, feel, and behavior.
331
276
 
332
277
  Example:
278
+
333
279
  ```ruby
280
+ # ...
334
281
  list(:multi) { # SWT styles go inside ()
335
282
  # ...
336
283
  }
284
+ # ...
337
285
  ```
338
-
339
286
  Passing `:multi` to `list` widget enables list element multi-selection.
340
287
 
341
288
  ```ruby
289
+ # ...
342
290
  composite(:border) { # SWT styles go inside ()
343
291
  # ...
344
292
  }
293
+ # ...
345
294
  ```
346
-
347
295
  Passing `:border` to `composite` widget ensures it has a border.
348
296
 
349
297
  When you need to pass in **multiple SWT styles**, simply separate by commas.
350
298
 
351
299
  Example:
300
+
352
301
  ```ruby
302
+ # ...
353
303
  text(:center, :border) { # Multiple SWT styles separated by comma
354
304
  # ...
355
305
  }
306
+ # ...
356
307
  ```
357
308
 
358
309
  Glimmer ships with SWT style **smart defaults** so you wouldn't have to set them yourself most of the time (albeit you can always override them):
@@ -394,17 +345,21 @@ https://help.eclipse.org/2019-12/topic/org.eclipse.platform.doc.isv/guide/swt_wi
394
345
  Code examples:
395
346
 
396
347
  ```ruby
348
+ # ...
397
349
  label {
398
350
  text "Hello World!" # SWT properties go inside {} block
399
351
  }
352
+ # ...
400
353
  ```
401
354
 
402
355
  In the above example, the `label` widget `text` property was set to "Hello World!".
403
356
 
404
357
  ```ruby
358
+ # ...
405
359
  button {
406
360
  enabled bind(@tic_tac_toe_board.box(row, column), :empty)
407
361
  }
362
+ # ...
408
363
  ```
409
364
 
410
365
  In the above example, the `text` widget `enabled` property was data-bound to `#empty` method on `@tic_tac_toe_board.box(row, column)` (learn more about data-binding below)
@@ -416,10 +371,12 @@ Colors make up a subset of widget properties. SWT accepts color objects created
416
371
  Example:
417
372
 
418
373
  ```ruby
374
+ # ...
419
375
  label {
420
376
  background rgb(144, 240, 244)
421
377
  foreground rgba(38, 92, 232, 255)
422
378
  }
379
+ # ...
423
380
  ```
424
381
 
425
382
  SWT also supports standard colors available as constants under the `SWT` namespace with the `COLOR_` prefix (e.g. `SWT::COLOR_BLUE`, `SWT::COLOR_WHITE`, `SWT::COLOR_RED`)
@@ -429,6 +386,7 @@ Glimmer accepts these constants as lowercase Ruby symbols with or without `color
429
386
  Example:
430
387
 
431
388
  ```ruby
389
+ # ...
432
390
  label {
433
391
  background :black
434
392
  foreground :yellow
@@ -437,12 +395,22 @@ label {
437
395
  background :color_white
438
396
  foreground :color_red
439
397
  }
398
+ # ...
440
399
  ```
441
400
 
442
401
  You may check out all available standard colors in `SWT` over here (having `COLOR_` prefix):
443
402
 
444
403
  https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/SWT.html
445
404
 
405
+
406
+ ##### `#color`
407
+
408
+ Glimmer color objects come with an instance method `#color` that returns the actual SWT `Color` object wrapped by the Glimmer color object. It is useful in cases you'd like to do some custom SWT programming outside of Glimmer.
409
+
410
+ ##### `GColor.color_for(display = nil, standard_color)`
411
+
412
+ Glimmer `GColor` class comes with `.color_for` method that builds an actual SWT `Color` object from a standard color string or symbol. Passing a `display` is optional. It is useful in cases you'd like to do some custom SWT programming outside of Glimmer.
413
+
446
414
  #### Fonts
447
415
 
448
416
  Fonts are represented in Glimmer as a hash of name, height, and style keys.
@@ -452,9 +420,11 @@ The style can be one (or more) of 3 values: `:normal`, `:bold`, and `:italic`
452
420
  Example:
453
421
 
454
422
  ```ruby
423
+ # ...
455
424
  label {
456
425
  font name: 'Arial', height: 36, style: :normal
457
426
  }
427
+ # ...
458
428
  ```
459
429
 
460
430
  Keys are optional, so some of them may be left off.
@@ -463,9 +433,11 @@ When passing multiple styles, they are included in an array.
463
433
  Example:
464
434
 
465
435
  ```ruby
436
+ # ...
466
437
  label {
467
438
  font style: [:bold, :italic]
468
439
  }
440
+ # ...
469
441
  ```
470
442
 
471
443
  ### Layouts
@@ -482,6 +454,7 @@ In Glimmer DSL, just like widgets, layouts can be specified with lowercase under
482
454
  Example:
483
455
 
484
456
  ```ruby
457
+ # ...
485
458
  composite {
486
459
  row_layout {
487
460
  wrap true
@@ -496,15 +469,18 @@ composite {
496
469
  }
497
470
  # ... widgets follow
498
471
  }
472
+ # ...
499
473
  ```
500
474
 
501
475
  Alternatively, a layout may be constructed by following the SWT API for the layout object. For example, a `RowLayout` can be constructed by passing it an SWT style constant (Glimmer automatically accepts symbols (e.g. `:horizontal`) for SWT style arguments like `SWT::HORIZONTAL`.)
502
476
 
503
477
  ```ruby
478
+ # ...
504
479
  composite {
505
480
  row_layout :horizontal
506
481
  # ... widgets follow
507
482
  }
483
+ # ...
508
484
  ```
509
485
 
510
486
  Here is a more sophisticated example taken from [hello_computed.rb](samples/hellocomputed/hello_computed.rb) sample:
@@ -597,6 +573,7 @@ Glimmer also automatically accepts symbols (e.g. `:fill`) for SWT style argument
597
573
  Examples:
598
574
 
599
575
  ```ruby
576
+ # ...
600
577
  composite {
601
578
  row_layout :horizontal
602
579
  label {
@@ -607,9 +584,11 @@ composite {
607
584
  }
608
585
  # ... more widgets follow
609
586
  }
587
+ # ...
610
588
  ```
611
589
 
612
590
  ```ruby
591
+ # ...
613
592
  composite {
614
593
  grid_layout 3, false # grid layout with 3 columns not of equal width
615
594
  label {
@@ -617,9 +596,11 @@ composite {
617
596
  layout_data :fill, :end, true, false
618
597
  }
619
598
  }
599
+ # ...
620
600
  ```
621
601
 
622
602
  ```ruby
603
+ # ...
623
604
  composite {
624
605
  grid_layout 3, false # grid layout with 3 columns not of equal width
625
606
  label {
@@ -627,6 +608,7 @@ composite {
627
608
  layout_data GridData.new(GSWT[:fill], GSWT[:end], true, false)
628
609
  }
629
610
  }
611
+ # ...
630
612
  ```
631
613
 
632
614
  **NOTE**: Layout data must never be reused between widgets. Always specify or clone again for every widget.
@@ -664,7 +646,7 @@ The 5th example demonstrates computed value data binding whereby the value of `n
664
646
 
665
647
  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`.
666
648
 
667
- Example from [hello_combo.rb](samples/hello_combo.rb) sample:
649
+ Example from [samples/hello_combo.rb](samples/hello_combo.rb) sample (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
668
650
 
669
651
  ![Hello Combo](images/glimmer-hello-combo.png)
670
652
 
@@ -709,7 +691,7 @@ HelloCombo.new.launch
709
691
 
710
692
  `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.
711
693
 
712
- Example from [hello_list_single_selection.rb](samples/hello_list_single_selection.rb) sample:
694
+ Example from [samples/hello_list_single_selection.rb](samples/hello_list_single_selection.rb) sample:
713
695
 
714
696
  ![Hello List Single Selection](images/glimmer-hello-list-single-selection.png)
715
697
 
@@ -733,6 +715,8 @@ shell {
733
715
 
734
716
  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.
735
717
 
718
+ Example from [samples/hello_list_multi_selection.rb](samples/hello_list_multi_selection.rb) sample (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
719
+
736
720
  ![Hello List Multi Selection](images/glimmer-hello-list-multi-selection.png)
737
721
 
738
722
  ```ruby
@@ -794,9 +778,13 @@ Glimmer comes with `Observer` module, which is used internally for data-binding,
794
778
 
795
779
  #### Observing Widgets
796
780
 
797
- Glimmer supports observing widgets with an `on_*event*` declaration where the '*event*' part is replaced with the lowercase underscored name of an SWT listener event method.
781
+ Glimmer supports observing widgets with two types of syntax:
782
+ 1. `on_{swt-listener-method-name}`: where {swt-listener-method-name} is replaced with the lowercase underscored method name on an SWT listener class (e.g. `on_verify_text` for `org.eclipse.swt.events.VerifyListener#verifyText`).
783
+ 2. `on_event_{swt-event-constant}`: where {swt-event-constant} is replaced with an `org.eclipse.swt.SWT` event constant (e.g. `on_event_show` for `SWT.Show` to observe when widget becomes visible)
784
+
785
+ Number 1 is more commonly used in SWT applications, so make it your starting point. Number 2 covers events not found in number 1, so look into it if you don't find an SWT listener you need in number 1.
798
786
 
799
- To figure out what the available events for an SWT widget are, check out all of its API methods starting with `add` and ending with `Listener`, and then open the listener class to check its "event methods".
787
+ **Regarding number 1**, to figure out what the available events for an SWT widget are, check out all of its `add***Listener` API methods, and then open the listener class argument to check its "event methods".
800
788
 
801
789
  For example, if you look at the `Button` SWT API:
802
790
  https://help.eclipse.org/2019-12/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fswt%2Fbrowser%2FBrowser.html
@@ -836,6 +824,64 @@ Note that every Tic Tac Toe grid cell has its `text` and `enabled` properties da
836
824
 
837
825
  Next however, each of these Tic Tac Toe grid cells, which are clickable buttons, have an `on_widget_selected` observer, which once triggered, marks the box (cell) on the `TicTacToeBoard` to make a move.
838
826
 
827
+ **Regarding number 2**, you can figure out all available events by looking at the `org.eclipse.swt.SWT` API:
828
+
829
+ https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/SWT.html
830
+
831
+ Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
832
+
833
+ `SWT.Show` - hooks a listener for showing a widget (using `on_event_show` in Glimmer)
834
+ `SWT.Hide` - hooks a listener for hiding a widget (using `on_event_hide` in Glimmer)
835
+
836
+ ```ruby
837
+ shell {
838
+ @button1 = button {
839
+ text "Show 2nd Button"
840
+ visible true
841
+ on_event_show {
842
+ @button2.widget.setVisible(false)
843
+ }
844
+ on_widget_selected {
845
+ @button2.widget.setVisible(true)
846
+ }
847
+ }
848
+ @button2 = button {
849
+ text "Show 1st Button"
850
+ visible false
851
+ on_event_show {
852
+ @button1.widget.setVisible(false)
853
+ }
854
+ on_widget_selected {
855
+ @button1.widget.setVisible(true)
856
+ }
857
+ }
858
+ }.open
859
+ ```
860
+
861
+ **Gotcha:** SWT.Resize event needs to be hooked using **`on_event_Resize`** because `org.eclipse.swt.SWT` has 2 constants for resize: `RESIZE` and `Resize`, so it cannot infer the right one automatically from the underscored version `on_event_resize`
862
+
863
+ ##### Alternative Syntax
864
+
865
+ Instead of declaring a widget observer using `on_***` syntax inside a widget content block, you may also do so after the widget declaration by invoking directly on the widget object.
866
+
867
+ Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
868
+
869
+ ```
870
+ @shell = shell {
871
+ label {
872
+ text "Hello, World!"
873
+ }
874
+ }
875
+ @shell.on_shell_iconified {
876
+ @shell.close
877
+ }
878
+ @shell.open
879
+ ```
880
+
881
+ The shell declared above has been modified so that the minimize button works just like the close button. Once you minimize the shell (iconify it), it closes.
882
+
883
+ The alternative syntax can be helpful if you prefer to separate Glimmer observer declarations from Glimmer UI declarations, or would like to add observers dynamically based on some logic later on.
884
+
839
885
  #### Observing Models
840
886
 
841
887
  The class that needs to observe a model object must include (mix in) the `Observer` module and implement the `#call(new_value)` method. The class to be observed doesn't need to do anything. It will automatically be enhanced by Glimmer for observation.
@@ -910,7 +956,7 @@ Glimmer supports creating custom widgets with minimal code, which automatically
910
956
 
911
957
  Simply create a new class that includes `Glimmer::SWT::CustomWidget` and put Glimmer DSL code in its `#body` method (its return value is stored in `#body_root` attribute). Glimmer will then automatically recognize this class by convention when it encounters a keyword matching the class name converted to underscored lowercase (and namespace double-colons `::` replaced with double-underscores `__`)
912
958
 
913
- **Example:**
959
+ #### Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
914
960
 
915
961
  Definition:
916
962
  ```ruby
@@ -931,12 +977,12 @@ shell {
931
977
  red_label {
932
978
  text 'Red Label'
933
979
  }
934
- }
980
+ }.open
935
981
  ```
936
982
 
937
983
  As you can see, `RedLabel` became Glimmer DSL keyword: `red_label`
938
984
 
939
- **Another Example:**
985
+ #### Another Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
940
986
 
941
987
  Definition:
942
988
  ```ruby
@@ -950,6 +996,7 @@ module Red
950
996
  }
951
997
  end
952
998
  end
999
+ end
953
1000
  ```
954
1001
 
955
1002
  Usage:
@@ -961,7 +1008,7 @@ shell {
961
1008
  text 'This is showing inside a Red Composite'
962
1009
  }
963
1010
  }
964
- }
1011
+ }.open
965
1012
  ```
966
1013
 
967
1014
  Notice how `Red::Composite` became `red__composite` with double-underscore, which is how Glimmer Custom Widgets signify namespaces by convention.
@@ -976,7 +1023,7 @@ Additionally, custom widgets can call the following class methods:
976
1023
  - `.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
1024
  - `.option`: declares a single option taking option name and default value as arguments (also generates an attribute reader just like `.options`)
978
1025
 
979
- **Content/Options Example:**
1026
+ #### Content/Options Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
980
1027
 
981
1028
  Definition:
982
1029
  ```ruby
@@ -989,7 +1036,7 @@ class Sandwich
989
1036
  def body
990
1037
  composite(swt_style) { # gets custom widget style
991
1038
  fill_layout orientation # using orientation option
992
- background container_background # using container_background option
1039
+ background bg_color # using container_background option
993
1040
  label {
994
1041
  text 'SANDWICH TOP'
995
1042
  }
@@ -1005,12 +1052,13 @@ end
1005
1052
  Usage:
1006
1053
  ```ruby
1007
1054
  shell {
1008
- sandwich(:no_focus, orientation: :horizontal, bg_color: :white) {
1055
+ sandwich(:no_focus, orientation: :vertical, bg_color: :red) {
1009
1056
  label {
1057
+ background :green
1010
1058
  text 'SANDWICH CONTENT'
1011
1059
  }
1012
1060
  }
1013
- }
1061
+ }.open
1014
1062
  ```
1015
1063
 
1016
1064
  Notice how `:no_focus` was the `swt_style` value, followed by the `options` hash `{orientation: :horizontal, bg_color: :white}`, and finally the `content` block containing the label with `'SANDWICH CONTENT'`
@@ -1019,6 +1067,97 @@ The following additional attributes may be called from outside a custom widget i
1019
1067
  - `#body_root`: top-most root Glimmer widget returned in `#body` method
1020
1068
  - `#widget`: actual SWT widget for `body_root`
1021
1069
 
1070
+ ### Miscellaneous
1071
+
1072
+ #### Video Widget
1073
+
1074
+ ![Video Widget](images/glimmer-video-widget.png)
1075
+
1076
+ 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.
1077
+
1078
+ Attributes (passed in an options hash as arguments to video widget):
1079
+ - `autoplay` (true [default] or false): plays video automatically as soon as loaded
1080
+ - `controls` (true [default] or false): displays controls
1081
+ - `looped` (true or false [default]): plays video in looped mode
1082
+ - `background` (Glimmer color [default: white]): sets background color just like with any other widget
1083
+ - `fit_to_width` (true [default] or false): fits video width to widget allotted width regardless of video's original size. Maintains video aspect ratio.
1084
+ - `fit_to_height` (true [default] or false): fits video height to widget allotted height regardless of video's original size. Maintains video aspect ratio.
1085
+ - `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.
1086
+ - `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.
1087
+
1088
+ Methods:
1089
+ - `play`: plays video
1090
+ - `pause`: pauses video
1091
+
1092
+ Example ([samples/video/hello_video.rb](samples/video/hello_video.rb)):
1093
+
1094
+ ```ruby
1095
+ # ...
1096
+ shell {
1097
+ video(file: video_file)
1098
+ }.open
1099
+ ```
1100
+
1101
+ Example ([samples/video/hello_looped_video_with_black_background.rb](samples/video/hello_looped_video_with_black_background.rb)):
1102
+
1103
+ ```ruby
1104
+ # ...
1105
+ shell {
1106
+ minimum_size 1024, 640
1107
+ video(file: video_file, looped: true, background: :black)
1108
+ }.open
1109
+ ```
1110
+
1111
+ #### Browser Widget
1112
+
1113
+ Glimmer supports SWT Browser widget, which can load URLs or render HTML. It can even be instrumented with JavaScript when needed (though highly discouraged in Glimmer except for rare cases when leveraging a pre-existing web codebase in a desktop app).
1114
+
1115
+ Example loading a URL (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
1116
+
1117
+ ```ruby
1118
+ shell {
1119
+ minimum_size 1024, 860
1120
+ browser {
1121
+ url 'http://brightonresort.com/about'
1122
+ }
1123
+ }.open
1124
+ ```
1125
+
1126
+ Example rendering HTML with JavaScript on document ready (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
1127
+
1128
+ ```ruby
1129
+ shell {
1130
+ minimum_size 130, 130
1131
+ @browser = browser {
1132
+ text <<~HTML
1133
+ <html>
1134
+ <head>
1135
+ </head>
1136
+ <body>
1137
+ <h1>Hello, World!</h1>
1138
+ </body>
1139
+ </html>
1140
+ HTML
1141
+ on_completed { # on load of the page execute this JavaScript
1142
+ @browser.widget.execute("alert('Hello, World!');")
1143
+ }
1144
+ }
1145
+ }.open
1146
+ ```
1147
+
1148
+ ## Glimmer Coding Style
1149
+
1150
+ - Widgets are declared with underscored lowercase versions of their SWT names minus the SWT package name.
1151
+ - Widget declarations may optionally have arguments and be followed by a block (to contain properties and content)
1152
+ - Widget blocks are always declared with curly brackets
1153
+ - Widget arguments are always wrapped inside parentheses
1154
+ - Widget properties are declared with underscored lowercase versions of the SWT properties
1155
+ - Widget property declarations always have arguments and never take a block
1156
+ - Widget property arguments are never wrapped inside parentheses
1157
+ - Widget listeners are always declared starting with `on_` prefix and affixing listener event method name afterwards in underscored lowercase form
1158
+ - Widget listeners are always followed by a block using curly brackets
1159
+ - Data-binding is done via `bind` keyword, which always takes arguments wrapped in parentheses
1160
+ - Custom widgets receive additional arguments to SWT style called options. These are passed as the last argument inside the parentheses, a hash of option names pointing to values.
1022
1161
 
1023
1162
  ## Samples
1024
1163
 
@@ -1056,10 +1195,14 @@ Here is a textual list of SWT widgets:
1056
1195
 
1057
1196
  https://help.eclipse.org/2019-12/topic/org.eclipse.platform.doc.isv/guide/swt_widgets_controls.htm?cp=2_0_7_0_0
1058
1197
 
1059
- Here is a list of SWT style bits:
1198
+ Here is a list of SWT style bits as used in widget declaration:
1060
1199
 
1061
1200
  https://wiki.eclipse.org/SWT_Widget_Style_Bits
1062
1201
 
1202
+ Here is a SWT style bit constant reference:
1203
+
1204
+ https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/SWT.html
1205
+
1063
1206
  ## SWT Packages
1064
1207
 
1065
1208
  Glimmer automatically imports all SWT Java packages upon adding `include Glimmer` to a class or module.