glimmer-dsl-swt 4.18.5.0 → 4.18.5.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +43 -0
  3. data/README.md +16 -11
  4. data/VERSION +1 -1
  5. data/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md +179 -33
  6. data/docs/reference/GLIMMER_SAMPLES.md +58 -0
  7. data/glimmer-dsl-swt.gemspec +7 -7
  8. data/lib/glimmer/data_binding/widget_binding.rb +4 -1
  9. data/lib/glimmer/dsl/swt/dialog_expression.rb +18 -9
  10. data/lib/glimmer/dsl/swt/dsl.rb +1 -0
  11. data/lib/glimmer/dsl/swt/font_expression.rb +1 -1
  12. data/lib/glimmer/dsl/swt/shape_expression.rb +1 -1
  13. data/lib/glimmer/dsl/swt/shell_expression.rb +1 -1
  14. data/lib/glimmer/swt/custom/drawable.rb +10 -2
  15. data/lib/glimmer/swt/custom/shape.rb +458 -58
  16. data/lib/glimmer/swt/custom/shape/arc.rb +35 -0
  17. data/lib/glimmer/swt/custom/shape/focus.rb +2 -2
  18. data/lib/glimmer/swt/custom/shape/image.rb +35 -9
  19. data/lib/glimmer/swt/custom/shape/line.rb +88 -4
  20. data/lib/glimmer/swt/custom/shape/oval.rb +18 -0
  21. data/lib/glimmer/swt/custom/shape/point.rb +10 -5
  22. data/lib/glimmer/swt/custom/shape/polygon.rb +105 -15
  23. data/lib/glimmer/swt/custom/shape/polyline.rb +88 -15
  24. data/lib/glimmer/swt/custom/shape/rectangle.rb +19 -0
  25. data/lib/glimmer/swt/custom/shape/text.rb +13 -3
  26. data/lib/glimmer/swt/{directory_dialog_proxy.rb → dialog_proxy.rb} +36 -7
  27. data/lib/glimmer/swt/font_proxy.rb +12 -6
  28. data/lib/glimmer/swt/message_box_proxy.rb +1 -0
  29. data/lib/glimmer/swt/properties.rb +3 -0
  30. data/lib/glimmer/swt/proxy_properties.rb +145 -0
  31. data/lib/glimmer/swt/transform_proxy.rb +39 -35
  32. data/lib/glimmer/swt/widget_proxy.rb +32 -60
  33. data/samples/elaborate/contact_manager.rb +2 -0
  34. data/samples/elaborate/login.rb +2 -0
  35. data/samples/elaborate/mandelbrot_fractal.rb +1 -0
  36. data/samples/elaborate/meta_sample.rb +1 -0
  37. data/samples/elaborate/tetris.rb +2 -1
  38. data/samples/elaborate/tic_tac_toe.rb +2 -0
  39. data/samples/elaborate/user_profile.rb +10 -8
  40. data/samples/hello/hello_browser.rb +2 -0
  41. data/samples/hello/hello_button.rb +2 -0
  42. data/samples/hello/hello_canvas.rb +157 -77
  43. data/samples/hello/hello_canvas_animation.rb +2 -0
  44. data/samples/hello/hello_canvas_transform.rb +2 -0
  45. data/samples/hello/hello_checkbox.rb +2 -0
  46. data/samples/hello/hello_checkbox_group.rb +2 -0
  47. data/samples/hello/hello_code_text.rb +2 -0
  48. data/{lib/glimmer/dsl/swt/directory_dialog_expression.rb → samples/hello/hello_color_dialog.rb} +44 -24
  49. data/samples/hello/hello_combo.rb +2 -0
  50. data/samples/hello/hello_computed.rb +2 -0
  51. data/samples/hello/hello_cursor.rb +2 -0
  52. data/samples/hello/hello_custom_shell.rb +1 -0
  53. data/samples/hello/hello_custom_widget.rb +2 -0
  54. data/samples/hello/hello_date_time.rb +2 -0
  55. data/samples/hello/hello_dialog.rb +2 -0
  56. data/samples/hello/hello_directory_dialog.rb +2 -0
  57. data/samples/hello/hello_drag_and_drop.rb +5 -3
  58. data/samples/hello/hello_expand_bar.rb +2 -0
  59. data/samples/hello/hello_file_dialog.rb +2 -0
  60. data/samples/hello/hello_font_dialog.rb +84 -0
  61. data/samples/hello/hello_group.rb +2 -0
  62. data/samples/hello/hello_link.rb +2 -0
  63. data/samples/hello/hello_list_multi_selection.rb +2 -0
  64. data/samples/hello/hello_list_single_selection.rb +2 -0
  65. data/samples/hello/hello_menu_bar.rb +2 -0
  66. data/samples/hello/hello_message_box.rb +2 -0
  67. data/samples/hello/hello_pop_up_context_menu.rb +2 -0
  68. data/samples/hello/hello_progress_bar.rb +2 -0
  69. data/samples/hello/hello_radio.rb +2 -0
  70. data/samples/hello/hello_radio_group.rb +2 -0
  71. data/samples/hello/hello_sash_form.rb +2 -0
  72. data/samples/hello/hello_spinner.rb +2 -0
  73. data/samples/hello/hello_styled_text.rb +19 -17
  74. data/samples/hello/hello_tab.rb +2 -0
  75. data/samples/hello/hello_table.rb +2 -0
  76. data/samples/hello/hello_world.rb +2 -0
  77. metadata +6 -6
  78. data/lib/glimmer/dsl/swt/file_dialog_expression.rb +0 -48
  79. data/lib/glimmer/swt/file_dialog_proxy.rb +0 -68
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  include Glimmer
23
25
 
