glimmer-dsl-swt 4.19.0.2 → 4.20.0.4

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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/README.md +26 -27
  4. data/RUBY_VERSION +1 -1
  5. data/VERSION +1 -1
  6. data/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md +44 -15
  7. data/docs/reference/GLIMMER_SAMPLES.md +157 -17
  8. data/glimmer-dsl-swt.gemspec +0 -0
  9. data/lib/glimmer/data_binding/shine.rb +41 -26
  10. data/lib/glimmer/dsl/swt/dsl.rb +2 -1
  11. data/lib/glimmer/dsl/swt/shine_data_binding_expression.rb +49 -0
  12. data/lib/glimmer/dsl/swt/widget_expression.rb +2 -0
  13. data/lib/glimmer/launcher.rb +6 -0
  14. data/lib/glimmer/rake_task/scaffold.rb +0 -2
  15. data/lib/glimmer/swt/combo_proxy.rb +48 -0
  16. data/lib/glimmer/swt/custom/code_text.rb +13 -9
  17. data/lib/glimmer/swt/tool_bar_proxy.rb +51 -0
  18. data/lib/glimmer/swt/widget_proxy.rb +6 -0
  19. data/samples/elaborate/contact_manager.rb +7 -5
  20. data/samples/elaborate/login.rb +18 -16
  21. data/samples/elaborate/mandelbrot_fractal.rb +2 -2
  22. data/samples/elaborate/metronome.rb +3 -3
  23. data/samples/elaborate/tetris/model/game.rb +0 -3
  24. data/samples/elaborate/tic_tac_toe.rb +2 -2
  25. data/samples/elaborate/weather.rb +164 -0
  26. data/samples/hello/hello_button.rb +1 -1
  27. data/samples/hello/hello_c_combo.rb +2 -1
  28. data/samples/hello/hello_c_tab.rb +1 -0
  29. data/samples/hello/hello_canvas.rb +5 -5
  30. data/samples/hello/hello_canvas_animation_data_binding.rb +1 -1
  31. data/samples/hello/hello_canvas_data_binding.rb +16 -16
  32. data/samples/hello/hello_checkbox.rb +4 -4
  33. data/samples/hello/hello_code_text.rb +3 -57
  34. data/samples/hello/hello_color_dialog.rb +1 -1
  35. data/samples/hello/hello_combo.rb +1 -1
  36. data/samples/hello/hello_composite.rb +71 -0
  37. data/samples/hello/hello_computed.rb +5 -5
  38. data/samples/hello/hello_cool_bar.rb +147 -0
  39. data/samples/hello/hello_custom_widget.rb +1 -1
  40. data/samples/hello/hello_date_time.rb +4 -4
  41. data/samples/hello/hello_dialog.rb +3 -2
  42. data/samples/hello/hello_drag_and_drop.rb +1 -1
  43. data/samples/hello/hello_file_dialog.rb +1 -1
  44. data/samples/hello/hello_font_dialog.rb +3 -3
  45. data/samples/hello/hello_group.rb +6 -6
  46. data/samples/hello/hello_layout.rb +243 -0
  47. data/samples/hello/hello_link.rb +56 -50
  48. data/samples/hello/hello_list_multi_selection.rb +1 -1
  49. data/samples/hello/hello_list_single_selection.rb +1 -1
  50. data/samples/hello/hello_progress_bar.rb +10 -10
  51. data/samples/hello/hello_radio.rb +6 -6
  52. data/samples/hello/hello_sash_form.rb +4 -4
  53. data/samples/hello/hello_shell.rb +205 -0
  54. data/samples/hello/hello_spinner.rb +6 -2
  55. data/samples/hello/hello_styled_text.rb +11 -11
  56. data/samples/hello/hello_tool_bar.rb +143 -0
  57. data/vendor/swt/linux/swt.jar +0 -0
  58. data/vendor/swt/linux_aarch64/swt.jar +0 -0
  59. data/vendor/swt/mac/swt.jar +0 -0
  60. data/vendor/swt/mac_aarch64/swt.jar +0 -0
  61. data/vendor/swt/windows/swt.jar +0 -0
  62. metadata +14 -3
