glimmer-dsl-opal 0.0.5 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +41 -0
  3. data/README.md +1003 -58
  4. data/VERSION +1 -1
  5. data/lib/glimmer-dsl-opal.rb +26 -8
  6. data/lib/glimmer/data_binding/element_binding.rb +1 -1
  7. data/lib/glimmer/data_binding/ext/observable_model.rb +40 -0
  8. data/lib/glimmer/data_binding/list_selection_binding.rb +1 -1
  9. data/lib/glimmer/data_binding/table_items_binding.rb +70 -0
  10. data/lib/glimmer/dsl/opal/async_exec_expression.rb +17 -0
  11. data/lib/glimmer/dsl/opal/column_properties_expression.rb +22 -0
  12. data/lib/glimmer/dsl/opal/combo_selection_data_binding_expression.rb +2 -2
  13. data/lib/glimmer/dsl/opal/dsl.rb +10 -12
  14. data/lib/glimmer/dsl/opal/layout_data_expression.rb +2 -2
  15. data/lib/glimmer/dsl/opal/{text_expression.rb → layout_expression.rb} +5 -5
  16. data/lib/glimmer/dsl/opal/list_selection_data_binding_expression.rb +2 -3
  17. data/lib/glimmer/dsl/opal/message_box_expression.rb +20 -0
  18. data/lib/glimmer/dsl/opal/observe_expression.rb +32 -0
  19. data/lib/glimmer/dsl/opal/shell_expression.rb +2 -2
  20. data/lib/glimmer/dsl/opal/{composite_expression.rb → table_column_expression.rb} +3 -3
  21. data/lib/glimmer/dsl/opal/{list_expression.rb → table_expression.rb} +3 -3
  22. data/lib/glimmer/dsl/opal/table_items_data_binding_expression.rb +29 -0
  23. data/lib/glimmer/dsl/opal/widget_expression.rb +23 -0
  24. data/lib/glimmer/opal/display_proxy.rb +23 -0
  25. data/lib/glimmer/opal/element_proxy.rb +48 -13
  26. data/lib/glimmer/swt/browser_proxy.rb +27 -0
  27. data/lib/glimmer/swt/button_proxy.rb +40 -0
  28. data/lib/glimmer/{opal/select_proxy.rb → swt/combo_proxy.rb} +15 -11
  29. data/lib/glimmer/swt/composite_proxy.rb +31 -0
  30. data/lib/glimmer/{opal → swt}/event_listener_proxy.rb +1 -1
  31. data/lib/glimmer/{opal → swt}/grid_layout_proxy.rb +7 -18
  32. data/lib/glimmer/swt/label_proxy.rb +30 -0
  33. data/lib/glimmer/swt/layout_data_proxy.rb +52 -0
  34. data/lib/glimmer/swt/layout_proxy.rb +60 -0
  35. data/lib/glimmer/{opal → swt}/list_proxy.rb +18 -15
  36. data/lib/glimmer/swt/message_box_proxy.rb +146 -0
  37. data/lib/glimmer/{opal → swt}/point.rb +1 -1
  38. data/lib/glimmer/{opal → swt}/property_owner.rb +1 -1
  39. data/lib/glimmer/swt/shell_proxy.rb +235 -0
  40. data/lib/glimmer/swt/tab_folder_proxy.rb +52 -0
  41. data/lib/glimmer/swt/tab_item_proxy.rb +101 -0
  42. data/lib/glimmer/swt/table_column_proxy.rb +56 -0
  43. data/lib/glimmer/swt/table_item_proxy.rb +147 -0
  44. data/lib/glimmer/swt/table_proxy.rb +177 -0
  45. data/lib/glimmer/swt/text_proxy.rb +46 -0
  46. data/lib/glimmer/swt/widget_proxy.rb +389 -0
  47. data/lib/jquery.js +2 -0
  48. data/lib/samples/elaborate/contact_manager.rb +2 -3
  49. data/lib/samples/elaborate/login.rb +0 -1
  50. data/lib/samples/elaborate/tic_tac_toe.rb +5 -5
  51. data/lib/samples/hello/hello_computed.rb +19 -19
  52. data/lib/samples/hello/hello_tab.rb +2 -2
  53. metadata +92 -59
  54. data/lib/glimmer/config.rb +0 -22
  55. data/lib/glimmer/dsl/engine.rb +0 -193
  56. data/lib/glimmer/dsl/expression.rb +0 -42
  57. data/lib/glimmer/dsl/expression_handler.rb +0 -48
  58. data/lib/glimmer/dsl/opal/browser_expression.rb +0 -17
  59. data/lib/glimmer/dsl/opal/button_expression.rb +0 -18
  60. data/lib/glimmer/dsl/opal/combo_expression.rb +0 -17
  61. data/lib/glimmer/dsl/opal/grid_layout_expression.rb +0 -17
  62. data/lib/glimmer/dsl/opal/label_expression.rb +0 -17
  63. data/lib/glimmer/dsl/parent_expression.rb +0 -12
  64. data/lib/glimmer/dsl/static_expression.rb +0 -36
  65. data/lib/glimmer/dsl/top_level_expression.rb +0 -7
  66. data/lib/glimmer/error.rb +0 -6
  67. data/lib/glimmer/invalid_keyword_error.rb +0 -6
  68. data/lib/glimmer/opal/div_proxy.rb +0 -20
  69. data/lib/glimmer/opal/document_proxy.rb +0 -90
  70. data/lib/glimmer/opal/iframe_proxy.rb +0 -23
  71. data/lib/glimmer/opal/input_proxy.rb +0 -41
  72. data/lib/glimmer/opal/label_proxy.rb +0 -25
  73. data/lib/glimmer/opal/layout_data_proxy.rb +0 -31
