Class: Wee::Component

Inherits:
Presenter show all
Defined in:
lib/wee/dialog.rb,
lib/wee/component.rb

Overview

The base class of all components. You should at least overwrite method #render in your own subclasses.

Direct Known Subclasses

BlockComponent, Dialog, RootComponent, Task

Defined Under Namespace

Classes: UnwindCall

Constant Summary collapse

NO_CHILDREN =
[].freeze

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Presenter

#render!, #renderer_class

Constructor Details

#initializeComponent

Initializes a newly created component.



39
40
# File 'lib/wee/component.rb', line 39

def initialize
end

Class Method Details

.dependsObject

Return an array of classes onto which the current component depends. Right now this is only used to determine the required ExternalResources.



32
33
34
# File 'lib/wee/component.rb', line 32

def self.depends
  []
end

.instanciate(*args, &block) ⇒ Object

Constructs a new instance of the component.

Overwrite this method when you want to use it both as a root component and as a non-root component. Here you can add neccessary decorations when used as root component, as for example a PageDecoration or a FormDecoration.

By default this methods adds no decoration.

See also class RootComponent.



24
25
26
# File 'lib/wee/component.rb', line 24

def self.instanciate(*args, &block)
  new(*args, &block)
end

Instance Method Details

#add_decoration(d) ⇒ Object

Adds decoration d to the decoration chain.

A global decoration is added in front of the decoration chain, a local decoration is added in front of all other local decorations but after all global decorations.

Returns: self



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/wee/component.rb', line 165

def add_decoration(d)
  if d.global?
    d.next = self.decoration
    self.decoration = d
  else
    last_global = nil
    each_decoration {|i| 
      if i.global?
        last_global = i
      else
        break
      end
    }
    if last_global.nil?
      # no global decorations specified -> add in front
      d.next = self.decoration
      self.decoration = d
    else
      # add after last_global
      d.next = last_global.next
      last_global.next = d
    end
  end

  return self
end

#childrenObject

Return all child components.

OVERWRITE this method and return all child components collected in an array.



92
93
94
# File 'lib/wee/component.rb', line 92

def children
  return NO_CHILDREN
end

#choose_from(items, caption = nil, selected_item = nil, &block) ⇒ Object



166
167
168
# File 'lib/wee/dialog.rb', line 166

def choose_from(items, caption=nil, selected_item=nil, &block)
  call! SingleSelectionDialog.new(items, caption, selected_item), &block
end

#confirm(question, &block) ⇒ Object



158
159
160
# File 'lib/wee/dialog.rb', line 158

def confirm(question, &block)
  call! ConfirmDialog.new(question), &block
end

#decorationObject



134
# File 'lib/wee/component.rb', line 134

def decoration() @decoration || self end

#decoration=(d) ⇒ Object


Decoration Methods




133
# File 'lib/wee/component.rb', line 133

def decoration=(d) @decoration = d end

#each_decorationObject

Iterates over all decorations (note that the component itself is excluded)



140
141
142
143
144
145
146
# File 'lib/wee/component.rb', line 140

def each_decoration # :yields: decoration
  d = @decoration
  while d and d != self
    yield d
    d = d.next
  end
end

#find_decorationObject

Searches a decoration in the decoration chain



151
152
153
154
# File 'lib/wee/component.rb', line 151

def find_decoration
   each_decoration {|d| yield d and return d }
   return nil
end

#inform(message, &block) ⇒ Object



162
163
164
# File 'lib/wee/dialog.rb', line 162

def inform(message, &block)
  call! InformDialog.new(message), &block
end

#process_callbacks(callbacks) ⇒ Object

Process and invoke all input callbacks specified for this component and all of it’s child components.

Returns the action callback to be invoked.



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/wee/component.rb', line 102

def process_callbacks(callbacks)
  callbacks.input_callbacks.each_triggered_call_with_value(self)

  action_callback = nil

  # process callbacks of all children
  for child in self.children
    if act = child.decoration.process_callbacks(callbacks)
      raise "Duplicate action callback" if action_callback
      action_callback = act
    end
  end

  if act = callbacks.action_callbacks.first_triggered(self)
    raise "Duplicate action callback" if action_callback
    action_callback = act
  end

  return action_callback
end

#remove_decoration(d) ⇒ Object

Remove decoration d from the decoration chain.

Returns the removed decoration or nil if it did not exist in the decoration chain.



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/wee/component.rb', line 198

def remove_decoration(d)
  if d == self.decoration  # 'd' is in front
    self.decoration = d.next
  else
    last_decoration = self.decoration
    next_decoration = nil
    loop do
      return nil if last_decoration == self or last_decoration.nil?
      next_decoration = last_decoration.next
      break if d == next_decoration
      last_decoration = next_decoration
    end
    last_decoration.next = d.next
  end
  d.next = nil  # decoration 'd' no longer is an owner of anything!
  return d
end

#remove_decoration_ifObject

Remove all decorations that match the block condition.

Example (removes all decorations of class HaloDecoration):

remove_decoration_if {|d| d.class == HaloDecoration}


223
224
225
226
227
# File 'lib/wee/component.rb', line 223

def remove_decoration_if # :yields: decoration
  to_remove = []
  each_decoration {|d| to_remove << d if yield d}
  to_remove.each {|d| remove_decoration(d)}
end

#render(r) ⇒ Object

This method renders the content of the component.

OVERWRITE this method in your own component classes to implement the view. By default this method does nothing!

r

An instance of class renderer_class()



51
52
# File 'lib/wee/component.rb', line 51

def render(r)
end

#state(s) ⇒ Object

Take snapshots of objects that should correctly be backtracked.

Backtracking means that you can go back in time of the components’ state. Therefore it is neccessary to take snapshots of those objects that want to participate in backtracking. Taking snapshots of the whole component tree would be too expensive and unflexible. Note that methods take_snapshot and restore_snapshot are called for those objects to take the snapshot (they behave like marshal_dump and marshal_load). Overwrite them if you want to define special behaviour.

By default only the decoration chain is backtracked. This is required to correctly backtrack called components. To disable backtracking of the decorations, change method Component#state_decoration to a no-operation:

def state_decoration(s)
  # nothing here
end
s

An object of class State



78
79
80
81
82
83
# File 'lib/wee/component.rb', line 78

def state(s)
  state_decoration(s)
  for child in self.children
    child.decoration.state(s)
  end
end