class Glimmer::LibUI::ControlProxy

Proxy for LibUI control objects

Follows the Proxy Design Pattern

Constants

BOOLEAN_PROPERTIES
KEYWORD_ALIASES
STRING_PROPERTIES
TransformProxy

Attributes

args[R]

libui returns the contained LibUI object

block[R]

libui returns the contained LibUI object

content_added[R]

libui returns the contained LibUI object

content_added?[R]

libui returns the contained LibUI object

keyword[R]

libui returns the contained LibUI object

libui[R]

libui returns the contained LibUI object

parent_proxy[R]

libui returns the contained LibUI object

Public Class Methods

constant_symbol(keyword) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 67
def constant_symbol(keyword)
  "#{keyword.camelcase(:upper)}Proxy".to_sym
end
control_proxies() click to toggle source

autosave all controls in this array to avoid garbage collection

# File lib/glimmer/libui/control_proxy.rb, line 46
def control_proxies
  @@control_proxies = [] unless defined?(@@control_proxies)
  @@control_proxies
end
create(keyword, parent, args, &block) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 37
def create(keyword, parent, args, &block)
  widget_proxy_class(keyword).new(keyword, parent, args, &block).tap {|c| control_proxies << c}
end
descendant_keyword_constant_map() click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 75
def descendant_keyword_constant_map
  @descendant_keyword_constant_map ||= add_aliases_to_keyword_constant_map(map_descendant_keyword_constants_for(self))
end
exists?(keyword) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 31
def exists?(keyword)
  ::LibUI.respond_to?("new_#{keyword}") or
    ::LibUI.respond_to?(keyword) or
    descendant_keyword_constant_map.keys.include?(keyword)
end
image_proxies() click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 59
def image_proxies
  control_proxies.select {|c| c.keyword == 'image' }
end
keyword(constant_symbol) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 71
def keyword(constant_symbol)
  constant_symbol.to_s.underscore.sub(/_proxy$/, '')
end
main_window_proxy() click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 51
def main_window_proxy
  control_proxies.find {|c| c.is_a?(WindowProxy)}
end
map_descendant_keyword_constants_for(klass, accumulator: {}) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 84
def map_descendant_keyword_constants_for(klass, accumulator: {})
  klass.constants.map do |constant_symbol|
    [constant_symbol, klass.const_get(constant_symbol)]
  end.select do |constant_symbol, constant|
    constant.is_a?(Module) && !accumulator.values.include?(constant)
  end.each do |constant_symbol, constant|
    accumulator[keyword(constant_symbol)] = constant
    map_descendant_keyword_constants_for(constant, accumulator: accumulator)
  end
  accumulator
end
menu_proxies() click to toggle source
new(keyword, parent, args, &block) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 132
def initialize(keyword, parent, args, &block)
  @keyword = keyword
  @parent_proxy = parent
  @args = args
  @block = block
  @enabled = true
  build_control
  post_add_content if @block.nil?
end
new_control(keyword, args) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 63
def new_control(keyword, args)
  ::LibUI.send("new_#{keyword}", *args)
end
reset_descendant_keyword_constant_map() click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 79
def reset_descendant_keyword_constant_map
  @descendant_keyword_constant_map = nil
  descendant_keyword_constant_map
end
widget_proxy_class(keyword) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 41
def widget_proxy_class(keyword)
  descendant_keyword_constant_map[keyword] || ControlProxy
end

Private Class Methods

add_aliases_to_keyword_constant_map(keyword_constant_map) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 98
def add_aliases_to_keyword_constant_map(keyword_constant_map)
  KEYWORD_ALIASES.each do |keyword, alias_keyword|
    keyword_constant_map[alias_keyword] = keyword_constant_map[keyword]
  end
  keyword_constant_map
end

Public Instance Methods

append_properties() click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 304
def append_properties
  @parent_proxy&.class&.constants&.include?(:APPEND_PROPERTIES) ? @parent_proxy.class::APPEND_PROPERTIES : []
