glimmer-dsl-opal 0.13.0 → 0.14.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 +6 -0
- data/README.md +188 -1309
- data/VERSION +1 -1
- data/lib/glimmer-dsl-opal.rb +1 -0
- 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_combo.rb +24 -22
- data/lib/glimmer-dsl-opal/samples/hello/hello_computed.rb +27 -9
- data/lib/net/http.rb +14 -6
- metadata +3 -3
- data/lib/glimmer-dsl-opal/samples/hello/hello_computed/contact.rb +0 -42
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '009ae1a27f92b9fe4ae8d28374761c84a8a46add536c37b49c67aba167a121b7'
|
4
|
+
data.tar.gz: baf143fe8365b8a3164eaf74adc4a3df720521557003d0507f09580f0da9b6b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81014168a1822232725770564b6f8a4522f08a4e93db72c4986966deaeac28eaffe7674f9446d7abf2d5a3a6056eec38a7f12508c72f751734bd8dc6356fdc2c
|
7
|
+
data.tar.gz: 800d13580d55f8c1255a68b7c07f6c4e7bdfb9308d3a41b14e44e94b50dd66056c9e437df38f73f2d04643633937cd0a99edba8a1ed174194cf8ce0be25328bf
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.14.0
|
4
|
+
|
5
|
+
- Initial Net::HTTP support for get and post_form
|
6
|
+
- Added "Weather" elaborate sample (minus multi-threaded refetches)
|
7
|
+
- Updated Hello, Button!, Hello, Combo!, and Hello, Computed! from Glimmer DSL for SWT
|
8
|
+
|
3
9
|
## 0.13.0
|
4
10
|
|
5
11
|
- Support Shine data-binding syntax in custom widgets
|
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.14.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,7 +8,7 @@
|
|
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
|
|
@@ -103,7 +103,7 @@ shell {
|
|
103
103
|
|
104
104
|
![Glimmer DSL for SWT Hello Table](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-table.png)
|
105
105
|
|
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):**
|
106
|
+
**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
107
|
|
108
108
|
![Glimmer DSL for Opal Hello Table](images/glimmer-dsl-opal-hello-table.png)
|
109
109
|
|
@@ -141,7 +141,7 @@ Hello, Table! Game Booked
|
|
141
141
|
|
142
142
|
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
143
|
|
144
|
-
**Alpha Version** 0.
|
144
|
+
**Alpha Version** 0.14.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
145
|
|
146
146
|
Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
|
147
147
|
- [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)
|
@@ -151,7 +151,7 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
|
|
151
151
|
|
152
152
|
## Table of Contents
|
153
153
|
|
154
|
-
- [Glimmer DSL for Opal 0.
|
154
|
+
- [Glimmer DSL for Opal 0.14.0 (Pure Ruby Web GUI)](#-glimmer-dsl-for-opal-0140-pure-ruby-web-gui)
|
155
155
|
- [Principles](#principles)
|
156
156
|
- [Background](#background)
|
157
157
|
- [Pre-requisites](#pre-requisites)
|
@@ -184,6 +184,7 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
|
|
184
184
|
- [Login](#login)
|
185
185
|
- [Tic Tac Toe](#tic-tac-toe)
|
186
186
|
- [Contact Manager](#contact-manager)
|
187
|
+
- [Weather](#weather)
|
187
188
|
- [External Samples](#external-samples)
|
188
189
|
- [Glimmer Calculator](#glimmer-calculator)
|
189
190
|
- [Glimmer Supporting Libraries](#glimmer-supporting-libraries)
|
@@ -205,7 +206,6 @@ Please keep in mind this is a live list of innovative ideas, some of which have
|
|
205
206
|
- **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
207
|
- **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
208
|
- **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
209
|
- **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
210
|
|
211
211
|
## Background
|
@@ -252,7 +252,7 @@ Add the following to `Gemfile`:
|
|
252
252
|
gem 'opal-rails', '~> 1.1.2'
|
253
253
|
gem 'opal-async', '~> 1.2.0'
|
254
254
|
gem 'opal-jquery', '~> 0.4.4'
|
255
|
-
gem 'glimmer-dsl-opal', '~> 0.
|
255
|
+
gem 'glimmer-dsl-opal', '~> 0.14.0'
|
256
256
|
gem 'glimmer-dsl-xml', '~> 1.2.0', require: false
|
257
257
|
gem 'glimmer-dsl-css', '~> 1.2.0', require: false
|
258
258
|
|
@@ -441,48 +441,50 @@ require 'glimmer-dsl-opal/samples/hello/hello_combo'
|
|
441
441
|
Or add the Glimmer code directly if you prefer to play around with it:
|
442
442
|
|
443
443
|
```ruby
|
444
|
-
class
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
444
|
+
class HelloCombo
|
445
|
+
class Person
|
446
|
+
attr_accessor :country, :country_options
|
447
|
+
|
448
|
+
def initialize
|
449
|
+
self.country_options = ['', 'Canada', 'US', 'Mexico']
|
450
|
+
reset_country!
|
451
|
+
end
|
452
|
+
|
453
|
+
def reset_country!
|
454
|
+
self.country = 'Canada'
|
455
|
+
end
|
454
456
|
end
|
455
|
-
end
|
456
457
|
|
457
|
-
|
458
|
-
include Glimmer
|
458
|
+
include Glimmer::UI::CustomShell
|
459
459
|
|
460
|
-
|
461
|
-
person = Person.new
|
462
|
-
|
460
|
+
before_body {
|
461
|
+
@person = Person.new
|
462
|
+
}
|
463
|
+
|
464
|
+
body {
|
463
465
|
shell {
|
464
466
|
row_layout(:vertical) {
|
465
|
-
|
467
|
+
fill true
|
466
468
|
}
|
467
469
|
|
468
470
|
text 'Hello, Combo!'
|
469
471
|
|
470
472
|
combo(:read_only) {
|
471
|
-
selection <=> [person, :country]
|
473
|
+
selection <=> [@person, :country] # also binds to country_options by convention
|
472
474
|
}
|
473
475
|
|
474
476
|
button {
|
475
477
|
text 'Reset Selection'
|
476
478
|
|
477
479
|
on_widget_selected do
|
478
|
-
person.reset_country
|
480
|
+
@person.reset_country!
|
479
481
|
end
|
480
482
|
}
|
481
|
-
}
|
482
|
-
|
483
|
+
}
|
484
|
+
}
|
483
485
|
end
|
484
486
|
|
485
|
-
HelloCombo.
|
487
|
+
HelloCombo.launch
|
486
488
|
```
|
487
489
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
488
490
|
|
@@ -534,17 +536,17 @@ class HelloComputed
|
|
534
536
|
end
|
535
537
|
end
|
536
538
|
|
537
|
-
include Glimmer
|
539
|
+
include Glimmer::UI::CustomShell
|
538
540
|
|
539
|
-
|
541
|
+
before_body {
|
540
542
|
@contact = Contact.new(
|
541
543
|
first_name: 'Barry',
|
542
544
|
last_name: 'McKibbin',
|
543
545
|
year_of_birth: 1985
|
544
546
|
)
|
545
|
-
|
547
|
+
}
|
546
548
|
|
547
|
-
|
549
|
+
body {
|
548
550
|
shell {
|
549
551
|
text 'Hello, Computed!'
|
550
552
|
|
@@ -601,11 +603,11 @@ class HelloComputed
|
|
601
603
|
}
|
602
604
|
}
|
603
605
|
}
|
604
|
-
}
|
605
|
-
|
606
|
+
}
|
607
|
+
}
|
606
608
|
end
|
607
609
|
|
608
|
-
HelloComputed.
|
610
|
+
HelloComputed.launch
|
609
611
|
```
|
610
612
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
611
613
|
|
@@ -633,44 +635,6 @@ Add the following require statement to `app/assets/javascripts/application.rb`
|
|
633
635
|
require 'glimmer-dsl-opal/samples/hello/hello_list_single_selection'
|
634
636
|
```
|
635
637
|
|
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
638
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
675
639
|
|
676
640
|
![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 +660,6 @@ Add the following require statement to `app/assets/javascripts/application.rb`
|
|
696
660
|
require 'glimmer-dsl-opal/samples/hello/hello_list_multi_selection'
|
697
661
|
```
|
698
662
|
|
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
663
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
757
664
|
|
758
665
|
![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 +685,6 @@ Add the following require statement to `app/assets/javascripts/application.rb`
|
|
778
685
|
require 'glimmer-dsl-opal/samples/hello/hello_browser'
|
779
686
|
```
|
780
687
|
|
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
688
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
794
689
|
|
795
690
|
![Glimmer DSL for SWT Hello Browser](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-browser.png)
|
@@ -894,7 +789,7 @@ class GreetingLabel
|
|
894
789
|
after_body {
|
895
790
|
return if colors.nil?
|
896
791
|
|
897
|
-
Thread.new {
|
792
|
+
Thread.new { # imported from Glimmer DSL for SWT. In Opal, avoid Threads and sleep to avoid blocking GUI.
|
898
793
|
colors.cycle { |color|
|
899
794
|
async_exec {
|
900
795
|
self.color = color
|
@@ -909,7 +804,7 @@ class GreetingLabel
|
|
909
804
|
label(swt_style) {
|
910
805
|
text "#{greeting}, #{name}!"
|
911
806
|
font @font
|
912
|
-
foreground
|
807
|
+
foreground <=> [self, :color]
|
913
808
|
}
|
914
809
|
}
|
915
810
|
|
@@ -1131,103 +1026,14 @@ You should see "Hello, Custom Widget!"
|
|
1131
1026
|
|
1132
1027
|
#### Hello, Radio!
|
1133
1028
|
|
1029
|
+
This is the low level way of using `radio`
|
1030
|
+
|
1134
1031
|
Add the following require statement to `app/assets/javascripts/application.rb`
|
1135
1032
|
|
1136
1033
|
```ruby
|
1137
1034
|
require 'glimmer-dsl-opal/samples/hello/hello_radio'
|
1138
1035
|
```
|
1139
1036
|
|
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
1037
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
1232
1038
|
|
1233
1039
|
![Glimmer DSL for SWT Hello Radio](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-radio.png)
|
@@ -1247,6 +1053,8 @@ You should see "Hello, Radio!"
|
|
1247
1053
|
|
1248
1054
|
#### Hello, Radio Group!
|
1249
1055
|
|
1056
|
+
`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.
|
1057
|
+
|
1250
1058
|
Add the following require statement to `app/assets/javascripts/application.rb`
|
1251
1059
|
|
1252
1060
|
```ruby
|
@@ -1261,7 +1069,7 @@ class HelloRadioGroup
|
|
1261
1069
|
attr_accessor :gender, :age_group
|
1262
1070
|
|
1263
1071
|
def initialize
|
1264
|
-
reset
|
1072
|
+
reset!
|
1265
1073
|
end
|
1266
1074
|
|
1267
1075
|
def gender_options
|
@@ -1272,17 +1080,19 @@ class HelloRadioGroup
|
|
1272
1080
|
['Child', 'Teen', 'Adult', 'Senior']
|
1273
1081
|
end
|
1274
1082
|
|
1275
|
-
def reset
|
1083
|
+
def reset!
|
1276
1084
|
self.gender = nil
|
1277
1085
|
self.age_group = 'Adult'
|
1278
1086
|
end
|
1279
1087
|
end
|
1280
1088
|
|
1281
|
-
include Glimmer
|
1089
|
+
include Glimmer::UI::CustomShell
|
1282
1090
|
|
1283
|
-
|
1284
|
-
person = Person.new
|
1285
|
-
|
1091
|
+
before_body {
|
1092
|
+
@person = Person.new
|
1093
|
+
}
|
1094
|
+
|
1095
|
+
body {
|
1286
1096
|
shell {
|
1287
1097
|
text 'Hello, Radio Group!'
|
1288
1098
|
row_layout :vertical
|
@@ -1294,7 +1104,7 @@ class HelloRadioGroup
|
|
1294
1104
|
|
1295
1105
|
radio_group {
|
1296
1106
|
row_layout :horizontal
|
1297
|
-
selection <=> [person, :gender]
|
1107
|
+
selection <=> [@person, :gender]
|
1298
1108
|
}
|
1299
1109
|
|
1300
1110
|
label {
|
@@ -1304,21 +1114,21 @@ class HelloRadioGroup
|
|
1304
1114
|
|
1305
1115
|
radio_group {
|
1306
1116
|
row_layout :horizontal
|
1307
|
-
selection <=> [person, :age_group]
|
1117
|
+
selection <=> [@person, :age_group]
|
1308
1118
|
}
|
1309
1119
|
|
1310
1120
|
button {
|
1311
1121
|
text 'Reset'
|
1312
1122
|
|
1313
1123
|
on_widget_selected do
|
1314
|
-
person.reset
|
1124
|
+
@person.reset!
|
1315
1125
|
end
|
1316
1126
|
}
|
1317
|
-
}
|
1318
|
-
|
1127
|
+
}
|
1128
|
+
}
|
1319
1129
|
end
|
1320
1130
|
|
1321
|
-
HelloRadioGroup.
|
1131
|
+
HelloRadioGroup.launch
|
1322
1132
|
```
|
1323
1133
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
1324
1134
|
|
@@ -1339,99 +1149,14 @@ You should see "Hello, Radio Group!"
|
|
1339
1149
|
|
1340
1150
|
#### Hello, Group!
|
1341
1151
|
|
1152
|
+
Not to be confused with `radio_group` or `checkbox_group`, `group` simply groups arbitrary widgets together and adds a title header above them.
|
1153
|
+
|
1342
1154
|
Add the following require statement to `app/assets/javascripts/application.rb`
|
1343
1155
|
|
1344
1156
|
```ruby
|
1345
1157
|
require 'glimmer-dsl-opal/samples/hello/hello_group'
|
1346
1158
|
```
|
1347
1159
|
|
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 <=> [person, :male]
|
1387
|
-
}
|
1388
|
-
|
1389
|
-
radio {
|
1390
|
-
text 'Female'
|
1391
|
-
selection <=> [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
1160
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
1436
1161
|
|
1437
1162
|
![Glimmer DSL for SWT Hello Group](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-group.png)
|
@@ -1451,80 +1176,14 @@ You should see "Hello, Group!"
|
|
1451
1176
|
|
1452
1177
|
#### Hello, Checkbox!
|
1453
1178
|
|
1179
|
+
This is the low level way of using `checkbox`
|
1180
|
+
|
1454
1181
|
Add the following require statement to `app/assets/javascripts/application.rb`
|
1455
1182
|
|
1456
1183
|
```ruby
|
1457
1184
|
require 'glimmer-dsl-opal/samples/hello/hello_checkbox'
|
1458
1185
|
```
|
1459
1186
|
|
1460
|
-
Or add the Glimmer code directly if you prefer to play around with it:
|
1461
|
-
|
1462
|
-
```ruby
|
1463
|
-
class HelloCheckbox
|
1464
|
-
class Person
|
1465
|
-
attr_accessor :skiing, :snowboarding, :snowmobiling, :snowshoeing
|
1466
|
-
|
1467
|
-
def initialize
|
1468
|
-
reset_activities
|
1469
|
-
end
|
1470
|
-
|
1471
|
-
def reset_activities
|
1472
|
-
self.skiing = false
|
1473
|
-
self.snowboarding = true
|
1474
|
-
self.snowmobiling = false
|
1475
|
-
self.snowshoeing = false
|
1476
|
-
end
|
1477
|
-
end
|
1478
|
-
|
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
1187
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
1529
1188
|
|
1530
1189
|
![Glimmer DSL for SWT Hello Checkbox](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-checkbox.png)
|
@@ -1544,6 +1203,8 @@ You should see "Hello, Checkbox!"
|
|
1544
1203
|
|
1545
1204
|
#### Hello, Checkbox Group!
|
1546
1205
|
|
1206
|
+
`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.
|
1207
|
+
|
1547
1208
|
Add the following require statement to `app/assets/javascripts/application.rb`
|
1548
1209
|
|
1549
1210
|
```ruby
|
@@ -1570,11 +1231,13 @@ class HelloCheckboxGroup
|
|
1570
1231
|
end
|
1571
1232
|
end
|
1572
1233
|
|
1573
|
-
include Glimmer
|
1234
|
+
include Glimmer::UI::CustomShell
|
1574
1235
|
|
1575
|
-
|
1576
|
-
person = Person.new
|
1577
|
-
|
1236
|
+
before_body {
|
1237
|
+
@person = Person.new
|
1238
|
+
}
|
1239
|
+
|
1240
|
+
body {
|
1578
1241
|
shell {
|
1579
1242
|
text 'Hello, Checkbox Group!'
|
1580
1243
|
row_layout :vertical
|
@@ -1585,21 +1248,21 @@ class HelloCheckboxGroup
|
|
1585
1248
|
}
|
1586
1249
|
|
1587
1250
|
checkbox_group {
|
1588
|
-
selection <=> [person, :activities]
|
1251
|
+
selection <=> [@person, :activities]
|
1589
1252
|
}
|
1590
1253
|
|
1591
1254
|
button {
|
1592
1255
|
text 'Reset Activities'
|
1593
1256
|
|
1594
1257
|
on_widget_selected do
|
1595
|
-
person.reset_activities
|
1258
|
+
@person.reset_activities
|
1596
1259
|
end
|
1597
1260
|
}
|
1598
|
-
}
|
1599
|
-
|
1261
|
+
}
|
1262
|
+
}
|
1600
1263
|
end
|
1601
1264
|
|
1602
|
-
HelloCheckboxGroup.
|
1265
|
+
HelloCheckboxGroup.launch
|
1603
1266
|
```
|
1604
1267
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
1605
1268
|
|
@@ -1607,354 +1270,50 @@ Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObt
|
|
1607
1270
|
|
1608
1271
|
Glimmer app on the web (using `glimmer-dsl-opal` gem):
|
1609
1272
|
|
1610
|
-
Start the Rails server:
|
1611
|
-
```
|
1612
|
-
rails s
|
1613
|
-
```
|
1614
|
-
|
1615
|
-
Visit `http://localhost:3000`
|
1616
|
-
|
1617
|
-
You should see "Hello, Checkbox Group!"
|
1618
|
-
|
1619
|
-
![Glimmer DSL for Opal Hello Checkbox Group](images/glimmer-dsl-opal-hello-checkbox-group.png)
|
1620
|
-
|
1621
|
-
#### Hello, Date Time!
|
1622
|
-
|
1623
|
-
Add the following require statement to `app/assets/javascripts/application.rb`
|
1624
|
-
|
1625
|
-
```ruby
|
1626
|
-
require 'glimmer-dsl-opal/samples/hello/hello_date_time'
|
1627
|
-
```
|
1628
|
-
|
1629
|
-
|
1630
|
-
|
1631
|
-
|
1632
|
-
|
1633
|
-
|
1634
|
-
|
1635
|
-
|
1636
|
-
|
1637
|
-
|
1638
|
-
|
1639
|
-
|
1640
|
-
|
1641
|
-
|
1642
|
-
|
1643
|
-
|
1644
|
-
|
1645
|
-
|
1646
|
-
|
1647
|
-
|
1648
|
-
|
1649
|
-
|
1650
|
-
|
1651
|
-
|
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
|
-
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
1677
|
-
|
1678
|
-
![Glimmer DSL for SWT Hello Checkbox Group](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-date-time.png)
|
1679
|
-
|
1680
|
-
Glimmer app on the web (using `glimmer-dsl-opal` gem):
|
1681
|
-
|
1682
|
-
Start the Rails server:
|
1683
|
-
```
|
1684
|
-
rails s
|
1685
|
-
```
|
1686
|
-
|
1687
|
-
Visit `http://localhost:3000`
|
1688
|
-
|
1689
|
-
You should see "Hello, Date Time!"
|
1690
|
-
|
1691
|
-
![Glimmer DSL for Opal Hello Date Time](images/glimmer-dsl-opal-hello-date-time.png)
|
1692
|
-
|
1693
|
-
#### Hello, Table!
|
1694
|
-
|
1695
|
-
Note: This [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) sample has near-complete support, but is missing table context menus at the moment.
|
1696
|
-
|
1697
|
-
Add the following require statement to `app/assets/javascripts/application.rb`
|
1698
|
-
|
1699
|
-
```ruby
|
1700
|
-
require 'glimmer-dsl-opal/samples/hello/hello_table'
|
1701
|
-
```
|
1702
|
-
|
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
|
1273
|
+
Start the Rails server:
|
1274
|
+
```
|
1275
|
+
rails s
|
1276
|
+
```
|
1277
|
+
|
1278
|
+
Visit `http://localhost:3000`
|
1279
|
+
|
1280
|
+
You should see "Hello, Checkbox Group!"
|
1281
|
+
|
1282
|
+
![Glimmer DSL for Opal Hello Checkbox Group](images/glimmer-dsl-opal-hello-checkbox-group.png)
|
1283
|
+
|
1284
|
+
#### Hello, Date Time!
|
1285
|
+
|
1286
|
+
Add the following require statement to `app/assets/javascripts/application.rb`
|
1287
|
+
|
1288
|
+
```ruby
|
1289
|
+
require 'glimmer-dsl-opal/samples/hello/hello_date_time'
|
1290
|
+
```
|
1291
|
+
|
1292
|
+
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
1293
|
+
|
1294
|
+
![Glimmer DSL for SWT Hello Checkbox Group](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-date-time.png)
|
1295
|
+
|
1296
|
+
Glimmer app on the web (using `glimmer-dsl-opal` gem):
|
1297
|
+
|
1298
|
+
Start the Rails server:
|
1299
|
+
```
|
1300
|
+
rails s
|
1301
|
+
```
|
1302
|
+
|
1303
|
+
Visit `http://localhost:3000`
|
1304
|
+
|
1305
|
+
You should see "Hello, Date Time!"
|
1306
|
+
|
1307
|
+
![Glimmer DSL for Opal Hello Date Time](images/glimmer-dsl-opal-hello-date-time.png)
|
1308
|
+
|
1309
|
+
#### Hello, Table!
|
1310
|
+
|
1311
|
+
Note: This [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) sample has near-complete support, but is missing table context menus at the moment.
|
1312
|
+
|
1313
|
+
Add the following require statement to `app/assets/javascripts/application.rb`
|
1314
|
+
|
1315
|
+
```ruby
|
1316
|
+
require 'glimmer-dsl-opal/samples/hello/hello_table'
|
1958
1317
|
```
|
1959
1318
|
|
1960
1319
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
@@ -2051,30 +1410,30 @@ Or add the Glimmer code directly if you prefer to play around with it:
|
|
2051
1410
|
|
2052
1411
|
```ruby
|
2053
1412
|
class HelloButton
|
2054
|
-
include Glimmer
|
1413
|
+
include Glimmer::UI::CustomShell
|
2055
1414
|
|
2056
1415
|
attr_accessor :count
|
2057
1416
|
|
2058
|
-
|
1417
|
+
before_body {
|
2059
1418
|
@count = 0
|
2060
|
-
|
1419
|
+
}
|
2061
1420
|
|
2062
|
-
|
1421
|
+
body {
|
2063
1422
|
shell {
|
2064
1423
|
text 'Hello, Button!'
|
2065
1424
|
|
2066
1425
|
button {
|
2067
|
-
text
|
1426
|
+
text <= [self, :count, on_read: ->(value) { "Click To Increment: #{value} " }]
|
2068
1427
|
|
2069
1428
|
on_widget_selected {
|
2070
1429
|
self.count += 1
|
2071
1430
|
}
|
2072
1431
|
}
|
2073
|
-
}
|
2074
|
-
|
1432
|
+
}
|
1433
|
+
}
|
2075
1434
|
end
|
2076
1435
|
|
2077
|
-
HelloButton.
|
1436
|
+
HelloButton.launch
|
2078
1437
|
```
|
2079
1438
|
|
2080
1439
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
@@ -2694,19 +2053,24 @@ class LoginPresenter
|
|
2694
2053
|
end
|
2695
2054
|
|
2696
2055
|
class Login
|
2697
|
-
include Glimmer
|
2056
|
+
include Glimmer::UI::CustomShell
|
2057
|
+
|
2058
|
+
before_body {
|
2059
|
+
@presenter = LoginPresenter.new
|
2060
|
+
}
|
2698
2061
|
|
2699
|
-
|
2700
|
-
|
2701
|
-
@shell = shell {
|
2062
|
+
body {
|
2063
|
+
shell {
|
2702
2064
|
text "Login"
|
2065
|
+
|
2703
2066
|
composite {
|
2704
2067
|
grid_layout 2, false #two columns with differing widths
|
2705
2068
|
|
2706
2069
|
label { text "Username:" } # goes in column 1
|
2707
2070
|
@user_name_text = text { # goes in column 2
|
2708
|
-
text
|
2709
|
-
enabled
|
2071
|
+
text <=> [@presenter, :user_name]
|
2072
|
+
enabled <= [@presenter, :logged_out?, computed_by: :status]
|
2073
|
+
|
2710
2074
|
on_key_pressed { |event|
|
2711
2075
|
@password_text.set_focus if event.keyCode == swt(:cr)
|
2712
2076
|
}
|
@@ -2714,43 +2078,47 @@ class Login
|
|
2714
2078
|
|
2715
2079
|
label { text "Password:" }
|
2716
2080
|
@password_text = text(:password, :border) {
|
2717
|
-
text
|
2718
|
-
enabled
|
2081
|
+
text <=> [@presenter, :password]
|
2082
|
+
enabled <= [@presenter, :logged_out?, computed_by: :status]
|
2083
|
+
|
2719
2084
|
on_key_pressed { |event|
|
2720
|
-
presenter.login if event.keyCode == swt(:cr)
|
2085
|
+
@presenter.login! if event.keyCode == swt(:cr)
|
2721
2086
|
}
|
2722
2087
|
}
|
2723
2088
|
|
2724
2089
|
label { text "Status:" }
|
2725
|
-
label { text
|
2090
|
+
label { text <= [@presenter, :status] }
|
2726
2091
|
|
2727
2092
|
button {
|
2728
2093
|
text "Login"
|
2729
|
-
enabled
|
2730
|
-
|
2094
|
+
enabled <= [@presenter, :logged_out?, computed_by: :status]
|
2095
|
+
|
2096
|
+
on_widget_selected { @presenter.login! }
|
2731
2097
|
on_key_pressed { |event|
|
2732
|
-
|
2098
|
+
if event.keyCode == swt(:cr)
|
2099
|
+
@presenter.login!
|
2100
|
+
end
|
2733
2101
|
}
|
2734
2102
|
}
|
2735
2103
|
|
2736
2104
|
button {
|
2737
2105
|
text "Logout"
|
2738
|
-
enabled
|
2739
|
-
|
2106
|
+
enabled <= [@presenter, :logged_in?, computed_by: :status]
|
2107
|
+
|
2108
|
+
on_widget_selected { @presenter.logout! }
|
2740
2109
|
on_key_pressed { |event|
|
2741
2110
|
if event.keyCode == swt(:cr)
|
2742
|
-
presenter.logout
|
2111
|
+
@presenter.logout!
|
2743
2112
|
@user_name_text.set_focus
|
2744
2113
|
end
|
2745
2114
|
}
|
2746
2115
|
}
|
2747
2116
|
}
|
2748
2117
|
}
|
2749
|
-
|
2750
|
-
end
|
2118
|
+
}
|
2751
2119
|
end
|
2752
2120
|
|
2753
|
-
Login.
|
2121
|
+
Login.launch
|
2754
2122
|
```
|
2755
2123
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
2756
2124
|
|
@@ -2781,214 +2149,7 @@ Add the following require statement to `app/assets/javascripts/application.rb`
|
|
2781
2149
|
require 'glimmer-dsl-opal/samples/elaborate/tic_tac_toe'
|
2782
2150
|
```
|
2783
2151
|
|
2784
|
-
Or add the Glimmer code directly if you prefer to play around with it:
|
2785
|
-
|
2786
2152
|
```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
2153
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
2993
2154
|
|
2994
2155
|
![Glimmer DSL for SWT Tic Tac Toe](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-tic-tac-toe.png)
|
@@ -3018,321 +2179,6 @@ Add the following require statement to `app/assets/javascripts/application.rb`
|
|
3018
2179
|
require 'glimmer-dsl-opal/samples/elaborate/contact_manager'
|
3019
2180
|
```
|
3020
2181
|
|
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
2182
|
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
3337
2183
|
|
3338
2184
|
Glimmer DSL for SWT Contact Manager
|
@@ -3386,6 +2232,39 @@ Glimmer DSL for Opal Contact Manager Edit Done
|
|
3386
2232
|
|
3387
2233
|
![Glimmer DSL for Opal Contact Manager Edit Done](images/glimmer-dsl-opal-contact-manager-edit-done.png)
|
3388
2234
|
|
2235
|
+
#### Weather
|
2236
|
+
|
2237
|
+
Add the following require statement to `app/assets/javascripts/application.rb`
|
2238
|
+
|
2239
|
+
```ruby
|
2240
|
+
require 'glimmer-dsl-opal/samples/elaborate/weather'
|
2241
|
+
```
|
2242
|
+
|
2243
|
+
Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
|
2244
|
+
|
2245
|
+
![Weather Montreal C](https://github.com/AMaleh/glimmer-dsl-swt/raw/master/images/glimmer-weather-montreal-celsius.png)
|
2246
|
+
|
2247
|
+
![Weather Montreal F](https://github.com/AMaleh/glimmer-dsl-swt/raw/master/images/glimmer-weather-montreal-fahrenheit.png)
|
2248
|
+
|
2249
|
+
![Weather Atlanta F](https://github.com/AMaleh /glimmer-dsl-swt/raw/master/images/glimmer-weather-atlanta-fahrenheit.png)
|
2250
|
+
|
2251
|
+
Glimmer app on the web (using `glimmer-dsl-opal` gem):
|
2252
|
+
|
2253
|
+
Start the Rails server:
|
2254
|
+
```
|
2255
|
+
rails s
|
2256
|
+
```
|
2257
|
+
|
2258
|
+
Visit `http://localhost:3000`
|
2259
|
+
|
2260
|
+
You should see "Weather"
|
2261
|
+
|
2262
|
+
![Opal Weather Montreal C](/images/glimmer-dsl-opal-weather-montreal-celsius.png)
|
2263
|
+
|
2264
|
+
![Opal Weather Montreal F](/images/glimmer-dsl-opal-weather-montreal-fahrenheit.png)
|
2265
|
+
|
2266
|
+
![Opal Weather Atlanta F](/images/glimmer-dsl-opal-weather-atlanta-fahrenheit.png)
|
2267
|
+
|
3389
2268
|
### External Samples
|
3390
2269
|
|
3391
2270
|
#### Glimmer Calculator
|