001/* An icon providing visual indication when constraints are violated.
002
003 Copyright (c) 2006-2016 The Regents of the University of California.
004 All rights reserved.
005 Permission is hereby granted, without written agreement and without
006 license or royalty fees, to use, copy, modify, and distribute this
007 software and its documentation for any purpose, provided that the above
008 copyright notice and the following two paragraphs appear in all copies
009 of this software.
010
011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
015 SUCH DAMAGE.
016
017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
022 ENHANCEMENTS, OR MODIFICATIONS.
023
024 PT_COPYRIGHT_VERSION_2
025 COPYRIGHTENDKEY
026
027 */
028package ptolemy.vergil.icon;
029
030import diva.canvas.Figure;
031import ptolemy.actor.gui.ColorAttribute;
032import ptolemy.data.DoubleToken;
033import ptolemy.data.expr.ConstraintMonitor;
034import ptolemy.data.expr.Parameter;
035import ptolemy.data.type.BaseType;
036import ptolemy.kernel.util.IllegalActionException;
037import ptolemy.kernel.util.NameDuplicationException;
038import ptolemy.kernel.util.NamedObj;
039
040///////////////////////////////////////////////////////////////////
041//// ConstraintMonitorIcon
042
043/**
044An icon providing visual indication when constraints are violated.
045This works specifically with {@link ConstraintMonitor}.
046
047 @author Edward A. Lee
048 @version $Id$
049 @since Ptolemy II 10.0
050 @Pt.ProposedRating Yellow (eal)
051 @Pt.AcceptedRating Red (celaine)
052 */
053public class ConstraintMonitorIcon extends BoxedValueIcon {
054
055    /** Create a new icon with the given name in the given container.
056     *  The container is required to implement Settable, or an exception
057     *  will be thrown.
058     *  @param container The container for this attribute.
059     *  @param name The name of this attribute.
060     *  @exception IllegalActionException If thrown by the parent
061     *  class or while setting an attribute
062     *  @exception NameDuplicationException If the name coincides with
063     *   an attribute already in the container.
064     */
065    public ConstraintMonitorIcon(NamedObj container, String name)
066            throws NameDuplicationException, IllegalActionException {
067        super(container, name);
068
069        okColor = new ColorAttribute(this, "okColor");
070        okColor.setExpression("{0.3, 1.0, 0.3, 1.0}");
071
072        closeColor = new ColorAttribute(this, "closeColor");
073        closeColor.setExpression("{1.0, 1.0, 0.0, 1.0}");
074
075        closeFraction = new Parameter(this, "closeFraction");
076        closeFraction.setTypeEquals(BaseType.DOUBLE);
077        closeFraction.setExpression("0.1");
078
079        highColor = new ColorAttribute(this, "highColor");
080        highColor.setExpression("{1.0, 0.3, 0.3, 1.0}");
081    }
082
083    ///////////////////////////////////////////////////////////////////
084    ////                         parameters                        ////
085
086    /** Color of the box to use when the constraint is close
087     *  to the threshold.
088     *  This defaults to yellow.
089     */
090    public ColorAttribute closeColor;
091
092    /** Fraction of the threshold that is to be considered close
093     *  to the threshold. This is a double that defaults to 0.1.
094     */
095    public Parameter closeFraction;
096
097    /** Color of the box to use when the constraint is above
098     *  the threshold.
099     *  This defaults to pink.
100     */
101    public ColorAttribute highColor;
102
103    /** Color of the box to use when the constraint is satisfied.
104     *  This defaults to a light green.
105     */
106    public ColorAttribute okColor;
107
108    ///////////////////////////////////////////////////////////////////
109    ////                         public methods                    ////
110
111    /** Override the base class to modify the background color, if appropriate.
112     *  @return A new figure.
113     */
114    @Override
115    public Figure createBackgroundFigure() {
116        ConstraintMonitor container = (ConstraintMonitor) getContainer();
117        try {
118            double aggregateValue = ((DoubleToken) container.getToken())
119                    .doubleValue();
120            double threshold = ((DoubleToken) container.threshold.getToken())
121                    .doubleValue();
122            double close = ((DoubleToken) closeFraction.getToken())
123                    .doubleValue();
124            if (aggregateValue >= threshold) {
125                boxColor.setToken(highColor.getToken());
126            } else if ((threshold != Double.POSITIVE_INFINITY)
127                    && (threshold - aggregateValue) <= close * threshold) {
128                boxColor.setToken(closeColor.getToken());
129            } else {
130                boxColor.setToken(okColor.getToken());
131            }
132        } catch (IllegalActionException e) {
133            // Ignore and use default color.
134        }
135
136        return super.createBackgroundFigure();
137    }
138
139    /** Override the base class to throw an exception if the container is
140     *  not an instance of {@link ConstraintMonitor}.
141     *  @exception IllegalActionException If this attribute is not of the
142     *   expected class for the container, or it has no name,
143     *   or the attribute and container are not in the same workspace, or
144     *   the proposed container would result in recursive containment.
145     *  @exception NameDuplicationException If the container already has
146     *   an attribute with the name of this attribute.
147     *  @see #getContainer()
148     */
149    @Override
150    public void setContainer(NamedObj container)
151            throws IllegalActionException, NameDuplicationException {
152        if (container != null && !(container instanceof ConstraintMonitor)) {
153            throw new IllegalActionException(this, container,
154                    "Container is required to be a ConstraintMonitor");
155        }
156        super.setContainer(container);
157    }
158}