end
append_property(property, value = nil) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 308
def append_property(property, value = nil)
  property = property.to_s.sub(/(=|\?)$/, '')
  @append_property_hash ||= {}
  if value.nil?
    value = @append_property_hash[property]
    handle_string_property(property, handle_boolean_property(property, value))
  else
    value = Glimmer::LibUI.boolean_to_integer(value) if BOOLEAN_PROPERTIES.include?(property) && (value.is_a?(TrueClass) || value.is_a?(FalseClass))
    @append_property_hash[property] = value
  end
end
can_handle_listener?(listener_name) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 163
def can_handle_listener?(listener_name)
  ::LibUI.respond_to?("#{libui_api_keyword}_#{listener_name}") ||
    ::LibUI.respond_to?("control_#{listener_name}") ||
    has_custom_listener?(listener_name)
end
content(&block) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 378
def content(&block)
  Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Libui::ControlExpression.new, @keyword, {post_add_content: @content_added}, &block)
end
custom_listener_name_aliases() click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 207
def custom_listener_name_aliases
  self.class.constants.include?(:CUSTOM_LISTENER_NAME_ALIASES) ? self.class::CUSTOM_LISTENER_NAME_ALIASES : {}
end
custom_listener_names() click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 203
def custom_listener_names
  self.class.constants.include?(:CUSTOM_LISTENER_NAMES) ? self.class::CUSTOM_LISTENER_NAMES : []
end
default_destroy() click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 340
def default_destroy
  deregister_all_custom_listeners
  send_to_libui('destroy')
  ControlProxy.control_proxies.delete(self)
end
deregister_all_custom_listeners() click to toggle source

deregisters all custom listeners except on_destroy, which can only be deregistered after destruction of a control, using deregister_custom_listeners

# File lib/glimmer/libui/control_proxy.rb, line 235
def deregister_all_custom_listeners
  (custom_listener_names - ['on_destroy']).each { |listener_name| deregister_custom_listeners(listener_name) }
end
deregister_custom_listeners(listener_name) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 230
def deregister_custom_listeners(listener_name)
  handle_custom_listener(listener_name).clear
end
destroy() click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 324
def destroy
  # TODO exclude menus from this initial return
  return if !is_a?(ControlProxy::WindowProxy) && ControlProxy.main_window_proxy&.destroying?
  data_binding_model_attribute_observer_registrations.each(&:deregister)
  if parent_proxy.nil?
    default_destroy
  else
    parent_proxy.destroy_child(self)
  end
end
destroy_child(child) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 335
def destroy_child(child)
  child.default_destroy
  children.delete(child)
end
enabled(value = nil) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 346
def enabled(value = nil)
  if value.nil?
    @enabled
  elsif value != @enabled
    @enabled = value == 1 || value
    if value == 1 || value
      send_to_libui('enable')
    else
      send_to_libui('disable')
    end
  end
end
Also aliased as: enabled?, set_enabled, enabled=
enabled=(value = nil)
Alias for: enabled
enabled?(value = nil)
Alias for: enabled
handle_custom_listener(listener_name, &listener) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 211
def handle_custom_listener(listener_name, &listener)
  listener_name = listener_name.to_s
  listener_name = custom_listener_name_aliases.stringify_keys[listener_name] || listener_name
  instance_variable_name = "@#{listener_name}_procs" # TODO ensure clearing custom listeners on destroy of a control
  instance_variable_set(instance_variable_name, []) if instance_variable_get(instance_variable_name).nil?
  if listener.nil?
    instance_variable_get(instance_variable_name)
  else
    instance_variable_get(instance_variable_name) << listener
    listener
  end
end
handle_listener(listener_name, &listener) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 169
def handle_listener(listener_name, &listener)
  safe_listener = Proc.new { listener.call(self) }
  if ::LibUI.respond_to?("#{libui_api_keyword}_#{listener_name}")
    if listeners[listener_name].nil?
      ::LibUI.send("#{libui_api_keyword}_#{listener_name}", @libui) do
        listeners_for(listener_name).map { |listener| listener.call }.last
      end
    end
    listeners_for(listener_name) << safe_listener
  elsif ::LibUI.respond_to?("control_#{listener_name}")
    if listeners[listener_name].nil?
      ::LibUI.send("control_#{listener_name}", @libui) do
        listeners_for(listener_name).map { |listener| listener.call }.last
      end
    end
    listeners_for(listener_name) << safe_listener
  elsif has_custom_listener?(listener_name)
    handle_custom_listener(listener_name, &listener)
  end
