glimmer-dsl-swt 4.18.5.2 → 4.18.6.1

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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +38 -0
  3. data/README.md +8 -10
  4. data/VERSION +1 -1
  5. data/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md +93 -16
  6. data/docs/reference/GLIMMER_SAMPLES.md +32 -0
  7. data/glimmer-dsl-swt.gemspec +9 -3
  8. data/lib/glimmer/swt/custom/drawable.rb +8 -7
  9. data/lib/glimmer/swt/custom/shape.rb +416 -37
  10. data/lib/glimmer/swt/custom/shape/arc.rb +22 -4
  11. data/lib/glimmer/swt/custom/shape/cubic.rb +117 -0
  12. data/lib/glimmer/swt/custom/shape/image.rb +19 -6
  13. data/lib/glimmer/swt/custom/shape/line.rb +119 -1
  14. data/lib/glimmer/swt/custom/shape/oval.rb +3 -3
  15. data/lib/glimmer/swt/custom/shape/path.rb +211 -0
  16. data/lib/glimmer/swt/custom/shape/path_segment.rb +111 -0
  17. data/lib/glimmer/swt/custom/shape/point.rb +40 -4
  18. data/lib/glimmer/swt/custom/shape/polygon.rb +93 -3
  19. data/lib/glimmer/swt/custom/shape/polyline.rb +76 -4
  20. data/lib/glimmer/swt/custom/shape/quad.rb +113 -0
  21. data/lib/glimmer/swt/custom/shape/rectangle.rb +7 -2
  22. data/lib/glimmer/swt/custom/shape/text.rb +2 -4
  23. data/lib/glimmer/swt/dialog_proxy.rb +4 -0
  24. data/lib/glimmer/swt/proxy_properties.rb +1 -1
  25. data/lib/glimmer/swt/widget_proxy.rb +16 -0
  26. data/samples/elaborate/contact_manager.rb +2 -0
  27. data/samples/elaborate/login.rb +2 -0
  28. data/samples/elaborate/mandelbrot_fractal.rb +2 -1
  29. data/samples/elaborate/meta_sample.rb +1 -0
  30. data/samples/elaborate/stock_ticker.rb +229 -0
  31. data/samples/elaborate/tetris.rb +2 -1
  32. data/samples/elaborate/tic_tac_toe.rb +2 -0
  33. data/samples/elaborate/user_profile.rb +10 -8
  34. data/samples/hello/hello_browser.rb +2 -0
  35. data/samples/hello/hello_button.rb +2 -0
  36. data/samples/hello/hello_canvas.rb +40 -21
  37. data/samples/hello/hello_canvas_animation.rb +2 -0
  38. data/samples/hello/hello_canvas_path.rb +66 -0
  39. data/samples/hello/hello_canvas_transform.rb +2 -0
  40. data/samples/hello/hello_checkbox.rb +2 -0
  41. data/samples/hello/hello_checkbox_group.rb +2 -0
  42. data/samples/hello/hello_code_text.rb +2 -0
  43. data/samples/hello/hello_color_dialog.rb +2 -0
  44. data/samples/hello/hello_combo.rb +2 -0
  45. data/samples/hello/hello_computed.rb +2 -0
  46. data/samples/hello/hello_cursor.rb +2 -0
  47. data/samples/hello/hello_custom_shell.rb +1 -0
  48. data/samples/hello/hello_custom_widget.rb +2 -0
  49. data/samples/hello/hello_date_time.rb +2 -0
  50. data/samples/hello/hello_dialog.rb +2 -0
  51. data/samples/hello/hello_directory_dialog.rb +2 -0
  52. data/samples/hello/hello_drag_and_drop.rb +5 -3
  53. data/samples/hello/hello_expand_bar.rb +2 -0
  54. data/samples/hello/hello_file_dialog.rb +2 -0
  55. data/samples/hello/hello_font_dialog.rb +2 -0
  56. data/samples/hello/hello_group.rb +2 -0
  57. data/samples/hello/hello_link.rb +2 -0
  58. data/samples/hello/hello_list_multi_selection.rb +2 -0
  59. data/samples/hello/hello_list_single_selection.rb +2 -0
  60. data/samples/hello/hello_menu_bar.rb +2 -0
  61. data/samples/hello/hello_message_box.rb +2 -0
  62. data/samples/hello/hello_pop_up_context_menu.rb +2 -0
  63. data/samples/hello/hello_progress_bar.rb +2 -0
  64. data/samples/hello/hello_radio.rb +2 -0
  65. data/samples/hello/hello_radio_group.rb +2 -0
  66. data/samples/hello/hello_sash_form.rb +2 -0
  67. data/samples/hello/hello_spinner.rb +2 -0
  68. data/samples/hello/hello_styled_text.rb +19 -17
  69. data/samples/hello/hello_tab.rb +2 -0
  70. data/samples/hello/hello_table.rb +2 -0
  71. data/samples/hello/hello_world.rb +2 -0
  72. metadata +8 -2
