Utterly Useless Widget
E N D
Presentation Transcript
creating your own Chameleon widget ... Utterly Useless 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 definiton class 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 magic if ( $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 = <<<EOT function {$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 functions include( '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 – try it out • test the application
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.php define("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_MINIMUM MATURITY_UNKNOWN MATURITY_ALPHA MATURITY_BETA MATURITY_RELEASECANDIDATE MATURITY_TECHNICALRELEASE MATURITY_PRODUCTRELEASE MATURITY_MAXIMUM • defined in widget as: $this->mnMaturityLevel = MATURITY_BETA;
Question and Answer • if we have time ... questions now • also: • look at how some existing widgets work • add some more functionality (perhaps simple query?)