end
has_custom_listener?(listener_name) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 198
def has_custom_listener?(listener_name)
  listener_name = listener_name.to_s
  custom_listener_names.include?(listener_name) || custom_listener_name_aliases.stringify_keys.keys.include?(listener_name)
end
libui_api_keyword() click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 320
def libui_api_keyword
  @keyword
end
listeners() click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 190
def listeners
  @listeners ||= {}
end
listeners_for(listener_name) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 194
def listeners_for(listener_name)
  listeners[listener_name] ||= []
end
method_missing(method_name, *args, &block) click to toggle source
Calls superclass method
# File lib/glimmer/libui/control_proxy.rb, line 259
def method_missing(method_name, *args, &block)
  if respond_to_libui?(method_name, *args, &block)
    send_to_libui(method_name, *args, &block)
  elsif append_properties.include?(method_name.to_s) ||
      append_properties.include?(method_name.to_s.sub(/(=|\?)$/, ''))
    append_property(method_name, *args)
  elsif can_handle_listener?(method_name.to_s)
    handle_listener(method_name.to_s, &block)
  else
    super
  end
end
notify_custom_listeners(listener_name, *args) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 224
def notify_custom_listeners(listener_name, *args)
  handle_custom_listener(listener_name).each do |listener|
    listener.call(*args)
  end
end
post_add_content() click to toggle source

Subclasses may override to perform post add_content work (normally must call super)

# File lib/glimmer/libui/control_proxy.rb, line 143
def post_add_content
  unless @content_added
    @parent_proxy&.post_initialize_child(self)
    @content_added = true
  end
end
post_initialize_child(child) click to toggle source

Subclasses may override to perform post initialization work on an added child

# File lib/glimmer/libui/control_proxy.rb, line 151
def post_initialize_child(child)
  # No Op by default
end
respond_to?(method_name, *args, &block) click to toggle source
Calls superclass method
# File lib/glimmer/libui/control_proxy.rb, line 239
def respond_to?(method_name, *args, &block)
  respond_to_libui?(method_name, *args, &block) ||
    (
      append_properties.include?(method_name.to_s) ||
      (append_properties.include?(method_name.to_s.sub(/\?$/, '')) && BOOLEAN_PROPERTIES.include?(method_name.to_s.sub(/\?$/, ''))) ||
      append_properties.include?(method_name.to_s.sub(/=$/, ''))
    ) ||
    can_handle_listener?(method_name.to_s) ||
    super(method_name, true)
end
respond_to_libui?(method_name, *args, &block) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 250
def respond_to_libui?(method_name, *args, &block)
  ::LibUI.respond_to?("control_#{method_name}") or
    (::LibUI.respond_to?("control_#{method_name.to_s.sub(/\?$/, '')}") && BOOLEAN_PROPERTIES.include?(method_name.to_s.sub(/\?$/, '')) ) or
    ::LibUI.respond_to?("control_set_#{method_name.to_s.sub(/=$/, '')}") or
    ::LibUI.respond_to?("#{libui_api_keyword}_#{method_name}") or
    (::LibUI.respond_to?("#{libui_api_keyword}_#{method_name.to_s.sub(/\?$/, '')}") && BOOLEAN_PROPERTIES.include?(method_name.to_s.sub(/\?$/, '')) ) or
    ::LibUI.respond_to?("#{libui_api_keyword}_set_#{method_name.to_s.sub(/=$/, '')}")
