Module: Rtml::WidgetCore::ClassMethods
- Included in:
- Rtml::Widget
- Defined in:
- lib/rtml/widget_core/class_methods.rb
Constant Summary collapse
- @@gui_enabled_widgets =
{}
Instance Method Summary collapse
-
#add_entry_point(entry_point) ⇒ Object
Adds the specified entry point to this Widget’s proxy module.
-
#affects(*targets) ⇒ Object
Specifies the targets that this Widget will affect.
-
#disable_subprocessing! ⇒ Object
By default, if a Widget’s entry point is called with a block argument, it will be passed into the #process method of the entry point’s return value.
-
#enable_subprocessing! ⇒ Object
Use this to enable subprocessing after it has already been disabled.
-
#entry_point(*names) ⇒ Object
Specifies entry points, which are names of methods that can be called from the targets to invoke this Widget.
-
#gui {|gui_configuration| ... } ⇒ Object
Yields this Widget’s GUI configuration to the supplied block, allowing you to set up your Widget to be accessible from the RTML Application Builder.
-
#gui_configuration ⇒ Object
Returns the
Rtml::WidgetCore::GuiConfiguration
instance for this Widget. -
#gui_enabled_widgets ⇒ Object
Returns the array of Widgets that have called the #gui method, thereby marking themselves as accessible to the RTML Application Builder.
- #proxy_module ⇒ Object
-
#reinclude_proxy_module ⇒ Object
Goes through each of the targets of this Widget, looks up its mapping in Rtml::Widgets.mapping, and calls proxy_module.append_features(mapping) for each of those mappings.
-
#shared(*names) ⇒ Object
Creates a “shared” variable for the parent object with the specified default value, if any.
-
#subprocessing_disabled? ⇒ Boolean
(also: #disable_subprocessing?)
Returns true if subprocessing has been disabled.
-
#target?(base) ⇒ Boolean
Returns true if the specified class is a valid target of this Widget.
Instance Method Details
#add_entry_point(entry_point) ⇒ Object
Adds the specified entry point to this Widget’s proxy module.
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/rtml/widget_core/class_methods.rb', line 133 def add_entry_point(entry_point) # This validation doesn't work because it's not this proxy module, it's those of the OTHER Widgets # that should be checked. Not sure of the best way to do that yet. # if proxy_module.public_instance_methods.include?(entry_point) # raise Rtml::Errors::RulesViolationError, # "Widget entry point #{entry_point} cannot be defined because it already exists!" # end #entry_point = entry_point.to_sym unless entry_point.is_a?(Symbol) entry_point = entry_point.to_s if entry_point.is_a?(Symbol) enter_from_hash = "#{entry_point}_from_hash" ['?','!'].each do |i| enter_from_hash = enter_from_hash.gsub(/#{Regexp::escape(i)}/, '') + i if enter_from_hash[i] end line = __LINE__ + 2 code = <<-end_code def #{entry_point}(*args, &block) # def screen(*args, &block) widget = #{self.name}.new(self) # widget = Rtml::Widgets::Screens.new(self) r = widget.#{entry_point}(*args, &block) # r = widget.screen(*args, &block) unless widget.disable_subprocessing? || !block_given? unless r.respond_to?(:process) raise Rtml::Errors::SubprocessingNotSupported, "Return value \#{r} does not support subprocessing" end r.process &block end r rescue ArgumentError => ae if ae.backtrace[0] =~ /#{Regexp::escape entry_point}/ raise ArgumentError, ae.message, caller else raise ae end end # end # Calls the entry point after reformatting the arguments in hash to fit the entry point's requirements # per +Rtml::WidgetCore::GuiConfiguration#construct_arguments+ # # This is primarily for interfacing with the RTML GUI. # def #{enter_from_hash}(hash, &block) arguments = #{self}.gui_configuration.construct_arguments(hash || {}) self.#{entry_point} *arguments, &block end end_code proxy_module.class_eval code, __FILE__, line reinclude_proxy_module entry_point end |
#affects(*targets) ⇒ Object
Specifies the targets that this Widget will affect. A target can be a name of a model or the name of a TML tag, which matches that model’s “name” attribute.
Examples:
affects :document, :element, :property # names of models
affects :tml, :head, :screen # names of TML tags
95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/rtml/widget_core/class_methods.rb', line 95 def affects(*targets) targets.flatten.each do |target| target = target.to_s unless target.kind_of?(String) unless self.targets.include? target self.targets << target map = Rtml::Widgets.mapping(target) map. << self map.imbue(proxy_module) end end end |
#disable_subprocessing! ⇒ Object
By default, if a Widget’s entry point is called with a block argument, it will be passed into the #process method of the entry point’s return value. This is called subprocessing – that is, processing the element to be returned at a lower level. This method disables subprocessing and its related assertions. It’s useful, for instance, if you want to manually control how or when the block argument is processed, or if you want to ignore it entirely.
If you want to disable subprocessing only under certain conditions, see the instance method of the same name.
73 74 75 |
# File 'lib/rtml/widget_core/class_methods.rb', line 73 def disable_subprocessing! @disable_subprocessing = true end |
#enable_subprocessing! ⇒ Object
Use this to enable subprocessing after it has already been disabled. See #disable_subprocessing!
78 79 80 |
# File 'lib/rtml/widget_core/class_methods.rb', line 78 def enable_subprocessing! @disable_subprocessing = false end |
#entry_point(*names) ⇒ Object
Specifies entry points, which are names of methods that can be called from the targets to invoke this Widget.
Examples:
entry_point :screen
123 124 125 126 127 128 129 130 |
# File 'lib/rtml/widget_core/class_methods.rb', line 123 def entry_point(*names) names.each do |name| #name = name.to_sym unless name.kind_of?(Symbol) unless entry_points.include?(name) entry_points << add_entry_point(name) end end end |
#gui {|gui_configuration| ... } ⇒ Object
Yields this Widget’s GUI configuration to the supplied block, allowing you to set up your Widget to be accessible from the RTML Application Builder. Note that if this method is never called, your Widget will not be available to the GUI.
22 23 24 |
# File 'lib/rtml/widget_core/class_methods.rb', line 22 def gui yield(gui_configuration) end |
#gui_configuration ⇒ Object
Returns the Rtml::WidgetCore::GuiConfiguration
instance for this Widget. Shorthand for:
.[]
29 30 31 |
# File 'lib/rtml/widget_core/class_methods.rb', line 29 def gui_configuration [self] ||= Rtml::WidgetCore::GuiConfiguration.new(self) end |
#gui_enabled_widgets ⇒ Object
Returns the array of Widgets that have called the #gui method, thereby marking themselves as accessible to the RTML Application Builder.
35 36 37 |
# File 'lib/rtml/widget_core/class_methods.rb', line 35 def @@gui_enabled_widgets end |
#proxy_module ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# File 'lib/rtml/widget_core/class_methods.rb', line 4 def proxy_module return @proxy_module if @proxy_module @proxy_module = Module.new @proxy_module.instance_variable_set("@shared_variables", shared_variables) @proxy_module.instance_eval do def included(base) @shared_variables.each do |sv| base.send(:attr_accessor, sv[:name]) end end end @proxy_module end |
#reinclude_proxy_module ⇒ Object
Goes through each of the targets of this Widget, looks up its mapping in Rtml::Widgets.mapping, and calls proxy_module.append_features(mapping) for each of those mappings.
110 111 112 113 114 115 116 |
# File 'lib/rtml/widget_core/class_methods.rb', line 110 def reinclude_proxy_module targets.each do |target| Rtml::Widgets.mapping(target).imbue(proxy_module) end # FIXME: Um... Maybe this is fine, but it seems out of place. Rtml::Widgets.bases.each { |base| Rtml::Widgets.add_proxies_to_base(base) } end |
#shared(*names) ⇒ Object
Creates a “shared” variable for the parent object with the specified default value, if any. This is much like a class variable, except that it is unique to the parent object in question. Multiple calls to a Widget’s entry point will result in multiple Widgets being instantiated. If you use an instance variable to hold data, then that instance variable will be different for every entry point called. However, sometimes you need to share data across multiple instances of the same Widget, but not across all instances of the same Widget. For instance, your Widget may want to track references to variables in an individual Screen, but not across multiple Screens. To accomplish this, you essentially need an instance variable for the Screen. The “shared” method manages these variables for you.
Examples:
shared :tml_variables
shared :variable_definitions, :variable_declarations
shared :tml_variables => [] # initializes #tml_variables to [].dup
52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/rtml/widget_core/class_methods.rb', line 52 def shared(*names) names.each do |name| if name.kind_of? Hash value = name.values.first name = name.keys.first.to_s shared_variables << { :name => name, :default_value => value } else name = name.to_s shared_variables << { :name => name, :default_value => nil } end delegate name, "#{name}=", :to => :parent end reinclude_proxy_module end |
#subprocessing_disabled? ⇒ Boolean Also known as: disable_subprocessing?
Returns true if subprocessing has been disabled. See also #disable_subprocessing!
83 84 85 |
# File 'lib/rtml/widget_core/class_methods.rb', line 83 def subprocessing_disabled? @disable_subprocessing ||= false end |
#target?(base) ⇒ Boolean
Returns true if the specified class is a valid target of this Widget
184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/rtml/widget_core/class_methods.rb', line 184 def target?(base) if base.respond_to?(:name) name = base.name.underscore.sub(/^.*\//, '') targets.each do |target| if base.kind_of?(ActiveRecord::Base) || base.kind_of?(Rtml::DocumentModelObject) # it's an instance, so we should check the tag name, not the class name return true if target == base.name else return true if target == name end end end false end |