@@ -0,0 +1,60 @@
1
+ require 'glimmer/swt/property_owner'
2
+
3
+ module Glimmer
4
+ module SWT
5
+ class LayoutProxy
6
+ include Glimmer::SWT::PropertyOwner
7
+
8
+ class << self
9
+ # Factory Method that translates a Glimmer DSL keyword into a WidgetProxy object
10
+ def for(keyword, parent, args)
11
+ the_layout_class = layout_class(keyword) || Glimmer::SWT::GridLayoutProxy
12
+ the_layout_class.new(parent, args)
13
+ end
14
+
15
+ def layout_class(keyword)
16
+ class_name_alternative = keyword.camelcase(:upper)
17
+ class_name_main = "#{class_name_alternative}Proxy"
18
+ a_layout_class = Glimmer::SWT.const_get(class_name_main.to_sym) rescue Glimmer::SWT.const_get(class_name_alternative.to_sym)
19
+ a_layout_class if a_layout_class.ancestors.include?(Glimmer::SWT::LayoutProxy)
20
+ rescue => e
21
+ puts "Layout #{keyword} was not found!"
22
+ nil
23
+ end
24
+
25
+ def layout_exists?(keyword)
26
+ !!layout_class(keyword)
27
+ end
28
+ end
29
+
30
+ attr_reader :parent, :args
31
+
32
+ def initialize(parent, args)
33
+ @parent = parent
34
+ @args = args
35
+ @parent.add_css_class(css_class)
36
+ end
37
+
38
+ def css_class
39
+ self.class.name.split('::').last.underscore.sub(/_proxy$/, '').gsub('_', '-')
40
+ end
41
+
42
+ def reapply
43
+ layout_css = <<~CSS
44
+ display: grid;
45
+ grid-template-columns: #{'auto ' * @num_columns.to_i};
46
+ grid-row-gap: #{@vertical_spacing}px;
47
+ grid-column-gap: #{@horizontal_spacing}px;
48
+ justify-content: start;
49
+ CSS
50
+ layout_css.split(";").map(&:strip).map {|l| l.split(':').map(&:strip)}.each do |key, value|
51
+ unless key.nil?
52
+ @parent.dom_element.css(key, value)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ require 'glimmer/swt/grid_layout_proxy'
@@ -1,19 +1,19 @@
1
- require 'glimmer/opal/element_proxy'
1
+ require 'glimmer/swt/widget_proxy'
2
2
 
3
3
  module Glimmer
4
- module Opal
5
- class ListProxy < ElementProxy
4
+ module SWT
5
+ class ListProxy < WidgetProxy
6
6
  ITEM_EMPTY = '_____'
7
7
  attr_reader :items, :selection
8
8
 
9
- def initialize(parent, args)
9
+ def initialize(parent, args)
10
10
  super(parent, args)
11
11
  @selection = []
12
12
  end
13
13
 
14
14
  def items=(items)
15
15
  @items = items.map {|item| item.strip == '' ? ITEM_EMPTY : item}