@@ -180,7 +180,7 @@ class MandelbrotFractal
180
180
  body {
181
181
  shell(:no_resize) {
182
182
  grid_layout
183
- text bind(self, :mandelbrot_shell_title)
183
+ text <= [self, :mandelbrot_shell_title]
184
184
  minimum_size mandelbrot.width + 29, mandelbrot.height + 77
185
185
  image @mandelbrot_image
186
186
 
@@ -194,7 +194,7 @@ class MandelbrotFractal
194
194
 
195
195
  minimum 0
196
196
  maximum Mandelbrot::PROGRESS_MAX
197
- selection bind(Mandelbrot, :progress)
197
+ selection <= [Mandelbrot, :progress]
198
198
  }
199
199
 
200
200
  @scrolled_composite = scrolled_composite {
@@ -83,7 +83,7 @@ class Metronome
83
83
  spinner {
84
84
  minimum 1
85
85
  maximum 64
86
- selection bind(self, 'rhythm.beat_count', after_write: ->(v) {restart_metronome})
86
+ selection <=> [self, 'rhythm.beat_count', after_write: ->(v) {restart_metronome}]
87
87
  font height: 30
88
88
  }
89
89
 
@@ -95,7 +95,7 @@ class Metronome
95
95
  spinner {
96
96
  minimum 30
97
97
  maximum 1000
98
- selection bind(self, 'rhythm.bpm')
98
+ selection <=> [self, 'rhythm.bpm']
99
99
  font height: 30
100
100
  }
101
101
 
@@ -122,7 +122,7 @@ class Metronome
122
122
  height_hint 50
123
123
  }
124
124
  rectangle(0, 0, :default, :default, 36, 36) {
125
- background bind(self, "rhythm.beats[#{n}].on") {|on| on ? :red : :yellow}
125
+ background <= [self, "rhythm.beats[#{n}].on", on_read: ->(on) { on ? :red : :yellow}]
126
126
  }
127
127
  }
128
128
  }
@@ -33,8 +33,6 @@ class Tetris
33
33
  class Game
34
34
  PLAYFIELD_WIDTH = 10
35
35
  PLAYFIELD_HEIGHT = 20
36
- # PLAYFIELD_WIDTH = 5
37
- # PLAYFIELD_HEIGHT = 5
38
36
  PREVIEW_PLAYFIELD_WIDTH = 4
39
37
  PREVIEW_PLAYFIELD_HEIGHT = 2
40
38
  SCORE_MULTIPLIER = {1 => 40, 2 => 100, 3 => 300, 4 => 1200}
@@ -201,7 +199,6 @@ class Tetris
201
199
 
202
200
  def delay
203
201
  [1.1 - (level.to_i * 0.1), 0.001].max
204
- # 99999
205
202
  end
206
203
 
207
204
  def beep
