Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * TMultiView and TView class file.
4
 *
5
 * @author Qiang Xue <qiang.xue@gmail.com>
6
 * @link http://www.pradosoft.com/
7
 * @copyright Copyright &copy; 2005-2008 PradoSoft
8
 * @license http://www.pradosoft.com/license/
9
 * @version $Id: TMultiView.php 2541 2008-10-21 15:05:13Z qiang.xue $
10
 * @package System.Web.UI.WebControls
11
 */
12
 
13
/**
14
 * TMultiView class
15
 *
16
 * TMultiView serves as a container for a group of {@link TView} controls.
17
 * The view collection can be retrieved by {@link getViews Views}.
18
 * Each view contains child controls. TMultiView determines which view and its
19
 * child controls are visible. At any time, at most one view is visible (called
20
 * active). To make a view active, set {@link setActiveView ActiveView} or
21
 * {@link setActiveViewIndex ActiveViewIndex}.
22
 *
23
 * TMultiView also responds to specific command events raised from button controls
24
 * contained in current active view. A command event with name 'NextView'
25
 * will cause TMultiView to make the next available view active.
26
 * Other command names recognized by TMultiView include
27
 * - PreviousView : switch to previous view
28
 * - SwitchViewID : switch to a view by its ID path
29
 * - SwitchViewIndex : switch to a view by its index in the {@link getViews Views} collection.
30
 *
31
 * TMultiView raises {@link OnActiveViewChanged OnActiveViewChanged} event
32
 * when its active view is changed during a postback.
33
 *
34
 * @author Qiang Xue <qiang.xue@gmail.com>
35
 * @version $Id: TMultiView.php 2541 2008-10-21 15:05:13Z qiang.xue $
36
 * @package System.Web.UI.WebControls
37
 * @since 3.0
38
 */
