glimmer-dsl-opal 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/README.md +195 -167
  4. data/VERSION +1 -1
  5. data/lib/glimmer-dsl-opal.rb +24 -7
  6. data/lib/glimmer-dsl-opal/ext/exception.rb +5 -0
  7. data/lib/glimmer-dsl-opal/missing/net/http.rb +17 -0
  8. data/lib/glimmer-dsl-opal/missing/uri.rb +26 -0
  9. data/lib/{samples → glimmer-dsl-opal/samples}/elaborate/contact_manager.rb +0 -0
  10. data/lib/{samples → glimmer-dsl-opal/samples}/elaborate/contact_manager/contact.rb +0 -0
  11. data/lib/{samples → glimmer-dsl-opal/samples}/elaborate/contact_manager/contact_manager_presenter.rb +0 -0
  12. data/lib/{samples → glimmer-dsl-opal/samples}/elaborate/contact_manager/contact_repository.rb +24 -99
  13. data/lib/{samples → glimmer-dsl-opal/samples}/elaborate/login.rb +0 -0
  14. data/lib/{samples → glimmer-dsl-opal/samples}/elaborate/tic_tac_toe.rb +0 -0
  15. data/lib/{samples → glimmer-dsl-opal/samples}/elaborate/tic_tac_toe/board.rb +0 -0
  16. data/lib/{samples → glimmer-dsl-opal/samples}/elaborate/tic_tac_toe/cell.rb +0 -0
  17. data/lib/{samples → glimmer-dsl-opal/samples}/hello/hello_browser.rb +0 -0
  18. data/lib/glimmer-dsl-opal/samples/hello/hello_combo.rb +63 -0
  19. data/lib/{samples → glimmer-dsl-opal/samples}/hello/hello_computed.rb +0 -0
  20. data/lib/{samples → glimmer-dsl-opal/samples}/hello/hello_computed/contact.rb +0 -0
  21. data/lib/glimmer-dsl-opal/samples/hello/hello_custom_shell.rb +155 -0
  22. data/lib/glimmer-dsl-opal/samples/hello/hello_custom_widget.rb +86 -0
  23. data/lib/{samples → glimmer-dsl-opal/samples}/hello/hello_list_multi_selection.rb +0 -0
  24. data/lib/{samples → glimmer-dsl-opal/samples}/hello/hello_list_single_selection.rb +0 -0
  25. data/lib/glimmer-dsl-opal/samples/hello/hello_tab.rb +50 -0
  26. data/lib/glimmer-dsl-opal/samples/hello/hello_world.rb +29 -0
  27. data/lib/{jquery.js → glimmer-dsl-opal/vendor/jquery.js} +0 -0
  28. data/lib/glimmer/data_binding/ext/observable_model.rb +1 -1
  29. data/lib/glimmer/dsl/opal/async_exec_expression.rb +2 -2
  30. data/lib/glimmer/dsl/opal/color_expression.rb +38 -0
  31. data/lib/glimmer/dsl/opal/custom_widget_expression.rb +57 -0
  32. data/lib/glimmer/dsl/opal/dsl.rb +7 -0
  33. data/lib/glimmer/dsl/opal/font_expression.rb +47 -0
  34. data/lib/glimmer/dsl/opal/property_expression.rb +5 -2
  35. data/lib/glimmer/dsl/opal/rgb_expression.rb +32 -0
  36. data/lib/glimmer/dsl/opal/rgba_expression.rb +32 -0
  37. data/lib/glimmer/dsl/opal/swt_expression.rb +46 -0
  38. data/lib/glimmer/dsl/opal/widget_expression.rb +2 -1
  39. data/lib/glimmer/dsl/opal/widget_listener_expression.rb +16 -3
  40. data/lib/glimmer/swt.rb +499 -0
  41. data/lib/glimmer/swt/browser_proxy.rb +1 -1
  42. data/lib/glimmer/swt/button_proxy.rb +2 -2
  43. data/lib/glimmer/swt/color_proxy.rb +119 -0
  44. data/lib/glimmer/swt/combo_proxy.rb +10 -9
  45. data/lib/glimmer/swt/composite_proxy.rb +8 -8
  46. data/lib/glimmer/{opal → swt}/display_proxy.rb +3 -1
  47. data/lib/glimmer/swt/fill_layout_proxy.rb +84 -0
  48. data/lib/glimmer/swt/font_proxy.rb +79 -0
  49. data/lib/glimmer/swt/grid_layout_proxy.rb +34 -4
  50. data/lib/glimmer/swt/label_proxy.rb +7 -3
  51. data/lib/glimmer/swt/layout_proxy.rb +15 -13
  52. data/lib/glimmer/swt/list_proxy.rb +17 -12
  53. data/lib/glimmer/swt/message_box_proxy.rb +4 -7
  54. data/lib/glimmer/swt/row_layout_proxy.rb +105 -0
  55. data/lib/glimmer/swt/shell_proxy.rb +32 -22
  56. data/lib/glimmer/swt/style_constantizable.rb +154 -0
  57. data/lib/glimmer/swt/swt_proxy.rb +53 -0
  58. data/lib/glimmer/swt/tab_folder_proxy.rb +8 -8
  59. data/lib/glimmer/swt/tab_item_proxy.rb +15 -32
  60. data/lib/glimmer/swt/table_proxy.rb +0 -18
  61. data/lib/glimmer/swt/widget_proxy.rb +140 -39
  62. data/lib/glimmer/ui/custom_shell.rb +73 -0
  63. data/lib/glimmer/ui/custom_widget.rb +290 -0
  64. data/lib/glimmer/util/proc_tracker.rb +39 -0
  65. metadata +88 -57
  66. data/lib/glimmer/opal/element_proxy.rb +0 -312
  67. data/lib/samples/elaborate/launch +0 -6
  68. data/lib/samples/hello/hello_combo.rb +0 -34
  69. data/lib/samples/hello/hello_tab.rb +0 -24
  70. data/lib/samples/hello/hello_world.rb +0 -8
  71. data/lib/samples/hello/launch +0 -10
  72. data/lib/samples/launch +0 -4
