class Glimmer::Tk::WidgetProxy
Proxy for Tk
Widget objects
Follows the Proxy Design Pattern
Constants
- DEFAULT_INITIALIZERS
Attributes
args[R]
parent_proxy[R]
tk[R]
Public Class Methods
create(keyword, parent, args)
click to toggle source
# File lib/glimmer/tk/widget_proxy.rb, line 43 def create(keyword, parent, args) widget_proxy_class(keyword).new(keyword, parent, args) end
new(underscored_widget_name, parent_proxy, args)
click to toggle source
Initializes a new Tk
Widget
Styles is a comma separate list of symbols representing Tk
styles in lower case
# File lib/glimmer/tk/widget_proxy.rb, line 81 def initialize(underscored_widget_name, parent_proxy, args) @parent_proxy = parent_proxy @args = args tk_widget_class = self.class.tk_widget_class_for(underscored_widget_name) @tk = tk_widget_class.new(@parent_proxy.tk, *args) # a common widget initializer @tk.grid DEFAULT_INITIALIZERS[underscored_widget_name]&.call(@tk) @parent_proxy.post_initialize_child(self) end
tk_widget_class_for(underscored_widget_name)
click to toggle source
This supports widgets in and out of basic Tk
# File lib/glimmer/tk/widget_proxy.rb, line 57 def tk_widget_class_for(underscored_widget_name) tk_widget_class_basename = underscored_widget_name.camelcase(:upper) potential_tk_widget_class_names = [ "::Tk::Tile::#{tk_widget_class_basename}", "::Tk::#{tk_widget_class_basename}", "::Tk#{tk_widget_class_basename}", "::Glimmer::Tk::#{tk_widget_class_basename}Proxy", ] tk_widget_class = nil potential_tk_widget_class_names.each do |tk_widget_name| begin tk_widget_class = eval(tk_widget_name) break rescue RuntimeError, SyntaxError, NameError => e Glimmer::Config.logger.debug e.full_message end end tk_widget_class end
widget_exists?(underscored_widget_name)
click to toggle source
# File lib/glimmer/tk/widget_proxy.rb, line 102 def self.widget_exists?(underscored_widget_name) !!tk_widget_class_for(underscored_widget_name) end
widget_proxy_class(keyword)
click to toggle source
# File lib/glimmer/tk/widget_proxy.rb, line 47 def widget_proxy_class(keyword) begin class_name = "#{keyword.camelcase(:upper)}Proxy".to_sym Glimmer::Tk.const_get(class_name) rescue Glimmer::Tk::WidgetProxy end end
Public Instance Methods
add_observer(observer, attribute)
click to toggle source
# File lib/glimmer/tk/widget_proxy.rb, line 220 def add_observer(observer, attribute) attribute_listener_installers = @tk.class.ancestors.map {|ancestor| widget_attribute_listener_installers[ancestor]}.compact widget_listener_installers = attribute_listener_installers.map{|installer| installer[attribute.to_s]}.compact if !attribute_listener_installers.empty? widget_listener_installers.to_a.first&.call(observer) end
attribute_setter(attribute)
click to toggle source
# File lib/glimmer/tk/widget_proxy.rb, line 161 def attribute_setter(attribute) "#{attribute}=" end
content(&block)
click to toggle source
# File lib/glimmer/tk/widget_proxy.rb, line 226 def content(&block) Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Tk::WidgetExpression.new, &block) end
get_attribute(attribute)
click to toggle source
# File lib/glimmer/tk/widget_proxy.rb, line 150 def get_attribute(attribute) widget_custom_attribute = widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][attribute.to_s] if widget_custom_attribute widget_custom_attribute[:getter][:invoker].call(@tk, args) elsif tk_widget_has_attribute_getter_setter?(attribute) @tk.send(attribute) else send(attribute) end end
has_attribute?(attribute, *args)
click to toggle source
# File lib/glimmer/tk/widget_proxy.rb, line 130 def has_attribute?(attribute, *args) (widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][attribute.to_s]) || tk_widget_has_attribute_setter?(attribute) || tk_widget_has_attribute_getter_setter?(attribute) || respond_to?(attribute_setter(attribute), args) end
method_missing(method, *args, &block)
click to toggle source
Calls superclass method
# File lib/glimmer/tk/widget_proxy.rb, line 230 def method_missing(method, *args, &block) method = method.to_s if args.empty? && block.nil? && widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][method] get_attribute(method) elsif widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][method.sub(/=$/, '')] && method.end_with?('=') && block.nil? set_attribute(method.sub(/=$/, ''), *args) else tk.send(method, *args, &block) end rescue => e Glimmer::Config.logger.debug {"Neither WidgetProxy nor #{tk.class.name} can handle the method ##{method}"} super(method.to_sym, *args, &block) end
post_add_content()
click to toggle source
Subclasses may override to perform post add_content work
# File lib/glimmer/tk/widget_proxy.rb, line 98 def post_add_content # No Op by default end
post_initialize_child(child)
click to toggle source
Subclasses may override to perform post initialization work on an added child
# File lib/glimmer/tk/widget_proxy.rb, line 93 def post_initialize_child(child) # No Op by default end
respond_to?(method, *args, &block)
click to toggle source
Calls superclass method
# File lib/glimmer/tk/widget_proxy.rb, line 244 def respond_to?(method, *args, &block) super || tk.respond_to?(method, *args, &block) end
set_attribute(attribute, *args)
click to toggle source
# File lib/glimmer/tk/widget_proxy.rb, line 137 def set_attribute(attribute, *args) widget_custom_attribute = widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][attribute.to_s] if widget_custom_attribute widget_custom_attribute[:setter][:invoker].call(@tk, args) elsif tk_widget_has_attribute_setter?(attribute) @tk.send(attribute_setter(attribute), *args) unless @tk.send(attribute) == args.first elsif tk_widget_has_attribute_getter_setter?(attribute) @tk.send(attribute, *args) unless @tk.send(attribute) == args.first else send(attribute_setter(attribute), args) end end
tk_widget_has_attribute_getter_setter?(attribute)
click to toggle source
# File lib/glimmer/tk/widget_proxy.rb, line 118 def tk_widget_has_attribute_getter_setter?(attribute) result = nil begin # TK Widget currently doesn't support respond_to? properly, so I have to resort to this trick for now @tk.send(attribute, @tk.send(attribute)) result = true rescue => e result = false end result end
tk_widget_has_attribute_setter?(attribute)
click to toggle source
# File lib/glimmer/tk/widget_proxy.rb, line 106 def tk_widget_has_attribute_setter?(attribute) result = nil begin # TK Widget currently doesn't support respond_to? properly, so I have to resort to this trick for now @tk.send(attribute_setter(attribute), @tk.send(attribute)) result = true rescue => e result = false end result end
widget_attribute_listener_installers()
click to toggle source
# File lib/glimmer/tk/widget_proxy.rb, line 188 def widget_attribute_listener_installers @tk_widget_attribute_listener_installers ||= { ::Tk::Tile::TCombobox => { 'text' => lambda do |observer| if observer.is_a?(Glimmer::DataBinding::ModelBinding) model = observer.model options_model_property = observer.property_name + '_options' @tk.values = model.send(options_model_property) if model.respond_to?(options_model_property) end @tk.bind('<ComboboxSelected>') { observer.call(@tk.textvariable.value) } end, }, ::Tk::Tile::TEntry => { 'text' => lambda do |observer| tk.validate = 'key' tk.validatecommand { |new_tk_variable| @text_variable_edit = new_tk_variable.value != @tk.textvariable.value if @text_variable_edit observer.call(new_tk_variable.value) @text_variable_edit = nil true else false end } end, }, } end
widget_custom_attribute_mapping()
click to toggle source
# File lib/glimmer/tk/widget_proxy.rb, line 165 def widget_custom_attribute_mapping @widget_custom_attribute_mapping ||= { ::Tk::Tile::TCombobox => { 'text' => { getter: {name: 'text', invoker: lambda { |widget, args| @tk.textvariable&.value }}, setter: {name: 'text=', invoker: lambda { |widget, args| @tk.textvariable&.value = args.first }}, }, }, ::Tk::Tile::TLabel => { 'text' => { getter: {name: 'text', invoker: lambda { |widget, args| @tk.textvariable&.value }}, setter: {name: 'text=', invoker: lambda { |widget, args| @tk.textvariable&.value = args.first }}, }, }, ::Tk::Tile::TEntry => { 'text' => { getter: {name: 'text', invoker: lambda { |widget, args| @tk.textvariable&.value }}, setter: {name: 'text=', invoker: lambda { |widget, args| @tk.textvariable&.value = args.first unless @text_variable_edit }}, }, }, } end