24
26
  shell {
@@ -1,3 +1,5 @@
1
+ require 'glimmer-dsl-swt'
2
+
1
3
  include Glimmer
2
4
 
3
5
  glimmer_logo = File.expand_path('../../icons/scaffold_app.png', __dir__)
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  class HelloCheckbox
23
25
  class Person
24
26
  attr_accessor :skiing, :snowboarding, :snowmobiling, :snowshoeing
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  # This sample demonstrates the use of a `checkbox_group` (aka `check_group`) in Glimmer, which provides terser syntax
23
25
  # than HelloCheckbox for representing multiple checkbox buttons (`button(:check)`) by relying on data-binding to
24
26
  # automatically spawn the `checkbox` widgets (`button(:check)`) based on available options on the model.
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  include Glimmer
23
25
 
24
26
  shell {
@@ -19,30 +19,50 @@
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/dsl/static_expression'
23
- require 'glimmer/dsl/parent_expression'
24
- require 'glimmer/dsl/top_level_expression'
25
- require 'glimmer/swt/directory_dialog_proxy'
22
+ require 'glimmer-dsl-swt'
26
23
 
27
- module Glimmer
28
- module DSL
29
- module SWT
30
- class DirectoryDialogExpression < StaticExpression
31
- include TopLevelExpression
32
- include ParentExpression
33
-
34
- include_package 'org.eclipse.swt.widgets'
35
-
36
- def can_interpret?(parent, keyword, *args, &block)
37
- keyword == 'directory_dialog' and
38
- (parent.nil? or parent.is_a?(Shell) or parent.is_a?(Glimmer::SWT::ShellProxy))
39
- end
24
+ class HelloColorDialog
25
+ include Glimmer::UI::CustomShell
26
+
27
+ attr_accessor :selected_color
28
+
29
+ before_body {
30
+ self.selected_color = :black
31
+ }
40
32
 
41
- def interpret(parent, keyword, *args, &block)
42
- args = [parent] + args unless parent.nil?
43
- Glimmer::SWT::DirectoryDialogProxy.send(:new, *args)
44
- end
45
- end
46
- end
47
- end
33
+ body {
34
+ shell {
35
+ minimum_size 220, 0
36
+ grid_layout
37
+
38
+ text 'Hello, Color Dialog!'
39
+
40
+ label {
41
+ layout_data :center, :center, true, false
42
+ text 'Selected Color:'
43
+ font height: 14, style: :bold
44
+ }
45
+
46
+ canvas(:border) {
47
+ layout_data :center, :center, true, false
48
+ background bind(self, :selected_color)
49
+
50
+ on_mouse_up {
51
+ self.selected_color = color_dialog.open
52
+ }
53
+ }
54
+
55
+ button {
56
+ layout_data :center, :center, true, false
57
+ text "Choose Color..."
58
+
59
+ on_widget_selected {
60
+ self.selected_color = color_dialog.open
61
+ }
62
+ }
63
+
64
+ }
65
+ }
48
66
  end
67
+
68
+ HelloColorDialog.launch
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  class HelloCombo
23
25
  class Person
24
26
  attr_accessor :country, :country_options
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  require_relative 'hello_computed/contact'
23
25
 
24
26
  class HelloComputed
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  class HelloCursor
23
25
  include Glimmer::UI::CustomShell
24
26
 
@@ -19,6 +19,7 @@
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-dsl-swt'
22
23
  require 'date'
23
24
 
24
25
  # This class declares an `email_shell` custom shell, aka custom window (by convention)
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  # This class declares a `greeting_label` custom widget (by convention)
23
25
  class GreetingLabel
24
26
  include Glimmer::UI::CustomWidget
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  class HelloDateTime
23
25
  class Person
24
26
  attr_accessor :date_of_birth
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  include Glimmer
23
25
 
24
26
  shell {
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  class HelloDirectoryDialog
23
25
  include Glimmer::UI::CustomShell
24
26
 
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2007-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
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  class Location
23
25
  attr_accessor :country
24
26
 
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  class HelloExpandBar
23
25
  include Glimmer::UI::CustomShell
24
26
 
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  class HelloFileDialog
23
25
  include Glimmer::UI::CustomShell
24
26
 
@@ -0,0 +1,84 @@
1
+ # Copyright (c) 2007-2021 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-dsl-swt'
23
+
24
+ class HelloFontDialog
25
+ include Glimmer::UI::CustomShell
26
+
27
+ attr_accessor :selected_font_data
28
+
29
+ before_body {
30
+ @selected_font_data = FontData.new('Times New Roman', 40, swt(:bold))
31
+ }
32
+
33
+ body {
34
+ shell {
35
+ grid_layout {
36
+ margin_width 15
37
+ margin_width 15
38
+ }
39
+ minimum_size 400, 0
40
+
41
+ text 'Hello, Font Dialog!'
42
+
43
+ label {
44
+ text 'Selected Font:'
45
+ font height: 14, style: :bold
46
+ }
47
+
48
+ label(:center) {
49
+ layout_data(:fill, :center, true, true) {
50
+ vertical_indent 15
51
+ height_hint 200
52
+ }
53
+ background :white
54
+ font bind(self, 'selected_font_data')
55
+ text bind(self, 'selected_font_data') {|font_data|
56
+ style = case font_data.style
57
+ when swt(:normal)
58
+ 'Normal'
59
+ when swt(:italic)
60
+ 'Italic'
61
+ when swt(:bold)
62
+ 'Bold'
63
+ when swt(:bold, :italic)
64
+ 'Bold Italic'
65
+ end
66
+ "#{font_data.name}\n#{font_data.height}\n#{style}"
67
+ }
68
+ }
69
+
70
+ button {
71
+ text "Choose Font..."
72
+
73
+ on_widget_selected {
74
+ self.selected_font_data = font_dialog {
75
+ font_list [@selected_font_data]
76
+ }.open
77
+ }
78
+ }
79
+
80
+ }
81
+ }
82
+ end
83
+
84
+ HelloFontDialog.launch
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  class HelloGroup
23
25
  class Person
24
26
  attr_accessor :male, :female, :child, :teen, :adult, :senior
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  include Glimmer
23
25
 
24
26
  shell { |main_shell|
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  class HelloListMultiSelection
23
25
  class Person
24
26
  attr_accessor :provinces, :provinces_options
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  class HelloListSingleSelection
23
25
  class Person
24
26
  attr_accessor :country, :country_options
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  include Glimmer
23
25
 
24
26
  COLORS = [:white, :red, :yellow, :green, :blue, :magenta, :gray, :black]
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  include Glimmer
23
25
 
24
26
  shell {
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  include Glimmer
23
25
 
24
26
  shell {
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  class HelloProgressBar
23
25
  include Glimmer::UI::CustomShell
24
26
 
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  class HelloRadio
23
25
  class Person
24
26
  attr_accessor :male, :female, :child, :teen, :adult, :senior
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  # This sample demonstrates the use of a `radio_group` in Glimmer, which provides terser syntax
23
25
  # than HelloRadio for representing multiple radio buttons by relying on data-binding to
24
26
  # automatically spawn the `radio` widgets based on available options on the model.
@@ -19,6 +19,8 @@
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-dsl-swt'
23
+
22
24
  class SashFormPresenter
23
25
  include Glimmer
24
26