39
class TMultiView extends TControl
40
{
41
	const CMD_NEXTVIEW='NextView';
42
	const CMD_PREVIOUSVIEW='PreviousView';
43
	const CMD_SWITCHVIEWID='SwitchViewID';
44
	const CMD_SWITCHVIEWINDEX='SwitchViewIndex';
45
	private $_cachedActiveViewIndex=-1;
46
	private $_ignoreBubbleEvents=false;
47
 
48
	/**
49
	 * Processes an object that is created during parsing template.
50
	 * This method overrides the parent implementation by adding only {@link TView}
51
	 * controls as children.
52
	 * @param string|TComponent text string or component parsed and instantiated in template
53
	 * @see createdOnTemplate
54
	 * @throws TConfigurationException if controls other than {@link TView} is being added
55
	 */
56
	public function addParsedObject($object)
57
	{
58
		if($object instanceof TView)
59
			$this->getControls()->add($object);
60
		else if(!is_string($object))
61
			throw new TConfigurationException('multiview_view_required');
62
	}
63
 
64
	/**
65
	 * Creates a control collection object that is to be used to hold child controls
66
	 * @return TViewCollection control collection
67
	 */
68
	protected function createControlCollection()
69
	{
70
		return new TViewCollection($this);
71
	}
72
 
73
	/**
74
	 * @return integer the zero-based index of the current view in the view collection. -1 if no active view. Default is -1.
75
	 */
76
	public function getActiveViewIndex()
77
	{
78
		if($this->_cachedActiveViewIndex>-1)
79
			return $this->_cachedActiveViewIndex;
80
		else
81
			return $this->getControlState('ActiveViewIndex',-1);
82
	}
83
 
84
	/**
85
	 * @param integer the zero-based index of the current view in the view collection. -1 if no active view.
86
	 * @throws TInvalidDataValueException if the view index is invalid
87
	 */
88
	public function setActiveViewIndex($value)
89
	{
90
		if(($index=TPropertyValue::ensureInteger($value))<0)
91
			$index=-1;
92
		$views=$this->getViews();
93
		$count=$views->getCount();
94
		if($count===0 && $this->getControlStage()<TControl::CS_CHILD_INITIALIZED)
95
			$this->_cachedActiveViewIndex=$index;
96
		else if($index<$count)
97
		{
98
			$this->setControlState('ActiveViewIndex',$index,-1);
99
			$this->_cachedActiveViewIndex=-1;
100
			if($index>=0)
101
				$this->activateView($views->itemAt($index),true);
102
		}
103
		else
104
			throw new TInvalidDataValueException('multiview_activeviewindex_invalid',$index);
105
	}
106
 
107
	/**
108
	 * @return TView the currently active view, null if no active view
109
	 * @throws TInvalidDataValueException if the current active view index is invalid
110
	 */
111
	public function getActiveView()
112
	{
113
		$index=$this->getActiveViewIndex();
114
		$views=$this->getViews();
115
		if($index>=$views->getCount())
116
			throw new TInvalidDataValueException('multiview_activeviewindex_invalid',$index);
117
		if($index<0)
118
			return null;
119
		$view=$views->itemAt($index);
120
		if(!$view->getActive())
121
			$this->activateView($view,false);
122
		return $view;
123
	}
124
 
125
	/**
126
	 * @param TView the view to be activated
127
	 * @throws TInvalidOperationException if the view is not in the view collection
128
	 */
129
	public function setActiveView($view)
130
	{
131
		if(($index=$this->getViews()->indexOf($view))>=0)
132
			$this->setActiveViewIndex($index);
133
		else
134
			throw new TInvalidOperationException('multiview_view_inexistent');
135
	}
136
 
137
	/**
138
	 * Activates the specified view.
139
	 * If there is any view currently active, it will be deactivated.
140
	 * @param TView the view to be activated
141
	 * @param boolean whether to trigger OnActiveViewChanged event.
142
	 */
143
	protected function activateView($view,$triggerViewChangedEvent=true)
144
	{
145
		if($view->getActive())
146
			return;
147
		$triggerEvent=$triggerViewChangedEvent && ($this->getControlStage()>=TControl::CS_STATE_LOADED || ($this->getPage() && !$this->getPage()->getIsPostBack()));
148
		foreach($this->getViews() as $v)
149
		{
150
			if($v===$view)
151
			{
152
				$view->setActive(true);
153
				if($triggerEvent)
154
				{
155
					$view->onActivate(null);
156
					$this->onActiveViewChanged(null);
157
				}
158
			}
159
			else if($v->getActive())
160
			{
161
				$v->setActive(false);
162
				if($triggerEvent)
163
					$v->onDeactivate(null);
164
			}
165
		}
166
	}
167
 
168
	/**
169
	 * @return TViewCollection the view collection
170
	 */
171
	public function getViews()
172
	{
173
		return $this->getControls();
174
	}
175
 
176
	/**
177
	 * Makes the multiview ignore all bubbled events.
178
	 * This is method is used internally by framework and control
179
	 * developers.
180
	 */
181
	public function ignoreBubbleEvents()
182
	{
183
		$this->_ignoreBubbleEvents=true;
184
	}
185
 
186
	/**
187
	 * Initializes the active view if any.
188
	 * This method overrides the parent implementation.
189
	 * @param TEventParameter event parameter
190
	 */
191
	public function onInit($param)
192
	{
193
		parent::onInit($param);
194
		if($this->_cachedActiveViewIndex>=0)
195
			$this->setActiveViewIndex($this->_cachedActiveViewIndex);
196
	}
197
 
198
	/**
199
	 * Raises <b>OnActiveViewChanged</b> event.
200
	 * The event is raised when the currently active view is changed to a new one
201
	 * @param TEventParameter event parameter
202
	 */
203
	public function onActiveViewChanged($param)
204
	{
205
		$this->raiseEvent('OnActiveViewChanged',$this,$param);
206
	}
207
 
208
	/**
209
	 * Processes the events bubbled from child controls.
210
	 * The method handles view-related command events.
211
	 * @param TControl sender of the event
212
	 * @param mixed event parameter
213
	 * @return boolean whether this event is handled
214
	 */
215
	public function bubbleEvent($sender,$param)
216
	{
217
		if(!$this->_ignoreBubbleEvents && ($param instanceof TCommandEventParameter))
218
		{
219
			switch($param->getCommandName())
220
			{
221
				case self::CMD_NEXTVIEW:
222
					if(($index=$this->getActiveViewIndex())<$this->getViews()->getCount()-1)
223
						$this->setActiveViewIndex($index+1);
224
					else
225
						$this->setActiveViewIndex(-1);
226
					return true;
227
				case self::CMD_PREVIOUSVIEW:
228
					if(($index=$this->getActiveViewIndex())>=0)
229
						$this->setActiveViewIndex($index-1);
230
					return true;
231
				case self::CMD_SWITCHVIEWID:
232
					$view=$this->findControl($param->getCommandParameter());
233
					if($view!==null && $view->getParent()===$this)
234
					{
235
						$this->setActiveView($view);
236
						return true;
237
					}
238
					else
239
						throw new TInvalidDataValueException('multiview_viewid_invalid');
240
				case self::CMD_SWITCHVIEWINDEX:
241
					$index=TPropertyValue::ensureInteger($param->getCommandParameter());
242
					$this->setActiveViewIndex($index);
243
					return true;
244
			}
245
		}
246
		return false;
247
	}
248
 
249
	/**
250
	 * Loads state into the wizard.
251
	 * This method is invoked by the framework when the control state is being saved.
252
	 */
253
	public function loadState()
254
	{
255
		// a dummy call to ensure the view is activated
256
		$this->getActiveView();
257
	}
258
 
259
	/**
260
	 * Renders the currently active view.
261
	 * @param THtmlWriter the writer for the rendering purpose.
262
	 */
263
	public function render($writer)
264
	{
265
		if(($view=$this->getActiveView())!==null)
266
			$view->renderControl($writer);
267
	}
268
}
269
 
