glimmer-dsl-swt 4.20.0.2 → 4.20.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +30 -0
  3. data/README.md +6 -6
  4. data/VERSION +1 -1
  5. data/docs/reference/GLIMMER_SAMPLES.md +128 -49
  6. data/docs/reference/GLIMMER_STYLE_GUIDE.md +4 -3
  7. data/glimmer-dsl-swt.gemspec +0 -0
  8. data/lib/glimmer/data_binding/shine.rb +3 -1
  9. data/lib/glimmer/data_binding/table_items_binding.rb +2 -2
  10. data/lib/glimmer/data_binding/tree_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/tree_items_data_binding_expression.rb +17 -12
  14. data/lib/glimmer/dsl/swt/widget_listener_expression.rb +3 -3
  15. data/lib/glimmer/swt/display_proxy.rb +11 -8
  16. data/lib/glimmer/swt/proxy_properties.rb +2 -1
  17. data/lib/glimmer/swt/table_proxy.rb +15 -8
  18. data/lib/glimmer/swt/widget_proxy.rb +2 -2
  19. data/lib/glimmer/ui/custom_shell.rb +3 -3
  20. data/lib/glimmer/ui/custom_widget.rb +5 -2
  21. data/samples/elaborate/calculator.rb +116 -0
  22. data/samples/elaborate/calculator/model/command.rb +105 -0
  23. data/samples/elaborate/calculator/model/command/all_clear.rb +17 -0
  24. data/samples/elaborate/calculator/model/command/command_history.rb +0 -0
  25. data/samples/elaborate/calculator/model/command/equals.rb +18 -0
  26. data/samples/elaborate/calculator/model/command/number.rb +20 -0
  27. data/samples/elaborate/calculator/model/command/operation.rb +27 -0
  28. data/samples/elaborate/calculator/model/command/operation/add.rb +15 -0
  29. data/samples/elaborate/calculator/model/command/operation/divide.rb +15 -0
  30. data/samples/elaborate/calculator/model/command/operation/multiply.rb +15 -0
  31. data/samples/elaborate/calculator/model/command/operation/subtract.rb +15 -0
  32. data/samples/elaborate/calculator/model/command/point.rb +20 -0
  33. data/samples/elaborate/calculator/model/presenter.rb +30 -0
  34. data/samples/elaborate/login.rb +15 -13
  35. data/samples/elaborate/tetris.rb +6 -6
  36. data/samples/elaborate/tetris/view/high_score_dialog.rb +1 -1
  37. data/samples/elaborate/timer.rb +233 -0
  38. data/samples/elaborate/timer/alarm1.wav +0 -0
  39. data/samples/elaborate/timer/sounds/alarm1.wav +0 -0
  40. data/samples/elaborate/user_profile.rb +4 -2
  41. data/samples/elaborate/weather.rb +164 -0
  42. data/samples/hello/hello_cool_bar.rb +4 -4
  43. data/samples/hello/hello_layout.rb +6 -2
  44. data/samples/hello/hello_shell.rb +205 -0
  45. data/samples/hello/hello_table.rb +5 -5
  46. data/samples/hello/hello_text.rb +120 -0
  47. data/samples/hello/hello_tool_bar.rb +4 -4
  48. data/samples/hello/hello_tree.rb +11 -11
  49. metadata +21 -2
Binary file
@@ -23,7 +23,9 @@ require 'glimmer-dsl-swt'
23
23
 
24
24
  include Glimmer
25
25
 
