glimmer-dsl-opal 0.0.4 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +35 -0
  3. data/README.md +983 -34
  4. data/VERSION +1 -1
  5. data/lib/glimmer-dsl-opal.rb +5 -2
  6. data/lib/glimmer/data_binding/ext/observable_model.rb +40 -0
  7. data/lib/glimmer/data_binding/table_items_binding.rb +70 -0
  8. data/lib/glimmer/dsl/opal/async_exec_expression.rb +17 -0
  9. data/lib/glimmer/dsl/opal/browser_expression.rb +17 -0
  10. data/lib/glimmer/dsl/opal/column_properties_expression.rb +22 -0
  11. data/lib/glimmer/dsl/opal/dsl.rb +11 -0
  12. data/lib/glimmer/dsl/opal/message_box_expression.rb +20 -0
  13. data/lib/glimmer/dsl/opal/observe_expression.rb +32 -0
  14. data/lib/glimmer/dsl/opal/tab_folder_expression.rb +17 -0
  15. data/lib/glimmer/dsl/opal/tab_item_expression.rb +17 -0
  16. data/lib/glimmer/dsl/opal/table_column_expression.rb +17 -0
  17. data/lib/glimmer/dsl/opal/table_expression.rb +17 -0
  18. data/lib/glimmer/dsl/opal/table_items_data_binding_expression.rb +29 -0
  19. data/lib/glimmer/opal/display_proxy.rb +23 -0
  20. data/lib/glimmer/opal/div_proxy.rb +11 -2
  21. data/lib/glimmer/opal/document_proxy.rb +124 -4
  22. data/lib/glimmer/opal/element_proxy.rb +45 -14
  23. data/lib/glimmer/opal/grid_layout_proxy.rb +3 -1
  24. data/lib/glimmer/opal/iframe_proxy.rb +23 -0
  25. data/lib/glimmer/opal/input_proxy.rb +8 -4
  26. data/lib/glimmer/opal/label_proxy.rb +1 -1
  27. data/lib/glimmer/opal/layout_data_proxy.rb +23 -2
  28. data/lib/glimmer/opal/list_proxy.rb +2 -2
  29. data/lib/glimmer/opal/modal.rb +94 -0
  30. data/lib/glimmer/opal/point.rb +5 -0
  31. data/lib/glimmer/opal/select_proxy.rb +1 -1
  32. data/lib/glimmer/opal/tab_folder.rb +53 -0
  33. data/lib/glimmer/opal/tab_item.rb +98 -0
  34. data/lib/glimmer/opal/table_column.rb +50 -0
  35. data/lib/glimmer/opal/table_item.rb +136 -0
  36. data/lib/glimmer/opal/table_proxy.rb +149 -0
  37. data/lib/samples/elaborate/contact_manager.rb +1 -2
  38. data/lib/samples/elaborate/login.rb +0 -1
  39. data/lib/samples/elaborate/tic_tac_toe.rb +5 -5
  40. data/lib/samples/hello/hello_tab.rb +2 -2
  41. metadata +28 -16
  42. data/lib/glimmer/config.rb +0 -22
  43. data/lib/glimmer/dsl/engine.rb +0 -193
  44. data/lib/glimmer/dsl/expression.rb +0 -42
  45. data/lib/glimmer/dsl/expression_handler.rb +0 -48
  46. data/lib/glimmer/dsl/parent_expression.rb +0 -12
  47. data/lib/glimmer/dsl/static_expression.rb +0 -36
  48. data/lib/glimmer/dsl/top_level_expression.rb +0 -7
  49. data/lib/glimmer/error.rb +0 -6
  50. data/lib/glimmer/invalid_keyword_error.rb +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4abedea4353104a18359a2131eee38b7cff23498f246e35ddec92380798c5555
4
- data.tar.gz: cbba1e1d0b89ebd01c9ddba94cfbeeee5359f93b985e192d826829369794c85e
3
+ metadata.gz: b56026edb0b7ab096e2b972afcc99f2914db153e52fa52616859b44e86d0ad8c
4
+ data.tar.gz: aa94ad9ded4e7cac3ec706db46a012861e9c1e3a0d0026cdcc7833f43733eba0
5
5
  SHA512:
6
- metadata.gz: 8223f782d4e4daeefa03081e95b54fc4ab0e9782825a4fd4c17d041d73284c7bf1c78a3141defa526b648e5d6ab41b63ffafea610584d235f7f6b29adb21d3ca
7
- data.tar.gz: d8f62269cc84ae305f3e6cbd74d371272008d7ed1f6d2d8bb44b3fb95cc96247c7628fb95f788a19e2e30d67aedf017dfc19e82b8467af349d000013caa05219
6
+ metadata.gz: 66e958ca4e486e0a33908fb21d72322c375da35774a86e0514898a50b214bff0ecd7e7f4f5ce930983394cf49d9386ddce45f9ddcc0eb5e0074c455e8ebb87c9
7
+ data.tar.gz: 9e57c5f9a2bb433f182e7f7ce392f19985796cd56f8f40bed01bfed2e7385a25b4bf3fb7b06c541dae0b77cda2a981ac71d2a094d21f0beede0f8867b3fd1333
@@ -1,5 +1,40 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.0.9
4
+
5
+ - Upgraded to glimmer gem v0.9.3
6
+ - Fixed issue with missing Glimmer::Opal::ElementProxy#id=(value) method breaking Contact Manager sample Find feature
7
+
8
+ ## 0.0.8
9
+
10
+ - Contact Manager sample support
11
+
12
+ ## 0.0.7
13
+
14
+ - Tic Tac Toe sample support
15
+ - Login sample support
16
+
17
+ ## 0.0.6
18
+
19
+ - Hello, Tab! sample support
20
+
21
+ ## 0.0.5
22
+
23
+ - Hello, Browser! sample support
24
+
25
+ ## 0.0.4
26
+
27
+ - Hello, List Single Selection! sample support
28
+ - Hello, List Multi Selection! sample support
29
+
30
+ ## 0.0.3
31
+
32
+ - Hello, Computed! sample support
33
+
34
+ ## 0.0.2
35
+
36
+ - Hello, Combo! sample support
37
+
3
38
  ## 0.0.1
