From 51ccd340f64a7e0e84a1c5fade6a4504a66990f5 Mon Sep 17 00:00:00 2001 From: xue <> Date: Sat, 4 Mar 2006 13:08:11 +0000 Subject: Added TMultiView and TView control. --- framework/Web/UI/WebControls/TMultiView.php | 350 ++++++++++++++++++++++++++++ 1 file changed, 350 insertions(+) create mode 100644 framework/Web/UI/WebControls/TMultiView.php (limited to 'framework') diff --git a/framework/Web/UI/WebControls/TMultiView.php b/framework/Web/UI/WebControls/TMultiView.php new file mode 100644 index 00000000..4208c6d0 --- /dev/null +++ b/framework/Web/UI/WebControls/TMultiView.php @@ -0,0 +1,350 @@ + + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Revision: $ $Date: $ + * @package System.Web.UI.WebControls + */ + +/** + * TMultiView class + * + * TMultiView serves as a container for a group of {@link TView} controls. + * The view collection can be retrieved by {@link getViews Views}. + * Each view contains child controls. TMultiView determines which view and its + * child controls are visible. At any time, at most one view is visible (called + * active). To make a view active, set {@link setActiveView ActiveView} or + * {@link setActiveViewIndex ActiveViewIndex}. + * + * TMultiView also responds to specific command events raised from button controls + * contained in current active view. A command event with name 'NextView' + * will cause TMultiView to make the next available view active. + * Other command names recognized by TMultiView include + * - PrevView : switch to previous view + * - SwitchViewID : switch to a view by its ID path + * - SwitchViewIndex : switch to a view by its index in the {@link getViews Views} collection. + * + * @author Qiang Xue + * @version $Revision: $ $Date: $ + * @package System.Web.UI.WebControls + * @since 3.0 + */ +class TMultiView extends TControl +{ + const CMD_NEXTVIEW='NextView'; + const CMD_PREVIOUSVIEW='PrevView'; + const CMD_SWITCHVIEWID='SwitchViewID'; + const CMD_SWITCHVIEWINDEX='SwitchViewIndex'; + + /** + * Processes an object that is created during parsing template. + * This method overrides the parent implementation by adding only {@link TView} + * controls as children. + * @param string|TComponent text string or component parsed and instantiated in template + * @see createdOnTemplate + * @throws TConfigurationException if controls other than {@link TView} is being added + */ + public function addParsedObject($object) + { + if($object instanceof TView) + $this->getControls()->add($object); + else if(!is_string($object)) + throw new TConfigurationException('multiview_view_required'); + } + + /** + * Creates a control collection object that is to be used to hold child controls + * @return TViewCollection control collection + */ + protected function createControlCollection() + { + return new TViewCollection($this); + } + + /** + * @return integer the zero-based index of the current view in the view collection. -1 if no active view. + */ + public function getActiveViewIndex() + { + if($this->_cachedActiveViewIndex>-1) + return $this->_cachedActiveViewIndex; + else + return $this->getControlState('ActiveViewIndex',-1); + } + + /** + * @param integer the zero-based index of the current view in the view collection. -1 if no active view. + * @throws TInvalidDataValueException if the view index is invalid + */ + public function setActiveViewIndex($value) + { + if(($index=TPropertyValue::ensureInteger($value))<0) + $index=-1; + $views=$this->getViews(); + $count=$views->getCount(); + if($view->getCount()===0 && $this->getControlStage()_cachedActiveViewIndex=$index; + else if($index<$count) + { + $this->setControlState('ActiveViewIndex',$index,-1); + $this->_cachedActiveViewIndex=-1; + if($index>=0) + $this->activateView($views->itemAt($index)); + } + else + throw new TInvalidDataValueException('multiview_activeviewindex_invalid',$index); + } + + /** + * @return TView the currently active view, null if no active view + * @throws TInvalidDataValueException if the current active view index is invalid + */ + public function getActiveView() + { + $index=$this->getActiveViewIndex(); + $views=$this->getViews(); + if($index>=$views->getCount()) + throw new TInvalidDataValueException('multiview_activeviewindex_invalid',$value); + if($index<0) + return null; + $view=$views->itemAt($index); + if(!$view->getActive()) + $this->activateView($view); + return $view; + } + + /** + * @param TView the view to be activated + * @throws TInvalidOperationException if the view is not in the view collection + */ + public function setActiveView($view) + { + if(($index=$this->getViews()->indexOf($view))>=0) + $this->setActiveViewIndex($index); + else + throw new TInvalidOperationException('multiview_view_inexistent'); + } + + /** + * Activates the specified view. + * If there is any view currently active, it will be deactivated. + * @param TView the view to be activated + */ + protected function activateView($view) + { + if($view->getActive()) + return; + $triggerEvent=$this->getControlStage()>=TControl::CS_STATE_LOADED || !$this->getPage()->getIsPostBack(); + foreach($this->getViews() as $v) + { + if($v===$view) + { + $view->setActive(true); + if($triggerEvent) + $view->onActivate(null); + $this->onActiveViewChanged(null); + } + else if($v->getActive()) + { + $v->setActive(false); + if($triggerEvent) + $v->onDeactivate(null); + } + } + } + + /** + * @return TViewCollection the view collection + */ + public function getViews() + { + return $this->getControls(); + } + + /** + * Initializes the active view if any. + * This method overrides the parent implementation. + * @param mixed event parameter + */ + public function onInit($param) + { + parent::onInit($param); + if($this->_cachedActiveViewIndex>=0) + $this->setActiveViewIndex($this->_cachedActiveViewIndex); + } + + /** + * Raises OnActiveViewChanged event. + * The event is raised when the currently active view is changed to a new one + * @param mixed event parameter + */ + public function onActiveViewChanged($param) + { + $this->raiseEvent('OnActiveViewChanged',$this,$param); + } + + /** + * Processes the events bubbled from child controls. + * The method handles view-related command events. + * @param TControl sender of the event + * @param mixed event parameter + * @return boolean whether this event is handled + */ + public function onBubbleEvent($sender,$param) + { + if($param instanceof TCommandEventParameter) + { + switch($param->getCommandName()) + { + case self::CMD_NEXTVIEW: + if(($index=$this->getActiveViewIndex())<$this->getViews()->getCount()-1) + $this->setActiveViewIndex($index+1); + else + $this->setActiveViewIndex(-1); + return true; + case self::CMD_PREVIOUSVIEW: + if(($index=$this->getActiveViewIndex())>=0) + $this->setActiveViewIndex($index-1); + return true; + case self::CMD_SWITCHVIEWID: + $view=$this->findControl($param->getCommandParameter()); + if($view!==null && $view->getParent()===$this) + { + $this->setActiveView($view); + return true; + } + else + throw new TInvalidDataValueException('multiview_viewid_invalid'); + case self::CMD_SWITCHVIEWINDEX: + $index=TPropertyValue::ensureInteger($param->getCommandParameter()); + $this->setActiveViewIndex($index); + return true; + } + } + return false; + } + + /** + * Renders the currently active view. + * @param THtmlWriter the writer for the rendering purpose. + */ + public function render($writer) + { + if(($view=$this->getActiveView())!==null) + $view->renderControl($writer); + } +} + +/** + * TViewCollection class. + * TViewCollection represents a collection that only takes {@link TView} instances + * as collection elements. + * @author Qiang Xue + * @version $Revision: $ $Date: $ + * @package System.Web.UI.WebControls + * @since 3.0 + */ +class TViewCollection extends TControlCollection +{ + /** + * Inserts an item at the specified position. + * This overrides the parent implementation by ensuring only {@link TView} + * controls be added into the collection. + * @param integer the speicified position. + * @param mixed new item + * @throws TInvalidDataTypeException if the item to be inserted is neither a string nor a TControl. + */ + public function insertAt($index,$item) + { + if($item instanceof TView) + parent::insertAt($index,$item); + else + throw new TInvalidDataTypeException('viewcollection_view_required'); + } +} + +/** + * TView class + * + * TView is a container for a group of controls. TView must be contained + * within a {@link TMultiView} control in which only one view can be active + * at one time. + * + * To activate a view, set {@link setActive Active} to true. + * When a view is activated, it raises {@link onActivate OnActivate} event; + * and when a view is deactivated, it raises {@link onDeactivate OnDeactivate}. + * + * @author Qiang Xue + * @version $Revision: $ $Date: $ + * @package System.Web.UI.WebControls + * @since 3.0 + */ +class TView extends TControl +{ + private $_active=false; + + /** + * Raises OnActivate event. + * @param TEventParameter event parameter + */ + public function onActivate($param) + { + $this->raiseEvent('Activate',$this,$param); + } + + /** + * Raises OnDeactivate event. + * @param TEventParameter event parameter + */ + public function onDeactivate($param) + { + $this->raiseEvent('OnDeactivate',$this,$param); + } + + /** + * @return boolean whether this view is active. Defaults to false. + */ + public function getActive() + { + return $this->_active; + } + + /** + * @param boolean whether this view is active. + */ + public function setActive($value) + { + $value=TPropertyValue::ensureBoolean($value); + $this->_active=$value + parent::setVisible($value); + } + + /** + * @return boolean whether this view is visible. + * The view is visible if it is active and its parent is visible. + */ + public function getVisible() + { + if(($parent=$this->getParent())===null) + return $this->getActive(); + else if($this->getActive()) + return $parent->getVisible(); + else + return false; + } + + /** + * @param boolean + * @throw TInvalidOperationException whenever this method is invoked. + */ + public function setVisible($value) + { + throw new TInvalidOperationException('view_visible_readonly'); + } +} + +?> \ No newline at end of file -- cgit v1.2.3