summaryrefslogtreecommitdiff
path: root/framework/Web/UI
diff options
context:
space:
mode:
Diffstat (limited to 'framework/Web/UI')
-rw-r--r--framework/Web/UI/ActiveControls/TActiveControlAdapter.php357
-rw-r--r--framework/Web/UI/WebControls/TStyle.php33
2 files changed, 361 insertions, 29 deletions
diff --git a/framework/Web/UI/ActiveControls/TActiveControlAdapter.php b/framework/Web/UI/ActiveControls/TActiveControlAdapter.php
index de6310a6..e6e8585f 100644
--- a/framework/Web/UI/ActiveControls/TActiveControlAdapter.php
+++ b/framework/Web/UI/ActiveControls/TActiveControlAdapter.php
@@ -157,6 +157,14 @@ class TActiveControlAdapter extends TControlAdapter
}
parent::saveState();
}
+
+ /**
+ * @return TCallbackPageStateTracker state tracker.
+ */
+ public function getStateTracker()
+ {
+ return $this->_stateTracker;
+ }
}
/**
@@ -168,87 +176,378 @@ class TActiveControlAdapter extends TControlAdapter
*
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
* @version $Revision: $ Sun Jun 18 20:51:25 EST 2006 $
- * @package System
+ * @package System.Web.UI.ActiveControls
* @since 3.0
*/
class TCallbackPageStateTracker
{
- private $_states = array('Visible', 'Enabled', 'Attributes', 'Style', 'TabIndex', 'ToolTip', 'AccessKey');
+ /**
+ * @var TMap new view state data
+ */
+ private $_states;
+ /**
+ * @var TMap old view state data
+ */
private $_existingState;
+ /**
+ * @var TControl the control tracked
+ */
private $_control;
+ /**
+ * @var object null object.
+ */
private $_nullObject;
-
+
+ /**
+ * Constructor. Add a set of default states to track.
+ * @param TControl control to track.
+ */
public function __construct($control)
{
$this->_control = $control;
$this->_existingState = new TMap;
$this->_nullObject = new stdClass;
+ $this->_states = new TMap;
+ $this->addStatesToTrack();
}
- public function trackChanges()
+ /**
+ * Add a list of view states to track. Each state is added
+ * to the StatesToTrack property with the view state name as key.
+ * The value should be an array with two enteries. The first entery
+ * is the name of the class that will calculate the state differences.
+ * The second entry is a php function/method callback that handles
+ * the changes in the viewstate.
+ */
+ protected function addStatesToTrack()
{
- foreach($this->_states as $name)
- $this->_existingState[$name] = $this->_control->getViewState($name);
+ $states = $this->getStatesToTrack();
+ $states['Visible'] = array('TScalarDiff', array($this, 'updateVisible'));
+ $states['Enabled'] = array('TScalarDiff', array($this, 'updateEnabled'));
+ $states['Attributes'] = array('TMapCollectionDiff', array($this, 'updateAttributes'));
+ $states['Style'] = array('TStyleDiff', array($this, 'updateStyle'));
+ $states['TabIndex'] = array('TScalarDiff', array($this, 'updateTabIndex'));
+ $states['ToolTip'] = array('TScalarDiff', array($this, 'updateToolTip'));
+ $states['AccessKey'] = array('TScalarDiff', array($this, 'updateAccessKey'));
}
- protected function getChanges()
+ /**
+ * @return TMap list of viewstates to track.
+ */
+ protected function getStatesToTrack()
{
- $diff = array();
- foreach($this->_states as $name)
- {
- $state = $this->_control->getViewState($name);
- // echo " $name ";
- $changes = $this->difference($state, $this->_existingState[$name]);
- // echo " \n ";
- if($changes !== $this->_nullObject)
- $diff[$name] = $changes;
- }
- return $diff;
+ return $this->_states;
}
-
- protected function difference($value1, $value2)
+
+ /**
+ * Start tracking view state changes. The clone function on objects are called
+ * for those viewstate having an object as value.
+ */
+ public function trackChanges()
{
-// var_dump($value1, $value2);
- if(gettype($value1) === gettype($value2)
- && $value1 === $value2) return $this->_nullObject;
- return $value1;
+ foreach($this->_states as $name => $value)
+ {
+ $obj = $this->_control->getViewState($name);
+ $this->_existingState[$name] = is_object($obj) ? clone($obj) : $obj;
+ }
}
- public function respondToChanges()
+ /**
+ * @array list of viewstate and the changed data.
+ */
+ protected function getChanges()
{
- foreach($this->getChanges() as $property => $value)
+ $changes = array();
+ foreach($this->_states as $name => $details)
{
- $this->{'update'.$property}($value);
+ $new = $this->_control->getViewState($name);
+ $old = $this->_existingState[$name];
+ if($new !== $old)
+ {
+ $diff = new $details[0]($new, $old, $this->_nullObject);
+ if(($change = $diff->getDifference()) !== $this->_nullObject)
+ $changes[] = array($details[1],array($change));
+ }
}
+ return $changes;
+ }
+
+ /**
+ * For each of the changes call the corresponding change handlers.
+ */
+ public function respondToChanges()
+ {
+ foreach($this->getChanges() as $change)
+ call_user_func_array($change[0], $change[1]);
}
+ /**
+ * @return TCallbackClientScript callback client scripting
+ */
protected function client()
{
return $this->_control->getPage()->getCallbackClient();
}
+ /**
+ * Updates the tooltip.
+ * @param string new tooltip
+ */
protected function updateToolTip($value)
{
$this->client()->setAttribute($this->_control, 'title', $value);
}
+ /**
+ * Updates the tab index.
+ * @param integer tab index
+ */
+ protected function updateTabIndex($value)
+ {
+ $this->client()->setAttribute($this->_control, 'tabindex', $value);
+ }
+
+ /**
+ * Updates the modifier access key
+ * @param string access key
+ */
+ protected function updateAccessKey($value)
+ {
+ $this->client()->setAttribute($this->_control, 'accesskey', $value);
+ }
+
+ /**
+ * Hides or shows the control on the client-side. The control must be
+ * already rendered on the client-side.
+ * @param boolean true to show the control, false to hide.
+ */
protected function updateVisible($visible)
{
- var_dump($visible);
if($visible === false)
$this->client()->hide($this->_control);
else
$this->client()->show($this->_control);
}
+ /**
+ * Enables or Disables the control on the client-side.
+ * @param boolean true to enable the control, false to disable.
+ */
protected function updateEnabled($enable)
{
$this->client()->setAttribute($this->_control, 'disabled', $enable===false);
}
+ /**
+ * Updates the CSS style on the control on the client-side.
+ * @param array list of new CSS style declarations.
+ */
protected function updateStyle($style)
{
- var_dump($style);
+ if(!is_null($style['CssClass']))
+ $this->client()->setAttribute($this->_control, 'class', $style['CssClass']);
+ if(count($style['Style']) > 0)
+ $this->client()->setStyle($this->_control, $style['Style']);
+ }
+
+ /**
+ * Updates/adds a list of attributes on the control.
+ * @param array list of attribute name-value pairs.
+ */
+ protected function updateAttributes($attributes)
+ {
+ foreach($attributes as $name => $value)
+ $this->client()->setAttribute($this->_control, $name, $value);
+ }
+}
+
+/**
+ * Calculates the viewstate changes during the request.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @version $Revision: $ Thu Jun 22 02:50:45 EST 2006 $
+ * @package System.Web.UI.ActiveControls
+ * @since 3.0
+ */
+abstract class TViewStateDiff
+{
+ /**
+ * @var mixed updated viewstate
+ */
+ protected $_new;
+ /**
+ * @var mixed viewstate value at the begining of the request.
+ */
+ protected $_old;
+ /**
+ * @var object null value.
+ */
+ protected $_null;
+
+ /**
+ * Constructor.
+ * @param mixed updated viewstate value.
+ * @param mixed viewstate value at the begining of the request.
+ * @param object representing the null value.
+ */
+ public function __construct($new, $old, $null)
+ {
+ $this->_new = $new;
+ $this->_old = $old;
+ $this->_null = $null;
+ }
+
+ /**
+ * @return mixed view state changes, nullObject if no difference.
+ */
+ public abstract function getDifference();
+}
+
+/**
+ * TScalarDiff class.
+ *
+ * Calculate the changes to a scalar value.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @version $Revision: $ Thu Jun 22 02:54:42 EST 2006 $
+ * @package System.Web.UI.ActiveControls
+ * @since 3.0
+ */
+class TScalarDiff extends TViewStateDiff
+{
+ /**
+ * @return mixed update viewstate value.
+ */
+ public function getDifference()
+ {
+ if(gettype($this->_new) === gettype($this->_old)
+ && $this->_new === $this->_old)
+ return $this->_null;
+ else
+ return $this->_new;
+ }
+}
+
+/**
+ * TStyleDiff class.
+ *
+ * Calculates the changes to the Style properties.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @version $Revision: $ Thu Jun 22 02:55:47 EST 2006 $
+ * @package System.Web.UI.ActiveControls
+ * @since 3.0
+ */
+class TStyleDiff extends TViewStateDiff
+{
+ /**
+ * @param TStyle control style
+ * @return array all the style properties combined.
+ */
+ protected function getCombinedStyle($obj)
+ {
+ if(!($obj instanceof TStyle))
+ return array();
+ $style = $obj->getStyleFields();
+ $style = array_merge($style,$this->getStyleFromString($obj->getCustomStyle()));
+ if($obj->hasFont())
+ $style = array_merge($style, $this->getStyleFromString($obj->getFont()->toString()));
+ return $style;
+ }
+
+ /**
+ * @param string CSS custom style string.
+ * @param array CSS style as name-value array.
+ */
+ protected function getStyleFromString($string)
+ {
+ $style = array();
+ if(!is_string($string)) return $style;
+
+ foreach(explode(';',$string) as $sub)
+ {
+ $arr=explode(':',$sub);
+ if(isset($arr[1]) && trim($arr[0])!=='')
+ $style[trim($arr[0])] = trim($arr[1]);
+ }
+ return $style;
+ }
+
+ /**
+ * @return string changes to the CSS class name.
+ */
+ protected function getCssClassDiff()
+ {
+ if(is_null($this->_old))
+ {
+ return !is_null($this->_new) && $this->_new->hasCssClass()
+ ? $this->_new->getCssClass() : null;
+ }
+ else
+ {
+ return $this->_old->getCssClass() !== $this->_new->getCssClass() ?
+ $this->_new->getCssClass() : null;
+ }
+ }
+
+ /**
+ * @return array list of changes to the control style.
+ */
+ protected function getStyleDiff()
+ {
+ $diff = array_diff_assoc(
+ $this->getCombinedStyle($this->_new),
+ $this->getCombinedStyle($this->_old));
+ return count($diff) > 0 ? $diff : null;
+ }
+
+ /**
+ * @return array list of changes to the control style and CSS class name.
+ */
+ public function getDifference()
+ {
+ if(is_null($this->_new))
+ return $this->_null;
+ else
+ {
+ $css = $this->getCssClassDiff();
+ $style = $this->getStyleDiff();
+ if(!is_null($css) || !is_null($style))
+ return array('CssClass' => $css, 'Style' => $style);
+ else
+ $this->_null;
+ }
+ }
+}
+
+/**
+ * TAttributesDiff class.
+ *
+ * Calculate the changes to attributes collection.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @version $Revision: $ Thu Jun 22 02:54:42 EST 2006 $
+ * @package System.Web.UI.ActiveControls
+ * @since 3.0
+ */
+class TMapCollectionDiff extends TViewStateDiff
+{
+ /**
+ * @return array updates to the attributes collection.
+ */
+ public function getDifference()
+ {
+ if(is_null($this->_old))
+ {
+ return !is_null($this->_new) ? $this->_new->toArray() : $this->_null;
+ }
+ else
+ {
+ $new = $this->_new->toArray();
+ $old = $this->_old->toArray();
+ $diff = array_diff_assoc($new, $old);
+ return count($diff) > 0 ? $diff : $this->_null;
+ }
}
}
diff --git a/framework/Web/UI/WebControls/TStyle.php b/framework/Web/UI/WebControls/TStyle.php
index 6bc413e4..597229ea 100644
--- a/framework/Web/UI/WebControls/TStyle.php
+++ b/framework/Web/UI/WebControls/TStyle.php
@@ -55,6 +55,15 @@ class TStyle extends TComponent
}
/**
+ * Need to clone the font object.
+ */
+ public function __clone()
+ {
+ if(!is_null($this->_font))
+ $this->_font = clone($this->_font);
+ }
+
+ /**
* @return string the background color of the control
*/
public function getBackColor()
@@ -140,6 +149,14 @@ class TStyle extends TComponent
}
/**
+ * @return boolean true if CSS is set or empty.
+ */
+ public function hasCssClass()
+ {
+ return !is_null($this->_class);
+ }
+
+ /**
* @param string the name of the CSS class of the control
*/
public function setCssClass($value)
@@ -156,6 +173,14 @@ class TStyle extends TComponent
$this->_font=new TFont;
return $this->_font;
}
+
+ /**
+ * @return boolean true if font is set.
+ */
+ public function hasFont()
+ {
+ return $this->_font !== null;
+ }
/**
* @return string the foreground color of the control
@@ -337,6 +362,14 @@ class TStyle extends TComponent
if($this->_class!==null)
$writer->addAttribute('class',$this->_class);
}
+
+ /**
+ * @return array list of style fields.
+ */
+ public function getStyleFields()
+ {
+ return $this->_fields;
+ }
}
/**