16
- redraw
16
+ redraw # consider repopulating li's instead of redrawing when li's are available.
17
17
  end
18
18
 
19
19
  def index_of(item)
@@ -43,37 +43,40 @@ module Glimmer
43
43
  'on_widget_selected' => {
44
44
  event: 'click',
45
45
  event_handler: -> (event_listener) {
46
- -> (event) {
47
- selected_item = event.target.text
48
- select(index_of(selected_item), event.meta?)
49
- event_listener.call(event)
46
+ -> (event) {
47
+ if event.target.prop('nodeName') == 'LI'
48
+ selected_item = event.target.text
49
+ select(index_of(selected_item), event.meta_key)
50
+ event_listener.call(event)
51
+ end
50
52
  }
51
53
  }
52
54
  }
53
55
  }
54
56
  end
55
57
 
56
- def name
58
+ def element
57
59
  'ul'
58
60
  end
59
61
 
60
62
  def dom
61
63
  list_items = @items
62
64
  list_id = id
63
- list_style = style
65
+ list_style = css
64
66
  list_selection = selection
65
- @dom ||= DOM {
66
- ul(id: list_id, style: list_style) {
67
+ @dom ||= html {
68
+ ul(id: list_id, class: name, style: list_style) {
67
69
  list_items.to_a.each_with_index do |item, index|
68
70
  li_class = ''
69
- li_class += ' selected-list-item' if list_selection.include?(item)
71
+ li_class += ' selected' if list_selection.include?(item)
70
72
  li_class += ' empty-list-item' if item == ITEM_EMPTY
71
73
  li(class: li_class) {
72
74
  item
73
75
  }
74
76
  end
77
+ nil #TODO look into glimmer-dsl-xml and why it doesn't ignore collections like each_with_index
75
78
  }
76
- }
79
+ }.to_s
77
80
  end
78
81
  end
79
82
  end
@@ -0,0 +1,146 @@
1
+ require 'glimmer/swt/widget_proxy'
2
+
3
+ module Glimmer
4
+ module SWT
5
+ class MessageBoxProxy < WidgetProxy
6
+ attr_reader :text, :message
7
+
8
+ def initialize(parent, args)
9
+ i = 0
10
+ @parent = parent
11
+ @args = args
12
+ @children = Set.new
13
+ @css_classes = Set.new(['modal', name])
14
+ @css = ''
15
+ @enabled = true
16
+ content do
17
+ on_widget_selected {
18
+ hide
19
+ }
20
+ end
21
+ end
22
+
23
+ def text=(txt)
24
+ @text = txt
25
+ redraw if @dom
26
+ end
27
+
28
+ def message=(msg)
29
+ @message = msg
30
+ redraw if @dom
31
+ end
32
+
33
+ def document
34
+ element = self
35
+ begin
36
+ element = element.parent
37
+ end while(element.parent)
38
+ element
39
+ end
40
+
41
+ def open
42
+ document.add_child(self)
43
+ end
44
+
45
+ def hide
46
+ dom_element.remove
47
+ end
48
+
49
+ def content(&block)
50
+ Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Opal::MessageBoxExpression.new, &block)
51
+ end
52
+
53
+ def name
54
+ 'div'
55
+ end
56
+
57
+ def selector
58
+ super + ' .close'
59
+ end
60
+
61
+ def listener_path
62
+ path + ' .close'
63
+ end
64
+
65
+ def observation_request_to_event_mapping
66
+ {
67
+ 'on_widget_selected' => {
68
+ event: 'click'
69
+ },
70
+ }
71
+ end
72
+
73
+ def style_dom_modal_css
74
+ <<~CSS
75
+ .modal {
76
+ position: fixed;
77
+ z-index: 1;
78
+ padding-top: 100px;
79
+ left: 0;
80
+ top: 0;
81
+ width: 100%;
82
+ height: 100%;
83
+ overflow: auto;
84
+ background-color: rgb(0,0,0);
85
+ background-color: rgba(0,0,0,0.4);
86
+ text-align: center;
87
+ }
88
+ .modal-content .text {
89
+ background: rgb(80, 116, 211);
90
+ color: white;
91
+ padding: 5px;
92
+ }
93
+ .modal-content .message {
94
+ padding: 20px;
95
+ }
96
+ .modal-content {
97
+ background-color: #fefefe;
98
+ margin: auto;
99
+ border: 1px solid #888;
100
+ display: inline-block;
101
+ min-width: 200px;
102
+ }
103
+ CSS
104
+ # .close {
105
+ # color: #aaaaaa;
106
+ # float: right;
107
+ # font-weight: bold;
108
+ # margin: 5px;
109
+ # }
110
+ # .close:hover,
111
+ # .close:focus {
112
+ # color: #000;
113
+ # text-decoration: none;
114
+ # cursor: pointer;
115
+ # }
116
+ end
117
+
118
+ def dom
119
+ modal_id = id
120
+ modal_style = css
121
+ modal_text = text
122
+ modal_message = message
123
+ modal_css_classes = css_classes
124
+ modal_class = modal_css_classes.to_a.join(' ')
125
+ @dom ||= html {
126
+ div(id: modal_id, style: modal_style, class: modal_class) {
127
+ style(class: 'modal-style') {
128
+ style_dom_modal_css #.split("\n").map(&:strip).join(' ')
129
+ }
130
+ div(class: 'modal-content') {
131
+ header(class: 'text') {
132
+ modal_text
133
+ }
134
+ tag(_name: 'p', id: 'message') {
135
+ modal_message
136
+ }
137
+ input(type: 'button', class: 'close', autofocus: 'autofocus', value: 'OK')
138
+ }
139
+ }
140
+ }.to_s
141
+ end
142
+ end
143
+ end
144
+ end
145
+
146
+ require 'glimmer/dsl/opal/message_box_expression'
@@ -1,5 +1,5 @@
1
1
  module Glimmer