@@ -0,0 +1,53 @@
1
+ # Copyright (c) 2020 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'
23
+ require 'glimmer/swt/style_constantizable'
24
+
25
+ module Glimmer
26
+ module SWT
27
+ # Proxy for org.eclipse.swt.SWT
28
+ #
29
+ # Follows the Proxy Design Pattern
30
+ class SWTProxy
31
+ include StyleConstantizable
32
+
33
+ class << self
34
+ def constant_source_class
35
+ SWT
36
+ end
37
+
38
+ def constant_value_none
39
+ SWT::NONE
40
+ end
41
+
42
+ def extra_styles
43
+ EXTRA_STYLES
44
+ end
45
+ end
46
+
47
+ EXTRA_STYLES = {
48
+ NO_RESIZE: self[:shell_trim, :resize!, :max!],
49
+ NO_SORT: -7,
50
+ }
51
+ end
52
+ end
53
+ end
@@ -12,20 +12,16 @@ module Glimmer
12
12
 
13
13
  def add_child(child)
14
14
  unless @children.include?(child)
15
- @children << child
15
+ @children << child
16
+ tabs_dom_element.append(child.tab_dom)
17
+ child.render
16
18
  end
19
+
17
20
  if @children.size == 1
18
21
  child.show
19
22
  end
20
23
  end
21
24
 
22
- def redraw
23
- super()
24
- @children.each do |child|
25
- add_child(child) # TODO think of impact of this on performance
26
- end
27
- end
28
-
29
25
  def hide_all_tab_content
30
26
  @children.each(&:hide)
31
27
  end
@@ -38,6 +34,10 @@ module Glimmer
38
34
  id + '-tabs'
39
35
  end
40
36
 
37
+ def tabs_dom_element
38
+ Document.find(tabs_path)
39
+ end
40
+
41
41
  def dom
42
42
  tab_folder_id = id
43
43
  tab_folder_id_style = css
@@ -8,7 +8,6 @@ module Glimmer
8
8
 
9
9
  def initialize(parent, args)
10
10
  super(parent, args)
