Module: Glimmer::LibUI::CustomControl
- Includes:
- DataBinding::ObservableModel, SuperModule
- Included in:
- CodeArea, CodeEntry, RefinedTable, CustomWindow
- Defined in:
- lib/glimmer/libui/custom_control.rb,
lib/glimmer/libui/custom_control/code_area.rb,
lib/glimmer/libui/custom_control/code_entry.rb,
lib/glimmer/libui/custom_control/refined_table.rb
Defined Under Namespace
Modules: GlimmerSupersedable Classes: CodeArea, CodeEntry, RefinedTable
Instance Attribute Summary collapse
-
#args ⇒ Object
readonly
Returns the value of attribute args.
-
#body_root ⇒ Object
readonly
Returns the value of attribute body_root.
-
#content(*args, &block) ⇒ Object
readonly
Returns content block if used as an attribute reader (no args) Otherwise, if a block is passed, it adds it as content to this custom control.
-
#keyword ⇒ Object
readonly
Returns the value of attribute keyword.
-
#libui ⇒ Object
readonly
Returns the value of attribute libui.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#parent ⇒ Object
readonly
Returns the value of attribute parent.
-
#parent_proxy ⇒ Object
readonly
Returns the value of attribute parent_proxy.
-
#slot_controls ⇒ Object
readonly
Returns the value of attribute slot_controls.
Class Method Summary collapse
- .add_custom_control_namespaces_for(klass) ⇒ Object
- .after_body(&block) ⇒ Object
- .before_body(&block) ⇒ Object
- .body(&block) ⇒ Object
- .custom_control_namespaces ⇒ Object
- .custom_controls_being_interpreted ⇒ Object
- .def_option_attr_accessors(new_options) ⇒ Object
-
.flyweight_custom_control_classes ⇒ Object
Flyweight Design Pattern memoization cache.
- .for(keyword) ⇒ Object
-
.keyword ⇒ Object
Returns keyword to use for this custom control.
- .namespaces_for_class(m) ⇒ Object
- .option(new_option, default: nil) ⇒ Object
-
.options(*new_options) ⇒ Object
Allows defining convenience option accessors for an array of option names Example: ‘options :color1, :color2` defines
#color1and#color2where they return the instance valuesoptions[:color1]andoptions[:color2]respectively. - .reset_custom_control_namespaces ⇒ Object
-
.shortcut_keyword ⇒ Object
Returns shortcut keyword to use for this custom control (keyword minus namespace).
Instance Method Summary collapse
- #can_handle_listener?(listener) ⇒ Boolean
- #handle_listener(listener, &block) ⇒ Object
-
#has_instance_method?(method_name) ⇒ Boolean
This method ensures it has an instance method not coming from Glimmer DSL.
- #initialize(keyword, parent, args, options, &content) ⇒ Object
- #observer_registrations ⇒ Object
- #post_add_content ⇒ Object
-
#post_initialize_child(child) ⇒ Object
Subclasses may override to perform post initialization work on an added child.
Instance Attribute Details
#args ⇒ Object (readonly)
Returns the value of attribute args.
192 193 194 |
# File 'lib/glimmer/libui/custom_control.rb', line 192 def args @args end |
#body_root ⇒ Object (readonly)
Returns the value of attribute body_root.
192 193 194 |
# File 'lib/glimmer/libui/custom_control.rb', line 192 def body_root @body_root end |
#content(*args, &block) ⇒ Object (readonly)
Returns content block if used as an attribute reader (no args) Otherwise, if a block is passed, it adds it as content to this custom control
246 247 248 |
# File 'lib/glimmer/libui/custom_control.rb', line 246 def content @content end |
#keyword ⇒ Object (readonly)
Returns the value of attribute keyword.
192 193 194 |
# File 'lib/glimmer/libui/custom_control.rb', line 192 def keyword @keyword end |
#libui ⇒ Object (readonly)
Returns the value of attribute libui.
192 193 194 |
# File 'lib/glimmer/libui/custom_control.rb', line 192 def libui @libui end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
192 193 194 |
# File 'lib/glimmer/libui/custom_control.rb', line 192 def end |
#parent ⇒ Object (readonly)
Returns the value of attribute parent.
192 193 194 |
# File 'lib/glimmer/libui/custom_control.rb', line 192 def parent @parent end |
#parent_proxy ⇒ Object (readonly)
Returns the value of attribute parent_proxy.
192 193 194 |
# File 'lib/glimmer/libui/custom_control.rb', line 192 def parent_proxy @parent_proxy end |
#slot_controls ⇒ Object (readonly)
Returns the value of attribute slot_controls.
192 193 194 |
# File 'lib/glimmer/libui/custom_control.rb', line 192 def slot_controls @slot_controls end |
Class Method Details
.add_custom_control_namespaces_for(klass) ⇒ Object
115 116 117 118 119 |
# File 'lib/glimmer/libui/custom_control.rb', line 115 def add_custom_control_namespaces_for(klass) Glimmer::LibUI::CustomControl.namespaces_for_class(klass).drop(1).each do |namespace| Glimmer::LibUI::CustomControl.custom_control_namespaces << namespace end end |
.after_body(&block) ⇒ Object
183 184 185 |
# File 'lib/glimmer/libui/custom_control.rb', line 183 def after_body(&block) @after_body_block = block end |
.before_body(&block) ⇒ Object
175 176 177 |
# File 'lib/glimmer/libui/custom_control.rb', line 175 def before_body(&block) @before_body_block = block end |
.body(&block) ⇒ Object
179 180 181 |
# File 'lib/glimmer/libui/custom_control.rb', line 179 def body(&block) @body_block = block end |
.custom_control_namespaces ⇒ Object
129 130 131 |
# File 'lib/glimmer/libui/custom_control.rb', line 129 def custom_control_namespaces @custom_control_namespaces ||= reset_custom_control_namespaces end |
.custom_controls_being_interpreted ⇒ Object
187 188 189 |
# File 'lib/glimmer/libui/custom_control.rb', line 187 def custom_controls_being_interpreted @custom_controls_being_interpreted ||= [] end |
.def_option_attr_accessors(new_options) ⇒ Object
161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/glimmer/libui/custom_control.rb', line 161 def def_option_attr_accessors() .each do |option, default| class_eval " def \#{option}\n options[:\#{option}]\n end\n \n def \#{option}=(option_value)\n self.options[:\#{option}] = option_value\n end\n end_eval\n end\nend\n", __FILE__, __LINE__ |
.flyweight_custom_control_classes ⇒ Object
Flyweight Design Pattern memoization cache. Can be cleared if memory is needed.
101 102 103 |
# File 'lib/glimmer/libui/custom_control.rb', line 101 def flyweight_custom_control_classes @flyweight_custom_control_classes ||= {} end |
.for(keyword) ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/glimmer/libui/custom_control.rb', line 67 def for(keyword) unless flyweight_custom_control_classes.keys.include?(keyword) begin extracted_namespaces = keyword. to_s. split(/__/).map do |namespace| namespace.camelcase(:upper) end custom_control_namespaces.each do |base| extracted_namespaces.reduce(base) do |result, namespace| if !result.constants.include?(namespace) namespace = result.constants.detect {|c| c.to_s.upcase == namespace.to_s.upcase } || namespace end begin flyweight_custom_control_classes[keyword] = constant = result.const_get(namespace) return constant if constant.ancestors.include?(Glimmer::LibUI::CustomControl) flyweight_custom_control_classes[keyword] = constant rescue => e # Glimmer::Config.logger.debug {"#{e.message}\n#{e.backtrace.join("\n")}"} flyweight_custom_control_classes[keyword] = result end end end raise "#{keyword} has no custom control class!" rescue => e Glimmer::Config.logger.debug {e.} Glimmer::Config.logger.debug {"#{e.message}\n#{e.backtrace.join("\n")}"} flyweight_custom_control_classes[keyword] = nil end end flyweight_custom_control_classes[keyword] end |
.keyword ⇒ Object
Returns keyword to use for this custom control
106 107 108 |
# File 'lib/glimmer/libui/custom_control.rb', line 106 def keyword self.name.underscore.gsub('::', '__') end |
.namespaces_for_class(m) ⇒ Object
121 122 123 124 125 126 127 |
# File 'lib/glimmer/libui/custom_control.rb', line 121 def namespaces_for_class(m) return [m] if m.name.nil? namespace_constants = m.name.split(/::/).map(&:to_sym) namespace_constants.reduce([Object]) do |output, namespace_constant| output += [output.last.const_get(namespace_constant)] end[1..-1].uniq.reverse end |
.option(new_option, default: nil) ⇒ Object
154 155 156 157 158 159 |
# File 'lib/glimmer/libui/custom_control.rb', line 154 def option(new_option, default: nil) new_option = new_option.to_s.to_sym = {new_option => default} = .merge() def_option_attr_accessors() end |
.options(*new_options) ⇒ Object
Allows defining convenience option accessors for an array of option names Example: ‘options :color1, :color2` defines #color1 and #color2 where they return the instance values options[:color1] and options[:color2] respectively. Can be called multiple times to set more options additively. When passed no arguments, it returns list of all option names captured so far
143 144 145 146 147 148 149 150 151 152 |
# File 'lib/glimmer/libui/custom_control.rb', line 143 def (*) = .compact.map(&:to_s).map(&:to_sym) if .empty? ||= {} # maps options to defaults else = .reduce({}) {|, new_option| .merge(new_option => nil)} = .merge() def_option_attr_accessors() end end |
.reset_custom_control_namespaces ⇒ Object
133 134 135 |
# File 'lib/glimmer/libui/custom_control.rb', line 133 def reset_custom_control_namespaces @custom_control_namespaces = Set[Object, Glimmer::LibUI] end |
.shortcut_keyword ⇒ Object
Returns shortcut keyword to use for this custom control (keyword minus namespace)
111 112 113 |
# File 'lib/glimmer/libui/custom_control.rb', line 111 def shortcut_keyword self.name.underscore.gsub('::', '__').split('__').last end |
Instance Method Details
#can_handle_listener?(listener) ⇒ Boolean
227 228 229 |
# File 'lib/glimmer/libui/custom_control.rb', line 227 def can_handle_listener?(listener) body_root&.can_handle_listener?(listener.to_s) end |
#handle_listener(listener, &block) ⇒ Object
231 232 233 |
# File 'lib/glimmer/libui/custom_control.rb', line 231 def handle_listener(listener, &block) body_root.handle_listener(listener.to_s, &block) end |
#has_instance_method?(method_name) ⇒ Boolean
This method ensures it has an instance method not coming from Glimmer DSL
236 237 238 239 240 241 242 |
# File 'lib/glimmer/libui/custom_control.rb', line 236 def has_instance_method?(method_name) respond_to?(method_name) and !@body_root.respond_to_libui?(method_name) and (method(method_name) rescue nil) and !method(method_name)&.source_location&.first&.include?('glimmer/dsl/engine.rb') and !method(method_name)&.source_location&.first&.include?('glimmer/libui/control_proxy.rb') end |
#initialize(keyword, parent, args, options, &content) ⇒ Object
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/glimmer/libui/custom_control.rb', line 194 def initialize(keyword, parent, args, , &content) CustomControl.custom_controls_being_interpreted << self @parent_proxy = @parent = parent ||= {} = self.class..merge() @slot_controls = {} @content = ProcTracker.new(content) if content execute_hook('before_body') body_block = self.class.instance_variable_get("@body_block") raise Glimmer::Error, 'Invalid custom control for having no body! Please define body block!' if body_block.nil? @body_root = instance_exec(&body_block) raise Glimmer::Error, 'Invalid custom control for having an empty body! Please fill body block!' if @body_root.nil? @libui = @body_root.libui execute_hook('after_body') # TODO deregister all observer_registrations on destroy of the control once that listener is supported # (on_destroy) unless it is the last window closing, in which case exit faster post_add_content if content.nil? end |
#observer_registrations ⇒ Object
223 224 225 |
# File 'lib/glimmer/libui/custom_control.rb', line 223 def observer_registrations @observer_registrations ||= [] end |
#post_add_content ⇒ Object
218 219 220 221 |
# File 'lib/glimmer/libui/custom_control.rb', line 218 def post_add_content @parent_proxy&.post_initialize_child(@body_root) Glimmer::LibUI::CustomControl.custom_controls_being_interpreted.pop end |
#post_initialize_child(child) ⇒ Object
Subclasses may override to perform post initialization work on an added child
214 215 216 |
# File 'lib/glimmer/libui/custom_control.rb', line 214 def post_initialize_child(child) # No Op by default end |