Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Overview

Thai This section covers functionality and features that are not platform specific. eg. look and feel, navigation, drag & drop, styling, widget help etc.

For a tutorial that covers widget functionality that interacts with the json query API, see Writing your first Infinit.e Widget.

Panel

In this section:

Table of Contents

 

 

Widget Header

All

Infinit.e

widgets have a header that developers have direct access to

add

for adding content

to

.  There are currently 2 version of the header which work as follows

bellow

below.  To use them just include the extra mxml tags shown in your widgets main mxml page.

Traditional Way (not recommended): This is the way all legacy widgets have used

, it

.  It gives

developers

you access to a single header bar to put anything

they

you want, and will continue expanding until the widget width is met, at which point

they will cut off

all additional content is cut off.

Code Block
Header bar:
<components:headerContent>
      <components:WidgetIgnoreFilterToggleButton id="localFilterSettings"
          toolTip="Ignore Workspace Filtering - Show All Results"
          click="setTimeout( onClickIgnoreLocalFilter, 100 )" />
</components:headerContent>

 

New/Better Way (recommended): This is the way all future widgets will be developed.  It gives

developers

you access to

3

three header bars to put anything

they

you want. The first bar is a Left Aligned section that always will show up next to the title of the widget.  The next is the same header bar as the traditional that will continue to fill the area remaining in the top header bar, but will still cut off if the widget width is too small.  The final bar is a second level dropdown that if included will add a button to the top level header bar, and give

developers

you a second bar that has scrolling capabilities to fit as many header elements as necessary.

Code Block
Left aligned header bar:
<widgetComponents:leftHeaderContent>
     <widgetComponents:WidgetDropDownList id="caseList"
                                             includeInLayout="false"
                                             width="150"
                                             change="caseList_changeHandler(event)"
                                             prompt="Case"
                                             visible="false" />
</widgetComponents:leftHeaderContent>

Second header bar:
Add this property to your widget:
secondToolbarButtonVisible="true"

Then add this array of your components
<widgetComponents:secondHeaderContent>      
	<widgetComponents:WidgetToggleButton id="centerButton" 
                                             label="Center"
                                             toolTip="Center selected nodes, or entire graph"
                                             click="centerButton_clickHandler(event)" />
</widgetComponents:secondHeaderContent>

 

Widget Help

If you want to add a custom help message to your widget that will display when a user clicks the '?' button on the right side of your widget, you just need to put whatever

uicomponent

ui component you desire inside a helpContent tag as shown below.

Code Block
<components:helpContent>
        <s:VGroup width="100%" height="100%" 
                  horizontalAlign="center" gap="5" 
                  paddingTop="5" paddingBottom="5" paddingLeft="10" paddingRight="10" >            
            <s:RichEditableText editable="false" multiline="true" maxWidth="300" >
                <s:textFlow>
                    <s:TextFlow>
                        <s:p>
                            This widget does xyz.  More details on using this widget can be found <s:a href="http://mywebsite.com/help">here</s:a>
                        </s:p>
                    </s:TextFlow>
                </s:textFlow>
            </s:RichEditableText>
        </s:VGroup>
</components:helpContent>

 

Styling

To ensure a similar experience between browsers, operating systems, and other environment factors we have included a default font

into Infinit.e

for widgets.  Because of the way widgets are dynamically loaded modules, if you want to take advantage of the global font widgets, you must include

the

our css stylesheet

we use to style all font

.  If you use the eclipse plugin or predefined project in the getting started section, these are created for you and included in your widget automatically.  If you choose not to use the Infinit.e font you are more than welcome to unreference the stylesheet and go with your own approach.

 The

 

Info

The stylesheet included with your project is just an example and is not uploaded with your project when it is being submitted

, so do not make changes to that stylesheet as they

. These changes will not be reflected when

uploaded

uploading your widget to the main

Infinit.e

application.

The