@@ -34,6 +34,7 @@ module Glimmer
34
34
  class Shape
35
35
  class Rectangle < Shape
36
36
  def parameter_names
37
+ # TODO consider optimizing just like text where it is set upon updating attribute and here you just return a variable
37
38
  if @args.to_a.size >= 6
38
39
  rectangle_round_parameter_names
39
40
  elsif @args.to_a.size == 5
@@ -81,7 +82,11 @@ module Glimmer
81
82
  end
82
83
 
83
84
  def point_xy_array
84
- [[x, y], [x + width, y], [x + width, y + height], [x, y + height]]
85
+ [[x, y], [x + calculated_width, y], [x + calculated_width, y + calculated_height], [x, y + calculated_height]]
86
+ end
87
+
88
+ def absolute_point_xy_array
89
+ [[absolute_x, absolute_y], [absolute_x + calculated_width, absolute_y], [absolute_x + calculated_width, absolute_y + calculated_height], [absolute_x, absolute_y + calculated_height]]
85
90
  end
86
91
 
87
92
  # checks if drawn or filled rectangle includes the point denoted by x and y (if drawn, it only returns true if point lies on the edge)
@@ -89,7 +94,7 @@ module Glimmer
89
94
  if filled?
90
95
  contain?(x, y)
91
96
  else
92
- comparison_lines = point_xy_array.zip(point_xy_array.rotate(1))
97
+ comparison_lines = absolute_point_xy_array.zip(absolute_point_xy_array.rotate(1))
93
98
  comparison_lines.any? {|line| Line.include?(line.first.first, line.first.last, line.last.first, line.last.last, x, y)}
94
99
  end
95
100
  end
@@ -33,8 +33,6 @@ module Glimmer
33
33
  # That is because Shape is drawn on a parent as graphics and doesn't have an SWT widget for itself
34
34
  class Shape
35
35
  class Text < Shape
36
- attr_accessor :extent
37
-
38
36
  def parameter_names
39
37
  @parameter_names || text_parameter_names
40
38
  end
@@ -69,11 +67,11 @@ module Glimmer
69
67
  end
70
68
 
71
69
  def width
72
- extent&.x
70
+ @extent&.x
73
71
  end
74
72
 
75
73
  def height
76
- extent&.y
74
+ @extent&.y
77
75
  end
78
76
 
79
77
  end
@@ -52,6 +52,10 @@ module Glimmer
52
52
  def dialog_class(keyword)
53
53
  the_class = eval(keyword.camelcase(:upper))
54
54
  the_class if the_class.ancestors.include?(org.eclipse.swt.widgets.Dialog)
55
+ rescue => e
56
+ Glimmer::Config.logger.debug {"Dialog for keyword #{keyword} not found!"}
57
+ Glimmer::Config.logger.debug { e.full_message }
58
+ nil
55
59
  end
56
60
  end
57
61
 
@@ -73,7 +73,7 @@ module Glimmer
73
73
  Glimmer::SWT::DisplayProxy.instance.auto_exec do
74
74
  result = if proxy_source_object&.respond_to?(attribute_setter(attribute_name))
75
75
  swt_widget_operation = true
76
- proxy_source_object&.send(attribute_setter(attribute_name), *args) unless proxy_source_object&.send(attribute_getter(attribute_name)) == args.first
76
+ proxy_source_object&.send(attribute_setter(attribute_name), *args) unless (proxy_source_object&.respond_to?(attribute_getter(attribute_name)) && proxy_source_object&.send(attribute_getter(attribute_name))) == args.first
77
77
  elsif proxy_source_object&.respond_to?(ruby_attribute_setter(attribute_name))
78
78
  swt_widget_operation = true
79
79
  proxy_source_object&.send(ruby_attribute_setter(attribute_name), args)
@@ -291,6 +291,22 @@ module Glimmer
291
291
  @swt_widget.removeControlListener(listener.swt_listener)
