/*- * Copyright © 2009 Diamond Light Source Ltd. * * This file is part of GDA. * * GDA is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License version 3 as published by the Free * Software Foundation. * * GDA is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along * with GDA. If not, see <http://www.gnu.org/licenses/>. */ package uk.ac.gda.dal.csswidgets.editparts; import gda.jython.InterfaceProvider; import gda.jython.batoncontrol.BatonChanged; import gda.observable.IObserver; import java.util.List; import org.csstudio.sds.model.AbstractWidgetModel; import org.csstudio.sds.model.WidgetProperty; import org.csstudio.sds.model.properties.actions.AbstractWidgetActionModel; import org.csstudio.sds.ui.editparts.AbstractWidgetEditPart; import org.csstudio.sds.ui.editparts.IWidgetPropertyChangeHandler; import org.csstudio.sds.ui.widgetactionhandler.WidgetActionHandlerService; import org.eclipse.draw2d.ActionEvent; import org.eclipse.draw2d.ActionListener; import org.eclipse.draw2d.ArrowButton; import org.eclipse.draw2d.Button; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.Label; import org.eclipse.draw2d.MouseEvent; import org.eclipse.draw2d.MouseListener; import org.eclipse.draw2d.PositionConstants; import org.eclipse.draw2d.RectangleFigure; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.jface.viewers.ICellEditorListener; import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.PlatformUI; import uk.ac.gda.dal.csswidgets.figures.ScannableControlFigure; import uk.ac.gda.dal.csswidgets.model.ScannableControlModel; public class ScannableControlEditPart extends AbstractWidgetEditPart { private ScannableControlFigure scannableControlFigure; private double incrementVal = 1.0; private double offset = 0.0; private ArrowButton increment = new ArrowButton(PositionConstants.EAST); private ArrowButton decrement = new ArrowButton(PositionConstants.WEST); private Button goReal = new Button("Go Real"); private Button goSim = new Button("Go Sim"); private Boolean amIHolder = InterfaceProvider.getBatonStateProvider().amIBatonHolder(); private Label label = new Label(); private RectangleFigure border = new RectangleFigure(); private String tooltipText; private ScannableControlModel model; private int wholeDigits=1; private int dp=4; private boolean showButtons=false; /** * Returns the casted model. This is just for convenience. * * @return the casted {@link ScannableControlModel} */ @Override protected ScannableControlModel getCastedModel() { return (ScannableControlModel) getModel(); } @Override protected IFigure doCreateFigure() { model = getCastedModel(); incrementVal = model.getDefaultIncrement(); scannableControlFigure = new ScannableControlFigure(amIHolder); dp = model.getDP(); scannableControlFigure.setDP(dp); scannableControlFigure.setBoxWidth(15+(dp*10)+((wholeDigits-1)*10)); if (model.isLive()) { scannableControlFigure.addMouseListener(new MouseListener.Stub() { @Override public void mousePressed(MouseEvent me) { me.consume(); if (me.button == 1 && amIHolder) { Rectangle mouseBound = new Rectangle(me.x, me.y, 1, 1); if (scannableControlFigure.getDemandBox().intersects(mouseBound)) { Rectangle rect = ScannableControlEditPart.this.scannableControlFigure.getBounds().getCopy(); rect.x = rect.x + 1; rect.y = rect.y + 1; rect.height = rect.height - 1; rect.width = rect.width - 1; getFigure().translateToAbsolute(rect); scannableControlFigure.showDemand(rect.x, rect.y); } } } }); } increment.setLocation(new Point(35+(dp*10)+((wholeDigits-1)*10), 19)); increment.setVisible(true); increment.setSize(20, 20); increment.setEnabled(amIHolder); increment.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { if (amIHolder) { double upperBound = model.getHighLimit(); if (model.getReadbackValue() + incrementVal <= upperBound) { double incVal = incrementVal; model.setReadbackValue(scannableControlFigure.getDemand() + incVal); scannableControlFigure.setDemand(scannableControlFigure.getDemand() + incVal); } } } }); scannableControlFigure.setIncrementCellEditor(new TextCellEditor((Composite) getViewer().getControl())); if (model.isLive()) { increment.addMouseListener(new MouseListener.Stub() { @Override public void mousePressed(MouseEvent me) { me.consume(); if (me.button == 2) { Rectangle rect = ScannableControlEditPart.this.scannableControlFigure.getBounds().getCopy(); rect.x = rect.x + 1; rect.y = rect.y + 1; rect.height = rect.height - 1; rect.width = rect.width - 1; getFigure().translateToAbsolute(rect); border.setLocation(new Point(0, 0)); border.setSize(rect.width, rect.height); border.setForegroundColor(new Color(null, 0, 0, 0)); label.setText("Increment=" + incrementVal); label.setLocation(new Point(0, 0)); label.setSize(rect.width, 20); label.setForegroundColor(new Color(null, 0, 0, 0)); scannableControlFigure.add(border); scannableControlFigure.add(label); scannableControlFigure.showIncrement(rect.x + 19, rect.y + 19); } if (me.button == 3) { Rectangle rect = ScannableControlEditPart.this.scannableControlFigure.getBounds().getCopy(); rect.x = rect.x + 1; rect.y = rect.y + 1; rect.height = rect.height - 1; rect.width = rect.width - 1; getFigure().translateToAbsolute(rect); border.setLocation(new Point(0, 0)); border.setSize(rect.width, rect.height); border.setForegroundColor(new Color(null, 0, 0, 0)); label.setText("Offset=" + offset); label.setLocation(new Point(0, 0)); label.setSize(rect.width, 20); label.setForegroundColor(new Color(null, 0, 0, 0)); scannableControlFigure.add(border); scannableControlFigure.add(label); scannableControlFigure.showOffset(rect.x + 19, rect.y + 19); } } }); decrement.addMouseListener(new MouseListener.Stub() { @Override public void mousePressed(MouseEvent me) { me.consume(); if (me.button == 2) { Rectangle rect = ScannableControlEditPart.this.scannableControlFigure.getBounds().getCopy(); rect.x = rect.x + 1; rect.y = rect.y + 1; rect.height = rect.height - 1; rect.width = rect.width - 1; getFigure().translateToAbsolute(rect); border.setLocation(new Point(0, 0)); border.setSize(rect.width, rect.height); border.setForegroundColor(new Color(null, 0, 0, 0)); label.setText("Increment=" + incrementVal); label.setLocation(new Point(0, 0)); label.setSize(rect.width, 20); label.setForegroundColor(new Color(null, 0, 0, 0)); scannableControlFigure.add(border); scannableControlFigure.add(label); scannableControlFigure.showIncrement(rect.x + 19, rect.y + 19); } if (me.button == 3) { Rectangle rect = ScannableControlEditPart.this.scannableControlFigure.getBounds().getCopy(); rect.x = rect.x + 1; rect.y = rect.y + 1; rect.height = rect.height - 1; rect.width = rect.width - 1; getFigure().translateToAbsolute(rect); border.setLocation(new Point(0, 0)); border.setSize(rect.width, rect.height); border.setForegroundColor(new Color(null, 0, 0, 0)); label.setText("Offset=" + offset); label.setLocation(new Point(0, 0)); label.setSize(rect.width, 20); label.setForegroundColor(new Color(null, 0, 0, 0)); scannableControlFigure.add(border); scannableControlFigure.add(label); scannableControlFigure.showOffset(rect.x + 19, rect.y + 19); } } }); } scannableControlFigure.getIncrementCellEditor().addListener(new ICellEditorListener() { @Override public void applyEditorValue() { scannableControlFigure.remove(label); scannableControlFigure.remove(border); try { incrementVal = Double.parseDouble(scannableControlFigure.getIncrementCellEditor().getValue().toString()); tooltipText = "Limits:Low=" + model.getLowLimit() + ",High=" + model.getHighLimit() + "\rUnits=" + model.getPropUnits() + "\rIncrement=" + incrementVal; model.setPropertyValue(AbstractWidgetModel.PROP_TOOLTIP, tooltipText); } catch (Exception e) { e.printStackTrace(); } } @Override public void cancelEditor() { } @Override public void editorValueChanged(boolean oldValidState, boolean newValidState) { } }); scannableControlFigure.setOffsetCellEditor(new TextCellEditor((Composite) getViewer().getControl())); scannableControlFigure.getOffsetCellEditor().addListener(new ICellEditorListener() { @Override public void applyEditorValue() { scannableControlFigure.remove(label); scannableControlFigure.remove(border); try { offset = Double.parseDouble(scannableControlFigure.getOffsetCellEditor().getValue().toString()); model.setOffset(offset); } catch (Exception e) { e.printStackTrace(); } } @Override public void cancelEditor() { } @Override public void editorValueChanged(boolean oldValidState, boolean newValidState) { } }); scannableControlFigure.add(increment); decrement.setLocation(new Point(0, 19)); decrement.setVisible(true); decrement.setSize(20, 20); decrement.setEnabled(amIHolder); decrement.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { if (amIHolder) { double lowerBound = model.getLowLimit(); if (model.getReadbackValue() + incrementVal >= lowerBound) { double incVal = incrementVal; model.setReadbackValue(scannableControlFigure.getDemand() - incVal); scannableControlFigure.setDemand(scannableControlFigure.getDemand() - incVal); } } } }); scannableControlFigure.add(decrement); InterfaceProvider.getBatonStateProvider().addBatonChangedObserver(new IObserver() { @Override public void update(Object source, Object arg) { if (arg instanceof BatonChanged) { amIHolder = InterfaceProvider.getBatonStateProvider().amIBatonHolder(); Display display = PlatformUI.getWorkbench().getDisplay(); if(!display.isDisposed()){ display.asyncExec(new Runnable() { @Override public void run() { scannableControlFigure.setBatton(amIHolder); increment.setEnabled(amIHolder); decrement.setEnabled(amIHolder); scannableControlFigure.repaint(); } }); } } } }); scannableControlFigure.setDemandCellEditor(new TextCellEditor((Composite) getViewer().getControl())); final Text text = (Text) scannableControlFigure.getDemandCellEditor().getControl(); text.addKeyListener(new KeyAdapter(){ @Override public void keyPressed(KeyEvent e) { showButtons=model.isShowButtons(); if (((e.keyCode == SWT.CR) || (e.keyCode == SWT.KEYPAD_CR)) && !showButtons) { String demandVal = scannableControlFigure.getDemandCellEditor().getValue().toString(); double demand = Double.parseDouble(demandVal); if((demand>=model.getLowLimit())&&(demand<=model.getHighLimit())){ scannableControlFigure.setDemand(demand); model.setReadbackValue(Double.parseDouble(scannableControlFigure.getDemandCellEditor().getValue().toString())); } } } }); goReal.setLocation(new Point(55+(dp*10)+((wholeDigits-1)*10), 19)); goReal.setVisible(model.isShowButtons()); goReal.setSize(60, 20); goReal.setEnabled(amIHolder); goReal.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { String demandVal = scannableControlFigure.getDemandCellEditor().getValue().toString(); double demand = Double.parseDouble(demandVal); if((demand>=model.getLowLimit())&&(demand<=model.getHighLimit()) && amIHolder){ scannableControlFigure.setDemand(demand); model.setReadbackValue(Double.parseDouble(scannableControlFigure.getDemandCellEditor().getValue().toString())); } } }); scannableControlFigure.add(goReal); goSim.setLocation(new Point(55+(dp*10)+((wholeDigits-1)*10), 39)); goSim.setVisible(model.isShowButtons()); goSim.setSize(60, 20); goSim.setEnabled(amIHolder); goSim.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { String demandVal = scannableControlFigure.getDemandCellEditor().getValue().toString(); double demand = Double.parseDouble(demandVal); if((demand>=model.getLowLimit())&&(demand<=model.getHighLimit()) && amIHolder){ scannableControlFigure.setDemand(demand); model.setSimReadbackValue(Double.parseDouble(scannableControlFigure.getDemandCellEditor().getValue().toString())); List<AbstractWidgetActionModel> actions = model.getActionData().getWidgetActions(); WidgetProperty property = model.getPropertyInternal(AbstractWidgetModel.PROP_ACTIONDATA); property.setManualValue("dummy"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } WidgetActionHandlerService.getInstance().performAction(model, actions.get(0)); } } }); scannableControlFigure.add(goSim); tooltipText = "Limits:Low=" + model.getLowLimit() + ",High=" + model.getHighLimit() + "\rUnits=" + model.getPropUnits() + "\rIncrement=" + incrementVal; model.setPropertyValue(AbstractWidgetModel.PROP_TOOLTIP, tooltipText); return scannableControlFigure; } @Override protected void registerPropertyChangeHandlers() { IWidgetPropertyChangeHandler handler = new IWidgetPropertyChangeHandler() { @Override public boolean handleChange(final Object oldValue, final Object newValue, final IFigure refreshableFigure) { ScannableControlFigure figure = (ScannableControlFigure) refreshableFigure; wholeDigits=1; figure.setReadback((Double)newValue); figure.repaint(); return true; } }; setPropertyChangeHandler(ScannableControlModel.PROP_READBACK_VALUE, handler); handler = new IWidgetPropertyChangeHandler() { @Override public boolean handleChange(final Object oldValue, final Object newValue, final IFigure refreshableFigure) { tooltipText = "Limits:Low=" + model.getLowLimit() + ",High=" + newValue + "\rUnits=" + model.getPropUnits() + "\rIncrement=" + incrementVal; model.setPropertyValue(AbstractWidgetModel.PROP_TOOLTIP, tooltipText); return true; } }; setPropertyChangeHandler(ScannableControlModel.PROP_HIGH_LIMIT, handler); handler = new IWidgetPropertyChangeHandler() { @Override public boolean handleChange(final Object oldValue, final Object newValue, final IFigure refreshableFigure) { tooltipText = "Limits:Low=" + newValue + ",High=" + model.getHighLimit() + "\rUnits=" + model.getPropUnits() + "\rIncrement=" + incrementVal; model.setPropertyValue(AbstractWidgetModel.PROP_TOOLTIP, tooltipText); return true; } }; setPropertyChangeHandler(ScannableControlModel.PROP_LOW_LIMIT, handler); handler = new IWidgetPropertyChangeHandler() { @Override public boolean handleChange(final Object oldValue, final Object newValue, final IFigure refreshableFigure) { tooltipText = "Limits:Low=" + model.getLowLimit() + ",High=" + model.getHighLimit() + "\rUnits="+ newValue + "\rIncrement=" + incrementVal; model.setPropertyValue(AbstractWidgetModel.PROP_TOOLTIP, tooltipText); return true; } }; setPropertyChangeHandler(ScannableControlModel.PROP_UNITS, handler); handler = new IWidgetPropertyChangeHandler() { @Override public boolean handleChange(final Object oldValue, final Object newValue, final IFigure refreshableFigure) { offset = (Double) newValue; return true; } }; setPropertyChangeHandler(ScannableControlModel.PROP_OFFSET, handler); handler = new IWidgetPropertyChangeHandler() { @Override public boolean handleChange(final Object oldValue, final Object newValue, final IFigure refreshableFigure) { dp = (int) Double.parseDouble(newValue.toString()); increment.setLocation(new Point(35+(dp*10)+((wholeDigits-1)*10), 19)); scannableControlFigure.setBoxWidth(15+(dp*10)+((wholeDigits-1)*10)); return true; } }; setPropertyChangeHandler(ScannableControlModel.PROP_DP, handler); handler = new IWidgetPropertyChangeHandler() { @Override public boolean handleChange(final Object oldValue, final Object newValue, final IFigure refreshableFigure) { showButtons = (Boolean) newValue; goReal.setVisible(showButtons); goSim.setVisible(showButtons); return true; } }; setPropertyChangeHandler(ScannableControlModel.PROP_SHOW_BUTTONS, handler); handler = new IWidgetPropertyChangeHandler() { @Override public boolean handleChange(final Object oldValue, final Object newValue, final IFigure refreshableFigure) { incrementVal=(Double) newValue; return true; } }; setPropertyChangeHandler(ScannableControlModel.PROP_DEF_INCREMENT, handler); } }