diff --git a/ARE/components/processor.adjustmentcurve/src/main/java/eu/asterics/component/processor/adjustmentcurve/AdjustmentCurveInstance.java b/ARE/components/processor.adjustmentcurve/src/main/java/eu/asterics/component/processor/adjustmentcurve/AdjustmentCurveInstance.java index 8727070bf..a4034bc04 100644 --- a/ARE/components/processor.adjustmentcurve/src/main/java/eu/asterics/component/processor/adjustmentcurve/AdjustmentCurveInstance.java +++ b/ARE/components/processor.adjustmentcurve/src/main/java/eu/asterics/component/processor/adjustmentcurve/AdjustmentCurveInstance.java @@ -64,11 +64,15 @@ public class AdjustmentCurveInstance extends AbstractRuntimeComponentInstance { final int MODE_CLIPMINMAX = 0; final int MODE_AUTOMINMAX = 1; + static final int OPMODE_FROM_FILE = 0; + static final int OPMODE_FROM_PROP_PERCENT = 1; + static final int OPMODE_FROM_PROP_ABSOLUTE = 2; + final int MAX_REDRAWSPEED = 50; private double input = 500; private double output = 500; - private int active = 0; + private boolean guiVisible = false; public Vector curvePoints = new Vector(); @@ -81,6 +85,8 @@ public class AdjustmentCurveInstance extends AbstractRuntimeComponentInstance { public int propFontSize = 14; public String propCaption = "dotMeter"; public String propFilename = "curve1"; + public int propOperationMode = 0; + String propCurvePoints; long timestamp = 0; @@ -99,7 +105,6 @@ public AdjustmentCurveInstance() { * CurvePoint e= new CurvePoint(); e.x=0; e.y=0; curvePoints.add(e); e= * new CurvePoint(); e.x=1000; e.y=1000; curvePoints.add(e); */ - } public synchronized void load() { @@ -131,6 +136,27 @@ public synchronized void load() { e.printStackTrace(); } } + + private void loadFromProperty() { + curvePoints.clear(); + try { + if (propCurvePoints != null && !"".equals(propCurvePoints)) { + propCurvePoints = propCurvePoints.replace(" ", ""); + String[] stringPoints = propCurvePoints.split("\\),"); + for (String stringPoint : stringPoints) { + stringPoint = stringPoint.replace(")", "").replace("(", ""); + String[] stringValues = stringPoint.split(","); + CurvePoint c = new CurvePoint(); + c.x = Double.parseDouble(stringValues[0]); + c.y = Double.parseDouble(stringValues[1]); + curvePoints.add(c); + } + } + } catch (Exception e) { + AstericsErrorHandling.instance.reportError(this, + "AdjustmentCurve: Could not parse 'propCurvePoints'. Make sure the format is like '(1,2),(2,3),(4,5)'."); + } + } public synchronized void save() { FileOutputStream fOut = null; @@ -161,30 +187,52 @@ public double calculateOutputValue(double x) { CurvePoint a, b; if (curvePoints.size() > 1) { - a = curvePoints.get(0); - if (x <= a.x) { - return (a.y); + if (x <= getX(0)) { + return (getY(0)); } - b = curvePoints.get(curvePoints.size() - 1); - if (x >= b.x) { - return (b.y); + if (x >= getX(curvePoints.size() - 1)) { + return (getY(curvePoints.size() - 1)); } int i = 0; - while ((i < curvePoints.size() - 1) && (x > curvePoints.get(i).x)) { + while ((i < curvePoints.size() - 1) && (x > getX(i))) { i++; } - a = curvePoints.get(i - 1); - b = curvePoints.get(i); + double ax = getX(i - 1); + double ay = getY(i - 1); + double bx = getX(i); + double by = getY(i); // System.out.println("x="+x+", a.x="+a.x+",b.x="+b.x); - double f = (x - a.x) / (b.x - a.x); - return (a.y + (b.y - a.y) * f); + double f = (x - ax) / (bx - ax); + return (ay + (by - ay) * f); } else { return (0); } } + private double getX(int index) { + double value = curvePoints.get(index).x; + if(propOperationMode == OPMODE_FROM_PROP_PERCENT) { + value = value > 100 ? 100 : value; + value = value < 0 ? 0 : value; + double range = propInMax - propInMin; + value = (value * range / 100) + propInMin; + } + return value; + } + + private double getY(int index) { + double value = curvePoints.get(index).y; + if(propOperationMode == OPMODE_FROM_PROP_PERCENT) { + value = value > 100 ? 100 : value; + value = value < 0 ? 0 : value; + double range = propOutMax - propOutMin; + value = (value * range / 100) + propOutMin; + } + return value; + } + /** * returns an Input Port. * @@ -248,12 +296,18 @@ public Object getRuntimePropertyValue(String propertyName) { if ("mode".equalsIgnoreCase(propertyName)) { return propMode; } + if ("operationMode".equalsIgnoreCase(propertyName)) { + return propOperationMode; + } if ("fontSize".equalsIgnoreCase(propertyName)) { return propFontSize; } if ("caption".equalsIgnoreCase(propertyName)) { return propCaption; } + if ("curvePoints".equalsIgnoreCase(propertyName)) { + return propCurvePoints; + } return null; } @@ -300,16 +354,12 @@ public Object setRuntimePropertyValue(String propertyName, Object newValue) { if ("true".equalsIgnoreCase((String) newValue)) { propDisplayGui = true; if (oldValue == false) { - gui = new GUI(this, AREServices.instance.getAvailableSpace(this)); - AREServices.instance.displayPanel(gui, this, true); - gui.updateGraph(input, output); - active = 1; + showGui(); } } else if ("false".equalsIgnoreCase((String) newValue)) { propDisplayGui = false; - if ((oldValue == true) && (gui != null)) { - AREServices.instance.displayPanel(gui, this, false); - active = 0; + if (oldValue == true) { + hideGui(); } } return oldValue; @@ -354,7 +404,29 @@ public Object setRuntimePropertyValue(String propertyName, Object newValue) { } return oldValue; } - + if ("operationMode".equalsIgnoreCase(propertyName)) { + final int oldValue = propOperationMode; + propOperationMode = Integer.parseInt(newValue.toString()); + if (oldValue != propOperationMode) { + switch (propOperationMode) { + case OPMODE_FROM_FILE: + load(); + if (propDisplayGui) { + showGui(); + } + break; + case OPMODE_FROM_PROP_PERCENT: + loadFromProperty(); + hideGui(); + break; + case OPMODE_FROM_PROP_ABSOLUTE: + loadFromProperty(); + hideGui(); + break; + } + } + return oldValue; + } if ("fontSize".equalsIgnoreCase(propertyName)) { final Object oldValue = propFontSize; propFontSize = Integer.parseInt(newValue.toString()); @@ -365,6 +437,14 @@ public Object setRuntimePropertyValue(String propertyName, Object newValue) { propCaption = newValue.toString(); return oldValue; } + if ("curvePoints".equalsIgnoreCase(propertyName)) { + final Object oldValue = propCurvePoints; + propCurvePoints = newValue.toString(); + if(propOperationMode == OPMODE_FROM_PROP_ABSOLUTE || propOperationMode == OPMODE_FROM_PROP_PERCENT) { + loadFromProperty(); + } + return oldValue; + } return null; } @@ -376,7 +456,7 @@ public Object setRuntimePropertyValue(String propertyName, Object newValue) { public void receiveData(byte[] data) { input = ConversionUtils.doubleFromBytes(data); output = calculateOutputValue(input); - if ((propDisplayGui == true) && (active == 1)) { + if ((propDisplayGui == true) && guiVisible) { if (System.currentTimeMillis() - timestamp > MAX_REDRAWSPEED) { gui.updateGraph(input, output); timestamp = System.currentTimeMillis(); @@ -405,13 +485,9 @@ public void receiveData(byte[] data) { final IRuntimeEventListenerPort elpDisplayGui = new IRuntimeEventListenerPort() { @Override public void receiveEvent(final String data) { - if (propDisplayGui == false) { propDisplayGui = true; - gui = new GUI(thisInstance, AREServices.instance.getAvailableSpace(thisInstance)); - AREServices.instance.displayPanel(gui, thisInstance, true); - gui.updateGraph(input, output); - active = 1; + showGui(); } } }; @@ -419,10 +495,7 @@ public void receiveEvent(final String data) { @Override public void receiveEvent(final String data) { propDisplayGui = false; - if (gui != null) { - AREServices.instance.displayPanel(gui, thisInstance, false); - } - active = 0; + hideGui(); // gui.updateGraph(input,output); } }; @@ -430,7 +503,7 @@ public void receiveEvent(final String data) { @Override public void receiveEvent(final String data) { // System.out.println("Load Curve"); - // if (active==0) + // if (guiVisible) load(); } }; @@ -452,11 +525,8 @@ public void start() { output = calculateOutputValue(input); if (propDisplayGui == true) { - gui = new GUI(this, AREServices.instance.getAvailableSpace(this)); - AREServices.instance.displayPanel(gui, this, true); - gui.updateGraph(input, output); + showGui(); } - active = 1; super.start(); } @@ -481,9 +551,24 @@ public void resume() { */ @Override public void stop() { - AREServices.instance.displayPanel(gui, this, false); - - active = 0; + hideGui(); super.stop(); } + + private void showGui() { + if(propOperationMode != OPMODE_FROM_FILE || guiVisible) { + return; + } + gui = new GUI(this, AREServices.instance.getAvailableSpace(this)); + AREServices.instance.displayPanel(gui, this, true); + gui.updateGraph(input, output); + guiVisible = true; + } + + private void hideGui() { + if (gui != null) { + AREServices.instance.displayPanel(gui, this, false); + guiVisible = false; + } + } } \ No newline at end of file diff --git a/ARE/components/processor.adjustmentcurve/src/main/resources/bundle_descriptor.xml b/ARE/components/processor.adjustmentcurve/src/main/resources/bundle_descriptor.xml index 05f5ee65b..53b5cf84e 100644 --- a/ARE/components/processor.adjustmentcurve/src/main/resources/bundle_descriptor.xml +++ b/ARE/components/processor.adjustmentcurve/src/main/resources/bundle_descriptor.xml @@ -66,7 +66,7 @@ type="integer" value="1" combobox="clip to min and max//autoupdate min and max" - description="how to deal with input values exceeding min or max"/> + description="how to deal with input values exceeding min or max (GUI related only)"/> + description="caption of the curve window"/> + + 5000 diff --git a/Documentation/ACS-Help/HTML/Plugins/processors/AdjustmentCurve.htm b/Documentation/ACS-Help/HTML/Plugins/processors/AdjustmentCurve.htm index 7cba7a345..202f8716b 100644 --- a/Documentation/ACS-Help/HTML/Plugins/processors/AdjustmentCurve.htm +++ b/Documentation/ACS-Help/HTML/Plugins/processors/AdjustmentCurve.htm @@ -40,9 +40,18 @@

Properties

  • outMax [double]: Sets the maximum value of the input range.
  • outMin [double]: Sets the minimum value of the output range.
  • outMax [double]: Sets the maximum value of the output range.
  • -
  • mode [combobox]: "autoupdate min and max" modifies the input range if incoming values exceed the current minimum or maximum, "clip to min and max" which keeps the values as set by the min/max properties.
  • +
  • mode [combobox]: GUI mode: "autoupdate min and max" modifies the shown input range of the GUI if incoming values exceed the current minimum or maximum, "clip to min and max" which keeps the values as set by the min/max properties.
  • fontSize [integer]: The size of the font for dispaying text in the GUI.
  • caption [string]: The caption of the AdjustmentCurve GUI.
  • +
  • + operationMode [integer]: Selects the mode of operation of the adjustment curve component, following modes are available: +
      +
    • "use file and GUI": Default mode. The x/y points of the adjustment curve are defined using the graphical user interface and are stored and loaded from a file, defined by property 'filename'.
    • +
    • "use property curvePoints (percent values)": No GUI is shown, x/y points of the adjustmentcurve are defined by property 'curvePoints' and interpreted as relative percentatge values of given in/out min/max values. In this mode no external file is needed or used.
    • +
    • "use property curvePoints (absolute values)": Same mode as before, using property 'curvePoints' with the difference that x/y values are defined as absolute values.
    • +
    +
  • +
  • curvePoints [string]: For operation mode 'use property curvePoints' this property defines the x/y points of the adjustment curve. The expected format are comma-separated tuples of double or integer values like e.g. '(10.0,0.0),(10,10),(100,100)' defining 3 x/y points.
  • \ No newline at end of file diff --git a/Documentation/ACS-Help/HTML/Plugins/processors/img/AdjustmentCurve.jpg b/Documentation/ACS-Help/HTML/Plugins/processors/img/AdjustmentCurve.jpg index ee4e6483b..5b31a0ba1 100644 Binary files a/Documentation/ACS-Help/HTML/Plugins/processors/img/AdjustmentCurve.jpg and b/Documentation/ACS-Help/HTML/Plugins/processors/img/AdjustmentCurve.jpg differ