26
- shell {
26
+ # A version of this was featured in a dzone article as an intro to Glimmer syntax:
27
+ # https://dzone.com/articles/an-introduction-glimmer
28
+ shell { |shell_proxy|
27
29
  text "User Profile"
28
30
 
29
31
  composite {
@@ -72,7 +74,7 @@ shell {
72
74
  button {
73
75
  text "close"
74
76
  layout_data :left, :center, true, true
75
- on_widget_selected { exit(0) }
77
+ on_widget_selected { shell_proxy.close }
76
78
  }
77
79
  }
78
80
  }.open
@@ -0,0 +1,164 @@
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
+ require 'net/http'
24
+ require 'json'
25
+ require 'facets/string/titlecase'
26
+
27
+ class Weather
28
+ include Glimmer::UI::CustomShell
29
+
30
+ DEFAULT_FONT_HEIGHT = 30
31
+ DEFAULT_FOREGROUND = :white
32
+
33
+ attr_accessor :city, :temp, :temp_min, :temp_max, :feels_like, :humidity
34
+
35
+ before_body {
36
+ @weather_mutex = Mutex.new
37
+ self.city = 'Montreal, QC, CA'
38
+ fetch_weather!
39
+ }
40
+
41
+ after_body {
42
+ Thread.new do
43
+ loop do
44
+ sleep(10)
45
+ break if body_root.disposed?
46
+ fetch_weather!
47
+ end
48
+ end
49
+ }
50
+
51
+ body {
52
+ shell(:no_resize) {
53
+ grid_layout
54
+
55
+ text 'Glimmer Weather'
56
+ minimum_size 400, 300
57
+ background rgb(135, 176, 235)
58
+
59
+ text {
60
+ layout_data(:center, :center, true, true)
61
+
62
+ text <=> [self, :city]
63
+
64
+ on_key_pressed {|event|
65
+ if event.keyCode == swt(:cr) # carriage return
66
+ Thread.new do
67
+ fetch_weather!
68
+ end
69
+ end
70
+ }
71
+ }
72
+
73
+ tab_folder {
74
+ layout_data(:center, :center, true, true)
75
+
76
+ ['℃', '℉'].each do |temp_unit|
77
+ tab_item {
78
+ grid_layout 2, false
79
+
80
+ text temp_unit
81
+ background :transparent
82
+
83
+ rectangle(0, 0, [:default, -2], [:default, -2], 15, 15) {
84
+ foreground DEFAULT_FOREGROUND
85
+ }
86
+
87
+ %w[temp temp_min temp_max feels_like].each do |field_name|
88
+ temp_field(field_name, temp_unit)
89
+ end
90
+
91
+ humidity_field
92
+ }
93
+ end
94
+ }
95
+ }
96
+ }
97
+
98
+ def temp_field(field_name, temp_unit)
99
+ name_label(field_name)
100
+ label {
101
+ layout_data(:fill, :center, true, false)
102
+ text <= [self, field_name, on_read: ->(t) { "#{kelvin_to_temp_unit(t, temp_unit).to_f.round}°" }]
103
+ font height: DEFAULT_FONT_HEIGHT
104
+ foreground DEFAULT_FOREGROUND
105
+ }
106
+ end
107
+
108
+ def humidity_field
109
+ name_label('humidity')
110
+ label {
111
+ layout_data(:fill, :center, true, false)
112
+ text <= [self, 'humidity', on_read: ->(h) { "#{h.to_f.round}%" }]
113
+ font height: DEFAULT_FONT_HEIGHT
114
+ foreground DEFAULT_FOREGROUND
115
+ }
116
+ end
117
+
118
+ def name_label(field_name)
119
+ label {
120
+ layout_data :fill, :center, false, false
121
+ text field_name.titlecase
122
+ font height: DEFAULT_FONT_HEIGHT
123
+ foreground DEFAULT_FOREGROUND
124
+ }
125
+ end
126
+
127
+ def fetch_weather!
128
+ @weather_mutex.synchronize do
129
+ self.weather_data = JSON.parse(Net::HTTP.get('api.openweathermap.org', "/data/2.5/weather?q=#{city}&appid=1d16d70a9aec3570b5cbd27e6b421330"))
130
+ end
131
+ rescue
132
+ # No Op
133
+ end
134
+
135
+ def weather_data=(data)
136
+ @weather_data = data
137
+ main_data = data['main']
138
+ # temps come back in Kelvin
139
+ self.temp = main_data['temp']
140
+ self.temp_min = main_data['temp_min']
141
+ self.temp_max = main_data['temp_max']
142
+ self.feels_like = main_data['feels_like']
143
+ self.humidity = main_data['humidity']
144
+ end
145
+
146
+ def kelvin_to_temp_unit(kelvin, temp_unit)
147
+ temp_unit == '℃' ? kelvin_to_celsius(kelvin) : kelvin_to_fahrenheit(kelvin)
148
+ end
149
+
150
+ def kelvin_to_celsius(kelvin)
151
+ kelvin - 273.15
152
+ end
153
+
154
+ def celsius_to_fahrenheit(celsius)
155
+ (celsius * 9 / 5 ) + 32
156
+ end
157
+
158
+ def kelvin_to_fahrenheit(kelvin)
159
+ celsius_to_fahrenheit(kelvin_to_celsius(kelvin))
160
+ end
161
+
162
+ end
163
+
164
+ Weather.launch
@@ -31,7 +31,7 @@ class HelloCoolBar
31
31
  end
32
32
 
33
33
  before_body {
34
- self.font_size = '10'
34
+ self.font_size = '30'
35
35
  }
36
36
 
37
37
  body {
@@ -80,9 +80,9 @@ class HelloCoolBar
80
80
 
81
81
 
82
82
  label {
83
- font height: 30
84
- text bind(self, :operation)
85
- text bind(self, :font_size)
83
+ font <= [self, :font_size, on_read: ->(size) { {height: size.to_i} }]
84
+ text <= [self, :operation]
85
+ text <= [self, :font_size]
86
86
  }
87
87
  }
88
88
  }
@@ -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