glimmer-dsl-swt 4.20.0.1 → 4.20.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/README.md +17 -13
  4. data/VERSION +1 -1
  5. data/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md +10 -7
  6. data/docs/reference/GLIMMER_SAMPLES.md +168 -49
  7. data/docs/reference/GLIMMER_STYLE_GUIDE.md +4 -3
  8. data/glimmer-dsl-swt.gemspec +0 -0
  9. data/lib/glimmer/data_binding/shine.rb +3 -1
  10. data/lib/glimmer/data_binding/table_items_binding.rb +2 -2
  11. data/lib/glimmer/dsl/swt/shine_data_binding_expression.rb +6 -3
  12. data/lib/glimmer/dsl/swt/table_items_data_binding_expression.rb +2 -2
  13. data/lib/glimmer/dsl/swt/widget_expression.rb +2 -0
  14. data/lib/glimmer/dsl/swt/widget_listener_expression.rb +3 -3
  15. data/lib/glimmer/rake_task/scaffold.rb +0 -2
  16. data/lib/glimmer/swt/combo_proxy.rb +48 -0
  17. data/lib/glimmer/swt/display_proxy.rb +11 -8
  18. data/lib/glimmer/swt/proxy_properties.rb +2 -1
  19. data/lib/glimmer/swt/table_proxy.rb +15 -8
  20. data/lib/glimmer/swt/tool_bar_proxy.rb +51 -0
  21. data/lib/glimmer/swt/widget_proxy.rb +8 -2
  22. data/lib/glimmer/ui/custom_shell.rb +3 -3
  23. data/lib/glimmer/ui/custom_widget.rb +5 -2
  24. data/samples/elaborate/calculator.rb +116 -0
  25. data/samples/elaborate/calculator/model/command.rb +105 -0
  26. data/samples/elaborate/calculator/model/command/all_clear.rb +17 -0
  27. data/samples/elaborate/calculator/model/command/command_history.rb +0 -0
  28. data/samples/elaborate/calculator/model/command/equals.rb +18 -0
  29. data/samples/elaborate/calculator/model/command/number.rb +20 -0
  30. data/samples/elaborate/calculator/model/command/operation.rb +27 -0
  31. data/samples/elaborate/calculator/model/command/operation/add.rb +15 -0
  32. data/samples/elaborate/calculator/model/command/operation/divide.rb +15 -0
  33. data/samples/elaborate/calculator/model/command/operation/multiply.rb +15 -0
  34. data/samples/elaborate/calculator/model/command/operation/subtract.rb +15 -0
  35. data/samples/elaborate/calculator/model/command/point.rb +20 -0
  36. data/samples/elaborate/calculator/model/presenter.rb +30 -0
  37. data/samples/elaborate/login.rb +15 -13
  38. data/samples/elaborate/tetris.rb +4 -4
  39. data/samples/elaborate/tetris/model/game.rb +0 -3
  40. data/samples/elaborate/timer.rb +233 -0
  41. data/samples/elaborate/timer/alarm1.wav +0 -0
  42. data/samples/elaborate/timer/sounds/alarm1.wav +0 -0
  43. data/samples/elaborate/user_profile.rb +4 -2
  44. data/samples/elaborate/weather.rb +164 -0
  45. data/samples/hello/hello_cool_bar.rb +147 -0
  46. data/samples/hello/hello_layout.rb +6 -2
  47. data/samples/hello/hello_shell.rb +205 -0
  48. data/samples/hello/hello_table.rb +5 -5
  49. data/samples/hello/hello_text.rb +120 -0
  50. data/samples/hello/hello_tool_bar.rb +143 -0
  51. metadata +25 -2
@@ -200,8 +200,12 @@ class HelloLayout
200
200
  grab_excess_horizontal_space true
201
201
  grab_excess_vertical_space true
202
202
  }
203
- # layout_data :fill, :fill, true, true # short alternative of specifying what is above
204
-
203
+
204
+ # this is a short alternative for specifying what is above
205
+ # layout_data(:fill, :fill, true, true) {
206
+ # horizontal_span 5
207
+ # }
208
+
205
209
  text "<this label fills all the space it can get\nhorizontally and vertically>"
206
210
  background :magenta
207
211
  }
