glimmer-dsl-opal 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +84 -3
- data/VERSION +1 -1
- data/app/assets/images/glimmer/images/calendar.gif +0 -0
- data/app/assets/images/glimmer/images/ui-icons_222222_256x240.png +0 -0
- data/app/assets/images/glimmer/images/ui-icons_444444_256x240.png +0 -0
- data/app/assets/images/glimmer/images/ui-icons_555555_256x240.png +0 -0
- data/app/assets/images/glimmer/images/ui-icons_777620_256x240.png +0 -0
- data/app/assets/images/glimmer/images/ui-icons_777777_256x240.png +0 -0
- data/app/assets/images/glimmer/images/ui-icons_cc0000_256x240.png +0 -0
- data/app/assets/images/glimmer/images/ui-icons_ffffff_256x240.png +0 -0
- data/app/assets/stylesheets/glimmer.css +15 -0
- data/app/assets/stylesheets/glimmer/jquery-ui.css +1312 -0
- data/app/assets/stylesheets/glimmer/jquery-ui.structure.css +886 -0
- data/app/assets/stylesheets/glimmer/jquery-ui.theme.css +443 -0
- data/app/assets/stylesheets/glimmer/jquery.ui.timepicker.css +57 -0
- data/lib/glimmer-dsl-opal.rb +14 -6
- data/lib/glimmer-dsl-opal/ext/date.rb +38 -3
- data/lib/glimmer-dsl-opal/samples/hello/hello_date_time.rb +63 -0
- data/lib/glimmer-dsl-opal/vendor/jquery-ui-timepicker/GPL-LICENSE.txt +278 -0
- data/lib/glimmer-dsl-opal/vendor/jquery-ui-timepicker/MIT-LICENSE.txt +20 -0
- data/lib/glimmer-dsl-opal/vendor/jquery-ui-timepicker/jquery.ui.timepicker.css +57 -0
- data/lib/glimmer-dsl-opal/vendor/jquery-ui-timepicker/jquery.ui.timepicker.js +1496 -0
- data/lib/glimmer-dsl-opal/vendor/jquery-ui/AUTHORS.txt +333 -0
- data/lib/glimmer-dsl-opal/vendor/jquery-ui/LICENSE.txt +43 -0
- data/lib/glimmer-dsl-opal/vendor/jquery-ui/images/ui-icons_444444_256x240.png +0 -0
- data/lib/glimmer-dsl-opal/vendor/jquery-ui/images/ui-icons_555555_256x240.png +0 -0
- data/lib/glimmer-dsl-opal/vendor/jquery-ui/images/ui-icons_777620_256x240.png +0 -0
- data/lib/glimmer-dsl-opal/vendor/jquery-ui/images/ui-icons_777777_256x240.png +0 -0
- data/lib/glimmer-dsl-opal/vendor/jquery-ui/images/ui-icons_cc0000_256x240.png +0 -0
- data/lib/glimmer-dsl-opal/vendor/jquery-ui/images/ui-icons_ffffff_256x240.png +0 -0
- data/lib/glimmer-dsl-opal/vendor/jquery-ui/jquery-ui.min.css +7 -0
- data/lib/glimmer-dsl-opal/vendor/jquery-ui/jquery-ui.min.js +13 -0
- data/lib/glimmer-dsl-opal/vendor/jquery-ui/jquery-ui.structure.min.css +5 -0
- data/lib/glimmer-dsl-opal/vendor/jquery-ui/jquery-ui.theme.min.css +5 -0
- data/lib/glimmer-dsl-opal/vendor/jquery-ui/package.json +74 -0
- data/lib/glimmer/dsl/opal/shell_expression.rb +7 -2
- data/lib/glimmer/dsl/opal/widget_expression.rb +5 -0
- data/lib/glimmer/engine.rb +9 -0
- data/lib/glimmer/swt.rb +3 -3
- data/lib/glimmer/swt/button_proxy.rb +1 -1
- data/lib/glimmer/swt/checkbox_proxy.rb +1 -0
- data/lib/glimmer/swt/date_time_proxy.rb +144 -0
- data/lib/glimmer/swt/make_shift_shell_proxy.rb +4 -4
- data/lib/glimmer/swt/message_box_proxy.rb +6 -6
- data/lib/glimmer/swt/radio_proxy.rb +1 -0
- data/lib/glimmer/swt/tab_folder_proxy.rb +3 -3
- data/lib/glimmer/swt/table_proxy.rb +10 -10
- data/lib/glimmer/swt/text_proxy.rb +2 -2
- data/lib/glimmer/swt/widget_proxy.rb +23 -7
- metadata +35 -2
@@ -13,14 +13,14 @@ module Glimmer
|
|
13
13
|
include TopLevelExpression
|
14
14
|
include ParentExpression
|
15
15
|
|
16
|
-
def interpret(parent, keyword, *args, &block)
|
16
|
+
def interpret(parent, keyword, *args, &block)
|
17
17
|
if Glimmer::UI::CustomShell.requested_and_not_handled?
|
18
18
|
parameters = Glimmer::UI::CustomShell.request_parameter_string.split("&").map {|str| str.split("=")}.to_h
|
19
19
|
`history.pushState(#{parameters.merge('custom_shell_handled' => 'true')}, document.title, #{"?#{Glimmer::UI::CustomShell.encoded_request_parameter_string}&custom_shell_handled=true"})`
|
20
20
|
custom_shell_keyword = parameters.delete('custom_shell')
|
21
21
|
CustomWidgetExpression.new.interpret(nil, custom_shell_keyword, *[parameters])
|
22
22
|
`history.pushState(#{parameters.reject {|k,v| k == 'custom_shell_handled'}}, document.title, #{"?#{Glimmer::UI::CustomShell.encoded_request_parameter_string.sub('&custom_shell_handled=true', '')}"})`
|
23
|
-
# just a placeholder that has an open method # TODO return an actual CustomShell in the future that does the work happening above in the #open method
|
23
|
+
# just a placeholder that has an open method # TODO return an actual CustomShell in the future that does the work happening above in the #open method
|
24
24
|
Glimmer::SWT::MakeShiftShellProxy.new
|
25
25
|
else
|
26
26
|
Glimmer::SWT::ShellProxy.new(*args)
|
@@ -30,6 +30,11 @@ module Glimmer
|
|
30
30
|
def add_content(parent, &content)
|
31
31
|
content.call(parent) if parent.is_a?(Glimmer::SWT::ShellProxy)
|
32
32
|
end
|
33
|
+
|
34
|
+
def add_content(parent, &block)
|
35
|
+
super(parent, &block)
|
36
|
+
parent.post_add_content
|
37
|
+
end
|
33
38
|
end
|
34
39
|
end
|
35
40
|
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module Glimmer
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
isolate_namespace Glimmer
|
4
|
+
|
5
|
+
initializer "glimmer.assets.precompile" do |app|
|
6
|
+
app.config.assets.precompile += %w( glimmer.css jquery-ui.css jquery-ui.structure.css jquery-ui.theme.css jquery.ui.timepicker.css )
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
data/lib/glimmer/swt.rb
CHANGED
@@ -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
|
@@ -0,0 +1,144 @@
|
|
1
|
+
require 'glimmer/swt/widget_proxy'
|
2
|
+
|
3
|
+
module Glimmer
|
4
|
+
module SWT
|
5
|
+
class DateTimeProxy < WidgetProxy
|
6
|
+
class << self
|
7
|
+
def create(keyword, parent, args)
|
8
|
+
case keyword
|
9
|
+
when 'date'
|
10
|
+
args += [:date]
|
11
|
+
when 'date_drop_down'
|
12
|
+
args += [:date, :drop_down]
|
13
|
+
when 'time'
|
14
|
+
args += [:time]
|
15
|
+
when 'calendar'
|
16
|
+
args += [:calendar]
|
17
|
+
end
|
18
|
+
new(parent, args)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(parent, args)
|
23
|
+
super(parent, args)
|
24
|
+
end
|
25
|
+
|
26
|
+
def post_add_content
|
27
|
+
# TODO handle date_drop_down version
|
28
|
+
if time?
|
29
|
+
dom_element.timepicker({
|
30
|
+
showPeriod: true,
|
31
|
+
showLeadingZero: true,
|
32
|
+
showOn: 'both',
|
33
|
+
button: "##{time_button_id}",
|
34
|
+
})
|
35
|
+
else
|
36
|
+
options = {}
|
37
|
+
if drop_down?
|
38
|
+
options = {
|
39
|
+
showOn: 'both',
|
40
|
+
buttonImage: 'assets/glimmer/images/calendar.gif',
|
41
|
+
buttonImageOnly: true,
|
42
|
+
buttonText: 'Select date'
|
43
|
+
}
|
44
|
+
end
|
45
|
+
dom_element.datepicker(options)
|
46
|
+
end
|
47
|
+
date_time_value = self.date_time
|
48
|
+
@added_content = true
|
49
|
+
self.date_time = date_time_value
|
50
|
+
end
|
51
|
+
|
52
|
+
def date?
|
53
|
+
args.to_a.include?(:date)
|
54
|
+
end
|
55
|
+
|
56
|
+
def time?
|
57
|
+
args.to_a.include?(:time)
|
58
|
+
end
|
59
|
+
|
60
|
+
def drop_down?
|
61
|
+
args.to_a.include?(:drop_down)
|
62
|
+
end
|
63
|
+
|
64
|
+
def calendar?
|
65
|
+
args.to_a.include?(:calendar)
|
66
|
+
end
|
67
|
+
|
68
|
+
def date_time
|
69
|
+
if @added_content
|
70
|
+
default_date = DateTime.new if @date_time.nil?
|
71
|
+
default_year = @date_time&.year || default_date.year
|
72
|
+
default_month = @date_time&.month || default_date.month
|
73
|
+
default_day = @date_time&.day || default_date.day
|
74
|
+
default_hour = @date_time&.hour || default_date.hour
|
75
|
+
default_min = @date_time&.min || default_date.min
|
76
|
+
default_sec = @date_time&.sec || default_date.sec
|
77
|
+
if time?
|
78
|
+
@date_time = DateTime.new(default_year, default_month, default_day, dom_element.timepicker('getHour').to_i, dom_element.timepicker('getMinute').to_i, default_sec)
|
79
|
+
else
|
80
|
+
@date_time = DateTime.new(dom_element.datepicker('getDate')&.year.to_i, dom_element.datepicker('getDate')&.month.to_i, dom_element.datepicker('getDate')&.day.to_i, default_hour, default_min, default_sec)
|
81
|
+
end
|
82
|
+
@date_time = @date_time&.to_datetime
|
83
|
+
else
|
84
|
+
@initial_date_time
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def date_time=(value)
|
89
|
+
if @added_content
|
90
|
+
@date_time = value&.to_datetime || DateTime.new
|
91
|
+
if time?
|
92
|
+
dom_element.timepicker('setTime', "#{@date_time.hour}:#{@date_time.min}")
|
93
|
+
else
|
94
|
+
dom_element.datepicker('setDate', @date_time.to_time)
|
95
|
+
end
|
96
|
+
else
|
97
|
+
@initial_date_time = value
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# TODO add date, time, year, month, day, hours, minutes, seconds attribute methods
|
102
|
+
|
103
|
+
def observation_request_to_event_mapping
|
104
|
+
{
|
105
|
+
'on_widget_selected' => [
|
106
|
+
{
|
107
|
+
event: 'change'
|
108
|
+
},
|
109
|
+
],
|
110
|
+
}
|
111
|
+
end
|
112
|
+
|
113
|
+
def time_button_id
|
114
|
+
"#{id}-time-button"
|
115
|
+
end
|
116
|
+
|
117
|
+
def time_button_class
|
118
|
+
"#{name}-time-button"
|
119
|
+
end
|
120
|
+
|
121
|
+
def element
|
122
|
+
calendar? ? 'div' : 'input'
|
123
|
+
end
|
124
|
+
|
125
|
+
def dom
|
126
|
+
@dom ||= html {
|
127
|
+
span {
|
128
|
+
send(element, type: 'text', id: id, class: name)
|
129
|
+
button(id: time_button_id, class: time_button_class, style: "border: none; background: url(assets/glimmer/images/ui-icons_222222_256x240.png) -80px, -96px; width: 16px; height: 16px;") if time?
|
130
|
+
}
|
131
|
+
}.to_s
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
# Aliases: `date`, `date_drop_down`, `time`, and `calendar`
|
137
|
+
DateProxy = DateTimeProxy
|
138
|
+
DateDropDownProxy = DateTimeProxy
|
139
|
+
TimeProxy = DateTimeProxy
|
140
|
+
CalendarProxy = DateTimeProxy
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
@@ -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 @@ module Glimmer
|
|
26
26
|
# No Op
|
27
27
|
end
|
28
28
|
|
29
|
-
def
|
29
|
+
def post_initialize_child(child)
|
30
30
|
# No Op
|
31
31
|
end
|
32
32
|
|
@@ -37,7 +37,7 @@ module Glimmer
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def open
|
40
|
-
document.
|
40
|
+
document.post_initialize_child(self)
|
41
41
|
end
|
42
42
|
|
43
43
|
def hide
|
@@ -53,11 +53,11 @@ module Glimmer
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def selector
|
56
|
-
super + ' .close'
|
56
|
+
super + ' .close'
|
57
57
|
end
|
58
58
|
|
59
59
|
def listener_path
|
60
|
-
path + ' .close'
|
60
|
+
path + ' .close'
|
61
61
|
end
|
62
62
|
|
63
63
|
def observation_request_to_event_mapping
|
@@ -66,7 +66,7 @@ module Glimmer
|
|
66
66
|
event: 'click'
|
67
67
|
},
|
68
68
|
}
|
69
|
-
end
|
69
|
+
end
|
70
70
|
|
71
71
|
def style_dom_modal_css
|
72
72
|
<<~CSS
|
@@ -119,11 +119,11 @@ module Glimmer
|
|
119
119
|
modal_text = text
|
120
120
|
modal_message = message
|
121
121
|
modal_class = ['modal', name].join(' ')
|
122
|
-
@dom ||= html {
|
122
|
+
@dom ||= html {
|
123
123
|
div(id: modal_id, style: modal_style, class: modal_class) {
|
124
124
|
style(class: 'modal-style') {
|
125
125
|
style_dom_modal_css #.split("\n").map(&:strip).join(' ')
|
126
|
-
}
|
126
|
+
}
|
127
127
|
div(class: 'modal-content') {
|
128
128
|
header(class: 'text') {
|
129
129
|
modal_text
|
@@ -2,7 +2,7 @@ require 'glimmer/swt/widget_proxy'
|
|
2
2
|
|
3
3
|
module Glimmer
|
4
4
|
module SWT
|
5
|
-
class TabFolderProxy < WidgetProxy
|
5
|
+
class TabFolderProxy < WidgetProxy
|
6
6
|
attr_reader :tabs
|
7
7
|
|
8
8
|
def initialize(parent, args)
|
@@ -10,9 +10,9 @@ module Glimmer
|
|
10
10
|
@tabs = []
|
11
11
|
end
|
12
12
|
|
13
|
-
def
|
13
|
+
def post_initialize_child(child)
|
14
14
|
unless @children.include?(child)
|
15
|
-
@children << child
|
15
|
+
@children << child
|
16
16
|
tabs_dom_element.append(child.tab_dom)
|
17
17
|
child.render
|
18
18
|
end
|
@@ -16,11 +16,11 @@ module Glimmer
|
|
16
16
|
end
|
17
17
|
|
18
18
|
# Only table_columns may be added as children
|
19
|
-
def
|
19
|
+
def post_initialize_child(child)
|
20
20
|
if child.is_a?(TableColumnProxy)
|
21
21
|
@columns << child
|
22
22
|
else
|
23
|
-
@children << child
|
23
|
+
@children << child
|
24
24
|
end
|
25
25
|
child.redraw
|
26
26
|
end
|
@@ -36,14 +36,14 @@ module Glimmer
|
|
36
36
|
changed.each(&:redraw)
|
37
37
|
end
|
38
38
|
|
39
|
-
def items=(new_items)
|
39
|
+
def items=(new_items)
|
40
40
|
@children = new_items
|
41
41
|
redraw
|
42
42
|
end
|
43
43
|
|
44
44
|
def search(&condition)
|
45
45
|
items.select {|item| condition.nil? || condition.call(item)}
|
46
|
-
end
|
46
|
+
end
|
47
47
|
|
48
48
|
def index_of(item)
|
49
49
|
items.index(item)
|
@@ -84,9 +84,9 @@ module Glimmer
|
|
84
84
|
event.singleton_class.send(:define_method, :column_index) do
|
85
85
|
(table_data || event.target).attr('data-column-index')
|
86
86
|
end
|
87
|
-
event_listener.call(event)
|
87
|
+
event_listener.call(event)
|
88
88
|
}
|
89
|
-
}
|
89
|
+
}
|
90
90
|
|
91
91
|
{
|
92
92
|
'on_mouse_down' => {
|
@@ -102,7 +102,7 @@ module Glimmer
|
|
102
102
|
|
103
103
|
def redraw
|
104
104
|
super()
|
105
|
-
@columns.to_a.each(&:redraw)
|
105
|
+
@columns.to_a.each(&:redraw)
|
106
106
|
end
|
107
107
|
|
108
108
|
def element
|
@@ -125,7 +125,7 @@ module Glimmer
|
|
125
125
|
Document.find(items_path)
|
126
126
|
end
|
127
127
|
|
128
|
-
def columns_dom
|
128
|
+
def columns_dom
|
129
129
|
tr {
|
130
130
|
}
|
131
131
|
end
|
@@ -134,9 +134,9 @@ module Glimmer
|
|
134
134
|
thead {
|
135
135
|
columns_dom
|
136
136
|
}
|
137
|
-
end
|
137
|
+
end
|
138
138
|
|
139
|
-
def items_dom
|
139
|
+
def items_dom
|
140
140
|
tbody {
|
141
141
|
}
|
142
142
|
end
|
@@ -35,7 +35,7 @@ module Glimmer
|
|
35
35
|
# Factory Method that translates a Glimmer DSL keyword into a WidgetProxy object
|
36
36
|
def for(keyword, parent, args)
|
37
37
|
the_widget_class = widget_class(keyword)
|
38
|
-
the_widget_class.respond_to?(:create) ? the_widget_class.create(parent, args) : the_widget_class.new(parent, args)
|
38
|
+
the_widget_class.respond_to?(:create) ? the_widget_class.create(keyword, parent, args) : the_widget_class.new(parent, args)
|
39
39
|
end
|
40
40
|
|
41
41
|
def widget_class(keyword)
|
@@ -103,7 +103,18 @@ module Glimmer
|
|
103
103
|
@children = Set.new # TODO consider moving to composite
|
104
104
|
@enabled = true
|
105
105
|
DEFAULT_INITIALIZERS[self.class.underscored_widget_name(self)]&.call(self)
|
106
|
-
@parent.
|
106
|
+
@parent.post_initialize_child(self) # TODO rename to post_initialize_child to be closer to glimmer-dsl-swt terminology
|
107
|
+
end
|
108
|
+
|
109
|
+
# Executes for the parent of a child that just got added
|
110
|
+
def post_initialize_child(child)
|
111
|
+
@children << child
|
112
|
+
child.render
|
113
|
+
end
|
114
|
+
|
115
|
+
# Executes at the closing of a parent widget curly braces after all children/properties have been added/set
|
116
|
+
def post_add_content
|
117
|
+
# No Op by default
|
107
118
|
end
|
108
119
|
|
109
120
|
def css_classes
|
@@ -123,11 +134,6 @@ module Glimmer
|
|
123
134
|
'div'
|
124
135
|
end
|
125
136
|
|
126
|
-
def add_child(child)
|
127
|
-
@children << child
|
128
|
-
child.render
|
129
|
-
end
|
130
|
-
|
131
137
|
def enabled=(value)
|
132
138
|
@enabled = value
|
133
139
|
dom_element.prop('disabled', !@enabled)
|
@@ -248,6 +254,8 @@ module Glimmer
|
|
248
254
|
Document.find(path)
|
249
255
|
end
|
250
256
|
|
257
|
+
# TODO consider adding a default #dom method implementation for the common case, automatically relying on #element and other methods to build the dom html
|
258
|
+
|
251
259
|
def style_element
|
252
260
|
style_element_id = "#{id}-style"
|
253
261
|
style_element_selector = "style##{style_element_id}"
|
@@ -458,6 +466,13 @@ module Glimmer
|
|
458
466
|
# }
|
459
467
|
# end,
|
460
468
|
# },
|
469
|
+
DateTimeProxy => { #radio?
|
470
|
+
:date_time => lambda do |observer|
|
471
|
+
on_widget_selected { |selection_event|
|
472
|
+
observer.call(date_time)
|
473
|
+
}
|
474
|
+
end
|
475
|
+
},
|
461
476
|
RadioProxy => { #radio?
|
462
477
|
:selection => lambda do |observer|
|
463
478
|
on_widget_selected { |selection_event|
|
@@ -491,6 +506,7 @@ require 'glimmer/swt/button_proxy'
|
|
491
506
|
require 'glimmer/swt/combo_proxy'
|
492
507
|
require 'glimmer/swt/checkbox_proxy'
|
493
508
|
require 'glimmer/swt/composite_proxy'
|
509
|
+
require 'glimmer/swt/date_time_proxy'
|
494
510
|
require 'glimmer/swt/group_proxy'
|
495
511
|
require 'glimmer/swt/label_proxy'
|
496
512
|
require 'glimmer/swt/list_proxy'
|