glimmer-dsl-opal 0.6.1 → 0.7.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +54 -0
  3. data/README.md +489 -16
  4. data/VERSION +1 -1
  5. data/lib/display.rb +31 -0
  6. data/lib/file.rb +29 -0
  7. data/lib/glimmer-dsl-opal.rb +31 -3
  8. data/lib/glimmer-dsl-opal/ext/date.rb +11 -0
  9. data/lib/glimmer-dsl-opal/ext/struct.rb +37 -0
  10. data/lib/glimmer-dsl-opal/samples/hello/hello_browser.rb +1 -1
  11. data/lib/glimmer-dsl-opal/samples/hello/hello_button.rb +46 -0
  12. data/lib/glimmer-dsl-opal/samples/hello/hello_custom_shell.rb +7 -7
  13. data/lib/glimmer-dsl-opal/samples/hello/hello_table.rb +283 -0
  14. data/lib/glimmer-dsl-swt.rb +20 -35
  15. data/lib/glimmer/data_binding/table_items_binding.rb +32 -19
  16. data/lib/glimmer/dsl/opal/block_property_expression.rb +41 -0
  17. data/lib/glimmer/dsl/opal/custom_widget_expression.rb +5 -0
  18. data/lib/glimmer/dsl/opal/dsl.rb +2 -0
  19. data/lib/glimmer/dsl/opal/widget_expression.rb +6 -2
  20. data/lib/glimmer/swt/combo_proxy.rb +40 -1
  21. data/lib/glimmer/swt/composite_proxy.rb +5 -1
  22. data/lib/glimmer/swt/control_editor.rb +54 -0
  23. data/lib/glimmer/swt/date_time_proxy.rb +66 -1
  24. data/lib/glimmer/swt/display_proxy.rb +4 -0
  25. data/lib/glimmer/swt/font_proxy.rb +4 -4
  26. data/lib/glimmer/swt/grid_layout_proxy.rb +7 -8
  27. data/lib/glimmer/swt/label_proxy.rb +11 -3
  28. data/lib/glimmer/swt/layout_data_proxy.rb +9 -3
  29. data/lib/glimmer/swt/layout_proxy.rb +1 -1
  30. data/lib/glimmer/swt/message_box_proxy.rb +3 -10
  31. data/lib/glimmer/swt/property_owner.rb +2 -2
  32. data/lib/glimmer/swt/shell_proxy.rb +8 -0
  33. data/lib/glimmer/swt/table_column_proxy.rb +71 -12
  34. data/lib/glimmer/swt/table_editor.rb +65 -0
  35. data/lib/glimmer/swt/table_item_proxy.rb +44 -1
  36. data/lib/glimmer/swt/table_proxy.rb +579 -12
  37. data/lib/glimmer/swt/text_proxy.rb +49 -1
  38. data/lib/glimmer/swt/widget_proxy.rb +106 -17
  39. data/lib/glimmer/ui/custom_shell.rb +9 -7
  40. data/lib/net/http.rb +1 -5
  41. data/lib/os.rb +36 -0
  42. data/lib/uri.rb +3 -3
  43. metadata +31 -9
  44. data/lib/glimmer/data_binding/ext/observable_model.rb +0 -40
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2989fcd48ddac2b782271cebca14b5a7615926251c14f2aef3fe878d177f7e41
4
- data.tar.gz: 7001fa83285f8e16bf5ba5a86004963324f271a5a795c6c45b0aa71c5fd53a3c
3
+ metadata.gz: b7eae61c6229ea57329b4ef092da209e5fb6df422c81250cb23e9b5a389a8e48
4
+ data.tar.gz: a88dc02904e056011e050f552735227a5dd9ebf2232875f934f39da7f0b117d6
5
5
  SHA512:
