Utterly Useless Widget creating your own Chameleon widget...
-
Upload
alice-singleton -
Category
Documents
-
view
238 -
download
0
Transcript of Utterly Useless Widget creating your own Chameleon widget...
Chameleon Overview
● extensible application development framework● uses template approach for interface design● CWC2 tags control creation of widgets● tags contain attributes that define how the widget
will look and work● written in PHP using PHP/MapScript
Chameleon Architecture
● main components that control a Chameleon application are:– Chameleon– UIManager– TemplateParser– WidgetManager– Widget
Chameleon
● Chameleon is an application class● provides basic execution control for an
application– CWCInitialize– CWCExecute
● CWCParseURL● CWCPrepareDrawPublish● CWCDrawPublish
CWCInitialize
● find map file● find template● load settings from config file● prepare multilingual objects● initialize session (on first load)● initialize PHP/MapScript object (load or restore)
CWCExecute
● control is passed to the Chameleon framework– authenticate (optional)– create UIManager– load/parse template– process form from submit– prepare for publishing– publish
UI Manager - Initialization
● creates WidgetManager and TemplateParser● gets list of widgets from TemplateParser● WidgetManager creates each widget● each widget initialized from its tag
– default settings in widget– tag attributes
UI Manager – Process Form Vars
● loop through each widget in priority● pass form variables from GET/POST to widget● ParseURL function handles changes to mapscript
map object● remember widgets are processed in priority
UIManager – Prepare to Publish
● UIManager gathers following from each widget– javascript includes (<script> tags)– javascript functions (to go a single <script> tag)– onload functions (in CWC2OnLoadFunction)– javascript variables– javascript init functions (called during page load)– HTML form vars (hidden inputs in FORM)
UIManager - Publish
● UIManager inserts blocks into template● UIManager replaces each CWC2 tag with value
returned by Widget->drawPublish()● UIManager returns finished template to the
browser
CWCWidget Overview
● CWCWidget is the base class for all widgets● provides basic architecture of a widget and a
default implementation of all required functions● new widgets are created as a subclass of
CWCWidget and then provide new implementations of only those functions required to implement functionality
CWCWidget – naming conventions
● widget name is used everywhere!– widget directory name– widget file name– widget class name– widget constructor name
Example - BoundingBoxPopup
● /chameleon/htdocs/widgets/BoundingBoxPopup● BoundingBoxPopup.widget.php● class BoundingBoxPopup extends CWCWidget● BoundingBoxPopup()
CWCWidget - Constructor
● constructor used to create instance of a widget● must call base class constructor
– parent::CWCWidget();● must register all tag attributes● must create button/popup instances● should set
– description– maturity level– priority
CWCWidget - Attributes
● attributes are handled by the framework ● provide validation and documentation● attributes can be of different types● attributes are automatically parsed from the tag,
validated and made available to the widget● widget should register all attributes in constructor
and read attribute values in InitDefaults()● can be mandatory or optional● validation controlled through chameleon.xml
CWCWidget – Attribute Types
● Attribute classes in Widget.php– Attribute (base attribute class, don't use)– BooleanAttribute – true or false– FloatAttribute – a floating point number– HexColorAttribute – a valid hex color (#ff002b)– IntegerAttribute – an integer value– RGBColorAttribute – three integers, space separated– StringAttribute – any string, possibly restricted to a
set of values
Registering Attributes
● $this->maAttributes["AXIS"] = new StringAttribute( "AXIS", true, array( "X", "Y" ) );– required attribute, must be one of X or Y
● $this->maAttributes["TEXTFIELDSIZE"] = new IntegerAttribute( "TEXTFIELDSIZE", false, 0 );– optional attribute, integer greater than or equal to 0
CWCWidget - InitDefaults
● InitDefaults is called after the widget tag has been parsed and the widget has been created
● must call parent::InitDefaults()● access embedded content through
– $this->maszContents ● initialize any default values for the widget,
including attributes:– if (isset($this->maParams["AXIS"]))
$this->mszAxis = ($this->maParams["AXIS"]);
CWCWidget - ParseURL
● called during execution● widget has a chance to change the state of the
application, normally based on FORM variable state
● use $this->moMapObject->oMap to access PHP/MapScript object
● use $this->getVar() to access form vars– also isVarSet and setVar
CWCWidget – Drawing
● GetXXX functions return snippets to include elsewhere in the template
● DrawPublish returns HTML representation of widget
CWCWidgets – buttons
● many widgets use 'buttons' to represent themselves– include( '../Button.php');– in Constructor/InitDefaults:
● $this->moButton = new CWCButton( this );● $this->moButton->InitDefaults();
– in (most) functions:● $this->moButton->XXXX();
– in DrawPublish()● $this->moButton->DrawPublish();
CWCWidget – buttons (cont)
● CWCButton adds all the necessary attributes, javascript, form variables to provide a clickable button to activate your widget– pre-rendered or generated buttons (buttonizer)– multi-state buttons– groups of buttons (radio groups)– Style resource handling
CWCWidget - Popups
● many widgets use popup dialogs to interact with the user
● CWCPopup (Popup.php) provides same level of abstraction as CWCButton
● see BoundingBoxPopup for an example of using buttons and popups in a single widget
Widget Maturity
● NavTool.php is a special helper file that implements a full widget based on CWCWidget
● intended to simplify creation of new widgets that interact with the map (Navigation Tools)
● NavTool-based widgets use “extends” rather than member variables
● examples are ZoomIn, ZoomOut, Query ...
the Utterly Useless Widget
● based on NavTool (interact by clicking the map)● will alert the pixel and/or the geographic location
of a mouse click● shows use of
– Button– attributes– adding custom functionality
UUW - overview
● normally create new widgets from existing widgets that provide similar functionality (as in interface functionality, not necessarily action functionality)
● starting from WidgetTemplate● adding functionality in incremental steps
UUW – set up
● copy MUM3/WidgetTemplate folder to chameleon/htdocs/widgets and rename to UUW
● copy the “utils.inc.php” file to the new “UUW” folder.
● open the new “UUW” folder and rename "WidgetTemplate.*" to "UUW.*"
● open "UUW.widget.php" in any text editor and replace all occurrences of “WidgetTemplate” with “UUW”.
● copy sample_uuw.* to chameleon/samples/htdocs
UUW – test empty widget
●Open sample_uuw.html and add a new widget. The definition should look something like this:<cwc2 type="UUW" imagetip="Info" image="icons/icon_query.png" styleresource="NavButton" imagewidth="25" toolset="nav"> <image state="normal"/> <image state="hover"/> <image state="selected"/></cwc2>
●Run the Chameleon application. You should see a navtool button for your new widget. It doesn’t do anything at the moment.
UUW – adding a member variable
● widget will be reporting mouse click position● add member variable to hold report text in class
definitonclass UUW extends NavTool{ // define member vars // i.e. var $mszMyVariable; var $mszReport;
UUW – initialization
● add code to initialize member variable and NavTool
function InitDefaults(){ // init defaults for parent parent::InitDefaults(); // init the widget defaults $this->SetNavCommand('UUW'); $this->mszReport = '';● then try it out ... the map submits when you click
(but still does nothing)
UUW – capture mouse clicks
● ParseURL – handling navigation instructions● in ParseURL, add following:// work some magicif ( $this->isVarSet( "NAV_CMD" ) && $this->getVar( "NAV_CMD" ) == 'UUW' ){ $this->mszReport = 'My Report Test'; }
UUW – using javascript functions
● need a way to display the report.● add following to GetJavascriptFunctions()// show the report$szShowReport = strlen( $this->mszReport ) >
0 ?'alert(\''.$this->mszReport.'\')' : '';$szJsFunctionName = "showReport";$szFunction = <<<EOTfunction {$szJsFunctionName}(){ {$szShowReport}; return true;}EOT;$aReturn[$szJsFunctionName] = $szFunction;
UUW – using onload functions
● finally, add an 'onload' function to show the report
● add following to GetJavascriptOnLoadFunctions//show report$aReturn['showReport'] = “showReport();\n”;
● try it out ...
UUW – include utility file
● we want to be able to report the pixel position and/or the geographic position of the mouse click
● some additional functions have been included in utils.inc.php to help us out :)
//include utility functionsinclude( 'utils.inc.php' );
UUW – remove test report
● we'll remove the test report title and add some code to generate a more useful report
● delete this line:$this->mszReport = 'My Report Test';
UUW – add new report
● add the following:$oMap = &$this->moMapNavigator->oSession->oMap;$nPixX = $this->getVar('MAP_CURSOR_POS_X', 0);$nPixY = $this->getVar('MAP_CURSOR_POS_Y', 0);$this->mszReport = reportPixelCoords($nPixX, $nPixY );$this->mszReport .= '------------------\n';$this->mszReport .= reportGeoCoords($nPixX, $nPixY,
$oMap );$this->mszReport .= '------------------\n';$this->mszReport .= reportLayerStatus($oMap);
UUW – try it out
● try it out ...● widget reports on:
– pixel location of click– geographic location of click– layer status
● Open utils.inc.php and look at:– pix2geo– reportXXX functions
UUW – controlling the report
● use attributes to allow user of your widget to control how it works
● we want to control display of the coordinates and layer status– pixel or geographic or both– layer status on or off
● Coordinate display is mandatory● Layer display is optional
UUW – add member variables for attributes
● add two new member variables to track these attributes
var $mszCoords;var $mbLayerStatus;
UUW – add COORDS attribute
● in constructor, add a new attribute for COORDS$this->maAttributes['COORDS'] = new
StringAttribute( 'COORDS', true, array( 'pix', 'geo', 'both' ));
● mandatory and must be one of the defined values
UUW – add LAYERSTATUS attribute
● in constructor, add a new attribute for LAYERSTATUS
$this->maAttributes['LAYERSTATUS'] = new BooleanAttribute( 'LAYERSTATUS', false);
● optional value
UUW – initialize attributes
● in InitDefaults, add initialization code for the attributes:
$this->mszCoords = isset($this->maParams['COORDS'] ) ? $this->maParams['COORDS'] : 'pix';
$this->mbLayerStatus = isset($this->maParams['LAYERSTATUS']) && strcasecmp($this->maParams['LAYERSTATUS'],'true') == 0;
UUW – update tag
● your UUW tag has to be updated to include the mandatory attribute COORDS
● try it again ... it should work now (but there's no difference)
UUW – using COORDS attribute
● update the ParseURL function to use this new attribute
if ($this->mszCoords == 'pix' || $this->mszCoords == 'both')
$this->mszReport .= reportPixelCoords($nPixX, $nPixY);
if ($this->mszCoords == 'geo' || $this->mszCoords == 'both')
{ if (strlen($this->mszReport) > 0) $this->mszReport .= '------------------\n'; $this->mszReport .= reportGeoCoords( $nPixX,
$nPixY, $oMap );}
UUW – using LAYERSTATUS attribute
● update the ParseURL function to use the new attribute
if ($this->mbLayerStatus){ if (strlen($this->mszReport) > 0) $this->mszReport .= '------------------\n'; $this->mszReport .= reportLayerStatus( $oMap );}● and try it out by experimenting with coords=””
and layerstatus=”” in your template● widget priority defined in widget.phpdefine("PRIORITY_LAST",0);define("PRIORITY_LOW",1);define("PRIORITY_MEDIUM",2);define("PRIORITY_HIGH",3);define("PRIORITY_SUPER",4);
define( "PRIORITY_MINIMUM", PRIORITY_LAST );define( "PRIORITY_MAXIMUM", PRIORITY_SUPER );● and defined in the constructor of the widget:$this->mnPriority = PRIORITY_NORMAL;● widget maturity level used for QC purposes and
deploying beta quality widgets with a release package:
MATURITY_MINIMUMMATURITY_UNKNOWNMATURITY_ALPHAMATURITY_BETAMATURITY_RELEASECANDIDATEMATURITY_TECHNICALRELEASEMATURITY_PRODUCTRELEASEMATURITY_MAXIMUM● defined in widget as:$this->mnMaturityLevel = MATURITY_BETA;