4
39
 
5
40
  - Initial support for webifying Glimmer SWT apps
data/README.md CHANGED
@@ -1,18 +1,20 @@
1
-
2
- # <img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=65 /> Glimmer DSL for Opal 0.0.4 (Web GUI for Desktop Apps)
1
+ # <img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=65 /> Glimmer DSL for Opal 0.0.9 (Webify Desktop Apps)
3
2
  [![Gem Version](https://badge.fury.io/rb/glimmer-dsl-opal.svg)](http://badge.fury.io/rb/glimmer-dsl-opal)
4
3
  [![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
5
4
 
6
- [Glimmer](https://github.com/AndyObtiva/glimmer) DSL for Opal is a web GUI adaptor for desktop apps built with [Glimmer](https://github.com/AndyObtiva/glimmer) & [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt).
7
-
8
- It enables running [Glimmer](https://github.com/AndyObtiva/glimmer) desktop apps on the web via [Rails](https://rubyonrails.org/) 5 and [Opal](https://opalrb.com/) 1.
5
+ Glimmer DSL for Opal is an experimental web GUI adaptor for [Glimmer](https://github.com/AndyObtiva/glimmer) desktop apps (i.e. apps built with [Glimmer](https://github.com/AndyObtiva/glimmer) [DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt)). It webifies them via [Rails](https://rubyonrails.org/) and [Opal](https://opalrb.com/), allowing Ruby desktop apps to run on the web without changing a line of code. Apps may then be custom-styled for the web via standard CSS.
9
6
 
10
- NOTE: Alpha Version 0.0.4 only supports capabilities below (detailed under [Examples](#examples)):
7
+ NOTE: Alpha Version 0.0.9 only supports bare-minimum capabilities for the following [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) [samples](https://github.com/AndyObtiva/glimmer#samples):
11
8
  - [Hello, World!](#hello-world)
12
9
  - [Hello, Combo!](#hello-combo)
13
10
  - [Hello, Computed!](#hello-computed)
14
11
  - [Hello, List Single Selection!](#hello-list-single-selection)
15
12
  - [Hello, List Multi Selection!](#hello-list-multi-selection)
13
+ - [Hello, Browser!](#hello-browser)
14
+ - [Hello, Tab!](#hello-tab)
15
+ - [Login](#login)
16
+ - [Tic Tac Toe](#tic-tac-toe)
17
+ - [Contact Manager](#contact-manager)
16
18
 
17
19
  Other Glimmer DSL gems:
18
20
  - [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (Desktop GUI)
@@ -30,6 +32,16 @@ The following keywords from [glimmer-dsl-swt](https://github.com/AndyObtiva/glim
30
32
  - `text`
31
33
  - `composite`
32
34
  - `list` & `list(:multi)`
35
+ - `tab_folder`
36
+ - `tab_item`
37
+ - `table`
38
+ - `table_column`
39
+ - `message_box`
40
+ - `on_widget_selected`
41
+ - `on_modify_text`
42
+ - `observe`
43
+ - `bind`
44
+ - `async_exec`
33
45
  - `grid_layout`
34
46
  - `layout_data`
35
47
 
@@ -40,37 +52,55 @@ The following keywords from [glimmer-dsl-swt](https://github.com/AndyObtiva/glim
40
52
 
41
53
  ## Setup
42
54
 
43
- Please follow these instructions to make Glimmer desktop apps work in Opal inside Rails 5
55
+ (NOTE: if you run into issues, they are probably fixed in master or development/wip branch, you may check out instead)
56
+
57
+ Please install a Rails 5 gem (e.g. `gem install rails -v5.2.4.3` )
44
58
 
45
59
  Start a new Rails 5 app:
46
60
 
47
61
  ```
48
- rails new hello_world
62
+ rails new glimmer_app
49
63
  ```
50
64
 
51
- Follow instructions to setup opal with a rails application: config/initializers/assets.rb
65
+ Add the following to `Gemfile`:
52
66
 
53
- Add the following to `Gemfile` (NOTE: if you run into issues, they are probably fixed in master or development/wip branch, you may check out instead):
54
67
  ```
55
- gem 'opal-rails'
56
- gem 'opal-browser'
57
- gem 'glimmer-dsl-opal', '~> 0.0.4', require: false
68
+ gem 'opal-rails', '~> 1.1.2'
69
+ gem 'opal-async', '~> 1.1.0'
70
+ gem 'opal-browser', '~> 0.2.0'
71
+ gem 'glimmer-dsl-opal', '~> 0.0.9', require: false
58
72
  ```
59
73
 
60
- Edit `config/initializers/assets.rb` and add:
74
+ Follow (opal-rails)[https://github.com/opal/opal-rails] instructions, basically the configuration of: config/initializers/assets.rb
75
+
76
+ Edit `config/initializers/assets.rb` and add the following at the bottom:
61
77
  ```
62
78
  Opal.use_gem 'glimmer-dsl-opal'
63
79
  ```
64
80
 
65
- ## Examples
81
+ Add the following line to the top of an empty `app/assets/javascripts/application.rb` (replacing `application.js`)
82
+
83
+ ```ruby
84
+ require 'glimmer-dsl-opal' # brings opal and opal browser too
85
+ ```
86
+
87
+ Add more code to `app/assets/javascripts/application.rb` from one of the samples below or require a [Glimmer](https://github.com/AndyObtiva/glimmer) app/[custom-shell](https://github.com/AndyObtiva/glimmer#custom-shell-gem) gem.
88
+
89
+ ## Samples
90
+
91
+ ### Hello Samples
66
92
 
67
- ### Hello, World!
93
+ #### Hello, World!
68
94
 
69
- Add the following Glimmer code to `app/assets/javascripts/application.js.rb`
95
+ Add the following require statement to `app/assets/javascripts/application.rb`
70
96
 
71
97
  ```ruby
72
- require 'glimmer-dsl-opal' # brings opal and opal browser too
98
+ require 'samples/hello/hello_world'
99
+ ```
100
+
101
+ Or add the Glimmer code directly if you prefer to play around with it:
73
102
 
103
+ ```ruby
74
104
  include Glimmer
75
105
 
76
106
  shell {
@@ -78,12 +108,12 @@ shell {
78
108
  label {
79
109
  text 'Hello, World!'
80
110
  }
81
- }
111
+ }.open
82
112
  ```
83
113
 
84
114
  Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
85
115
 
86
- ![Glimmer DSL for Opal Hello World](https://github.com/AndyObtiva/glimmer/blob/master/images/glimmer-hello-world.png)
116
+ ![Glimmer DSL for SWT Hello World](https://github.com/AndyObtiva/glimmer/blob/master/images/glimmer-hello-world.png)
87
117
 
88
118
  Glimmer app on the web (using `glimmer-dsl-opal` gem):
89
119
 
@@ -98,13 +128,17 @@ You should see "Hello, World!"
98
128
 
99
129
  ![Glimmer DSL for Opal Hello World](images/glimmer-dsl-opal-hello-world.png)
100
130
 
101
- ### Hello, Combo!
131
+ #### Hello, Combo!
102
132
 
103
- Add the following Glimmer code to `app/assets/javascripts/application.js.rb`
133
+ Add the following require statement to `app/assets/javascripts/application.rb`
104
134
 
105
135
  ```ruby
106
- require 'glimmer-dsl-opal' # brings opal and opal browser too
136
+ require 'samples/hello/hello_combo'
137
+ ```
138
+
139
+ Or add the Glimmer code directly if you prefer to play around with it:
107
140
 
141
+ ```ruby
108
142
  class Person
109
143
  attr_accessor :country, :country_options
110
144
 
@@ -142,7 +176,7 @@ HelloCombo.new.launch
142
176
  ```
143
177
  Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
144
178
 
145
- ![Glimmer DSL for Opal Hello Combo](https://github.com/AndyObtiva/glimmer/blob/master/images/glimmer-hello-combo.png)
179
+ ![Glimmer DSL for SWT Hello Combo](https://github.com/AndyObtiva/glimmer/blob/master/images/glimmer-hello-combo.png)
146
180
 
147
181
  Glimmer app on the web (using `glimmer-dsl-opal` gem):
148
182
 
@@ -157,13 +191,18 @@ You should see "Hello, Combo!"
157
191
 
158
192
  ![Glimmer DSL for Opal Hello Combo](images/glimmer-dsl-opal-hello-combo.png)
159
193
 
160
- ### Hello, Computed!
194
+ #### Hello, Computed!
195
+
196
+ Add the following require statement to `app/assets/javascripts/application.rb`
161
197
 
162
- Add the following Glimmer code to `app/assets/javascripts/application.js.rb`
163
198
 
164
199
  ```ruby
165
- require 'glimmer-dsl-opal' # brings opal and opal browser too
200
+ require 'samples/hello/hello_computed'
201
+ ```
202
+
203
+ Or add the Glimmer code directly if you prefer to play around with it:
166
204
 
205
+ ```ruby
167
206
  class HelloComputed
168
207
  class Contact
169
208
  attr_accessor :first_name, :last_name, :year_of_birth
@@ -256,7 +295,7 @@ HelloComputed.new.launch
256
295
  ```
257
296
  Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
258
297
 
259
- ![Glimmer DSL for Opal Hello Computed](https://github.com/AndyObtiva/glimmer/blob/master/images/glimmer-hello-computed.png)
298
+ ![Glimmer DSL for SWT Hello Computed](https://github.com/AndyObtiva/glimmer/blob/master/images/glimmer-hello-computed.png)
260
299
 
261
300
  Glimmer app on the web (using `glimmer-dsl-opal` gem):
262
301
 
@@ -271,9 +310,16 @@ You should see "Hello, Computed!"
271
310
 
272
311
  ![Glimmer DSL for Opal Hello Computed](images/glimmer-dsl-opal-hello-computed.png)
273
312
 
274
- ### Hello, List Single Selection!
313
+ #### Hello, List Single Selection!
314
+
315
+ Add the following require statement to `app/assets/javascripts/application.rb`
275
316
 
276
- Add the following Glimmer code to `app/assets/javascripts/application.js.rb`
317
+
318
+ ```ruby
319
+ require 'samples/hello/hello_list_single_selection'
320
+ ```
321
+
322
+ Or add the Glimmer code directly if you prefer to play around with it:
277
323
 
278
324
  ```ruby
279
325
  class Person
@@ -313,7 +359,7 @@ HelloListSingleSelection.new.launch
313
359
  ```
314
360
  Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
315
361
 
316
- ![Glimmer DSL for Opal Hello List Single Selection](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-hello-list-single-selection.png)
362
+ ![Glimmer DSL for SWT Hello List Single Selection](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-hello-list-single-selection.png)
317
363
 
318
364
  Glimmer app on the web (using `glimmer-dsl-opal` gem):
319
365
 
@@ -328,9 +374,15 @@ You should see "Hello, List Single Selection!"
328
374
 
329
375
  ![Glimmer DSL for Opal Hello List Single Selection](images/glimmer-dsl-opal-hello-list-single-selection.png)
330
376
 
331
- ### Hello, List Multi Selection!
377
+ #### Hello, List Multi Selection!
332
378
 
333
- Add the following Glimmer code to `app/assets/javascripts/application.js.rb`
379
+ Add the following require statement to `app/assets/javascripts/application.rb`
380
+
381
+ ```ruby
382
+ require 'samples/hello/hello_list_multi_selection'
383
+ ```
384
+
385
+ Or add the Glimmer code directly if you prefer to play around with it:
334
386
 
335
387
  ```ruby
336
388
  class Person
@@ -380,7 +432,7 @@ HelloListMultiSelection.new.launch
380
432
  ```
381
433
  Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
382
434
 
383
- ![Glimmer DSL for Opal Hello List Multi Selection](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-hello-list-multi-selection.png)
435
+ ![Glimmer DSL for SWT Hello List Multi Selection](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-hello-list-multi-selection.png)
384
436
 
385
437
  Glimmer app on the web (using `glimmer-dsl-opal` gem):
386
438
 
@@ -395,6 +447,903 @@ You should see "Hello, List Multi Selection!"
395
447
 
396
448
  ![Glimmer DSL for Opal Hello List Multi Selection](images/glimmer-dsl-opal-hello-list-multi-selection.png)
397
449
 
450
+ #### Hello, Browser!
451
+
452
+ Add the following require statement to `app/assets/javascripts/application.rb`
453
+
454
+ ```ruby
455
+ require 'samples/hello/hello_browser'
456
+ ```
457
+
458
+ Or add the Glimmer code directly if you prefer to play around with it:
459
+
460
+ ```ruby
461
+ include Glimmer
462
+
463
+ shell {
464
+ minimum_size 1024, 860
465
+ browser {
466
+ url 'http://brightonresort.com/about'
467
+ }
468
+ }.open
469
+ ```
470
+ Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
471
+
472
+ ![Glimmer DSL for SWT Hello Browser](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-hello-browser.png)
473
+
474
+ Glimmer app on the web (using `glimmer-dsl-opal` gem):
475
+
476
+ Start the Rails server:
477
+ ```
478
+ rails s
479
+ ```
480
+
481
+ Visit `http://localhost:3000`
482
+
483
+ You should see "Hello, Browser!"
484
+
485
+ ![Glimmer DSL for Opal Hello Browser](images/glimmer-dsl-opal-hello-browser.png)
486
+
487
+ #### Hello, Tab!
488
+
489
+ Add the following require statement to `app/assets/javascripts/application.rb`
490
+
491
+ ```ruby
492
+ require 'samples/hello/hello_tab'
493
+ ```
494
+
495
+ Or add the Glimmer code directly if you prefer to play around with it:
496
+
497
+ ```ruby
498
+ class HelloTab
499
+ include Glimmer
500
+ def launch
501
+ shell {
502
+ text "Hello, Tab!"
503
+ tab_folder {
504
+ tab_item {
505
+ text "English"
506
+ label {
507
+ text "Hello, World!"
508
+ }
509
+ }
510
+ tab_item {
511
+ text "French"
512
+ label {
513
+ text "Bonjour, Univers!"
514
+ }
515
+ }
516
+ }
517
+ }.open
518
+ end
519
+ end
520
+
521
+ HelloTab.new.launch
522
+ ```
523
+ Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
524
+
525
+ ![Glimmer DSL for SWT Hello Tab English](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-hello-tab-english.png)
526
+ ![Glimmer DSL for SWT Hello Tab French](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-hello-tab-french.png)
527
+
528
+ Glimmer app on the web (using `glimmer-dsl-opal` gem):
529
+
530
+ Start the Rails server:
531
+ ```
532
+ rails s
533
+ ```
534
+
535
+ Visit `http://localhost:3000`
536
+
537
+ You should see "Hello, Tab!"
538
+
539
+ ![Glimmer DSL for Opal Hello Tab English](images/glimmer-dsl-opal-hello-tab-english.png)
540
+ ![Glimmer DSL for Opal Hello Tab French](images/glimmer-dsl-opal-hello-tab-french.png)
541
+
542
+ ### Elaborate Samples
543
+
544
+ #### Login
545
+
546
+ Add the following require statement to `app/assets/javascripts/application.rb`
547
+
548
+ ```ruby
549
+ require 'samples/elaborate/login'
550
+ ```
551
+
552
+ Or add the Glimmer code directly if you prefer to play around with it:
553
+
554
+ ```ruby
555
+ require "observer"
556
+
557
+ #Presents login screen data
558
+ class LoginPresenter
559
+
560
+ attr_accessor :user_name
561
+ attr_accessor :password
562
+ attr_accessor :status
563
+
564
+ def initialize
565
+ @user_name = ""
566
+ @password = ""
567
+ @status = "Logged Out"
568
+ end
569
+
570
+ def status=(status)
571
+ @status = status
572
+
573
+ #TODO add feature to bind dependent properties to master property (2017-07-25 nested data binding)
574
+ notify_observers("logged_in")
575
+ notify_observers("logged_out")
576
+ end
577
+
578
+ def logged_in
579
+ self.status == "Logged In"
580
+ end
581
+
582
+ def logged_out
583
+ !self.logged_in
584
+ end
585
+
586
+ def login
587
+ self.status = "Logged In"
588
+ end
589
+
590
+ def logout
591
+ self.user_name = ""
592
+ self.password = ""
593
+ self.status = "Logged Out"
594
+ end
595
+
596
+ end
597
+
598
+ #Login screen
599
+ class Login
600
+ include Glimmer
601
+
602
+ def launch
603
+ presenter = LoginPresenter.new
604
+ @shell = shell {
605
+ text "Login"
606
+ composite {
607
+ grid_layout 2, false #two columns with differing widths
608
+
609
+ label { text "Username:" } # goes in column 1
610
+ text { # goes in column 2
611
+ text bind(presenter, :user_name)
612
+ enabled bind(presenter, :logged_out)
613
+ }
614
+
615
+ label { text "Password:" }
616
+ text(:password, :border) {
617
+ text bind(presenter, :password)
618
+ enabled bind(presenter, :logged_out)
619
+ }
620
+
621
+ label { text "Status:" }
622
+ label { text bind(presenter, :status) }
623
+
624
+ button {
625
+ text "Login"
626
+ enabled bind(presenter, :logged_out)
627
+ on_widget_selected { presenter.login }
628
+ }
629
+
630
+ button {
631
+ text "Logout"
632
+ enabled bind(presenter, :logged_in)
633
+ on_widget_selected { presenter.logout }
634
+ }
635
+ }
636
+ }
637
+ @shell.open
638
+ end
639
+ end
640
+
641
+ Login.new.launch
642
+ ```
643
+ Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
644
+
645
+ ![Glimmer DSL for SWT Login](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-login.png)
646
+ ![Glimmer DSL for SWT Login Filled In](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-login-filled-in.png)
647
+ ![Glimmer DSL for SWT Login Logged In](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-login-logged-in.png)
648
+
649
+ Glimmer app on the web (using `glimmer-dsl-opal` gem):
650
+
651
+ Start the Rails server:
652
+ ```
653
+ rails s
654
+ ```
655
+
656
+ Visit `http://localhost:3000`
657
+
658
+ You should see "Login" dialog
659
+
660
+ ![Glimmer DSL for Opal Login](images/glimmer-dsl-opal-login.png)
661
+ ![Glimmer DSL for Opal Login Filled In](images/glimmer-dsl-opal-login-filled-in.png)
662
+ ![Glimmer DSL for Opal Login Logged In](images/glimmer-dsl-opal-login-logged-in.png)
663
+
664
+ #### Tic Tac Toe
665
+
666
+ Add the following require statement to `app/assets/javascripts/application.rb`
667
+
668
+ ```ruby
669
+ require 'samples/elaborate/tic_tac_toe'
670
+ ```
671
+
672
+ Or add the Glimmer code directly if you prefer to play around with it:
673
+
674
+ ```ruby
675
+ class TicTacToe
676
+ class Cell
677
+ EMPTY = ""
678
+ attr_accessor :sign, :empty
679
+
680
+ def initialize
681
+ reset
682
+ end
683
+
684
+ def mark(sign)
685
+ self.sign = sign
686
+ end
687
+
688
+ def reset
689
+ self.sign = EMPTY
690
+ end
691
+
692
+ def sign=(sign_symbol)
693
+ @sign = sign_symbol
694
+ self.empty = sign == EMPTY
695
+ end
696
+
697
+ def marked
698
+ !empty
699
+ end
700
+ end
701
+ end
702
+
703
+ class TicTacToe
704
+ class Board
705
+ DRAW = :draw
706
+ IN_PROGRESS = :in_progress
707
+ WIN = :win
708
+ attr :winning_sign
709
+ attr_accessor :game_status
710
+
711
+ def initialize
712
+ @sign_state_machine = {nil => "X", "X" => "O", "O" => "X"}
713
+ build_grid
714
+ @winning_sign = Cell::EMPTY
715
+ @game_status = IN_PROGRESS
716
+ end
717
+
718
+ #row and column numbers are 1-based
719
+ def mark(row, column)
720
+ self[row, column].mark(current_sign)
721
+ game_over? #updates winning sign
722
+ end
723
+
724
+ def current_sign
725
+ @current_sign = @sign_state_machine[@current_sign]
726
+ end
727
+
728
+ def [](row, column)
729
+ @grid[row-1][column-1]
730
+ end
731
+
732
+ def game_over?
733
+ win? or draw?
734
+ end
735
+
736
+ def win?
737
+ win = (row_win? or column_win? or diagonal_win?)
738
+ self.game_status=WIN if win
739
+ win
740
+ end
741
+
742
+ def reset
743
+ (1..3).each do |row|
744
+ (1..3).each do |column|
745
+ self[row, column].reset
746
+ end
747
+ end
748
+ @winning_sign = Cell::EMPTY
749
+ @current_sign = nil
750
+ self.game_status=IN_PROGRESS
751
+ end
752
+
753
+ private
754
+
755
+ def build_grid
756
+ @grid = []
757
+ 3.times do |row_index| #0-based
758
+ @grid << []
759
+ 3.times { @grid[row_index] << Cell.new }
760
+ end
761
+ end
762
+
763
+ def row_win?
764
+ (1..3).each do |row|
765
+ if row_has_same_sign(row)
766
+ @winning_sign = self[row, 1].sign
767
+ return true
768
+ end
769
+ end
770
+ false
771
+ end
772
+
773
+ def column_win?
774
+ (1..3).each do |column|
775
+ if column_has_same_sign(column)
776
+ @winning_sign = self[1, column].sign
777
+ return true
778
+ end
779
+ end
780
+ false
781
+ end
782
+
783
+ #needs refactoring if we ever decide to make the board size dynamic
784
+ def diagonal_win?
785
+ if (self[1, 1].sign == self[2, 2].sign) and (self[2, 2].sign == self[3, 3].sign) and self[1, 1].marked
786
+ @winning_sign = self[1, 1].sign
787
+ return true
788
+ end
789
+ if (self[3, 1].sign == self[2, 2].sign) and (self[2, 2].sign == self[1, 3].sign) and self[3, 1].marked
790
+ @winning_sign = self[3, 1].sign
791
+ return true
792
+ end
793
+ false
794
+ end
795
+
796
+ def draw?
797
+ @board_full = true
798
+ 3.times do |x|
799
+ 3.times do |y|
800
+ @board_full = false if self[x, y].empty
801
+ end
802
+ end
803
+ self.game_status = DRAW if @board_full
804
+ @board_full
805
+ end
806
+
807
+ def row_has_same_sign(number)
808
+ row_sign = self[number, 1].sign
809
+ [2, 3].each do |column|
810
+ return false unless row_sign == (self[number, column].sign)
811
+ end
812
+ true if self[number, 1].marked
813
+ end
814
+
815
+ def column_has_same_sign(number)
816
+ column_sign = self[1, number].sign
817
+ [2, 3].each do |row|
818
+ return false unless column_sign == (self[row, number].sign)
819
+ end
820
+ true if self[1, number].marked
821
+ end
822
+
823
+ end
824
+ end
825
+
826
+ class TicTacToe
827
+ include Glimmer
828
+
829
+ def initialize
830
+ @tic_tac_toe_board = Board.new
831
+ @shell = shell {
832
+ text "Tic-Tac-Toe"
833
+ composite {
834
+ grid_layout 3, true
835
+ (1..3).each { |row|
836
+ (1..3).each { |column|
837
+ button {
838
+ layout_data :fill, :fill, true, true
839
+ text bind(@tic_tac_toe_board[row, column], :sign)
840
+ enabled bind(@tic_tac_toe_board[row, column], :empty)
841
+ on_widget_selected {
842
+ @tic_tac_toe_board.mark(row, column)
843
+ }
844
+ }
845
+ }
846
+ }
847
+ }
848
+ }
849
+ observe(@tic_tac_toe_board, :game_status) { |game_status|
850
+ display_win_message if game_status == Board::WIN
851
+ display_draw_message if game_status == Board::DRAW
852
+ }
853
+ end
854
+
855
+ def display_win_message
856
+ display_game_over_message("Player #{@tic_tac_toe_board.winning_sign} has won!")
857
+ end
858
+
859
+ def display_draw_message
860
+ display_game_over_message("Draw!")
861
+ end
862
+
863
+ def display_game_over_message(message_text)
864
+ message_box(@shell) {
865
+ text 'Game Over'
866
+ message message_text
867
+ }.open
868
+ @tic_tac_toe_board.reset
869
+ end
870
+
871
+ def open
872
+ @shell.open
873
+ end
874
+ end
875
+
876
+ TicTacToe.new.open
877
+ ```
878
+ Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
879
+
880
+ ![Glimmer DSL for SWT Tic Tac Toe](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-tic-tac-toe.png)
881
+ ![Glimmer DSL for SWT Tic Tac Toe In Progress](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-tic-tac-toe-in-progress.png)
882
+ ![Glimmer DSL for SWT Tic Tac Toe Game Over](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-tic-tac-toe-game-over.png)
883
+
884
+ Glimmer app on the web (using `glimmer-dsl-opal` gem):
885
+
886
+ Start the Rails server:
887
+ ```
888
+ rails s
889
+ ```
890
+
891
+ Visit `http://localhost:3000`
892
+
893
+ You should see "Tic Tac Toe"
894
+
895
+ ![Glimmer DSL for Opal Tic Tac Toe](images/glimmer-dsl-opal-tic-tac-toe.png)
896
+ ![Glimmer DSL for Opal Tic Tac Toe In Progress](images/glimmer-dsl-opal-tic-tac-toe-in-progress.png)
897
+ ![Glimmer DSL for Opal Tic Tac Toe Game Over](images/glimmer-dsl-opal-tic-tac-toe-game-over.png)
898
+
899
+ #### Contact Manager
900
+
901
+ Add the following require statement to `app/assets/javascripts/application.rb`
902
+
903
+ ```ruby
904
+ require 'samples/elaborate/contact_manager'
905
+ ```
906
+
907
+ Or add the Glimmer code directly if you prefer to play around with it:
908
+
909
+ ```ruby
910
+ class ContactManager
911
+ class Contact
912
+ attr_accessor :first_name, :last_name, :email
913
+
914
+ def initialize(attribute_map)
915
+ @first_name = attribute_map[:first_name]
916
+ @last_name = attribute_map[:last_name]
917
+ @email = attribute_map[:email]
918
+ end
919
+ end
920
+ end
921
+
922
+ class ContactManager
923
+ class ContactRepository
924
+ NAMES_FIRST = %w[
925
+ Liam
926
+ Noah
927
+ William
928
+ James
929
+ Oliver
930
+ Benjamin
931
+ Elijah
932
+ Lucas
933
+ Mason
934
+ Logan
935
+ Alexander
936
+ Ethan
937
+ Jacob
938
+ Michael
939
+ Daniel
940
+ Henry
941
+ Jackson
942
+ Sebastian
943
+ Aiden
944
+ Matthew
945
+ Samuel
946
+ David
947
+ Joseph
948
+ Carter
949
+ Owen
950
+ Wyatt
951
+ John
952
+ Jack
953
+ Luke
954
+ Jayden
955
+ Dylan
956
+ Grayson
957
+ Levi
958
+ Isaac
959
+ Gabriel
960
+ Julian
961
+ Mateo
962
+ Anthony
963
+ Jaxon
964
+ Lincoln
965
+ Joshua
966
+ Christopher
967
+ Andrew
968
+ Theodore
969
+ Caleb
970
+ Ryan
971
+ Asher
972
+ Nathan
973
+ Thomas
974
+ Leo
975
+ Isaiah
976
+ Charles
977
+ Josiah
978
+ Hudson
979
+ Christian
980
+ Hunter
981
+ Connor
982
+ Eli
983
+ Ezra
984
+ Aaron
985
+ Landon
986
+ Adrian
987
+ Jonathan
988
+ Nolan
989
+ Jeremiah
990
+ Easton
991
+ Elias
992
+ Colton
993
+ Cameron
994
+ Carson
995
+ Robert
996
+ Angel
997
+ Maverick
998
+ Nicholas
999
+ Dominic
1000
+ Jaxson
1001
+ Greyson
1002
+ Adam
1003
+ Ian
1004
+ Austin
1005
+ Santiago
1006
+ Jordan
1007
+ Cooper
1008
+ Brayden
1009
+ Roman
1010
+ Evan
1011
+ Ezekiel
1012
+ Xaviar
1013
+ Jose
1014
+ Jace
1015
+ Jameson
1016
+ Leonardo
1017
+ Axel
1018
+ Everett
1019
+ Kayden
1020
+ Miles
1021
+ Sawyer
1022
+ Jason
1023
+ Emma
1024
+ Olivia
1025
+ Ava
1026
+ Isabella
1027
+ Sophia
1028
+ Charlotte
1029
+ Mia
1030
+ Amelia
1031
+ Harper
1032
+ Evelyn
1033
+ Abigail
1034
+ Emily
1035
+ Elizabeth
1036
+ Mila
1037
+ Ella
1038
+ Avery
1039
+ Sofia
1040
+ Camila
1041
+ Aria
1042
+ Scarlett
1043
+ Victoria
1044
+ Madison
1045
+ Luna
1046
+ Grace
1047
+ Chloe
1048
+ Penelope
1049
+ Layla
1050
+ Riley
1051
+ Zoey
1052
+ Nora
1053
+ Lily
1054
+ Eleanor
1055
+ Hannah
1056
+ Lillian
1057
+ Addison
1058
+ Aubrey
1059
+ Ellie
1060
+ Stella
1061
+ Natalie
1062
+ Zoe
1063
+ Leah
1064
+ Hazel
1065
+ Violet
1066
+ Aurora
1067
+ Savannah
1068
+ Audrey
1069
+ Brooklyn
1070
+ Bella
1071
+ Claire
1072
+ Skylar
1073
+ Lucy
1074
+ Paisley
1075
+ Everly
1076
+ Anna
1077
+ Caroline
1078
+ Nova
1079
+ Genesis
1080
+ Emilia
1081
+ Kennedy
1082
+ Samantha
1083
+ Maya
1084
+ Willow
1085
+ Kinsley
1086
+ Naomi
1087
+ Aaliyah
1088
+ Elena
1089
+ Sarah
1090
+ Ariana
1091
+ Allison
1092
+ Gabriella
1093
+ Alice
1094
+ Madelyn
1095
+ Cora
1096
+ Ruby
1097
+ Eva
1098
+ Serenity
1099
+ Autumn
1100
+ Adeline
1101
+ Hailey
1102
+ Gianna
1103
+ Valentina
1104
+ Isla
1105
+ Eliana
1106
+ Quinn
1107
+ Nevaeh
1108
+ Ivy
1109
+ Sadie
1110
+ Piper
1111
+ Lydia
1112
+ Alexa
1113
+ Josephine
1114
+ Emery
1115
+ Julia
1116
+ Delilah
1117
+ Arianna
1118
+ Vivian
1119
+ Kaylee
1120
+ Sophie
1121
+ Brielle
1122
+ Madeline
1123
+ ]
1124
+ NAMES_LAST = %w[
1125
+ Smith
1126
+ Johnson
1127
+ Williams
1128
+ Brown
1129
+ Jones
1130
+ Miller
1131
+ Davis
1132
+ Wilson
1133
+ Anderson
1134
+ Taylor
1135
+ ]
1136
+ def initialize(contacts = nil)
1137
+ @contacts = contacts || 1000.times.map do |n|
1138
+ random_first_name_index = (rand*NAMES_FIRST.size).to_i
1139
+ random_last_name_index = (rand*NAMES_LAST.size).to_i
1140
+ first_name = NAMES_FIRST[random_first_name_index]
1141
+ last_name = NAMES_LAST[random_last_name_index]
1142
+ email = "#{first_name}@#{last_name}.com".downcase
1143
+ Contact.new(
1144
+ first_name: first_name,
1145
+ last_name: last_name,
1146
+ email: email
1147
+ )
1148
+ end
1149
+ end
1150
+
1151
+ def find(attribute_filter_map)
1152
+ @contacts.find_all do |contact|
1153
+ match = true
1154
+ attribute_filter_map.keys.each do |attribute_name|
1155
+ contact_value = contact.send(attribute_name).downcase
1156
+ filter_value = attribute_filter_map[attribute_name].downcase
1157
+ match = false unless contact_value.match(filter_value)
1158
+ end
1159
+ match
1160
+ end
1161
+ end
1162
+ end
1163
+ end
1164
+
1165
+ class ContactManager
1166
+ class ContactManagerPresenter
1167
+ attr_accessor :results
1168
+ @@contact_attributes = [:first_name, :last_name, :email]
1169
+ @@contact_attributes.each {|attribute_name| attr_accessor attribute_name}
1170
+
1171
+ def initialize(contact_repository = nil)
1172
+ @contact_repository = contact_repository || ContactRepository.new
1173
+ @results = []
1174
+ end
1175
+
1176
+ def list
1177
+ self.results = @contact_repository.find({})
1178
+ end
1179
+
1180
+ def find
1181
+ filter_map = {}
1182
+ @@contact_attributes.each do |attribute_name|
1183
+ filter_map[attribute_name] = self.send(attribute_name) if self.send(attribute_name)
1184
+ end
1185
+ self.results = @contact_repository.find(filter_map)
1186
+ @sort_attribute_name = nil
1187
+ @sort_direction_ascending = nil
1188
+ end
1189
+
1190
+ def toggle_sort(attribute_name)
1191
+ @sort_attribute_name = attribute_name
1192
+ @sort_direction_ascending = !@sort_direction_ascending
1193
+ sorted_results = self.results.sort_by {|contact| contact.send(attribute_name).downcase}
1194
+ sorted_results = sorted_results.reverse unless @sort_direction_ascending
1195
+ self.results = sorted_results
1196
+ end
1197
+ end
1198
+ end
1199
+
1200
+ class ContactManager
1201
+ include Glimmer
1202
+
1203
+ def initialize
1204
+ @contact_manager_presenter = ContactManagerPresenter.new
1205
+ @contact_manager_presenter.list
1206
+ end
1207
+
1208
+ def launch
1209
+ shell {
1210
+ text "Contact Manager"
1211
+ composite {
1212
+ composite {
1213
+ grid_layout 2, false
1214
+ label {text "First &Name: "}
1215
+ text {
1216
+ text bind(@contact_manager_presenter, :first_name)
1217
+ on_key_pressed {|key_event|
1218
+ @contact_manager_presenter.find if key_event.keyCode == Glimmer::SWT::SWTProxy[:cr]
1219
+ }
1220
+ }
1221
+ label {text "&Last Name: "}
1222
+ text {
1223
+ text bind(@contact_manager_presenter, :last_name)
1224
+ on_key_pressed {|key_event|
1225
+ @contact_manager_presenter.find if key_event.keyCode == Glimmer::SWT::SWTProxy[:cr]
1226
+ }
1227
+ }
1228
+ label {text "&Email: "}
1229
+ text {
1230
+ text bind(@contact_manager_presenter, :email)
1231
+ on_key_pressed {|key_event|
1232
+ @contact_manager_presenter.find if key_event.keyCode == Glimmer::SWT::SWTProxy[:cr]
1233
+ }
1234
+ }
1235
+ composite {
1236
+ grid_layout 2, false
1237
+ button {
1238
+ text "&Find"
1239
+ on_widget_selected {
1240
+ @contact_manager_presenter.find
1241
+ }
1242
+ }
1243
+ button {
1244
+ text "&List All"
1245
+ on_widget_selected {
1246
+ @contact_manager_presenter.list
1247
+ }
1248
+ }
1249
+ }
1250
+ }
1251
+
1252
+ table(:multi) { |table_proxy|
1253
+ layout_data {
1254
+ horizontal_alignment :fill
1255
+ vertical_alignment :fill
1256
+ grab_excess_horizontal_space true
1257
+ grab_excess_vertical_space true
1258
+ height_hint 200
1259
+ }
1260
+ table_column {
1261
+ text "First Name"
1262
+ width 80
1263
+ on_widget_selected {
1264
+ @contact_manager_presenter.toggle_sort(:first_name)
1265
+ }
1266
+ }
1267
+ table_column {
1268
+ text "Last Name"
1269
+ width 80
1270
+ on_widget_selected {
1271
+ @contact_manager_presenter.toggle_sort(:last_name)
1272
+ }
1273
+ }
1274
+ table_column {
1275
+ text "Email"
1276
+ width 200
1277
+ on_widget_selected {
1278
+ @contact_manager_presenter.toggle_sort(:email)
1279
+ }
1280
+ }
1281
+ items bind(@contact_manager_presenter, :results), column_properties(:first_name, :last_name, :email)
1282
+ on_mouse_down { |event|
1283
+ table_proxy.edit_table_item(event.table_item, event.column_index)
1284
+ }
1285
+ }
1286
+ }
1287
+ }.open
1288
+ end
1289
+ end
1290
+
1291
+ ContactManager.new.launch
1292
+
1293
+ ```
1294
+ Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
1295
+
1296
+ Glimmer DSL for SWT Contact Manager
1297
+
1298
+ ![Glimmer DSL for SWT Contact Manager](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-contact-manager.png)
1299
+
1300
+ Glimmer DSL for SWT Contact Manager Find
1301
+
1302
+ ![Glimmer DSL for SWT Contact Manager Find](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-contact-manager-find.png)
1303
+
1304
+ Glimmer DSL for SWT Contact Manager Edit Started
1305
+
1306
+ ![Glimmer DSL for SWT Contact Manager Edit Started](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-contact-manager-edit-started.png)
1307
+
1308
+ Glimmer DSL for SWT Contact Manager Edit In Progress
1309
+
1310
+ ![Glimmer DSL for SWT Contact Manager Edit In Progress](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-contact-manager-edit-in-progress.png)
1311
+
1312
+ Glimmer DSL for SWT Contact Manager Edit Done
1313
+
1314
+ ![Glimmer DSL for SWT Contact Manager Edit Done](https://github.com/AndyObtiva/glimmer/raw/master/images/glimmer-contact-manager-edit-done.png)
1315
+
1316
+ Glimmer app on the web (using `glimmer-dsl-opal` gem):
1317
+
1318
+ Start the Rails server:
1319
+ ```
1320
+ rails s
1321
+ ```
1322
+
1323
+ Visit `http://localhost:3000`
1324
+
1325
+ You should see "Tic Tac Toe"
1326
+
1327
+ Glimmer DSL for Opal Contact Manager
1328
+
1329
+ ![Glimmer DSL for Opal Contact Manager](images/glimmer-dsl-opal-contact-manager.png)
1330
+
1331
+ Glimmer DSL for Opal Contact Manager Find
1332
+
1333
+ ![Glimmer DSL for Opal Contact Manager Find](images/glimmer-dsl-opal-contact-manager-find.png)
1334
+
1335
+ Glimmer DSL for Opal Contact Manager Edit Started
1336
+
1337
+ ![Glimmer DSL for Opal Contact Manager Edit Started](images/glimmer-dsl-opal-contact-manager-edit-started.png)
1338
+
1339
+ Glimmer DSL for Opal Contact Manager Edit In Progress
1340
+
1341
+ ![Glimmer DSL for Opal Contact Manager Edit In Progress](images/glimmer-dsl-opal-contact-manager-edit-in-progress.png)
1342
+
1343
+ Glimmer DSL for Opal Contact Manager Edit Done
1344
+
1345
+ ![Glimmer DSL for Opal Contact Manager Edit Done](images/glimmer-dsl-opal-contact-manager-edit-done.png)
1346
+
398
1347
  ## Help
399
1348
 
400
1349
  ### Issues