@@ -0,0 +1,205 @@
1
+ # Copyright (c) 2007-2021 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require 'glimmer-dsl-swt'
23
+
24
+ class HelloShell
25
+ include Glimmer::UI::CustomShell
26
+
27
+ body {
28
+ # this is the initial shell that opens. If you close it, you close the app.
29
+ shell { |root_shell_proxy|
30
+ row_layout(:vertical)
31
+ text 'Hello, Shell!'
32
+
33
+ button {
34
+ layout_data {
35
+ width 200
36
+ height 50
37
+ }
38
+ text "Nested Shell"
39
+
40
+ on_widget_selected {
41
+ # build a nested shell, meaning a shell that specifies its parent shell (root_shell_proxy)
42
+ shell(root_shell_proxy) {
43
+ # shell has fill_layout(:horizontal) by default with no margins
44
+ text 'Nested Shell'
45
+
46
+ label {
47
+ font height: 20
48
+ text "Since this shell is nested, \nyou can hit ESC to close"
49
+ }
50
+ }.open
51
+ }
52
+ }
53
+
54
+ button {
55
+ layout_data {
56
+ width 200
57
+ height 50
58
+ }
59
+ text "Independent Shell"
60
+
61
+ on_widget_selected {
62
+ # build an independent shell, meaning a shell that is independent of its parent
63
+ shell {
64
+ # shell has fill_layout(:horizontal) by default with no margins
65
+ text 'Independent Shell'
66
+
67
+ label {
68
+ font height: 20
69
+ text "Since this shell is independent, \nyou cannot close by hitting ESC"
70
+ }
71
+ }.open
72
+ }
73
+ }
74
+
75
+ button {
76
+ layout_data {
77
+ width 200
78
+ height 50
79
+ }
80
+ text "Close-Button Shell"
81
+
82
+ on_widget_selected {
83
+ shell(:close) {
84
+ # shell has fill_layout(:horizontal) by default with no margins
85
+ text 'Nested Shell'
86
+
87
+ label {
88
+ font height: 20
89
+ text "Shell with close button only\n(varies per platform)"
90
+ }
91
+ }.open
92
+ }
93
+ }
94
+
95
+ button {
96
+ layout_data {
97
+ width 200
98
+ height 50
99
+ }
100
+ text "Minimize-Button Shell"
101
+
102
+ on_widget_selected {
103
+ # build a nested shell, meaning a shell that specifies its parent shell (root_shell_proxy)
104
+ shell(root_shell_proxy, :min) {
105
+ # shell has fill_layout(:horizontal) by default with no margins
106
+ text 'Minimize-Button Shell'
107
+
108
+ label {
109
+ font height: 20
110
+ text "Shell with minimize button only\n(varies per platform)"
111
+ }
112
+ }.open
113
+ }
114
+ }
115
+
116
+ button {
117
+ layout_data {
118
+ width 200
119
+ height 50
120
+ }
121
+ text "Maximize-Button Shell"
122
+
123
+ on_widget_selected {
124
+ # build a nested shell, meaning a shell that specifies its parent shell (root_shell_proxy)
125
+ shell(root_shell_proxy, :max) {
126
+ # shell has fill_layout(:horizontal) by default with no margins
127
+ text 'Maximize-Button Shell'
128
+
129
+ label {
130
+ font height: 20
131
+ text "Shell with maximize button only\n(varies per platform)"
132
+ }
133
+ }.open
134
+ }
135
+ }
136
+
137
+ button {
138
+ layout_data {
139
+ width 200
140
+ height 50
141
+ }
142
+ text "Buttonless Shell"
143
+
144
+ on_widget_selected {
145
+ # build a nested shell, meaning a shell that specifies its parent shell (root_shell_proxy)
146
+ shell(root_shell_proxy, :title) {
147
+ # shell has fill_layout(:horizontal) by default with no margins
148
+ text 'Buttonless Shell'
149
+
150
+ label {
151
+ font height: 20
152
+ text "Buttonless shell (title only)\n(varies per platform)"
153
+ }
154
+ }.open
155
+ }
156
+ }
157
+
158
+ button {
159
+ layout_data {
160
+ width 200
161
+ height 50
162
+ }
163
+ text "No Trim Shell"
164
+
165
+ on_widget_selected {
166
+ # build a nested shell, meaning a shell that specifies its parent shell (root_shell_proxy)
167
+ shell(root_shell_proxy, :no_trim) {
168
+ # shell has fill_layout(:horizontal) by default with no margins
169
+ text 'No Trim Shell'
170
+
171
+ label {
172
+ font height: 20
173
+ text "No trim shell, meaning no buttons or title bar.\n(varies per platform)"
174
+ }
175
+ }.open
176
+ }
177
+ }
178
+
179
+ button {
180
+ layout_data {
181
+ width 200
182
+ height 50
183
+ }
184
+ text "Always On Top Shell"
185
+
186
+ on_widget_selected {
187
+ # build a nested shell, meaning a shell that specifies its parent shell (root_shell_proxy)
188
+ shell(root_shell_proxy, :on_top) {
189
+ # shell has fill_layout(:horizontal) by default with no margins
190
+ text 'Always On Top Shell'
191
+
192
+ label {
193
+ font height: 20
194
+ text "Always on top shell.\n(varies per platform)"
195
+ }
196
+ }.open
197
+ }
198
+ }
199
+
200
+ }
201
+
202
+ }
203
+ end
204
+
205
+ HelloShell.launch
@@ -206,11 +206,11 @@ class HelloTable
206
206
 