292
292
  end
293
293
  end
294
+
295
+ def x
296
+ bounds.x
297
+ end
298
+
299
+ def y
300
+ bounds.y
301
+ end
302
+
303
+ def width
304
+ bounds.width
305
+ end
306
+
307
+ def height
308
+ bounds.height
309
+ end
294
310
 
295
311
  # these work in tandem with the property_type_converters
296
312
  # sometimes, they are specified in subclasses instead
@@ -19,6 +19,8 @@
19
19
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
20
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
+ require 'glimmer-dsl-swt'
23
+
22
24
  require_relative "contact_manager/contact_manager_presenter"
23
25
 
24
26
  class ContactManager
@@ -19,6 +19,8 @@
19
19
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
20
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
+ require 'glimmer-dsl-swt'
23
+
22
24
  class LoginPresenter
23
25
 
24
26
  attr_accessor :user_name
@@ -19,6 +19,7 @@
19
19
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
20
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
+ require 'glimmer-dsl-swt'
22
23
  require 'complex'
23
24
  require 'concurrent-ruby'
24
25
 
@@ -378,7 +379,7 @@ class MandelbrotFractal
378
379
  image @mandelbrot_image
379
380
  }
380
381
  @canvas.set_size @mandelbrot_image.bounds.width, @mandelbrot_image.bounds.height
381
- @scrolled_composite.swt_widget.set_min_size(Point.new(@mandelbrot_image.bounds.width, @mandelbrot_image.bounds.height))
382
+ @scrolled_composite.set_min_size(Point.new(@mandelbrot_image.bounds.width, @mandelbrot_image.bounds.height))
382
383
  if @location_x && @location_y
383
384
  # center on mouse click location
384
385
  factor = (zoom / last_zoom)
@@ -19,6 +19,7 @@
19
19
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
20
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
+ require 'glimmer-dsl-swt'
22
23
  require 'fileutils'
23
24
 
24
25
  class Sample
