Adapter Widget Dev Guide
Adapter Widget Dev Guide
Callback Methods
requiredScripts()
init()
update(userPropertyName)
cleanup()
What is AdapterWidget ?
AdapterWidget is developed for CPT graphics widget developers, who want to develop
his/her own widgets running on CPT graphics web page and/or CPT dashboard, then
maybe deliver the new widgets to his/her customer to use.
CPT Tools already provide dozens of widgets for user to choose when building CPT
graphics. But it is hard to meet all user’s diverse requirements, so we come out
AdapterWidget.
AdapterWidget already handles the logics of data communication, applying basic widget
properties(size, zorder etc), javascript/css files loading, so that developer of
AdapterWidget can just focus on the specific logic of his/her own widget.
After you developed a AdapterWidget, you can save it as a Graphic UserLib, then export it
as single package file to share it with others for reuse, more details on how to export a
Graphic UserLib and how to import a Graphic UserLib.
Most of AdapterWidget can be converted to a CPT Dashboard widget with one click,
without changing any code. That means your efforts spent on developing AdapterWidget
can be reused on CPT Dashboard. More details on how to reuse AdapterWidget in CPT
Dashboard.
want more graphic widgets that CPT Tools not provided yet
the widget provided by CPT Tools not meet your requirement well
provide project specific widgets to your customer, so that they can use them
you know web programming technologies
To develop your widgets based on AdapterWidget, you will need to do two things:
When you define a new widget based on AdapterWidget, you probably want to allow users
of your widget to customize the look-n-feel or logics. You can define your own properties
on your widget for above purpose. We name your own property as User Property.
User Property behaves the same as other property(like size, zorder, visible etc), except
one difference: its name must start with ‘@’. This helps CPT Tools to differentiate User
Property from builtin property.
For example, if you are developing a Slider widget for user to change some integer data
point’s value, you may want user to define the valid value range. You can use User
Property to implement that.
Till now, there are 7 data types(String, Integer, Float, Boolean, Area, Color and Image) for
User Property. When you creating a new User Property, you can choose the most suitable
data type. When user edits User Property, CPT Tools will choose the most suitable
property editor widget based on the User Property’s data type.
Select an AdapterWidget
In AdapterWidget’s property editor, right click, then in the contextual menu, choose
“New User Property …”
In the new User Property dialog, define its name and data type, then save
’Placeholder’: tooltip text for the User Property, displayed when user mouse
over your User Property in CPT Tools.
‘ActionOnly’: specify the User Property is an action, CPT Tools will only
display all component’s actions when you edit it. To enable this, the User
Property must be a String.
Then the new property will show up in the property editor tree, and you can give it a
default value
Now you need to input your widget’s logics(javascript codes) into ‘javascriptCode’ property.
Click ‘javascriptCode’ property, a code editor dialog will show up, and CPT have put some
code skeleton and comments there.
There are 3 areas in the AdapterWidget Editing window: Code Editor, Preview and Test
Data:
Code Editor is plain code editor, that support javascript syntax highlight, simple code
error checking etc. And you change the font’s size at the bottom of the Code Editor.
Preview is a simple embed web browser, that will create a container for
AdapterWidget, set up mock APIs used by AdapterWidget. Note: This preview area
is only designed to have a quick look on the widget’s UI looking, it does not
communicate with controller backend. If you don’t need it, you can hide it by clicking
the checkbox ‘Enable Preview’ at the bottom of Code Editor.
Test Data is a list of User Property. For example, you can change ‘@BoolValue’ User
Property and see what the toggle widget behaves on the fly.
We will explain the programming interface of AdapterWidget in details later, now let’s try a
demo.
Here we will demo how to use AdapterWidget to integrate the wonderful jQuery Toggles 3rd
party javascript library to make our own toggle widget, that can be used on CPT graphics
web page.
1. Download jQuery Toggles
Go to jQuery Toggles, download the source codes zipball, unzip it under CPT/grweb/public
folder, it looks like this:
Now we can drag and drop a AdapterWidget(under ‘general’ category) to graphic canvas,
then create a User Property named “@BoolValue”:
3. Make Data Binding
4. Javascript Coding
this.requiredScripts = function() {
// *Note*, you need to put the javascript/css files
// under 'CPT/grweb/public/user_codes' folder manually,
// otherwise these files cann't be deployed to device
return ["../user_codes/toggles/css/toggles.css",
"../user_codes/toggles/css/themes/toggles-light.css",
"../user_codes/toggles/toggles.js"];
};
Click “Save” button, you can see that the toggle widget works in the Preview area. And in
“Test Data” area, you can change property ‘@BoolValue’ to ‘true’, the toggle button will
display ‘on’ state; change it to ‘false’, the toggle button will display ‘off’ state.
5. Deployment
Now we are ready to push files to controller, do a Full Deployment, wait until it’s done and
click ‘preview’ button to see graphic page in browser.
You can change the ConstBool object’s state using setTrue/setFalse actions, and the
toggle button will change its state to reflect your changes.
Till now, the toggle widget is just a readonly widget, when click it in browser web page, it
will toggle its state, but the change will not be pushed to backend object ‘ConstBool’.
We will define two more User Properties to allow user to specify the setTrue/setFalse
actions’ path, so that when the toggle widget’s state changed, it will invoke related action.
We use ‘@OnAction’ for ‘setTrue’ action, ‘@OffAction’ for ‘setFalse’ action. One important
thing is when create ‘@OnAction’ and ‘@OffAction’, the ‘ActionOnly’ checkbox must be
checked, this will tell CPT Tools that this User Property is only about an action slot’s path,
so that when user clicks the property for editing, CPT Tools will display action selection
editor.
this.init = function() {
$(this.elem).css("text-align", "center")
.addClass("toggle toggle-light")
.toggles();
this.update("@BoolValue");
};
The above code will listen to the ‘toggle’ event, and when the event happens, it will invoke
the action based on the ‘active’ value, that is the current state of toggle widget.
The ‘invokeAction’ method will communicate with backend to trigger the setTrue/setFalse
action, more details later.
Now do a deployment and open preview page, click the toggle widget will change the state
of ‘ConstBo’ object.
8. Final Tweak
When bind ‘@BoolValue’ to ‘ConstBo.out’, CPT Tools will set up the object’s actions as the
widget’s contextual menu. That’s why when you click the toggle widget, the action menu
will show up.
It can be turned off by click ‘actions’ property and uncheck all actions:
To make your widget can be reused, you can save it as a graphic UserLib:
Here the User Lib’s name is ‘toggle’, and set its Category as “Toggles”.
Then later you can just drag this new graphic userlib object to canvas to create a new
toggle widget.
After you finish your widget, you can export it as a single package file, all required
files(css, javascript, images etc) are packed together. The package file’s extension name
is .gul(Graphic UserLib). You can share it with others, just like share a plain file.
Right click on your widget, there will be a contextual menu showing up:
Click the ‘Export Graphic UserLib …’ menu, CPT will ask for where to save the exported
package file, choose a folder then click ‘Save’ button. By default, CPT will generate a
default package name, for example Toggles-Toggle_20160804.gul, although you can
change it, better to leave it as default. At last, CPT Tools will open the exported package file
in File Explorer, so that you can easily find it and send it to others.
11. Import Widget from a package file(.gul)
If you want to reuse a widget shared by others, you need to get the .gul file, then in Graphic
UserLibs UI box, right click and in the contextual menu click “Import Graphic UserLib …”
menu item, then locate the package file and click ‘Ok’. During import, CPT may ask you to
confirm before a file is overwritted.
When you developing a widget based on AdapterWidget and want to reuse it in CPT
dashboard, you need to keep something in mind:
If you beer these rules in mind, then your widget is able to be used in dashboard.
Note: Now dashboard widget is readonly, it can not change underlying data. Writing
data may be supported in future.
After you finish developing your widget and it works well on CPT Graphics web page, then
you can follow these steps to make it work in CPT dashboard:
3. Do a deployment
Now open CPT dashboard, create a new Pane, then click ‘+’ button to add a widget, on the
widget selection menu, your widget will be there.
If you want to more examples for reference, you can contact us at cptsuite@gmail.com.
To make it easier, CPT Tools provides a dashboard widget management UI. You can open
the management UI, open any graphic file, click menu Tools -> Dashboard Widget
Management … , or you can right click in graphic UserLib box, there is a menu item, too.
You can rename or delete a dashboard widget here, after your changes is done, you need
to run FULL deployment to make your changes happen on controller side.
NOTE: After deployment, the dashboard widgets on controller side will be exact the
same as your computer. That means any dashboard widget on controller that does
not exist on your computer, will be removed.
AdapterWidget Programming Interface
To make the widget development easier, AdapterWidget isolate the inner widget from
outside environment, it provides the container dom element, several data service methods.
On the other side, the inner widget need to implement several callback methods, that will be
called by AdapterWidget under certain condition.
AdapterWidget will create a container ‘div’ dom element for the inner widget. inner
widget should limit its operations(for example, create new dom element) within this
container. The container element looks like this:
AdapterWidget will take care of the container element’s position, size, zorder,
visibility etc; but within the container element, the inner widget has totally control.
You can use ‘this.elem’ to access the container element object, but more convenient
way is using jQuery wrapped object ‘$(this.elem)’, so that all jQuery functionalities
are ready to be use, for example:
Callback Methods
requiredScripts()
Return a URL array of required javascript and css resource that are required.
This is the first callback method to be called by AdapterWidget. If the returned value
is an empty array, undefined or null values, AdapterWidget will load nothing;
otherwise, AdapterWidget will load these resource in order. In general, css resource
should be loaded before javascript resource.
this.requiredScripts = function() {
return ["../user_codes/toggles/css/toggles.css",
"../user_codes/toggles/css/themes/toggles-
light.css",
"../user_codes/toggles/toggles.js"];
};
init()
This is the right place to execute initialization tasks, for example, create widget’s dom
element, initialize widget’s data, set up widget’s style, bind listener to widget’s event
etc. Refer to above toggle widget demo for example.
update(userPropertyName)
This is the right place to update widget’s UI state. readData can be used to get User
Property’s value. Refer to above toggle widget demo for example.
cleanup()
Will be called when the widget will be removed from web page.
readData(propertyName)
This method will return property’s value, no matter User Property or not.
All property’s values are returned as string, it is the inner widget’s responsibility to
cast it into correct data type.
cast it into correct data type.
writeData(userPropertyName, value)
Call this method will change an object’s slot that bound to the given userProperty
with ‘value’
Call this method will invoke action addressed by ‘path’ with optional ‘value’ and
optional ‘valueDataType’.
hasData(userPropertyName)
Return if the given userPropertyName has been defined.
runSqlQuery(query, dataCallback)
Run the given sql ‘query’ statement on history db in controller and feed data back to
‘dataCallback’ method.
Above query will get average data value per hour for columns ‘data1’ and ‘data2’ of
yesterday.
‘dataCallback’ function should accept a data object and the data object looks like
this:
data = {
columns: ['hour', 'data1Avg', 'data2Avg'], // result column
labels
rows: [
['00', '505', '780'],
['01', '238', '1024'],
// ... ... more records
]
}
in ‘dataCallback’ function, you can decide how to render the queried result on UI.
Non-admin users can only run ‘select’ sql query, that means they can not
change the data in DB; Users with admin role can run any sql query.
hasWritePerm()
Call this method to query if current account has ‘write’ permission on current graphic
page. The return value is boolean value: true or false.
When calling ‘invokeAction’ method, the framework already call this method already,
and will return string ‘permission denied’ when current account doesn’t have
permission.
readNote(path, dataHandler)
writeNote(path, content)
startSpinner()
Call this method to start a loading spinner, indicating that some work is under going.
stopSpinner()
Call this method to stop the spinner started by above ‘startSpinner’ method.
Preloaded 3rd Javascript Library
Following javascript libraries are used by CPT graphic web page, these are ready to be
used within the inner widget, and no need to specify them in the requiredScripts method.
jQuery
Underscore.js
Underscore.string
Backbone.js
Spin.js
Bootstrap.js 2.3.2
Moment.js
If a javascript library or css file are required by multiple widgets, AdapterWidget will
guarantee it loaded only once.