Class: Rtml::Widget
- Inherits:
-
Object
- Object
- Rtml::Widget
- Extended by:
- Rtml::WidgetCore::ClassMethods
- Defined in:
- lib/rtml/widget.rb
Overview
The Widget is the driving force behind RubyTML. It is interaction with Widgets of all shapes and sizes that produces a document model and, finally, the TML document itself. A Widget is so named because it is a generic class that can be made to encapsulate any desired functionality. The Rtml::Widget base class takes care of interfacing content generation code with the RTML project as a whole.
If you’ve done any RTML programming at all, you’ve been using Widgets. Does the following code look familiar?
screen :idle, :next => :main, :timeout => 3 do
display
end
Even core functionality such as the “screen” method is traced back to a Widget – in this case, Rtml::Widgets::Screens
.
Since interfacing with the various components of RTML is handled by the base class, writing a Widget is easy:
class Rtml::Widgets::CardParser < Rtml::Widget
affects :screen
entry_point :card
def card( = {})
raise ":parser must be provided" unless [:parser]
parent.build :card, :parser => [:parser], :parser_params => ([:params] || 'read_data')
end
end
When invoked from a Screen, this code will produce a TML card parser element:
screen . . . do
card :parser => :mag #=> <card parser='mag' params='read_data' />
end
If you are just interested in using the Widgets, you are encouraged to read the documentation for the various Widgets themselves. If you find that you need to program a new Widget in order to address some missing functionality, you can generate one easily with the command line generator:
ruby script/generate widget my_widget [entry_point1 entry_point2 . . .]
Constant Summary collapse
- RDOC_ACCESSORS =
These are the accessors that RDoc uses to define what a particular RTML-specific attribute maps to.
There are 3 kinds of accessors:
-
Shared variable
-
These are used to create variables that are different across parent objects, but which are shared between multiple Widgets (whether totally separate, or instances of the same) on the same instantiated parent. It’s a little complicated, but it’s critical in (for example) tracking TML variable definitions.
-
-
Valid parent
-
These are the names of TML elements (or “document” for document-level Widgets) that are allowed to instantiate the Widget in question by calling its entry points.
-
-
Entry point
-
These are instance methods defined by the Widget which are proxied into potential parent objects. Calling an entry point results in the configuration and eventual instantiation of the Widget which declared the entry point.
-
-
{ :shared => 'shared variable', :affects => 'valid parent', :entry_point => "entry point", }
- @@widget_id_tracker =
0
Instance Attribute Summary collapse
-
#parent ⇒ Object
readonly
Returns the value of attribute parent.
-
#source_type ⇒ Object
(also: #parent_type)
readonly
Returns the value of attribute source_type.
Instance Method Summary collapse
-
#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.
- #document ⇒ Object
-
#enable_subprocessing! ⇒ Object
Use this to enable subprocessing after it has already been disabled.
-
#initialize(parent) ⇒ Widget
constructor
A new instance of Widget.
-
#subprocessing_disabled? ⇒ Boolean
(also: #disable_subprocessing?)
Returns true if subprocessing has been disabled.
- #validate_parent(*options) ⇒ Object
-
#widget_id ⇒ Object
A guaranteed unique ID for this Widget.
Constructor Details
#initialize(parent) ⇒ Widget
Returns a new instance of Widget.
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/rtml/widget.rb', line 86 def initialize(parent) @parent = parent set_source_type! parent. << self # proxy parent methods into parent, unless they exist for widget already singleton_class = (class << self; self; end) (@parent.public_methods - self.public_methods).each do |proxy_method| # don't delegate entry points -- this addresses the infinite loop issue in which calling a method that's been # defined as an entry point but hasn't been created in the Widget itself would recurse back into the parent # object forever. unless entry_points.include? proxy_method singleton_class.send(:delegate, proxy_method, :to => :parent) end end self.class.shared_variables.each do |sv| unless @parent.instance_variable_get("@#{sv[:name]}") if sv[:default_value] if sv[:default_value].kind_of?(Class) @parent.instance_variable_set("@#{sv[:name]}", sv[:default_value].new) else @parent.instance_variable_set("@#{sv[:name]}", sv[:default_value].dup) end end end end end |
Instance Attribute Details
#parent ⇒ Object (readonly)
Returns the value of attribute parent.
66 67 68 |
# File 'lib/rtml/widget.rb', line 66 def parent @parent end |
#source_type ⇒ Object (readonly) Also known as: parent_type
Returns the value of attribute source_type.
67 68 69 |
# File 'lib/rtml/widget.rb', line 67 def source_type @source_type end |
Instance Method Details
#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.
There is a class method of the same name that has the same effect for the entire class; this instance method can disable subprocessing for particular instances, and is useful if you only want subprocessing under certain conditions.
135 136 137 |
# File 'lib/rtml/widget.rb', line 135 def disable_subprocessing! @disable_subprocessing = true end |
#document ⇒ Object
77 78 79 |
# File 'lib/rtml/widget.rb', line 77 def document @document ||= (parent.kind_of?(Rtml::Document) || !parent.respond_to?(:document) ? parent : parent.document) end |
#enable_subprocessing! ⇒ Object
Use this to enable subprocessing after it has already been disabled. See #disable_subprocessing!
123 124 125 |
# File 'lib/rtml/widget.rb', line 123 def enable_subprocessing! @disable_subprocessing = false end |
#subprocessing_disabled? ⇒ Boolean Also known as: disable_subprocessing?
Returns true if subprocessing has been disabled. See also #disable_subprocessing!
116 117 118 119 |
# File 'lib/rtml/widget.rb', line 116 def subprocessing_disabled? @disable_subprocessing = self.class.disable_subprocessing? unless defined?(@disable_subprocessing) @disable_subprocessing end |
#validate_parent(*options) ⇒ Object
70 71 72 73 74 75 |
# File 'lib/rtml/widget.rb', line 70 def validate_parent(*) = .flatten.collect { |o| o.kind_of?(String) ? o : o.to_s } unless .include?(parent.name) raise ArgumentError, "Expected parent to be one of #{.to_sentence(:language => :en)}; found #{parent.name}" end end |
#widget_id ⇒ Object
A guaranteed unique ID for this Widget.
82 83 84 |
# File 'lib/rtml/widget.rb', line 82 def @widget_id ||= (@@widget_id_tracker += 1) end |