@@ -0,0 +1,229 @@
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
+ # This Sample is an Early Alpha (New Canvas Path DSL Feature)
25
+
26
+ class StockTicker
27
+ class Stock
28
+ class << self
29
+ attr_writer :stock_price_min, :stock_price_max
30
+
31
+ def stock_price_min
32
+ @stock_price_min ||= 1
33
+ end
34
+
35
+ def stock_price_max
36
+ @stock_price_max ||= 600
37
+ end
38
+ end
39
+
40
+ attr_reader :name, :stock_prices
41
+ attr_accessor :stock_price
42
+
43
+ def initialize(name, stock_price)
44
+ @name = name
45
+ @stock_price = stock_price
46
+ @stock_prices = [@stock_price]
47
+ @delta_sign = 1
48
+ start_new_trend!
49
+ end
50
+
51
+ def tick!
52
+ @tick_count = @tick_count.to_i + 1
53
+ delta = @tick_count%@trend_length
54
+ if delta == 0
55
+ @delta_sign *= -1
56
+ start_new_trend!
57
+ end
58
+ stock_prices << self.stock_price = [[@stock_price + @delta_sign*delta, Stock.stock_price_min].max, Stock.stock_price_max].min
59
+ end
60
+
61
+ def start_new_trend!
62
+ @trend_length = (rand*12).to_i + 1
63
+ end
64
+ end
65
+
66
+ include Glimmer::UI::CustomShell
67
+
68
+ before_body {
69
+ @stocks = [
70
+ Stock.new('DELL', 81),
71
+ Stock.new('AAPL', 121),
72
+ Stock.new('MSFT', 232),
73
+ Stock.new('ADBE', 459),
74
+ ]
75
+ @stock_colors = [:red, :dark_green, :blue, :dark_magenta]
76
+ max_stock_name_width = 0
77
+ left_margin = 5
78
+ @tabs = ['Lines', 'Quadratic Bezier Curves', 'Cubic Bezier Curves', 'Points'].map {|title| {title: title, stock_paths: [], stock_transforms: []}}
79
+ @stocks.each_with_index do |stock, stock_index|
80
+ observe(stock, :stock_price) do |new_price|
81
+ begin
82
+ @tabs.each do |tab|
83
+ new_x = stock.stock_prices.count - 1
84
+ new_y = @tabs.first[:canvas].bounds.height - new_price - 1
85
+ max_stock_name_width = tab[:text]&.bounds&.width if tab[:text]&.bounds&.width.to_f > max_stock_name_width
86
+ if new_x > 0
87
+ case tab[:title]
88
+ when 'Cubic Bezier Curves'
89
+ if new_x%3 == 0 && stock.stock_prices[new_x] && stock.stock_prices[new_x - 1] && stock.stock_prices[new_x - 2]
90
+ tab[:stock_paths][stock_index].content {
91
+ cubic(new_x - 2, @tabs.first[:canvas].bounds.height - stock.stock_prices[new_x - 2] - 1, new_x - 1, @tabs.first[:canvas].bounds.height - stock.stock_prices[new_x - 1] - 1, new_x, new_y)
92
+ tab[:stock_transforms][stock_index] ||= transform {
93
+ translate max_stock_name_width + 5 + left_margin, tab[:text].bounds.height / 2.0
94
+ }
95
+ }
96
+ end
97
+ when 'Quadratic Bezier Curves'
98
+ if new_x%2 == 0 && stock.stock_prices[new_x] && stock.stock_prices[new_x - 1]
99
+ tab[:stock_paths][stock_index].content {
100
+ quad(new_x - 1, @tabs.first[:canvas].bounds.height - stock.stock_prices[new_x - 1] - 1, new_x, new_y)
101
+ tab[:stock_transforms][stock_index] ||= transform {
102
+ translate max_stock_name_width + 5 + left_margin, tab[:text].bounds.height / 2.0
103
+ }
104
+ }
105
+ end
106
+ when 'Lines'
107
+ tab[:stock_paths][stock_index].content {
108
+ line(new_x, new_y)
109
+ tab[:stock_transforms][stock_index] ||= transform {
110
+ translate max_stock_name_width + 5 + left_margin, tab[:text].bounds.height / 2.0
111
+ }
112
+ }
113
+ when 'Points'
114
+ tab[:stock_paths][stock_index].content {
115
+ point(new_x, new_y)
116
+ tab[:stock_transforms][stock_index] ||= transform {
117
+ translate max_stock_name_width + 5 + left_margin, tab[:text].bounds.height / 2.0
118
+ }
119
+ }
120
+ end
121
+ new_x_location = new_x + max_stock_name_width + 5 + left_margin + 5
122
+ canvas_width = tab[:canvas].bounds.width
123
+ if new_x_location > canvas_width
124
+ tab[:canvas].set_size(new_x_location, @tabs.first[:canvas].bounds.height)
125
+ tab[:canvas].cursor = :hand
126
+ tab[:scrolled_composite].set_min_size(new_x_location, @tabs.first[:canvas].bounds.height)
127
+ tab[:scrolled_composite].set_origin(tab[:scrolled_composite].origin.x + 1, tab[:scrolled_composite].origin.y) if (tab[:scrolled_composite].origin.x + tab[:scrolled_composite].client_area.width) == canvas_width
128
+ end
129
+ else
130
+ tab[:canvas].content {
131
+ tab[:text] = text(stock.name, new_x + left_margin, new_y) {
132
+ foreground @stock_colors[stock_index]
133
+ }
134
+ }
135
+ end
136
+ end
137
+ rescue => e
138
+ Glimmer::Config.logger.error {e.full_message}
139
+ end
140
+ end
141
+ end
142
+ }
143
+
144
+ after_body {
145
+ @thread = Thread.new {
146
+ loop {
147
+ @stocks.each(&:tick!)
148
+ sleep(0.01)
149
+ }
150
+ }
151
+ }
152
+
153
+ body {
154
+ shell {
155
+ fill_layout {
156
+ margin_width 15
157
+ margin_height 15
158
+ }
159
+ text 'Stock Ticker'
160
+ minimum_size 650, 650
161
+ background :white
162
+
163
+ @tab_folder = tab_folder {
164
+ @tabs.each do |tab|
165
+ tab_item {
166
+ fill_layout {
167
+ margin_width 0
168
+ margin_height 0
169
+ }
170
+ text tab[:title]
171
+
172
+ tab[:scrolled_composite] = scrolled_composite {
173
+ tab[:canvas] = canvas {
174
+ background :white
175
+
176
+ @stocks.count.times do |stock_index|
177
+ tab[:stock_paths][stock_index] = path {
178
+ antialias :on
179
+ foreground @stock_colors[stock_index]
180
+ }
181
+ end
182
+
183
+ on_mouse_down {
184
+ @drag_detected = false
185
+ }
186
+
187
+ on_drag_detected { |drag_detect_event|
188
+ @drag_detected = true
189
+ @drag_start_x = drag_detect_event.x
190
+ @drag_start_y = drag_detect_event.y
191
+ }
192
+
193
+ on_mouse_move { |mouse_event|
194
+ if @drag_detected
195
+ origin = tab[:scrolled_composite].origin
196
+ new_x = origin.x - (mouse_event.x - @drag_start_x)
197
+ new_y = origin.y - (mouse_event.y - @drag_start_y)
198
+ tab[:scrolled_composite].set_origin(new_x, new_y)
199
+ end
200
+ }
201
+
202
+ on_mouse_up { |mouse_event|
203
+ @drag_detected = false
204
+ }
205
+ }
206
+ }
207
+ }
208
+ end
209
+ }
210
+
211
+ on_swt_show {
212
+ Stock.stock_price_min = 25
213
+ Stock.stock_price_max = @tabs.first[:canvas].bounds.height - 6
214
+ # pre-initialize all tabs by selecting them so that they render content when they are later in the background
215
+ @tab_folder.items.each do |item|
216
+ @tab_folder.selection = item
217
+ end
218
+ @tab_folder.selection = @tab_folder.items.first
219
+ }
220
+
221
+ on_widget_disposed {
222
+ @thread.kill # safe to kill as data is in memory only
223
+ }
224
+ }
225
+ }
226
+ end
227
+
228
+ StockTicker.launch
229
+
@@ -19,7 +19,7 @@
19
19
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
20
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
- # Tetris App View Custom Shell (represents `tetris` keyword)
22
+ require 'glimmer-dsl-swt'
23
23
 
