glimmer-dsl-opal 0.10.0 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5cf10a8e6a840bef3b7a757f55dec62651a334bce49f52d2ebac77ef6d68d0a3
4
- data.tar.gz: 02c7196499a96d53a3cc00d761af4cda2c6baa90a7d3587faee4d67b6d0e2615
3
+ metadata.gz: a69a60c500b662de0e458896e7da698a769ed5823c924d591825d3bfd5845605
4
+ data.tar.gz: 223e76c5d758d5caecfa9843a491acb23302f9c1f1b3cf592af830bfefa4c114
5
5
  SHA512:
6
- metadata.gz: 8dab1f9539fa2be9a6ae67e485011ebb3ab2f3322a35f3d266e2a1bb1b64bc408ffb47f4e3ddd3f67b103b21c2ce68de154b4bfd77736f8bf12a18b0dc611161
7
- data.tar.gz: 9651ec109a222fd805ef90e82c1898329648399a92c1008ac884b69b3e39bca3d119769169f52ae913fe8e523c72fcafdf0c82f6f066e80255e208414f11f5e6
6
+ metadata.gz: 79b96f5af0774f9bf5e508af1a67aa6a80cb061f818b295b178dd01e65561003fb573b394f5c21fc03440cfb2f834f95260ae03e5558fb1c24ac9261520fa275
7
+ data.tar.gz: c9c643cd2043e1a62db4f7487f2c2a7a447b09ebc7f33d8d255c1cb6daf2ed78b19aab3be25f1efef7408df02ca61f757f455b69552b9ec4f8ac9c7e35b97291
@@ -1,5 +1,10 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.10.1
4
+
5
+ - Delaying shell rendering till `#open` method is called as per the right expectation
6
+ - When nesting dialogs on top of each other, disable all previously opened ones leaving only the top-most dialog active
7
+
3
8
  ## 0.10.0
4
9
 
5
10
  - Hello, Dialog! Sample
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Opal 0.10.0 (Pure Ruby Web GUI)
1
+ # [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Opal 0.10.1 (Pure Ruby Web GUI)
2
2
  [![Gem Version](https://badge.fury.io/rb/glimmer-dsl-opal.svg)](http://badge.fury.io/rb/glimmer-dsl-opal)
3
3
  [![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4
4
 
@@ -141,7 +141,7 @@ Hello, Table! Game Booked
141
141
 
142
142
  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.
143
143
 
144
- **Alpha Version** 0.10.0 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))
144
+ **Alpha Version** 0.10.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))
145
145
 
146
146
  Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
147
147
  - [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)
@@ -151,7 +151,7 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
151
151
 
152
152
  ## Table of Contents
153
153
 