270
/**
271
 * TViewCollection class.
272
 * TViewCollection represents a collection that only takes {@link TView} instances
273
 * as collection elements.
274
 * @author Qiang Xue <qiang.xue@gmail.com>
275
 * @version $Id: TMultiView.php 2541 2008-10-21 15:05:13Z qiang.xue $
276
 * @package System.Web.UI.WebControls
277
 * @since 3.0
278
 */
279
class TViewCollection extends TControlCollection
280
{
281
	/**
282
	 * Inserts an item at the specified position.
283
	 * This overrides the parent implementation by ensuring only {@link TView}
284
	 * controls be added into the collection.
285
	 * @param integer the speicified position.
286
	 * @param mixed new item
287
	 * @throws TInvalidDataTypeException if the item to be inserted is neither a string nor a TControl.
288
	 */
289
	public function insertAt($index,$item)
290
	{
291
		if($item instanceof TView)
292
			parent::insertAt($index,$item);
293
		else
294
			throw new TInvalidDataTypeException('viewcollection_view_required');
295
	}
296
}
297
 
298
/**
299
 * TView class
300
 *
301
 * TView is a container for a group of controls. TView must be contained
302
 * within a {@link TMultiView} control in which only one view can be active
303
 * at one time.
304
 *
305
 * To activate a view, set {@link setActive Active} to true.
306
 * When a view is activated, it raises {@link onActivate OnActivate} event;
307
 * and when a view is deactivated, it raises {@link onDeactivate OnDeactivate}.
308
 *
309
 * @author Qiang Xue <qiang.xue@gmail.com>
310
 * @version $Id: TMultiView.php 2541 2008-10-21 15:05:13Z qiang.xue $
311
 * @package System.Web.UI.WebControls
312
 * @since 3.0
313
 */
314
class TView extends TControl
315
{
316
	private $_active=false;
317
 
318
	/**
319
	 * Raises <b>OnActivate</b> event.
320
	 * @param TEventParameter event parameter
321
	 */
322
	public function onActivate($param)
323
	{
324
		$this->raiseEvent('OnActivate',$this,$param);
325
	}
326
 
327
	/**
328
	 * Raises <b>OnDeactivate</b> event.
329
	 * @param TEventParameter event parameter
330
	 */
331
	public function onDeactivate($param)
332
	{
333
		$this->raiseEvent('OnDeactivate',$this,$param);
334
	}
335
 
336
	/**
337
	 * @return boolean whether this view is active. Defaults to false.
338
	 */
339
	public function getActive()
340
	{
341
		return $this->_active;
342
	}
343
 
344
	/**
345
	 * @param boolean whether this view is active.
346
	 */
347
	public function setActive($value)
348
	{
349
		$value=TPropertyValue::ensureBoolean($value);
350
		$this->_active=$value;
351
		parent::setVisible($value);
352
	}
353
 
354
	/**
355
	 * @param boolean whether the parents should also be checked if visible
356
	 * @return boolean whether this view is visible.
357
	 * The view is visible if it is active and its parent is visible.
358
	 */
359
	public function getVisible($checkParents=true)
360
	{
361
		if(($parent=$this->getParent())===null)
362
			return $this->getActive();
363
		else if($this->getActive())
364
			return $parent->getVisible($checkParents);
365
		else
366
			return false;
367
	}
368
 
369
	/**
370
	 * @param boolean
371
	 * @throws TInvalidOperationException whenever this method is invoked.
372
	 */
373
	public function setVisible($value)
374
	{
375
		throw new TInvalidOperationException('view_visible_readonly');
376
	}
377
}
378