In the stylesheet we have included styles, all spark components, and a selection of common MX components.  If you include a MX component that we have not styled in our stylesheet, you have the option to add a style to your widget individually.  If using the eclipse plugin or predefined project there is a commented out example in the <fx:Style> tag of adding the font to a mx:Text component.

Here is an example

is also shown here

that also achieves the same results:

Code Block
langjavascript
<fx:Style>
mx|Text
{
    font-family: infiniteNonCFFFont;
}
</fx:Style>

Anchor
widgetsave
widgetsave
Widget Saving - Community vs. User Options

Typically a widget will save any options that it wants on reloading during a onSaveWidgetOptions call.  Any

json

JSON object passed to the widget framework on that call will be returned when the widget is loaded via onLoadWidgetOptions in a WidgetSaveObject.  The WidgetSaveObject has

2

two interesting fields, userSave and communitySave.  The userSave object is the standard object that was saved during a onSaveWidgetOptions call and should be used for any save options that are unique to an individual

user; for example their

user.  Examples of these save options include a user's current zoom level and centerpoint on a map widget

or

, and the selected graph type

on

for a statistics widget. 

Code Block
titleWidget Saving Example
//Here is an example of creating an anonymous object (tempWidgetOptions)
//and setting some fields to save the zoom and centerpoint of a map widget 
//This method will be polled every few minutes
public function onSaveWidgetOptions():Object
{
      var tempWidgetOptions:Object = new Object();
      tempWidgetOptions[ "centerLat" ] = _map.center.lat;
      tempWidgetOptions[ "centerLng" ] = _map.center.lng;
      tempWidgetOptions[ "zoomLevel" ] = _map.zoom;
      return tempWidgetOptions;
}

//The next time a widget is opened it will be sent the anonymous object
//that was last saved from onSaveWidgetOptions
//that object can be used to restore previous states
public function onLoadWidgetOptions( widgetOptions:WidgetSaveObject ):void
{               
    if ( widgetOptions != null )
    {
        //this holds a users last map 
        if ( widgetOptions.userSave != null )
        {
              this.widgetOptions = widgetOptions.userSave;
              //widgetOptions contains fields centerLat,centerLng,zoomLevel from our last save
        }
	}
}
The

communitySave

The communitySave object is used for giving a widget specific saved data for a given community

, for example

.  Example of sample uses include the following

  • giving an intelligence community a KML-specific view to a region of interest
for
  • on a map widget
or
  • ,
  • using a certain color scheme specific to business operations for a statistics widget.
 

The communitySave objects can only be set external to a widget in http://infinite.ikanow.com/manager/fileUploader.jsp