154
- - [Glimmer DSL for Opal 0.10.0 (Pure Ruby Web GUI)](#-glimmer-dsl-for-opal-0100-pure-ruby-web-gui)
154
+ - [Glimmer DSL for Opal 0.10.1 (Pure Ruby Web GUI)](#-glimmer-dsl-for-opal-0101-pure-ruby-web-gui)
155
155
  - [Principles](#principles)
156
156
  - [Background](#background)
157
157
  - [Pre-requisites](#pre-requisites)
@@ -249,7 +249,7 @@ Add the following to `Gemfile`:
249
249
  gem 'opal-rails', '~> 1.1.2'
250
250
  gem 'opal-async', '~> 1.2.0'
251
251
  gem 'opal-jquery', '~> 0.4.4'
252
- gem 'glimmer-dsl-opal', '~> 0.10.0'
252
+ gem 'glimmer-dsl-opal', '~> 0.10.1'
253
253
  gem 'glimmer-dsl-xml', '~> 1.1.0', require: false
254
254
  gem 'glimmer-dsl-css', '~> 1.1.0', require: false
255
255
 
@@ -2547,8 +2547,63 @@ require 'glimmer-dsl-opal/samples/hello/hello_dialog'
2547
2547
  Or add the Glimmer code directly if you prefer to play around with it:
2548
2548
 
2549
2549
  ```ruby
2550
+ include Glimmer
2550
2551
 
2552
+ shell {
2553
+ row_layout :vertical
2554
+
2555
+ text 'Hello, Dialog!'
2556
+
2557
+ 7.times { |n|
2558
+ dialog_number = n + 1
2559
+
2560
+ button {
2561
+ layout_data {
2562
+ width 200
2563
+ height 50
2564
+ }
2565
+ text "Dialog #{dialog_number}"
2566
+
2567
+ on_widget_selected {
2568
+ dialog { |dialog_proxy|
2569
+ row_layout(:vertical) {
2570
+ center true
2571
+ }
2572
+
2573
+ text "Dialog #{dialog_number}"
2574
+
2575
+ label {
2576
+ text "Given `dialog` is modal, you cannot interact with the main window till the dialog is closed."
2577
+ }
2578
+ composite {
2579
+ row_layout {
2580
+ margin_height 0
2581
+ margin_top 0
2582
+ margin_bottom 0
2583
+ }
2551
2584
 
2585
+ label {
2586
+ text "Unlike `message_box`, `dialog` can contain arbitrary widgets:"
2587
+ }
2588
+ radio {
2589
+ text 'Radio'
2590
+ }
2591
+ checkbox {
2592
+ text 'Checkbox'
2593
+ }
2594
+ }
2595
+ button {
2596
+ text 'Close'
2597
+
2598
+ on_widget_selected {
2599
+ dialog_proxy.close
2600
+ }
2601
+ }
2602
+ }.open
2603
+ }
2604
+ }
2605
+ }
2606
+ }.open
2552
2607
  ```
2553
2608
 
2554
2609
  Glimmer app on the desktop (using [`glimmer-dsl-swt`](https://github.com/AndyObtiva/glimmer-dsl-swt) gem):
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.10.0
1
+ 0.10.1
@@ -22,6 +22,7 @@
22
22
  require 'glimmer/swt/latest_shell_proxy'
23
23
  require 'glimmer/swt/latest_message_box_proxy'
24
24
  require 'glimmer/swt/latest_dialog_proxy'
25
+ require 'glimmer/swt/display_proxy'
25
26
 
26
27
  module Glimmer
27
28
  module DSL
@@ -35,7 +36,9 @@ module Glimmer
35
36
  end
36
37
  end
37
38
  if ['shell', 'message_box', 'dialog'].include?(keyword) && Glimmer::SWT::DisplayProxy.instance.shells.empty?
38
- Document.ready?(&work)
39
+ Document.ready? do
40
+ Glimmer::SWT::DisplayProxy.instance.async_exec(&work)
41
+ end
39
42
  Glimmer::SWT.const_get("Latest#{keyword.camelcase(:upper)}Proxy").new
40
43
  else
41
44
  work.call
@@ -11,7 +11,7 @@ module Glimmer
11
11
  include ParentExpression
12
12
 
13
13
  def interpret(parent, keyword, *args, &block)
14
- parent = args.delete_at(0)
14
+ parent = args.delete_at(0) if !textual?(args.first)
15
15
  Glimmer::SWT::MessageBoxProxy.new(parent, args)
16
16
  end
17
17
  end
@@ -4,8 +4,6 @@ require 'glimmer/swt/widget_proxy'
4
4
  module Glimmer
5
5
  module SWT
6
6
  class CompositeProxy < WidgetProxy
7
- attr_reader :layout
8
-
9
7
  def initialize(parent, args, block)
10
8
  super(parent, args, block)
11
9
  @layout = default_layout
@@ -27,7 +25,23 @@ module Glimmer
27
25
  def layout=(the_layout)
28
26
  @layout = the_layout
29
27
  end
28
+ alias set_layout layout=
29
+ alias setLayout layout=
30
+
31
+ def get_layout
32
+ @layout
33
+ end
34
+ alias getLayout get_layout #TODO consider pregenerating these aliases with an easy method in the future
35
+
36
+ def pack(*args)
37
+ # No Op (just a shim) TODO consider if it should be implemented
38
+ end
30
39
 
40
+ def layout​(changed = nil, all = nil)
41
+ # TODO implement layout(changed = nil, all = nil) just as per SWT API
42
+ @layout&.layout(self, changed)
43
+ end
44
+
31
45
  end
32
46
 
33
47
  end
@@ -63,7 +63,7 @@ module Glimmer
63
63
  i = 0
64
64
  @parent = parent
65
65
  @parent = nil if parent.is_a?(LatestShellProxy)
66
- @parent ||= DisplayProxy.instance.shells.last || ShellProxy.new([])
66
+ @parent ||= DisplayProxy.instance.shells.detect(&:open?) || ShellProxy.new([])
67
67
  @args = args
68
68
  @block = block
69
69
  @children = Set.new
@@ -71,6 +71,7 @@ module Glimmer
71
71
  # on_widget_selected {
72
72
  # hide
73
73
  # }
74
+ DisplayProxy.instance.opened_dialogs.last&.suspend_event_handling
74
75
  DisplayProxy.instance.dialogs << self
75
76
  @parent.post_initialize_child(self)
76
77
  end
@@ -84,35 +85,39 @@ module Glimmer
84
85
  end
85
86
  end
86
87
 
88
+ def open?
89
+ @open
90
+ end
91
+
87
92
  def open
88
- unless @init
89
- dom_element.remove_class('hide')
90
- dom_element.dialog({'auto_open' => false})
91
- @init = true
92
- dom_element.dialog('option', 'appendTo', parent.path)
93
- dom_element.dialog('option', 'modal', true) # NOTE: Not Working! Doing manually below by relying on overlay in ShellProxy.
94
- if DisplayProxy.instance.dialogs.size == 1 # only add for first dialog open
95
- Element['.dialog-overlay'].remove_class('hide')
96
- end
97
- dom_element.dialog('option', 'closeOnEscape', true)
98
- dom_element.dialog('option', 'draggable', true)
99
- dom_element.dialog('option', 'width', 'auto')
100
- dom_element.dialog('option', 'minHeight', 'none')
101
- dom_element.on('dialogclose') do
102
- unless @hiding
103
- close
104
- else
105
- @hiding = false
93
+ owned_proc = Glimmer::Util::ProcTracker.new(owner: self) {
94
+ shell.open(async: false) unless shell.open?
95
+ unless @init
96
+ dom_element.remove_class('hide')
97
+ dom_element.dialog('auto_open' => false)
98
+ @init = true
99
+ dom_element.dialog('option', 'appendTo', parent.path)
100
+ dom_element.dialog('option', 'modal', true) # NOTE: Not Working! Doing manually below by relying on overlay in ShellProxy.
101
+ unless DisplayProxy.instance.dialogs.any?(&:open?) # only add for first dialog open
102
+ Element['.dialog-overlay'].remove_class('hide')
106
103
  end
104
+ dom_element.dialog('option', 'closeOnEscape', true)
105
+ dom_element.dialog('option', 'draggable', true)
106
+ dom_element.dialog('option', 'width', 'auto')
107
+ dom_element.dialog('option', 'minHeight', 'none')
108
+ dom_element.on('dialogclose') do
109
+ unless @hiding
110
+ close
111
+ else
112
+ @hiding = false
113
+ end
114
+ end
115
+ else
116
+ dom_element.dialog('open')
107
117
  end
108
- else
109
- dom_element.dialog('open')
110
- end
111
- @open = true
112
- end
113
-
114
- def open?
115
- @open
118
+ @open = true
119
+ }
120
+ DisplayProxy.instance.async_exec(owned_proc)
116
121
  end
117
122
 
118
123
  def hide
@@ -128,7 +133,10 @@ module Glimmer
128
133
  @open = false
129
134
  @init = false
130
135
  Element['.dialog-overlay'].add_class('hide') unless DisplayProxy.instance.dialogs.any?(&:open?)
136
+ parent.children.delete(self)
137
+ shell.close if shell.children.empty?
131
138
  DisplayProxy.instance.dialogs.delete(self)
139
+ DisplayProxy.instance.opened_dialogs.last&.resume_event_handling
132
140
  end
133
141
 
134
142
 
@@ -144,6 +152,16 @@ module Glimmer
144
152
  end
145
153
  end
146
154
 
155
+ def suspend_event_handling
156
+ super
157
+ Element["[aria-describedby=#{id}]"].css('z-index', 9)
158
+ end
159
+
160
+ def resume_event_handling
161
+ super
162
+ Element["[aria-describedby=#{id}]"].css('z-index', 100)
163
+ end
164
+
147
165
  # def selector
148
166
  # super + ' .close'
149
167
  # end
@@ -162,7 +180,7 @@ module Glimmer
162
180
 
163
181
  def dom
164
182
  @dom ||= html {
165
- div(id: id, class: "#{name} hide", title: text) {
183
+ div(id: id, class: "#{name} modal hide", title: text) {
166
184
  }
167
185
  }.to_s
168
186
  end
@@ -1,3 +1,5 @@
1
+ require 'glimmer/swt/widget_proxy'
2
+
1
3
  module Glimmer
2
4
  module SWT
3
5
  class DisplayProxy < WidgetProxy
@@ -36,20 +38,43 @@ module Glimmer
36
38
  @dialogs ||= []
37
39
  end
38
40
 
41
+ def modals
42
+ message_boxes + dialogs
43
+ end
44
+
45
+ def message_box_open?
46
+ message_boxes.any?(&:open?)
47
+ end
48
+
49
+ def dialog_open?
50
+ dialogs.any?(&:open?)
51
+ end
52
+
53
+ def opened_dialogs
54
+ dialogs.select(&:open?)
55
+ end
56
+
57
+ def modal_open?
58
+ message_box_open? or dialog_open?
59
+ end
60
+
39
61
  def render
40
62
  # No rendering as body is rendered as part of ShellProxy.. this class only serves as an SWT Display utility
41
63
  end
42
64
 
43
- def async_exec(&block)
65
+ def async_exec(proc_tracker = nil, &block)
66
+ block = proc_tracker unless proc_tracker.nil?
67
+ can_open_modal = !modal_open?
68
+ return block.call if !can_open_modal && dialog_open? && block.respond_to?(:owner) && !block.owner.nil? && block.owner.is_a?(DialogProxy) && opened_dialogs.last == WidgetProxy.widget_handling_listener&.dialog_ancestor
69
+ return block.call if !can_open_modal && block.respond_to?(:owner) && !block.owner.nil? && block.owner.is_a?(MessageBoxProxy)
44
70
  executer = lambda do
45
- if Document.find('.modal').to_a.empty?
71
+ if !modal_open?
46
72
  block.call
47
73
  else
48
- sleep(0.05)
49
- Async::Task.new(&executer)
74
+ Async::Task.new(delay: 100, &executer)
50
75
  end
51
76
  end
52
- Async::Task.new(&executer)
77
+ Async::Task.new(delay: 1, &executer)
53
78
  end
54
79
  # sync_exec kept for API compatibility reasons
55
80
  alias sync_exec async_exec
@@ -14,39 +14,29 @@ module Glimmer
14
14
 
15
15
  attr_reader :num_columns, :make_columns_equal_width, :horizontal_spacing, :vertical_spacing, :margin_width, :margin_height
16
16
 
17
- def initialize(parent, args)
18
- super(parent, args)
19
- self.horizontal_spacing = 10
20
- self.vertical_spacing = 10
21
- self.margin_width = 15
22
- self.margin_height = 15
23
- self.num_columns = @args.first || 1
24
- reapply
25
- end
26
-
27
17
  def num_columns=(columns)
28
18
  @num_columns = columns
29
19
  # TODO do the following instead of reapply
30
20
  # @parent.add_css_class("num-columns-#{@num_columns}")
31
- reapply
21
+ # reinitialize # TODO reimplement without using reinitialize
32
22
  end
33
23
 
34
24
  def make_columns_equal_width=(equal_width)
35
25
  @make_columns_equal_width = equal_width
36
26
  # @parent.add_css_class('make_columns_equal_width') if @make_columns_equal_width
37
- reapply
27
+ # reinitialize # TODO reimplement without using reinitialize
38
28
  end
39
29
 
40
30
  def horizontal_spacing=(spacing)
41
31
  @horizontal_spacing = spacing
42
32
  # @parent.add_css_class("horizontal-spacing-#{@horizontal_spacing}")
43
- reapply
33
+ # reinitialize # TODO reimplement without using reinitialize
44
34
  end
45
35
 
46
36
  def vertical_spacing=(spacing)
47
37
  @vertical_spacing = spacing
48
38
  # @parent.add_css_class("vertical-spacing-#{@vertical_spacing}")
49
- reapply
39
+ # reinitialize # TODO reimplement without using reinitialize
50
40
  end
51
41
 
52
42
  def margin_width=(pixels)
@@ -66,8 +56,13 @@ module Glimmer
66
56
  @parent.dom_element.css('padding-bottom', effective_margin_height)
67
57
  end
68
58
 
69
- def reapply
70
- # TODO get rid of this method
59
+ def initialize(parent, args)
60
+ super(parent, args)
61
+ self.horizontal_spacing = 10
62
+ self.vertical_spacing = 10
63
+ self.margin_width = 15
64
+ self.margin_height = 15
65
+ self.num_columns = @args.first || 1
71
66
  layout_css = <<~CSS
72
67
  grid-template-columns: #{'auto ' * @num_columns.to_i};
73
68
  grid-row-gap: #{@vertical_spacing}px;
@@ -31,7 +31,9 @@ module Glimmer
31
31
 
32
32
  def open
33
33
  Document.ready? do
34
- DisplayProxy.instance.dialogs.last&.open
34
+ DisplayProxy.instance.async_exec {
35
+ DisplayProxy.instance.dialogs.last&.open
36
+ }
35
37
  end
36
38
  end
37
39
 
@@ -31,7 +31,9 @@ module Glimmer
31
31
 
32
32
  def open
33
33
  Document.ready? do
34
- DisplayProxy.instance.message_boxes.last&.open
34
+ DisplayProxy.instance.async_exec {
35
+ DisplayProxy.instance.message_boxes.last&.open
36
+ }
35
37
  end
36
38
  end
37
39
 
@@ -19,9 +19,11 @@
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/shell_proxy'
23
+
22
24
  module Glimmer
23
25
  module SWT
24
- class LatestShellProxy #< ShellProxy
26
+ class LatestShellProxy < ShellProxy
25
27
  def initialize(parent, args, block)
26
28
  # No Op
27
29
  end
@@ -40,7 +42,9 @@ module Glimmer
40
42
 
41
43
  def open
42
44
  Document.ready? do
43
- latest_shell&.open
45
+ DisplayProxy.instance.async_exec {
46
+ latest_shell&.open
47
+ }
44
48
  end
45
49
  end
46
50
 
@@ -31,29 +31,32 @@ module Glimmer
31
31
 
32
32
  def initialize(parent, args)
33
33
  @parent = parent
34
+ @args = args
34
35
  @parent = parent.body_root if @parent.is_a?(Glimmer::UI::CustomWidget)
35
36
  @parent.css_classes.each do |css_class|
36
37
  @parent.remove_css_class(css_class) if css_class.include?('layout')
37
38
  end
38
- @args = args
39
39
  @parent.add_css_class(css_class)
40
40
  @parent.layout = self
41
41
  self.margin_width = 15 if respond_to?(:margin_width=)
42
42
  self.margin_height = 15 if respond_to?(:margin_height=)
43
43
  end
44
-
45
- def css_class
46
- self.class.name.split('::').last.underscore.sub(/_proxy$/, '').gsub('_', '-')
44
+
45
+ def layout​(composite = nil, flush_cache = false)
46
+ # TODO implement def layout​(composite = nil, flush_cache = false) as per SWT API
47
+ composite ||= @parent
48
+ initialize(composite, @args)
47
49
  end
48
50
 
49
- def reapply
50
- # subclasses can override this
51
+ def css_class
52
+ self.class.name.split('::').last.underscore.sub(/_proxy$/, '').gsub('_', '-')
51
53
  end
52
54
 
53
55
  # Decorates widget dom. Subclasses may override. Returns widget dom by default.
54
56
  def dom(widget_dom)
55
57
  widget_dom
56
58
  end
59
+
57
60
  end
58
61
  end
59
62
  end
@@ -26,7 +26,7 @@ module Glimmer
26
26
  module SWT
27
27
  class MessageBoxProxy < WidgetProxy
28
28
  STYLE = <<~CSS
29
- .modal {
29
+ .message-box {
30
30
  position: fixed;
31
31
  z-index: 1000;
32
32
  padding-top: 100px;
@@ -39,15 +39,15 @@ module Glimmer
39
39
  background-color: rgba(0,0,0,0.4);
40
40
  text-align: center;
41
41
  }
42
- .modal-content .text {
42
+ .message-box-content .text {
43
43
  background: rgb(80, 116, 211);
44
44
  color: white;
45
45
  padding: 5px;
46
46
  }
47
- .modal-content .message {
47
+ .message-box-content .message {
48
48
  padding: 20px;
49
49
  }
50
- .modal-content {
50
+ .message-box-content {
51
51
  background-color: #fefefe;
52
52
  padding-bottom: 15px;
53
53
  border: 1px solid #888;
@@ -81,13 +81,14 @@ module Glimmer
81
81
  @enabled = true
82
82
  on_widget_selected {
83
83
  hide
84
+ @open = false
84
85
  }
85
86
  DisplayProxy.instance.message_boxes << self
86
87
  end
87
88
 
88
89
  def text=(txt)
89
90
  @text = txt
90
- dom_element.find('.modal-content .text').html(@text)
91
+ dom_element.find('.message-box-content .text').html(@text)
91
92
  end
92
93
 
93
94
  def html_message
@@ -96,11 +97,20 @@ module Glimmer
96
97
 
97
98
  def message=(msg)
98
99
  @message = msg
99
- dom_element.find('.modal-content .message').html(html_message)
100
+ dom_element.find('.message-box-content .message').html(html_message)
101
+ end
102
+
103
+ def open?
104
+ @open
100
105
  end
101
106
 
102
107
  def open
103
- parent.post_initialize_child(self)
108
+ shell.open(async: false) unless shell.open?
109
+ owned_proc = Glimmer::Util::ProcTracker.new(owner: self) {
110
+ parent.post_initialize_child(self)
111
+ @open = true
112
+ }
113
+ DisplayProxy.instance.async_exec(owned_proc)
104
114
  end
105
115
 
106
116
  def hide
@@ -130,7 +140,7 @@ module Glimmer
130
140
  def dom
131
141
  @dom ||= html {
132
142
  div(id: id, class: "modal #{name}") {
133
- div(class: 'modal-content') {
143
+ div(class: 'message-box-content') {
134
144
  header(class: 'text') {
135
145
  "#{text}&nbsp;" # ensure title area occuppied when there is no text by adding non-breaking space (&nbsp;)
136
146
  }
@@ -43,12 +43,10 @@ module Glimmer
43
43
  CSS
44
44
 
45
45
  attr_reader :type, :margin_width, :margin_height, :margin_top, :margin_right, :margin_bottom, :margin_left, :spacing, :pack, :center
46
-
46
+
47
47
  def initialize(parent, args)
48
48
  super(parent, args)
49
- @type = @args.first || :horizontal
50
- @marign_width = 15
51
- @margin_height = 15
49
+ @type = args.first || :horizontal
52
50
  self.pack = true
53
51
  @parent.dom_element.add_class('row-layout')
54
52
  @parent.dom_element.add_class(horizontal? ? 'row-layout-horizontal' : 'row-layout-vertical')
@@ -47,9 +47,7 @@ module Glimmer
47
47
  def initialize(args)
48
48
  @args = args
49
49
  @children = []
50
- # TODO consider the implication of emptying the body
51
- Document.find('body').empty unless ENV['RUBY_ENV'] == 'test'
52
- render
50
+ render # TODO attach to specific element
53
51
  @layout = FillLayoutProxy.new(self, [])
54
52
  @layout.margin_width = 0
55
53
  @layout.margin_height = 0
@@ -95,7 +93,7 @@ module Glimmer
95
93
  def dom
96
94
  i = 0
97
95
  body_id = id
98
- body_class = ([name] + css_classes.to_a).join(' ')
96
+ body_class = ([name, 'hide'] + css_classes.to_a).join(' ')
99
97
  @dom ||= html {
100
98
  div(id: body_id, class: body_class) {
101
99
  # TODO consider supporting the idea of dynamic CSS building on close of shell that adds only as much CSS as needed for widgets that were mentioned
@@ -115,10 +113,34 @@ module Glimmer
115
113
  }.to_s
116
114
  end
117
115
 
118
- def open
119
- # TODO consider the idea of delaying rendering till the open method
120
- # TODO make it start as hidden and show shell upon open
121
- # DisplayProxy.instance.shells << self
116
+ def open(async: true)
117
+ work = lambda do
118
+ unless @open
119
+ DisplayProxy.instance.shells.select(&:open?).reject {|s| s == self}.map(&:hide)
120
+ dom_element.remove_class('hide')
121
+ @open = true
122
+ end
123
+ end
124
+ if async
125
+ DisplayProxy.instance.async_exec(&work)
126
+ else
127
+ work.call
128
+ end
129
+ end
130
+
131
+ def hide
132
+ dom_element.add_class('hide')
133
+ @open = false
134
+ end
135
+
136
+ def close
137
+ DisplayProxy.instance.shells.delete(self)
138
+ dom_element.remove
139
+ @open = false
140
+ end
141
+
142
+ def open?
143
+ @open
122
144
  end
123
145
  end
124
146
  end
@@ -77,15 +77,20 @@ module Glimmer
77
77
  def underscored_widget_name(widget_proxy)
78
78
  widget_proxy.class.name.split(/::|\./).last.sub(/Proxy$/, '').underscore
79
79
  end
80
+
81
+ def widget_handling_listener
82
+ @@widget_handling_listener
83
+ end
80
84
  end
81
85
 
82
86
  DEFAULT_INITIALIZERS = {
87
+ # TODO remove if built in class initializer is taking care of this
83
88
  composite: lambda do |composite_proxy|
84
- if composite_proxy.layout.nil?
85
- layout = GridLayoutProxy.new(composite_proxy, [])
86
- composite_proxy.layout = layout
87
- layout.margin_width = 15
88
- layout.margin_height = 15
89
+ if composite_proxy.get_layout.nil?
90
+ the_layout = GridLayoutProxy.new(composite_proxy, [])
91
+ composite_proxy.layout = the_layout
92
+ the_layout.margin_width = 15
93
+ the_layout.margin_height = 15
89
94
  end
90
95
  end,
91
96
  # scrolled_composite: lambda do |scrolled_composite|
@@ -100,7 +105,7 @@ module Glimmer
100
105
  table_column_proxy.width = 80
101
106
  end,
102
107
  # group: lambda do |group_proxy|
103
- # group_proxy.layout = GridLayoutProxy.new(group_proxy, []) if group.layout.nil?
108
+ # group_proxy.layout = GridLayoutProxy.new(group_proxy, []) if group.get_layout.nil?
104
109
  # end,
105
110
  }
106
111
 
@@ -135,8 +140,8 @@ module Glimmer
135
140
  dom_element.css('position', 'relative')
136
141
  menu&.render
137
142
  menu.dom_element.css('position', 'absolute')
138
- menu.dom_element.css('left', mouse_event.x - parent.layout&.margin_width.to_i) # TODO - parent.layout&.margin_left.to_i)
139
- menu.dom_element.css('top', mouse_event.y - parent.layout&.margin_height.to_i - 5) # TODO - parent.layout&.margin_top.to_i)
143
+ menu.dom_element.css('left', mouse_event.x - parent.get_layout&.margin_width.to_i) # TODO - parent.get_layout&.margin_left.to_i)
144
+ menu.dom_element.css('top', mouse_event.y - parent.get_layout&.margin_height.to_i - 5) # TODO - parent.get_layout&.margin_top.to_i)
140
145
  @menu_requested = false
141
146
  end
142
147
  }
@@ -193,12 +198,24 @@ module Glimmer
193
198
  'div'
194
199
  end
195
200
 
196
- def pack(*args)
197
- # No Op (just a shim) TODO consider if it should be implemented
201
+ def shell
202
+ current_widget = self
203
+ current_widget = current_widget.parent until current_widget.parent.nil?
204
+ current_widget
205
+ end
206
+
207
+ def parents
208
+ parents_array = []
209
+ current_widget = self
210
+ until current_widget.parent.nil?
211
+ current_widget = current_widget.parent
212
+ parents_array << current_widget
213
+ end
214
+ parents_array
198
215
  end
199
216
 
200
- def layout(*args)
201
- # No Op (just a shim) TODO consider if it should be implemented
217
+ def dialog_ancestor
218
+ parents.detect {|p| p.is_a?(DialogProxy)}
202
219
  end
203
220
 
204
221
  def enabled=(value)
@@ -237,7 +254,7 @@ module Glimmer
237
254
  alias setFocus set_focus
238
255
 
239
256
  def parent_path
240
- @parent.path
257
+ @parent&.path
241
258
  end
242
259
 
243
260
  def parent_dom_element
@@ -287,7 +304,7 @@ module Glimmer
287
304
  # TODO consider passing parent element instead and having table item include a table cell widget only for opal
288
305
  @dom = nil
289
306
  @dom = dom
290
- @dom = @parent.layout.dom(@dom) if @parent.respond_to?(:layout) && @parent.layout
307
+ @dom = @parent.get_layout.dom(@dom) if @parent.respond_to?(:layout) && @parent.get_layout
291
308
  @dom
292
309
  end
293
310
 
@@ -633,6 +650,18 @@ module Glimmer
633
650
  @event_listener_proxies ||= []
634
651
  end
635
652
 
653
+ def suspend_event_handling
654
+ @event_handling_suspended = true
655
+ end
656
+
657
+ def resume_event_handling
658
+ @event_handling_suspended = false
659
+ end
660
+
661
+ def event_handling_suspended?
662
+ @event_handling_suspended
663
+ end
664
+
636
665
  def can_handle_observation_request?(observation_request)
637
666
  # TODO sort this out for Opal
638
667
  observation_request = observation_request.to_s
@@ -662,7 +691,10 @@ module Glimmer
662
691
  # TODO look into the issue with using async::task.new here. maybe put it in event listener (like not being able to call preventDefault or return false successfully )
663
692
  # maybe consider pushing inside the widget classes instead where needed only or implement universal doit support correctly to bypass this issue
664
693
  # Async::Task.new do
665
- event_listener.call(event)
694
+ @@widget_handling_listener = self
695
+ # TODO also make sure to disable all widgets for suspension
696
+ event_listener.call(event) unless dialog_ancestor&.event_handling_suspended?
697
+ @widget_handling_listener = nil
666
698
  # end
667
699
  end
668
700
  the_listener_dom_element = event_element_css_selector ? Element[event_element_css_selector] : listener_dom_element
@@ -56,7 +56,7 @@ module Glimmer
56
56
 
57
57
  def initialize(parent, args, options, &content)
58
58
  super(parent, args, options, &content)
59
- raise Error, 'Invalid custom shell body root! Must be a shell or another custom shell.' unless body_root.is_a?(Glimmer::SWT::ShellProxy) || body_root.is_a?(Glimmer::UI::CustomShell) || body_root.is_a?(Glimmer::SWT::LatestShellProxy)
59
+ raise Error, 'Invalid custom shell body root! Must be a shell or another custom shell.' unless body_root.is_a?(Glimmer::SWT::ShellProxy) || body_root.is_a?(Glimmer::UI::CustomShell)
60
60
  end
61
61
 
62
62
  # Classes may override
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2020-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
@@ -24,16 +24,25 @@ require 'delegate'
24
24
  module Glimmer
25
25
  module Util
26
26
  class ProcTracker < DelegateClass(Proc)
27
- def initialize(proc)
28
- super(proc)
27
+ attr_reader :owner
28
+
29
+ def initialize(proc = nil, owner: nil, &block)
30
+ super(proc || block)
31
+ @owner = owner
29
32
  end
33
+
30
34
  def call(*args)
31
35
  __getobj__.call(*args)
32
36
  @called = true
33
37
  end
38
+
34
39
  def called?
35
40
  !!@called
36
41
  end
42
+
43
+ def respond_to?(method, *args, &block)
44
+ %w[owner called?].include?(method.to_s) || super(method, *args, &block)
45
+ end
37
46
  end
38
47
  end
39
48
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer-dsl-opal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - AndyMaleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-13 00:00:00.000000000 Z
11
+ date: 2021-01-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer