glimmer-dsl-opal 0.7.3 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +40 -0
  3. data/README.md +847 -158
  4. data/VERSION +1 -1
  5. data/lib/glimmer-dsl-opal.rb +15 -3
  6. data/lib/glimmer-dsl-opal/ext/class.rb +10 -0
  7. data/lib/{file.rb → glimmer-dsl-opal/ext/file.rb} +0 -0
  8. data/lib/glimmer-dsl-opal/ext/glimmer/dsl/engine.rb +25 -0
  9. data/lib/glimmer-dsl-opal/samples/elaborate/contact_manager.rb +50 -23
  10. data/lib/glimmer-dsl-opal/samples/elaborate/login.rb +22 -5
  11. data/lib/glimmer-dsl-opal/samples/hello/hello_browser.rb +24 -1
  12. data/lib/glimmer-dsl-opal/samples/hello/hello_button.rb +46 -0
  13. data/lib/glimmer-dsl-opal/samples/hello/hello_computed.rb +27 -0
  14. data/lib/glimmer-dsl-opal/samples/hello/hello_custom_shell.rb +7 -7
  15. data/lib/glimmer-dsl-opal/samples/hello/hello_list_multi_selection.rb +62 -32
  16. data/lib/glimmer-dsl-opal/samples/hello/hello_list_single_selection.rb +47 -22
  17. data/lib/glimmer-dsl-opal/samples/hello/hello_menu_bar.rb +241 -0
  18. data/lib/glimmer-dsl-opal/samples/hello/hello_message_box.rb +37 -0
  19. data/lib/glimmer-dsl-opal/samples/hello/hello_pop_up_context_menu.rb +84 -0
  20. data/lib/glimmer-dsl-opal/samples/hello/hello_world.rb +3 -3
  21. data/lib/glimmer/config/opal_logger.rb +16 -0
  22. data/lib/glimmer/data_binding/observable_element.rb +1 -1
  23. data/lib/glimmer/dsl/opal/custom_widget_expression.rb +6 -0
  24. data/lib/glimmer/dsl/opal/dsl.rb +2 -0
  25. data/lib/glimmer/dsl/opal/menu_bar_expression.rb +54 -0
  26. data/lib/glimmer/dsl/opal/menu_expression.rb +61 -0
  27. data/lib/glimmer/dsl/opal/shell_expression.rb +0 -4
  28. data/lib/glimmer/dsl/opal/widget_expression.rb +3 -2
  29. data/lib/glimmer/dsl/opal/widget_listener_expression.rb +2 -2
  30. data/lib/glimmer/swt/custom/checkbox_group.rb +2 -2
  31. data/lib/glimmer/swt/custom/radio_group.rb +2 -2
  32. data/lib/glimmer/swt/date_time_proxy.rb +1 -1
  33. data/lib/glimmer/swt/display_proxy.rb +5 -4
  34. data/lib/glimmer/swt/event_listener_proxy.rb +14 -4
  35. data/lib/glimmer/swt/grid_layout_proxy.rb +21 -12
  36. data/lib/glimmer/swt/label_proxy.rb +17 -6
  37. data/lib/glimmer/swt/latest_message_box_proxy.rb +20 -0
  38. data/lib/glimmer/swt/latest_shell_proxy.rb +20 -0
  39. data/lib/glimmer/swt/layout_data_proxy.rb +6 -6
  40. data/lib/glimmer/swt/list_proxy.rb +15 -0
  41. data/lib/glimmer/swt/menu_item_proxy.rb +174 -0
  42. data/lib/glimmer/swt/menu_proxy.rb +273 -0
  43. data/lib/glimmer/swt/message_box_proxy.rb +57 -72
  44. data/lib/glimmer/swt/property_owner.rb +2 -0
  45. data/lib/glimmer/swt/radio_proxy.rb +1 -1
  46. data/lib/glimmer/swt/shell_proxy.rb +34 -189
  47. data/lib/glimmer/swt/tab_folder_proxy.rb +43 -0
  48. data/lib/glimmer/swt/table_column_proxy.rb +3 -2
  49. data/lib/glimmer/swt/table_editor.rb +1 -1
  50. data/lib/glimmer/swt/table_item_proxy.rb +7 -5
  51. data/lib/glimmer/swt/table_proxy.rb +10 -0
  52. data/lib/glimmer/swt/widget_proxy.rb +325 -31
  53. data/lib/glimmer/ui/custom_shell.rb +9 -7
  54. data/lib/glimmer/ui/custom_widget.rb +3 -3
  55. metadata +26 -6
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.7.3
1
+ 0.9.1
@@ -33,6 +33,11 @@ if RUBY_ENGINE == 'opal'
33
33
  # TODO look into making append_path work (causing some trouble right now)
34
34
  # Opal.append_path File.expand_path('../glimmer-dsl-opal/missing', __FILE__)
35
35
  # Opal.append_path GLIMMER_DSL_OPAL_MISSING
36
+ module Kernel
37
+ def include_package(package)
38
+ # No Op (just a shim)
39
+ end
40
+ end
36
41
 
37
42
  require 'opal-parser'
38
43
  require 'native' # move this to opal-async
@@ -49,14 +54,18 @@ if RUBY_ENGINE == 'opal'
49
54
  # require 'glimmer-dsl-opal/vendor/jquery-ui/jquery-ui.structure.min.css'
50
55
  # require 'glimmer-dsl-opal/vendor/jquery-ui/jquery-ui.theme.min.css'
51
56
  require 'opal-jquery'
57
+ require 'opal/jquery/local_storage'
52
58
 
53
59
  require 'facets/hash/symbolize_keys'
60
+ require 'glimmer-dsl-opal/ext/class'
61
+ require 'glimmer-dsl-opal/ext/file'
54
62
  require 'glimmer-dsl-opal/ext/struct'
55
63
  require 'glimmer'
56
64
  require 'glimmer-dsl-opal/ext/exception'
57
65
  require 'glimmer-dsl-opal/ext/date'
66
+ require 'glimmer-dsl-opal/ext/glimmer/dsl/engine'
58
67
  require 'uri'
59
-
68
+
60
69
  # Spiking async logging
61
70
  # logger = Glimmer::Config.logger
62
71
  # original_add_method = logger.class.instance_method(:add)
@@ -68,14 +77,17 @@ if RUBY_ENGINE == 'opal'
68
77
  # end
69
78
 
70
79
  require 'glimmer/dsl/opal/dsl'
71
-
80
+ require 'glimmer/config/opal_logger'
72
81
  require 'glimmer-dsl-xml'
73
82
  require 'glimmer-dsl-css'
74
83
  Element.alias_native :replace_with, :replaceWith
75
84
  Element.alias_native :select
76
85
 
77
- # Glimmer::Config.loop_max_count = 20
86
+ # Glimmer::Config.loop_max_count = 20 # TODO disable
78
87
 
88
+ original_logger_level = Glimmer::Config.logger.level
89
+ Glimmer::Config.logger = Glimmer::Config::OpalLogger.new(STDOUT)
90
+ Glimmer::Config.logger.level = original_logger_level
79
91
  Glimmer::Config.excluded_keyword_checkers << lambda do |method_symbol, *args|
80
92
  method = method_symbol.to_s
81
93
  result = false