11
- css_classes << 'tab-item'
12
11
  content {
13
12
  on_widget_selected {
14
13
  @parent.hide_all_tab_content
@@ -18,22 +17,20 @@ module Glimmer
18
17
  end
19
18
 
20
19
  def show
21
- # TODO refactor/rewrite via simply class application in jquery
22
- # Document.find(path).remove_class('hide')
23
20
  @content_visible = true
24
- redraw
21
+ dom_element.remove_class('hide')
22
+ tab_dom_element.add_class('selected')
25
23
  end
26
24
 
27
25
  def hide
28
- # TODO refactor/rewrite via simply class application in jquery
29
- # Document.find(path).add_class('hide')
30
26
  @content_visible = false
31
- redraw
27
+ dom_element.add_class('hide')
28
+ tab_dom_element.remove_class('selected')
32
29
  end
33
30
 
34
31
  def text=(value)
35
32
  @text = value
36
- redraw
33
+ tab_dom_element.html(@text)
37
34
  end
38
35
 
39
36
  def selector
@@ -52,47 +49,33 @@ module Glimmer
52
49
  tab_path
53
50
  end
54
51
 
55
- def redraw
56
- if @tab_dom
57
- old_tab_dom = @tab_dom
58
- @tab_dom = nil
59
- Document.find(tab_path).replace_with(tab_dom)
60
- else
61
- Document.find(parent.tabs_path).append(tab_dom)
62
- end
63
- super()
64
- end
65
-
66
52
  def tab_path
67
53
  "#{parent.tabs_path} > ##{tab_id}"
68
54
  end
69
55
 
56
+ def tab_dom_element
57
+ Document.find(tab_path)
58
+ end
59
+
70
60
  def tab_id
71
61
  id + '-tab'
72
62
  end
73
63
 
64
+ # This contains the clickable tab area with tab names
74
65
  def tab_dom
75
- tab_selected = @content_visible ? 'selected' : ''
76
66
  @tab_dom ||= html {
77
- button(id: tab_id, class: "tab #{tab_selected}") {
67
+ button(id: tab_id, class: "tab") {
78
68
  @text
79
69
  }
80
70
  }.to_s
81
71
  end
82
72
 
73
+ # This contains the tab content
83
74
  def dom
84
- tab_item_id = id
85
- tab_item_id_style = css
86
- tab_item_css_classes = css_classes
87
- css_classes << name
88
- if @content_visible
89
- tab_item_css_classes.delete('hide')
90
- else
91
- tab_item_css_classes << 'hide'
92
- end
93
- tab_item_class_string = tab_item_css_classes.to_a.join(' ')
75
+ tab_item_id = id
76
+ tab_item_class_string = [name, 'hide'].join(' ')
94
77
  @dom ||= html {
95
- div(id: tab_item_id, style: tab_item_id_style, class: tab_item_class_string) {
78
+ div(id: tab_item_id, class: tab_item_class_string) {
96
79
  }
97
80
  }.to_s
98
81
  end
@@ -105,24 +105,6 @@ module Glimmer
105
105
  @columns.to_a.each(&:redraw)
106
106
  end
107
107
 
108
- # def redraw
109
- # if @dom
110
- # old_dom = @dom
111
- # @dom = nil
112
- # old_dom.replace dom
113
- # else
114
- # dom
115
- # end
116
- # if @last_redrawn_children != @children
117
- # items_dom_element.empty
118
- # @last_redrawn_children = @children
119
- # @children = []
120
- # @last_redrawn_children.each do |child|
121
- # add_child(child)
122
- # end
123
- # end
124
- # end
125
-
126
108
  def element
127
109
  'table'
128
110
  end
@@ -1,5 +1,27 @@
1
+ # Copyright (c) 2020 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
+
1
22
  require 'glimmer/swt/event_listener_proxy'
2
23
  require 'glimmer/swt/property_owner'
24
+ require 'glimmer/swt/swt_proxy'
3
25
 
4
26
  module Glimmer
5
27
  module SWT
@@ -7,12 +29,12 @@ module Glimmer
7
29
  include Glimmer
8
30
  include PropertyOwner
9
31
 
10
- attr_reader :parent, :args, :path, :css_classes, :css, :children, :enabled
32
+ attr_reader :parent, :args, :path, :children, :enabled, :foreground, :background, :font
11
33
 
12
34
  class << self
13
35
  # Factory Method that translates a Glimmer DSL keyword into a WidgetProxy object
14
36
  def for(keyword, parent, args)
15
- the_widget_class = widget_class(keyword) || Glimmer::SWT::LabelProxy
37
+ the_widget_class = widget_class(keyword)
16
38
  the_widget_class.new(parent, args)
17
39
  end
18
40
 
@@ -44,18 +66,50 @@ module Glimmer
44
66
  def reset_max_id_numbers!
45
67
  @max_id_numbers = {}
46
68
  end
69
+
70
+ def underscored_widget_name(widget_proxy)
71
+ widget_proxy.class.name.split(/::|\./).last.sub(/Proxy$/, '').underscore
72
+ end
47
73
  end
48
74
 
75
+ DEFAULT_INITIALIZERS = {
76
+ "composite" => lambda do |composite_proxy|
77
+ if composite_proxy.layout.nil?
78
+ layout = GridLayoutProxy.new(composite_proxy, [])
79
+ composite_proxy.layout = layout
80
+ layout.margin_width = 15
81
+ layout.margin_height = 15
82
+ end
83
+ end,
84
+ # "scrolled_composite" => lambda do |scrolled_composite|
85
+ # scrolled_composite.expand_horizontal = true
86
+ # scrolled_composite.expand_vertical = true
87
+ # end,
88
+ # "table" => lambda do |table|
89
+ # table.setHeaderVisible(true)
90
+ # table.setLinesVisible(true)
91
+ # end,
92
+ "table_column" => lambda do |table_column_proxy|
93
+ table_column_proxy.width = 80
94
+ end,
95
+ # "group" => lambda do |group_proxy|
96
+ # group_proxy.layout = GridLayoutProxy.new(group_proxy, []) if group.layout.nil?
97
+ # end,
98
+ }
99
+
49
100
  def initialize(parent, args)
50
101
  @parent = parent
51
102
  @args = args
52
- @children = Set.new
53
- @css_classes = Set.new
54
- @css = ''
103
+ @children = Set.new # TODO consider moving to composite
55
104
  @enabled = true
56
- @parent.add_child(self)
105
+ DEFAULT_INITIALIZERS[self.class.underscored_widget_name(self)]&.call(self)
106
+ @parent.add_child(self) # TODO rename to post_initialize_child to be closer to glimmer-dsl-swt terminology
57
107
  end
58
108
 
109
+ def css_classes
110
+ dom_element.attr('class').to_s.split
111
+ end
112
+
59
113
  def dispose
60
114
  Document.find(path).remove
61
115
  end
@@ -71,28 +125,44 @@ module Glimmer
71
125
 
72
126
  def add_child(child)
73
127
  @children << child
74
- child.redraw
128
+ child.render
75
129
  end
76
130
 
77
131
  def enabled=(value)
78
132
  @enabled = value
79
- # TODO consider relying less on redraw in setters in the future
80
- redraw
133
+ dom_element.prop('disabled', !@enabled)
134
+ end
135
+
136
+ def foreground=(value)
137
+ @foreground = value
138
+ dom_element.css('color', foreground.to_css) unless foreground.nil?
139
+ end
140
+
141
+ def background=(value)
142
+ @background = value
143
+ dom_element.css('background-color', background.to_css) unless background.nil?
144
+ end
145
+
146
+ def font=(value)
147
+ @font = value.is_a?(FontProxy) ? value : FontProxy.new(self, value)
148
+ dom_element.css('font-family', @font.name) unless @font.nil?
149
+ dom_element.css('font-style', 'italic') if @font&.style == :italic
150
+ dom_element.css('font-weight', 'bold') if @font&.style == :bold
151
+ dom_element.css('font-size', "#{@font.height}px") unless @font.nil?
81
152
  end
82
153
 
83
154
  def parent_path
84
155
  @parent.path
85
156
  end
86
157
 
87
- def redraw
88
- if @dom && !Document.find(path).empty?
89
- old_element = Document.find(path)
90
- old_dom = @dom
91
- @dom = nil
92
- old_element.replace_with(dom.gsub('<html>', '').gsub('</html>', ''))
158
+ def render
159
+ old_element = dom_element
160
+ brand_new = @dom.nil? || old_element.empty?
161
+ build_dom
162
+ if brand_new
163
+ Document.find(parent_path).append(@dom)
93
164
  else
94
- @dom = nil
95
- Document.find(parent_path).append(dom.gsub('<html>', '').gsub('</html>', ''))
165
+ old_element.replace_with(@dom)
96
166
  end
97
167
  @observation_requests&.clone&.each do |keyword, event_listener_set|
98
168
  event_listener_set.each do |event_listener|
@@ -101,8 +171,15 @@ module Glimmer
101
171
  end
102
172
  end
103
173
  children.each do |child|
104
- child.redraw
105
- end
174
+ child.render
175
+ end
176
+ end
177
+ alias redraw render
178
+
179
+ def build_dom
180
+ @dom = nil
181
+ @dom = dom
182
+ @dom = @parent.layout.dom(@dom) if @parent.respond_to?(:layout) && @parent.layout
106
183
  end
107
184
 
108
185
  def content(&block)
@@ -133,33 +210,23 @@ module Glimmer
133
210
  end
134
211
 
135
212
  def add_css_class(css_class)
136
- @css_classes << css_class
137
- redraw
213
+ dom_element.add_class(css_class)
138
214
  end
139
215
 
140
- def add_css_classes(css_classes)
141
- @css_classes += css_classes
142
- redraw
216
+ def add_css_classes(css_classes_to_add)
217
+ css_classes_to_add.each {|css_class| add_css_class(css_class)}
143
218
  end
144
219
 
145
220
  def remove_css_class(css_class)
146
- @css_classes.delete(css_class)
147
- redraw
148
- end
149
-
150
- def remove_css_classes(css_classes)
151
- @css_classes -= css_classes
152
- redraw
221
+ dom_element.remove_class(css_class)
153
222
  end
154
223
 
155
- def clear_css_classes(css_class)
156
- @css_classes.clear
157
- redraw
224
+ def remove_css_classes(css_classes_to_remove)
225
+ css_classes_to_remove.each {|css_class| remove_css_class(css_class)}
158
226
  end
159
227
 
160
- def css=(css)
161
- @css = css
162
- redraw
228
+ def clear_css_classes
229
+ css_classes.each {|css_class| remove_css_class(css_class)}
163
230
  end
164
231
 
165
232
  def has_style?(symbol)
@@ -170,6 +237,20 @@ module Glimmer
170
237
  Document.find(path)
171
238
  end
172
239
 
240
+ def style_element
241
+ style_element_id = "#{id}-style"
242
+ style_element_selector = "style##{style_element_id}"
243
+ element = dom_element.find(style_element_selector)
244
+ if element.empty?
245
+ new_element = Element.new(:style)
246
+ new_element.attr('id', style_element_id)
247
+ new_element.attr('class', "#{name.gsub('_', '-')}-instance-style widget-instance-style")
248
+ dom_element.prepend(new_element)
249
+ element = dom_element.find(style_element_selector)
250
+ end
251
+ element
252
+ end
253
+
173
254
  def parent_dom_element
174
255
  Document.find(parent_path)
175
256
  end
@@ -178,6 +259,19 @@ module Glimmer
178
259
  path
179
260
  end
180
261
 
262
+ def can_handle_observation_request?(observation_request)
263
+ # TODO sort this out for Opal
264
+ observation_request = observation_request.to_s
265
+ if observation_request.start_with?('on_swt_')
266
+ constant_name = observation_request.sub(/^on_swt_/, '')
267
+ SWTProxy.has_constant?(constant_name)
268
+ elsif observation_request.start_with?('on_')
269
+ # event = observation_request.sub(/^on_/, '')
270
+ # can_add_listener?(event) || can_handle_drag_observation_request?(observation_request) || can_handle_drop_observation_request?(observation_request)
271
+ true # TODO filter by valid listeners only in the future
272
+ end
273
+ end
274
+
181
275
  def handle_observation_request(keyword, &event_listener)
182
276
  return unless observation_request_to_event_mapping.keys.include?(keyword)
183
277
  @observation_requests ||= {}
@@ -222,8 +316,15 @@ module Glimmer
222
316
  end
223
317
 
224
318
  def property_type_converters
319
+ color_converter = lambda do |value|
320
+ if value.is_a?(Symbol) || value.is_a?(String)
321
+ ColorProxy.new(value)
322
+ else
323
+ value
324
+ end
325
+ end
225
326
  @property_type_converters ||= {
226
- # :background => color_converter,
327
+ :background => color_converter,
227
328
  # :background_image => lambda do |value|
228
329
  # if value.is_a?(String)
229
330
  # if value.start_with?('uri:classloader')
@@ -243,7 +344,7 @@ module Glimmer
243
344
  # value
244
345
  # end
245
346
  # end,
246
- # :foreground => color_converter,
347
+ :foreground => color_converter,
247
348
  # :font => lambda do |value|
248
349
  # if value.is_a?(Hash)
249
350
  # font_properties = value