glimmer-dsl-opal 0.25.2 → 0.26.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/README.md +46 -9
  4. data/VERSION +1 -1
  5. data/lib/glimmer/dsl/opal/combo_selection_data_binding_expression.rb +3 -3
  6. data/lib/glimmer/dsl/opal/menu_expression.rb +0 -3
  7. data/lib/glimmer/swt/c_combo_proxy.rb +30 -1
  8. data/lib/glimmer/swt/combo_proxy.rb +10 -2
  9. data/lib/glimmer/swt/control_editor.rb +2 -2
  10. data/lib/glimmer/swt/dialog_proxy.rb +11 -4
  11. data/lib/glimmer/swt/display_proxy.rb +18 -3
  12. data/lib/glimmer/swt/shell_proxy.rb +28 -1
  13. data/lib/glimmer/swt/table_item_proxy.rb +0 -20
  14. data/lib/glimmer/swt/table_proxy.rb +4 -0
  15. data/lib/glimmer/swt/widget_proxy.rb +48 -7
  16. data/lib/glimmer/ui/custom_shell.rb +2 -0
  17. data/lib/glimmer/ui/custom_widget.rb +2 -0
  18. data/lib/glimmer-dsl-opal/samples/elaborate/login.rb +3 -5
  19. data/lib/glimmer-dsl-opal/samples/elaborate/tetris/model/block.rb +48 -0
  20. data/lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb +275 -0
  21. data/lib/glimmer-dsl-opal/samples/elaborate/tetris/model/past_game.rb +39 -0
  22. data/lib/glimmer-dsl-opal/samples/elaborate/tetris/model/tetromino.rb +329 -0
  23. data/lib/glimmer-dsl-opal/samples/elaborate/tetris/view/block.rb +36 -0
  24. data/lib/glimmer-dsl-opal/samples/elaborate/tetris/view/high_score_dialog.rb +122 -0
  25. data/lib/glimmer-dsl-opal/samples/elaborate/tetris/view/playfield.rb +56 -0
  26. data/lib/glimmer-dsl-opal/samples/elaborate/tetris/view/score_lane.rb +83 -0
  27. data/lib/glimmer-dsl-opal/samples/elaborate/tetris/view/tetris_menu_bar.rb +136 -0
  28. data/lib/glimmer-dsl-opal/samples/elaborate/tetris.rb +150 -0
  29. data/lib/glimmer-dsl-opal/samples/hello/hello_custom_widget.rb +1 -1
  30. data/lib/glimmer-dsl-opal.rb +1 -0
  31. metadata +14 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 98f731b5aabef981ca377d64bbd87ca7a86a5f8edd4d0de428c81aeabe8680bf
4
- data.tar.gz: 7f7cc811ff007c65a15749a53e4b51b5ae194ffc06714d7e07c101d2c40c5484
3
+ metadata.gz: e1bec8104295a4c2f4a5b3f6d1464c9e0b0f5175092e93b7dd9508a5c4feabd0
4
+ data.tar.gz: 778f2026c647b7454d0586cf2310297d143d122a4b8937ec6189abdba260667d
5
5
  SHA512:
6
- metadata.gz: c71b8149524cbcd0b44319f24eb22e50476a6891cf479245d2632c3a367b97828b8197132092d0dd1389b5b79e7bf1e3a2abb5b787ad18d62655663252645fce
7
- data.tar.gz: 18328ff77046a9fa0fd42abffd15c9251c0a9eed4886071c048fcd2320c1828d7033237cc76abbb2548e52cdb3c4d5ed3f3e235eca66af2a49c8eadca6b0d20c
6
+ metadata.gz: 33e3f1b4bd51b3cfdc34d9f24403bb47d0a889c235e169232a3e8b8dae6db26617110dd55f8ed4a40d752c2e5f60569ea70c2b95db7a4435f1a2fddac25e3d7f
7
+ data.tar.gz: 8fafbadda7e92fcf19ac96b994e3dcb67ed25febcdd521a97e94f57a66f272312cbc6763a341c30b1f1cf46e27ff62928eaed02cf8f1aa91c72590794e6ec7ee
data/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.26.1
4
+
5
+ - Support display on_swt_keydown event keyCode/key_code values for arrow keys and alt/shift/ctrl
6
+ - Use arrow keys for movement in Tetris
7
+ - Use alt/shift keys for rotate right in Tetris
8
+
9
+ ## 0.26.0
10
+
11
+ - Tetris elaborate sample (minimal initial version of the one in Glimmer DSL for SWT)
12
+ - Support `menu_item` `selection` attribute data-binding for `:check` and `:radio` SWT styles
13
+ - Set 'custom_shell' data for custom shell on its body_root
14
+ - Provide parent_proxy on custom widgets as an alternative to parent for compatibility with Glimmer DSL for SWT
15
+ - Have custom widgets derive their parent from body root if not passed in explicitly
16
+
17
+ ## 0.25.4
18
+
19
+ - Upgrade to opal-async 1.4.0
20
+ - Update Hello, Custom Widget! to utilize `Array#async_cycle` instead of `Array#cycle`
21
+
22
+ ## 0.25.3
23
+
24
+ - Fix `c_combo`'s data-binding of selection receiving model changes
25
+ - Fix Hello, C Combo!'s reset button
26
+ - Fix Login sample by removing unnecessary require statement at the top
27
+
3
28
  ## 0.25.2
4
29
 
5
30
  - Fix sizing of buttons with font height specified to fit text
data/README.md CHANGED
@@ -12,6 +12,8 @@ Use in one of two ways:
12
12
 
13
13
  Glimmer DSL for Opal successfully reuses the entire [Glimmer](https://github.com/AndyObtiva/glimmer) core DSL engine in [Opal Ruby](https://opalrb.com/) inside a web browser, and as such inherits the full range of Glimmer desktop [data-binding](https://github.com/AndyObtiva/glimmer#data-binding) capabilities for the web (including Shine syntax using `<=>` and `<=` for bidirectional [two-way] and unidirectional [one-way] data-binding respectively).
14
14
 
15
+ (note that auto-webification of desktop apps that involve multiple threads might involve extra changes to the code to utilize web async calls due to the async nature of transpiled JavaScript code)
16
+
15
17
  #### Hello, Table! Sample
16
18
 
17
19
  Code: [lib/glimmer-dsl-opal/samples/hello/hello_table.rb](lib/glimmer-dsl-opal/samples/hello/hello_table.rb)
@@ -143,7 +145,7 @@ Hello, Table! Game Booked
143
145
 
144
146
  NOTE: Glimmer DSL for Opal is an alpha project. Please help make better by contributing, adopting for small or low risk projects, and providing feedback. It is still an early alpha, so the more feedback and issues you report the better.
145
147
 
146
- **Alpha Version** 0.25.1 only supports bare-minimum capabilities for the included [samples](https://github.com/AndyObtiva/glimmer-dsl-opal#samples) (originally written for [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt))
148
+ **Alpha Version** 0.26.1 only supports bare-minimum capabilities for the included [samples](https://github.com/AndyObtiva/glimmer-dsl-opal#samples) (originally written for [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt))
147
149
 
148
150
  Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
149
151
  - [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)
@@ -194,6 +196,7 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
194
196
  - [Elaborate Samples](#elaborate-samples)
195
197
  - [Login](#login)
196
198
  - [Contact Manager](#contact-manager)
199
+ - [Tetris](#tetris)
197
200
  - [Tic Tac Toe](#tic-tac-toe)
198
201
  - [User Profile](#user-profile)
199
202
  - [Weather](#weather)
@@ -232,8 +235,8 @@ Alternatively, web developers may directly use [Glimmer DSL for Opal](https://ru
232
235
 
233
236
  ## Pre-requisites
234
237
 
235
- - Rails 5: [https://github.com/rails/rails/tree/5-2-stable](https://github.com/rails/rails/tree/5-2-stable)
236
- - Opal 1.0.4: [https://github.com/opal/opal](https://github.com/opal/opal)
238
+ - Rails 5.2: [https://github.com/rails/rails/tree/5-2-stable](https://github.com/rails/rails/tree/5-2-stable)
239
+ - Opal 1.0.5: [https://github.com/opal/opal](https://github.com/opal/opal)
237
240
  - Opal-Rails 1.1.2: [https://github.com/opal/opal-rails](https://github.com/opal/opal-rails)
238
241
  - jQuery 3: [https://code.jquery.com/](https://code.jquery.com/) (jQuery 3.5.1 is included in the [glimmer-dsl-opal](https://rubygems.org/gems/glimmer-dsl-opal) gem)
239
242
  - jQuery-UI 1.12: [https://code.jquery.com/](https://jqueryui.com/) (jQuery-UI 1.12.1 is included in the [glimmer-dsl-opal](https://rubygems.org/gems/glimmer-dsl-opal) gem)
@@ -250,7 +253,7 @@ Please follow the following steps to setup.
250
253
  Install a Rails 5 gem:
251
254
 
252
255
  ```
253
- gem install rails -v5.2.4.4
256
+ gem install rails -v5.2.6
254
257
  ```
255
258
 
256
259
  Start a new Rails 5 app:
@@ -262,11 +265,11 @@ rails new glimmer_app_server
262
265
  Add the following to `Gemfile`:
263
266
 
264
267
  ```
265
- gem 'opal', '1.0.4'
268
+ gem 'opal', '1.0.5'
266
269
  gem 'opal-rails', '1.1.2'
267
- gem 'opal-async', '~> 1.3.0'
270
+ gem 'opal-async', '~> 1.4.0'
268
271
  gem 'opal-jquery', '~> 0.4.4'
269
- gem 'glimmer-dsl-opal', '~> 0.25.1'
272
+ gem 'glimmer-dsl-opal', '~> 0.26.1'
270
273
  gem 'glimmer-dsl-xml', '~> 1.2.0', require: false
271
274
  gem 'glimmer-dsl-css', '~> 1.2.0', require: false
272
275
 
@@ -1035,7 +1038,7 @@ Add the following require statement to `app/assets/javascripts/application.rb`
1035
1038
  require 'glimmer-dsl-opal/samples/hello/hello_custom_widget'
1036
1039
  ```
1037
1040
 
1038
- Or add the Glimmer code directly if you prefer to play around with it:
1041
+ Or add the Glimmer code directly if you prefer to play around with it (note that the Opal version needs `Array#async_cycle` from the opal-async gem instead of `Array#cycle` due to the async nature of JavaScript):
1039
1042
 
1040
1043
  ```ruby
1041
1044
  # This class declares a `greeting_label` custom widget (by convention)
@@ -1060,7 +1063,7 @@ class GreetingLabel
1060
1063
  return if colors.nil?
1061
1064
 
1062
1065
  Thread.new { # imported from Glimmer DSL for SWT. In Opal, avoid Threads and sleep to avoid blocking GUI.
1063
- colors.cycle { |color|
1066
+ colors.async_cycle { |color|
1064
1067
  async_exec {
1065
1068
  self.color = color
1066
1069
  }
@@ -2582,6 +2585,40 @@ Glimmer DSL for Opal Contact Manager Edit Done
2582
2585
 
2583
2586
  ![Glimmer DSL for Opal Contact Manager Edit Done](images/glimmer-dsl-opal-contact-manager-edit-done.png)
2584
2587
 
2588
+ #### Tetris
2589
+
2590
+ This is a minimal initial version of the [Tetris seen in Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/docs/reference/GLIMMER_SAMPLES.md#glimmer-tetris).
2591
+
2592
+ Note that while the Glimmer GUI DSL code is mostly the same, some of the behavioral code around threads is changed
2593
+ into async Opal code via the [opal-async](https://github.com/AndyObtiva/opal-async) gem due to the async nature of transpiled JavaScript.
2594
+
2595
+ Still, this sample has done the remarkable feat of reusing all of the Tetris model/view logic from Glimmer DSL for SWT mostly unchanged.
2596
+
2597
+ Add the following require statement to `app/assets/javascripts/application.rb`
2598
+
2599
+ ```ruby
2600
+ require 'glimmer-dsl-opal/samples/elaborate/tetris'
2601
+ ```
2602
+
2603
+ Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
2604
+
2605
+ ![Glimmer DSL for SWT Tetris](https://github.com/AndyObtiva/glimmer-dsl-swt/raw/master/images/glimmer-tetris.png)
2606
+
2607
+ Glimmer app on the web (using `glimmer-dsl-opal` gem):
2608
+
2609
+ Start the Rails server:
2610
+ ```
2611
+ rails s
2612
+ ```
2613
+
2614
+ Visit `http://localhost:3000`
2615
+
2616
+ You should see "Tetris" (a minimal version of the one in Glimmer DSL for SWT)
2617
+
2618
+ ![Glimmer DSL for Opal Tetris](images/glimmer-dsl-opal-tetris.png)
2619
+
2620
+ ![Glimmer DSL for Opal Tetris Video](images/glimmer-dsl-opal-tetris.gif)
2621
+
2585
2622
  #### Tic Tac Toe
2586
2623
 
2587
2624
  Add the following require statement to `app/assets/javascripts/application.rb`
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.25.2
1
+ 0.26.1
@@ -6,17 +6,17 @@ require 'glimmer/swt/combo_proxy'
6
6
  module Glimmer
7
7
  module DSL
8
8
  module Opal
9
- class ComboSelectionDataBindingExpression < Expression
9
+ class ComboSelectionDataBindingExpression < Expression
10
10
  def can_interpret?(parent, keyword, *args, &block)
11
11
  keyword == 'selection' and
12
12
  block.nil? and
13
- parent.is_a?(Glimmer::SWT::ComboProxy) and
13
+ (parent.is_a?(Glimmer::SWT::ComboProxy) || parent.is_a?(Glimmer::SWT::CComboProxy)) and
14
14
  args.size == 1 and
15
15
  args[0].is_a?(DataBinding::ModelBinding) and
16
16
  args[0].evaluate_options_property.is_a?(Array)
17
17
  end
18
18
 
19
- def interpret(parent, keyword, *args, &block)
19
+ def interpret(parent, keyword, *args, &block)
20
20
  model_binding = args[0]
21
21
 
22
22
  #TODO make this options observer dependent and all similar observers in element specific data binding handlers
@@ -37,9 +37,6 @@ module Glimmer
37
37
  if parent.is_a?(Glimmer::SWT::WidgetProxy)
38
38
  return true
39
39
  else
40
- puts 'parent'
41
- puts parent.class
42
- puts parent
43
40
  raise Glimmer::Error, "menu may only be nested under a widget (like shell or another menu)!"
44
41
  end
45
42
  end
@@ -26,7 +26,7 @@ module Glimmer
26
26
  module SWT
27
27
  class CComboProxy < ComboProxy
28
28
  def post_add_content
29
- `$(#{path}).selectmenu()`
29
+ dom_element.selectmenu
30
30
  c_combo_dom_element.css('width', 'initial')
31
31
  end
32
32
 
@@ -38,6 +38,11 @@ module Glimmer
38
38
  c_combo_dom_element.css('font-size', "#{@font.height}px") unless @font.nil?
39
39
  end
40
40
 
41
+ def text=(value)
42
+ super(value)
43
+ c_combo_text_element.text(value)
44
+ end
45
+
41
46
  def c_combo_path
42
47
  "##{id}-button"
43
48
  end
@@ -45,6 +50,30 @@ module Glimmer
45
50
  def c_combo_dom_element
46
51
  Document.find(c_combo_path)
47
52
  end
53
+
54
+ def c_combo_text_path
55
+ c_combo_path + ' .ui-selectmenu-text'
56
+ end
57
+
58
+ def c_combo_text_element
59
+ Document.find(c_combo_text_path)
60
+ end
61
+
62
+ def observation_request_to_event_mapping
63
+ super.merge(
64
+ 'on_widget_selected' => [
65
+ {
66
+ event: 'selectmenuchange',
67
+ event_handler: -> (event_listener) {
68
+ -> (event) {
69
+ self.text = event.target.value
70
+ event_listener.call(event)
71
+ }
72
+ }
73
+ },
74
+ ],
75
+ )
76
+ end
48
77
  end
49
78
  end
50
79
 
@@ -1,3 +1,4 @@
1
+
1
2
  require 'glimmer/data_binding/observable_element'
2
3
  require 'glimmer/swt/widget_proxy'
3
4
 
@@ -6,7 +7,6 @@ module Glimmer
6
7
  class ComboProxy < WidgetProxy
7
8
  include Glimmer::DataBinding::ObservableElement
8
9
  attr_reader :text, :items
9
- attr_accessor :selection # virtual attribute just to pass the shine data-binding test (TODO THINK OF A BETTER WAY OF HANDLING THIS)
10
10
 
11
11
  def initialize(parent, args, block)
12
12
  super(parent, args, block)
@@ -19,7 +19,15 @@ module Glimmer
19
19
 
20
20
  def text=(value)
21
21
  @text = value
22
- Document.find(path).value = value
22
+ dom_element.val(value)
23
+ end
24
+
25
+ def selection
26
+ text
27
+ end
28
+
29
+ def selection=(value)
30
+ self.text = value
23
31
  end
24
32
 
25
33
  def items=(the_items)
@@ -27,8 +27,8 @@ module Glimmer
27
27
  ATTRIBUTES = [:grabHorizontal, :grabVertical, :horizontalAlignment, :verticalAlignment, :minimumWidth, :minimumHeight]
28
28
  attr_accessor(*ATTRIBUTES)
29
29
  ATTRIBUTES.each do |attribute|
30
- alias_method attribute.underscore, attribute
31
- alias_method "#{attribute.underscore}=", "#{attribute}="
30
+ alias_method attribute.to_s.underscore, attribute
31
+ alias_method "#{attribute.to_s.underscore}=", "#{attribute}="
32
32
  end
33
33
 
34
34
  # TODO consider supporting a java_attr_accessor to get around having to generate all the aliases manually
@@ -19,12 +19,13 @@
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/swt/widget_proxy'
23
22
  require 'glimmer/swt/display_proxy'
23
+ require 'glimmer/swt/widget_proxy'
24
+ require 'glimmer/swt/shell_proxy'
24
25
 
25
26
  module Glimmer
26
27
  module SWT
27
- class DialogProxy < CompositeProxy
28
+ class DialogProxy < ShellProxy
28
29
  STYLE = <<~CSS
29
30
  .ui-dialog .ui-dialog-content {
30
31
  background: rgb(235, 235, 235);
@@ -86,7 +87,7 @@ module Glimmer
86
87
  @open
87
88
  end
88
89
 
89
- def open
90
+ def open(async: true)
90
91
  owned_proc = Glimmer::Util::ProcTracker.new(owner: self, invoked_from: :open) {
91
92
  shell.open(async: false) unless shell.open?
92
93
  unless @init
@@ -113,8 +114,13 @@ module Glimmer
113
114
  dom_element.dialog('open')
114
115
  end
115
116
  @open = true
117
+ listeners_for('swt_show').each {|listener| listener.call(Event.new(widget: self))}
116
118
  }
117
- DisplayProxy.instance.async_exec(owned_proc)
119
+ if async
120
+ DisplayProxy.instance.async_exec(owned_proc)
121
+ else
122
+ owned_proc.call
123
+ end
118
124
  end
119
125
 
120
126
  def hide
@@ -129,6 +135,7 @@ module Glimmer
129
135
  dom_element.remove
130
136
  @open = false
131
137
  @init = false
138
+ listeners_for('swt_close').each {|listener| listener.call(Event.new(widget: self))}
132
139
  Element['.dialog-overlay'].add_class('hide') unless DisplayProxy.instance.dialogs.any?(&:open?)
133
140
  parent.children.delete(self)
134
141
  shell.close if shell.children.empty?
@@ -1,8 +1,19 @@
1
1
  require 'glimmer/swt/widget_proxy'
2
+ require 'glimmer/swt/swt_proxy'
2
3
 
3
4
  module Glimmer
4
5
  module SWT
5
6
  class DisplayProxy < WidgetProxy
7
+ JS_KEY_CODE_TO_SWT_KEY_CODE_MAP = {
8
+ 16 => SWTProxy[:shift],
9
+ 17 => SWTProxy[:ctrl],
10
+ 18 => SWTProxy[:alt],
11
+ 37 => SWTProxy[:arrow_left],
12
+ 38 => SWTProxy[:arrow_up],
13
+ 39 => SWTProxy[:arrow_right],
14
+ 40 => SWTProxy[:arrow_down],
15
+ }
16
+
6
17
  class << self
7
18
  def instance
8
19
  @instance ||= new
@@ -95,7 +106,9 @@ module Glimmer
95
106
  event.singleton_class.define_method(:character) do
96
107
  which || key_code
97
108
  end
98
- event.define_singleton_method(:keyCode) {event.which}
109
+ event.define_singleton_method(:keyCode) {
110
+ JS_KEY_CODE_TO_SWT_KEY_CODE_MAP[event.which] || event.which
111
+ }
99
112
  event.define_singleton_method(:key_code, &event.method(:keyCode))
100
113
  event.define_singleton_method(:character) {event.which.chr}
101
114
  event.define_singleton_method(:stateMask) do
@@ -133,7 +146,9 @@ module Glimmer
133
146
  event.singleton_class.define_method(:character) do
134
147
  which || key_code
135
148
  end
136
- event.define_singleton_method(:keyCode) {event.which}
149
+ event.define_singleton_method(:keyCode) {
150
+ JS_KEY_CODE_TO_SWT_KEY_CODE_MAP[event.which] || event.which
151
+ }
137
152
  event.define_singleton_method(:key_code, &event.method(:keyCode))
138
153
  event.define_singleton_method(:character) {event.which.chr}
139
154
  event.define_singleton_method(:stateMask) do
@@ -150,7 +165,7 @@ module Glimmer
150
165
  doit = value
151
166
  end
152
167
  event.define_singleton_method(:doit) { doit }
153
- event_listener.call(event) if event.key_code != 13 && (event.key_code == 127 || event.key_code <= 31)
168
+ event_listener.call(event) if event.which != 13 && (event.which == 127 || event.which <= 40)
154
169
 
155
170
  # TODO Fix doit false, it's not stopping input
156
171
  unless doit
@@ -69,6 +69,7 @@ module Glimmer
69
69
  HEIGHT_MIN = 0
70
70
 
71
71
  def initialize(args)
72
+ # TODO set parent
72
73
  @args = args
73
74
  @children = []
74
75
  render # TODO attach to specific element
@@ -78,7 +79,7 @@ module Glimmer
78
79
  self.minimum_size = Point.new(WIDTH_MIN, HEIGHT_MIN)
79
80
  DisplayProxy.instance.shells << self
80
81
  end
81
-
82
+
82
83
  def post_add_content
83
84
  `$( document ).tooltip()`
84
85
  end
@@ -128,6 +129,16 @@ module Glimmer
128
129
  dom_element.css('min-height', "#{@minimum_size.y}px")
129
130
  end
130
131
 
132
+ def handle_observation_request(keyword, original_event_listener)
133
+ case keyword
134
+ when 'on_swt_show', 'on_swt_close', 'on_shell_closed'
135
+ keyword = 'on_swt_close' if keyword == 'on_shell_closed'
136
+ listeners_for(keyword.sub(/^on_/, '')) << original_event_listener.to_proc
137
+ else
138
+ super(keyword, original_event_listener)
139
+ end
140
+ end
141
+
131
142
  def style_dom_css
132
143
  <<~CSS
133
144
  .hide {
@@ -169,6 +180,7 @@ module Glimmer
169
180
  DisplayProxy.instance.shells.select(&:open?).reject {|s| s == self}.map(&:hide)
170
181
  dom_element.remove_class('hide')
171
182
  @open = true
183
+ listeners_for('swt_show').each {|listener| listener.call(Event.new(widget: self))}
172
184
  end
173
185
  end
174
186
  if async
@@ -177,6 +189,7 @@ module Glimmer
177
189
  work.call
178
190
  end
179
191
  end
192
+ alias show open
180
193
 
181
194
  def hide
182
195
  dom_element.add_class('hide')
@@ -187,11 +200,25 @@ module Glimmer
187
200
  DisplayProxy.instance.shells.delete(self)
188
201
  dom_element.remove
189
202
  @open = false
203
+ listeners_for('swt_close').each {|listener| listener.call(Event.new(widget: self))}
190
204
  end
191
205
 
192
206
  def open?
193
207
  @open
194
208
  end
209
+
210
+ def visible
211
+ @open
212
+ end
213
+ alias visible? visible
214
+
215
+ def visible=(value)
216
+ if value
217
+ show(async: false)
218
+ else
219
+ hide
220
+ end
221
+ end
195
222
  end
196
223
  end
197
224
  end