Infotitle1.
  1. Create a JSON file with the data you want to pass in (see KML example below for the built in map's kml layer adder)
2.
  1. Upload the JSON file to a new JSON share in the fileUploader.jsp with the following fields set:
    1. Title: Must match the widget you want the communitySave to be accessible in.  For example,
for example
    1. if you want a
kml
    1. KML layer in the Map widget you must name your share "Map"
    2. Type: Must be "widgetsave"
    3. Community: Must be a non-personal community (e.g. select a community you own)

Any JSON saved

int his

in this manner will be available to users in that community in the onLoadWidgetOptions as seen below:

Code Block
titleLoading Community Save Data
public function onLoadWidgetOptions( widgetOptions:WidgetSaveObject ):void
{               
    if ( widgetOptions != null )
    {
        //this holds a users last map 
        if ( widgetOptions.userSave != null )
        {
              //...code from above here
        }
		if ( widgetOptions.communitySave != null )
		{
			//Any shares you have access to with type widgetSave will be provided here
			//Here we will be given a map of community ids to shares e.g. { "commid12345": {"key1":"value1"}, "commid67890":{"anotherkey",["blue","green","red"]}}
			for ( var commid:String in widgetOptions.communitySave )
			{
				//this is the object saved in the share for community <commid>
				//Now you can do what you want with it (we printed it out)
				var community_save_object = widgetOptions.communitySave[commid];
				for ( var key:String in community_save_object )
				{					
					trace("CommId: " + commid + " key: " + key + " value: " + community_save_object[key]);
					
				}
			}
		}
 	}
}

KML Layers example:

The map widget that ships with the platform shows an example of using the per-community settings in order to allow different KML layers.

To use

, upload

the per-community settings for different KML layers

  1. Upload each KML as a binary share (not necessary if the KML is accessible via URI)
and then upload
  1.  
  2. Upload a JSON share with type "widgetsave" that looks like:

 

Code Block
{
	"kml-name1": "URI1",
	"kml-name2": "URI2",
	//etc
}

(NOTE: must be shared to a non-personal community)

InfoIf

Referencing items in JSON shares:

Any item uploaded to the fileManager.jsp can be referenced via "$infinite/share/get/{id}".  This is useful when clients may use different dns names to access the gui.

 

 If you are writing your own widget, the expansion should replicate:

Code Block
var ENDPOINT_URL:String = flash.external.ExternalInterface.call( "getEndPointUrl" );
url = url.replace( "\$infinite/", ENDPOINT_URL );

 

All members of the communities to which the file is shared (and the uploaded KML, if any) should then see the KML names in the "KML Layers" dropdown.

Anchor
widgetdragdrop
widgetdragdrop
Widget Drag and Drop

A generic drag and drop interface is implemented for sending

document

documents, entities, and associations between widgets.  To accept these things a widget only needs to implement an event handler for the widgetDrop event on WidgetModule.

Code Block
<components:WidgetModule xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:components="com.ikanow.infinit.e.widget.library.components.*"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    implements="com.ikanow.infinit.e.widget.library.widget.IWidget"
    widgetDrop="widgetmodule1_widgetDropHandler(event)">
	
	<fx:Script>
        <![CDATA[
			import com.ikanow.infinit.e.widget.library.events.WidgetDropEvent;

			protected function widgetmodule1_widgetDropHandler(event:WidgetDropEvent):void
            {                
                trace("Ents: " + event.entities.length);
                trace("Assocs: " + event.associations.length);
                trace("Docs: " + event.documents.length);
                trace("Source: " + event.dragSource);
                trace("WidgetName: " + event.dragWidgetName);
                trace("WidgetClass: " + event.dragWidgetClass);               
            }
		]]>
    </fx:Script>
</components:WidgetModule>

The WidgetDropEvent object holds 3 anonymous arrays: entities,associations,documents, and any/all of these may have data in them.

It

The object also holds some information on where the drag came from:

dragSource: the dragger manually specifies this, can be anything
dragWidgetName: the title of the widget the drag came from
dragWidgetClass: the class of the widget the drag came from (i.e. the mxml file name of WidgetModule)

 

To send dragged items to another widget,

  • dispatch an drag event with the dataformat using WidgetDragUtil.WIDGET_DRAG_FORMAT:

 

Code Block
protected function widgetheaderdragimage1_mouseDownHandler(event:MouseEvent):void
{
	var docs:Array = new Array();
	for each ( var doc:Object in docList.selectedItems )
	{                    
		docs.push(doc);
	}                
	var dragObject:WidgetDragObject = new WidgetDragObject();
	dragObject.documents = new ArrayCollection(docs);
	dragObject.dragSource = "MyCustomWidgetName";  //this is the user made drag name, can be anything               
	var ds:DragSource = new DragSource();
	ds.addData(dragObject, WidgetDragUtil.WIDGET_DRAG_FORMAT );           
	DragManager.doDrag(dragImage, ds, event);
}
 

Widget Header icon

A widget header icon has been supplied in the widget library to allow uniformity between widgets

, this icon can be added to a widget by adding it to

.

To add the icon

  1. Add the header block on all widgets
(and implement
  1. Implement the mousedown handler as shown above, supplying your specific data):

Code Block
<components:WidgetHeaderDragImage id="dragImage" mouseDown="widgetheaderdragimage1_mouseDownHandler(event)" toolTip="Drag this to another widget/the query bar to send selected documents" />
When

The added

to a

widget

it

header icon will look like the following:

Image Modified