Class: Glimmer::Wx::ControlProxy

Inherits:
Object
  • Object
show all
Includes:
DataBindable
Defined in:
lib/glimmer/wx/control_proxy.rb,
lib/glimmer/wx/control_proxy/frame_proxy.rb

Overview

Proxy for Wx control objects

Follows the Proxy Design Pattern

Direct Known Subclasses

FrameProxy

Defined Under Namespace

Classes: FrameProxy

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from DataBindable

#data_bind, #data_bind_read, #data_bind_write, #data_binding_model_attribute_observer_registrations

Constructor Details

#initialize(keyword, parent, args, &block) ⇒ ControlProxy

Returns a new instance of ControlProxy.



93
94
95
96
97
98
99
100
# File 'lib/glimmer/wx/control_proxy.rb', line 93

def initialize(keyword, parent, args, &block)
  @keyword = keyword
  @parent_proxy = parent
  @args = args
  @block = block
  build_control
  post_add_content if @block.nil?
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args, &block) ⇒ Object



206
207
208
209
210
211
212
213
214
# File 'lib/glimmer/wx/control_proxy.rb', line 206

def method_missing(method_name, *args, &block)
  if @wx.respond_to?(method_name, true)
    @wx.send(method_name, *args, &block)
  elsif can_handle_listener?(method_name.to_s)
    handle_listener(method_name.to_s, &block)
  else
    super
  end
end

Instance Attribute Details

#argsObject (readonly)

wx returns the contained LibUI object



90
91
92
# File 'lib/glimmer/wx/control_proxy.rb', line 90

def args
  @args
end

#blockObject (readonly)

wx returns the contained LibUI object



90
91
92
# File 'lib/glimmer/wx/control_proxy.rb', line 90

def block
  @block
end

#content_addedObject (readonly) Also known as: content_added?

wx returns the contained LibUI object



90
91
92
# File 'lib/glimmer/wx/control_proxy.rb', line 90

def content_added
  @content_added
end

#keywordObject (readonly)

wx returns the contained LibUI object



90
91
92
# File 'lib/glimmer/wx/control_proxy.rb', line 90

def keyword
  @keyword
end

#parent_proxyObject (readonly)

wx returns the contained LibUI object



90
91
92
# File 'lib/glimmer/wx/control_proxy.rb', line 90

def parent_proxy
  @parent_proxy
end

#wxObject (readonly)

wx returns the contained LibUI object



90
91
92
# File 'lib/glimmer/wx/control_proxy.rb', line 90

def wx
  @wx
end

Class Method Details

.constant_symbol(keyword) ⇒ Object



57
58
59
# File 'lib/glimmer/wx/control_proxy.rb', line 57

def constant_symbol(keyword)
  "#{keyword.to_s.camelcase(:upper)}Proxy".to_sym
end

.control_proxy_class(keyword) ⇒ Object



41
42
43
# File 'lib/glimmer/wx/control_proxy.rb', line 41

def control_proxy_class(keyword)
  descendant_keyword_constant_map[keyword] || ControlProxy
end

.create(keyword, parent, args, &block) ⇒ Object



37
38
39
# File 'lib/glimmer/wx/control_proxy.rb', line 37

def create(keyword, parent, args, &block)
  control_proxy_class(keyword).new(keyword, parent, args, &block)
end

.descendant_keyword_constant_mapObject



65
66
67
# File 'lib/glimmer/wx/control_proxy.rb', line 65

def descendant_keyword_constant_map
  @descendant_keyword_constant_map ||= map_descendant_keyword_constants_for(self)
end

.exists?(keyword) ⇒ Boolean

Returns:

  • (Boolean)


32
33
34
35
# File 'lib/glimmer/wx/control_proxy.rb', line 32

def exists?(keyword)
  ::Wx.constants.include?(wx_constant_symbol(keyword)) or
    descendant_keyword_constant_map.keys.include?(keyword)
end

.keyword(constant_symbol) ⇒ Object



61
62
63
# File 'lib/glimmer/wx/control_proxy.rb', line 61

def keyword(constant_symbol)
  constant_symbol.to_s.underscore.sub(/_proxy$/, '')
end

.map_descendant_keyword_constants_for(klass, accumulator: {}) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/glimmer/wx/control_proxy.rb', line 74

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

.new_control(keyword, parent, args) ⇒ Object



45
46
47
48
49
50
51
# File 'lib/glimmer/wx/control_proxy.rb', line 45

def new_control(keyword, parent, args)
  args = args.clone || []
  if args.last.is_a?(Hash)
    args[-1] = args[-1].clone
  end
  ::Wx.const_get(wx_constant_symbol(keyword)).new(parent, *args)
end

.reset_descendant_keyword_constant_mapObject



69
70
71
72
# File 'lib/glimmer/wx/control_proxy.rb', line 69

def reset_descendant_keyword_constant_map
  @descendant_keyword_constant_map = nil
  descendant_keyword_constant_map
end

.wx_constant_symbol(keyword) ⇒ Object



53
54
55
# File 'lib/glimmer/wx/control_proxy.rb', line 53

