summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitattributes1
-rw-r--r--framework/Web/UI/WebControls/TWebControl.php937
-rw-r--r--framework/Web/UI/WebControls/TWebControlDecorator.php339
3 files changed, 843 insertions, 434 deletions
diff --git a/.gitattributes b/.gitattributes
index fe708dd6..9ec66334 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -2893,6 +2893,7 @@ framework/Web/UI/WebControls/TTextProcessor.php -text
framework/Web/UI/WebControls/TValidationSummary.php -text
framework/Web/UI/WebControls/TWebControl.php -text
framework/Web/UI/WebControls/TWebControlAdapter.php -text
+framework/Web/UI/WebControls/TWebControlDecorator.php -text
framework/Web/UI/WebControls/TWizard.php -text
framework/Web/UI/WebControls/TWizardNavigationButtonStyle.php -text
framework/Web/UI/WebControls/TXmlTransform.php -text
diff --git a/framework/Web/UI/WebControls/TWebControl.php b/framework/Web/UI/WebControls/TWebControl.php
index 2e1899ad..de9e4868 100644
--- a/framework/Web/UI/WebControls/TWebControl.php
+++ b/framework/Web/UI/WebControls/TWebControl.php
@@ -1,434 +1,503 @@
-<?php
-/**
- * TWebControl class file.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005-2008 PradoSoft
- * @license http://www.pradosoft.com/license/
- * @version $Id$
- * @package System.Web.UI.WebControls
- */
-
-/**
- * Includes TStyle and TWebAdapter definition
- */
-Prado::using('System.Web.UI.WebControls.TStyle');
-Prado::using('System.Web.UI.WebControls.TWebControlAdapter');
-
-/**
- * TWebControl class
- *
- * TWebControl is the base class for controls that share a common set
- * of UI-related properties and methods. TWebControl-derived controls
- * are usually associated with HTML tags. They thus have tag name, attributes
- * and body contents. You can override {@link getTagName} to specify the tag name,
- * {@link addAttributesToRender} to specify the attributes to be rendered,
- * and {@link renderContents} to customize the body content rendering.
- * TWebControl encapsulates a set of properties related with CSS style fields,
- * such as {@link getBackColor BackColor}, {@link getBorderWidth BorderWidth}, etc.
- *
- * Subclasses of TWebControl typically needs to override {@link addAttributesToRender}
- * and {@link renderContents}. The former is used to render the attributes
- * of the HTML tag associated with the control, while the latter is to render
- * the body contents enclosed within the HTML tag.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Web.UI.WebControls
- * @since 3.0
- */
-class TWebControl extends TControl implements IStyleable
-{
- /**
- * Copies basic control attributes from another control.
- * Properties including AccessKey, ToolTip, TabIndex, Enabled
- * and Attributes are copied.
- * @param TWebControl source control
- */
- public function copyBaseAttributes(TWebControl $control)
- {
- $this->setAccessKey($control->getAccessKey());
- $this->setToolTip($control->getToolTip());
- $this->setTabIndex($control->getTabIndex());
- if(!$control->getEnabled())
- $this->setEnabled(false);
- if($control->getHasAttributes())
- $this->getAttributes()->copyFrom($control->getAttributes());
- }
-
- /**
- * @return string the access key of the control
- */
- public function getAccessKey()
- {
- return $this->getViewState('AccessKey','');
- }
-
- /**
- * Sets the access key of the control.
- * Only one-character string can be set, or an exception will be raised.
- * Pass in an empty string if you want to disable access key.
- * @param string the access key to be set
- * @throws TInvalidDataValueException if the access key is specified with more than one character
- */
- public function setAccessKey($value)
- {
- if(strlen($value)>1)
- throw new TInvalidDataValueException('webcontrol_accesskey_invalid',get_class($this),$value);
- $this->setViewState('AccessKey',$value,'');
- }
-
- /**
- * @return string the background color of the control
- */
- public function getBackColor()
- {
- if($style=$this->getViewState('Style',null))
- return $style->getBackColor();
- else
- return '';
- }
-
- /**
- * @param string the background color of the control
- */
- public function setBackColor($value)
- {
- $this->getStyle()->setBackColor($value);
- }
-
- /**
- * @return string the border color of the control
- */
- public function getBorderColor()
- {
- if($style=$this->getViewState('Style',null))
- return $style->getBorderColor();
- else
- return '';
- }
-
- /**
- * @param string the border color of the control
- */
- public function setBorderColor($value)
- {
- $this->getStyle()->setBorderColor($value);
- }
-
- /**
- * @return string the border style of the control
- */
- public function getBorderStyle()
- {
- if($style=$this->getViewState('Style',null))
- return $style->getBorderStyle();
- else
- return '';
- }
-
- /**
- * @param string the border style of the control
- */
- public function setBorderStyle($value)
- {
- $this->getStyle()->setBorderStyle($value);
- }
-
- /**
- * @return string the border width of the control
- */
- public function getBorderWidth()
- {
- if($style=$this->getViewState('Style',null))
- return $style->getBorderWidth();
- else
- return '';
- }
-
- /**
- * @param string the border width of the control
- */
- public function setBorderWidth($value)
- {
- $this->getStyle()->setBorderWidth($value);
- }
-
- /**
- * @return TFont the font of the control
- */
- public function getFont()
- {
- return $this->getStyle()->getFont();
- }
-
- /**
- * @return string the foreground color of the control
- */
- public function getForeColor()
- {
- if($style=$this->getViewState('Style',null))
- return $style->getForeColor();
- else
- return '';
- }
-
- /**
- * @param string the foreground color of the control
- */
- public function setForeColor($value)
- {
- $this->getStyle()->setForeColor($value);
- }
-
- /**
- * @return string the height of the control
- */
- public function getHeight()
- {
- if($style=$this->getViewState('Style',null))
- return $style->getHeight();
- else
- return '';
- }
-
- /**
- * @param TDisplayStyle display style of the control, default is TDisplayStyle::Fixed
- */
- public function setDisplay($value)
- {
- $this->getStyle()->setDisplayStyle($value);
- }
-
- /**
- * @return TDisplayStyle display style of the control, default is TDisplayStyle::Fixed
- */
- public function getDisplay()
- {
- return $this->getStyle()->getDisplayStyle();
- }
-
- /**
- * @param string the css class of the control
- */
- public function setCssClass($value)
- {
- $this->getStyle()->setCssClass($value);
- }
-
- /**
- * @return string the css class of the control
- */
- public function getCssClass()
- {
- if($style=$this->getViewState('Style',null))
- return $style->getCssClass();
- else
- return '';
- }
-
- /**
- * @param string the height of the control
- */
- public function setHeight($value)
- {
- $this->getStyle()->setHeight($value);
- }
-
- /**
- * @return boolean whether the control has defined any style information
- */
- public function getHasStyle()
- {
- return $this->getViewState('Style',null)!==null;
- }
-
- /**
- * Creates a style object to be used by the control.
- * This method may be overriden by controls to provide customized style.
- * @return TStyle the default style created for TWebControl
- */
- protected function createStyle()
- {
- return new TStyle;
- }
-
- /**
- * @return TStyle the object representing the css style of the control
- */
- public function getStyle()
- {
- if($style=$this->getViewState('Style',null))
- return $style;
- else
- {
- $style=$this->createStyle();
- $this->setViewState('Style',$style,null);
- return $style;
- }
- }
-
- /**
- * Sets the css style string of the control.
- * The style string will be prefixed to the styles set via other control properties (e.g. Height, Width).
- * @param string the css style string
- * @throws TInvalidDataValueException if the parameter is not a string
- */
- public function setStyle($value)
- {
- if(is_string($value))
- $this->getStyle()->setCustomStyle($value);
- else
- throw new TInvalidDataValueException('webcontrol_style_invalid',get_class($this));
- }
-
- /**
- * Removes all style data.
- */
- public function clearStyle()
- {
- $this->clearViewState('Style');
- }
-
- /**
- * @return integer the tab index of the control
- */
- public function getTabIndex()
- {
- return $this->getViewState('TabIndex',0);
- }
-
- /**
- * Sets the tab index of the control.
- * Pass 0 if you want to disable tab index.
- * @param integer the tab index to be set
- */
- public function setTabIndex($value)
- {
- $this->setViewState('TabIndex',TPropertyValue::ensureInteger($value),0);
- }
-
- /**
- * Returns the tag name used for this control.
- * By default, the tag name is 'span'.
- * You can override this method to provide customized tag names.
- * @return string tag name of the control to be rendered
- */
- protected function getTagName()
- {
- return 'span';
- }
-
- /**
- * @return string the tooltip of the control
- */
- public function getToolTip()
- {
- return $this->getViewState('ToolTip','');
- }
-
- /**
- * Sets the tooltip of the control.
- * Pass an empty string if you want to disable tooltip.
- * @param string the tooltip to be set
- */
- public function setToolTip($value)
- {
- $this->setViewState('ToolTip',$value,'');
- }
-
- /**
- * @return string the width of the control
- */
- public function getWidth()
- {
- if($style=$this->getViewState('Style',null))
- return $style->getWidth();
- else
- return '';
- }
-
- /**
- * @param string the width of the control
- */
- public function setWidth($value)
- {
- $this->getStyle()->setWidth($value);
- }
-
- /**
- * Adds attribute name-value pairs to renderer.
- * By default, the method will render 'id', 'accesskey', 'disabled',
- * 'tabindex', 'title' and all custom attributes.
- * The method can be overriden to provide customized attribute rendering.
- * @param THtmlWriter the writer used for the rendering purpose
- */
- protected function addAttributesToRender($writer)
- {
- if($this->getID()!=='')
- $writer->addAttribute('id',$this->getClientID());
- if(($accessKey=$this->getAccessKey())!=='')
- $writer->addAttribute('accesskey',$accessKey);
- if(!$this->getEnabled())
- $writer->addAttribute('disabled','disabled');
- if(($tabIndex=$this->getTabIndex())>0)
- $writer->addAttribute('tabindex',"$tabIndex");
- if(($toolTip=$this->getToolTip())!=='')
- $writer->addAttribute('title',$toolTip);
- if($style=$this->getViewState('Style',null))
- $style->addAttributesToRender($writer);
- if($this->getHasAttributes())
- {
- foreach($this->getAttributes() as $name=>$value)
- $writer->addAttribute($name,$value);
- }
- }
-
- /**
- * Renders the control.
- * This method overrides the parent implementation by replacing it with
- * the following sequence:
- * - {@link renderBeginTag}
- * - {@link renderContents}
- * - {@link renderEndTag}
- * @param THtmlWriter the writer used for the rendering purpose
- */
- public function render($writer)
- {
- $this->renderBeginTag($writer);
- $this->renderContents($writer);
- $this->renderEndTag($writer);
- }
-
- /**
- * Renders the openning tag for the control (including attributes)
- * @param THtmlWriter the writer used for the rendering purpose
- */
- public function renderBeginTag($writer)
- {
- $this->addAttributesToRender($writer);
- $writer->renderBeginTag($this->getTagName());
- }
-
- /**
- * Renders the body content enclosed between the control tag.
- * By default, child controls and text strings will be rendered.
- * You can override this method to provide customized content rendering.
- * @param THtmlWriter the writer used for the rendering purpose
- */
- public function renderContents($writer)
- {
- parent::renderChildren($writer);
- }
-
- /**
- * Renders the closing tag for the control
- * @param THtmlWriter the writer used for the rendering purpose
- */
- public function renderEndTag($writer)
- {
- $writer->renderEndTag();
- }
-}
-
+<?php
+/**
+ * TWebControl class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2005-2010 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Id$
+ * @package System.Web.UI.WebControls
+ */
+
+/**
+ * Includes TStyle and TWebAdapter definition
+ */
+Prado::using('System.Web.UI.WebControls.TStyle');
+Prado::using('System.Web.UI.WebControls.TWebControlAdapter');
+Prado::using('System.Web.UI.WebControls.TWebControlDecorator');
+
+/**
+ * TWebControl class
+ *
+ * TWebControl is the base class for controls that share a common set
+ * of UI-related properties and methods. TWebControl-derived controls
+ * are usually associated with HTML tags. They thus have tag name, attributes
+ * and body contents. You can override {@link getTagName} to specify the tag name,
+ * {@link addAttributesToRender} to specify the attributes to be rendered,
+ * and {@link renderContents} to customize the body content rendering.
+ * TWebControl encapsulates a set of properties related with CSS style fields,
+ * such as {@link getBackColor BackColor}, {@link getBorderWidth BorderWidth}, etc.
+ *
+ * Subclasses of TWebControl typically needs to override {@link addAttributesToRender}
+ * and {@link renderContents}. The former is used to render the attributes
+ * of the HTML tag associated with the control, while the latter is to render
+ * the body contents enclosed within the HTML tag.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id$
+ * @package System.Web.UI.WebControls
+ * @since 3.0
+ */
+class TWebControl extends TControl implements IStyleable
+{
+ /**
+ * @var boolean ensures the inclusion the id in the tag rendering.
+ */
+ private $_ensureid=false;
+
+ /**
+ * @var TWebControlDecorator this render things before and after both the open and close tag
+ */
+ protected $_decorator;
+
+
+ /**
+ * Subclasses can override getEnsureId or just set this property. eg. If your subclass
+ * control does work with javascript and your class wants to flag that it requires an id
+ * to operate properly. Once set to true, it stays that way.
+ * @param boolean pass true to enable enforcement of the tag attribute id.
+ */
+ public function setEnsureId($value)
+ {
+ $this->_ensureid |= TPropertyValue::ensureBoolean($value);
+ }
+
+ /**
+ * @return whether this web control must have an id
+ */
+ public function getEnsureId()
+ {
+ return $this->_ensureid;
+ }
+
+ /**
+ * @return TWebControlDecorator
+ */
+ public function getDecorator($create=true)
+ {
+ if($create && !$this->_decorator)
+ $this->_decorator = Prado::createComponent('TWebControlDecorator', $this);
+ return $this->_decorator;
+ }
+
+ /**
+ * Copies basic control attributes from another control.
+ * Properties including AccessKey, ToolTip, TabIndex, Enabled
+ * and Attributes are copied.
+ * @param TWebControl source control
+ */
+ public function copyBaseAttributes(TWebControl $control)
+ {
+ $this->setAccessKey($control->getAccessKey());
+ $this->setToolTip($control->getToolTip());
+ $this->setTabIndex($control->getTabIndex());
+ if(!$control->getEnabled())
+ $this->setEnabled(false);
+ if($control->getHasAttributes())
+ $this->getAttributes()->copyFrom($control->getAttributes());
+ }
+
+ /**
+ * @return string the access key of the control
+ */
+ public function getAccessKey()
+ {
+ return $this->getViewState('AccessKey','');
+ }
+
+ /**
+ * Sets the access key of the control.
+ * Only one-character string can be set, or an exception will be raised.
+ * Pass in an empty string if you want to disable access key.
+ * @param string the access key to be set
+ * @throws TInvalidDataValueException if the access key is specified with more than one character
+ */
+ public function setAccessKey($value)
+ {
+ if(strlen($value)>1)
+ throw new TInvalidDataValueException('webcontrol_accesskey_invalid',get_class($this),$value);
+ $this->setViewState('AccessKey',$value,'');
+ }
+
+ /**
+ * @return string the background color of the control
+ */
+ public function getBackColor()
+ {
+ if($style=$this->getViewState('Style',null))
+ return $style->getBackColor();
+ else
+ return '';
+ }
+
+ /**
+ * @param string the background color of the control
+ */
+ public function setBackColor($value)
+ {
+ $this->getStyle()->setBackColor($value);
+ }
+
+ /**
+ * @return string the border color of the control
+ */
+ public function getBorderColor()
+ {
+ if($style=$this->getViewState('Style',null))
+ return $style->getBorderColor();
+ else
+ return '';
+ }
+
+ /**
+ * @param string the border color of the control
+ */
+ public function setBorderColor($value)
+ {
+ $this->getStyle()->setBorderColor($value);
+ }
+
+ /**
+ * @return string the border style of the control
+ */
+ public function getBorderStyle()
+ {
+ if($style=$this->getViewState('Style',null))
+ return $style->getBorderStyle();
+ else
+ return '';
+ }
+
+ /**
+ * @param string the border style of the control
+ */
+ public function setBorderStyle($value)
+ {
+ $this->getStyle()->setBorderStyle($value);
+ }
+
+ /**
+ * @return string the border width of the control
+ */
+ public function getBorderWidth()
+ {
+ if($style=$this->getViewState('Style',null))
+ return $style->getBorderWidth();
+ else
+ return '';
+ }
+
+ /**
+ * @param string the border width of the control
+ */
+ public function setBorderWidth($value)
+ {
+ $this->getStyle()->setBorderWidth($value);
+ }
+
+ /**
+ * @return TFont the font of the control
+ */
+ public function getFont()
+ {
+ return $this->getStyle()->getFont();
+ }
+
+ /**
+ * @return string the foreground color of the control
+ */
+ public function getForeColor()
+ {
+ if($style=$this->getViewState('Style',null))
+ return $style->getForeColor();
+ else
+ return '';
+ }
+
+ /**
+ * @param string the foreground color of the control
+ */
+ public function setForeColor($value)
+ {
+ $this->getStyle()->setForeColor($value);
+ }
+
+ /**
+ * @return string the height of the control
+ */
+ public function getHeight()
+ {
+ if($style=$this->getViewState('Style',null))
+ return $style->getHeight();
+ else
+ return '';
+ }
+
+ /**
+ * @param TDisplayStyle display style of the control, default is TDisplayStyle::Fixed
+ */
+ public function setDisplay($value)
+ {
+ $this->getStyle()->setDisplayStyle($value);
+ }
+
+ /**
+ * @return TDisplayStyle display style of the control, default is TDisplayStyle::Fixed
+ */
+ public function getDisplay()
+ {
+ return $this->getStyle()->getDisplayStyle();
+ }
+
+ /**
+ * @param string the css class of the control
+ */
+ public function setCssClass($value)
+ {
+ $this->getStyle()->setCssClass($value);
+ }
+
+ /**
+ * @return string the css class of the control
+ */
+ public function getCssClass()
+ {
+ if($style=$this->getViewState('Style',null))
+ return $style->getCssClass();
+ else
+ return '';
+ }
+
+ /**
+ * @param string the height of the control
+ */
+ public function setHeight($value)
+ {
+ $this->getStyle()->setHeight($value);
+ }
+
+ /**
+ * @return boolean whether the control has defined any style information
+ */
+ public function getHasStyle()
+ {
+ return $this->getViewState('Style',null)!==null;
+ }
+
+ /**
+ * Creates a style object to be used by the control.
+ * This method may be overriden by controls to provide customized style.
+ * @return TStyle the default style created for TWebControl
+ */
+ protected function createStyle()
+ {
+ return new TStyle;
+ }
+
+ /**
+ * @return TStyle the object representing the css style of the control
+ */
+ public function getStyle()
+ {
+ if($style=$this->getViewState('Style',null))
+ return $style;
+ else
+ {
+ $style=$this->createStyle();
+ $this->setViewState('Style',$style,null);
+ return $style;
+ }
+ }
+
+ /**
+ * Sets the css style string of the control.
+ * The style string will be prefixed to the styles set via other control properties (e.g. Height, Width).
+ * @param string the css style string
+ * @throws TInvalidDataValueException if the parameter is not a string
+ */
+ public function setStyle($value)
+ {
+ if(is_string($value))
+ $this->getStyle()->setCustomStyle($value);
+ else
+ throw new TInvalidDataValueException('webcontrol_style_invalid',get_class($this));
+ }
+
+ /**
+ * Removes all style data.
+ */
+ public function clearStyle()
+ {
+ $this->clearViewState('Style');
+ }
+
+ /**
+ * @return integer the tab index of the control
+ */
+ public function getTabIndex()
+ {
+ return $this->getViewState('TabIndex',0);
+ }
+
+ /**
+ * Sets the tab index of the control.
+ * Pass 0 if you want to disable tab index.
+ * @param integer the tab index to be set
+ */
+ public function setTabIndex($value)
+ {
+ $this->setViewState('TabIndex',TPropertyValue::ensureInteger($value),0);
+ }
+
+ /**
+ * Returns the tag name used for this control.
+ * By default, the tag name is 'span'.
+ * You can override this method to provide customized tag names.
+ * @return string tag name of the control to be rendered
+ */
+ protected function getTagName()
+ {
+ return 'span';
+ }
+
+ /**
+ * @return string the tooltip of the control
+ */
+ public function getToolTip()
+ {
+ return $this->getViewState('ToolTip','');
+ }
+
+ /**
+ * Sets the tooltip of the control.
+ * Pass an empty string if you want to disable tooltip.
+ * @param string the tooltip to be set
+ */
+ public function setToolTip($value)
+ {
+ $this->setViewState('ToolTip',$value,'');
+ }
+
+ /**
+ * @return string the width of the control
+ */
+ public function getWidth()
+ {
+ if($style=$this->getViewState('Style',null))
+ return $style->getWidth();
+ else
+ return '';
+ }
+
+ /**
+ * @param string the width of the control
+ */
+ public function setWidth($value)
+ {
+ $this->getStyle()->setWidth($value);
+ }
+
+
+ /**
+ * @difficulty if your subclass overrides the onPreRender method be sure to call
+ * this method through parent::onPreRender($param); so your sub-class can be decorated,
+ * among other things.
+ * @param TEventParameter event parameter to be passed to the event handlers
+ */
+ public function onPreRender($param) {
+ if($decorator = $this->getDecorator(false))
+ $decorator->instantiate();
+
+ parent::onPreRender($param);
+ }
+
+ /**
+ * Adds attribute name-value pairs to renderer.
+ * By default, the method will render 'id', 'accesskey', 'disabled',
+ * 'tabindex', 'title' and all custom attributes.
+ * The method can be overriden to provide customized attribute rendering.
+ * @param THtmlWriter the writer used for the rendering purpose
+ */
+ protected function addAttributesToRender($writer)
+ {
+ if($this->getID()!=='' || $this->getEnsureId())
+ $writer->addAttribute('id',$this->getClientID());
+ if(($accessKey=$this->getAccessKey())!=='')
+ $writer->addAttribute('accesskey',$accessKey);
+ if(!$this->getEnabled())
+ $writer->addAttribute('disabled','disabled');
+ if(($tabIndex=$this->getTabIndex())>0)
+ $writer->addAttribute('tabindex',"$tabIndex");
+ if(($toolTip=$this->getToolTip())!=='')
+ $writer->addAttribute('title',$toolTip);
+ if($style=$this->getViewState('Style',null))
+ $style->addAttributesToRender($writer);
+ if($this->getHasAttributes())
+ {
+ foreach($this->getAttributes() as $name=>$value)
+ $writer->addAttribute($name,$value);
+ }
+ }
+
+ /**
+ * Renders the control.
+ * This method overrides the parent implementation by replacing it with
+ * the following sequence:
+ * - {@link renderBeginTag}
+ * - {@link renderContents}
+ * - {@link renderEndTag}
+ * @param THtmlWriter the writer used for the rendering purpose
+ */
+ public function render($writer)
+ {
+ if($this->getIsRenderBlocked())
+ return;
+
+ $this->renderBeginTag($writer);
+ $this->renderContents($writer);
+ $this->renderEndTag($writer);
+ }
+
+ /**
+ * Renders the openning tag for the control (including attributes)
+ * @param THtmlWriter the writer used for the rendering purpose
+ */
+ public function renderBeginTag($writer)
+ {
+ if($decorator = $this->getDecorator(false)) {
+ $decorator->renderPreTagText($writer);
+ $this->addAttributesToRender($writer);
+ $writer->renderBeginTag($this->getTagName());
+ $decorator->renderPreContentsText($writer);
+ } else {
+ $this->addAttributesToRender($writer);
+ $writer->renderBeginTag($this->getTagName());
+ }
+ }
+
+ /**
+ * Renders the body content enclosed between the control tag.
+ * By default, child controls and text strings will be rendered.
+ * You can override this method to provide customized content rendering.
+ * @param THtmlWriter the writer used for the rendering purpose
+ */
+ public function renderContents($writer)
+ {
+ parent::renderChildren($writer);
+ }
+
+ /**
+ * Renders the closing tag for the control
+ * @param THtmlWriter the writer used for the rendering purpose
+ */
+ public function renderEndTag($writer)
+ {
+ if($decorator = $this->getDecorator(false)) {
+ $decorator->renderPostContentsText($writer);
+ $writer->renderEndTag();
+ $decorator->renderPostTagText($writer);
+ } else
+ $writer->renderEndTag($writer);
+ }
+}
diff --git a/framework/Web/UI/WebControls/TWebControlDecorator.php b/framework/Web/UI/WebControls/TWebControlDecorator.php
new file mode 100644
index 00000000..07102d31
--- /dev/null
+++ b/framework/Web/UI/WebControls/TWebControlDecorator.php
@@ -0,0 +1,339 @@
+<?
+/**
+ * TWebControlDecorator class file.
+ *
+ * @author Brad Anderson <javalizard@gmail.com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2005-2010 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Id: TWebControlDecorator.php 2541 2008-10-21 15:05:13Z qiang.xue $
+ * @package System.Web.UI.WebControls
+ */
+
+
+/**
+ * TWebControlDecorator class
+ *
+ * This places theme related html and templates before and after both the open and close
+ * tag of a {@link TWebControl}.
+ *
+ * This is an easy way to have your look and feel depend upon the theme instead of writing
+ * specific html in your templates to achieve your website desires. This makes updating the
+ * look and feel of your website much more simple. Here is an example of how to code your theme
+ * skin:
+ * <code>
+ * <com:THeader2 TagName="h3">
+ * <prop:Decorator.PreTagText>
+ * <!-- In case the them you are importing needs this for it's h3 to look right -->
+ * <div class="imported-theme-h3-container">
+ * </prop:Decorator.PreTagText>
+ * <prop:Decorator.PostTagText>
+ * <!-- To close things properly -->
+ * </div>
+ * </prop:Decorator.PostTagText>
+ * </com:THeader2>
+ * </code>
+ *
+ * The order of the inclusion of the decoration into the page goes like this:
+ * * PreTagTemplate
+ * * PreTagText
+ * * TWebControl Open Tag Rendered
+ * * PreContentsText
+ * * PreContentsTemplate
+ * * TWebControl Children Rendered
+ * * PostContentsTemplate
+ * * PostContentsText
+ * * TWebControl CloseTag Rendered
+ * * PostTagText
+ * * PostTagTemplate
+ *
+ * To move controls around please see the {@link TMigrate} control. You may use {@link TMigrate}
+ * in your Decorator templates to move controls in your MasterTemplate around using your theme
+ * elements around on your page.
+ *
+ * @author Brad Anderson <javalizard@gmail.com>
+ * @version $Id: TWebControlDecorator.php 2541 2008-10-21 15:05:13Z qiang.xue $
+ * @package System.Web.UI.WebControls
+ * @since 3.2
+ */
+
+class TWebControlDecorator extends TComponent {
+
+ /**
+ * @var boolean tells if there should only be decoration around the inner content
+ */
+ private $_internalonly;
+
+ /**
+ * @var TWebControl the control to decorate
+ */
+ private $_control;
+
+ /**
+ * @var boolean This tells if the Templates have been
+ */
+ private $_addedTemplateDecoration=false;
+
+
+ /**
+ * @var string the text that goes before the open tag
+ */
+ private $_pretagtext = '';
+ /**
+ * @var string the text that goes after the open tag
+ */
+ private $_precontentstext = '';
+ /**
+ * @var string the text that goes before the close tag
+ */
+ private $_postcontentstext = '';
+ /**
+ * @var string the text that goes after the close tag
+ */
+ private $_posttagtext = '';
+
+
+
+ /**
+ * @var TTemplate the template that goes before the open tag
+ */
+ private $_pretagtemplate;
+ /**
+ * @var TTemplate the template that goes after the open tag
+ */
+ private $_precontentstemplate;
+ /**
+ * @var TTemplate the template that goes before the close tag
+ */
+ private $_postcontentstemplate;
+ /**
+ * @var TTemplate the template that goes after the close tag
+ */
+ private $_posttagtemplate;
+
+ /**
+ * Constructor.
+ * Initializes the control .
+ * @param TWebControl The control that is to be decorated.
+ * @param boolean whether decoration is just around the inner content
+ */
+ public function __construct($control, $onlyinternal = false) {
+ parent::__construct();
+
+ $this->_control = $control;
+ $this->_internalonly = $onlyinternal;
+ }
+
+ /**
+ * @return string gets the text before the open tag in the TWebControl
+ */
+ public function getPreTagText() {
+ return $this->_pretagtext;
+ }
+
+ /**
+ * @param string sets the text before the open tag in the TWebControl
+ */
+ public function setPreTagText($value) {
+ if(!$this->_internalonly && !$this->_control->getIsSkinApplied())
+ $this->_pretagtext = TPropertyValue::ensureString($value);
+ }
+
+
+ /**
+ * @return string the text after the open tag in the TWebControl
+ */
+ public function getPreContentsText() {
+ return $this->_precontentstext;
+ }
+
+ /**
+ * @param string sets the text after the open tag in the TWebControl
+ */
+ public function setPreContentsText($value) {
+ if(!$this->_control->getIsSkinApplied())
+ $this->_precontentstext = TPropertyValue::ensureString($value);
+ }
+
+
+ /**
+ * @return string the text before the close tag in the TWebControl
+ */
+ public function getPostContentsText() {
+ return $this->_postcontentstext;
+ }
+
+ /**
+ * @param string sets the text before the close tag in the TWebControl
+ */
+ public function setPostContentsText($value) {
+ if(!$this->_control->getIsSkinApplied())
+ $this->_postcontentstext = TPropertyValue::ensureString($value);
+ }
+
+
+ /**
+ * @return string the text before the close tag in the TWebControl
+ */
+ public function getPostTagText() {
+ return $this->_posttagtext;
+ }
+
+ /**
+ * @param string sets the text after the close tag in the TWebControl
+ */
+ public function setPostTagText($value) {
+ if(!$this->_internalonly && !$this->_control->getIsSkinApplied())
+ $this->_posttagtext = TPropertyValue::ensureString($value);
+ }
+
+
+ /**
+ * @return TTemplate|null the template before the open tag in the TWebControl. Defaults to null.
+ */
+ public function getPreTagTemplate() {
+ return $this->_pretagtemplate;
+ }
+
+ /**
+ * @param TTemplate sets the template before the open tag in the TWebControl
+ */
+ public function setPreTagTemplate($value) {
+ if(!$this->_internalonly && !$this->_control->getIsSkinApplied())
+ $this->_pretagtemplate = $value;
+ }
+
+
+ /**
+ * @return TTemplate|null the template after the open tag in the TWebControl. Defaults to null.
+ */
+ public function getPreContentsTemplate() {
+ return $this->_precontentstemplate;
+ }
+
+ /**
+ * @param TTemplate sets the template after the open tag in the TWebControl
+ */
+ public function setPreContentsTemplate($value) {
+ if(!$this->_control->getIsSkinApplied())
+ $this->_precontentstemplate = $value;
+ }
+
+
+ /**
+ * @return TTemplate|null the template before the close tag in the TWebControl. Defaults to null.
+ */
+ public function getPostContentsTemplate() {
+ return $this->_postcontentstemplate;
+ }
+
+ /**
+ * @param TTemplate sets the template before the close tag in the TWebControl
+ */
+ public function setPostContentsTemplate($value) {
+ if(!$this->_control->getIsSkinApplied())
+ $this->_postcontentstemplate = $value;
+ }
+
+
+ /**
+ * @return TTemplate|null the template after the close tag in the TWebControl. Defaults to null.
+ */
+ public function getPostTagTemplate() {
+ return $this->_posttagtemplate;
+ }
+
+ /**
+ * @param TTemplate sets the template before the close tag in the TWebControl
+ */
+ public function setPostTagTemplate($value) {
+ if(!$this->_internalonly && !$this->_control->getIsSkinApplied())
+ $this->_posttagtemplate = $value;
+ }
+
+ /**
+ * this is a framework call. The Text decoration can't
+ * influence the object hierarchy because they are rendered into into the writer directly.
+ * This call attaches the ensureTemplateDecoration to the TPage onSaveStateComplete so
+ * these controls don't have page states. This is as close to not influencing the page as possible.
+ */
+ public function instantiate() {
+
+ $this->_addedTemplateDecoration = false;
+
+ if($this->getPreTagTemplate() || $this->getPreContentsTemplate() ||
+ $this->getPostContentsTemplate() || $this->getPostTagTemplate())
+ $control->Page->onSaveStateComplete[] = array($this, 'ensureTemplateDecoration');
+ // OnPreRenderComplete onSaveStateComplete
+ }
+
+
+ /**
+ * This method places the templates around the open and close tag
+ * @return boolean returns true if the template decorations have been added
+ */
+ public function ensureTemplateDecoration() {
+ $control = $this->_control;
+ if($this->_addedTemplateDecoration || !$control->Parent) return $this->_addedTemplateDecoration;
+
+ $this->_addedTemplateDecoration = true;
+
+ if($this->getPreTagTemplate()) {
+ $pretag = Prado::createComponent('TCompositeControl');
+ $this->getPreTagTemplate()->instantiateIn($pretag);
+ $control->getParent()->getControls()->insertBefore($control, $pretag);
+ }
+
+ if($this->getPreContentsTemplate()) {
+ $precontents = Prado::createComponent('TCompositeControl');
+ $this->getPreContentsTemplate()->instantiateIn($precontents);
+ $control->getControls()->insertAt(0, $precontents);
+ }
+
+ if($this->getPostContentsTemplate()) {
+ $postcontents = Prado::createComponent('TCompositeControl');
+ $this->getPostContentsTemplate()->instantiateIn($postcontents);
+ $control->getControls()->add($postcontents);
+ }
+
+ if($this->getPostTagTemplate()) {
+ $posttag = Prado::createComponent('TCompositeControl');
+ $this->getPostTagTemplate()->instantiateIn($posttag);
+ $control->getParent()->getControls()->insertAfter($control, $posttag);
+ }
+ return true;
+ }
+
+
+ /**
+ * This method places the pre tag text into the {@link TTextWriter}
+ * @param {@link TTextWriter} the writer to which the text is written
+ */
+ public function renderPreTagText($writer) {
+ $writer->write($this->getPreTagText());
+ }
+
+ /**
+ * This method places the pre contents text into the {@link TTextWriter}
+ * @param {@link TTextWriter} the writer to which the text is written
+ */
+ public function renderPreContentsText($writer) {
+ $writer->write($this->getPreContentsText());
+ }
+
+ /**
+ * This method places the post contents text into the {@link TTextWriter}
+ * @param {@link TTextWriter} the writer to which the text is written
+ */
+ public function renderPostContentsText($writer) {
+ $writer->write($this->getPostContentsText());
+ }
+
+ /**
+ * This method places the post tag text into the {@link TTextWriter}
+ * @param {@link TTextWriter} the writer to which the text is written
+ */
+ public function renderPostTagText($writer) {
+ $writer->write($this->getPostTagText());
+ }
+}