end
send_to_libui(method_name, *args, &block) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 272
def send_to_libui(method_name, *args, &block)
  if ::LibUI.respond_to?("#{libui_api_keyword}_#{method_name.to_s.sub(/\?$/, '')}") && args.empty?
    property = method_name.to_s.sub(/\?$/, '')
    value = ::LibUI.send("#{libui_api_keyword}_#{property}", @libui, *args)
    handle_string_property(property, handle_boolean_property(property, value))
  elsif ::LibUI.respond_to?("#{libui_api_keyword}_set_#{method_name.to_s.sub(/=$/, '')}") && !args.empty?
    property = method_name.to_s.sub(/=$/, '')
    args[0] = Glimmer::LibUI.boolean_to_integer(args.first) if BOOLEAN_PROPERTIES.include?(property) && (args.first.is_a?(TrueClass) || args.first.is_a?(FalseClass))
    args[0] = '' if STRING_PROPERTIES.include?(property) && args.first == nil
    if property.to_s == 'checked'
      current_value = Glimmer::LibUI.integer_to_boolean(::LibUI.send("#{libui_api_keyword}_checked", @libui), allow_nil: false)
      new_value = Glimmer::LibUI.integer_to_boolean(args[0], allow_nil: false)
      ::LibUI.send("#{libui_api_keyword}_set_#{property}", @libui, *args) if new_value != current_value
    else
      ::LibUI.send("#{libui_api_keyword}_set_#{property}", @libui, *args)
    end
  elsif ::LibUI.respond_to?("#{libui_api_keyword}_#{method_name}") && !args.empty?
    ::LibUI.send("#{libui_api_keyword}_#{method_name}", @libui, *args)
  elsif ::LibUI.respond_to?("control_#{method_name.to_s.sub(/\?$/, '')}") && args.empty?
    property = method_name.to_s.sub(/\?$/, '')
    value = ::LibUI.send("control_#{property}", @libui, *args)
    handle_string_property(property, handle_boolean_property(property, value))
  elsif ::LibUI.respond_to?("control_set_#{method_name.to_s.sub(/=$/, '')}")
    property = method_name.to_s.sub(/=$/, '')
    args[0] = Glimmer::LibUI.boolean_to_integer(args.first) if BOOLEAN_PROPERTIES.include?(property) && (args.first.is_a?(TrueClass) || args.first.is_a?(FalseClass))
    args[0] = '' if STRING_PROPERTIES.include?(property) && args.first == nil
    ::LibUI.send("control_set_#{method_name.to_s.sub(/=$/, '')}", @libui, *args)
  elsif ::LibUI.respond_to?("control_#{method_name}") && !args.empty?
    ::LibUI.send("control_#{method_name}", @libui, *args)
  end
end
set_enabled(value = nil)
Alias for: enabled
set_visible(value = nil)
Alias for: visible
visible(value = nil) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 362
def visible(value = nil)
  current_value = send_to_libui('visible')
  if value.nil?
    current_value
  elsif value != current_value
    if value == 1 || value
      send_to_libui('show')
    else
      send_to_libui('hide')
    end
  end
end
Also aliased as: visible?, set_visible, visible=
visible=(value = nil)
Alias for: visible
visible?(value = nil)
Alias for: visible
window_proxy() click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 155
def window_proxy
  found_proxy = self
  until found_proxy.nil? || found_proxy.is_a?(WindowProxy)
    found_proxy = found_proxy.parent_proxy
  end
  found_proxy
end

Private Instance Methods

build_control() click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 384
def build_control
  @libui = if ::LibUI.respond_to?("new_#{keyword}")
    ControlProxy.new_control(@keyword, @args)
  elsif ::LibUI.respond_to?(keyword)
    @args[0] = @args.first.libui if @args.first.is_a?(ControlProxy)
    ::LibUI.send(@keyword, *@args)
  end
end
handle_boolean_property(property, value) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 393
def handle_boolean_property(property, value)
  BOOLEAN_PROPERTIES.include?(property) ? Glimmer::LibUI.integer_to_boolean(value) : value
end
handle_string_property(property, value) click to toggle source
# File lib/glimmer/libui/control_proxy.rb, line 397
def handle_string_property(property, value)
  STRING_PROPERTIES.include?(property) ? value.to_s : value
end