6
- metadata.gz: e24b36f65ca89e2e4880b81ae6ac6fba81c4a1ae2c832a87e43a6401ee6f90b2014a223cac2c218374dc895cfece65c5c145ed9a637256310f1b3a7fac9e3e2b
7
- data.tar.gz: d0f249102835911d3eb48f15ac87303376c935b54f17dd4f94ff5ab4db0d8ac6f780ea49ed8cd3c98e52d11c5dbad6975f34635f33f9064f26adca1dee47166e
6
+ metadata.gz: b7d86f37ff864394d31403aa99c4af80248e389dbbe894cf5dd615c3bae6b0b8c21e6191e7d75bc3a753c8227db1cf730ccc14feaae42395c89a62af15ee573e
7
+ data.tar.gz: 5b0c73b30a581c883a45c832817eed87e9260cb236056718083a42d67f0c93af397d58e052e231503d59f2e8ada03287cde0b5c89bf35729be5889924b7ed2fb
@@ -1,5 +1,58 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.7.4
4
+
5
+ - Hello, Button! Sample
6
+ - Fix issue with aligning label as :left, :center, or :right via style style when fill_layout is used
7
+ - Fix Hello, Browser sample by accessing https ssl website
8
+ - Fix issue with filling space horizontally when using grid layout
9
+ - Fix broken embedded `calendar` widget data-binding for hello_date_time.rb sample
10
+ - Fix broken message_box after opening multiple shells
11
+ - Fix issue with opening custom shells in new tabs/windows when CustomShell subclass is required conditionally
12
+
13
+ ## 0.7.3
14
+
15
+ - Refactor to use to_collection gem
16
+ - Fix issue with breaking `date`/`date_drop_down` data-binding as table editor on focus lost
17
+ - Fix issue with requiring OS, File, and Display class after they've been extracted out
18
+
19
+ ## 0.7.2
20
+
21
+ - `date_drop_down` `table_column` `editor`
22
+ - `date` `table_column` `editor`
23
+ - `time` `table_column` `editor`
24
+ - Implement `on_focus_gained`, `on_focus_lost` universally on all widgets
25
+ - Add support for Struct keyword_init to Opal
26
+ - Fix issue with hello_table button/combo not being centered (yet stretched)
27
+ - Fix issue with table item selection for booking not working after editing has been added
28
+ - Fix escape keyboard event handling for combo table editor
29
+
30
+ ## 0.7.1
31
+
32
+ - Combo table editor (enabled in Hello, Table! sample)
33
+ - Fix issue with table cell selection for editing not working
34
+ - Remove widget from parent upon dispose
35
+ - Remove listeners upon widget dispose
36
+
37
+ ## 0.7.0
38
+
39
+ - Hello, Table! Sample
40
+ - `table` :editable style to enable auto-editing
41
+ - `table` `header_visible` property to hide header when false
42
+ - `table` `item_count` property to set minimum item count (fill empty rows when below in table items)
43
+ - `table` selection data-binding
44
+ - `table` built-in sorting support
45
+ - `table_column` left text alignment and padding of 5px by default
46
+ - `table` sort property and direction in GUI
47
+ - `table_column` sort_property
48
+ - `table_column` sort_by block
49
+ - `table_column` sort block
50
+ - `table` default sort via property, compare block, and property block
51
+ - `table` additional sort properties
52
+ - Prevent `table` unnecessary updates by comparing data to previous data and not updating when it's the same
53
+ - Contact Manager sample support for on_key_pressed in text widgets upon hitting ENTER
54
+ - Fix issue with edit table item error on sorting table
55
+
3
56
  ## 0.6.1
4
57
 
5
58
  - Fix issue with rendering date_time without a block
@@ -108,3 +161,4 @@
108
161
 
109
162
  - Initial support for webifying Glimmer SWT apps
110
163
  - Support for Shell and Label widgets (text property only).