@@ -0,0 +1,10 @@
1
+ class Class
2
+ def inherited(klass)
3
+ @descendants ||= []
4
+ @descendants << klass
5
+ end
6
+
7
+ def descendants
8
+ @descendants.to_collection.map { |klass| [klass] + (klass.descendants if klass.respond_to?(:descendants)).to_a }.flatten.compact
9
+ end
10
+ end
@@ -0,0 +1,25 @@
1
+ require 'glimmer/swt/latest_shell_proxy'
2
+ require 'glimmer/swt/latest_message_box_proxy'
3
+
4
+ module Glimmer
5
+ module DSL
6
+ class Engine
7
+ class << self
8
+ def interpret_expression(expression, keyword, *args, &block)
9
+ work = lambda do
10
+ expression.interpret(parent, keyword, *args, &block).tap do |ui_object|
11
+ add_content(ui_object, expression, &block)
12
+ dsl_stack.pop
13
+ end
14
+ end
15
+ if ['shell', 'message_box'].include?(keyword) && Glimmer::SWT::DisplayProxy.instance.send("#{keyword}s").empty?
16
+ Document.ready?(&work)
17
+ Glimmer::SWT.const_get("Latest#{keyword.camelcase(:upper)}Proxy").new
18
+ else
19
+ work.call
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -12,41 +12,76 @@ class ContactManager
12
12
  shell {
13
13
  text "Contact Manager"
14
14
  composite {
15
- composite {
16
- grid_layout 2, false
17
- label {text "First &Name: "}
15
+ group {
16
+ grid_layout(2, false) {
17
+ margin_width 0
18
+ margin_height 0
19
+ }
20
+ layout_data :fill, :center, true, false
21
+ text 'Lookup Contacts'
22
+ font height: 24
23
+
24
+ label {
25
+ layout_data :right, :center, false, false
26
+ text "First &Name: "
27
+ font height: 16
28
+ }
18
29
  text {
30
+ layout_data :fill, :center, true, false
19
31
  text bind(@contact_manager_presenter, :first_name)
20
32
  on_key_pressed {|key_event|
21
- @contact_manager_presenter.find if key_event.keyCode == Glimmer::SWT::SWTProxy[:cr]
33
+ @contact_manager_presenter.find if key_event.keyCode == swt(:cr)
22
34
  }
23
35
  }
24
- label {text "&Last Name: "}
36
+
37
+ label {
38
+ layout_data :right, :center, false, false
39
+ text "&Last Name: "
40
+ font height: 16
41
+ }
25
42
  text {
43
+ layout_data :fill, :center, true, false
26
44
  text bind(@contact_manager_presenter, :last_name)
27
45
  on_key_pressed {|key_event|
28
- @contact_manager_presenter.find if key_event.keyCode == Glimmer::SWT::SWTProxy[:cr]
46
+ @contact_manager_presenter.find if key_event.keyCode == swt(:cr)
29
47
  }
30
48
  }
31
- label {text "&Email: "}
49
+
50
+ label {
51
+ layout_data :right, :center, false, false
52
+ text "&Email: "
53
+ font height: 16
54
+ }
32
55
  text {
56
+ layout_data :fill, :center, true, false
33
57
  text bind(@contact_manager_presenter, :email)
34
58
  on_key_pressed {|key_event|
35
- @contact_manager_presenter.find if key_event.keyCode == Glimmer::SWT::SWTProxy[:cr]
59
+ @contact_manager_presenter.find if key_event.keyCode == swt(:cr)
36
60
  }
37
61
  }
62
+
38
63
  composite {
39
- grid_layout 2, false
64
+ row_layout {
65
+ margin_width 0
66
+ margin_height 0
67
+ }
68
+ layout_data(:right, :center, false, false) {
69
+ horizontal_span 2
70
+ }
71
+
40
72
  button {
41
73
  text "&Find"
42
- on_widget_selected {
43
- @contact_manager_presenter.find
74
+ on_widget_selected { @contact_manager_presenter.find }
75
+ on_key_pressed {|key_event|
76
+ @contact_manager_presenter.find if key_event.keyCode == swt(:cr)
44
77
  }
45
78
  }
79
+
46
80
  button {
47
81
  text "&List All"
48
- on_widget_selected {
49
- @contact_manager_presenter.list
82
+ on_widget_selected { @contact_manager_presenter.list }
83
+ on_key_pressed {|key_event|
84
+ @contact_manager_presenter.list if key_event.keyCode == swt(:cr)
50
85
  }
51
86
  }
52
87
  }
@@ -63,25 +98,17 @@ class ContactManager
63
98
  table_column {
64
99
  text "First Name"
65
100
  width 80
66
- on_widget_selected {
67
- @contact_manager_presenter.toggle_sort(:first_name)
68
- }
69
101
  }
70
102
  table_column {
71
103
  text "Last Name"
72
104
  width 80
73
- on_widget_selected {
74
- @contact_manager_presenter.toggle_sort(:last_name)
75
- }
76
105
  }
77
106
  table_column {
78
107
  text "Email"
79
108
  width 200
80
- on_widget_selected {
81
- @contact_manager_presenter.toggle_sort(:email)
82
- }
83
109
  }
84
- items bind(@contact_manager_presenter, :results), column_properties(:first_name, :last_name, :email)
110
+ items bind(@contact_manager_presenter, :results),
111
+ column_properties(:first_name, :last_name, :email)
85
112
  on_mouse_up { |event|
86
113
  table_proxy.edit_table_item(event.table_item, event.column_index)
87
114
  }
@@ -1,6 +1,5 @@
1
1
  require "observer"
2
2
 
3
- #Presents login screen data
4
3
  class LoginPresenter
5
4
 
6
5
  attr_accessor :user_name
@@ -16,10 +15,13 @@ class LoginPresenter
16
15
  def status=(status)
17
16
  @status = status
18
17
 
19
- #TODO add feature to bind dependent properties to master property (2017-07-25 nested data binding)
20
18
  notify_observers("logged_in")
21
19
  notify_observers("logged_out")
22
20
  end
21
+
22
+ def valid?
23
+ !@user_name.to_s.strip.empty? && !@password.to_s.strip.empty?
24
+ end
23
25
 
24
26
  def logged_in
25
27
  self.status == "Logged In"
@@ -30,6 +32,7 @@ class LoginPresenter
30
32
  end
31
33
 
32
34
  def login
35
+ return unless valid?
33
36
  self.status = "Logged In"
34
37
  end
35
38
 
@@ -41,7 +44,6 @@ class LoginPresenter
41
44
 
42
45
  end
43
46
 
44
- #Login screen
45
47
  class Login
46
48
  include Glimmer
47
49
 
@@ -53,15 +55,21 @@ class Login
53
55
  grid_layout 2, false #two columns with differing widths
54
56
 
55
57
  label { text "Username:" } # goes in column 1
56
- text { # goes in column 2
58
+ @user_name_text = text { # goes in column 2
57
59
  text bind(presenter, :user_name)
58
60
  enabled bind(presenter, :logged_out)
61
+ on_key_pressed { |event|
62
+ @password_text.set_focus if event.keyCode == swt(:cr)
63
+ }
59
64
  }
60
65
 
61
66
  label { text "Password:" }
62
- text(:password, :border) {
67
+ @password_text = text(:password, :border) {
63
68
  text bind(presenter, :password)
64
69
  enabled bind(presenter, :logged_out)
70
+ on_key_pressed { |event|
71
+ presenter.login if event.keyCode == swt(:cr)
72
+ }
65
73
  }
66
74
 
67
75
  label { text "Status:" }
@@ -71,12 +79,21 @@ class Login
71
79
  text "Login"
72
80
  enabled bind(presenter, :logged_out)
73
81
  on_widget_selected { presenter.login }
82
+ on_key_pressed { |event|
83
+ presenter.login if event.keyCode == swt(:cr)
84
+ }
74
85
  }
75
86
 
76
87
  button {
77
88
  text "Logout"
78
89
  enabled bind(presenter, :logged_in)
79
90
  on_widget_selected { presenter.logout }
91
+ on_key_pressed { |event|
92
+ if event.keyCode == swt(:cr)
93
+ presenter.logout
94
+ @user_name_text.set_focus
95
+ end
96
+ }
80
97
  }
81
98
  }
82
99
  }
@@ -1,8 +1,31 @@
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
  include Glimmer
2
23
 
3
24
  shell {
25
+ text 'Hello, Browser!'
4
26
  minimum_size 1024, 860
27
+
5
28
  browser {
6
- url 'http://brightonresort.com/about'
29
+ url 'https://brightonresort.com/about'
7
30
  }
8
31
  }.open
@@ -0,0 +1,46 @@
1
+ # Copyright (c) 2007-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
+ class HelloButton
23
+ include Glimmer
24
+
25
+ attr_accessor :count
26
+
27
+ def initialize
28
+ @count = 0
29
+ end
30
+
31
+ def launch
32
+ shell {
33
+ text 'Hello, Button!'
34
+
35
+ button {
36
+ text bind(self, :count) {|value| "Click To Increment: #{value} "}
37
+
38
+ on_widget_selected {
39
+ self.count += 1
40
+ }
41
+ }
42
+ }.open
43
+ end
44
+ end
45
+
46
+ HelloButton.new.launch
@@ -1,3 +1,24 @@
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_relative 'hello_computed/contact'
2
23
 
3
24
  class HelloComputed
@@ -14,6 +35,7 @@ class HelloComputed
14
35
  def launch
15
36
  shell {
16
37
  text 'Hello, Computed!'
38
+
17
39
  composite {
18
40
  grid_layout {
19
41
  num_columns 2
@@ -21,6 +43,7 @@ class HelloComputed
21
43
  horizontal_spacing 20
22
44
  vertical_spacing 10
23
45
  }
46
+
24
47
  label {text 'First &Name: '}
25
48
  text {
26
49
  text bind(@contact, :first_name)
@@ -29,6 +52,7 @@ class HelloComputed
29
52
  grab_excess_horizontal_space true
30
53
  }
31
54
  }
55
+
32
56
  label {text '&Last Name: '}
33
57
  text {
34
58
  text bind(@contact, :last_name)
@@ -37,6 +61,7 @@ class HelloComputed
37
61
  grab_excess_horizontal_space true
38
62
  }
39
63
  }
64
+
40
65
  label {text '&Year of Birth: '}
41
66
  text {
42
67
  text bind(@contact, :year_of_birth)
@@ -45,6 +70,7 @@ class HelloComputed
45
70
  grab_excess_horizontal_space true
46
71
  }
47
72
  }
73
+
48
74
  label {text 'Name: '}
49
75
  label {
50
76
  text bind(@contact, :name, computed_by: [:first_name, :last_name])
@@ -53,6 +79,7 @@ class HelloComputed
53
79
  grab_excess_horizontal_space true
54
80
  }
55
81
  }
82
+
56
83
  label {text 'Age: '}
57
84
  label {
58
85
  text bind(@contact, :age, on_write: :to_i, computed_by: [:year_of_birth])
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2020 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
@@ -26,7 +26,7 @@ require 'date'
26
26
  class EmailShell
27
27
  include Glimmer::UI::CustomShell
28
28
 
29
- # multiple options without default values
29
+ # multiple options without default values
30
30
  options :date, :subject, :from, :message
31
31
 
32
32
  # single option with default value
@@ -41,7 +41,7 @@ class EmailShell
41
41
  shell(swt_style) {
42
42
  grid_layout(2, false)
43
43
 
44
- text subject
44
+ text subject
45
45
 
46
46
  label {
47
47
  text 'Date:'
@@ -78,7 +78,7 @@ class EmailShell
78
78
  }
79
79
 
80
80
  background :white
81
- text message
81
+ text message
82
82
  }
83
83
  }
84
84
  }
@@ -149,7 +149,7 @@ class HelloCustomShell
149
149
  }
150
150
  }
151
151
  }.open
152
- end
152
+ end
153
153
  end
154
154
 
155
155
  HelloCustomShell.new.launch