@@ -47,8 +47,8 @@ class TicTacToe
47
47
  (1..3).each { |column|
48
48
  button {
49
49
  layout_data :fill, :fill, true, true
50
- text bind(@tic_tac_toe_board[row, column], :sign)
51
- enabled bind(@tic_tac_toe_board[row, column], :empty)
50
+ text <= [@tic_tac_toe_board[row, column], :sign]
51
+ enabled <= [@tic_tac_toe_board[row, column], :empty]
52
52
  font style: :bold, height: 20
53
53
  on_widget_selected {
54
54
  @tic_tac_toe_board.mark(row, column)
@@ -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 'net/http'
23
+ require 'json'
24
+ require 'facets/string/titlecase'
25
+ require 'glimmer-dsl-swt'
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
@@ -35,7 +35,7 @@ class HelloButton
35
35
  text 'Hello, Button!'
36
36
 
37
37
  button {
38
- text bind(self, :count) {|value| "Click To Increment: #{value} "}
38
+ text <= [self, :count, on_read: ->(value) { "Click To Increment: #{value} " }]
39
39
 
40
40
  on_widget_selected {
41
41
  self.count += 1
@@ -21,6 +21,7 @@
21
21
 
22
22
  require 'glimmer-dsl-swt'
23
23
 
24
+ # This is a sample for the c_combo widget, a more customizable version of combo
24
25
  class HelloCCombo
25
26
  class Person
26
27
  attr_accessor :country, :country_options
@@ -50,7 +51,7 @@ class HelloCCombo
50
51
  text 'Hello, C Combo!'
51
52
 
52
53
  c_combo(:read_only) {
53
- selection bind(@person, :country) # also binds to country_options by convention
54
+ selection <=> [@person, :country] # also binds to country_options by convention
54
55
  font height: 45 # unlike `combo`, `c_combo` changes height when setting the font height
55
56
  }
56
57
 
@@ -23,6 +23,7 @@
23
23
 
24
24
  require 'glimmer-dsl-swt'
25
25
 
26
+ # This is a sample for the Custom Tab widgets (c_tab_folder & c_tab_item), which are more customizable versions of tab_folder and tab_item.
26
27
  class HelloCTab
27
28
  include Glimmer::UI::CustomShell
28
29
 
@@ -59,7 +59,7 @@ class HelloCanvas
59
59
  rectangle([:default, -70], :default, :default, [:default, 1]) {
60
60
  foreground :cyan
61
61
  text {
62
- string bind(self, :artist)
62
+ string <=> [self, :artist]
63
63
  x :default, 1 # add 1 pixel to default x (shape centered within parent horizontally)
64
64
  y :default, 1 # add 1 pixel to default y (shape centered within parent vertically)
65
65
  background :yellow
@@ -105,7 +105,7 @@ class HelloCanvas
105
105
  menu {
106
106
  menu_item {
107
107
  text 'Change Background Color...'
108
- enabled bind(self, :selected_shape) {|shape| shape.respond_to?(:background) && shape.background }
108
+ enabled <=> [self, :selected_shape, on_read: ->(shape) { shape.respond_to?(:background) && shape.background }]
109
109
  on_widget_selected {
110
110
  @selected_shape&.background = color_dialog.open
111
111
  self.selected_shape = nil
@@ -113,7 +113,7 @@ class HelloCanvas
113
113
  }
114
114
  menu_item {
115
115
  text 'Change Background Pattern Color 1...'
116
- enabled bind(self, :selected_shape) {|shape| shape.respond_to?(:background_pattern) && shape.background_pattern }
116
+ enabled <=> [self, :selected_shape, on_read: ->(shape) { shape.respond_to?(:background_pattern) && shape.background_pattern }]
117
117
  on_widget_selected {
118
118
  if @selected_shape
119
119
  background_pattern_args = @selected_shape.background_pattern_args
@@ -125,7 +125,7 @@ class HelloCanvas
125
125
  }
126
126
  menu_item {
127
127
  text 'Change Background Pattern Color 2...'
128
- enabled bind(self, :selected_shape) {|shape| shape.respond_to?(:background_pattern) && shape.background_pattern }
128
+ enabled <=> [self, :selected_shape, on_read: ->(shape) { shape.respond_to?(:background_pattern) && shape.background_pattern }]
129
129
  on_widget_selected {
130
130
  if @selected_shape
131
131
  background_pattern_args = @selected_shape.background_pattern_args
@@ -138,7 +138,7 @@ class HelloCanvas
138
138
  menu_item(:separator)
139
139
  menu_item {
140
140
  text 'Change Foreground Color...'
141
- enabled bind(self, :selected_shape) {|shape| shape.respond_to?(:foreground) && shape.foreground }
141
+ enabled <=> [self, :selected_shape, on_read: ->(shape) { shape.respond_to?(:foreground) && shape.foreground }]
142
142
  on_widget_selected {
143
143
  @selected_shape&.foreground = color_dialog.open
144
144
  self.selected_shape = nil
@@ -46,7 +46,7 @@ class HelloAnimationDataBinding
46
46
  digits 3
47
47
  minimum 1
48
48
  maximum 100
49
- selection bind(self, :delay_time, on_read: ->(v) {(BigDecimal(v.to_s)*1000).to_f}, on_write: ->(v) {(BigDecimal(v.to_s)/1000).to_f})
49
+ selection <=> [self, :delay_time, on_read: ->(v) {(BigDecimal(v.to_s)*1000).to_f}, on_write: ->(v) {(BigDecimal(v.to_s)/1000).to_f}]
50
50
  }
51
51
  animation {
52
52
  every bind(self, :delay_time)
@@ -81,7 +81,7 @@ class HelloCanvasDataBinding
81
81
  }
82
82
  maximum CANVAS_WIDTH
83
83
  increment 3
84
- selection bind(self, :x1_value)
84
+ selection <=> [self, :x1_value]
85
85
  }
86
86
  spinner {
87
87
  layout_data(:fill, :center, false, false) {
@@ -89,7 +89,7 @@ class HelloCanvasDataBinding
89
89
  }
90
90
  maximum CANVAS_HEIGHT
91
91
  increment 3
92
- selection bind(self, :y1_value)
92
+ selection <=> [self, :y1_value]
93
93
  }
94
94
  label {
95
95
  layout_data(:fill, :center, false, false) {
@@ -109,7 +109,7 @@ class HelloCanvasDataBinding
109
109
  }
110
110
  maximum CANVAS_WIDTH
111
111
  increment 3
112
- selection bind(self, :x2_value)
112
+ selection <=> [self, :x2_value]
113
113
  }
114
114
  spinner {
115
115
  layout_data(:fill, :center, false, false) {
@@ -117,7 +117,7 @@ class HelloCanvasDataBinding
117
117
  }
118
118
  maximum CANVAS_HEIGHT
119
119
  increment 3
120
- selection bind(self, :y2_value)
120
+ selection <=> [self, :y2_value]
121
121
  }
122
122
  label {
123
123
  layout_data(:fill, :center, false, false) {
@@ -143,7 +143,7 @@ class HelloCanvasDataBinding
143
143
  }
144
144
  maximum 255
145
145
  increment 10
146
- selection bind(self, :foreground_red)
146
+ selection <=> [self, :foreground_red]
147
147
  }
148
148
  spinner {
149
149
  layout_data(:fill, :center, false, false) {
@@ -151,7 +151,7 @@ class HelloCanvasDataBinding
151
151
  }
152
152
  maximum 255
153
153
  increment 10
154
- selection bind(self, :foreground_green)
154
+ selection <=> [self, :foreground_green]
155
155
  }
156
156
  spinner {
157
157
  layout_data(:fill, :center, false, false) {
@@ -159,7 +159,7 @@ class HelloCanvasDataBinding
159
159
  }
160
160
  maximum 255
161
161
  increment 10
162
- selection bind(self, :foreground_blue)
162
+ selection <=> [self, :foreground_blue]
163
163
  }
164
164
  label {
165
165
  layout_data(:fill, :center, false, false) {
@@ -178,13 +178,13 @@ class HelloCanvasDataBinding
178
178
  horizontal_span 3
179
179
  }
180
180
  maximum 255
181
- selection bind(self, :line_width_value)
181
+ selection <=> [self, :line_width_value]
182
182
  }
183
183
  combo(:read_only) {
184
184
  layout_data(:fill, :center, false, false) {
185
185
  horizontal_span 3
186
186
  }
187
- selection bind(self, :line_style_value)
187
+ selection <=> [self, :line_style_value]
188
188
  }
189
189
  canvas {
190
190
  layout_data(:center, :center, false, false) {
@@ -195,13 +195,13 @@ class HelloCanvasDataBinding
195
195
  background :white
196
196
 
197
197
  line {
198
- x1 bind(self, :x1_value)
199
- y1 bind(self, :y1_value)
200
- x2 bind(self, :x2_value)
201
- y2 bind(self, :y2_value)
202
- foreground bind(self, :foreground_value, computed_by: [:foreground_red, :foreground_green, :foreground_blue])
203
- line_width bind(self, :line_width_value)
204
- line_style bind(self, :line_style_value)
198
+ x1 <=> [self, :x1_value]
199
+ y1 <=> [self, :y1_value]
200
+ x2 <=> [self, :x2_value]
201
+ y2 <=> [self, :y2_value]
202
+ foreground <=> [self, :foreground_value, computed_by: [:foreground_red, :foreground_green, :foreground_blue]]
203
+ line_width <=> [self, :line_width_value]
204
+ line_style <=> [self, :line_style_value]
205
205
  }
206
206
  }
207
207
  }
@@ -56,22 +56,22 @@ class HelloCheckbox
56
56
  composite {
57
57
  checkbox {
58
58
  text 'Skiing'
59
- selection bind(@person, :skiing)
59
+ selection <=> [@person, :skiing]
60
60
  }
61
61
 
62
62
  checkbox {
63
63
  text 'Snowboarding'
64
- selection bind(@person, :snowboarding)
64
+ selection <=> [@person, :snowboarding]
65
65
  }
66
66
 
67
67
  checkbox {
68
68
  text 'Snowmobiling'
69
- selection bind(@person, :snowmobiling)
69
+ selection <=> [@person, :snowmobiling]
70
70
  }
71
71
 
72
72
  checkbox {
73
73
  text 'Snowshoeing'
74
- selection bind(@person, :snowshoeing)
74
+ selection <=> [@person, :snowshoeing]
75
75
  }
76
76
  }
77
77