164
+ - Hello, World! sample support
data/README.md CHANGED
@@ -1,14 +1,64 @@
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 (Auto-Webify Desktop Apps)
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.7.4 (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
 
5
5
  ### You can finally live in pure Ruby land on the web!
6
6
 
7
- [Glimmer](https://github.com/AndyObtiva/glimmer) DSL for [Opal](https://opalrb.com/) is an experimental proof-of-concept web GUI adapter for [Glimmer](https://github.com/AndyObtiva/glimmer) desktop apps (i.e. apps built with [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt)). It webifies them via [Rails](https://rubyonrails.org/), allowing Ruby desktop apps to run on the web via [Opal Ruby](https://opalrb.com/) without changing a line of code. Apps may then be custom-styled by web designers for the web with standard CSS.
7
+ [Glimmer](https://github.com/AndyObtiva/glimmer) DSL for [Opal](https://opalrb.com/) is an **alpha** [gem](https://rubygems.org/gems/glimmer-dsl-opal) that enables building web GUI in pure Ruby via [Opal](https://opalrb.com/) on [Rails](https://rubyonrails.org/).
8
+
9
+ Use in one of two ways:
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.
8
12
 
9
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 powerful Glimmer desktop [data-binding](https://github.com/AndyObtiva/glimmer#data-binding) capabilities for the web.
10
14
 
11
- NOTE: Alpha Version 0.6.1 only supports bare-minimum capabilities for the following [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) [samples](https://github.com/AndyObtiva/glimmer#samples):
15
+ #### Tic Tac Toe Sample
16
+
17
+ Add the following require statement to `app/assets/javascripts/application.rb` in a [Glimmer setup](#setup) Rails app:
18
+
19
+ ```ruby
20
+ require 'glimmer-dsl-opal/samples/elaborate/tic_tac_toe'
21
+ ```
22
+
23
+ Glimmer GUI code from [glimmer-dsl-opal/samples/elaborate/tic_tac_toe.rb](lib/glimmer-dsl-opal/samples/elaborate/tic_tac_toe.rb):
24
+
25
+ ```ruby
26
+ # ...
27
+ @shell = shell {
28
+ text "Tic-Tac-Toe"
29
+ minimum_size 150, 178
30
+ composite {
31
+ grid_layout 3, true
32
+ (1..3).each { |row|
33
+ (1..3).each { |column|
34
+ button {
35
+ layout_data :fill, :fill, true, true
36
+ text bind(@tic_tac_toe_board[row, column], :sign)
37
+ enabled bind(@tic_tac_toe_board[row, column], :empty)
38
+ font style: :bold, height: 20
39
+ on_widget_selected {
40
+ @tic_tac_toe_board.mark(row, column)
41
+ }
42
+ }
43
+ }
44
+ }
45
+ }
46
+ }
47
+ # ...
48
+ ```
49
+ Tic Tac Toe on the web (using the [glimmer-dsl-opal](https://rubygems.org/gems/glimmer-dsl-opal) gem):
50
+
51
+ ![Glimmer DSL for Opal Tic Tac Toe](images/glimmer-dsl-opal-tic-tac-toe.png)
52
+ ![Glimmer DSL for Opal Tic Tac Toe In Progress](images/glimmer-dsl-opal-tic-tac-toe-in-progress.png)
53
+ ![Glimmer DSL for Opal Tic Tac Toe Game Over](images/glimmer-dsl-opal-tic-tac-toe-game-over.png)
54
+
55
+ Tic Tac Toe on the desktop with the same exact code (using the [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
56
+
57
+ ![Glimmer DSL for SWT Tic Tac Toe](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-tic-tac-toe.png)
58
+ ![Glimmer DSL for SWT Tic Tac Toe In Progress](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-tic-tac-toe-in-progress.png)
59
+ ![Glimmer DSL for SWT Tic Tac Toe Game Over](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-tic-tac-toe-game-over.png)
60
+
61
+ NOTE: **Alpha Version** 0.7.4 only supports bare-minimum capabilities for the following [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) [samples](https://github.com/AndyObtiva/glimmer#samples):
12
62
 
13
63
  Hello:
14
64
 
@@ -27,6 +77,8 @@ Hello:
27
77
  - [Hello, Checkbox!](#hello-checkbox)
28
78
  - [Hello, Checkbox Group!](#hello-checkbox-group)
29
79
  - [Hello, Date Time!](#hello-date-time)
80
+ - [Hello, Table!](#hello-table)
81
+ - [Hello, Button!](#hello-button)
30
82
 
31
83
  Elaborate:
32
84
 
@@ -44,14 +96,6 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
44
96
  - [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
45
97
  - [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS (Cascading Style Sheets)
46
98
 
47
- ## Background
48
-
49
- The idea behind Glimmer DSL for Opal is that you start by having a [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) desktop app that communicates with a Rails API for any web/cloud concerns. The GUI DSL is very simple in Glimmer DSL for SWT. Once the app is built. You simply embed it in a Rails app as a one line require statement after adding the Glimmer DSL for Opal gem, and BOOM, it just works on the web inside a web browser with the same server/client communication you had in the desktop app (I am working on adding minimal support for net/http in Opal so that desktop apps that use it continue to work in a web browser).
50
-
51
- Part of the idea is that web browsers just render GUI widgets similar to those of a desktop app (after all a web browser is a desktop app), so whether you run your GUI on the desktop or on the web should just be a low-level concern, hopefully automated completely with Glimmer DSL for Opal.
52
-
53
- Last but not least, you would likely want some special branding on the web, so you can push that off to a web designer who would be more than happy to do the web graphic design and customize the look and feel with pure CSS (no need for programming with Ruby or JavaScript). This enables a clean separation of concerns and distribution of tasks among developers and designers, let alone saving effort on the web GUI by reusing the desktop GUI as a base right off the bat.
54
-
55
99
  ## Supported Glimmer DSL Keywords
56
100
 
57
101
  The following keywords from [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) have partial support in Opal:
@@ -92,6 +136,22 @@ Event loop:
92
136
  - `display`
93
137
  - `async_exec`
94
138
 
139
+ ## Background
140
+
141
+ The original idea behind Glimmer DSL for Opal was that you start by having a [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) desktop app that communicates with a Rails API for any web/cloud concerns. The pure Ruby [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) is very simple, so it is more productive to build GUI in it since it does not go through a server/client request/response cycle and can be iterated on locally with a much shorter feedback cycle. Once the GUI and the rest of the app is built. You simply embed it in a Rails app as a one line require statement after adding the Glimmer DSL for Opal gem, and BOOM, it just works on the web inside a web browser with the same server/client communication you had in the desktop app (I am working on adding minimal support for net/http in Opal so that desktop apps that use it continue to work in a web browser. Until then, just use [Opal-jQuery](https://github.com/opal/opal-jquery) http support). That way, you get two apps for one: desktop and web.
142
+
143
+ Part of the idea is that web browsers just render GUI widgets similar to those of a desktop app (after all a web browser is a desktop app), so whether you run your GUI on the desktop or on the web should just be a low-level concern, hopefully automated completely with Glimmer DSL for Opal.
144
+
145
+ Last but not least, you would likely want some special branding on the web, so you can push that off to a web designer who would be more than happy to do the web graphic design and customize the look and feel with pure CSS (no need for programming with Ruby or JavaScript). This enables a clean separation of concerns and distribution of tasks among developers and designers, let alone saving effort on the web GUI by reusing the desktop GUI as a base right off the bat.
146
+
147
+ Alternatively, web developers may directly use [Glimmer DSL for Opal](https://rubygems.org/gems/glimmer-dsl-opal) to build the GUI of web apps since it is as simple as desktop development, thus requiring a lot less code that is in pure Ruby only (as demonstrated in examples below) and avoiding opaque web concepts like 'render' and 'reactive' due to treating GUI as persistent just like desktop apps do. No HTML/JS/CSS skills are even required. Still, web designers may be involved with CSS only if needed, thanks to the clean semantic markup [Glimmer DSL for Opal](https://rubygems.org/gems/glimmer-dsl-opal) automatically produces.
148
+
149
+ ## Principles
150
+
151
+ - Live purely in Rubyland via the Glimmer GUI DSL, completely oblivious to web browser technologies.
152
+ - 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.
153
+ - HTML is strictly made for creating documents not interactive applications. As such, software engineers can avoid and focus on creating web applications with Glimmer DSL for Opal in pure Ruby while content creators and web designers are the ones responsible for creating HTML documents for content purposes only as HTML was originally intended. As such, Glimmer web GUI built by software engineers gets embedded in the body of a web page with content around it maintained by content creators and web designers. This achieves a correct separation of responsibilities and better maintainability.
154
+
95
155
  ## Pre-requisites
96
156
 
97
157
  - Rails 5: [https://github.com/rails/rails/tree/5-2-stable](https://github.com/rails/rails/tree/5-2-stable)
@@ -102,7 +162,7 @@ Event loop:
102
162
 
103
163
  ## Setup
104
164
 
105
- (NOTE: if you run into issues, keep in mind this is a very early experimental and incomplete alpha. Also, there is a slight chance any issues you encounter are fixed in master or some other branch that you could check out instead)
165
+ (NOTE: Keep in mind this is a very early experimental and incomplete **alpha**. If you run into issues, try to go back to a [previous revision](https://rubygems.org/gems/glimmer-dsl-opal/versions). Also, there is a slight chance any issues you encounter are fixed in master or some other branch that you could check out instead)
106
166
 
107
167
  The [glimmer-dsl-opal](https://rubygems.org/gems/glimmer-dsl-opal) gem is a Rails Engine gem that includes assets.
108
168
 
@@ -126,7 +186,7 @@ Add the following to `Gemfile`:
126
186
  gem 'opal-rails', '~> 1.1.2'
127
187
  gem 'opal-async', '~> 1.2.0'
128
188
  gem 'opal-jquery', '~> 0.4.4'
129
- gem 'glimmer-dsl-opal', '~> 0.6.1'
189
+ gem 'glimmer-dsl-opal', '~> 0.7.4'
130
190
  gem 'glimmer-dsl-xml', '~> 1.1.0', require: false
131
191
  gem 'glimmer-dsl-css', '~> 1.1.0', require: false
132
192
 
@@ -163,7 +223,9 @@ Edit `app/views/layouts/application.html.erb` and add the following below other
163
223
  <%= stylesheet_link_tag 'glimmer/glimmer', media: 'all', 'data-turbolinks-track': 'reload' %>
164
224
  ```
165
225
 
166
- Open a `Document.ready?` block and add inside it Glimmer GUI DSL code or a require statement for one of the samples below.
226
+ Clear the file `app/views/welcomes/index.html.erb` from any content.
227
+
228
+ Open `app/assets/javascripts/application.rb`, add a `Document.ready?` block, and add inside it Glimmer GUI DSL code or a require statement for one of the samples below.
167
229
 
168
230
  ```ruby
169
231
  Document.ready? do
@@ -754,6 +816,10 @@ You should see "Hello, Custom Widget!"
754
816
 
755
817
  #### Hello, Custom Shell!
756
818
 
819
+ This sample demonstrates Glimmer DSL for Opal's ability to open multiple shells (windows) as web browser tabs.
820
+
821
+ It automatically handles routing so that tab URLs are bookmarkable. Web developers do not have to do any routing configuration manually.
822
+
757
823
  Add the following require statement to `app/assets/javascripts/application.rb`
758
824
 
759
825
  ```ruby
@@ -1482,6 +1548,413 @@ You should see "Hello, Date Time!"
1482
1548
 
1483
1549
  ![Glimmer DSL for Opal Hello Date Time](images/glimmer-dsl-opal-hello-date-time.png)
1484
1550
 
1551
+ #### Hello, Table!
1552
+
1553
+ 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.
1554
+
1555
+ Add the following require statement to `app/assets/javascripts/application.rb`
1556
+
1557
+ ```ruby
1558
+ require 'glimmer-dsl-opal/samples/hello/hello_table'
1559
+ ```
1560
+
1561
+ Or add the Glimmer code directly if you prefer to play around with it:
1562
+
1563
+ ```ruby
1564
+ class HelloTable
1565
+ class BaseballGame
1566
+ class << self
1567
+ attr_accessor :selected_game
1568
+
1569
+ def all_playoff_games
1570
+ @all_playoff_games ||= {
1571
+ 'NLDS' => [
1572
+ new(Time.new(2037, 10, 6, 12, 0), 'Chicago Cubs', 'Milwaukee Brewers', 'Free Bobblehead'),
1573
+ new(Time.new(2037, 10, 7, 12, 0), 'Chicago Cubs', 'Milwaukee Brewers'),
1574
+ new(Time.new(2037, 10, 8, 12, 0), 'Milwaukee Brewers', 'Chicago Cubs'),
1575
+ new(Time.new(2037, 10, 9, 12, 0), 'Milwaukee Brewers', 'Chicago Cubs'),
1576
+ new(Time.new(2037, 10, 10, 12, 0), 'Milwaukee Brewers', 'Chicago Cubs', 'Free Umbrella'),
1577
+ new(Time.new(2037, 10, 6, 18, 0), 'Cincinnati Reds', 'St Louis Cardinals', 'Free Bobblehead'),
1578
+ new(Time.new(2037, 10, 7, 18, 0), 'Cincinnati Reds', 'St Louis Cardinals'),
1579
+ new(Time.new(2037, 10, 8, 18, 0), 'St Louis Cardinals', 'Cincinnati Reds'),
1580
+ new(Time.new(2037, 10, 9, 18, 0), 'St Louis Cardinals', 'Cincinnati Reds'),
1581
+ new(Time.new(2037, 10, 10, 18, 0), 'St Louis Cardinals', 'Cincinnati Reds', 'Free Umbrella'),
1582
+ ],
1583
+ 'ALDS' => [
1584
+ new(Time.new(2037, 10, 6, 12, 0), 'New York Yankees', 'Boston Red Sox', 'Free Bobblehead'),
1585
+ new(Time.new(2037, 10, 7, 12, 0), 'New York Yankees', 'Boston Red Sox'),
1586
+ new(Time.new(2037, 10, 8, 12, 0), 'Boston Red Sox', 'New York Yankees'),
1587
+ new(Time.new(2037, 10, 9, 12, 0), 'Boston Red Sox', 'New York Yankees'),
1588
+ new(Time.new(2037, 10, 10, 12, 0), 'Boston Red Sox', 'New York Yankees', 'Free Umbrella'),
1589
+ new(Time.new(2037, 10, 6, 18, 0), 'Houston Astros', 'Cleveland Indians', 'Free Bobblehead'),
1590
+ new(Time.new(2037, 10, 7, 18, 0), 'Houston Astros', 'Cleveland Indians'),
1591
+ new(Time.new(2037, 10, 8, 18, 0), 'Cleveland Indians', 'Houston Astros'),
1592
+ new(Time.new(2037, 10, 9, 18, 0), 'Cleveland Indians', 'Houston Astros'),
1593
+ new(Time.new(2037, 10, 10, 18, 0), 'Cleveland Indians', 'Houston Astros', 'Free Umbrella'),
1594
+ ],
1595
+ 'NLCS' => [
1596
+ new(Time.new(2037, 10, 12, 12, 0), 'Chicago Cubs', 'Cincinnati Reds', 'Free Towel'),
1597
+ new(Time.new(2037, 10, 13, 12, 0), 'Chicago Cubs', 'Cincinnati Reds'),
1598
+ new(Time.new(2037, 10, 14, 12, 0), 'Cincinnati Reds', 'Chicago Cubs'),
1599
+ new(Time.new(2037, 10, 15, 18, 0), 'Cincinnati Reds', 'Chicago Cubs'),
1600
+ new(Time.new(2037, 10, 16, 18, 0), 'Cincinnati Reds', 'Chicago Cubs'),
1601
+ new(Time.new(2037, 10, 17, 18, 0), 'Chicago Cubs', 'Cincinnati Reds'),
1602
+ new(Time.new(2037, 10, 18, 12, 0), 'Chicago Cubs', 'Cincinnati Reds', 'Free Poncho'),
1603
+ ],
1604
+ 'ALCS' => [
1605
+ new(Time.new(2037, 10, 12, 12, 0), 'Houston Astros', 'Boston Red Sox', 'Free Towel'),
1606
+ new(Time.new(2037, 10, 13, 12, 0), 'Houston Astros', 'Boston Red Sox'),
1607
+ new(Time.new(2037, 10, 14, 12, 0), 'Boston Red Sox', 'Houston Astros'),
1608
+ new(Time.new(2037, 10, 15, 18, 0), 'Boston Red Sox', 'Houston Astros'),
1609
+ new(Time.new(2037, 10, 16, 18, 0), 'Boston Red Sox', 'Houston Astros'),
1610
+ new(Time.new(2037, 10, 17, 18, 0), 'Houston Astros', 'Boston Red Sox'),
1611
+ new(Time.new(2037, 10, 18, 12, 0), 'Houston Astros', 'Boston Red Sox', 'Free Poncho'),
1612
+ ],
1613
+ 'World Series' => [
1614
+ new(Time.new(2037, 10, 20, 18, 0), 'Chicago Cubs', 'Boston Red Sox', 'Free Baseball Cap'),
1615
+ new(Time.new(2037, 10, 21, 18, 0), 'Chicago Cubs', 'Boston Red Sox'),
1616
+ new(Time.new(2037, 10, 22, 18, 0), 'Boston Red Sox', 'Chicago Cubs'),
1617
+ new(Time.new(2037, 10, 23, 18, 0), 'Boston Red Sox', 'Chicago Cubs'),
1618
+ new(Time.new(2037, 10, 24, 18, 0), 'Boston Red Sox', 'Chicago Cubs'),
1619
+ new(Time.new(2037, 10, 25, 18, 0), 'Chicago Cubs', 'Boston Red Sox'),
1620
+ new(Time.new(2037, 10, 26, 18, 0), 'Chicago Cubs', 'Boston Red Sox', 'Free World Series Polo'),
1621
+ ]
1622
+ }
1623
+ end
1624
+
1625
+ def playoff_type
1626
+ @playoff_type ||= 'World Series'
1627
+ end
1628
+
1629
+ def playoff_type=(new_playoff_type)
1630
+ @playoff_type = new_playoff_type
1631
+ self.schedule=(all_playoff_games[@playoff_type])
1632
+ end
1633
+
1634
+ def playoff_type_options
1635
+ all_playoff_games.keys
1636
+ end
1637
+
1638
+ def schedule
1639
+ @schedule ||= all_playoff_games[playoff_type]
1640
+ end
1641
+
1642
+ def schedule=(new_schedule)
1643
+ @schedule = new_schedule
1644
+ end
1645
+ end
1646
+
1647
+ include Glimmer
1648
+ include Glimmer::DataBinding::ObservableModel
1649
+
1650
+ TEAM_BALLPARKS = {
1651
+ 'Boston Red Sox' => 'Fenway Park',
1652
+ 'Chicago Cubs' => 'Wrigley Field',
1653
+ 'Cincinnati Reds' => 'Great American Ball Park',
1654
+ 'Cleveland Indians' => 'Progressive Field',
1655
+ 'Houston Astros' => 'Minute Maid Park',
1656
+ 'Milwaukee Brewers' => 'Miller Park',
1657
+ 'New York Yankees' => 'Yankee Stadium',
1658
+ 'St Louis Cardinals' => 'Busch Stadium',
1659
+ }
1660
+
1661
+ attr_accessor :date_time, :home_team, :away_team, :ballpark, :promotion
1662
+
1663
+ def initialize(date_time, home_team, away_team, promotion = 'N/A')
1664
+ self.date_time = date_time
1665
+ self.home_team = home_team
1666
+ self.away_team = away_team
1667
+ self.promotion = promotion
1668
+ observe(self, :date_time) do |new_value|
1669
+ notify_observers(:game_date)
1670
+ notify_observers(:game_time)
1671
+ end
1672
+ end
1673
+
1674
+ def home_team=(home_team_value)
1675
+ if home_team_value != away_team
1676
+ @home_team = home_team_value
1677
+ self.ballpark = TEAM_BALLPARKS[@home_team]
1678
+ end
1679
+ end
1680
+
1681
+ def away_team=(away_team_value)
1682
+ if away_team_value != home_team
1683
+ @away_team = away_team_value
1684
+ end
1685
+ end
1686
+
1687
+ def date
1688
+ Date.new(date_time.year, date_time.month, date_time.day)
1689
+ end
1690
+
1691
+ def time
1692
+ Time.new(0, 1, 1, date_time.hour, date_time.min, date_time.sec, '+00:00')
1693
+ end
1694
+
1695
+ def game_date
1696
+ date_time.strftime("%m/%d/%Y")
1697
+ end
1698
+
1699
+ def game_time
1700
+ date_time.strftime("%I:%M %p")
1701
+ end
1702
+
1703
+ def home_team_options
1704
+ TEAM_BALLPARKS.keys
1705
+ end
1706
+
1707
+ def away_team_options
1708
+ TEAM_BALLPARKS.keys
1709
+ end
1710
+
1711
+ def ballpark_options
1712
+ [TEAM_BALLPARKS[@home_team], TEAM_BALLPARKS[@away_team]]
1713
+ end
1714
+
1715
+ def to_s
1716
+ "#{home_team} vs #{away_team} at #{ballpark} on #{game_date} #{game_time}"
1717
+ end
1718
+
1719
+ def book!
1720
+ "Thank you for booking #{to_s}"
1721
+ end
1722
+ end
1723
+
1724
+ include Glimmer
1725
+
1726
+ def launch
1727
+ shell {
1728
+ grid_layout
1729
+
1730
+ text 'Hello, Table!'
1731
+
1732
+ label {
1733
+ layout_data :center, :center, true, false
1734
+
1735
+ text 'Baseball Playoff Schedule'
1736
+ font height: 30, style: :bold
1737
+ }
1738
+
1739
+ combo(:read_only) {
1740
+ layout_data :center, :center, true, false
1741
+ selection bind(BaseballGame, :playoff_type)
1742
+ font height: 16
1743
+ }
1744
+
1745
+ table(:editable) { |table_proxy|
1746
+ layout_data :fill, :fill, true, true
1747
+
1748
+ table_column {
1749
+ text 'Game Date'
1750
+ width 150
1751
+ sort_property :date # ensure sorting by real date value (not `game_date` string specified in items below)
1752
+ editor :date_drop_down, property: :date_time
1753
+ }
1754
+ table_column {
1755
+ text 'Game Time'
1756
+ width 150
1757
+ sort_property :time # ensure sorting by real time value (not `game_time` string specified in items below)
1758
+ editor :time, property: :date_time
1759
+ }
1760
+ table_column {
1761
+ text 'Ballpark'
1762
+ width 180
1763
+ editor :none
1764
+ }
1765
+ table_column {
1766
+ text 'Home Team'
1767
+ width 150
1768
+ editor :combo, :read_only # read_only is simply an SWT style passed to combo widget
1769
+ }
1770
+ table_column {
1771
+ text 'Away Team'
1772
+ width 150
1773
+ editor :combo, :read_only # read_only is simply an SWT style passed to combo widget
1774
+ }
1775
+ table_column {
1776
+ text 'Promotion'
1777
+ width 150
1778
+ # default text editor is used here
1779
+ }
1780
+
1781
+ # Data-bind table items (rows) to a model collection property, specifying column properties ordering per nested model
1782
+ items bind(BaseballGame, :schedule), column_properties(:game_date, :game_time, :ballpark, :home_team, :away_team, :promotion)
1783
+
1784
+ # Data-bind table selection
1785
+ selection bind(BaseballGame, :selected_game)
1786
+
1787
+ # Default initial sort property
1788
+ sort_property :date
1789
+
1790
+ # Sort by these additional properties after handling sort by the column the user clicked
1791
+ additional_sort_properties :date, :time, :home_team, :away_team, :ballpark, :promotion
1792
+ }
1793
+
1794
+ button {
1795
+ text 'Book Selected Game'
1796
+ layout_data :center, :center, true, false
1797
+ font height: 16
1798
+ enabled bind(BaseballGame, :selected_game)
1799
+
1800
+ on_widget_selected {
1801
+ book_selected_game
1802
+ }
1803
+ }
1804
+ }.open
1805
+ end
1806
+
1807
+ def book_selected_game
1808
+ message_box {
1809
+ text 'Baseball Game Booked!'
1810
+ message BaseballGame.selected_game.book!
1811
+ }.open
1812
+ end
1813
+ end
1814
+
1815
+ HelloTable.new.launch
1816
+ ```
1817
+
1818
+ Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
1819
+
1820
+ ![Glimmer DSL for SWT Hello Table](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-table.png)
1821
+
1822
+ Hello, Table! Editing Game Date
1823
+
1824
+ ![Hello Table](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-table-editing-game-date.png)
1825
+
1826
+ Hello, Table! Editing Game Time
1827
+
1828
+ ![Hello Table](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-table-editing-game-time.png)
1829
+
1830
+ Hello, Table! Editing Home Team
1831
+
1832
+ ![Hello Table](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-table-editing-home-team.png)
1833
+
1834
+ Hello, Table! Sorted Game Date Ascending
1835
+
1836
+ ![Hello Table](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-table-sorted-game-date-ascending.png)
1837
+
1838
+ Hello, Table! Sorted Game Date Descending
1839
+
1840
+ ![Hello Table](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-table-sorted-game-date-descending.png)
1841
+
1842
+ Hello, Table! Playoff Type Combo
1843
+
1844
+ ![Hello Table](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-table-playoff-type-combo.png)
1845
+
1846
+ Hello, Table! Playoff Type Changed
1847
+
1848
+ ![Hello Table](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-table-playoff-type-changed.png)
1849
+
1850
+ Hello, Table! Game Booked
1851
+
1852
+ ![Hello Table](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-table-game-booked.png)
1853
+
1854
+
1855
+ Glimmer app on the web (using `glimmer-dsl-opal` gem):
1856
+
1857
+ Start the Rails server:
1858
+ ```
1859
+ rails s
1860
+ ```
1861
+
1862
+ Visit `http://localhost:3000`
1863
+
1864
+ You should see "Hello, Date Time!"
1865
+
1866
+ ![Glimmer DSL for Opal Hello Table](images/glimmer-dsl-opal-hello-table.png)
1867
+
1868
+ Hello, Table! Editing Game Date
1869
+
1870
+ ![Glimmer DSL for Opal Hello Table](images/glimmer-dsl-opal-hello-table-editing-game-date.png)
1871
+
1872
+ Hello, Table! Editing Game Time
1873
+
1874
+ ![Glimmer DSL for Opal Hello Table](images/glimmer-dsl-opal-hello-table-editing-game-time.png)
1875
+
1876
+ Hello, Table! Editing Home Team
1877
+
1878
+ ![Glimmer DSL for Opal Hello Table](images/glimmer-dsl-opal-hello-table-editing-home-team.png)
1879
+
1880
+ Hello, Table! Sorted Game Date Ascending
1881
+
1882
+ ![Glimmer DSL for Opal Hello Table](images/glimmer-dsl-opal-hello-table-sorted-game-date-ascending.png)
1883
+
1884
+ Hello, Table! Sorted Game Date Descending
1885
+
1886
+ ![Glimmer DSL for Opal Hello Table](images/glimmer-dsl-opal-hello-table-sorted-game-date-descending.png)
1887
+
1888
+ Hello, Table! Playoff Type Combo
1889
+
1890
+ ![Glimmer DSL for Opal Hello Table](images/glimmer-dsl-opal-hello-table-playoff-type-combo.png)
1891
+
1892
+ Hello, Table! Playoff Type Changed
1893
+
1894
+ ![Glimmer DSL for Opal Hello Table](images/glimmer-dsl-opal-hello-table-playoff-type-changed.png)
1895
+
1896
+ Hello, Table! Game Booked
1897
+
1898
+ ![Glimmer DSL for Opal Hello Table](images/glimmer-dsl-opal-hello-table-game-booked.png)
1899
+
1900
+ #### Hello, Button!
1901
+
1902
+ Add the following require statement to `app/assets/javascripts/application.rb`
1903
+
1904
+ ```ruby
1905
+ require 'glimmer-dsl-opal/samples/hello/hello_button'
1906
+ ```
1907
+
1908
+ Or add the Glimmer code directly if you prefer to play around with it:
1909
+
1910
+ ```ruby
1911
+ class HelloButton
1912
+ include Glimmer
1913
+
1914
+ attr_accessor :count
1915
+
1916
+ def initialize
1917
+ @count = 0
1918
+ end
1919
+
1920
+ def launch
1921
+ shell {
1922
+ text 'Hello, Button!'
1923
+
1924
+ button {
1925
+ text bind(self, :count) {|value| "Click To Increment: #{value} "}
1926
+
1927
+ on_widget_selected {
1928
+ self.count += 1
1929
+ }
1930
+ }
1931
+ }.open
1932
+ end
1933
+ end
1934
+
1935
+ HelloButton.new.launch
1936
+ ```
1937
+
1938
+ Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
1939
+
1940
+ ![Glimmer DSL for SWT Hello Button](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-button.png)
1941
+ ![Glimmer DSL for SWT Hello Button](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-hello-button-incremented.png)
1942
+
1943
+ Glimmer app on the web (using `glimmer-dsl-opal` gem):
1944
+
1945
+ Start the Rails server:
1946
+ ```
1947
+ rails s
1948
+ ```
1949
+
1950
+ Visit `http://localhost:3000`
1951
+
1952
+ You should see "Hello, Button!"
1953
+
1954
+ ![Glimmer DSL for Opal Hello Button](images/glimmer-dsl-opal-hello-button.png)
1955
+ ![Glimmer DSL for Opal Hello Button](images/glimmer-dsl-opal-hello-button-incremented.png)
1956
+
1957
+
1485
1958
  ### Elaborate Samples
1486
1959
 
1487
1960
  #### Login
@@ -2223,7 +2696,7 @@ Visit `http://localhost:3000`
2223
2696
 
2224
2697
  You should see "Glimmer Calculator"
2225
2698
 
2226
- ![Glimmer Calculator Opal](https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-calculator/master/glimmer-cs-calculator-screenshot-opal.png)
2699
+ [![Glimmer Calculator Opal](https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-calculator/master/glimmer-cs-calculator-screenshot-opal.png)](http://glimmer-cs-calculator-server.herokuapp.com)
2227
2700
 
2228
2701
  Here is an Apple Calculator CSS themed version (with [CSS only](https://github.com/AndyObtiva/glimmer-cs-calculator/blob/master/server/glimmer-cs-calculator-server/app/assets/stylesheets/welcomes_apple.scss), no app code changes):
2229
2702
 
@@ -2231,7 +2704,7 @@ Visit http://glimmer-cs-calculator-server.herokuapp.com/welcomes/apple
2231
2704
 
2232
2705
  You should see "Apple Calculator Theme"
2233
2706
 
2234
- ![Glimmer Calculator Opal Apple Calculator Theme](https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-calculator/master/glimmer-cs-calculator-screenshot-opal-apple.png)
2707
+ [![Glimmer Calculator Opal Apple Calculator Theme](https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-calculator/master/glimmer-cs-calculator-screenshot-opal-apple.png)](http://glimmer-cs-calculator-server.herokuapp.com/welcomes/apple)
2235
2708
 
2236
2709
  ## Help
2237
2710