glimmer-dsl-tk 0.0.1 → 0.0.6
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 +30 -0
- data/README.md +483 -14
- data/VERSION +1 -1
- data/bin/girb +10 -0
- data/bin/girb_runner.rb +26 -0
- data/lib/glimmer-dsl-tk.rb +3 -3
- data/lib/glimmer/data_binding/tk/list_selection_binding.rb +75 -0
- data/lib/glimmer/data_binding/tk/widget_binding.rb +28 -0
- data/lib/glimmer/dsl/tk/bind_expression.rb +36 -0
- data/lib/glimmer/dsl/tk/block_attribute_expression.rb +41 -0
- data/lib/glimmer/dsl/tk/data_binding_expression.rb +33 -0
- data/lib/glimmer/dsl/tk/dsl.rb +3 -0
- data/lib/glimmer/dsl/tk/list_selection_data_binding_expression.rb +60 -0
- data/lib/glimmer/dsl/tk/widget_expression.rb +8 -2
- data/lib/glimmer/tk/button_proxy.rb +35 -0
- data/lib/glimmer/tk/entry_proxy.rb +38 -0
- data/lib/glimmer/tk/frame_proxy.rb +42 -0
- data/lib/glimmer/tk/label_proxy.rb +40 -0
- data/lib/glimmer/tk/list_proxy.rb +60 -0
- data/lib/glimmer/tk/notebook_proxy.rb +45 -0
- data/lib/glimmer/tk/root_proxy.rb +2 -2
- data/lib/glimmer/tk/widget_proxy.rb +163 -37
- data/samples/hello/hello_combo.rb +61 -0
- data/samples/hello/hello_computed.rb +75 -0
- data/samples/hello/hello_computed/contact.rb +21 -0
- data/samples/hello/hello_list_multi_selection.rb +69 -0
- data/samples/hello/hello_list_single_selection.rb +60 -0
- data/samples/hello/hello_tab.rb +48 -0
- data/samples/hello/hello_world.rb +2 -0
- metadata +71 -130
@@ -0,0 +1,42 @@
|
|
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/tk/widget_proxy'
|
23
|
+
|
24
|
+
module Glimmer
|
25
|
+
module Tk
|
26
|
+
# Proxy for Tk::Tile::Frame
|
27
|
+
#
|
28
|
+
# Follows the Proxy Design Pattern
|
29
|
+
class FrameProxy < WidgetProxy
|
30
|
+
attr_reader :tab_options
|
31
|
+
|
32
|
+
def initialize(underscored_widget_name, parent_proxy, args)
|
33
|
+
if parent_proxy.is_a?(NotebookProxy)
|
34
|
+
@tab_options, args[0] = args[0].to_h.partition {|key, value| NotebookProxy::TAB_OPTIONS.include?(key.to_s)}
|
35
|
+
@tab_options = Hash[@tab_options]
|
36
|
+
args.delete_at(0) if args[0].to_a.empty?
|
37
|
+
end
|
38
|
+
super
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,40 @@
|
|
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/tk/widget_proxy'
|
23
|
+
|
24
|
+
module Glimmer
|
25
|
+
module Tk
|
26
|
+
# Proxy for Tk::Tile::TLabel
|
27
|
+
#
|
28
|
+
# Follows the Proxy Design Pattern
|
29
|
+
class LabelProxy < WidgetProxy
|
30
|
+
# TODO specify attribute setters
|
31
|
+
# def tk_widget_has_attribute_setter?(attribute)
|
32
|
+
# if ['anchor', 'justify'].include?(attribute.to_s)
|
33
|
+
# true
|
34
|
+
# else
|
35
|
+
# super
|
36
|
+
# end
|
37
|
+
# end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,60 @@
|
|
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/tk/widget_proxy'
|
23
|
+
|
24
|
+
module Glimmer
|
25
|
+
module Tk
|
26
|
+
# Custom list widget implementation
|
27
|
+
class ListProxy < WidgetProxy
|
28
|
+
def initialize(underscored_widget_name, parent_proxy, args)
|
29
|
+
super('treeview', parent_proxy, args)
|
30
|
+
@tk.show = 'tree'
|
31
|
+
end
|
32
|
+
|
33
|
+
def widget_custom_attribute_mapping
|
34
|
+
@widget_custom_attribute_mapping ||= {
|
35
|
+
::Tk::Tile::Treeview => {
|
36
|
+
'items' => {
|
37
|
+
getter: {name: 'items', invoker: lambda { |widget, args| tk.children('').map(&:text) }},
|
38
|
+
setter: {name: 'items=', invoker: lambda { |widget, args|
|
39
|
+
@tk.delete @tk.children('')
|
40
|
+
args.first.each do |child|
|
41
|
+
@tk.insert('', 'end', :text => child)
|
42
|
+
end
|
43
|
+
}},
|
44
|
+
},
|
45
|
+
'selection' => {
|
46
|
+
getter: {name: 'selection', invoker: lambda { |widget, args| @tk.selection.map(&:text) }},
|
47
|
+
setter: {name: 'selection=', invoker: lambda { |widget, args|
|
48
|
+
selection_args = args.first.is_a?(Array) ? args.first : [args.first]
|
49
|
+
selection_items = selection_args.map do |arg|
|
50
|
+
@tk.children('').detect {|item| item.text == arg}
|
51
|
+
end
|
52
|
+
@tk.selection_set(*selection_items)
|
53
|
+
}},
|
54
|
+
},
|
55
|
+
},
|
56
|
+
}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,45 @@
|
|
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/tk/widget_proxy'
|
23
|
+
|
24
|
+
module Glimmer
|
25
|
+
module Tk
|
26
|
+
# Proxy for Tk::Tile::Notebook
|
27
|
+
#
|
28
|
+
# Follows the Proxy Design Pattern
|
29
|
+
class NotebookProxy < WidgetProxy
|
30
|
+
TAB_OPTIONS = ['state', 'sticky', 'padding', 'text', 'image', 'compound', 'underline']
|
31
|
+
|
32
|
+
attr_reader :tab_proxies
|
33
|
+
|
34
|
+
def initialize(*args)
|
35
|
+
@tab_proxies = []
|
36
|
+
super
|
37
|
+
end
|
38
|
+
|
39
|
+
def post_initialize_child(child)
|
40
|
+
@tab_proxies << child
|
41
|
+
@tk.add child.tk, child.tab_options
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -29,7 +29,7 @@ module Glimmer
|
|
29
29
|
class RootProxy < WidgetProxy
|
30
30
|
|
31
31
|
def initialize(*args)
|
32
|
-
@
|
32
|
+
@tk = ::TkRoot.new
|
33
33
|
end
|
34
34
|
|
35
35
|
def open
|
@@ -37,7 +37,7 @@ module Glimmer
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def content(&block)
|
40
|
-
Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::
|
40
|
+
Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Tk::RootExpression.new, &block)
|
41
41
|
end
|
42
42
|
|
43
43
|
# Starts Tk mainloop
|
@@ -25,23 +25,67 @@ module Glimmer
|
|
25
25
|
#
|
26
26
|
# Follows the Proxy Design Pattern
|
27
27
|
class WidgetProxy
|
28
|
-
attr_reader :parent_proxy, :
|
28
|
+
attr_reader :parent_proxy, :tk, :args
|
29
29
|
|
30
30
|
DEFAULT_INITIALIZERS = {
|
31
|
-
'
|
32
|
-
|
31
|
+
'combobox' => lambda do |tk|
|
32
|
+
tk.textvariable = ::TkVariable.new
|
33
|
+
end,
|
34
|
+
'label' => lambda do |tk|
|
35
|
+
tk.textvariable = ::TkVariable.new
|
36
|
+
end,
|
37
|
+
'entry' => lambda do |tk|
|
38
|
+
tk.textvariable = ::TkVariable.new
|
33
39
|
end,
|
34
40
|
}
|
35
41
|
|
42
|
+
class << self
|
43
|
+
def create(keyword, parent, args)
|
44
|
+
widget_proxy_class(keyword).new(keyword, parent, args)
|
45
|
+
end
|
46
|
+
|
47
|
+
def widget_proxy_class(keyword)
|
48
|
+
begin
|
49
|
+
class_name = "#{keyword.camelcase(:upper)}Proxy".to_sym
|
50
|
+
Glimmer::Tk.const_get(class_name)
|
51
|
+
rescue
|
52
|
+
Glimmer::Tk::WidgetProxy
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# This supports widgets in and out of basic Tk
|
57
|
+
def tk_widget_class_for(underscored_widget_name)
|
58
|
+
tk_widget_class_basename = underscored_widget_name.camelcase(:upper)
|
59
|
+
potential_tk_widget_class_names = [
|
60
|
+
"::Tk::Tile::#{tk_widget_class_basename}",
|
61
|
+
"::Tk::#{tk_widget_class_basename}",
|
62
|
+
"::Tk#{tk_widget_class_basename}",
|
63
|
+
"::Glimmer::Tk::#{tk_widget_class_basename}Proxy",
|
64
|
+
]
|
65
|
+
tk_widget_class = nil
|
66
|
+
potential_tk_widget_class_names.each do |tk_widget_name|
|
67
|
+
begin
|
68
|
+
tk_widget_class = eval(tk_widget_name)
|
69
|
+
break
|
70
|
+
rescue RuntimeError, SyntaxError, NameError => e
|
71
|
+
Glimmer::Config.logger.debug e.full_message
|
72
|
+
end
|
73
|
+
end
|
74
|
+
tk_widget_class
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
36
78
|
# Initializes a new Tk Widget
|
37
79
|
#
|
38
80
|
# Styles is a comma separate list of symbols representing Tk styles in lower case
|
39
|
-
def initialize(
|
40
|
-
|
41
|
-
@
|
42
|
-
tk_widget_class = self.class.tk_widget_class_for(underscored_widget_name)
|
43
|
-
@
|
44
|
-
|
81
|
+
def initialize(underscored_widget_name, parent_proxy, args)
|
82
|
+
@parent_proxy = parent_proxy
|
83
|
+
@args = args
|
84
|
+
tk_widget_class = self.class.tk_widget_class_for(underscored_widget_name)
|
85
|
+
@tk = tk_widget_class.new(@parent_proxy.tk, *args)
|
86
|
+
# a common widget initializer
|
87
|
+
@tk.grid
|
88
|
+
DEFAULT_INITIALIZERS[underscored_widget_name]&.call(@tk)
|
45
89
|
@parent_proxy.post_initialize_child(self)
|
46
90
|
end
|
47
91
|
|
@@ -59,24 +103,23 @@ module Glimmer
|
|
59
103
|
!!tk_widget_class_for(underscored_widget_name)
|
60
104
|
end
|
61
105
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
nil
|
106
|
+
def tk_widget_has_attribute_setter?(attribute)
|
107
|
+
result = nil
|
108
|
+
begin
|
109
|
+
# TK Widget currently doesn't support respond_to? properly, so I have to resort to this trick for now
|
110
|
+
@tk.send(attribute_setter(attribute), @tk.send(attribute))
|
111
|
+
result = true
|
112
|
+
rescue => e
|
113
|
+
result = false
|
114
|
+
end
|
115
|
+
result
|
73
116
|
end
|
74
117
|
|
75
|
-
def
|
118
|
+
def tk_widget_has_attribute_getter_setter?(attribute)
|
76
119
|
result = nil
|
77
120
|
begin
|
78
121
|
# TK Widget currently doesn't support respond_to? properly, so I have to resort to this trick for now
|
79
|
-
@
|
122
|
+
@tk.send(attribute, @tk.send(attribute))
|
80
123
|
result = true
|
81
124
|
rescue => e
|
82
125
|
result = false
|
@@ -84,40 +127,123 @@ module Glimmer
|
|
84
127
|
result
|
85
128
|
end
|
86
129
|
|
87
|
-
def has_attribute?(
|
88
|
-
|
130
|
+
def has_attribute?(attribute, *args)
|
131
|
+
(widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][attribute.to_s]) ||
|
132
|
+
tk_widget_has_attribute_setter?(attribute) ||
|
133
|
+
tk_widget_has_attribute_getter_setter?(attribute) ||
|
134
|
+
respond_to?(attribute_setter(attribute), args)
|
89
135
|
end
|
90
136
|
|
91
|
-
def set_attribute(
|
92
|
-
|
93
|
-
|
137
|
+
def set_attribute(attribute, *args)
|
138
|
+
widget_custom_attribute = widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][attribute.to_s]
|
139
|
+
if widget_custom_attribute
|
140
|
+
widget_custom_attribute[:setter][:invoker].call(@tk, args)
|
141
|
+
elsif tk_widget_has_attribute_setter?(attribute)
|
142
|
+
@tk.send(attribute_setter(attribute), *args) unless @tk.send(attribute) == args.first
|
143
|
+
elsif tk_widget_has_attribute_getter_setter?(attribute)
|
144
|
+
@tk.send(attribute, *args) unless @tk.send(attribute) == args.first
|
94
145
|
else
|
95
|
-
send(attribute_setter(
|
146
|
+
send(attribute_setter(attribute), args)
|
96
147
|
end
|
97
148
|
end
|
98
149
|
|
99
|
-
def get_attribute(
|
100
|
-
|
101
|
-
|
150
|
+
def get_attribute(attribute)
|
151
|
+
widget_custom_attribute = widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][attribute.to_s]
|
152
|
+
if widget_custom_attribute
|
153
|
+
widget_custom_attribute[:getter][:invoker].call(@tk, args)
|
154
|
+
elsif tk_widget_has_attribute_getter_setter?(attribute)
|
155
|
+
@tk.send(attribute)
|
156
|
+
else
|
157
|
+
send(attribute)
|
158
|
+
end
|
159
|
+
end
|
102
160
|
|
103
|
-
def attribute_setter(
|
104
|
-
"#{
|
161
|
+
def attribute_setter(attribute)
|
162
|
+
"#{attribute}="
|
163
|
+
end
|
164
|
+
|
165
|
+
def widget_custom_attribute_mapping
|
166
|
+
@widget_custom_attribute_mapping ||= {
|
167
|
+
::Tk::Tile::TCombobox => {
|
168
|
+
'text' => {
|
169
|
+
getter: {name: 'text', invoker: lambda { |widget, args| @tk.textvariable&.value }},
|
170
|
+
setter: {name: 'text=', invoker: lambda { |widget, args| @tk.textvariable&.value = args.first }},
|
171
|
+
},
|
172
|
+
},
|
173
|
+
::Tk::Tile::TLabel => {
|
174
|
+
'text' => {
|
175
|
+
getter: {name: 'text', invoker: lambda { |widget, args| @tk.textvariable&.value }},
|
176
|
+
setter: {name: 'text=', invoker: lambda { |widget, args| @tk.textvariable&.value = args.first }},
|
177
|
+
},
|
178
|
+
},
|
179
|
+
::Tk::Tile::TEntry => {
|
180
|
+
'text' => {
|
181
|
+
getter: {name: 'text', invoker: lambda { |widget, args| @tk.textvariable&.value }},
|
182
|
+
setter: {name: 'text=', invoker: lambda { |widget, args| @tk.textvariable&.value = args.first unless @text_variable_edit }},
|
183
|
+
},
|
184
|
+
},
|
185
|
+
}
|
186
|
+
end
|
187
|
+
|
188
|
+
def widget_attribute_listener_installers
|
189
|
+
@tk_widget_attribute_listener_installers ||= {
|
190
|
+
::Tk::Tile::TCombobox => {
|
191
|
+
'text' => lambda do |observer|
|
192
|
+
if observer.is_a?(Glimmer::DataBinding::ModelBinding)
|
193
|
+
model = observer.model
|
194
|
+
options_model_property = observer.property_name + '_options'
|
195
|
+
@tk.values = model.send(options_model_property) if model.respond_to?(options_model_property)
|
196
|
+
end
|
197
|
+
@tk.bind('<ComboboxSelected>') {
|
198
|
+
observer.call(@tk.textvariable.value)
|
199
|
+
}
|
200
|
+
end,
|
201
|
+
},
|
202
|
+
::Tk::Tile::TEntry => {
|
203
|
+
'text' => lambda do |observer|
|
204
|
+
tk.validate = 'key'
|
205
|
+
tk.validatecommand { |new_tk_variable|
|
206
|
+
@text_variable_edit = new_tk_variable.value != @tk.textvariable.value
|
207
|
+
if @text_variable_edit
|
208
|
+
observer.call(new_tk_variable.value)
|
209
|
+
@text_variable_edit = nil
|
210
|
+
true
|
211
|
+
else
|
212
|
+
false
|
213
|
+
end
|
214
|
+
}
|
215
|
+
end,
|
216
|
+
},
|
217
|
+
}
|
105
218
|
end
|
219
|
+
|
220
|
+
def add_observer(observer, attribute)
|
221
|
+
attribute_listener_installers = @tk.class.ancestors.map {|ancestor| widget_attribute_listener_installers[ancestor]}.compact
|
222
|
+
widget_listener_installers = attribute_listener_installers.map{|installer| installer[attribute.to_s]}.compact if !attribute_listener_installers.empty?
|
223
|
+
widget_listener_installers.to_a.first&.call(observer)
|
224
|
+
end
|
106
225
|
|
107
226
|
def content(&block)
|
108
227
|
Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Tk::WidgetExpression.new, &block)
|
109
228
|
end
|
110
229
|
|
111
230
|
def method_missing(method, *args, &block)
|
112
|
-
|
231
|
+
method = method.to_s
|
232
|
+
if args.empty? && block.nil? && widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][method]
|
233
|
+
get_attribute(method)
|
234
|
+
elsif widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][method.sub(/=$/, '')] && method.end_with?('=') && block.nil?
|
235
|
+
set_attribute(method.sub(/=$/, ''), *args)
|
236
|
+
else
|
237
|
+
tk.send(method, *args, &block)
|
238
|
+
end
|
113
239
|
rescue => e
|
114
|
-
Glimmer::Config.logger.debug {"Neither WidgetProxy nor #{
|
115
|
-
super
|
240
|
+
Glimmer::Config.logger.debug {"Neither WidgetProxy nor #{tk.class.name} can handle the method ##{method}"}
|
241
|
+
super(method.to_sym, *args, &block)
|
116
242
|
end
|
117
243
|
|
118
244
|
def respond_to?(method, *args, &block)
|
119
245
|
super ||
|
120
|
-
|
246
|
+
tk.respond_to?(method, *args, &block)
|
121
247
|
end
|
122
248
|
end
|
123
249
|
end
|