def wx_constant_symbol(keyword)
  keyword.to_s.camelcase(:upper).to_sym
end

Instance Method Details

#can_handle_listener?(listener_name) ⇒ Boolean

Returns:

  • (Boolean)


137
138
139
140
141
# File 'lib/glimmer/wx/control_proxy.rb', line 137

def can_handle_listener?(listener_name)
  listener_name.to_s.start_with?('on_')
  # TODO figure out if there is a way to check this in Wx or not.
#           has_custom_listener?(listener_name)
end

#content(&block) ⇒ Object



216
217
218
# File 'lib/glimmer/wx/control_proxy.rb', line 216

def content(&block)
  Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Libui::ControlExpression.new, @keyword, {post_add_content: @content_added}, &block)
end

#control_proxyObject

Returns closest control ancestor



129
130
131
132
133
134
135
# File 'lib/glimmer/wx/control_proxy.rb', line 129

def control_proxy
  found_proxy = parent_proxy
  until found_proxy.nil? || found_proxy.is_a?(ControlProxy)
    found_proxy = found_proxy.parent_proxy
  end
  found_proxy
end

#custom_listener_name_aliasesObject



168
169
170
# File 'lib/glimmer/wx/control_proxy.rb', line 168

def custom_listener_name_aliases
  self.class.constants.include?(:CUSTOM_LISTENER_NAME_ALIASES) ? self.class::CUSTOM_LISTENER_NAME_ALIASES : {}
end

#custom_listener_namesObject



164
165
166
# File 'lib/glimmer/wx/control_proxy.rb', line 164

def custom_listener_names
  self.class.constants.include?(:CUSTOM_LISTENER_NAMES) ? self.class::CUSTOM_LISTENER_NAMES : []
end

#deregister_all_custom_listenersObject

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



196
197
198
# File 'lib/glimmer/wx/control_proxy.rb', line 196

def deregister_all_custom_listeners
  (custom_listener_names - ['on_destroy']).each { |listener_name| deregister_custom_listeners(listener_name) }
end

#deregister_custom_listeners(listener_name) ⇒ Object



191
192
193
# File 'lib/glimmer/wx/control_proxy.rb', line 191

def deregister_custom_listeners(listener_name)
  handle_custom_listener(listener_name).clear
end

#frame_proxyObject

Returns closest frame ancestor or self if it is a frame



120
121
122
123
124
125
126
# File 'lib/glimmer/wx/control_proxy.rb', line 120

def frame_proxy
  found_proxy = self
  until found_proxy.nil? || found_proxy.is_a?(FrameProxy)
    found_proxy = found_proxy.parent_proxy
  end
  found_proxy
end

#handle_custom_listener(listener_name, &listener) ⇒ Object



172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/glimmer/wx/control_proxy.rb', line 172

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) ⇒ Object



143
144
145
146
147
148
149
# File 'lib/glimmer/wx/control_proxy.rb', line 143

def handle_listener(listener_name, &listener)
  event = listener_name.to_s.sub('on_', '')
  frame_proxy.wx.send("evt_#{event}", @wx, &listener)
#         elsif has_custom_listener?(listener_name)
#           handle_custom_listener(listener_name, &listener)
#         end
end

#has_custom_listener?(listener_name) ⇒ Boolean

Returns:

  • (Boolean)


159
160
161
162
# File 'lib/glimmer/wx/control_proxy.rb', line 159

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

#listenersObject



151
152
153
# File 'lib/glimmer/wx/control_proxy.rb', line 151

def listeners
  @listeners ||= {}
end

#listeners_for(listener_name) ⇒ Object



155
156
157
# File 'lib/glimmer/wx/control_proxy.rb', line 155

def listeners_for(listener_name)
  listeners[listener_name] ||= []
end

#notify_custom_listeners(listener_name, *args) ⇒ Object



185
186
187
188
189
# File 'lib/glimmer/wx/control_proxy.rb', line 185

def notify_custom_listeners(listener_name, *args)
  handle_custom_listener(listener_name).each do |listener|
    listener.call(*args)
  end
end

#optionsObject



102
103
104
# File 'lib/glimmer/wx/control_proxy.rb', line 102

def options
  @args&.last&.is_a?(Hash) ? @args.last : {}
end

#post_add_contentObject

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



107
108
109
110
111
112
# File 'lib/glimmer/wx/control_proxy.rb', line 107

def post_add_content
  unless @content_added
    @parent_proxy&.post_initialize_child(self)
    @content_added = true
  end
end

#post_initialize_child(child) ⇒ Object

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



115
116
117
# File 'lib/glimmer/wx/control_proxy.rb', line 115

def post_initialize_child(child)
  # No Op by default
end

#respond_to?(method_name, *args, &block) ⇒ Boolean

Returns:

  • (Boolean)


200
201
202
203
204
# File 'lib/glimmer/wx/control_proxy.rb', line 200

def respond_to?(method_name, *args, &block)
  @wx.respond_to?(method_name, true) ||
    can_handle_listener?(method_name.to_s) ||
    super(method_name, true)
end