glimmer-dsl-swt 4.18.3.1 → 4.18.4.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 +55 -1
- data/README.md +739 -324
- data/VERSION +1 -1
- data/glimmer-dsl-swt.gemspec +9 -4
- data/lib/ext/rouge/themes/glimmer.rb +29 -0
- data/lib/glimmer-dsl-swt.rb +0 -1
- data/lib/glimmer/data_binding/table_items_binding.rb +8 -5
- data/lib/glimmer/data_binding/widget_binding.rb +9 -1
- data/lib/glimmer/dsl/swt/image_expression.rb +14 -6
- data/lib/glimmer/dsl/swt/layout_data_expression.rb +4 -4
- data/lib/glimmer/dsl/swt/layout_expression.rb +5 -3
- data/lib/glimmer/swt/custom/code_text.rb +171 -53
- data/lib/glimmer/swt/custom/drawable.rb +4 -6
- data/lib/glimmer/swt/custom/shape.rb +69 -12
- data/lib/glimmer/swt/date_time_proxy.rb +1 -3
- data/lib/glimmer/swt/display_proxy.rb +12 -1
- data/lib/glimmer/swt/font_proxy.rb +1 -0
- data/lib/glimmer/swt/image_proxy.rb +79 -1
- data/lib/glimmer/swt/shell_proxy.rb +13 -1
- data/lib/glimmer/swt/table_proxy.rb +43 -15
- data/lib/glimmer/swt/widget_proxy.rb +11 -2
- data/lib/glimmer/ui/custom_shell.rb +1 -0
- data/lib/glimmer/ui/custom_widget.rb +10 -3
- data/samples/elaborate/meta_sample.rb +1 -1
- data/samples/elaborate/meta_sample/meta_sample_logo.png +0 -0
- data/samples/elaborate/tetris.rb +90 -17
- data/samples/elaborate/tetris/model/game.rb +89 -8
- data/samples/elaborate/tetris/{view/game_over_dialog.rb → model/past_game.rb} +12 -41
- data/samples/elaborate/tetris/model/tetromino.rb +18 -5
- data/samples/elaborate/tetris/view/block.rb +8 -13
- data/samples/elaborate/tetris/view/high_score_dialog.rb +131 -0
- data/samples/elaborate/tetris/view/playfield.rb +1 -1
- data/samples/elaborate/tetris/view/score_lane.rb +6 -6
- data/samples/elaborate/tetris/view/tetris_menu_bar.rb +70 -3
- data/samples/hello/hello_canvas.rb +10 -9
- data/samples/hello/hello_canvas_animation.rb +5 -5
- data/samples/hello/hello_code_text.rb +92 -0
- data/samples/hello/hello_table.rb +6 -4
- data/samples/hello/hello_table/baseball_park.png +0 -0
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e3d59d0d54c7528a521c07263fa47768f172e49ea2d5bee86c376d0425b8a5f8
|
4
|
+
data.tar.gz: 0da445293890975f23fbf5cce1af49ea4e8b54e2d86a99b6d0f4cfa7fe6559bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a51c136d719ebe688209fa1a3bf8509dee32f1c90d535b06c08b6f5d835a0872c9487f437f06c7985007c210bf7aef3ecb29c6a11819e9ee48ffed77ea5ee40f
|
7
|
+
data.tar.gz: 8c285b55812b44969dbe3ab527b1ad1d5cc2325d2455cdf676412bfdc41f1094ce7402c3f0f5181546be9d539299f5c669de553c0b04339c3ffa3ef5c81c3fbb
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,59 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
### 4.18.4.0
|
4
|
+
|
5
|
+
- Extract line numbers part of text_editor widget from Gladiator into Glimmer code_text and make it an option (e.g. lines: true or lines: {width: 4})
|
6
|
+
- code_text support select all via CMD+A
|
7
|
+
- code_text support end of line via CTRL+E and beginning of line via CTRL+A
|
8
|
+
- Support automatic inferrence of Canvas Shape DSL gradient option (just like fill option)
|
9
|
+
- Support automatic inferrence of Canvas Shape DSL round option (just like fill option)
|
10
|
+
- Add a background image to Hello, Table! Sample + font/color changes
|
11
|
+
- Make Canvas patterns auto-reused and auto-disposed when canvas is disposed
|
12
|
+
- Make Canvas images auto-dispose themselves when canvas is disposed
|
13
|
+
- Update Hello, Code Text!
|
14
|
+
- Change Glimmer Tetris Sample up arrow default to rotate left
|
15
|
+
- Fix issue with "undefined method lex for nil:NilClass" in `code_text`
|
16
|
+
|
17
|
+
### 4.18.3.5
|
18
|
+
|
19
|
+
- Add `write_on_cancel: true` option for TableProxy#edit_table_item to make cancel behave just like save for special cases where you cannot cancel except the edit mode itself
|
20
|
+
- Make code_text custom widget support multiple code languages via `language: 'java'` option
|
21
|
+
- Make code_text custom widget support multiple themes via `theme: 'github'` option
|
22
|
+
- Hello, Code Text! Sample
|
23
|
+
- Fix issue with High Score Dialog in Tetris Sample not sorting by scores correctly (string compare instead of numeric compare) until first game is completed
|
24
|
+
- Fix issue with setting date geting rejected in `date_time` for month or day being incompatible with the year/month/day combo
|
25
|
+
|
26
|
+
### 4.18.3.4
|
27
|
+
|
28
|
+
- Support building Image objects with the Glimmer Canvas Shape DSL
|
29
|
+
- Tetris build icon image in-game by nesting Glimmer Shape DSL syntax
|
30
|
+
- Canvas Make shapes auto-fill if you specify a background only (no need to say fill: true) or not fill if you specify a foreground only
|
31
|
+
- Tetris option to switch Up Arrow between Instant Down, Rotate Right, and Rotate Left
|
32
|
+
|
33
|
+
### 4.18.3.3
|
34
|
+
|
35
|
+
- Support Table data binding read_only_sort: true option to allow visual sorting without affecting model data
|
36
|
+
- on_quit to
|
37
|
+
- Tetris Add lines and level to High Score Dialog
|
38
|
+
- Tetris Immediate Drop on Arrow Up
|
39
|
+
- Tetris Pause on showing High Score Dialog
|
40
|
+
- Tetris Make High Scores -> Show a check menu item
|
41
|
+
- Tetris Disable pause button upon showing High Score Dialog
|
42
|
+
- Fix Quit Tetris CMD+Q shortcut by adding on_quit event to display
|
43
|
+
- Tetris Fix escape button upon entering high score name
|
44
|
+
- If WidgetBinding encounters a disposed widget, it deregisters all observables that it is observing
|
45
|
+
|
46
|
+
### 4.18.3.2
|
47
|
+
|
48
|
+
- Tetris High Scores
|
49
|
+
- Tetris Modify High Score Player Name
|
50
|
+
- Tetris Show High Scores (Menu Item + Accelerator)
|
51
|
+
- Tetris add a menu item with beep enablement option
|
52
|
+
- Tetris Clear High Scores
|
53
|
+
- Tetris Add left and right alt (option) buttons as alternative to shift for rotation. Use left ctrl as rotate left. Use a, s, d as left, down, right.
|
54
|
+
- Fix issues relating to setting parenthood with custom widgets before building their body (instead of after)
|
55
|
+
- Fix issues relating to not respecting arity of passed in table editing callbacks: before_write, after_write, and after_cancel
|
56
|
+
|
3
57
|
### 4.18.3.1
|
4
58
|
|
5
59
|
- Provide an auto_sync_exec all data-binding config option to automatically sync_exec GUI calls from other threads instead of requiring users to use sync_exec on model attribute-change logic. Default value to false.
|
@@ -10,9 +64,9 @@
|
|
10
64
|
- Supporting deregistering Display listeners just like standard listeners via deregister
|
11
65
|
- Enhance performance of excluded keyword check
|
12
66
|
- Remove CustomWidget support for multiple before_body/after_body blocks instead of one each since it is not needed.
|
67
|
+
- Add new :fill_screen style for `shell` to start app filling the screen size (not full screen mode though)
|
13
68
|
- Tetris Menu Bar with Game Menu -> Start, Pause, Restart, and Exit
|
14
69
|
- Tetris refactor mutation methods to end with bangs
|
15
|
-
- Add new :fill_screen style for `shell` to start app filling the screen size (not full screen mode though)
|
16
70
|
- Tetris Stop game if user does not play again in the end (instead of closing it)
|
17
71
|
- End Tetris Thread loop gracefully if game over is encountered
|
18
72
|
- Tetris use more observers instead of callbacks to Game
|
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 SWT 4.18.
|
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 SWT 4.18.4.0
|
2
2
|
## JRuby Desktop Development GUI Framework
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/glimmer-dsl-swt.svg)](http://badge.fury.io/rb/glimmer-dsl-swt)
|
4
4
|
[![Travis CI](https://travis-ci.com/AndyObtiva/glimmer-dsl-swt.svg?branch=master)](https://travis-ci.com/github/AndyObtiva/glimmer-dsl-swt)
|
@@ -8,7 +8,7 @@
|
|
8
8
|
|
9
9
|
**[Contributors Wanted! (Submit a Glimmer App Sample to Get Started)](#contributing)**
|
10
10
|
|
11
|
-
[Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer) is a native-GUI cross-platform desktop development library written in [JRuby](https://www.jruby.org/), an OS-threaded faster JVM version of [Ruby](https://www.ruby-lang.org/en/). [Glimmer](https://github.com/AndyObtiva/glimmer)'s main innovation is a declarative [Ruby DSL](#glimmer-dsl-syntax) that enables productive and efficient authoring of desktop application user-interfaces by relying on the robust [Eclipse SWT library](https://www.eclipse.org/swt/). [Glimmer](https://rubygems.org/gems/glimmer) additionally innovates by having built-in [data-binding](#data-binding) support, which greatly facilitates synchronizing the GUI with domain models, thus achieving true decoupling of object oriented components and enabling developers to solve business problems (test-first) without worrying about GUI concerns, or alternatively drive development GUI-first, and then write clean business models (test-first) afterwards. Not only does Glimmer provide a large set of GUI [widgets](#widgets), but it also supports drawing Canvas Graphics like [Shapes](#canvas-shape-dsl) and [Animations](#canvas-animation-dsl). To get started quickly, [Glimmer](https://rubygems.org/gems/glimmer)
|
11
|
+
[Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer) is a native-GUI cross-platform desktop development library written in [JRuby](https://www.jruby.org/), an OS-threaded faster JVM version of [Ruby](https://www.ruby-lang.org/en/). [Glimmer](https://github.com/AndyObtiva/glimmer)'s main innovation is a declarative [Ruby DSL](#glimmer-dsl-syntax) that enables productive and efficient authoring of desktop application user-interfaces by relying on the robust [Eclipse SWT library](https://www.eclipse.org/swt/). [Glimmer](https://rubygems.org/gems/glimmer) additionally innovates by having built-in [data-binding](#data-binding) support, which greatly facilitates synchronizing the GUI with domain models, thus achieving true decoupling of object oriented components and enabling developers to solve business problems (test-first) without worrying about GUI concerns, or alternatively drive development GUI-first, and then write clean business models (test-first) afterwards. Not only does Glimmer provide a large set of GUI [widgets](#widgets), but it also supports drawing Canvas Graphics like [Shapes](#canvas-shape-dsl) and [Animations](#canvas-animation-dsl). To get started quickly, [Glimmer](https://rubygems.org/gems/glimmer) offers [scaffolding](#scaffolding) options for [Apps](#in-production), [Gems](#custom-shell-gem), and [Custom Widgets](#custom-widgets). [Glimmer](https://rubygems.org/gems/glimmer) also includes native-executable [packaging](#packaging--distribution) support, sorely lacking in other libraries, thus enabling the delivery of desktop apps written in [Ruby](https://www.ruby-lang.org/en/) as truly native DMG/PKG/APP files on the [Mac](https://www.apple.com/ca/macos) + [App Store](https://developer.apple.com/macos/distribution/), MSI/EXE files on [Windows](https://www.microsoft.com/en-ca/windows), and [Gem Packaged Shell Scripts](#custom-shell-gem) on [Linux](https://www.linux.org/).
|
12
12
|
|
13
13
|
[Glimmer receives two updates per month](https://rubygems.org/gems/glimmer-dsl-swt/versions). You can trust [Glimmer](https://rubygems.org/gems/glimmer) with your Ruby desktop GUI development needs. Please make [Glimmer](https://rubygems.org/gems/glimmer) even better by providing feedback and [contributing](#contributing) when possible.
|
14
14
|
|
@@ -28,9 +28,10 @@ Glimmer DSL gems:
|
|
28
28
|
|
29
29
|
## Examples
|
30
30
|
|
31
|
-
### Hello, World!
|
31
|
+
### Hello, World! Sample
|
32
|
+
|
33
|
+
Glimmer GUI DSL code (from [samples/hello/hello_world.rb](samples/hello/hello_world.rb)):
|
32
34
|
|
33
|
-
Glimmer code (from [samples/hello/hello_world.rb](samples/hello/hello_world.rb)):
|
34
35
|
```ruby
|
35
36
|
include Glimmer
|
36
37
|
|
@@ -52,169 +53,163 @@ Glimmer app:
|
|
52
53
|
|
53
54
|
![Hello World](images/glimmer-hello-world.png)
|
54
55
|
|
55
|
-
|
56
|
+
Learn more about [Hello, World!](#hello-world).
|
57
|
+
|
58
|
+
### Hello, Table! Sample
|
56
59
|
|
57
|
-
Glimmer code (from [samples/
|
60
|
+
Glimmer GUI DSL code (from [samples/hello/hello_table.rb](samples/hello/hello_table.rb)):
|
58
61
|
|
59
62
|
```ruby
|
60
|
-
# ...
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
63
|
+
# ... model code precedes
|
64
|
+
shell {
|
65
|
+
grid_layout
|
66
|
+
|
67
|
+
text 'Hello, Table!'
|
68
|
+
background_image File.expand_path('hello_table/baseball_park.png', __dir__)
|
69
|
+
|
70
|
+
label {
|
71
|
+
layout_data :center, :center, true, false
|
72
|
+
|
73
|
+
text 'BASEBALL PLAYOFF SCHEDULE'
|
74
|
+
foreground rgb(94, 107, 103)
|
75
|
+
font name: 'Optima', height: 38, style: :bold
|
76
|
+
}
|
77
|
+
|
78
|
+
combo(:read_only) {
|
79
|
+
layout_data :center, :center, true, false
|
80
|
+
selection bind(BaseballGame, :playoff_type)
|
81
|
+
font height: 14
|
82
|
+
}
|
83
|
+
|
84
|
+
table(:editable) { |table_proxy|
|
85
|
+
layout_data :fill, :fill, true, true
|
86
|
+
|
87
|
+
table_column {
|
88
|
+
text 'Game Date'
|
89
|
+
width 150
|
90
|
+
sort_property :date # ensure sorting by real date value (not `game_date` string specified in items below)
|
91
|
+
editor :date_drop_down, property: :date_time
|
92
|
+
}
|
93
|
+
table_column {
|
94
|
+
text 'Game Time'
|
95
|
+
width 150
|
96
|
+
sort_property :time # ensure sorting by real time value (not `game_time` string specified in items below)
|
97
|
+
editor :time, property: :date_time
|
98
|
+
}
|
99
|
+
table_column {
|
100
|
+
text 'Ballpark'
|
101
|
+
width 180
|
102
|
+
editor :none
|
103
|
+
}
|
104
|
+
table_column {
|
105
|
+
text 'Home Team'
|
106
|
+
width 150
|
107
|
+
editor :combo, :read_only # read_only is simply an SWT style passed to combo widget
|
108
|
+
}
|
109
|
+
table_column {
|
110
|
+
text 'Away Team'
|
111
|
+
width 150
|
112
|
+
editor :combo, :read_only # read_only is simply an SWT style passed to combo widget
|
113
|
+
}
|
114
|
+
table_column {
|
115
|
+
text 'Promotion'
|
116
|
+
width 150
|
117
|
+
# default text editor is used here
|
118
|
+
}
|
119
|
+
|
120
|
+
# Data-bind table items (rows) to a model collection property, specifying column properties ordering per nested model
|
121
|
+
items bind(BaseballGame, :schedule), column_properties(:game_date, :game_time, :ballpark, :home_team, :away_team, :promotion)
|
122
|
+
|
123
|
+
# Data-bind table selection
|
124
|
+
selection bind(BaseballGame, :selected_game)
|
125
|
+
|
126
|
+
# Default initial sort property
|
127
|
+
sort_property :date
|
128
|
+
|
129
|
+
# Sort by these additional properties after handling sort by the column the user clicked
|
130
|
+
additional_sort_properties :date, :time, :home_team, :away_team, :ballpark, :promotion
|
131
|
+
|
132
|
+
menu {
|
133
|
+
menu_item {
|
134
|
+
text 'Book'
|
135
|
+
|
136
|
+
on_widget_selected {
|
137
|
+
book_selected_game
|
78
138
|
}
|
79
139
|
}
|
80
140
|
}
|
141
|
+
}
|
142
|
+
|
143
|
+
button {
|
144
|
+
text 'Book Selected Game'
|
145
|
+
layout_data :center, :center, true, false
|
146
|
+
font height: 14
|
147
|
+
enabled bind(BaseballGame, :selected_game)
|
148
|
+
|
149
|
+
on_widget_selected {
|
150
|
+
book_selected_game
|
151
|
+
}
|
152
|
+
}
|
153
|
+
}.open
|
81
154
|
# ...
|
82
155
|
```
|
83
156
|
|
84
157
|
Run via `glimmer samples` or directly:
|
85
158
|
|
86
159
|
```
|
87
|
-
glimmer samples/
|
160
|
+
glimmer samples/hello/hello_table.rb
|
88
161
|
```
|
89
162
|
|
90
|
-
Glimmer
|
163
|
+
Glimmer App:
|
164
|
+
|
165
|
+
![Hello Table](images/glimmer-hello-table.png)
|
91
166
|
|
92
|
-
|
167
|
+
Learn more about [Hello, Table!](#hello-table).
|
93
168
|
|
94
|
-
###
|
169
|
+
### Tetris
|
95
170
|
|
96
|
-
Glimmer code (from [samples/elaborate/
|
171
|
+
Glimmer GUI DSL code (from [samples/elaborate/tetris.rb](samples/elaborate/tetris.rb)):
|
97
172
|
|
98
173
|
```ruby
|
99
|
-
# ...
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
label {
|
113
|
-
layout_data :right, :center, false, false
|
114
|
-
text "First &Name: "
|
115
|
-
font height: 16
|
116
|
-
}
|
117
|
-
text {
|
118
|
-
layout_data :fill, :center, true, false
|
119
|
-
text bind(@contact_manager_presenter, :first_name)
|
120
|
-
on_key_pressed {|key_event|
|
121
|
-
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
122
|
-
}
|
123
|
-
}
|
124
|
-
|
125
|
-
label {
|
126
|
-
layout_data :right, :center, false, false
|
127
|
-
text "&Last Name: "
|
128
|
-
font height: 16
|
129
|
-
}
|
130
|
-
text {
|
131
|
-
layout_data :fill, :center, true, false
|
132
|
-
text bind(@contact_manager_presenter, :last_name)
|
133
|
-
on_key_pressed {|key_event|
|
134
|
-
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
135
|
-
}
|
136
|
-
}
|
137
|
-
|
138
|
-
label {
|
139
|
-
layout_data :right, :center, false, false
|
140
|
-
text "&Email: "
|
141
|
-
font height: 16
|
142
|
-
}
|
143
|
-
text {
|
144
|
-
layout_data :fill, :center, true, false
|
145
|
-
text bind(@contact_manager_presenter, :email)
|
146
|
-
on_key_pressed {|key_event|
|
147
|
-
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
148
|
-
}
|
149
|
-
}
|
150
|
-
|
151
|
-
composite {
|
152
|
-
row_layout {
|
153
|
-
margin_width 0
|
154
|
-
margin_height 0
|
155
|
-
}
|
156
|
-
layout_data(:right, :center, false, false) {
|
157
|
-
horizontal_span 2
|
158
|
-
}
|
159
|
-
|
160
|
-
button {
|
161
|
-
text "&Find"
|
162
|
-
on_widget_selected { @contact_manager_presenter.find }
|
163
|
-
on_key_pressed {|key_event|
|
164
|
-
@contact_manager_presenter.find if key_event.keyCode == swt(:cr)
|
165
|
-
}
|
166
|
-
}
|
167
|
-
|
168
|
-
button {
|
169
|
-
text "&List All"
|
170
|
-
on_widget_selected { @contact_manager_presenter.list }
|
171
|
-
on_key_pressed {|key_event|
|
172
|
-
@contact_manager_presenter.list if key_event.keyCode == swt(:cr)
|
173
|
-
}
|
174
|
-
}
|
175
|
-
}
|
176
|
-
}
|
174
|
+
# ... more code resides in other files (navigate sample files to learn more)
|
175
|
+
shell(:no_resize) {
|
176
|
+
grid_layout {
|
177
|
+
num_columns 2
|
178
|
+
make_columns_equal_width false
|
179
|
+
margin_width 0
|
180
|
+
margin_height 0
|
181
|
+
horizontal_spacing 0
|
182
|
+
}
|
183
|
+
|
184
|
+
text 'Glimmer Tetris'
|
185
|
+
minimum_size 475, 500
|
186
|
+
image tetris_icon
|
177
187
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
table_column {
|
191
|
-
text "Last Name"
|
192
|
-
width 80
|
193
|
-
}
|
194
|
-
table_column {
|
195
|
-
text "Email"
|
196
|
-
width 200
|
197
|
-
}
|
198
|
-
items bind(@contact_manager_presenter, :results),
|
199
|
-
column_properties(:first_name, :last_name, :email)
|
200
|
-
on_mouse_up { |event|
|
201
|
-
table_proxy.edit_table_item(event.table_item, event.column_index)
|
202
|
-
}
|
203
|
-
}
|
204
|
-
}
|
205
|
-
}.open
|
188
|
+
tetris_menu_bar(game: game)
|
189
|
+
|
190
|
+
playfield(game_playfield: game.playfield, playfield_width: playfield_width, playfield_height: playfield_height, block_size: BLOCK_SIZE)
|
191
|
+
|
192
|
+
score_lane(game: game, block_size: BLOCK_SIZE) {
|
193
|
+
layout_data(:fill, :fill, true, true)
|
194
|
+
}
|
195
|
+
|
196
|
+
on_widget_disposed {
|
197
|
+
deregister_observers
|
198
|
+
}
|
199
|
+
}
|
206
200
|
# ...
|
207
201
|
```
|
208
202
|
|
209
203
|
Run via `glimmer samples` or directly:
|
210
204
|
|
211
205
|
```
|
212
|
-
glimmer samples/elaborate/
|
206
|
+
glimmer samples/elaborate/tetris.rb
|
213
207
|
```
|
214
208
|
|
215
|
-
Glimmer
|
209
|
+
Glimmer app:
|
210
|
+
|
211
|
+
![Tetris](images/glimmer-tetris.png)
|
216
212
|
|
217
|
-
![Contact Manager](images/glimmer-contact-manager.png)
|
218
213
|
|
219
214
|
### Desktop Apps Built with Glimmer DSL for SWT
|
220
215
|
|
@@ -235,12 +230,13 @@ If you see anything that needs to be improved, please do not hesitate to contact
|
|
235
230
|
|
236
231
|
- [Glimmer (JRuby Desktop Development GUI Framework)](#jruby-desktop-development-gui-framework)
|
237
232
|
- [Examples](#examples)
|
238
|
-
- [Hello, World!](#hello-world)
|
239
|
-
- [
|
240
|
-
- [
|
233
|
+
- [Hello, World! Sample](#hello-world-sample)
|
234
|
+
- [Hello, Table! Sample](#hello-table-sample)
|
235
|
+
- [Tetris](#tetris)
|
241
236
|
- [Desktop Apps Built with Glimmer DSL for SWT](#desktop-apps-built-with-glimmer-dsl-for-swt)
|
242
237
|
- [Table of contents](#table-of-contents)
|
243
238
|
- [Background](#background)
|
239
|
+
- [Software Architecture](#software-architecture)
|
244
240
|
- [Platform Support](#platform-support)
|
245
241
|
- [Pre-requisites](#pre-requisites)
|
246
242
|
- [Setup](#setup)
|
@@ -275,6 +271,8 @@ If you see anything that needs to be improved, please do not hesitate to contact
|
|
275
271
|
- [Multi-Threading](#multi-threading)
|
276
272
|
- [Menus](#menus)
|
277
273
|
- [ScrolledComposite](#scrolledcomposite)
|
274
|
+
- [Sash Form Widget](#sash-form-widget)
|
275
|
+
- [Browser Widget](#browser-widget)
|
278
276
|
- [Widget Styles](#widget-styles)
|
279
277
|
- [Explicit SWT Style Bit](#explicit-swt-style-bit)
|
280
278
|
- [Negative SWT Style Bits](#negative-swt-style-bits)
|
@@ -306,7 +304,12 @@ If you see anything that needs to be improved, please do not hesitate to contact
|
|
306
304
|
- [Lifecycle Hooks Example](#lifecycle-hooks-example)
|
307
305
|
- [Custom Widget API](#custom-widget-api)
|
308
306
|
- [Content/Options Example](#contentoptions-example)
|
309
|
-
- [
|
307
|
+
- [Custom Widget Gotchas](#custom-widget-gotchas)
|
308
|
+
- [Built-In Custom Widgets](#built-in-custom-widgets)
|
309
|
+
- [Checkbox Group Custom Widget](#checkbox-group-custom-widget)
|
310
|
+
- [Radio Group Custom Widget](#radio-group-custom-widget)
|
311
|
+
- [Code Text Custom Widget](#code-text-custom-widget)
|
312
|
+
- [Video Custom Widget](#video-custom-widget)
|
310
313
|
- [Custom Widget Final Notes](#custom-widget-final-notes)
|
311
314
|
- [Custom Shells](#custom-shells)
|
312
315
|
- [Drag and Drop](#drag-and-drop)
|
@@ -314,12 +317,6 @@ If you see anything that needs to be improved, please do not hesitate to contact
|
|
314
317
|
- [Multi-DSL Support](#multi-dsl-support)
|
315
318
|
- [Application Menu Items (About/Preferences)](#application-menu-items-aboutpreferences)
|
316
319
|
- [App Name and Version](#app-name-and-version)
|
317
|
-
- [Checkbox Group Widget](#checkbox-group-widget)
|
318
|
-
- [Radio Group Widget](#radio-group-widget)
|
319
|
-
- [Code Text Widget](#code-text-widget)
|
320
|
-
- [Video Widget](#video-widget)
|
321
|
-
- [Sash Form Widget](#sash-form-widget)
|
322
|
-
- [Browser Widget](#browser-widget)
|
323
320
|
- [Glimmer Configuration](#glimmer-configuration)
|
324
321
|
- [logger](#logger)
|
325
322
|
- [logging_devices](#loggingdevices)
|
@@ -369,9 +366,9 @@ If you see anything that needs to be improved, please do not hesitate to contact
|
|
369
366
|
- [Elaborate Samples](#elaborate-samples)
|
370
367
|
- [User Profile](#user-profile)
|
371
368
|
- [Login](#login)
|
372
|
-
- [Tic Tac Toe Sample](#tic-tac-toe
|
373
|
-
- [Contact Manager Sample](#contact-manager
|
374
|
-
- [Tetris](#tetris)
|
369
|
+
- [Tic Tac Toe Sample](#tic-tac-toe)
|
370
|
+
- [Contact Manager Sample](#contact-manager)
|
371
|
+
- [Glimmer Tetris](#glimmer-tetris)
|
375
372
|
- [External Samples](#external-samples)
|
376
373
|
- [Glimmer Calculator](#glimmer-calculator)
|
377
374
|
- [Gladiator](#gladiator)
|
@@ -407,6 +404,38 @@ If you see anything that needs to be improved, please do not hesitate to contact
|
|
407
404
|
|
408
405
|
[Ruby](https://www.ruby-lang.org) is a dynamically-typed object-oriented language, which provides great productivity gains due to its powerful expressive syntax and dynamic nature. While it is proven by the [Ruby](https://www.ruby-lang.org) on Rails framework for web development, it currently lacks a robust platform-independent framework for building desktop applications. Given that Java libraries can now be utilized in Ruby code through JRuby, Eclipse technologies, such as [SWT](https://www.eclipse.org/swt/), JFace, and RCP can help fill the gap of desktop application development with Ruby.
|
409
406
|
|
407
|
+
## Software Architecture
|
408
|
+
|
409
|
+
There are several requirements for building enterprise-level/consumer-level desktop GUI applications:
|
410
|
+
- Cross-Platform Support (Mac, Windows, Linux) without compilation/recompilation
|
411
|
+
- OS Native Look & Feel
|
412
|
+
- High Performance
|
413
|
+
- Productivity
|
414
|
+
- Maintainability
|
415
|
+
- Extensibility
|
416
|
+
- Native Executable Packaging
|
417
|
+
- Multi-Threading / Parallel Programming
|
418
|
+
- Arbitrary Graphics Painting
|
419
|
+
- Audio Support
|
420
|
+
|
421
|
+
Glimmer provides cross-platform support that does not require Ruby compilation (like Tk does), thanks to JRuby, a JVM (Java Virtual Machine) faster OS-threaded version of Ruby.
|
422
|
+
|
423
|
+
Glimmer leverages SWT (Standard Widget Toolkit), which provides cross-platform widgets that automatically use the native GUI libraries under each operating system, such as Win32 on Windows, Cocoa on Mac, and GTK on Linux.
|
424
|
+
|
425
|
+
Furthermore, what is special about SWT regarding "High Performance" is that it does all the GUI painting natively outside of Java, thus producing GUI that runs at maximum performance even in Ruby. As such, you do not need to worry about Ruby dynamic typing getting in the way of GUI performance. It has ZERO effect on it and since SWT supports making asynchronous calls for GUI rendering, you could avoid blocking the GUI completely with any computations happening in Ruby no matter how complex, thus never affecting the responsiveness of GUI of applications while taking full advantage of the productivity benefits of Ruby dynamic typing.
|
426
|
+
|
427
|
+
Glimmer takes this further by providing a very programmer friendly DSL (Domain Specific Language) that visually maps lightweight Ruby syntax to the containment hierarchy of GUI widgets (meaning Ruby blocks nested within each other map to GUI widgets nested within each other). This provides maximum productivity and maintainability.
|
428
|
+
|
429
|
+
Extensibility has never been simpler in desktop GUI application development than with Glimmer, which provides the ability to support any new custom keywords through custom widgets and custom shells (windows). Basically, you map a keyword by declaring a view class matching its name by convention with a GUI body that simply consists of reusable Glimmer GUI syntax. They can be passive views or smart views with additional logic. This provides the ultimate realization of Object Oriented Programming and micro-level MVC pattern.
|
430
|
+
|
431
|
+
Thanks to Java and JRuby, Glimmer apps can be packaged as cross-platform JAR files (with JRuby Warbler) and native executables (with Java Packager) as Mac APP/DMG/PACKAGE or Windows EXE/MSI.
|
432
|
+
|
433
|
+
The Java Virtual Machine already supports OS-native threads, so Glimmer apps can have multiple things running in parallel with no problem.
|
434
|
+
|
435
|
+
SWT supports Canvas graphics drawing, and Glimmer takes that further by provding a Canvas Shape/Transform/Animation DSL, making it very simple to decorate any existing widgets or add new widgets with a completely custom look and feel if needed for branding or entertainment (gaming) purposes.
|
436
|
+
|
437
|
+
Audio is supported via the Java Sound library in a cross-platform approach and video is supported via a Glimmer custom widget, so any Glimmer app can be enhanced with audio and video where needed.
|
438
|
+
|
410
439
|
## Platform Support
|
411
440
|
|
412
441
|
Glimmer runs on the following platforms:
|
@@ -460,7 +489,7 @@ jgem install glimmer-dsl-swt
|
|
460
489
|
|
461
490
|
Or this command if you want a specific version:
|
462
491
|
```
|
463
|
-
jgem install glimmer-dsl-swt -v 4.18.
|
492
|
+
jgem install glimmer-dsl-swt -v 4.18.4.0
|
464
493
|
|
465
494
|
|
466
495
|
```
|
@@ -480,7 +509,7 @@ Note: if you're using activerecord or activesupport, keep in mind that Glimmer u
|
|
480
509
|
|
481
510
|
Add the following to `Gemfile`:
|
482
511
|
```
|
483
|
-
gem 'glimmer-dsl-swt', '~> 4.18.
|
512
|
+
gem 'glimmer-dsl-swt', '~> 4.18.4.0
|
484
513
|
'
|
485
514
|
```
|
486
515
|
|
@@ -539,7 +568,7 @@ bin/glimmer samples
|
|
539
568
|
Below are the full usage instructions that come up when running `glimmer` without args.
|
540
569
|
|
541
570
|
```
|
542
|
-
Glimmer (JRuby Desktop Development GUI Framework) - JRuby Gem: glimmer-dsl-swt v4.18.
|
571
|
+
Glimmer (JRuby Desktop Development GUI Framework) - JRuby Gem: glimmer-dsl-swt v4.18.4.0
|
543
572
|
|
544
573
|
|
545
574
|
|
@@ -815,7 +844,7 @@ glimmer run
|
|
815
844
|
|
816
845
|
#### Custom Shell
|
817
846
|
|
818
|
-
To scaffold a Glimmer custom shell (full window view) for an existing Glimmer app, run the following command:
|
847
|
+
To scaffold a Glimmer [custom shell](#custom-shells) (full window view) for an existing Glimmer app, run the following command:
|
819
848
|
|
820
849
|
```
|
821
850
|
glimmer scaffold:customshell[name]
|
@@ -829,7 +858,7 @@ glimmer scaffold:cs[name]
|
|
829
858
|
|
830
859
|
#### Custom Widget
|
831
860
|
|
832
|
-
To scaffold a Glimmer custom widget (part of a view) for an existing Glimmer app, run the following command:
|
861
|
+
To scaffold a Glimmer [custom widget](#custom-widgets) (part of a view) for an existing Glimmer app, run the following command:
|
833
862
|
|
834
863
|
```
|
835
864
|
glimmer scaffold:customwidget[name]
|
@@ -843,7 +872,7 @@ glimmer scaffold:cw[name]
|
|
843
872
|
|
844
873
|
#### Custom Shell Gem
|
845
874
|
|
846
|
-
Custom shell gems are self-contained Glimmer apps as well as reusable custom shells.
|
875
|
+
Custom shell gems are self-contained Glimmer apps as well as reusable [custom shells](#custom-shells).
|
847
876
|
They have everything scaffolded Glimmer apps come with in addition to gem content like a [Juwelier](https://rubygems.org/gems/juwelier) Rakefile that can build gemspec and release gems.
|
848
877
|
Unlike scaffolded Glimmer apps, custom shell gem content lives under the `lib` directory (not `app`).
|
849
878
|
They can be packaged as both a native executable (e.g. Mac DMG/PKG/APP) and a Ruby gem.
|
@@ -878,7 +907,7 @@ Examples:
|
|
878
907
|
|
879
908
|
#### Custom Widget Gem
|
880
909
|
|
881
|
-
To scaffold a Glimmer custom widget gem (part of a view distributed as a Ruby gem), run the following command:
|
910
|
+
To scaffold a Glimmer [custom widget](#custom-widgets) gem (part of a view distributed as a Ruby gem), run the following command:
|
882
911
|
|
883
912
|
```
|
884
913
|
glimmer scaffold:gem:customwidget[name,namespace]
|
@@ -904,7 +933,7 @@ Examples:
|
|
904
933
|
|
905
934
|
### Gem Listing
|
906
935
|
|
907
|
-
The `glimmer` command comes with tasks for listing Glimmer related gems to make it easy to find Glimmer Custom Shells, Custom Widgets, and DSLs published by others in the Glimmer community on [rubygems.org](http://www.rubygems.org).
|
936
|
+
The `glimmer` command comes with tasks for listing Glimmer related gems to make it easy to find Glimmer [Custom Shells](#custom-shells), [Custom Widgets](#custom-widgets), and DSLs published by others in the Glimmer community on [rubygems.org](http://www.rubygems.org).
|
908
937
|
|
909
938
|
#### Listing Custom Shell Gems
|
910
939
|
|
@@ -1020,7 +1049,7 @@ Output:
|
|
1020
1049
|
|
1021
1050
|
Css glimmer-dsl-css 1.1.0 AndyMaleh Glimmer DSL for CSS
|
1022
1051
|
Opal glimmer-dsl-opal 0.10.2 AndyMaleh Glimmer DSL for Opal
|
1023
|
-
Swt glimmer-dsl-swt 4.18.
|
1052
|
+
Swt glimmer-dsl-swt 4.18.4.0
|
1024
1053
|
|
1025
1054
|
AndyMaleh Glimmer DSL for SWT
|
1026
1055
|
Tk glimmer-dsl-tk 0.0.6 AndyMaleh Glimmer DSL for Tk
|
@@ -1098,9 +1127,12 @@ bin/girb
|
|
1098
1127
|
|
1099
1128
|
Watch out for hands-on examples in this README indicated by "you may copy/paste in [`girb`](#girb-glimmer-irb-command)"
|
1100
1129
|
|
1101
|
-
Keep in mind that all samples live under [https://github.com/AndyObtiva/glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt)
|
1130
|
+
Keep in mind that all samples live under [https://github.com/AndyObtiva/glimmer-dsl-swt/samples](https://github.com/AndyObtiva/glimmer-dsl-swt/samples)
|
1102
1131
|
|
1103
|
-
If you need a more GUI interactive option to experiement with Glimmer GUI DSL Syntax, you may try
|
1132
|
+
If you need a more GUI interactive option to experiement with Glimmer GUI DSL Syntax, you may try:
|
1133
|
+
- [Glimmer Meta-Sample (The Sample of Samples)](#samples): allows launching Glimmer samples and viewing/editing code to learn/experiment too.
|
1134
|
+
- ["Ugliest Editor Ever"](https://github.com/AndyObtiva/glimmer-cs-gladiator)
|
1135
|
+
- Just build your own GUI editor using the [Glimmer DSL for SWT Ruby Gem](https://rubygems.org/gems/glimmer-dsl-swt).
|
1104
1136
|
|
1105
1137
|
## Glimmer GUI DSL Syntax
|
1106
1138
|
|
@@ -1859,6 +1891,79 @@ Glimmer provides smart defaults for the `scrolled_composite` widget by:
|
|
1859
1891
|
- Automatically setting the :h_scroll and :v_scroll SWT styles (can be set manually if only one of either :h_scroll or :v_scroll is desired )
|
1860
1892
|
- Automatically setting the expand horizontal and expand vertical SWT properties to `true`
|
1861
1893
|
|
1894
|
+
#### Sash Form Widget
|
1895
|
+
|
1896
|
+
`sash_form` is an SWT built-in custom widget that provides a resizable sash that splits a window area into two or more panes.
|
1897
|
+
|
1898
|
+
It can be customized with the `weights` attribute by setting initial weights to size the panes at first display.
|
1899
|
+
|
1900
|
+
One noteworthy thing about the Glimmer implementation is that, unlike behavior in SWT, it allows declaring `weights` before the content of the `sash_form`, thus providing more natural and convenient syntax (Glimmer automatically takes care of sending that declaration to SWT at the end of declaring `sash_form` content as per the SWT requirements)
|
1901
|
+
|
1902
|
+
Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
1903
|
+
|
1904
|
+
```ruby
|
1905
|
+
shell {
|
1906
|
+
text 'Sash Form Example'
|
1907
|
+
sash_form {
|
1908
|
+
label {
|
1909
|
+
text '(resize >>)'
|
1910
|
+
background :dark_green
|
1911
|
+
foreground :white
|
1912
|
+
font height: 20
|
1913
|
+
}
|
1914
|
+
label {
|
1915
|
+
text '(<< resize)'
|
1916
|
+
background :red
|
1917
|
+
foreground :white
|
1918
|
+
font height: 20
|
1919
|
+
}
|
1920
|
+
weights 1, 2
|
1921
|
+
}
|
1922
|
+
}.open
|
1923
|
+
```
|
1924
|
+
|
1925
|
+
You may check out a more full-fledged example in [Hello, Sash Form!](#hello-sash-form)
|
1926
|
+
|
1927
|
+
![Hello Sash Form](images/glimmer-hello-sash-form.png)
|
1928
|
+
|
1929
|
+
#### Browser Widget
|
1930
|
+
|
1931
|
+
![Hello Browser](images/glimmer-hello-browser.png)
|
1932
|
+
|
1933
|
+
Glimmer supports the SWT Browser widget, which can load URLs or render HTML. It can even be instrumented with JavaScript when needed (though highly discouraged since it defeats the purpose of using Ruby except in very rare cases like leveraging a pre-existing web codebase in a desktop app).
|
1934
|
+
|
1935
|
+
Example loading a URL (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
1936
|
+
|
1937
|
+
```ruby
|
1938
|
+
shell {
|
1939
|
+
minimum_size 1024, 860
|
1940
|
+
browser {
|
1941
|
+
url 'http://brightonresort.com/about'
|
1942
|
+
}
|
1943
|
+
}.open
|
1944
|
+
```
|
1945
|
+
|
1946
|
+
Example rendering HTML with JavaScript on document ready (you may copy/paste in [`girb`](#girb-glimmer-irb-command) provided you install and require [glimmer-dsl-xml gem](https://github.com/AndyObtiva/glimmer-dsl-xml)):
|
1947
|
+
|
1948
|
+
```ruby
|
1949
|
+
shell {
|
1950
|
+
minimum_size 130, 130
|
1951
|
+
@browser = browser {
|
1952
|
+
text html {
|
1953
|
+
head {
|
1954
|
+
meta(name: "viewport", content: "width=device-width, initial-scale=2.0")
|
1955
|
+
}
|
1956
|
+
body {
|
1957
|
+
h1 { "Hello, World!" }
|
1958
|
+
}
|
1959
|
+
}
|
1960
|
+
on_completed { # on load of the page execute this JavaScript
|
1961
|
+
@browser.swt_widget.execute("alert('Hello, World!');")
|
1962
|
+
}
|
1963
|
+
}
|
1964
|
+
}.open
|
1965
|
+
```
|
1966
|
+
|
1862
1967
|
### Widget Styles
|
1863
1968
|
|
1864
1969
|
SWT widgets receive `SWT` styles in their constructor as per this guide:
|
@@ -2321,7 +2426,8 @@ Shape keywords and their args (including defaults) are listed below (they basica
|
|
2321
2426
|
- `rectangle(x, y, width, height, vertical = true, fill: true, gradient: true)` gradient rectangle, which is always filled, and takes an optional extra argument to specify true for vertical gradient (default) and false for horizontal gradient
|
2322
2427
|
- `text(string, x, y, flags = nil)` text with optional flags (flag format is `swt(comma_separated_flags)` where flags can be :draw_delimiter (i.e. new lines), :draw_tab, :draw_mnemonic, and :draw_transparent as explained in [GC API](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/GC.html))
|
2323
2428
|
|
2324
|
-
Shape keywords that can be filled with color can take an keyword argument `fill: true
|
2429
|
+
Shape keywords that can be filled with color can take an keyword argument `fill: true`. Defaults to false when not specified unless background is set with no foreground (or foreground is set with no background), in which case a smart default is applied.
|
2430
|
+
Smart defaults can be applied to automatically infer `gradient: true` (rectangle with both foreground and background) and `round: true` (rectangle with more than 4 args, the extra args are numeric) as well.
|
2325
2431
|
|
2326
2432
|
Optionally, a shape keyword takes a block that can set any attributes from [org.eclipse.swt.graphics.GC](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/GC.html) (methods starting with `set`), which enable setting the `background` for filling and `foreground` for drawing.
|
2327
2433
|
|
@@ -2345,6 +2451,8 @@ Here is a list of supported attributes nestable within a block under shapes:
|
|
2345
2451
|
- `text_anti_alias` enables text antialiasing (SWT style value of `:default`, `:off`, `:on` whereby `:default` applies OS default, which varies per OS)
|
2346
2452
|
- `transform` sets transform object using [Canvas Transform DSL](#canvas-transform-dsl) syntax
|
2347
2453
|
|
2454
|
+
Keep in mind that ordering of shapes matters as it is followed in painting. For example, it is recommended you paint filled shapes first and then drawn ones.
|
2455
|
+
|
2348
2456
|
Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
2349
2457
|
|
2350
2458
|
```ruby
|
@@ -2359,10 +2467,10 @@ shell {
|
|
2359
2467
|
|
2360
2468
|
canvas {
|
2361
2469
|
background :dark_yellow
|
2362
|
-
rectangle(0, 0, 220, 400
|
2470
|
+
rectangle(0, 0, 220, 400) {
|
2363
2471
|
background :dark_red
|
2364
2472
|
}
|
2365
|
-
rectangle(50, 20, 300, 150, 30, 50, round: true
|
2473
|
+
rectangle(50, 20, 300, 150, 30, 50, round: true) {
|
2366
2474
|
background :yellow
|
2367
2475
|
}
|
2368
2476
|
rectangle(150, 200, 100, 70, true, gradient: true) {
|
@@ -2432,6 +2540,103 @@ In any case, if there is anything missing you would like added to the Glimmer Sh
|
|
2432
2540
|
|
2433
2541
|
Keep in mind that the Shape DSL can be used inside any widget, not just `canvas`. Unlike shapes on a `canvas`, which are standalone graphics, when included in a widget, which already has its own look and feel, shapes are used as a decorative add-on that complements its look by getting painted on top of it. For example, shapes were used to decorate `composite` blocks in the [Tetris](#tetris) sample to have a more bevel look. In summary, Shapes can be used in a hybrid approach (shapes inside a widget), not just standalone in a `canvas`.
|
2434
2542
|
|
2543
|
+
#### Shapes inside an Image
|
2544
|
+
|
2545
|
+
You can build an image using the Canvas Shape DSL (including setting the icon of the application).
|
2546
|
+
|
2547
|
+
Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
2548
|
+
|
2549
|
+
```
|
2550
|
+
include Glimmer
|
2551
|
+
|
2552
|
+
shell {
|
2553
|
+
text 'Image Shape DSL Example'
|
2554
|
+
label {
|
2555
|
+
bevel_constant = 20
|
2556
|
+
icon_block_size = 64
|
2557
|
+
icon_bevel_size = icon_block_size.to_f / 25.to_f
|
2558
|
+
icon_bevel_pixel_size = 0.16*icon_block_size.to_f
|
2559
|
+
icon_size = 8
|
2560
|
+
icon_pixel_size = icon_block_size * icon_size
|
2561
|
+
image(icon_pixel_size, icon_pixel_size) {
|
2562
|
+
icon_size.times { |row|
|
2563
|
+
icon_size.times { |column|
|
2564
|
+
colored = row >= 1 && column.between?(1, 6)
|
2565
|
+
color = colored ? color([:white, :red, :blue, :green, :yellow, :magenta, :cyan, :dark_blue].sample) : color(:white)
|
2566
|
+
x = column * icon_block_size
|
2567
|
+
y = row * icon_block_size
|
2568
|
+
rectangle(x, y, icon_block_size, icon_block_size) {
|
2569
|
+
background color
|
2570
|
+
}
|
2571
|
+
polygon(x, y, x + icon_block_size, y, x + icon_block_size - icon_bevel_pixel_size, y + icon_bevel_pixel_size, x + icon_bevel_pixel_size, y + icon_bevel_pixel_size) {
|
2572
|
+
background rgb(color.red + 4*bevel_constant, color.green + 4*bevel_constant, color.blue + 4*bevel_constant)
|
2573
|
+
}
|
2574
|
+
polygon(x + icon_block_size, y, x + icon_block_size - icon_bevel_pixel_size, y + icon_bevel_pixel_size, x + icon_block_size - icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_block_size, y + icon_block_size) {
|
2575
|
+
background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
|
2576
|
+
}
|
2577
|
+
polygon(x + icon_block_size, y + icon_block_size, x, y + icon_block_size, x + icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_block_size - icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size) {
|
2578
|
+
background rgb(color.red - 2*bevel_constant, color.green - 2*bevel_constant, color.blue - 2*bevel_constant)
|
2579
|
+
}
|
2580
|
+
polygon(x, y, x, y + icon_block_size, x + icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_bevel_pixel_size, y + icon_bevel_pixel_size) {
|
2581
|
+
background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
|
2582
|
+
}
|
2583
|
+
}
|
2584
|
+
}
|
2585
|
+
}
|
2586
|
+
}
|
2587
|
+
}.open
|
2588
|
+
```
|
2589
|
+
|
2590
|
+
![Image Shape DSL](images/glimmer-example-image-shape-dsl.png)
|
2591
|
+
|
2592
|
+
Example setting the icon of the application (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
2593
|
+
|
2594
|
+
```
|
2595
|
+
include Glimmer
|
2596
|
+
|
2597
|
+
shell {
|
2598
|
+
text 'Image Shape DSL Example'
|
2599
|
+
label {
|
2600
|
+
text 'Image Shape DSL Example'
|
2601
|
+
font height: 30
|
2602
|
+
}
|
2603
|
+
bevel_constant = 20
|
2604
|
+
icon_block_size = 64
|
2605
|
+
icon_bevel_size = icon_block_size.to_f / 25.to_f
|
2606
|
+
icon_bevel_pixel_size = 0.16*icon_block_size.to_f
|
2607
|
+
icon_size = 8
|
2608
|
+
icon_pixel_size = icon_block_size * icon_size
|
2609
|
+
image(icon_pixel_size, icon_pixel_size) {
|
2610
|
+
icon_size.times { |row|
|
2611
|
+
icon_size.times { |column|
|
2612
|
+
colored = row >= 1 && column.between?(1, 6)
|
2613
|
+
color = colored ? color([:white, :red, :blue, :green, :yellow, :magenta, :cyan, :dark_blue].sample) : color(:white)
|
2614
|
+
x = column * icon_block_size
|
2615
|
+
y = row * icon_block_size
|
2616
|
+
rectangle(x, y, icon_block_size, icon_block_size) {
|
2617
|
+
background color
|
2618
|
+
}
|
2619
|
+
polygon(x, y, x + icon_block_size, y, x + icon_block_size - icon_bevel_pixel_size, y + icon_bevel_pixel_size, x + icon_bevel_pixel_size, y + icon_bevel_pixel_size) {
|
2620
|
+
background rgb(color.red + 4*bevel_constant, color.green + 4*bevel_constant, color.blue + 4*bevel_constant)
|
2621
|
+
}
|
2622
|
+
polygon(x + icon_block_size, y, x + icon_block_size - icon_bevel_pixel_size, y + icon_bevel_pixel_size, x + icon_block_size - icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_block_size, y + icon_block_size) {
|
2623
|
+
background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
|
2624
|
+
}
|
2625
|
+
polygon(x + icon_block_size, y + icon_block_size, x, y + icon_block_size, x + icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_block_size - icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size) {
|
2626
|
+
background rgb(color.red - 2*bevel_constant, color.green - 2*bevel_constant, color.blue - 2*bevel_constant)
|
2627
|
+
}
|
2628
|
+
polygon(x, y, x, y + icon_block_size, x + icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_bevel_pixel_size, y + icon_bevel_pixel_size) {
|
2629
|
+
background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
|
2630
|
+
}
|
2631
|
+
}
|
2632
|
+
}
|
2633
|
+
}
|
2634
|
+
}.open
|
2635
|
+
```
|
2636
|
+
|
2637
|
+
![Image Shape DSL](images/glimmer-example-image-shape-dsl-app-switcher-icon.png)
|
2638
|
+
|
2639
|
+
|
2435
2640
|
### Canvas Transform DSL
|
2436
2641
|
|
2437
2642
|
The transform DSL builds [org.eclipse.swt.graphics.Transform](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/Transform.html) objects with a nice declarative syntax.
|
@@ -2537,7 +2742,7 @@ shell {
|
|
2537
2742
|
|
2538
2743
|
frame { |index|
|
2539
2744
|
background rgb(index%100, index%100 + 100, index%55 + 200)
|
2540
|
-
rectangle(index, index, 20, 20
|
2745
|
+
rectangle(index, index, 20, 20) {
|
2541
2746
|
background :red
|
2542
2747
|
}
|
2543
2748
|
}
|
@@ -2576,6 +2781,12 @@ Learn more at the [Hello, Canvas Animation! Sample](#hello-canvas-animation).
|
|
2576
2781
|
|
2577
2782
|
If there is anything missing you would like added to the Glimmer Animation DSL that you saw available in the SWT APIs, you may [report an issue](https://github.com/AndyObtiva/glimmer-dsl-swt/issues) or implement yourself and [contribute](#contributing) via a Pull Request.
|
2578
2783
|
|
2784
|
+
#### Animation via Data-Binding
|
2785
|
+
|
2786
|
+
Animation could be alternatively implemented without the `animation` keyword through a loop that invokes model methods inside `sync_exec {}` (or `async_exec {}`), which indirectly cause updates to the GUI via data-binding.
|
2787
|
+
|
2788
|
+
The [Glimmer Tetris](#glimmer-tetris) sample provides a good example of that.
|
2789
|
+
|
2579
2790
|
### Data-Binding
|
2580
2791
|
|
2581
2792
|
Data-binding is done with `bind` command following widget property to bind and taking model and bindable attribute as arguments.
|
@@ -2989,6 +3200,7 @@ Here is an explanation of the example above:
|
|
2989
3200
|
- Task Start Date table column has a custom sort comparator block
|
2990
3201
|
- Additional (secondary) sort properties are applied when sorting by Task, Project, or Duration in the order specified
|
2991
3202
|
|
3203
|
+
`bind(model, :property, read_only_sort: true)` could be used with items to make sorting not propagate sorting changes to model.
|
2992
3204
|
|
2993
3205
|
#### Tree
|
2994
3206
|
|
@@ -3392,7 +3604,7 @@ shell {
|
|
3392
3604
|
|
3393
3605
|
Notice how `:no_focus` was the `swt_style` value, followed by the `options` hash `{orientation: :horizontal, bg_color: :white}`, and finally the `content` block containing the label with `'SANDWICH CONTENT'`
|
3394
3606
|
|
3395
|
-
####
|
3607
|
+
#### Custom Widget Gotchas
|
3396
3608
|
|
3397
3609
|
Beware of defining a custom attribute that is a common SWT widget property name.
|
3398
3610
|
For example, if you define `text=` and `text` methods to accept a custom text and then later you write this body:
|
@@ -3422,6 +3634,314 @@ body {
|
|
3422
3634
|
|
3423
3635
|
The `text` method invoked in the custom widget body will call the one you defined above it. To avoid this gotcha, simply name the text property above something else, like `custom_text`.
|
3424
3636
|
|
3637
|
+
#### Built-In Custom Widgets
|
3638
|
+
|
3639
|
+
##### Checkbox Group Custom Widget
|
3640
|
+
|
3641
|
+
`checkbox_group` (or alias `check_group`) is a Glimmer built-in custom widget that displays a list of `checkbox` buttons (`button(:check)`) based on its `items` property.
|
3642
|
+
|
3643
|
+
`checkbox_group` consists of a root `composite` (with `grid_layout 1, false` by default) that holds nested `checkbox` (`button(:check)`) widgets.
|
3644
|
+
|
3645
|
+
The `selection` property determines which `checkbox` buttons are checked. It expects an `Array` of `String` objects
|
3646
|
+
The `selection_indices` property determines which `checkbox` button indices are checked. It expects an `Array` of index `Integer` objects that are zero-based.
|
3647
|
+
The `checkboxes` property returns the list of nested `checkbox` widgets.
|
3648
|
+
|
3649
|
+
When data-binding `selection`, the model property should have a matching property with `_options` suffix (e.g. `activities_options` for `activities`) to provide an `Array` of `String` objects for `checkbox` buttons.
|
3650
|
+
|
3651
|
+
You may see an example at the [Hello, Checkbox Group!](#hello-checkbox-group) sample.
|
3652
|
+
|
3653
|
+
![Hello Checkbox Group](images/glimmer-hello-checkbox-group.png)
|
3654
|
+
|
3655
|
+
##### Radio Group Custom Widget
|
3656
|
+
|
3657
|
+
`radio_group` is a Glimmer built-in custom widget that displays a list of `radio` buttons (`button(:radio)`) based on its `items` property, which expects an `Array` of `String` objects.
|
3658
|
+
|
3659
|
+
`radio_group` consists of a root `composite` (with `grid_layout 1, false` by default) that holds nested `radio` widgets.
|
3660
|
+
|
3661
|
+
The `selection` property determines which `radio` button is selected. It expects a `String`
|
3662
|
+
The `selection_index` property determines which `radio` button index is selected. It expects an index integer that is zero-based.
|
3663
|
+
The `radios` property returns the list of nested `radio` widgets.
|
3664
|
+
|
3665
|
+
When data-binding `selection`, the model property should have a matching property with `_options` suffix (e.g. `country_options` for `country`) to provide text for `radio` buttons.
|
3666
|
+
|
3667
|
+
This custom widget is used in the [Glimmer Meta-Sample (The Sample of Samples)](#samples):
|
3668
|
+
|
3669
|
+
![Glimmer Meta-Sample](images/glimmer-meta-sample.png)
|
3670
|
+
|
3671
|
+
Glimmer Meta-Sample Code Example:
|
3672
|
+
|
3673
|
+
```ruby
|
3674
|
+
# ...
|
3675
|
+
radio_group { |radio_group_proxy|
|
3676
|
+
row_layout(:vertical) {
|
3677
|
+
fill true
|
3678
|
+
}
|
3679
|
+
selection bind(sample_directory, :selected_sample_name)
|
3680
|
+
font height: 24
|
3681
|
+
}
|
3682
|
+
|
3683
|
+
# ...
|
3684
|
+
```
|
3685
|
+
|
3686
|
+
You may see another example at the [Hello, Radio Group!](#hello-radio-group) sample.
|
3687
|
+
|
3688
|
+
##### Code Text Custom Widget
|
3689
|
+
|
3690
|
+
`code_text` is a Glimmer built-in custom widget that displays syntax highlighted Ruby code in a customized SWT [StyledText](https://help.eclipse.org/2020-09/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/custom/StyledText.html) widget.
|
3691
|
+
|
3692
|
+
It is used in the [Glimmer Meta-Sample (The Sample of Samples)](#samples):
|
3693
|
+
|
3694
|
+
![Glimmer Meta-Sample](images/glimmer-meta-sample.png)
|
3695
|
+
|
3696
|
+
Glimmer Meta-Sample Code Example:
|
3697
|
+
|
3698
|
+
```ruby
|
3699
|
+
# ...
|
3700
|
+
@code_text = code_text {
|
3701
|
+
text bind(SampleDirectory, 'selected_sample.code', read_only: true)
|
3702
|
+
editable bind(SampleDirectory, 'selected_sample.editable')
|
3703
|
+
}
|
3704
|
+
# ...
|
3705
|
+
```
|
3706
|
+
|
3707
|
+
To use, simply use `code_text` in place of the `text` or `styled_text` widget. If you set its `text` value to Ruby code, it automatically styles it with syntax highlighting.
|
3708
|
+
|
3709
|
+
###### Options
|
3710
|
+
|
3711
|
+
**lines**
|
3712
|
+
(default: false)
|
3713
|
+
|
3714
|
+
Shows line numbers when set to true.
|
3715
|
+
|
3716
|
+
If set to a hash like `{width: 4}`, it sets the width of the line numbers lane in character count (default: 4)
|
3717
|
+
|
3718
|
+
**theme**
|
3719
|
+
(default: 'glimmer')
|
3720
|
+
|
3721
|
+
Changes syntax color highlighting theme. Can be one of the following:
|
3722
|
+
- glimmer
|
3723
|
+
- github
|
3724
|
+
- pastie
|
3725
|
+
|
3726
|
+
**language**
|
3727
|
+
(default: `'ruby'`)
|
3728
|
+
|
3729
|
+
Sets the code language, which can be one of the following [rouge gem](#https://rubygems.org/gems/rouge) supported languages:
|
3730
|
+
- abap
|
3731
|
+
- actionscript
|
3732
|
+
- ada
|
3733
|
+
- apache
|
3734
|
+
- apex
|
3735
|
+
- apiblueprint
|
3736
|
+
- apple_script
|
3737
|
+
- armasm
|
3738
|
+
- augeas
|
3739
|
+
- awk
|
3740
|
+
- batchfile
|
3741
|
+
- bbcbasic
|
3742
|
+
- bibtex
|
3743
|
+
- biml
|
3744
|
+
- bpf
|
3745
|
+
- brainfuck
|
3746
|
+
- brightscript
|
3747
|
+
- bsl
|
3748
|
+
- c
|
3749
|
+
- ceylon
|
3750
|
+
- cfscript
|
3751
|
+
- clean
|
3752
|
+
- clojure
|
3753
|
+
- cmake
|
3754
|
+
- cmhg
|
3755
|
+
- coffeescript
|
3756
|
+
- common_lisp
|
3757
|
+
- conf
|
3758
|
+
- console
|
3759
|
+
- coq
|
3760
|
+
- cpp
|
3761
|
+
- crystal
|
3762
|
+
- csharp
|
3763
|
+
- css
|
3764
|
+
- csvs
|
3765
|
+
- cuda
|
3766
|
+
- cypher
|
3767
|
+
- cython
|
3768
|
+
- d
|
3769
|
+
- dart
|
3770
|
+
- datastudio
|
3771
|
+
- diff
|
3772
|
+
- digdag
|
3773
|
+
- docker
|
3774
|
+
- dot
|
3775
|
+
- ecl
|
3776
|
+
- eex
|
3777
|
+
- eiffel
|
3778
|
+
- elixir
|
3779
|
+
- elm
|
3780
|
+
- email
|
3781
|
+
- epp
|
3782
|
+
- erb
|
3783
|
+
- erlang
|
3784
|
+
- escape
|
3785
|
+
- factor
|
3786
|
+
- fortran
|
3787
|
+
- freefem
|
3788
|
+
- fsharp
|
3789
|
+
- gdscript
|
3790
|
+
- ghc_cmm
|
3791
|
+
- ghc_core
|
3792
|
+
- gherkin
|
3793
|
+
- glsl
|
3794
|
+
- go
|
3795
|
+
- gradle
|
3796
|
+
- graphql
|
3797
|
+
- groovy
|
3798
|
+
- hack
|
3799
|
+
- haml
|
3800
|
+
- handlebars
|
3801
|
+
- haskell
|
3802
|
+
- haxe
|
3803
|
+
- hcl
|
3804
|
+
- hlsl
|
3805
|
+
- hocon
|
3806
|
+
- hql
|
3807
|
+
- html
|
3808
|
+
- http
|
3809
|
+
- hylang
|
3810
|
+
- idlang
|
3811
|
+
- igorpro
|
3812
|
+
- ini
|
3813
|
+
- io
|
3814
|
+
- irb
|
3815
|
+
- isbl
|
3816
|
+
- j
|
3817
|
+
- janet
|
3818
|
+
- java
|
3819
|
+
- javascript
|
3820
|
+
- jinja
|
3821
|
+
- jsl
|
3822
|
+
- json
|
3823
|
+
- json_doc
|
3824
|
+
- jsonnet
|
3825
|
+
- jsp
|
3826
|
+
- jsx
|
3827
|
+
- julia
|
3828
|
+
- kotlin
|
3829
|
+
- lasso
|
3830
|
+
- liquid
|
3831
|
+
- literate_coffeescript
|
3832
|
+
- literate_haskell
|
3833
|
+
- livescript
|
3834
|
+
- llvm
|
3835
|
+
- lua
|
3836
|
+
- lustre
|
3837
|
+
- lutin
|
3838
|
+
- m68k
|
3839
|
+
- magik
|
3840
|
+
- make
|
3841
|
+
- markdown
|
3842
|
+
- mason
|
3843
|
+
- mathematica
|
3844
|
+
- matlab
|
3845
|
+
- minizinc
|
3846
|
+
- moonscript
|
3847
|
+
- mosel
|
3848
|
+
- msgtrans
|
3849
|
+
- mxml
|
3850
|
+
- nasm
|
3851
|
+
- nesasm
|
3852
|
+
- nginx
|
3853
|
+
- nim
|
3854
|
+
- nix
|
3855
|
+
- objective_c
|
3856
|
+
- objective_cpp
|
3857
|
+
- ocaml
|
3858
|
+
- ocl
|
3859
|
+
- openedge
|
3860
|
+
- opentype_feature_file
|
3861
|
+
- pascal
|
3862
|
+
- perl
|
3863
|
+
- php
|
3864
|
+
- plain_text
|
3865
|
+
- plist
|
3866
|
+
- pony
|
3867
|
+
- postscript
|
3868
|
+
- powershell
|
3869
|
+
- praat
|
3870
|
+
- prolog
|
3871
|
+
- prometheus
|
3872
|
+
- properties
|
3873
|
+
- protobuf
|
3874
|
+
- puppet
|
3875
|
+
- python
|
3876
|
+
- q
|
3877
|
+
- qml
|
3878
|
+
- r
|
3879
|
+
- racket
|
3880
|
+
- reasonml
|
3881
|
+
- rego
|
3882
|
+
- rescript
|
3883
|
+
- robot_framework
|
3884
|
+
- ruby
|
3885
|
+
- rust
|
3886
|
+
- sas
|
3887
|
+
- sass
|
3888
|
+
- scala
|
3889
|
+
- scheme
|
3890
|
+
- scss
|
3891
|
+
- sed
|
3892
|
+
- shell
|
3893
|
+
- sieve
|
3894
|
+
- slice
|
3895
|
+
- slim
|
3896
|
+
- smalltalk
|
3897
|
+
- smarty
|
3898
|
+
- sml
|
3899
|
+
- solidity
|
3900
|
+
- sparql
|
3901
|
+
- sqf
|
3902
|
+
- sql
|
3903
|
+
- ssh
|
3904
|
+
- supercollider
|
3905
|
+
- swift
|
3906
|
+
- systemd
|
3907
|
+
- tap
|
3908
|
+
- tcl
|
3909
|
+
- terraform
|
3910
|
+
- tex
|
3911
|
+
- toml
|
3912
|
+
- tsx
|
3913
|
+
- ttcn3
|
3914
|
+
- tulip
|
3915
|
+
- turtle
|
3916
|
+
- twig
|
3917
|
+
- typescript
|
3918
|
+
- vala
|
3919
|
+
- varnish
|
3920
|
+
- vb
|
3921
|
+
- velocity
|
3922
|
+
- verilog
|
3923
|
+
- vhdl
|
3924
|
+
- viml
|
3925
|
+
- vue
|
3926
|
+
- wollok
|
3927
|
+
- xml
|
3928
|
+
- xojo
|
3929
|
+
- xpath
|
3930
|
+
- xquery
|
3931
|
+
- yaml
|
3932
|
+
- yang
|
3933
|
+
- zig
|
3934
|
+
|
3935
|
+
Learn more at [Hello, Code Text!](#hello-code-text)
|
3936
|
+
|
3937
|
+
##### Video Custom Custom Widget
|
3938
|
+
|
3939
|
+
[![Video Widget](images/glimmer-video-widget.png)](https://github.com/AndyObtiva/glimmer-cw-video)
|
3940
|
+
|
3941
|
+
Glimmer supports a [video custom widget](https://github.com/AndyObtiva/glimmer-cw-video) not in SWT, which was originally a Glimmer built-in custom widget, but has been later extracted into its own [Ruby gem](https://rubygems.org/gems/glimmer-cw-video).
|
3942
|
+
|
3943
|
+
Simply install the [glimmer-cw-video](https://rubygems.org/gems/glimmer-cw-video) gem.
|
3944
|
+
|
3425
3945
|
#### Custom Widget Final Notes
|
3426
3946
|
|
3427
3947
|
This [Eclipse guide](https://www.eclipse.org/articles/Article-Writing%20Your%20Own%20Widget/Writing%20Your%20Own%20Widget.htm) for how to write custom SWT widgets is also applicable to Glimmer Custom Widgets written in Ruby. I recommend reading it:
|
@@ -3496,6 +4016,8 @@ shell { |app_shell|
|
|
3496
4016
|
}.open
|
3497
4017
|
```
|
3498
4018
|
|
4019
|
+
If you use a Custom Shell as the top-level app shell, you may invoke the class method `::launch` instead to avoid building an app class yourself or including Glimmer into the top-level namespace (e.g. `Tetris.launch` instead of `include Glimmer; tetris.open`)
|
4020
|
+
|
3499
4021
|
You may check out [Hello, Custom Shell!](#hello-custom-shell) for another example.
|
3500
4022
|
|
3501
4023
|
### Drag and Drop
|
@@ -3811,157 +4333,6 @@ You may run `glimmer` with the `--profile.graph` instead for a more detailed out
|
|
3811
4333
|
|
3812
4334
|
Learn more at the [JRuby Performance Profile WIKI page](https://github.com/jruby/jruby/wiki/Profiling-JRuby).
|
3813
4335
|
|
3814
|
-
#### Checkbox Group Widget
|
3815
|
-
|
3816
|
-
`checkbox_group` (or alias `check_group`) is a Glimmer built-in custom widget that displays a list of `checkbox` buttons (`button(:check)`) based on its `items` property.
|
3817
|
-
|
3818
|
-
`checkbox_group` consists of a root `composite` (with `grid_layout 1, false` by default) that holds nested `checkbox` (`button(:check)`) widgets.
|
3819
|
-
|
3820
|
-
The `selection` property determines which `checkbox` buttons are checked. It expects an `Array` of `String` objects
|
3821
|
-
The `selection_indices` property determines which `checkbox` button indices are checked. It expects an `Array` of index `Integer` objects that are zero-based.
|
3822
|
-
The `checkboxes` property returns the list of nested `checkbox` widgets.
|
3823
|
-
|
3824
|
-
When data-binding `selection`, the model property should have a matching property with `_options` suffix (e.g. `activities_options` for `activities`) to provide an `Array` of `String` objects for `checkbox` buttons.
|
3825
|
-
|
3826
|
-
You may see an example at the [Hello, Checkbox Group!](#hello-checkbox-group) sample.
|
3827
|
-
|
3828
|
-
![Hello Checkbox Group](images/glimmer-hello-checkbox-group.png)
|
3829
|
-
|
3830
|
-
#### Radio Group Widget
|
3831
|
-
|
3832
|
-
`radio_group` is a Glimmer built-in custom widget that displays a list of `radio` buttons (`button(:radio)`) based on its `items` property, which expects an `Array` of `String` objects.
|
3833
|
-
|
3834
|
-
`radio_group` consists of a root `composite` (with `grid_layout 1, false` by default) that holds nested `radio` widgets.
|
3835
|
-
|
3836
|
-
The `selection` property determines which `radio` button is selected. It expects a `String`
|
3837
|
-
The `selection_index` property determines which `radio` button index is selected. It expects an index integer that is zero-based.
|
3838
|
-
The `radios` property returns the list of nested `radio` widgets.
|
3839
|
-
|
3840
|
-
When data-binding `selection`, the model property should have a matching property with `_options` suffix (e.g. `country_options` for `country`) to provide text for `radio` buttons.
|
3841
|
-
|
3842
|
-
This custom widget is used in the [Glimmer Meta-Sample (The Sample of Samples)](#samples):
|
3843
|
-
|
3844
|
-
![Glimmer Meta-Sample](images/glimmer-meta-sample.png)
|
3845
|
-
|
3846
|
-
Glimmer Meta-Sample Code Example:
|
3847
|
-
|
3848
|
-
```ruby
|
3849
|
-
# ...
|
3850
|
-
radio_group { |radio_group_proxy|
|
3851
|
-
row_layout(:vertical) {
|
3852
|
-
fill true
|
3853
|
-
}
|
3854
|
-
selection bind(sample_directory, :selected_sample_name)
|
3855
|
-
font height: 24
|
3856
|
-
}
|
3857
|
-
|
3858
|
-
# ...
|
3859
|
-
```
|
3860
|
-
|
3861
|
-
You may see another example at the [Hello, Radio Group!](#hello-radio-group) sample.
|
3862
|
-
|
3863
|
-
#### Code Text Widget
|
3864
|
-
|
3865
|
-
`code_text` is a Glimmer built-in custom widget that displays syntax highlighted Ruby code in a customized SWT [StyledText](https://help.eclipse.org/2020-09/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/custom/StyledText.html) widget.
|
3866
|
-
|
3867
|
-
It is used in the [Glimmer Meta-Sample (The Sample of Samples)](#samples):
|
3868
|
-
|
3869
|
-
![Glimmer Meta-Sample](images/glimmer-meta-sample.png)
|
3870
|
-
|
3871
|
-
Glimmer Meta-Sample Code Example:
|
3872
|
-
|
3873
|
-
```ruby
|
3874
|
-
# ...
|
3875
|
-
@code_text = code_text {
|
3876
|
-
text bind(SampleDirectory, 'selected_sample.code', read_only: true)
|
3877
|
-
editable bind(SampleDirectory, 'selected_sample.editable')
|
3878
|
-
}
|
3879
|
-
# ...
|
3880
|
-
```
|
3881
|
-
|
3882
|
-
To use, simply use `code_text` in place of the `text` or `styled_text` widget. If you set its `text` value to Ruby code, it automatically styles it with syntax highlighting.
|
3883
|
-
|
3884
|
-
#### Video Widget
|
3885
|
-
|
3886
|
-
[![Video Widget](images/glimmer-video-widget.png)](https://github.com/AndyObtiva/glimmer-cw-video)
|
3887
|
-
|
3888
|
-
Glimmer supports a [video custom widget](https://github.com/AndyObtiva/glimmer-cw-video) not in SWT.
|
3889
|
-
|
3890
|
-
You may obtain via `glimmer-cw-video` gem.
|
3891
|
-
|
3892
|
-
#### Sash Form Widget
|
3893
|
-
|
3894
|
-
`sash_form` is an SWT built-in custom widget that provides a resizable sash that splits a window area into two or more panes.
|
3895
|
-
|
3896
|
-
It can be customized with the `weights` attribute by setting initial weights to size the panes at first display.
|
3897
|
-
|
3898
|
-
One noteworthy thing about the Glimmer implementation is that, unlike behavior in SWT, it allows declaring `weights` before the content of the `sash_form`, thus providing more natural and convenient syntax (Glimmer automatically takes care of sending that declaration to SWT at the end of declaring `sash_form` content as per the SWT requirements)
|
3899
|
-
|
3900
|
-
Example (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
3901
|
-
|
3902
|
-
```ruby
|
3903
|
-
shell {
|
3904
|
-
text 'Sash Form Example'
|
3905
|
-
sash_form {
|
3906
|
-
label {
|
3907
|
-
text '(resize >>)'
|
3908
|
-
background :dark_green
|
3909
|
-
foreground :white
|
3910
|
-
font height: 20
|
3911
|
-
}
|
3912
|
-
label {
|
3913
|
-
text '(<< resize)'
|
3914
|
-
background :red
|
3915
|
-
foreground :white
|
3916
|
-
font height: 20
|
3917
|
-
}
|
3918
|
-
weights 1, 2
|
3919
|
-
}
|
3920
|
-
}.open
|
3921
|
-
```
|
3922
|
-
|
3923
|
-
You may check out a more full-fledged example in [Hello, Sash Form!](#hello-sash-form)
|
3924
|
-
|
3925
|
-
![Hello Sash Form](images/glimmer-hello-sash-form.png)
|
3926
|
-
|
3927
|
-
#### Browser Widget
|
3928
|
-
|
3929
|
-
![Hello Browser](images/glimmer-hello-browser.png)
|
3930
|
-
|
3931
|
-
Glimmer supports the SWT Browser widget, which can load URLs or render HTML. It can even be instrumented with JavaScript when needed (though highly discouraged since it defeats the purpose of using Ruby except in very rare cases like leveraging a pre-existing web codebase in a desktop app).
|
3932
|
-
|
3933
|
-
Example loading a URL (you may copy/paste in [`girb`](#girb-glimmer-irb-command)):
|
3934
|
-
|
3935
|
-
```ruby
|
3936
|
-
shell {
|
3937
|
-
minimum_size 1024, 860
|
3938
|
-
browser {
|
3939
|
-
url 'http://brightonresort.com/about'
|
3940
|
-
}
|
3941
|
-
}.open
|
3942
|
-
```
|
3943
|
-
|
3944
|
-
Example rendering HTML with JavaScript on document ready (you may copy/paste in [`girb`](#girb-glimmer-irb-command) provided you install and require [glimmer-dsl-xml gem](https://github.com/AndyObtiva/glimmer-dsl-xml)):
|
3945
|
-
|
3946
|
-
```ruby
|
3947
|
-
shell {
|
3948
|
-
minimum_size 130, 130
|
3949
|
-
@browser = browser {
|
3950
|
-
text html {
|
3951
|
-
head {
|
3952
|
-
meta(name: "viewport", content: "width=device-width, initial-scale=2.0")
|
3953
|
-
}
|
3954
|
-
body {
|
3955
|
-
h1 { "Hello, World!" }
|
3956
|
-
}
|
3957
|
-
}
|
3958
|
-
on_completed { # on load of the page execute this JavaScript
|
3959
|
-
@browser.swt_widget.execute("alert('Hello, World!');")
|
3960
|
-
}
|
3961
|
-
}
|
3962
|
-
}.open
|
3963
|
-
```
|
3964
|
-
|
3965
4336
|
##### SWT Browser Style Options
|
3966
4337
|
|
3967
4338
|
The `browser` widget can use a particular desktop browser by setting the SWT Style to:
|
@@ -4147,8 +4518,18 @@ end
|
|
4147
4518
|
|
4148
4519
|
### log_excluded_keywords
|
4149
4520
|
|
4521
|
+
(default = false)
|
4522
|
+
|
4150
4523
|
This just tells Glimmer whether to log excluded keywords or not (at the debug level). It is off by default.
|
4151
4524
|
|
4525
|
+
### auto_sync_exec
|
4526
|
+
|
4527
|
+
(default = false)
|
4528
|
+
|
4529
|
+
This automatically uses sync_exec on GUI calls from threads other than the main GUI thread instead of requiring users to manually use sync_exec. Default value to false.
|
4530
|
+
|
4531
|
+
Keep in mind the caveat that it would force redraws on every minor changein the models instead of applying large scope changes all together, thus causing too much drawing/stutter in the GUI. As such, this is a good fit for simpler GUIs, not ones used with highly sophisticated 2D graphics. It may be mitigated in the future by introducing the idea of large-scale observation events that wrap around smaller events. Until then, keep the caveat in mind or just use sync_exec manually as usually done with Java SWT apps.
|
4532
|
+
|
4152
4533
|
## Glimmer Style Guide
|
4153
4534
|
|
4154
4535
|
- Widgets are declared with underscored lowercase versions of their SWT names minus the SWT package name.
|
@@ -4227,14 +4608,14 @@ You may edit the code of any sample before launching it by clicking on the "Laun
|
|
4227
4608
|
Note that if you fail to run any sample through the Glimmer Meta-Sample for whatever reason, you could always run directly by cloning the project, running `bundle`, and then this command (drop the "bin" if you install the glimmer-dsl-swt gem instead):
|
4228
4609
|
|
4229
4610
|
```ruby
|
4230
|
-
bin/glimmer samples/hello/hello_canvas_transform.rb
|
4611
|
+
bin/glimmer samples/hello/hello_canvas_transform.rb
|
4231
4612
|
```
|
4232
4613
|
|
4233
4614
|
### Hello Samples
|
4234
4615
|
|
4235
4616
|
For hello-type simple samples, check the following.
|
4236
4617
|
|
4237
|
-
#### Hello, World!
|
4618
|
+
#### Hello, World!
|
4238
4619
|
|
4239
4620
|
Code:
|
4240
4621
|
|
@@ -4689,6 +5070,26 @@ Hello, Dialog! Open Dialog
|
|
4689
5070
|
|
4690
5071
|
![Hello Dialog Open Dialog](images/glimmer-hello-dialog-open-dialog.png)
|
4691
5072
|
|
5073
|
+
#### Hello, Code Text!
|
5074
|
+
|
5075
|
+
This sample demonstrates the Glimmer Built-In [Code Text Custom Widget](#code-text-custom-widget).
|
5076
|
+
|
5077
|
+
Code:
|
5078
|
+
|
5079
|
+
[samples/hello/hello_code_text.rb](samples/hello/hello_code_text.rb)
|
5080
|
+
|
5081
|
+
Hello, Code Text! Ruby Language / Glimmer Theme / Show Line Numbers (default width of 4)
|
5082
|
+
|
5083
|
+
![Hello Code Text Ruby](images/glimmer-hello-code-text-ruby.png)
|
5084
|
+
|
5085
|
+
Hello, Code Text! JavaScript Language / Pastie Theme / Show Line Numbers (custom width of 2)
|
5086
|
+
|
5087
|
+
![Hello Code Text JavaScript](images/glimmer-hello-code-text-javascript.png)
|
5088
|
+
|
5089
|
+
Hello, Code Text! HTML Language / GitHub Theme / No Line Numbers
|
5090
|
+
|
5091
|
+
![Hello Code Text HTML](images/glimmer-hello-code-text-html.png)
|
5092
|
+
|
4692
5093
|
#### Hello, Canvas!
|
4693
5094
|
|
4694
5095
|
This sample demonstrates the use of the `canvas` widget and [Shape DSL](#canvas-shape-dsl) in Glimmer.
|
@@ -4758,7 +5159,7 @@ Code:
|
|
4758
5159
|
![Login Filled In](images/glimmer-login-filled-in.png)
|
4759
5160
|
![Login Logged In](images/glimmer-login-logged-in.png)
|
4760
5161
|
|
4761
|
-
#### Tic Tac Toe
|
5162
|
+
#### Tic Tac Toe
|
4762
5163
|
|
4763
5164
|
This sample demonstrates a full MVC application, including GUI layout, text and enablement data-binding, and test-driven development (has [specs](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/spec/samples/elaborate/tic_tac_toe/board_spec.rb)).
|
4764
5165
|
|
@@ -4772,7 +5173,7 @@ Code:
|
|
4772
5173
|
![Tic Tac Toe In Progress](images/glimmer-tic-tac-toe-in-progress.png)
|
4773
5174
|
![Tic Tac Toe Game Over](images/glimmer-tic-tac-toe-game-over.png)
|
4774
5175
|
|
4775
|
-
#### Contact Manager
|
5176
|
+
#### Contact Manager
|
4776
5177
|
|
4777
5178
|
This sample demonstrates table data-binding, sorting, filtering, GUI layout, MVP pattern, and test-driven development (has [specs](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/spec/samples/elaborate/contact_manager/contact_manager_presenter_spec.rb)).
|
4778
5179
|
|
@@ -4800,18 +5201,32 @@ Contact Manager - Edit Done
|
|
4800
5201
|
|
4801
5202
|
![Contact Manager](images/glimmer-contact-manager-edit-done.png)
|
4802
5203
|
|
4803
|
-
#### Tetris
|
5204
|
+
#### Glimmer Tetris
|
4804
5205
|
|
4805
|
-
This sample demonstrates how to build an interactive animated game with MVC architecture, custom-shell/custom-widgets, multi-threading, asynchronous programming, data-binding, canvas shape graphic decorations, and keyboard events.
|
5206
|
+
This sample demonstrates how to build an interactive animated game with MVC architecture, custom-shell/custom-widgets, multi-threading, asynchronous programming, data-binding, canvas shape graphic decorations, canvas shape icon image generation, and keyboard events/shortcuts.
|
4806
5207
|
|
4807
5208
|
Code:
|
4808
5209
|
|
4809
5210
|
[samples/elaborate/tetris.rb](samples/elaborate/tetris.rb)
|
4810
5211
|
|
5212
|
+
![Tetris Icon](images/glimmer-tetris-icon.png)
|
5213
|
+
|
4811
5214
|
![Tetris](images/glimmer-tetris.png)
|
4812
5215
|
|
4813
5216
|
![Tetris Game Over](images/glimmer-tetris-game-over.png)
|
4814
5217
|
|
5218
|
+
![Tetris Game Over](images/glimmer-tetris-game-over-sorted-by-score.png)
|
5219
|
+
|
5220
|
+
![Tetris High Scores](images/glimmer-tetris-high-score-dialog.png)
|
5221
|
+
|
5222
|
+
![Tetris Game Menu](images/glimmer-tetris-game-menu.png)
|
5223
|
+
|
5224
|
+
![Tetris View Menu](images/glimmer-tetris-view-menu.png)
|
5225
|
+
|
5226
|
+
![Tetris Options Menu](images/glimmer-tetris-options-menu.png)
|
5227
|
+
|
5228
|
+
![Tetris Help Menu](images/glimmer-tetris-help-menu.png)
|
5229
|
+
|
4815
5230
|
### External Samples
|
4816
5231
|
|
4817
5232
|
#### Glimmer Calculator
|