207
207
  combo(:read_only) {
208
208
  layout_data :center, :center, true, false
209
- selection bind(BaseballGame, :playoff_type)
209
+ selection <=> [BaseballGame, :playoff_type]
210
210
  font height: 14
211
211
  }
212
212
 
213
- table(:editable) { |table_proxy|
213
+ table { |table_proxy|
214
214
  layout_data :fill, :fill, true, true
215
215
 
216
216
  table_column {
@@ -247,10 +247,10 @@ class HelloTable
247
247
  }
248
248
 
249
249
  # Data-bind table items (rows) to a model collection property, specifying column properties ordering per nested model
250
- items bind(BaseballGame, :schedule), column_properties(:game_date, :game_time, :ballpark, :home_team, :away_team, :promotion)
250
+ items <=> [BaseballGame, :schedule, column_properties: [:game_date, :game_time, :ballpark, :home_team, :away_team, :promotion]]
251
251
 
252
252
  # Data-bind table selection
253
- selection bind(BaseballGame, :selected_game)
253
+ selection <=> [BaseballGame, :selected_game]
254
254
 
255
255
  # Default initial sort property
256
256
  sort_property :date
@@ -273,7 +273,7 @@ class HelloTable
273
273
  text 'Book Selected Game'
274
274
  layout_data :center, :center, true, false
275
275
  font height: 14
276
- enabled bind(BaseballGame, :selected_game)
276
+ enabled <= [BaseballGame, :selected_game]
277
277
 
278
278
  on_widget_selected {
279
279
  book_selected_game
@@ -0,0 +1,120 @@
1
+ require 'glimmer-dsl-swt'
2
+
3
+ class HelloText
4
+ include Glimmer::UI::CustomShell
5
+
6
+ attr_accessor :default, :center, :left, :right, :password, :telephone, :read_only, :wrap, :multi
7
+
8
+ before_body {
9
+ self.default = 'default is :border style'
10
+ self.center = 'centered'
11
+ self.left = 'left-aligned'
12
+ self.right = 'right-aligned'
13
+ self.password = 'password'
14
+ self.telephone = '555-555-5555'
15
+ self.read_only = 'Telephone area code is 555'
16
+ self.wrap = 'wraps if text content is too long like this example'
17
+ self.multi = "multi-line enables hitting enter,\nbut does not wrap by default"
18
+ }
19
+
20
+ body {
21
+ shell {
22
+ grid_layout 2, false
23
+
24
+ text 'Hello, Text!'
25
+ minimum_size 350, 100
26
+
27
+ label {
28
+ text 'text'
29
+ }
30
+ text { # includes :border style by default
31
+ layout_data :fill, :center, true, false
32
+ text <=> [self, :default]
33
+ }
34
+
35
+ label {
36
+ text 'text(:center, :border)'
37
+ }
38
+ text(:center, :border) {
39
+ layout_data :fill, :center, true, false
40
+ text <=> [self, :center]
41
+ }
42
+
43
+ label {
44
+ text 'text(:left, :border)'
45
+ }
46
+ text(:left, :border) {
47
+ layout_data :fill, :center, true, false
48
+ text <=> [self, :left]
49
+ }
50
+
51
+ label {
52
+ text 'text(:right, :border)'
53
+ }
54
+ text(:right, :border) {
55
+ layout_data :fill, :center, true, false
56
+ text <=> [self, :right]
57
+ }
58
+
59
+ label {
60
+ text 'text(:password, :border)'
61
+ }
62
+ text(:password, :border) {
63
+ layout_data :fill, :center, true, false
64
+ text <=> [self, :password]
65
+ }
66
+
67
+ label {
68
+ text 'text(:read_only, :border)'
69
+ }
70
+ text(:read_only, :border) {
71
+ layout_data :fill, :center, true, false
72
+ text <=> [self, :read_only]
73
+ }
74
+
75
+ label {
76
+ text 'text with event handlers'
77
+ }
78
+ text {
79
+ layout_data :fill, :center, true, false
80
+ text <=> [self, :telephone]
81
+
82
+ # this event kicks in just after the user typed and before modifying the text attribute value
83
+ on_verify_text do |verify_event|
84
+ new_text = verify_event.widget.text.clone
85
+ new_text[verify_event.start...verify_event.end] = verify_event.text
86
+ verify_event.doit = telephone?(new_text)
87
+ end
88
+
89
+ # this event kicks in just after the text widget is verified and modified
90
+ on_modify_text do |modify_event|
91
+ self.read_only = "Telephone area code is #{modify_event.widget.text.gsub(/[^0-9]/, '')[0...3]}"
92
+ end
93
+ }
94
+
95
+ label {
96
+ text 'text(:wrap, :border)'
97
+ }
98
+ text(:wrap, :border) {
99
+ layout_data(:fill, :center, true, false) {
100
+ width_hint 100
101
+ }
102
+ text <=> [self, :wrap]
103
+ }
104
+
105
+ label {
106
+ text 'text(:multi, :border)'
107
+ }
108
+ text(:multi, :border) {
109
+ layout_data :fill, :center, true, false
110
+ text <=> [self, :multi]
111
+ }
112
+ }
113
+ }
114
+
115
+ def telephone?(text)
116
+ !!text.match(/^\d{0,3}[-.\/]?\d{0,3}[-.\/]?\d{0,4}$/)
117
+ end
118
+ end
119
+
120
+ HelloText.launch
@@ -0,0 +1,143 @@
1
+ # Copyright (c) 2007-2021 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require 'glimmer-dsl-swt'
23
+
24
+ class HelloToolBar
25
+ include Glimmer::UI::CustomShell
26
+
27
+ attr_accessor :operation, :font_size
28
+
29
+ def font_size_options
30
+ (10..30).to_a.map(&:to_s)
31
+ end
32
+
33
+ before_body {
34
+ self.font_size = '30'
35
+ }
36
+
37
+ body {
38
+ shell {
39
+ fill_layout(:vertical) {
40
+ margin_width 0
41
+ margin_height 0
42
+ }
43
+
44
+ text 'Hello, Tool Bar!'
45
+
46
+ tool_bar { # optionally takes a :flat style, :wrap style if you need wrapping upon shrinking window, and :vertical style if you need vertical layout
47
+ tool_item {
48
+ image cut_image # alternatively you can pass an image file path
49
+
50
+ on_widget_selected do
51
+ self.operation = 'Cut'
52
+ end
53
+ }
54
+ tool_item {
55
+ image copy_image # alternatively you can pass an image file path
56
+
57
+ on_widget_selected do
58
+ self.operation = 'Copy'
59
+ end
60
+ }
61
+ tool_item {
62
+ image paste_image # alternatively you can pass an image file path
63
+
64
+ on_widget_selected do
65
+ self.operation = 'Paste'
66
+ end
67
+ }
68
+ tool_item(:separator)
69
+ tool_item {
70
+ text 'Font Size'
71
+ }
72
+ # a combo can be nested in a tool_bar (it auto-generates a tool_item for itself behind the scenes)
73
+ combo {
74
+ selection bind(self, :font_size)
75
+ }
76
+ }
77
+
78
+ label {
79
+ font <= [self, :font_size, on_read: ->(size) { {height: size.to_i} }]
80
+ text <= [self, :operation]
81
+ text <= [self, :font_size]
82
+ }
83
+ }
84
+ }
85
+
86
+ def cut_image
87
+ # building image on the fly with Canvas Shape DSL
88
+ image(25, 25) {
89
+ rectangle(0, 0, 25, 25) {
90
+ background_pattern 0, 0, 0, 25, :white, :gray
91
+ line(20, 2, 9, 15) {
92
+ line_width 2
93
+ }
94
+ line(5, 2, 16, 15) {
95
+ line_width 2
96
+ }
97
+ oval(2, 15, 8, 8) {
98
+ line_width 2
99
+ }
100
+ oval(16, 15, 8, 8) {
101
+ line_width 2
102
+ }
103
+ }
104
+ }
105
+ end
106
+
107
+ def copy_image
108
+ # building image on the fly with Canvas Shape DSL
109
+ image(25, 25) {
110
+ rectangle(0, 0, 25, 25) {
111
+ background_pattern 0, 0, 0, 25, :white, :gray
112
+ rectangle([:default, 2], [:default, -2], 14, 14, 5, 5) {
113
+ line_width 2
114
+ }
115
+ rectangle([:default, -2], [:default, 2], 14, 14, 5, 5) {
116
+ line_width 2
117
+ }
118
+ }
119
+ }
120
+ end
121
+
122
+ def paste_image
123
+ image(25, 25) {
124
+ rectangle(0, 0, 25, 25) {
125
+ background_pattern 0, 0, 0, 25, :white, :gray
126
+ rectangle(:default, [:default, 1], 15, 20, 5, 5) {
127
+ line_width 2
128
+ }
129
+ line(7, 8, 18, 8) {
130
+ line_width 2
131
+ }
132
+ line(7, 13, 18, 13) {
133
+ line_width 2
134
+ }
135
+ line(7, 18, 18, 18) {
136
+ line_width 2
137
+ }
138
+ }
139
+ }
140
+ end
141
+ end
142
+
143
+ HelloToolBar.launch