glimmer-dsl-swt 4.19.0.2 → 4.20.0.4

Sign up to get free protection for your applications and to get access to all the features.
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
Binary file
@@ -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,26 +19,41 @@
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
- ## NOTE: Unsupported for now TODO support in the future
23
- #
24
- # require File.dirname(__FILE__) + "/glimmer"
25
- #
26
- # class Array
27
- # include Glimmer
28
- #
29
- # alias original_compare <=>
30
- #
31
- # def <=>(other)
32
- # if (self[0].class.name == "WidgetProxy")
33
- # content(self[0]) {
34
- # if (other.size == 2)
35
- # eval("#{self[1]} bind (other[0], other[1])")
36
- # elsif (other.size == 3)
37
- # eval("#{self[1]} bind (other[0], other[1], other[2])")
38
- # end
39
- # }
40
- # else
41
- # original_compare(other)
42
- # end
43
- # end
44
- # end
22
+ module Glimmer
23
+ module DataBinding
24
+ class Shine
25
+ include Glimmer
26
+
27
+ def initialize(parent, parent_attribute)
28
+ @parent = parent
29
+ @parent_attribute = parent_attribute
30
+ end
31
+
32
+ alias original_compare <=>
33
+
34
+ def <=>(other)
35
+ if other.is_a?(Array)
36
+ @parent.content {
37
+ send(@parent_attribute, bind(*other))
38
+ }
39
+ else # || other.is_a?(Hash) # TODO support hash e.g. {model: model_obj, attribute: :some_attribute, more-options...}
40
+ original_compare(other)
41
+ end
42
+ end
43
+
44
+ def <=(other)
45
+ if other.is_a?(Array)
46
+ args_clone = other.clone
47
+ if args_clone.last.is_a?(Hash)
48
+ args_clone.last[:read_only] = true
49
+ else # || other.is_a?(Hash) # TODO support hash e.g. {model: model_obj, attribute: :some_attribute, more-options...}
50
+ args_clone << {read_only: true}
51
+ end
52
+ @parent.content {
53
+ send(@parent_attribute, bind(*args_clone))
54
+ }
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -20,7 +20,7 @@
20
20
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
22
  require 'glimmer/launcher'
23
- require Glimmer::Launcher.swt_jar_file
23
+ require ENV['SWT_JAR_FILE_PATH'] || "#{Glimmer::Launcher.swt_jar_file}#{Glimmer::Launcher.special_cpu_architecture_suffix}"
24
24
  require 'glimmer/dsl/engine'
25
25
  Dir[File.expand_path('../*_expression.rb', __FILE__)].each {|f| require f}
26
26
 
@@ -52,6 +52,7 @@ module Glimmer
52
52
  image
53
53
  multiply
54
54
  property
55
+ shine_data_binding
55
56
  block_property
56
57
  dialog
57
58
  widget
@@ -0,0 +1,49 @@
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/expression'
23
+ require 'glimmer/data_binding/model_binding'
24
+ require 'glimmer/data_binding/widget_binding'
25
+ require 'glimmer/swt/display_proxy'
26
+ require 'glimmer/data_binding/shine'
27
+
28
+ module Glimmer
29
+ module DSL
30
+ module SWT
31
+ class ShineDataBindingExpression < Expression
32
+ def can_interpret?(parent, keyword, *args, &block)
33
+ args.size == 0 and
34
+ block.nil? and
35
+ parent.respond_to?(:set_attribute) and
36
+ parent.respond_to?(:has_attribute?) and
37
+ parent.has_attribute?(keyword, *args) and
38
+ !parent.is_a?(Glimmer::UI::CustomWidget) and
39
+ !parent.is_a?(Glimmer::UI::CustomShape) and
40
+ !(parent.respond_to?(:swt_widget) && parent.swt_widget.class == org.eclipse.swt.widgets.Canvas && keyword == 'image')
41
+ end
42
+
43
+ def interpret(parent, keyword, *args, &block)
44
+ Glimmer::DataBinding::Shine.new(parent, keyword)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -70,3 +70,5 @@ require 'glimmer/swt/sash_form_proxy'
70
70
  require 'glimmer/swt/styled_text_proxy'