2
- module Opal
2
+ module SWT
3
3
  Point = Struct.new(:x, :y)
4
4
  end
5
5
  end
@@ -1,5 +1,5 @@
1
1
  module Glimmer
2
- module Opal
2
+ module SWT
3
3
  # Adapts Glimmer UI classes to SWT JavaBean property owner classes (which are now adapted to Opal)
4
4
  module PropertyOwner
5
5
  def get_attribute(attribute_name)
@@ -0,0 +1,235 @@
1
+ require 'glimmer/swt/widget_proxy'
2
+ require 'glimmer/swt/point'
3
+
4
+ module Glimmer
5
+ module SWT
6
+ class ShellProxy < WidgetProxy
7
+ # TODO consider renaming to ShellProxy to match SWT API
8
+ attr_reader :minimum_size
9
+
10
+ def initialize(args)
11
+ @args = args
12
+ @children = []
13
+ # Document.ready? do
14
+ Document.find('body').empty unless ENV['RUBY_ENV'] == 'test'
15
+ redraw
16
+ # end
17
+ end
18
+
19
+ def element
20
+ 'div'
21
+ end
22
+
23
+ def parent_path
24
+ 'body'
25
+ end
26
+
27
+ def text
28
+ $document.title
29
+ end
30
+
31
+ def text=(value)
32
+ # Document.ready? do
33
+ Document.title = value
34
+ # end
35
+ end
36
+
37
+ def minimum_size=(width_or_minimum_size, height = nil)
38
+ @minimum_size = height.nil? ? width_or_minimum_size : Point.new(width_or_minimum_size, height)
39
+ redraw
40
+ end
41
+
42
+ def style_dom_css
43
+ <<~CSS
44
+ .hide {
45
+ display: none !important;
46
+ }
47
+ .selected, .tabs .tab.selected {
48
+ background: rgb(80, 116, 211);
49
+ color: white;
50
+ }
51
+ CSS
52
+ end
53
+
54
+ def style_dom_shell_css
55
+ <<~CSS
56
+ html {
57
+ width: 100%;
58
+ height: 100%;
59
+ }
60
+ body, .shell {
61
+ width: 100%;
62
+ height: 100%;
63
+ margin: 0;
64
+ }
65
+ .shell iframe {
66
+ width: 100%;
67
+ height: 100%;
68
+ }
69
+ CSS
70
+ end
71
+
72
+ def style_dom_list_css
73
+ <<~CSS
74
+ ul {
75
+ list-style: none;
76
+ padding: 0;
77
+ }
78
+ li {
79
+ cursor: default;
80
+ padding-left: 10px;
81
+ padding-right: 10px;
82
+ }
83
+ li.empty-list-item {
84
+ color: transparent;
85
+ }
86
+ CSS
87
+ end
88
+
89
+ def style_dom_tab_css
90
+ <<~CSS
91
+ .tabs .tab {
92
+ background-color: inherit;
93
+ float: left;
94
+ border: none;
95
+ outline: none;
96
+ cursor: pointer;
97
+ padding: 14px 16px;
98
+ transition: 0.3s;
99
+ font-size: 17px;
100
+ }
101
+ .tabs {
102
+ overflow: hidden;
103
+ border: 1px solid #ccc;
104
+ background-color: #f1f1f1;
105
+ }
106
+ CSS
107
+ end
108
+
109
+ def style_dom_tab_item_css
110
+ <<~CSS
111
+ /* Create an selected/current tablink class */
112
+ .tabs .tab.selected {
113
+ background-color: #ccc;
114
+ }
115
+ /* Change background color of buttons on hover */
116
+ .tabs .tab:hover {
117
+ background-color: #ddd;
118
+ }
119
+ /* Style the tab content */
120
+ .tab-item {
121
+ padding: 6px 12px;
122
+ border: 1px solid #ccc;
123
+ border-top: none;
124
+ }
125
+ CSS
126
+ end
127
+
128
+ def style_dom_modal_css
129
+ <<~CSS
130
+ /* The Modal (background) */
131
+ .modal {
132
+ position: fixed; /* Stay in place */
133
+ z-index: 1; /* Sit on top */
134
+ padding-top: 100px; /* Location of the box */
135
+ left: 0;
136
+ top: 0;
137
+ width: 100%; /* Full width */
138
+ height: 100%; /* Full height */
139
+ overflow: auto; /* Enable scroll if needed */
140
+ background-color: rgb(0,0,0); /* Fallback color */
141
+ background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
142
+ text-align: center;
143
+ }
144
+
145
+ /* Modal Content */
146
+ .modal-content {
147
+ background-color: #fefefe;
148
+ margin: auto;
149
+ border: 1px solid #888;
150
+ display: inline-block;
151
+ min-width: 200px;
152
+ }
153
+
154
+ .modal-content .text {
155
+ background: rgb(80, 116, 211);
156
+ color: white;
157
+ padding: 5px;
158
+ }
159
+
160
+ .modal-content .message {
161
+ padding: 20px;
162
+ }
163
+
164
+ /* The Close Button */
165
+ .close {
166
+ color: #aaaaaa;
167
+ float: right;
168
+ font-weight: bold;
169
+ margin: 5px;
170
+ }
171
+
172
+ .close:hover,
173
+ .close:focus {
174
+ color: #000;
175
+ text-decoration: none;
176
+ cursor: pointer;
177
+ }
178
+ CSS
179
+ end
180
+
181
+ def style_dom_table_css
182
+ <<~CSS
183
+ table {
184
+ border-spacing: 0;
185
+ }
186
+
187
+ table tr th,td {
188
+ cursor: default;
189
+ }
190
+ CSS
191
+ end
192
+
193
+ def dom
194
+ i = 0
195
+ body_id = id
196
+ body_class = name
197
+ body_style = '' # a start for more styling further along
198
+ if @minimum_size
199
+ body_style += "min-width: #{@minimum_size.x}px; min-height: #{@minimum_size.y}px;" if @minimum_size
200
+ Document.find('body').css('min-width', "#{@minimum_size.x}px")
201
+ Document.find('body').css('min-height', "#{@minimum_size.y}px")
202
+ end
203
+ @dom ||= html {
204
+ div(id: body_id, class: body_class, style: body_style) {
205
+ style(class: 'common-style') {
206
+ style_dom_css
207
+ }
208
+ style(class: 'shell-style') {
209
+ style_dom_shell_css
210
+ }
211
+ style(class: 'list-style') {
212
+ style_dom_list_css
213
+ }
214
+ style(class: 'tab-style') {
215
+ style_dom_tab_css
216
+ }
217
+ # style(class: 'tab-item-style') {
218
+ # style_dom_tab_item_css
219
+ # }
220
+ # style(class: 'modal-style') {
221
+ # style_dom_modal_css
222
+ # }
223
+ style(class: 'table-style') {
224
+ style_dom_table_css
225
+ }
226
+ }
227
+ }.to_s
228
+ end
229
+
230
+ def open
231
+ # TODO make it start as hidden and show shell upon open
232
+ end
233
+ end
234
+ end
235
+ end