24
24
  require_relative 'tetris/model/game'
25
25
 
@@ -28,6 +28,7 @@ require_relative 'tetris/view/score_lane'
28
28
  require_relative 'tetris/view/high_score_dialog'
29
29
  require_relative 'tetris/view/tetris_menu_bar'
30
30
 
31
+ # Tetris App View Custom Shell (represents `tetris` keyword)
31
32
  class Tetris
32
33
  include Glimmer::UI::CustomShell
33
34
 
@@ -19,6 +19,8 @@
19
19
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
20
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
+ require 'glimmer-dsl-swt'
23
+
22
24
  require_relative "tic_tac_toe/board"
23
25
 
24
26
  class TicTacToe
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2007-2021 Andy Maleh
2
- #
2
+ #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining
4
4
  # a copy of this software and associated documentation files (the
5
5
  # "Software"), to deal in the Software without restriction, including
@@ -7,10 +7,10 @@
7
7
  # distribute, sublicense, and/or sell copies of the Software, and to
8
8
  # permit persons to whom the Software is furnished to do so, subject to
9
9
  # the following conditions:
10
- #
10
+ #
11
11
  # The above copyright notice and this permission notice shall be
12
12
  # included in all copies or substantial portions of the Software.
13
- #
13
+ #
14
14
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
15
  # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
16
  # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -19,6 +19,8 @@
19
19
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
20
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
+ require 'glimmer-dsl-swt'
23
+
22
24
  include Glimmer
23
25
 
24
26
  shell {
@@ -32,21 +34,21 @@ shell {
32
34
  grid_layout 2, false
33
35
  layout_data :fill, :fill, true, true
34
36
  label {text "First"}; text {text "Bullet"}
35
- label {text "Last"}; text {text "Tooth"}
37
+ label {text "Last"}; text {text "Tooth"}
36
38
  }
37
39
 
38
40
  group {
39
41
  layout_data :fill, :fill, true, true
40
42
  text "Gender"
41
43
  radio {text "Male"; selection true}
42
- radio {text "Female"}
44
+ radio {text "Female"}
43
45
  }
44
46
 
45
47
  group {
46
48
  layout_data :fill, :fill, true, true
47
49
  text "Role"
48
50
  check {text "Student"; selection true}
49
- check {text "Employee"; selection true}
51
+ check {text "Employee"; selection true}
50
52
  }
51
53
 
52
54
  group {
@@ -59,11 +61,11 @@ shell {
59
61
  button {
60
62
  text "save"
61
63
  layout_data :right, :center, true, true
62
- on_widget_selected {
64
+ on_widget_selected {
63
65
  message_box {
64
66
  text 'Profile Saved!'
65
67
  message 'User profile has been saved!'
66
- }.open
68
+ }.open
67
69
  }
68
70
  }
69
71