71
71
  require 'glimmer/swt/date_time_proxy'
72
72
  require 'glimmer/swt/tab_folder_proxy'
73
+ require 'glimmer/swt/combo_proxy'
74
+ require 'glimmer/swt/tool_bar_proxy'
@@ -71,6 +71,12 @@ module Glimmer
71
71
  def platform_os
72
72
  OPERATING_SYSTEMS_SUPPORTED.detect {|os| OS.send("#{os}?")}
73
73
  end
74
+
75
+ def special_cpu_architecture_suffix
76
+ host_cpu = OS.host_cpu.downcase
77
+ special = host_cpu.include?('aarch64') || host_cpu.include?('arm')
78
+ special ? "_aarch64" : ''
79
+ end
74
80
 
75
81
  def swt_jar_file
76
82
  @swt_jar_file ||= File.expand_path(File.join(__FILE__, '..', '..', '..', 'vendor', 'swt', platform_os, 'swt.jar'))
@@ -441,8 +441,6 @@ module Glimmer
441
441
  require '#{file_name(app_name)}/view/app_view'
442
442
 
443
443
  class #{class_name(app_name)}
444
- include Glimmer
445
-
446
444
  APP_ROOT = File.expand_path('../..', __FILE__)
447
445
  VERSION = File.read(File.join(APP_ROOT, 'VERSION'))
448
446
  LICENSE = File.read(File.join(APP_ROOT, 'LICENSE.txt'))
@@ -0,0 +1,48 @@
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/swt/widget_proxy'
23
+
24
+ module Glimmer
25
+ module SWT
26
+ # Proxy for org.eclipse.swt.widgets.Combo
27
+ #
28
+ # Follows the Proxy Design Pattern
29
+ class ComboProxy < WidgetProxy
30
+ attr_accessor :tool_item_proxy, :swt_tool_item
31
+
32
+ def initialize(*init_args, &block)
33
+ super
34
+ self.tool_item_proxy = WidgetProxy.new("tool_item", parent_proxy, [:separator]) if parent_proxy.swt_widget.is_a?(ToolBar)
35
+ self.swt_tool_item = tool_item_proxy&.swt_widget
36
+ end
37
+
38
+ def post_add_content
39
+ if self.tool_item_proxy
40
+ self.swt_widget.pack
41
+ self.tool_item_proxy.text = 'filler' # text seems needed (any text works)
42
+ self.tool_item_proxy.width = swt_widget.size.x
43
+ self.tool_item_proxy.control = swt_widget
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -124,21 +124,15 @@ module Glimmer
124
124
 
125
125
  @line_numbers_styled_text_proxy = styled_text(swt(swt(swt_style), :h_scroll!, :v_scroll!)) {
126
126
  layout_data(:right, :fill, false, true)
127
- top_pixel_before_read = nil
127
+
128
128
  text bind(self,
129
129
  :styled_text_proxy_text,
130
130
  read_only: true,
131
131
  on_read: lambda { |text_value|
132
- line_count = "#{text_value} ".split("\n").count
133
- line_count = 1 if line_count == 0
134
- lines_text_size = [line_count.to_s.size, @lines_width].max
135
- if lines_text_size > @lines_width
136
- @lines_width = lines_text_size
137
- end
138
- line_count.times.map {|n| (' ' * (lines_text_size - (n+1).to_s.size)) + (n+1).to_s }.join("\n") + "\n"
132
+ line_numbers_text_from(text_value)
139
133
  },
140
134
  after_read: lambda {
141
- @line_numbers_styled_text_proxy&.top_pixel = styled_text_proxy_top_pixel
135
+ @line_numbers_styled_text_proxy&.top_pixel = styled_text_proxy_top_pixel unless styled_text_proxy_top_pixel.nil?
142
136
  }
143
137
  )
144
138
  top_pixel bind(self, :styled_text_proxy_top_pixel, read_only: true)
@@ -151,6 +145,7 @@ module Glimmer
151
145
  left_margin 5
152
146
  editable false
153
147
  caret nil
148
+
154
149
  on_focus_gained {
155
150
  @styled_text_proxy&.setFocus
156
151
  }
@@ -173,6 +168,7 @@ module Glimmer
173
168
  @styled_text_proxy = styled_text(swt_style) {
174
169
  # custom_widget_property_owner # TODO implement to route properties here without declaring method_missing
175
170
  layout_data :fill, :fill, true, true if lines
171
+
176
172
  text bind(self, :styled_text_proxy_text) if lines
177
173
  top_pixel bind(self, :styled_text_proxy_top_pixel) if lines
178
174
  font name: @font_name, height: OS.mac? ? 15 : 12
@@ -291,6 +287,14 @@ module Glimmer
291
287
  new_offset = beginning_of_current_line_offset + current_line.size
292
288
  @styled_text_proxy.setSelection(new_offset, new_offset)
293
289
  end
290
+
291
+ def line_numbers_text_from(text_value)
292
+ line_count = "#{text_value} ".split("\n").count
293
+ line_count = 1 if line_count == 0
294
+ lines_text_size = [line_count.to_s.size, @lines_width].max
295
+ @lines_width = lines_text_size if lines_text_size > @lines_width
296
+ line_count.times.map {|n| (' ' * (lines_text_size - (n+1).to_s.size)) + (n+1).to_s }.join("\n") + "\n"
297
+ end
294
298
  end
295
299
  end
296
300
  end
@@ -0,0 +1,51 @@
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/swt/widget_proxy'
23
+
24
+ module Glimmer
25
+ module SWT
26
+ # Proxy for org.eclipse.swt.widgets.ToolBarProxy
27
+ #
28
+ # Follows the Proxy Design Pattern
29
+ class ToolBarProxy < WidgetProxy
30
+ attr_accessor :cool_item_proxy, :swt_cool_item
31
+
32
+ def initialize(*init_args, &block)
33
+ super
34
+ self.cool_item_proxy = WidgetProxy.new("cool_item", parent_proxy, []) if parent_proxy.swt_widget.is_a?(CoolBar)
35
+ self.swt_cool_item = cool_item_proxy&.swt_widget
36
+ end
37
+
38
+ def post_add_content
39
+ apply_preferred_size if cool_item_proxy
40
+ end
41
+
42
+ def apply_preferred_size
43
+ swt_widget.pack
44
+ size = swt_widget.size
45
+ cool_item_proxy.control = swt_widget
46
+ preferred = swt_cool_item.computeSize(size.x, size.y)
47
+ swt_cool_item.setPreferredSize(preferred)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -1006,6 +1006,12 @@ module Glimmer
1006
1006
  image: lambda do |*value|
1007
1007
  ImageProxy.create(*value).swt_image
1008
1008
  end,
1009
+ disabled_image: lambda do |*value|
1010
+ ImageProxy.create(*value).swt_image
1011
+ end,
1012
+ hot_image: lambda do |*value|
1013
+ ImageProxy.create(*value).swt_image
1014
+ end,
1009
1015
  images: lambda do |array|
1010
1016
  array.to_a.map do |value|
1011
1017
  ImageProxy.create(value).swt_image
@@ -51,7 +51,7 @@ class ContactManager
51
51
  }
52
52
  text {
53
53
  layout_data :fill, :center, true, false
54
- text bind(@contact_manager_presenter, :first_name)
54
+ text <=> [@contact_manager_presenter, :first_name]
55
55
  on_key_pressed {|key_event|
56
56
  @contact_manager_presenter.find if key_event.keyCode == swt(:cr)
57
57
  }
@@ -64,7 +64,7 @@ class ContactManager
64
64
  }
65
65
  text {
66
66
  layout_data :fill, :center, true, false
67
- text bind(@contact_manager_presenter, :last_name)
67
+ text <=> [@contact_manager_presenter, :last_name]
68
68
  on_key_pressed {|key_event|
69
69
  @contact_manager_presenter.find if key_event.keyCode == swt(:cr)
70
70
  }
@@ -77,7 +77,7 @@ class ContactManager
77
77
  }
78
78
  text {
79
79
  layout_data :fill, :center, true, false
80
- text bind(@contact_manager_presenter, :email)
80
+ text <=> [@contact_manager_presenter, :email]
81
81
  on_key_pressed {|key_event|
82
82
  @contact_manager_presenter.find if key_event.keyCode == swt(:cr)
83
83
  }
@@ -118,6 +118,7 @@ class ContactManager
118
118
  grab_excess_vertical_space true
119
119
  height_hint 200
120
120
  }
121
+
121
122
  table_column {
122
123
  text "First Name"
123
124
  width 80
@@ -130,8 +131,9 @@ class ContactManager
130
131
  text "Email"
131
132
  width 200
132
133
  }
133
- items bind(@contact_manager_presenter, :results),
134
- column_properties(:first_name, :last_name, :email)
134
+
135
+ items bind(@contact_manager_presenter, :results), column_properties(:first_name, :last_name, :email)
136
+
135
137
  on_mouse_up { |event|
136
138
  table_proxy.edit_table_item(event.table_item, event.column_index)
137
139
  }
@@ -35,24 +35,19 @@ class LoginPresenter
35
35
 
36
36
  def status=(status)
37
37
  @status = status
38
-
39
- notify_observers("logged_in")
40
- notify_observers("logged_out")
41
38
  end
42
39
 
43
40
  def valid?
44
41
  !@user_name.to_s.strip.empty? && !@password.to_s.strip.empty?
45
42
  end
46
43
 
47
- def logged_in
44
+ def logged_in?
48
45
  self.status == "Logged In"
49
46
  end
50
- alias logged_in? logged_in
51
47
 
52
- def logged_out
53
- !self.logged_in
48
+ def logged_out?
49
+ !self.logged_in?
54
50
  end
55
- alias logged_out? logged_out
56
51
 
57
52
  def login!
58
53
  return unless valid?
@@ -77,13 +72,15 @@ class Login
77
72
  body {
78
73
  shell {
79
74
  text "Login"
75
+
80
76
  composite {
81
77
  grid_layout 2, false #two columns with differing widths
82
78
 
83
79
  label { text "Username:" } # goes in column 1
84
80
  @user_name_text = text { # goes in column 2
85
- text bind(@presenter, :user_name)
86
- enabled bind(@presenter, :logged_out)
81
+ text <=> [@presenter, :user_name]
82
+ enabled <= [@presenter, :logged_out?, computed_by: :status]
83
+
87
84
  on_key_pressed { |event|
88
85
  @password_text.set_focus if event.keyCode == swt(:cr)
89
86
  }
@@ -91,28 +88,33 @@ class Login
91
88
 
92
89
  label { text "Password:" }
93
90
  @password_text = text(:password, :border) {
94
- text bind(@presenter, :password)
95
- enabled bind(@presenter, :logged_out)
91
+ text <=> [@presenter, :password]
92
+ enabled <= [@presenter, :logged_out?, computed_by: :status]
93
+
96
94
  on_key_pressed { |event|
97
95
  @presenter.login! if event.keyCode == swt(:cr)
98
96
  }
99
97
  }
100
98
 
101
99
  label { text "Status:" }
102
- label { text bind(@presenter, :status) }
100
+ label { text <= [@presenter, :status] }
103
101
 
104
102
  button {
105
103
  text "Login"
106
- enabled bind(@presenter, :logged_out)
104
+ enabled <= [@presenter, :logged_out?, computed_by: :status]
105
+
107
106
  on_widget_selected { @presenter.login! }
108
107
  on_key_pressed { |event|
109
- @presenter.login! if event.keyCode == swt(:cr)
108
+ if event.keyCode == swt(:cr)
109
+ @presenter.login!
110
+ end
110
111
  }
111
112
  }
112
113
 
113
114
  button {
114
115
  text "Logout"
115
- enabled bind(@presenter, :logged_in)
116
+ enabled <= [@presenter, :logged_in?, computed_by: :status]
117
+
116
118
  on_widget_selected { @presenter.logout! }
117
119
  on_key_pressed { |event|
118
120
  if event.keyCode == swt(:cr)