glimmer-dsl-opal 0.12.0 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -0
- data/README.md +179 -1296
- data/VERSION +1 -1
- data/app/controllers/glimmer/application_controller.rb +4 -0
- data/app/controllers/glimmer/image_paths_controller.rb +46 -0
- data/app/views/glimmer/image_paths/index.html.erb +1 -0
- data/{lib/glimmer-dsl-opal/samples/hello/hello_computed/contact.rb → config/routes.rb} +2 -20
- data/lib/glimmer-dsl-opal.rb +9 -3
- data/lib/glimmer-dsl-opal/ext/file.rb +25 -0
- data/lib/glimmer-dsl-opal/samples/elaborate/contact_manager.rb +0 -2
- data/lib/glimmer-dsl-opal/samples/elaborate/weather.rb +157 -0
- data/lib/glimmer-dsl-opal/samples/hello/hello_button.rb +7 -7
- data/lib/glimmer-dsl-opal/samples/hello/hello_checkbox.rb +16 -14
- data/lib/glimmer-dsl-opal/samples/hello/hello_checkbox_group.rb +14 -9
- data/lib/glimmer-dsl-opal/samples/hello/hello_combo.rb +24 -22
- data/lib/glimmer-dsl-opal/samples/hello/hello_computed.rb +27 -9
- data/lib/glimmer-dsl-opal/samples/hello/hello_custom_shell.rb +15 -11
- data/lib/glimmer-dsl-opal/samples/hello/hello_custom_widget.rb +1 -1
- data/lib/glimmer-dsl-opal/samples/hello/hello_radio.rb +18 -16
- data/lib/glimmer-dsl-opal/samples/hello/hello_radio_group.rb +17 -12
- data/lib/glimmer-dsl-opal/samples/hello/hello_table.rb +29 -21
- data/lib/glimmer-dsl-opal/samples/hello/hello_table/baseball_park.png +0 -0
- data/lib/glimmer/config.rb +11 -0
- data/lib/glimmer/dsl/opal/custom_widget_expression.rb +2 -2
- data/lib/glimmer/engine.rb +21 -0
- data/lib/glimmer/swt/composite_proxy.rb +34 -0
- data/lib/glimmer/swt/label_proxy.rb +15 -2
- data/lib/glimmer/swt/shell_proxy.rb +43 -0
- data/lib/glimmer/swt/table_item_proxy.rb +3 -0
- data/lib/glimmer/ui/custom_widget.rb +11 -2
- data/lib/net/http.rb +15 -6
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f8072dfb955151aa374817c0f2f175bf9c7adfd115eca1bbd6df6c2c3b0725e4
|
4
|
+
data.tar.gz: 94304037d23dfe1719087fc93d3dc9056be7701f6fdac1044bfe2719e61e43b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f85477240562b1eb7c3bfb3e147577bf6ac7f265c54b6d5acad7ae295a65b1226ff41798eb2a8d41804d2c56d999992f6e6e98b64bde1bed5708c52c46862f0
|
7
|
+
data.tar.gz: 847b86e900e53586993c74982b37d68ede27f399982188187de524dec31b1d5ffdf0ffc31694da38510060f3e5224c71acc7ca85d75fdef398a8e42c287ca666
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,27 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.16.0
|
4
|
+
|
5
|
+
- Support label widget background_image attribute
|
6
|
+
- Have File.expand_path support expanding paths even if they did not base off of __dir__ or __FILE__
|
7
|
+
- Custom specification of gems having image paths via server-side configuration in Glimmer::Config.gems_having_image_paths
|
8
|
+
|
9
|
+
## 0.15.1
|
10
|
+
|
11
|
+
- Auto-expose images of gems that depend on glimmer-dsl-opal as downloadable asset links providing `/glimmer/image_paths` server call to obtain them
|
12
|
+
- Update Hello, Table! to work with image background
|
13
|
+
|
14
|
+
## 0.14.0
|
15
|
+
|
16
|
+
- Initial Net::HTTP support for get and post_form
|
17
|
+
- Added "Weather" elaborate sample (minus multi-threaded refetches)
|
18
|
+
- Updated Hello, Button!, Hello, Combo!, and Hello, Computed! from Glimmer DSL for SWT
|
19
|
+
|
20
|
+
## 0.13.0
|
21
|
+
|
22
|
+
- Support Shine data-binding syntax in custom widgets
|
23
|
+
- Update Hello, Checkbox!, Hello, Checkbox Group!, Hello, Radio! and Hello, Radio Group! to utilize Shine data-binding syntax from latest glimmer-dsl-swt
|
24
|
+
|
3
25
|
## 0.12.0
|
4
26
|
|
5
27
|
- Support CustomShell.launch opening in the same window if no other shell is open or DisplayProxy.open_custom_shells_in_current_window = true is set
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Opal 0.
|
1
|
+
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Opal 0.16.0 (Pure Ruby Web GUI)
|
2
2
|
[![Gem Version](https://badge.fury.io/rb/glimmer-dsl-opal.svg)](http://badge.fury.io/rb/glimmer-dsl-opal)
|
3
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)
|
4
4
|
|
@@ -8,12 +8,14 @@
|
|
8
8
|
|
9
9
|
Use in one of two ways:
|
10
10
|
- **Direct:** build the GUI of web apps with the same friendly desktop GUI Ruby syntax as [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt), thus requiring a lot less code than web technologies that is in pure Ruby and avoiding opaque web concepts like 'render' and 'reactive'. No HTML/JS/CSS skills are even required. Web designers may be involved with CSS styling only if needed.
|
11
|
-
- **Adapter:** auto-webify [Glimmer](https://github.com/AndyObtiva/glimmer) desktop apps (i.e. apps built with [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt)) via [Opal](https://opalrb.com/) on [Rails](https://rubyonrails.org/) without changing a line of code. Just insert them as a single require statement in a Rails app, and BOOM! They're running on the web! Apps may then optionally be custom-styled for the web by web designers with standard CSS if needed.
|
11
|
+
- **Adapter:** auto-webify [Glimmer](https://github.com/AndyObtiva/glimmer) desktop apps (i.e. apps built with [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt)) via [Opal](https://opalrb.com/) on [Rails](https://rubyonrails.org/) without changing a line of GUI code. Just insert them as a single require statement in a Rails app, and BOOM! They're running on the web! Apps may then optionally be custom-styled for the web by web designers with standard CSS if needed.
|
12
12
|
|
13
13
|
Glimmer DSL for Opal successfully reuses the entire [Glimmer](https://github.com/AndyObtiva/glimmer) core DSL engine in [Opal Ruby](https://opalrb.com/) inside a web browser, and as such inherits the full range of Glimmer desktop [data-binding](https://github.com/AndyObtiva/glimmer#data-binding) capabilities for the web (including Shine syntax using `<=>` and `<=` for bidirectional [two-way] and unidirectional [one-way] data-binding respectively).
|
14
14
|
|
15
15
|
#### Hello, Table! Sample
|
16
16
|
|
17
|
+
Code: [lib/glimmer-dsl-opal/samples/hello/hello_table.rb](lib/glimmer-dsl-opal/samples/hello/hello_table.rb)
|
18
|
+
|
17
19
|
Glimmer GUI code from [glimmer-dsl-opal/samples/hello/hello_table.rb](lib/glimmer-dsl-opal/samples/hello/hello_table.rb):
|
18
20
|
|
19
21
|
```ruby
|
@@ -103,7 +105,7 @@ shell {
|
|
103
105
|
|
104
106
|
![Glimmer DSL for SWT Hello Table](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-table.png)
|
105
107
|
|
106
|
-
**Hello, Table! (same code) running on the web via Opal on Rails (using the [glimmer-dsl-opal](https://rubygems.org/gems/glimmer-dsl-opal) gem):**
|
108
|
+
**Hello, Table! (same GUI code) running on the web via Opal on Rails (using the [glimmer-dsl-opal](https://rubygems.org/gems/glimmer-dsl-opal) gem):**
|
107
109
|
|
108
110
|
![Glimmer DSL for Opal Hello Table](images/glimmer-dsl-opal-hello-table.png)
|
109
111
|
|
@@ -141,7 +143,7 @@ Hello, Table! Game Booked
|
|
141
143
|
|
142
144
|
NOTE: Glimmer DSL for Opal is an alpha project. Please help make better by contributing, adopting for small or low risk projects, and providing feedback. It is still an early alpha, so the more feedback and issues you report the better.
|
143
145
|
|
144
|
-
**Alpha Version** 0.
|
146
|
+
**Alpha Version** 0.16.0 only supports bare-minimum capabilities for the included [samples](https://github.com/AndyObtiva/glimmer-dsl-opal#samples) (originally written for [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt))
|
145
147
|
|
146
148
|
Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
|
147
149
|
- [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)
|
@@ -151,7 +153,7 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
|
|
151
153
|
|
152
154
|
## Table of Contents
|
153
155
|
|
154
|
-
- [Glimmer DSL for Opal 0.
|
156
|
+
- [Glimmer DSL for Opal 0.16.0 (Pure Ruby Web GUI)](#-glimmer-dsl-for-opal-0160-pure-ruby-web-gui)
|
155
157
|
- [Principles](#principles)
|
156
158
|
- [Background](#background)
|
157
159
|
- [Pre-requisites](#pre-requisites)
|
@@ -184,6 +186,7 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
|
|
184
186
|
- [Login](#login)
|
185
187
|
- [Tic Tac Toe](#tic-tac-toe)
|
186
188
|
- [Contact Manager](#contact-manager)
|
189
|
+
- [Weather](#weather)
|
187
190
|
- [External Samples](#external-samples)
|
188
191
|
- [Glimmer Calculator](#glimmer-calculator)
|
189
192
|
- [Glimmer Supporting Libraries](#glimmer-supporting-libraries)
|
@@ -205,7 +208,6 @@ Please keep in mind this is a live list of innovative ideas, some of which have
|
|
205
208
|
- **HTML is for creating documents not interactive applications**. As such, software engineers can avoid it and focus on creating web applications more productively with Glimmer DSL for Opal in pure Ruby instead (just like they do in desktop development) while content creators and web designers can be the ones responsible for creating HTML documents for web content purposes only as HTML was originally intended. That way, Glimmer web GUI is used and embedded in web pages when providing users with applications while the rest of the web pages are maintained by non-engineers as pure HTML. This achieves a correct separation of responsibilities and better productivity and maintainability.
|
206
209
|
- **Approximate styles by developers via the Glimmer GUI DSL. Perfect styles by designers via pure CSS**. Developers can simply build GUI with approximate styling similar to desktop GUI and mockups without worrying about pixel-perfect aesthetics. Web designers can take styling further with pure CSS since every HTML element auto-generated by Glimmer DSL for Opal has a predictable ID and CSS class. This achieves a proper separation of responsibilities between developers and designers.
|
207
210
|
- **Web servers are used just like servers in traditional client/server architecture**, meaning they simply provide RMI services to enable centralizing some of the application logic and data in the cloud to make available everywhere and enable data-sharing with others.
|
208
|
-
- **Everybody In!** All JS frameworks sadly suffer from very major software design handicaps because of trying to ensure data security, so you end up with a very strict separation between server data and client data, making your head spin and worrying more about hackers and attackers than serving users. Try again! Thanks to the principle of Everybody In, Glimmer DSL for Opal apps have a very unique software architecture that revolves around the idea of multi-tenancy. Basically, every user gets their own server-side real-estate, that is a fully-secure-and-independent server-side instance that has its own user database, so hackers are not only intentionally allowed in, they are WELCOMED! As such, instead of protecting all users' data with an iron fist over a shared server/database (a terribly insecure architecture no matter how profilerate), you simply provide each user their own fully-independent server/client real-estate, thus be able to focus on serving them in the best way possible by writing code that is so simple it is just like desktop application code, but living in the Cloud on the Web. In summary, just code web as if you're on the desktop and be happy!
|
209
211
|
- **Forget Routers!** Glimmer DSL for Opal supports auto-routing of custom shells (windows), which are opened as separate tabs in a web browser with automatically generated routes and bookmarkable URLs.
|
210
212
|
|
211
213
|
## Background
|
@@ -252,7 +254,7 @@ Add the following to `Gemfile`:
|
|
252
254
|
gem 'opal-rails', '~> 1.1.2'
|
253
255
|
gem 'opal-async', '~> 1.2.0'
|
254
256
|
gem 'opal-jquery', '~> 0.4.4'
|
255
|
-
gem 'glimmer-dsl-opal', '~> 0.
|
257
|
+
gem 'glimmer-dsl-opal', '~> 0.16.0'
|
256
258
|
gem 'glimmer-dsl-xml', '~> 1.2.0', require: false
|
257
259
|
gem 'glimmer-dsl-css', '~> 1.2.0', require: false
|
258
260
|
|
@@ -441,48 +443,50 @@ require 'glimmer-dsl-opal/samples/hello/hello_combo'
|
|
441
443
|
Or add the Glimmer code directly if you prefer to play around with it:
|
442
444
|
|
443
445
|
```ruby
|
444
|
-
class
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
446
|
+
class HelloCombo
|
447
|
+
class Person
|
448
|
+
attr_accessor :country, :country_options
|
449
|
+
|
450
|
+
def initialize
|
451
|
+
self.country_options = ['', 'Canada', 'US', 'Mexico']
|
452
|
+
reset_country!
|
453
|
+
end
|
454
|
+
|
455
|
+
def reset_country!
|
456
|
+
self.country = 'Canada'
|
457
|
+
end
|
454
458
|
end
|
455
|
-
end
|
456
459
|
|
457
|
-
|
458
|
-
include Glimmer
|
460
|
+
include Glimmer::UI::CustomShell
|
459
461
|
|
460
|
-
|
461
|
-
person = Person.new
|
462
|
-
|
462
|
+
before_body {
|
463
|
+
@person = Person.new
|
464
|
+
}
|
465
|
+
|
466
|
+
body {
|
463
467
|
shell {
|
464
468
|
row_layout(:vertical) {
|
465
|
-
|
469
|
+
fill true
|
466
470
|
}
|
467
471
|
|
468
472
|
text 'Hello, Combo!'
|
469
473
|
|
470
474
|
combo(:read_only) {
|
471
|
-
selection <=> [person, :country]
|
475
|
+
selection <=> [@person, :country] # also binds to country_options by convention
|
472
476
|
}
|
473
477
|
|
474
478
|
button {
|
475
479
|
text 'Reset Selection'
|
476
480
|
|
477
481
|
on_widget_selected do
|
478
|
-
person.reset_country
|
482
|
+
@person.reset_country!
|
479
483
|
end
|
480
484
|
}
|
481
|
-
}
|
482
|
-
|
485
|
+
}
|
486
|
+
}
|
483
487
|
end
|
484
488
|
|
485
|
-
HelloCombo.
|
489
|
+
HelloCombo.launch
|
486
490
|
```
|
487
491
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
488
492
|
|
@@ -534,17 +538,17 @@ class HelloComputed
|
|
534
538
|
end
|
535
539
|
end
|
536
540
|
|
537
|
-
include Glimmer
|
541
|
+
include Glimmer::UI::CustomShell
|
538
542
|
|
539
|
-
|
543
|
+
before_body {
|
540
544
|
@contact = Contact.new(
|
541
545
|
first_name: 'Barry',
|
542
546
|
last_name: 'McKibbin',
|
543
547
|
year_of_birth: 1985
|
544
548
|
)
|
545
|
-
|
549
|
+
}
|
546
550
|
|
547
|
-
|
551
|
+
body {
|
548
552
|
shell {
|
549
553
|
text 'Hello, Computed!'
|
550
554
|
|
@@ -601,11 +605,11 @@ class HelloComputed
|
|
601
605
|
}
|
602
606
|
}
|
603
607
|
}
|
604
|
-
}
|
605
|
-
|
608
|
+
}
|
609
|
+
}
|
606
610
|
end
|
607
611
|
|
608
|
-
HelloComputed.
|
612
|
+
HelloComputed.launch
|
609
613
|
```
|
610
614
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
611
615
|
|
@@ -633,44 +637,6 @@ Add the following require statement to `app/assets/javascripts/application.rb`
|
|
633
637
|
require 'glimmer-dsl-opal/samples/hello/hello_list_single_selection'
|
634
638
|
```
|
635
639
|
|
636
|
-
Or add the Glimmer code directly if you prefer to play around with it:
|
637
|
-
|
638
|
-
```ruby
|
639
|
-
class Person
|
640
|
-
attr_accessor :country, :country_options
|
641
|
-
|
642
|
-
def initialize
|
643
|
-
self.country_options=["", "Canada", "US", "Mexico"]
|
644
|
-
self.country = "Canada"
|
645
|
-
end
|
646
|
-
|
647
|
-
def reset_country
|
648
|
-
self.country = "Canada"
|
649
|
-
end
|
650
|
-
end
|
651
|
-
|
652
|
-
class HelloListSingleSelection
|
653
|
-
include Glimmer
|
654
|
-
def launch
|
655
|
-
person = Person.new
|
656
|
-
shell {
|
657
|
-
composite {
|
658
|
-
list {
|
659
|
-
selection bind(person, :country)
|
660
|
-
}
|
661
|
-
button {
|
662
|
-
text "Reset"
|
663
|
-
on_widget_selected do
|
664
|
-
person.reset_country
|
665
|
-
end
|
666
|
-
}
|
667
|
-
}
|
668
|
-
}.open
|
669
|
-
end
|
670
|
-
end
|
671
|
-
|
672
|
-
HelloListSingleSelection.new.launch
|
673
|
-
```
|
674
640
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
675
641
|
|
676
642
|
![Glimmer DSL for SWT Hello List Single Selection](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-list-single-selection.png)
|
@@ -696,63 +662,6 @@ Add the following require statement to `app/assets/javascripts/application.rb`
|
|
696
662
|
require 'glimmer-dsl-opal/samples/hello/hello_list_multi_selection'
|
697
663
|
```
|
698
664
|
|
699
|
-
Or add the Glimmer code directly if you prefer to play around with it:
|
700
|
-
|
701
|
-
```ruby
|
702
|
-
class HelloListMultiSelection
|
703
|
-
class Person
|
704
|
-
attr_accessor :provinces, :provinces_options
|
705
|
-
|
706
|
-
def initialize
|
707
|
-
self.provinces_options = [
|
708
|
-
'',
|
709
|
-
'Alberta',
|
710
|
-
'British Columbia',
|
711
|
-
'Manitoba',
|
712
|
-
'New Brunswick',
|
713
|
-
'Newfoundland and Labrador',
|
714
|
-
'Northwest Territories',
|
715
|
-
'Nova Scotia',
|
716
|
-
'Nunavut',
|
717
|
-
'Ontario',
|
718
|
-
'Prince Edward Island',
|
719
|
-
'Quebec',
|
720
|
-
'Saskatchewan',
|
721
|
-
'Yukon'
|
722
|
-
]
|
723
|
-
reset_provinces
|
724
|
-
end
|
725
|
-
|
726
|
-
def reset_provinces
|
727
|
-
self.provinces = ['Quebec', 'Manitoba', 'Alberta']
|
728
|
-
end
|
729
|
-
end
|
730
|
-
|
731
|
-
include Glimmer
|
732
|
-
|
733
|
-
def launch
|
734
|
-
person = Person.new
|
735
|
-
|
736
|
-
shell {
|
737
|
-
grid_layout
|
738
|
-
|
739
|
-
text 'Hello, List Multi Selection!'
|
740
|
-
|
741
|
-
list(:multi) {
|
742
|
-
selection bind(person, :provinces)
|
743
|
-
}
|
744
|
-
|
745
|
-
button {
|
746
|
-
text 'Reset Selections To Default Values'
|
747
|
-
|
748
|
-
on_widget_selected { person.reset_provinces }
|
749
|
-
}
|
750
|
-
}.open
|
751
|
-
end
|
752
|
-
end
|
753
|
-
|
754
|
-
HelloListMultiSelection.new.launch
|
755
|
-
```
|
756
665
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
757
666
|
|
758
667
|
![Glimmer DSL for SWT Hello List Multi Selection](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-list-multi-selection.png)
|
@@ -778,18 +687,6 @@ Add the following require statement to `app/assets/javascripts/application.rb`
|
|
778
687
|
require 'glimmer-dsl-opal/samples/hello/hello_browser'
|
779
688
|
```
|
780
689
|
|
781
|
-
Or add the Glimmer code directly if you prefer to play around with it:
|
782
|
-
|
783
|
-
```ruby
|
784
|
-
include Glimmer
|
785
|
-
|
786
|
-
shell {
|
787
|
-
minimum_size 1024, 860
|
788
|
-
browser {
|
789
|
-
url 'http://brightonresort.com/about'
|
790
|
-
}
|
791
|
-
}.open
|
792
|
-
```
|
793
690
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
794
691
|
|
795
692
|
![Glimmer DSL for SWT Hello Browser](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-browser.png)
|
@@ -894,7 +791,7 @@ class GreetingLabel
|
|
894
791
|
after_body {
|
895
792
|
return if colors.nil?
|
896
793
|
|
897
|
-
Thread.new {
|
794
|
+
Thread.new { # imported from Glimmer DSL for SWT. In Opal, avoid Threads and sleep to avoid blocking GUI.
|
898
795
|
colors.cycle { |color|
|
899
796
|
async_exec {
|
900
797
|
self.color = color
|
@@ -909,7 +806,7 @@ class GreetingLabel
|
|
909
806
|
label(swt_style) {
|
910
807
|
text "#{greeting}, #{name}!"
|
911
808
|
font @font
|
912
|
-
foreground
|
809
|
+
foreground <=> [self, :color]
|
913
810
|
}
|
914
811
|
}
|
915
812
|
|
@@ -1131,103 +1028,14 @@ You should see "Hello, Custom Widget!"
|
|
1131
1028
|
|
1132
1029
|
#### Hello, Radio!
|
1133
1030
|
|
1031
|
+
This is the low level way of using `radio`
|
1032
|
+
|
1134
1033
|
Add the following require statement to `app/assets/javascripts/application.rb`
|
1135
1034
|
|
1136
1035
|
```ruby
|
1137
1036
|
require 'glimmer-dsl-opal/samples/hello/hello_radio'
|
1138
1037
|
```
|
1139
1038
|
|
1140
|
-
Or add the Glimmer code directly if you prefer to play around with it:
|
1141
|
-
|
1142
|
-
```ruby
|
1143
|
-
class HelloRadio
|
1144
|
-
class Person
|
1145
|
-
attr_accessor :male, :female, :child, :teen, :adult, :senior
|
1146
|
-
|
1147
|
-
def initialize
|
1148
|
-
reset
|
1149
|
-
end
|
1150
|
-
|
1151
|
-
def reset
|
1152
|
-
self.male = nil
|
1153
|
-
self.female = nil
|
1154
|
-
self.child = nil
|
1155
|
-
self.teen = nil
|
1156
|
-
self.adult = true
|
1157
|
-
self.senior = nil
|
1158
|
-
end
|
1159
|
-
end
|
1160
|
-
|
1161
|
-
include Glimmer
|
1162
|
-
|
1163
|
-
def launch
|
1164
|
-
person = Person.new
|
1165
|
-
|
1166
|
-
shell {
|
1167
|
-
text 'Hello, Radio!'
|
1168
|
-
row_layout :vertical
|
1169
|
-
|
1170
|
-
label {
|
1171
|
-
text 'Gender:'
|
1172
|
-
font style: :bold
|
1173
|
-
}
|
1174
|
-
|
1175
|
-
composite {
|
1176
|
-
row_layout
|
1177
|
-
|
1178
|
-
radio {
|
1179
|
-
text 'Male'
|
1180
|
-
selection bind(person, :male)
|
1181
|
-
}
|
1182
|
-
|
1183
|
-
radio {
|
1184
|
-
text 'Female'
|
1185
|
-
selection bind(person, :female)
|
1186
|
-
}
|
1187
|
-
}
|
1188
|
-
|
1189
|
-
label {
|
1190
|
-
text 'Age Group:'
|
1191
|
-
font style: :bold
|
1192
|
-
}
|
1193
|
-
|
1194
|
-
composite {
|
1195
|
-
row_layout
|
1196
|
-
|
1197
|
-
radio {
|
1198
|
-
text 'Child'
|
1199
|
-
selection bind(person, :child)
|
1200
|
-
}
|
1201
|
-
|
1202
|
-
radio {
|
1203
|
-
text 'Teen'
|
1204
|
-
selection bind(person, :teen)
|
1205
|
-
}
|
1206
|
-
|
1207
|
-
radio {
|
1208
|
-
text 'Adult'
|
1209
|
-
selection bind(person, :adult)
|
1210
|
-
}
|
1211
|
-
|
1212
|
-
radio {
|
1213
|
-
text 'Senior'
|
1214
|
-
selection bind(person, :senior)
|
1215
|
-
}
|
1216
|
-
}
|
1217
|
-
|
1218
|
-
button {
|
1219
|
-
text 'Reset'
|
1220
|
-
|
1221
|
-
on_widget_selected do
|
1222
|
-
person.reset
|
1223
|
-
end
|
1224
|
-
}
|
1225
|
-
}.open
|
1226
|
-
end
|
1227
|
-
end
|
1228
|
-
|
1229
|
-
HelloRadio.new.launch
|
1230
|
-
```
|
1231
1039
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
1232
1040
|
|
1233
1041
|
![Glimmer DSL for SWT Hello Radio](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-radio.png)
|
@@ -1247,6 +1055,8 @@ You should see "Hello, Radio!"
|
|
1247
1055
|
|
1248
1056
|
#### Hello, Radio Group!
|
1249
1057
|
|
1058
|
+
`radio_group` is a level higher than `radio` in abstraction. It generates a group of radio widgets based on available options in model `attribute_options` methods.
|
1059
|
+
|
1250
1060
|
Add the following require statement to `app/assets/javascripts/application.rb`
|
1251
1061
|
|
1252
1062
|
```ruby
|
@@ -1261,7 +1071,7 @@ class HelloRadioGroup
|
|
1261
1071
|
attr_accessor :gender, :age_group
|
1262
1072
|
|
1263
1073
|
def initialize
|
1264
|
-
reset
|
1074
|
+
reset!
|
1265
1075
|
end
|
1266
1076
|
|
1267
1077
|
def gender_options
|
@@ -1272,17 +1082,19 @@ class HelloRadioGroup
|
|
1272
1082
|
['Child', 'Teen', 'Adult', 'Senior']
|
1273
1083
|
end
|
1274
1084
|
|
1275
|
-
def reset
|
1085
|
+
def reset!
|
1276
1086
|
self.gender = nil
|
1277
1087
|
self.age_group = 'Adult'
|
1278
1088
|
end
|
1279
1089
|
end
|
1280
1090
|
|
1281
|
-
include Glimmer
|
1091
|
+
include Glimmer::UI::CustomShell
|
1282
1092
|
|
1283
|
-
|
1284
|
-
person = Person.new
|
1285
|
-
|
1093
|
+
before_body {
|
1094
|
+
@person = Person.new
|
1095
|
+
}
|
1096
|
+
|
1097
|
+
body {
|
1286
1098
|
shell {
|
1287
1099
|
text 'Hello, Radio Group!'
|
1288
1100
|
row_layout :vertical
|
@@ -1294,7 +1106,7 @@ class HelloRadioGroup
|
|
1294
1106
|
|
1295
1107
|
radio_group {
|
1296
1108
|
row_layout :horizontal
|
1297
|
-
selection
|
1109
|
+
selection <=> [@person, :gender]
|
1298
1110
|
}
|
1299
1111
|
|
1300
1112
|
label {
|
@@ -1304,21 +1116,21 @@ class HelloRadioGroup
|
|
1304
1116
|
|
1305
1117
|
radio_group {
|
1306
1118
|
row_layout :horizontal
|
1307
|
-
selection
|
1119
|
+
selection <=> [@person, :age_group]
|
1308
1120
|
}
|
1309
1121
|
|
1310
1122
|
button {
|
1311
1123
|
text 'Reset'
|
1312
1124
|
|
1313
1125
|
on_widget_selected do
|
1314
|
-
person.reset
|
1126
|
+
@person.reset!
|
1315
1127
|
end
|
1316
1128
|
}
|
1317
|
-
}
|
1318
|
-
|
1129
|
+
}
|
1130
|
+
}
|
1319
1131
|
end
|
1320
1132
|
|
1321
|
-
HelloRadioGroup.
|
1133
|
+
HelloRadioGroup.launch
|
1322
1134
|
```
|
1323
1135
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
1324
1136
|
|
@@ -1339,99 +1151,14 @@ You should see "Hello, Radio Group!"
|
|
1339
1151
|
|
1340
1152
|
#### Hello, Group!
|
1341
1153
|
|
1154
|
+
Not to be confused with `radio_group` or `checkbox_group`, `group` simply groups arbitrary widgets together and adds a title header above them.
|
1155
|
+
|
1342
1156
|
Add the following require statement to `app/assets/javascripts/application.rb`
|
1343
1157
|
|
1344
1158
|
```ruby
|
1345
1159
|
require 'glimmer-dsl-opal/samples/hello/hello_group'
|
1346
1160
|
```
|
1347
1161
|
|
1348
|
-
Or add the Glimmer code directly if you prefer to play around with it:
|
1349
|
-
|
1350
|
-
```ruby
|
1351
|
-
class HelloGroup
|
1352
|
-
class Person
|
1353
|
-
attr_accessor :male, :female, :child, :teen, :adult, :senior
|
1354
|
-
|
1355
|
-
def initialize
|
1356
|
-
reset
|
1357
|
-
end
|
1358
|
-
|
1359
|
-
def reset
|
1360
|
-
self.male = nil
|
1361
|
-
self.female = nil
|
1362
|
-
self.child = nil
|
1363
|
-
self.teen = nil
|
1364
|
-
self.adult = true
|
1365
|
-
self.senior = nil
|
1366
|
-
end
|
1367
|
-
end
|
1368
|
-
|
1369
|
-
include Glimmer
|
1370
|
-
|
1371
|
-
def launch
|
1372
|
-
person = Person.new
|
1373
|
-
|
1374
|
-
shell {
|
1375
|
-
text 'Hello, Group!'
|
1376
|
-
row_layout :vertical
|
1377
|
-
|
1378
|
-
group {
|
1379
|
-
row_layout
|
1380
|
-
|
1381
|
-
text 'Gender'
|
1382
|
-
font style: :bold
|
1383
|
-
|
1384
|
-
radio {
|
1385
|
-
text 'Male'
|
1386
|
-
selection bind(person, :male)
|
1387
|
-
}
|
1388
|
-
|
1389
|
-
radio {
|
1390
|
-
text 'Female'
|
1391
|
-
selection bind(person, :female)
|
1392
|
-
}
|
1393
|
-
}
|
1394
|
-
|
1395
|
-
group {
|
1396
|
-
row_layout
|
1397
|
-
|
1398
|
-
text 'Age Group'
|
1399
|
-
font style: :bold
|
1400
|
-
|
1401
|
-
radio {
|
1402
|
-
text 'Child'
|
1403
|
-
selection bind(person, :child)
|
1404
|
-
}
|
1405
|
-
|
1406
|
-
radio {
|
1407
|
-
text 'Teen'
|
1408
|
-
selection bind(person, :teen)
|
1409
|
-
}
|
1410
|
-
|
1411
|
-
radio {
|
1412
|
-
text 'Adult'
|
1413
|
-
selection bind(person, :adult)
|
1414
|
-
}
|
1415
|
-
|
1416
|
-
radio {
|
1417
|
-
text 'Senior'
|
1418
|
-
selection bind(person, :senior)
|
1419
|
-
}
|
1420
|
-
}
|
1421
|
-
|
1422
|
-
button {
|
1423
|
-
text 'Reset'
|
1424
|
-
|
1425
|
-
on_widget_selected do
|
1426
|
-
person.reset
|
1427
|
-
end
|
1428
|
-
}
|
1429
|
-
}.open
|
1430
|
-
end
|
1431
|
-
end
|
1432
|
-
|
1433
|
-
HelloGroup.new.launch
|
1434
|
-
```
|
1435
1162
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
1436
1163
|
|
1437
1164
|
![Glimmer DSL for SWT Hello Group](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-group.png)
|
@@ -1451,130 +1178,68 @@ You should see "Hello, Group!"
|
|
1451
1178
|
|
1452
1179
|
#### Hello, Checkbox!
|
1453
1180
|
|
1181
|
+
This is the low level way of using `checkbox`
|
1182
|
+
|
1454
1183
|
Add the following require statement to `app/assets/javascripts/application.rb`
|
1455
1184
|
|
1456
1185
|
```ruby
|
1457
1186
|
require 'glimmer-dsl-opal/samples/hello/hello_checkbox'
|
1458
1187
|
```
|
1459
1188
|
|
1189
|
+
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
1190
|
+
|
1191
|
+
![Glimmer DSL for SWT Hello Checkbox](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-checkbox.png)
|
1192
|
+
|
1193
|
+
Glimmer app on the web (using `glimmer-dsl-opal` gem):
|
1194
|
+
|
1195
|
+
Start the Rails server:
|
1196
|
+
```
|
1197
|
+
rails s
|
1198
|
+
```
|
1199
|
+
|
1200
|
+
Visit `http://localhost:3000`
|
1201
|
+
|
1202
|
+
You should see "Hello, Checkbox!"
|
1203
|
+
|
1204
|
+
![Glimmer DSL for Opal Hello Checkbox](images/glimmer-dsl-opal-hello-checkbox.png)
|
1205
|
+
|
1206
|
+
#### Hello, Checkbox Group!
|
1207
|
+
|
1208
|
+
`checkbox_group` is a level higher than `checkbox` in abstraction. It generates a group of checkbox widgets based on available options in model `attribute_options` methods.
|
1209
|
+
|
1210
|
+
Add the following require statement to `app/assets/javascripts/application.rb`
|
1211
|
+
|
1212
|
+
```ruby
|
1213
|
+
require 'glimmer-dsl-opal/samples/hello/hello_checkbox_group'
|
1214
|
+
```
|
1215
|
+
|
1460
1216
|
Or add the Glimmer code directly if you prefer to play around with it:
|
1461
1217
|
|
1462
1218
|
```ruby
|
1463
|
-
class
|
1219
|
+
class HelloCheckboxGroup
|
1464
1220
|
class Person
|
1465
|
-
attr_accessor :
|
1221
|
+
attr_accessor :activities
|
1466
1222
|
|
1467
1223
|
def initialize
|
1468
1224
|
reset_activities
|
1469
1225
|
end
|
1470
1226
|
|
1227
|
+
def activities_options
|
1228
|
+
['Skiing', 'Snowboarding', 'Snowmobiling', 'Snowshoeing']
|
1229
|
+
end
|
1230
|
+
|
1471
1231
|
def reset_activities
|
1472
|
-
self.
|
1473
|
-
self.snowboarding = true
|
1474
|
-
self.snowmobiling = false
|
1475
|
-
self.snowshoeing = false
|
1232
|
+
self.activities = ['Snowboarding']
|
1476
1233
|
end
|
1477
1234
|
end
|
1478
1235
|
|
1479
|
-
include Glimmer
|
1480
|
-
|
1481
|
-
def launch
|
1482
|
-
person = Person.new
|
1483
|
-
|
1484
|
-
shell {
|
1485
|
-
text 'Hello, Checkbox!'
|
1486
|
-
row_layout :vertical
|
1487
|
-
|
1488
|
-
label {
|
1489
|
-
text 'Check all snow activities you are interested in:'
|
1490
|
-
font style: :bold
|
1491
|
-
}
|
1492
|
-
|
1493
|
-
composite {
|
1494
|
-
checkbox {
|
1495
|
-
text 'Skiing'
|
1496
|
-
selection bind(person, :skiing)
|
1497
|
-
}
|
1498
|
-
|
1499
|
-
checkbox {
|
1500
|
-
text 'Snowboarding'
|
1501
|
-
selection bind(person, :snowboarding)
|
1502
|
-
}
|
1503
|
-
|
1504
|
-
checkbox {
|
1505
|
-
text 'Snowmobiling'
|
1506
|
-
selection bind(person, :snowmobiling)
|
1507
|
-
}
|
1508
|
-
|
1509
|
-
checkbox {
|
1510
|
-
text 'Snowshoeing'
|
1511
|
-
selection bind(person, :snowshoeing)
|
1512
|
-
}
|
1513
|
-
}
|
1514
|
-
|
1515
|
-
button {
|
1516
|
-
text 'Reset Activities'
|
1517
|
-
|
1518
|
-
on_widget_selected do
|
1519
|
-
person.reset_activities
|
1520
|
-
end
|
1521
|
-
}
|
1522
|
-
}.open
|
1523
|
-
end
|
1524
|
-
end
|
1525
|
-
|
1526
|
-
HelloCheckbox.new.launch
|
1527
|
-
```
|
1528
|
-
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
1529
|
-
|
1530
|
-
![Glimmer DSL for SWT Hello Checkbox](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-checkbox.png)
|
1531
|
-
|
1532
|
-
Glimmer app on the web (using `glimmer-dsl-opal` gem):
|
1533
|
-
|
1534
|
-
Start the Rails server:
|
1535
|
-
```
|
1536
|
-
rails s
|
1537
|
-
```
|
1538
|
-
|
1539
|
-
Visit `http://localhost:3000`
|
1540
|
-
|
1541
|
-
You should see "Hello, Checkbox!"
|
1542
|
-
|
1543
|
-
![Glimmer DSL for Opal Hello Checkbox](images/glimmer-dsl-opal-hello-checkbox.png)
|
1544
|
-
|
1545
|
-
#### Hello, Checkbox Group!
|
1546
|
-
|
1547
|
-
Add the following require statement to `app/assets/javascripts/application.rb`
|
1548
|
-
|
1549
|
-
```ruby
|
1550
|
-
require 'glimmer-dsl-opal/samples/hello/hello_checkbox_group'
|
1551
|
-
```
|
1552
|
-
|
1553
|
-
Or add the Glimmer code directly if you prefer to play around with it:
|
1554
|
-
|
1555
|
-
```ruby
|
1556
|
-
class HelloCheckboxGroup
|
1557
|
-
class Person
|
1558
|
-
attr_accessor :activities
|
1559
|
-
|
1560
|
-
def initialize
|
1561
|
-
reset_activities
|
1562
|
-
end
|
1563
|
-
|
1564
|
-
def activities_options
|
1565
|
-
['Skiing', 'Snowboarding', 'Snowmobiling', 'Snowshoeing']
|
1566
|
-
end
|
1567
|
-
|
1568
|
-
def reset_activities
|
1569
|
-
self.activities = ['Snowboarding']
|
1570
|
-
end
|
1571
|
-
end
|
1236
|
+
include Glimmer::UI::CustomShell
|
1572
1237
|
|
1573
|
-
|
1238
|
+
before_body {
|
1239
|
+
@person = Person.new
|
1240
|
+
}
|
1574
1241
|
|
1575
|
-
|
1576
|
-
person = Person.new
|
1577
|
-
|
1242
|
+
body {
|
1578
1243
|
shell {
|
1579
1244
|
text 'Hello, Checkbox Group!'
|
1580
1245
|
row_layout :vertical
|
@@ -1585,21 +1250,21 @@ class HelloCheckboxGroup
|
|
1585
1250
|
}
|
1586
1251
|
|
1587
1252
|
checkbox_group {
|
1588
|
-
selection
|
1253
|
+
selection <=> [@person, :activities]
|
1589
1254
|
}
|
1590
1255
|
|
1591
1256
|
button {
|
1592
1257
|
text 'Reset Activities'
|
1593
1258
|
|
1594
1259
|
on_widget_selected do
|
1595
|
-
person.reset_activities
|
1260
|
+
@person.reset_activities
|
1596
1261
|
end
|
1597
1262
|
}
|
1598
|
-
}
|
1599
|
-
|
1263
|
+
}
|
1264
|
+
}
|
1600
1265
|
end
|
1601
1266
|
|
1602
|
-
HelloCheckboxGroup.
|
1267
|
+
HelloCheckboxGroup.launch
|
1603
1268
|
```
|
1604
1269
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
1605
1270
|
|
@@ -1626,53 +1291,6 @@ Add the following require statement to `app/assets/javascripts/application.rb`
|
|
1626
1291
|
require 'glimmer-dsl-opal/samples/hello/hello_date_time'
|
1627
1292
|
```
|
1628
1293
|
|
1629
|
-
Or add the Glimmer code directly if you prefer to play around with it:
|
1630
|
-
|
1631
|
-
```ruby
|
1632
|
-
class HelloDateTime
|
1633
|
-
class Person
|
1634
|
-
attr_accessor :date_of_birth
|
1635
|
-
end
|
1636
|
-
|
1637
|
-
include Glimmer
|
1638
|
-
|
1639
|
-
def launch
|
1640
|
-
person = Person.new
|
1641
|
-
person.date_of_birth = DateTime.new(2013, 7, 12, 18, 37, 23)
|
1642
|
-
|
1643
|
-
shell {
|
1644
|
-
row_layout :vertical
|
1645
|
-
|
1646
|
-
text 'Hello, Date Time!'
|
1647
|
-
minimum_size 180, 180
|
1648
|
-
|
1649
|
-
label {
|
1650
|
-
text 'Date of Birth'
|
1651
|
-
font height: 16, style: :bold
|
1652
|
-
}
|
1653
|
-
|
1654
|
-
date { # alias for date_time(:date)
|
1655
|
-
date_time bind(person, :date_of_birth)
|
1656
|
-
}
|
1657
|
-
|
1658
|
-
date_drop_down { # alias for date_time(:date, :drop_down)
|
1659
|
-
date_time bind(person, :date_of_birth)
|
1660
|
-
}
|
1661
|
-
|
1662
|
-
time { # alias for date_time(:time)
|
1663
|
-
date_time bind(person, :date_of_birth)
|
1664
|
-
}
|
1665
|
-
|
1666
|
-
calendar { # alias for date_time(:calendar)
|
1667
|
-
date_time bind(person, :date_of_birth)
|
1668
|
-
}
|
1669
|
-
}.open
|
1670
|
-
end
|
1671
|
-
end
|
1672
|
-
|
1673
|
-
HelloDateTime.new.launch
|
1674
|
-
```
|
1675
|
-
|
1676
1294
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
1677
1295
|
|
1678
1296
|
![Glimmer DSL for SWT Hello Checkbox Group](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-date-time.png)
|
@@ -1700,263 +1318,6 @@ Add the following require statement to `app/assets/javascripts/application.rb`
|
|
1700
1318
|
require 'glimmer-dsl-opal/samples/hello/hello_table'
|
1701
1319
|
```
|
1702
1320
|
|
1703
|
-
Or add the Glimmer code directly if you prefer to play around with it:
|
1704
|
-
|
1705
|
-
```ruby
|
1706
|
-
class HelloTable
|
1707
|
-
class BaseballGame
|
1708
|
-
class << self
|
1709
|
-
attr_accessor :selected_game
|
1710
|
-
|
1711
|
-
def all_playoff_games
|
1712
|
-
@all_playoff_games ||= {
|
1713
|
-
'NLDS' => [
|
1714
|
-
new(Time.new(2037, 10, 6, 12, 0), 'Chicago Cubs', 'Milwaukee Brewers', 'Free Bobblehead'),
|
1715
|
-
new(Time.new(2037, 10, 7, 12, 0), 'Chicago Cubs', 'Milwaukee Brewers'),
|
1716
|
-
new(Time.new(2037, 10, 8, 12, 0), 'Milwaukee Brewers', 'Chicago Cubs'),
|
1717
|
-
new(Time.new(2037, 10, 9, 12, 0), 'Milwaukee Brewers', 'Chicago Cubs'),
|
1718
|
-
new(Time.new(2037, 10, 10, 12, 0), 'Milwaukee Brewers', 'Chicago Cubs', 'Free Umbrella'),
|
1719
|
-
new(Time.new(2037, 10, 6, 18, 0), 'Cincinnati Reds', 'St Louis Cardinals', 'Free Bobblehead'),
|
1720
|
-
new(Time.new(2037, 10, 7, 18, 0), 'Cincinnati Reds', 'St Louis Cardinals'),
|
1721
|
-
new(Time.new(2037, 10, 8, 18, 0), 'St Louis Cardinals', 'Cincinnati Reds'),
|
1722
|
-
new(Time.new(2037, 10, 9, 18, 0), 'St Louis Cardinals', 'Cincinnati Reds'),
|
1723
|
-
new(Time.new(2037, 10, 10, 18, 0), 'St Louis Cardinals', 'Cincinnati Reds', 'Free Umbrella'),
|
1724
|
-
],
|
1725
|
-
'ALDS' => [
|
1726
|
-
new(Time.new(2037, 10, 6, 12, 0), 'New York Yankees', 'Boston Red Sox', 'Free Bobblehead'),
|
1727
|
-
new(Time.new(2037, 10, 7, 12, 0), 'New York Yankees', 'Boston Red Sox'),
|
1728
|
-
new(Time.new(2037, 10, 8, 12, 0), 'Boston Red Sox', 'New York Yankees'),
|
1729
|
-
new(Time.new(2037, 10, 9, 12, 0), 'Boston Red Sox', 'New York Yankees'),
|
1730
|
-
new(Time.new(2037, 10, 10, 12, 0), 'Boston Red Sox', 'New York Yankees', 'Free Umbrella'),
|
1731
|
-
new(Time.new(2037, 10, 6, 18, 0), 'Houston Astros', 'Cleveland Indians', 'Free Bobblehead'),
|
1732
|
-
new(Time.new(2037, 10, 7, 18, 0), 'Houston Astros', 'Cleveland Indians'),
|
1733
|
-
new(Time.new(2037, 10, 8, 18, 0), 'Cleveland Indians', 'Houston Astros'),
|
1734
|
-
new(Time.new(2037, 10, 9, 18, 0), 'Cleveland Indians', 'Houston Astros'),
|
1735
|
-
new(Time.new(2037, 10, 10, 18, 0), 'Cleveland Indians', 'Houston Astros', 'Free Umbrella'),
|
1736
|
-
],
|
1737
|
-
'NLCS' => [
|
1738
|
-
new(Time.new(2037, 10, 12, 12, 0), 'Chicago Cubs', 'Cincinnati Reds', 'Free Towel'),
|
1739
|
-
new(Time.new(2037, 10, 13, 12, 0), 'Chicago Cubs', 'Cincinnati Reds'),
|
1740
|
-
new(Time.new(2037, 10, 14, 12, 0), 'Cincinnati Reds', 'Chicago Cubs'),
|
1741
|
-
new(Time.new(2037, 10, 15, 18, 0), 'Cincinnati Reds', 'Chicago Cubs'),
|
1742
|
-
new(Time.new(2037, 10, 16, 18, 0), 'Cincinnati Reds', 'Chicago Cubs'),
|
1743
|
-
new(Time.new(2037, 10, 17, 18, 0), 'Chicago Cubs', 'Cincinnati Reds'),
|
1744
|
-
new(Time.new(2037, 10, 18, 12, 0), 'Chicago Cubs', 'Cincinnati Reds', 'Free Poncho'),
|
1745
|
-
],
|
1746
|
-
'ALCS' => [
|
1747
|
-
new(Time.new(2037, 10, 12, 12, 0), 'Houston Astros', 'Boston Red Sox', 'Free Towel'),
|
1748
|
-
new(Time.new(2037, 10, 13, 12, 0), 'Houston Astros', 'Boston Red Sox'),
|
1749
|
-
new(Time.new(2037, 10, 14, 12, 0), 'Boston Red Sox', 'Houston Astros'),
|
1750
|
-
new(Time.new(2037, 10, 15, 18, 0), 'Boston Red Sox', 'Houston Astros'),
|
1751
|
-
new(Time.new(2037, 10, 16, 18, 0), 'Boston Red Sox', 'Houston Astros'),
|
1752
|
-
new(Time.new(2037, 10, 17, 18, 0), 'Houston Astros', 'Boston Red Sox'),
|
1753
|
-
new(Time.new(2037, 10, 18, 12, 0), 'Houston Astros', 'Boston Red Sox', 'Free Poncho'),
|
1754
|
-
],
|
1755
|
-
'World Series' => [
|
1756
|
-
new(Time.new(2037, 10, 20, 18, 0), 'Chicago Cubs', 'Boston Red Sox', 'Free Baseball Cap'),
|
1757
|
-
new(Time.new(2037, 10, 21, 18, 0), 'Chicago Cubs', 'Boston Red Sox'),
|
1758
|
-
new(Time.new(2037, 10, 22, 18, 0), 'Boston Red Sox', 'Chicago Cubs'),
|
1759
|
-
new(Time.new(2037, 10, 23, 18, 0), 'Boston Red Sox', 'Chicago Cubs'),
|
1760
|
-
new(Time.new(2037, 10, 24, 18, 0), 'Boston Red Sox', 'Chicago Cubs'),
|
1761
|
-
new(Time.new(2037, 10, 25, 18, 0), 'Chicago Cubs', 'Boston Red Sox'),
|
1762
|
-
new(Time.new(2037, 10, 26, 18, 0), 'Chicago Cubs', 'Boston Red Sox', 'Free World Series Polo'),
|
1763
|
-
]
|
1764
|
-
}
|
1765
|
-
end
|
1766
|
-
|
1767
|
-
def playoff_type
|
1768
|
-
@playoff_type ||= 'World Series'
|
1769
|
-
end
|
1770
|
-
|
1771
|
-
def playoff_type=(new_playoff_type)
|
1772
|
-
@playoff_type = new_playoff_type
|
1773
|
-
self.schedule=(all_playoff_games[@playoff_type])
|
1774
|
-
end
|
1775
|
-
|
1776
|
-
def playoff_type_options
|
1777
|
-
all_playoff_games.keys
|
1778
|
-
end
|
1779
|
-
|
1780
|
-
def schedule
|
1781
|
-
@schedule ||= all_playoff_games[playoff_type]
|
1782
|
-
end
|
1783
|
-
|
1784
|
-
def schedule=(new_schedule)
|
1785
|
-
@schedule = new_schedule
|
1786
|
-
end
|
1787
|
-
end
|
1788
|
-
|
1789
|
-
include Glimmer
|
1790
|
-
include Glimmer::DataBinding::ObservableModel
|
1791
|
-
|
1792
|
-
TEAM_BALLPARKS = {
|
1793
|
-
'Boston Red Sox' => 'Fenway Park',
|
1794
|
-
'Chicago Cubs' => 'Wrigley Field',
|
1795
|
-
'Cincinnati Reds' => 'Great American Ball Park',
|
1796
|
-
'Cleveland Indians' => 'Progressive Field',
|
1797
|
-
'Houston Astros' => 'Minute Maid Park',
|
1798
|
-
'Milwaukee Brewers' => 'Miller Park',
|
1799
|
-
'New York Yankees' => 'Yankee Stadium',
|
1800
|
-
'St Louis Cardinals' => 'Busch Stadium',
|
1801
|
-
}
|
1802
|
-
|
1803
|
-
attr_accessor :date_time, :home_team, :away_team, :ballpark, :promotion
|
1804
|
-
|
1805
|
-
def initialize(date_time, home_team, away_team, promotion = 'N/A')
|
1806
|
-
self.date_time = date_time
|
1807
|
-
self.home_team = home_team
|
1808
|
-
self.away_team = away_team
|
1809
|
-
self.promotion = promotion
|
1810
|
-
observe(self, :date_time) do |new_value|
|
1811
|
-
notify_observers(:game_date)
|
1812
|
-
notify_observers(:game_time)
|
1813
|
-
end
|
1814
|
-
end
|
1815
|
-
|
1816
|
-
def home_team=(home_team_value)
|
1817
|
-
if home_team_value != away_team
|
1818
|
-
@home_team = home_team_value
|
1819
|
-
self.ballpark = TEAM_BALLPARKS[@home_team]
|
1820
|
-
end
|
1821
|
-
end
|
1822
|
-
|
1823
|
-
def away_team=(away_team_value)
|
1824
|
-
if away_team_value != home_team
|
1825
|
-
@away_team = away_team_value
|
1826
|
-
end
|
1827
|
-
end
|
1828
|
-
|
1829
|
-
def date
|
1830
|
-
Date.new(date_time.year, date_time.month, date_time.day)
|
1831
|
-
end
|
1832
|
-
|
1833
|
-
def time
|
1834
|
-
Time.new(0, 1, 1, date_time.hour, date_time.min, date_time.sec, '+00:00')
|
1835
|
-
end
|
1836
|
-
|
1837
|
-
def game_date
|
1838
|
-
date_time.strftime("%m/%d/%Y")
|
1839
|
-
end
|
1840
|
-
|
1841
|
-
def game_time
|
1842
|
-
date_time.strftime("%I:%M %p")
|
1843
|
-
end
|
1844
|
-
|
1845
|
-
def home_team_options
|
1846
|
-
TEAM_BALLPARKS.keys
|
1847
|
-
end
|
1848
|
-
|
1849
|
-
def away_team_options
|
1850
|
-
TEAM_BALLPARKS.keys
|
1851
|
-
end
|
1852
|
-
|
1853
|
-
def ballpark_options
|
1854
|
-
[TEAM_BALLPARKS[@home_team], TEAM_BALLPARKS[@away_team]]
|
1855
|
-
end
|
1856
|
-
|
1857
|
-
def to_s
|
1858
|
-
"#{home_team} vs #{away_team} at #{ballpark} on #{game_date} #{game_time}"
|
1859
|
-
end
|
1860
|
-
|
1861
|
-
def book!
|
1862
|
-
"Thank you for booking #{to_s}"
|
1863
|
-
end
|
1864
|
-
end
|
1865
|
-
|
1866
|
-
include Glimmer
|
1867
|
-
|
1868
|
-
def launch
|
1869
|
-
shell {
|
1870
|
-
grid_layout
|
1871
|
-
|
1872
|
-
text 'Hello, Table!'
|
1873
|
-
|
1874
|
-
label {
|
1875
|
-
layout_data :center, :center, true, false
|
1876
|
-
|
1877
|
-
text 'Baseball Playoff Schedule'
|
1878
|
-
font height: 30, style: :bold
|
1879
|
-
}
|
1880
|
-
|
1881
|
-
combo(:read_only) {
|
1882
|
-
layout_data :center, :center, true, false
|
1883
|
-
selection bind(BaseballGame, :playoff_type)
|
1884
|
-
font height: 16
|
1885
|
-
}
|
1886
|
-
|
1887
|
-
table(:editable) { |table_proxy|
|
1888
|
-
layout_data :fill, :fill, true, true
|
1889
|
-
|
1890
|
-
table_column {
|
1891
|
-
text 'Game Date'
|
1892
|
-
width 150
|
1893
|
-
sort_property :date # ensure sorting by real date value (not `game_date` string specified in items below)
|
1894
|
-
editor :date_drop_down, property: :date_time
|
1895
|
-
}
|
1896
|
-
table_column {
|
1897
|
-
text 'Game Time'
|
1898
|
-
width 150
|
1899
|
-
sort_property :time # ensure sorting by real time value (not `game_time` string specified in items below)
|
1900
|
-
editor :time, property: :date_time
|
1901
|
-
}
|
1902
|
-
table_column {
|
1903
|
-
text 'Ballpark'
|
1904
|
-
width 180
|
1905
|
-
editor :none
|
1906
|
-
}
|
1907
|
-
table_column {
|
1908
|
-
text 'Home Team'
|
1909
|
-
width 150
|
1910
|
-
editor :combo, :read_only # read_only is simply an SWT style passed to combo widget
|
1911
|
-
}
|
1912
|
-
table_column {
|
1913
|
-
text 'Away Team'
|
1914
|
-
width 150
|
1915
|
-
editor :combo, :read_only # read_only is simply an SWT style passed to combo widget
|
1916
|
-
}
|
1917
|
-
table_column {
|
1918
|
-
text 'Promotion'
|
1919
|
-
width 150
|
1920
|
-
# default text editor is used here
|
1921
|
-
}
|
1922
|
-
|
1923
|
-
# Data-bind table items (rows) to a model collection property, specifying column properties ordering per nested model
|
1924
|
-
items bind(BaseballGame, :schedule), column_properties(:game_date, :game_time, :ballpark, :home_team, :away_team, :promotion)
|
1925
|
-
|
1926
|
-
# Data-bind table selection
|
1927
|
-
selection bind(BaseballGame, :selected_game)
|
1928
|
-
|
1929
|
-
# Default initial sort property
|
1930
|
-
sort_property :date
|
1931
|
-
|
1932
|
-
# Sort by these additional properties after handling sort by the column the user clicked
|
1933
|
-
additional_sort_properties :date, :time, :home_team, :away_team, :ballpark, :promotion
|
1934
|
-
}
|
1935
|
-
|
1936
|
-
button {
|
1937
|
-
text 'Book Selected Game'
|
1938
|
-
layout_data :center, :center, true, false
|
1939
|
-
font height: 16
|
1940
|
-
enabled bind(BaseballGame, :selected_game)
|
1941
|
-
|
1942
|
-
on_widget_selected {
|
1943
|
-
book_selected_game
|
1944
|
-
}
|
1945
|
-
}
|
1946
|
-
}.open
|
1947
|
-
end
|
1948
|
-
|
1949
|
-
def book_selected_game
|
1950
|
-
message_box {
|
1951
|
-
text 'Baseball Game Booked!'
|
1952
|
-
message BaseballGame.selected_game.book!
|
1953
|
-
}.open
|
1954
|
-
end
|
1955
|
-
end
|
1956
|
-
|
1957
|
-
HelloTable.new.launch
|
1958
|
-
```
|
1959
|
-
|
1960
1321
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
1961
1322
|
|
1962
1323
|
![Glimmer DSL for SWT Hello Table](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-table.png)
|
@@ -2051,30 +1412,30 @@ Or add the Glimmer code directly if you prefer to play around with it:
|
|
2051
1412
|
|
2052
1413
|
```ruby
|
2053
1414
|
class HelloButton
|
2054
|
-
include Glimmer
|
1415
|
+
include Glimmer::UI::CustomShell
|
2055
1416
|
|
2056
1417
|
attr_accessor :count
|
2057
1418
|
|
2058
|
-
|
1419
|
+
before_body {
|
2059
1420
|
@count = 0
|
2060
|
-
|
1421
|
+
}
|
2061
1422
|
|
2062
|
-
|
1423
|
+
body {
|
2063
1424
|
shell {
|
2064
1425
|
text 'Hello, Button!'
|
2065
1426
|
|
2066
1427
|
button {
|
2067
|
-
text
|
1428
|
+
text <= [self, :count, on_read: ->(value) { "Click To Increment: #{value} " }]
|
2068
1429
|
|
2069
1430
|
on_widget_selected {
|
2070
1431
|
self.count += 1
|
2071
1432
|
}
|
2072
1433
|
}
|
2073
|
-
}
|
2074
|
-
|
1434
|
+
}
|
1435
|
+
}
|
2075
1436
|
end
|
2076
1437
|
|
2077
|
-
HelloButton.
|
1438
|
+
HelloButton.launch
|
2078
1439
|
```
|
2079
1440
|
|
2080
1441
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
@@ -2694,19 +2055,24 @@ class LoginPresenter
|
|
2694
2055
|
end
|
2695
2056
|
|
2696
2057
|
class Login
|
2697
|
-
include Glimmer
|
2058
|
+
include Glimmer::UI::CustomShell
|
2059
|
+
|
2060
|
+
before_body {
|
2061
|
+
@presenter = LoginPresenter.new
|
2062
|
+
}
|
2698
2063
|
|
2699
|
-
|
2700
|
-
|
2701
|
-
@shell = shell {
|
2064
|
+
body {
|
2065
|
+
shell {
|
2702
2066
|
text "Login"
|
2067
|
+
|
2703
2068
|
composite {
|
2704
2069
|
grid_layout 2, false #two columns with differing widths
|
2705
2070
|
|
2706
2071
|
label { text "Username:" } # goes in column 1
|
2707
2072
|
@user_name_text = text { # goes in column 2
|
2708
|
-
text
|
2709
|
-
enabled
|
2073
|
+
text <=> [@presenter, :user_name]
|
2074
|
+
enabled <= [@presenter, :logged_out?, computed_by: :status]
|
2075
|
+
|
2710
2076
|
on_key_pressed { |event|
|
2711
2077
|
@password_text.set_focus if event.keyCode == swt(:cr)
|
2712
2078
|
}
|
@@ -2714,43 +2080,47 @@ class Login
|
|
2714
2080
|
|
2715
2081
|
label { text "Password:" }
|
2716
2082
|
@password_text = text(:password, :border) {
|
2717
|
-
text
|
2718
|
-
enabled
|
2083
|
+
text <=> [@presenter, :password]
|
2084
|
+
enabled <= [@presenter, :logged_out?, computed_by: :status]
|
2085
|
+
|
2719
2086
|
on_key_pressed { |event|
|
2720
|
-
presenter.login if event.keyCode == swt(:cr)
|
2087
|
+
@presenter.login! if event.keyCode == swt(:cr)
|
2721
2088
|
}
|
2722
2089
|
}
|
2723
2090
|
|
2724
2091
|
label { text "Status:" }
|
2725
|
-
label { text
|
2092
|
+
label { text <= [@presenter, :status] }
|
2726
2093
|
|
2727
2094
|
button {
|
2728
2095
|
text "Login"
|
2729
|
-
enabled
|
2730
|
-
|
2096
|
+
enabled <= [@presenter, :logged_out?, computed_by: :status]
|
2097
|
+
|
2098
|
+
on_widget_selected { @presenter.login! }
|
2731
2099
|
on_key_pressed { |event|
|
2732
|
-
|
2100
|
+
if event.keyCode == swt(:cr)
|
2101
|
+
@presenter.login!
|
2102
|
+
end
|
2733
2103
|
}
|
2734
2104
|
}
|
2735
2105
|
|
2736
2106
|
button {
|
2737
2107
|
text "Logout"
|
2738
|
-
enabled
|
2739
|
-
|
2108
|
+
enabled <= [@presenter, :logged_in?, computed_by: :status]
|
2109
|
+
|
2110
|
+
on_widget_selected { @presenter.logout! }
|
2740
2111
|
on_key_pressed { |event|
|
2741
2112
|
if event.keyCode == swt(:cr)
|
2742
|
-
presenter.logout
|
2113
|
+
@presenter.logout!
|
2743
2114
|
@user_name_text.set_focus
|
2744
2115
|
end
|
2745
2116
|
}
|
2746
2117
|
}
|
2747
2118
|
}
|
2748
2119
|
}
|
2749
|
-
|
2750
|
-
end
|
2120
|
+
}
|
2751
2121
|
end
|
2752
2122
|
|
2753
|
-
Login.
|
2123
|
+
Login.launch
|
2754
2124
|
```
|
2755
2125
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
2756
2126
|
|
@@ -2781,214 +2151,7 @@ Add the following require statement to `app/assets/javascripts/application.rb`
|
|
2781
2151
|
require 'glimmer-dsl-opal/samples/elaborate/tic_tac_toe'
|
2782
2152
|
```
|
2783
2153
|
|
2784
|
-
Or add the Glimmer code directly if you prefer to play around with it:
|
2785
|
-
|
2786
2154
|
```ruby
|
2787
|
-
class TicTacToe
|
2788
|
-
class Cell
|
2789
|
-
EMPTY = ""
|
2790
|
-
attr_accessor :sign, :empty
|
2791
|
-
|
2792
|
-
def initialize
|
2793
|
-
reset
|
2794
|
-
end
|
2795
|
-
|
2796
|
-
def mark(sign)
|
2797
|
-
self.sign = sign
|
2798
|
-
end
|
2799
|
-
|
2800
|
-
def reset
|
2801
|
-
self.sign = EMPTY
|
2802
|
-
end
|
2803
|
-
|
2804
|
-
def sign=(sign_symbol)
|
2805
|
-
@sign = sign_symbol
|
2806
|
-
self.empty = sign == EMPTY
|
2807
|
-
end
|
2808
|
-
|
2809
|
-
def marked
|
2810
|
-
!empty
|
2811
|
-
end
|
2812
|
-
end
|
2813
|
-
end
|
2814
|
-
|
2815
|
-
class TicTacToe
|
2816
|
-
class Board
|
2817
|
-
DRAW = :draw
|
2818
|
-
IN_PROGRESS = :in_progress
|
2819
|
-
WIN = :win
|
2820
|
-
attr :winning_sign
|
2821
|
-
attr_accessor :game_status
|
2822
|
-
|
2823
|
-
def initialize
|
2824
|
-
@sign_state_machine = {nil => "X", "X" => "O", "O" => "X"}
|
2825
|
-
build_grid
|
2826
|
-
@winning_sign = Cell::EMPTY
|
2827
|
-
@game_status = IN_PROGRESS
|
2828
|
-
end
|
2829
|
-
|
2830
|
-
#row and column numbers are 1-based
|
2831
|
-
def mark(row, column)
|
2832
|
-
self[row, column].mark(current_sign)
|
2833
|
-
game_over? #updates winning sign
|
2834
|
-
end
|
2835
|
-
|
2836
|
-
def current_sign
|
2837
|
-
@current_sign = @sign_state_machine[@current_sign]
|
2838
|
-
end
|
2839
|
-
|
2840
|
-
def [](row, column)
|
2841
|
-
@grid[row-1][column-1]
|
2842
|
-
end
|
2843
|
-
|
2844
|
-
def game_over?
|
2845
|
-
win? or draw?
|
2846
|
-
end
|
2847
|
-
|
2848
|
-
def win?
|
2849
|
-
win = (row_win? or column_win? or diagonal_win?)
|
2850
|
-
self.game_status=WIN if win
|
2851
|
-
win
|
2852
|
-
end
|
2853
|
-
|
2854
|
-
def reset
|
2855
|
-
(1..3).each do |row|
|
2856
|
-
(1..3).each do |column|
|
2857
|
-
self[row, column].reset
|
2858
|
-
end
|
2859
|
-
end
|
2860
|
-
@winning_sign = Cell::EMPTY
|
2861
|
-
@current_sign = nil
|
2862
|
-
self.game_status=IN_PROGRESS
|
2863
|
-
end
|
2864
|
-
|
2865
|
-
private
|
2866
|
-
|
2867
|
-
def build_grid
|
2868
|
-
@grid = []
|
2869
|
-
3.times do |row_index| #0-based
|
2870
|
-
@grid << []
|
2871
|
-
3.times { @grid[row_index] << Cell.new }
|
2872
|
-
end
|
2873
|
-
end
|
2874
|
-
|
2875
|
-
def row_win?
|
2876
|
-
(1..3).each do |row|
|
2877
|
-
if row_has_same_sign(row)
|
2878
|
-
@winning_sign = self[row, 1].sign
|
2879
|
-
return true
|
2880
|
-
end
|
2881
|
-
end
|
2882
|
-
false
|
2883
|
-
end
|
2884
|
-
|
2885
|
-
def column_win?
|
2886
|
-
(1..3).each do |column|
|
2887
|
-
if column_has_same_sign(column)
|
2888
|
-
@winning_sign = self[1, column].sign
|
2889
|
-
return true
|
2890
|
-
end
|
2891
|
-
end
|
2892
|
-
false
|
2893
|
-
end
|
2894
|
-
|
2895
|
-
#needs refactoring if we ever decide to make the board size dynamic
|
2896
|
-
def diagonal_win?
|
2897
|
-
if (self[1, 1].sign == self[2, 2].sign) and (self[2, 2].sign == self[3, 3].sign) and self[1, 1].marked
|
2898
|
-
@winning_sign = self[1, 1].sign
|
2899
|
-
return true
|
2900
|
-
end
|
2901
|
-
if (self[3, 1].sign == self[2, 2].sign) and (self[2, 2].sign == self[1, 3].sign) and self[3, 1].marked
|
2902
|
-
@winning_sign = self[3, 1].sign
|
2903
|
-
return true
|
2904
|
-
end
|
2905
|
-
false
|
2906
|
-
end
|
2907
|
-
|
2908
|
-
def draw?
|
2909
|
-
@board_full = true
|
2910
|
-
3.times do |x|
|
2911
|
-
3.times do |y|
|
2912
|
-
@board_full = false if self[x, y].empty
|
2913
|
-
end
|
2914
|
-
end
|
2915
|
-
self.game_status = DRAW if @board_full
|
2916
|
-
@board_full
|
2917
|
-
end
|
2918
|
-
|
2919
|
-
def row_has_same_sign(number)
|
2920
|
-
row_sign = self[number, 1].sign
|
2921
|
-
[2, 3].each do |column|
|
2922
|
-
return false unless row_sign == (self[number, column].sign)
|
2923
|
-
end
|
2924
|
-
true if self[number, 1].marked
|
2925
|
-
end
|
2926
|
-
|
2927
|
-
def column_has_same_sign(number)
|
2928
|
-
column_sign = self[1, number].sign
|
2929
|
-
[2, 3].each do |row|
|
2930
|
-
return false unless column_sign == (self[row, number].sign)
|
2931
|
-
end
|
2932
|
-
true if self[1, number].marked
|
2933
|
-
end
|
2934
|
-
|
2935
|
-
end
|
2936
|
-
end
|
2937
|
-
|
2938
|
-
class TicTacToe
|
2939
|
-
include Glimmer
|
2940
|
-
|
2941
|
-
def initialize
|
2942
|
-
@tic_tac_toe_board = Board.new
|
2943
|
-
@shell = shell {
|
2944
|
-
text "Tic-Tac-Toe"
|
2945
|
-
minimum_size 150, 178
|
2946
|
-
composite {
|
2947
|
-
grid_layout 3, true
|
2948
|
-
(1..3).each { |row|
|
2949
|
-
(1..3).each { |column|
|
2950
|
-
button {
|
2951
|
-
layout_data :fill, :fill, true, true
|
2952
|
-
text bind(@tic_tac_toe_board[row, column], :sign)
|
2953
|
-
enabled bind(@tic_tac_toe_board[row, column], :empty)
|
2954
|
-
font style: :bold, height: 20
|
2955
|
-
on_widget_selected {
|
2956
|
-
@tic_tac_toe_board.mark(row, column)
|
2957
|
-
}
|
2958
|
-
}
|
2959
|
-
}
|
2960
|
-
}
|
2961
|
-
}
|
2962
|
-
}
|
2963
|
-
observe(@tic_tac_toe_board, :game_status) { |game_status|
|
2964
|
-
display_win_message if game_status == Board::WIN
|
2965
|
-
display_draw_message if game_status == Board::DRAW
|
2966
|
-
}
|
2967
|
-
end
|
2968
|
-
|
2969
|
-
def display_win_message
|
2970
|
-
display_game_over_message("Player #{@tic_tac_toe_board.winning_sign} has won!")
|
2971
|
-
end
|
2972
|
-
|
2973
|
-
def display_draw_message
|
2974
|
-
display_game_over_message("Draw!")
|
2975
|
-
end
|
2976
|
-
|
2977
|
-
def display_game_over_message(message_text)
|
2978
|
-
message_box(@shell) {
|
2979
|
-
text 'Game Over'
|
2980
|
-
message message_text
|
2981
|
-
}.open
|
2982
|
-
@tic_tac_toe_board.reset
|
2983
|
-
end
|
2984
|
-
|
2985
|
-
def open
|
2986
|
-
@shell.open
|
2987
|
-
end
|
2988
|
-
end
|
2989
|
-
|
2990
|
-
TicTacToe.new.open
|
2991
|
-
```
|
2992
2155
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
2993
2156
|
|
2994
2157
|
![Glimmer DSL for SWT Tic Tac Toe](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-tic-tac-toe.png)
|
@@ -3018,321 +2181,6 @@ Add the following require statement to `app/assets/javascripts/application.rb`
|
|
3018
2181
|
require 'glimmer-dsl-opal/samples/elaborate/contact_manager'
|
3019
2182
|
```
|
3020
2183
|
|
3021
|
-
Or add the Glimmer code directly if you prefer to play around with it:
|
3022
|
-
|
3023
|
-
```ruby
|
3024
|
-
class ContactManager
|
3025
|
-
class Contact
|
3026
|
-
attr_accessor :first_name, :last_name, :email
|
3027
|
-
|
3028
|
-
def initialize(attribute_map)
|
3029
|
-
@first_name = attribute_map[:first_name]
|
3030
|
-
@last_name = attribute_map[:last_name]
|
3031
|
-
@email = attribute_map[:email]
|
3032
|
-
end
|
3033
|
-
end
|
3034
|
-
end
|
3035
|
-
|
3036
|
-
class ContactManager
|
3037
|
-
class ContactRepository
|
3038
|
-
NAMES_FIRST = %w[
|
3039
|
-
Liam
|
3040
|
-
Noah
|
3041
|
-
William
|
3042
|
-
James
|
3043
|
-
Oliver
|
3044
|
-
Benjamin
|
3045
|
-
Elijah
|
3046
|
-
Lucas
|
3047
|
-
Mason
|
3048
|
-
Logan
|
3049
|
-
Alexander
|
3050
|
-
Ethan
|
3051
|
-
Jacob
|
3052
|
-
Michael
|
3053
|
-
Daniel
|
3054
|
-
Henry
|
3055
|
-
Jackson
|
3056
|
-
Sebastian
|
3057
|
-
Aiden
|
3058
|
-
Matthew
|
3059
|
-
Samuel
|
3060
|
-
David
|
3061
|
-
Joseph
|
3062
|
-
Carter
|
3063
|
-
Owen
|
3064
|
-
Wyatt
|
3065
|
-
John
|
3066
|
-
Jack
|
3067
|
-
Luke
|
3068
|
-
Jayden
|
3069
|
-
Dylan
|
3070
|
-
Grayson
|
3071
|
-
Levi
|
3072
|
-
Isaac
|
3073
|
-
Gabriel
|
3074
|
-
Julian
|
3075
|
-
Mateo
|
3076
|
-
Anthony
|
3077
|
-
Jaxon
|
3078
|
-
Lincoln
|
3079
|
-
Joshua
|
3080
|
-
Christopher
|
3081
|
-
Andrew
|
3082
|
-
Theodore
|
3083
|
-
Caleb
|
3084
|
-
Ryan
|
3085
|
-
Asher
|
3086
|
-
Nathan
|
3087
|
-
Thomas
|
3088
|
-
Leo
|
3089
|
-
Isaiah
|
3090
|
-
Charles
|
3091
|
-
Josiah
|
3092
|
-
Hudson
|
3093
|
-
Christian
|
3094
|
-
Hunter
|
3095
|
-
Connor
|
3096
|
-
Eli
|
3097
|
-
Ezra
|
3098
|
-
Aaron
|
3099
|
-
Landon
|
3100
|
-
Adrian
|
3101
|
-
Jonathan
|
3102
|
-
Nolan
|
3103
|
-
Jeremiah
|
3104
|
-
Easton
|
3105
|
-
Elias
|
3106
|
-
Colton
|
3107
|
-
Cameron
|
3108
|
-
Carson
|
3109
|
-
Robert
|
3110
|
-
Angel
|
3111
|
-
Maverick
|
3112
|
-
Nicholas
|
3113
|
-
Dominic
|
3114
|
-
Jaxson
|
3115
|
-
Greyson
|
3116
|
-
Adam
|
3117
|
-
Ian
|
3118
|
-
Austin
|
3119
|
-
Santiago
|
3120
|
-
Jordan
|
3121
|
-
Cooper
|
3122
|
-
Brayden
|
3123
|
-
Roman
|
3124
|
-
Evan
|
3125
|
-
Ezekiel
|
3126
|
-
Xaviar
|
3127
|
-
Jose
|
3128
|
-
Jace
|
3129
|
-
Jameson
|
3130
|
-
Leonardo
|
3131
|
-
Axel
|
3132
|
-
Everett
|
3133
|
-
Kayden
|
3134
|
-
Miles
|
3135
|
-
Sawyer
|
3136
|
-
Jason
|
3137
|
-
Emma
|
3138
|
-
Olivia
|
3139
|
-
]
|
3140
|
-
NAMES_LAST = %w[
|
3141
|
-
Smith
|
3142
|
-
Johnson
|
3143
|
-
Williams
|
3144
|
-
Brown
|
3145
|
-
Jones
|
3146
|
-
Miller
|
3147
|
-
Davis
|
3148
|
-
Wilson
|
3149
|
-
Anderson
|
3150
|
-
Taylor
|
3151
|
-
]
|
3152
|
-
def initialize(contacts = nil)
|
3153
|
-
@contacts = contacts || 100.times.map do |n|
|
3154
|
-
random_first_name_index = (rand*NAMES_FIRST.size).to_i
|
3155
|
-
random_last_name_index = (rand*NAMES_LAST.size).to_i
|
3156
|
-
first_name = NAMES_FIRST[random_first_name_index]
|
3157
|
-
last_name = NAMES_LAST[random_last_name_index]
|
3158
|
-
email = "#{first_name}@#{last_name}.com".downcase
|
3159
|
-
Contact.new(
|
3160
|
-
first_name: first_name,
|
3161
|
-
last_name: last_name,
|
3162
|
-
email: email
|
3163
|
-
)
|
3164
|
-
end
|
3165
|
-
end
|
3166
|
-
|
3167
|
-
def find(attribute_filter_map)
|
3168
|
-
@contacts.find_all do |contact|
|
3169
|
-
match = true
|
3170
|
-
attribute_filter_map.keys.each do |attribute_name|
|
3171
|
-
contact_value = contact.send(attribute_name).downcase
|
3172
|
-
filter_value = attribute_filter_map[attribute_name].downcase
|
3173
|
-
match = false unless contact_value.match(filter_value)
|
3174
|
-
end
|
3175
|
-
match
|
3176
|
-
end
|
3177
|
-
end
|
3178
|
-
end
|
3179
|
-
end
|
3180
|
-
|
3181
|
-
class ContactManager
|
3182
|
-
class ContactManagerPresenter
|
3183
|
-
attr_accessor :results
|
3184
|
-
@@contact_attributes = [:first_name, :last_name, :email]
|
3185
|
-
@@contact_attributes.each {|attribute_name| attr_accessor attribute_name}
|
3186
|
-
|
3187
|
-
def initialize(contact_repository = nil)
|
3188
|
-
@contact_repository = contact_repository || ContactRepository.new
|
3189
|
-
@results = []
|
3190
|
-
end
|
3191
|
-
|
3192
|
-
def list
|
3193
|
-
self.results = @contact_repository.find({})
|
3194
|
-
end
|
3195
|
-
|
3196
|
-
def find
|
3197
|
-
filter_map = {}
|
3198
|
-
@@contact_attributes.each do |attribute_name|
|
3199
|
-
filter_map[attribute_name] = self.send(attribute_name) if self.send(attribute_name)
|
3200
|
-
end
|
3201
|
-
self.results = @contact_repository.find(filter_map)
|
3202
|
-
@sort_attribute_name = nil
|
3203
|
-
@sort_direction_ascending = nil
|
3204
|
-
end
|
3205
|
-
|
3206
|
-
def toggle_sort(attribute_name)
|
3207
|
-
@sort_attribute_name = attribute_name
|
3208
|
-
@sort_direction_ascending = !@sort_direction_ascending
|
3209
|
-
sorted_results = self.results.sort_by {|contact| contact.send(attribute_name).downcase}
|
3210
|
-
sorted_results = sorted_results.reverse unless @sort_direction_ascending
|
3211
|
-
self.results = sorted_results
|
3212
|
-
end
|
3213
|
-
end
|
3214
|
-
end
|
3215
|
-
|
3216
|
-
class ContactManager
|
3217
|
-
include Glimmer
|
3218
|
-
|
3219
|
-
def initialize
|
3220
|
-
@contact_manager_presenter = ContactManagerPresenter.new
|
3221
|
-
@contact_manager_presenter.list
|
3222
|
-
end
|
3223
|
-
|
3224
|
-
def launch
|
3225
|
-
shell {
|
3226
|
-
text "Contact Manager"
|
3227
|
-
composite {
|
3228
|
-
group {
|
3229
|
-
grid_layout(2, false) {
|
3230
|
-
margin_width 0
|
3231
|
-
margin_height 0
|
3232
|
-
}
|
3233
|
-
layout_data :fill, :center, true, false
|
3234
|
-
text 'Lookup Contacts'
|
3235
|
-
font height: 24
|
3236
|
-
|
3237
|
-
label {
|
3238
|
-
layout_data :right, :center, false, false
|
3239
|
-
text "First &Name: "
|
3240
|
-
font height: 16
|
3241
|
-
}
|
3242
|
-
text {
|
3243
|
-
layout_data :fill, :center, true, false
|
3244
|
-
text bind(@contact_manager_presenter, :first_name)
|
3245
|
-
on_key_pressed {|key_event|
|
3246
|
-
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
3247
|
-
}
|
3248
|
-
}
|
3249
|
-
|
3250
|
-
label {
|
3251
|
-
layout_data :right, :center, false, false
|
3252
|
-
text "&Last Name: "
|
3253
|
-
font height: 16
|
3254
|
-
}
|
3255
|
-
text {
|
3256
|
-
layout_data :fill, :center, true, false
|
3257
|
-
text bind(@contact_manager_presenter, :last_name)
|
3258
|
-
on_key_pressed {|key_event|
|
3259
|
-
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
3260
|
-
}
|
3261
|
-
}
|
3262
|
-
|
3263
|
-
label {
|
3264
|
-
layout_data :right, :center, false, false
|
3265
|
-
text "&Email: "
|
3266
|
-
font height: 16
|
3267
|
-
}
|
3268
|
-
text {
|
3269
|
-
layout_data :fill, :center, true, false
|
3270
|
-
text bind(@contact_manager_presenter, :email)
|
3271
|
-
on_key_pressed {|key_event|
|
3272
|
-
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
3273
|
-
}
|
3274
|
-
}
|
3275
|
-
|
3276
|
-
composite {
|
3277
|
-
row_layout {
|
3278
|
-
margin_width 0
|
3279
|
-
margin_height 0
|
3280
|
-
}
|
3281
|
-
layout_data(:right, :center, false, false) {
|
3282
|
-
horizontal_span 2
|
3283
|
-
}
|
3284
|
-
|
3285
|
-
button {
|
3286
|
-
text "&Find"
|
3287
|
-
on_widget_selected { @contact_manager_presenter.find }
|
3288
|
-
on_key_pressed {|key_event|
|
3289
|
-
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
3290
|
-
}
|
3291
|
-
}
|
3292
|
-
|
3293
|
-
button {
|
3294
|
-
text "&List All"
|
3295
|
-
on_widget_selected { @contact_manager_presenter.list }
|
3296
|
-
on_key_pressed {|key_event|
|
3297
|
-
@contact_manager_presenter.list if key_event.keyCode == swt(:cr)
|
3298
|
-
}
|
3299
|
-
}
|
3300
|
-
}
|
3301
|
-
}
|
3302
|
-
|
3303
|
-
table(:multi) { |table_proxy|
|
3304
|
-
layout_data {
|
3305
|
-
horizontal_alignment :fill
|
3306
|
-
vertical_alignment :fill
|
3307
|
-
grab_excess_horizontal_space true
|
3308
|
-
grab_excess_vertical_space true
|
3309
|
-
height_hint 200
|
3310
|
-
}
|
3311
|
-
table_column {
|
3312
|
-
text "First Name"
|
3313
|
-
width 80
|
3314
|
-
}
|
3315
|
-
table_column {
|
3316
|
-
text "Last Name"
|
3317
|
-
width 80
|
3318
|
-
}
|
3319
|
-
table_column {
|
3320
|
-
text "Email"
|
3321
|
-
width 200
|
3322
|
-
}
|
3323
|
-
items bind(@contact_manager_presenter, :results),
|
3324
|
-
column_properties(:first_name, :last_name, :email)
|
3325
|
-
on_mouse_up { |event|
|
3326
|
-
table_proxy.edit_table_item(event.table_item, event.column_index)
|
3327
|
-
}
|
3328
|
-
}
|
3329
|
-
}
|
3330
|
-
}.open
|
3331
|
-
end
|
3332
|
-
end
|
3333
|
-
|
3334
|
-
ContactManager.new.launch
|
3335
|
-
```
|
3336
2184
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
3337
2185
|
|
3338
2186
|
Glimmer DSL for SWT Contact Manager
|
@@ -3386,6 +2234,41 @@ Glimmer DSL for Opal Contact Manager Edit Done
|
|
3386
2234
|
|
3387
2235
|
![Glimmer DSL for Opal Contact Manager Edit Done](images/glimmer-dsl-opal-contact-manager-edit-done.png)
|
3388
2236
|
|
2237
|
+
#### Weather
|
2238
|
+
|
2239
|
+
Code: [lib/glimmer-dsl-opal/samples/elaborate/weather](lib/glimmer-dsl-opal/samples/elaborate/weather.rb)
|
2240
|
+
|
2241
|
+
Add the following require statement to `app/assets/javascripts/application.rb`
|
2242
|
+
|
2243
|
+
```ruby
|
2244
|
+
require 'glimmer-dsl-opal/samples/elaborate/weather'
|
2245
|
+
```
|
2246
|
+
|
2247
|
+
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
2248
|
+
|
2249
|
+
![Weather Montreal C](https://github.com/AMaleh/glimmer-dsl-swt/raw/master/images/glimmer-weather-montreal-celsius.png)
|
2250
|
+
|
2251
|
+
![Weather Montreal F](https://github.com/AMaleh/glimmer-dsl-swt/raw/master/images/glimmer-weather-montreal-fahrenheit.png)
|
2252
|
+
|
2253
|
+
![Weather Atlanta F](https://github.com/AMaleh/glimmer-dsl-swt/raw/master/images/glimmer-weather-atlanta-fahrenheit.png)
|
2254
|
+
|
2255
|
+
Glimmer app on the web (using `glimmer-dsl-opal` gem):
|
2256
|
+
|
2257
|
+
Start the Rails server:
|
2258
|
+
```
|
2259
|
+
rails s
|
2260
|
+
```
|
2261
|
+
|
2262
|
+
Visit `http://localhost:3000`
|
2263
|
+
|
2264
|
+
You should see "Weather"
|
2265
|
+
|
2266
|
+
![Opal Weather Montreal C](/images/glimmer-dsl-opal-weather-montreal-celsius.png)
|
2267
|
+
|
2268
|
+
![Opal Weather Montreal F](/images/glimmer-dsl-opal-weather-montreal-fahrenheit.png)
|
2269
|
+
|
2270
|
+
![Opal Weather Atlanta F](/images/glimmer-dsl-opal-weather-atlanta-fahrenheit.png)
|
2271
|
+
|
3389
2272
|
### External Samples
|
3390
2273
|
|
3391
2274
|
#### Glimmer Calculator
|