180 likes | 414 Views
Writing Widgets & Custom Script API for BOY. Xihui Chen chenx1@ornl.gov Spring 2012 EPICS Collaboration Meeting. BOY Architecture. BOY Framework. Abstract Widget. XML Reader & Writer. Properties. Macro. Actions. Color & Font Macro. OPI Editor. OPI Runtime. Navigator. Palette.
E N D
Writing Widgets & Custom Script API for BOY Xihui Chen chenx1@ornl.gov Spring 2012 EPICS Collaboration Meeting
BOY Architecture BOY Framework Abstract Widget XML Reader & Writer Properties Macro Actions Color & Font Macro OPI Editor OPI Runtime Navigator Palette Toolbar Console Outline Toolbar Context Menu Console Context Menu Script Engine Utility PV Properties Sheet GEF CSS Platform Eclipse
MVC Pattern • All BOY widgets should follow Model-View-Controller Pattern • Separate responsibilities • Decouple complexity • Increase flexibility • Code reuse
Widget Model • Definition • Defines the set of properties • Stores the according values • Only properties in model will be persisted to .opi file • Implementation • All widgets model must subclass org.csstudio.opibuilder.model.AbstractWidgetModel • All PV widgets should subclass org.csstudio.opibuilder.model.AbstractPVWidgetModel • All Container Widgets must subclass org.csstudio.opibuilder.model.AbstractContainerModel
Widget Model Example • publicclass SimpleBarGraphModel extends AbstractPVWidgetModel{ • /** Lower limit of the widget. */ • publicstaticfinal String PROP_MIN = "max"; //$NON-NLS-1$ • /** Higher limit of the widget. */ • publicstaticfinal String PROP_MAX = "min"; //$NON-NLS-1$ • publicfinal String ID = • "org.csstudio.opibuilder.widgetExample.SimpleBarGraph"; //$NON-NLS-1$ • /** • * Initialize the properties when the widget is first created. • */ • public SimpleBarGraphModel() { • setForegroundColor(new RGB(255, 0, 0)); • setBackgroundColor(new RGB(0,0,255)); • setSize(50, 100); • } • @Override • protectedvoid configureProperties() { • addProperty(new DoubleProperty(PROP_MIN, "Min", • WidgetPropertyCategory.Behavior, 0)); • addProperty(new DoubleProperty(PROP_MAX, "Max", • WidgetPropertyCategory.Behavior, 100)); • } • @Override • public String getTypeID() { • returnID; • } • ... • }
Widget Properties • Currently supported property types: • Create your own property type by extending org.csstudio.opibuilder.properties.AbstractWidgetProperty
Widget Figure (View) • Definition • The graphical representation of the widget • No dependency on model and controller. • It should be autonomous, which means it should have its own behavior independent from model and controller • Implementation • All widgets figure must be an instance of org.eclipse.draw2d.IFigure • In most cases, just subclass org.eclipse.draw2d.Figure or other existing figures will make it easier
Widget Figure(cont’d) • To use SWT widgets, subclass org.csstudio.opibuilder.widgets.figures.AbstractSWTWidgetFigure • Example: combo, web browser, table widget in BOY • You may use SWT_AWT bridge to use Swing widget in BOY
Available Figure Resources • A widget figure can be assembled from several other figures, so you can reuse exist figures: • org.csstudio.swt.xygraph • Linear Scale • SWT XYGraph • org.csstudio.swt.widgets • Round Scale • Existing Widgets
Widget Figure Example • publicclass SimpleBarGraphFigure extends Figure { • privatedoublemin =0; • privatedoublemax = 100; • privatedoublevalue = 50; • @Override • protectedvoid paintClientArea(Graphics graphics) { • super.paintClientArea(graphics); • //fill background rectangle • graphics.setBackgroundColor(getBackgroundColor()); • graphics.fillRectangle(getClientArea()); • //fill foreground rectangle which show the value's position • graphics.setBackgroundColor(getForegroundColor()); • //coerce drawing value in range • double coercedValue = value; • if(value < min) • coercedValue = min; • elseif (value > max) • coercedValue = max; • int valueLength = (int) ((coercedValue-min)*getClientArea().height/(max-min)); • graphics.fillRectangle(getClientArea().x, • getClientArea().y + getClientArea().height -valueLength, • getClientArea().width, valueLength); • } • publicvoid setValue(double value) { • this.value = value; • repaint(); • } • publicdouble getValue() { • returnvalue; • } • ... • }
Widget Editpart (Controller) • Definition • The coordinator between model and view • Responsible for the behavior of the widget when properties value changed • Implementation • All widgets editpart must subclass org.csstudio.opibuilder.editparts.AbstractWidgetEditPart • All PV widgets should subclass org.csstudio.opibuilder.editparts.AbstractPVWidgetEditPart • All Container Widgets must subclass org.csstudio.opibuilder.editparts.AbstractContainerEditpart
Widget Editpart Example • publicclassSimpleBarGraphEditpartextendsAbstractPVWidgetEditPart { • /** • * Create and initialize figure. • */ • @Override • protectedIFiguredoCreateFigure() { • SimpleBarGraphFigurefigure = newSimpleBarGraphFigure(); • figure.setMin(getWidgetModel().getMin()); • figure.setMax(getWidgetModel().getMax()); • returnfigure; • } • @Override • protectedvoidregisterPropertyChangeHandlers() { • // The handler when PV value changed. • IWidgetPropertyChangeHandlervalueHandler = newIWidgetPropertyChangeHandler() { • publicbooleanhandleChange(final Object oldValue, • final Object newValue, • finalIFigure figure) { • if(newValue == null) • returnfalse; • ((SimpleBarGraphFigure) figure).setValue(ValueUtil.getDouble((IValue)newValue)); • returnfalse; • } • }; • setPropertyChangeHandler(AbstractPVWidgetModel.PROP_PVVALUE, valueHandler); • //The handler when max property value changed. • IWidgetPropertyChangeHandlermaxHandler = newIWidgetPropertyChangeHandler() { • publicbooleanhandleChange(Object oldValue, Object newValue, IFigure figure) { • ((SimpleBarGraphFigure) figure).setMax((Double)newValue); • returnfalse; • } • }; • setPropertyChangeHandler(SimpleBarGraphModel.PROP_MAX, maxHandler); • … • } • … • }
Register the widget with BOY • Use the standard Eclipse extension point mechanism • Extension point: org.csstudio.opibuilder.widget
Integrate the widget with CSS • CSS Developer • Include the widget plugin into your build • CSS User • Export it to a deployable Plugin JAR file and copy it to your CSS dropins folder
Example • Follow steps on • BOY online help->Creating Customized Widget
Create Custom Script API • Purpose: call your own Java API from BOY scripts • For example, retrieve data from MySQL database and display the data on BOY widgets. • Technology: Eclipse Fragment • A fragment on host of org.csstudio.opibuilder plugin will be recognized as part of the host • It allows adding third party libraries or plugins • Add static method to your utility class • Export the package from MANIFEST.MF/Runtime page
Example • Follow steps on • BOY online help-> Script->Creating Custom ScriptUtil
Summary • BOY Widgets • All BOY widgets must follow the MVC pattern • Each widget should have at least three classes: Model, Editpart and Figure • Using Eclipse extension point to register widgets with BOY • Glad to have your widgets included in BOY as standard widgets • contact chenx1@ornl.gov • Custom Script API • Use Fragment on host of org.csstudio.opibuilder Thank you!