001/* An abstract attribute for a visible text annotation. 002 003 Copyright (c) 2004-2014 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.kernel.attributes; 029 030import java.awt.Color; 031import java.awt.Font; 032import java.awt.GraphicsEnvironment; 033 034import javax.swing.SwingConstants; 035 036import ptolemy.actor.gui.ColorAttribute; 037import ptolemy.data.BooleanToken; 038import ptolemy.data.IntToken; 039import ptolemy.data.expr.Parameter; 040import ptolemy.data.expr.StringParameter; 041import ptolemy.data.type.BaseType; 042import ptolemy.kernel.util.Attribute; 043import ptolemy.kernel.util.IllegalActionException; 044import ptolemy.kernel.util.NameDuplicationException; 045import ptolemy.kernel.util.NamedObj; 046import ptolemy.kernel.util.Workspace; 047import ptolemy.vergil.icon.TextIcon; 048 049/////////////////////////////////////////////////////////////////// 050//// AbstractTextAttribute 051 052/** 053 An abstract base class for text annotations. 054 <p> 055 @author Edward A. Lee, Steve Neuendorffer 056 @version $Id$ 057 @since Ptolemy II 4.1 058 @Pt.ProposedRating Yellow (eal) 059 @Pt.AcceptedRating Red (cxh) 060 */ 061public class AbstractTextAttribute extends VisibleAttribute { 062 /** Construct an attribute with the given name contained by the 063 * specified container. The container argument must not be null, or a 064 * NullPointerException will be thrown. This attribute will use the 065 * workspace of the container for synchronization and version counts. 066 * If the name argument is null, then the name is set to the empty 067 * string. Increment the version of the workspace. 068 * @param container The container. 069 * @param name The name of this attribute. 070 * @exception IllegalActionException If the attribute is not of an 071 * acceptable class for the container, or if the name contains a period. 072 * @exception NameDuplicationException If the name coincides with 073 * an attribute already in the container. 074 */ 075 public AbstractTextAttribute(NamedObj container, String name) 076 throws IllegalActionException, NameDuplicationException { 077 super(container, name); 078 079 _icon = new TextIcon(this, "_icon"); 080 _icon.setPersistent(false); 081 082 textSize = new Parameter(this, "textSize"); 083 textSize.setExpression("14"); 084 textSize.setTypeEquals(BaseType.INT); 085 textSize.addChoice("9"); 086 textSize.addChoice("10"); 087 textSize.addChoice("11"); 088 textSize.addChoice("12"); 089 textSize.addChoice("14"); 090 textSize.addChoice("18"); 091 textSize.addChoice("24"); 092 textSize.addChoice("32"); 093 094 textColor = new ColorAttribute(this, "textColor"); 095 textColor.setExpression("{0.0, 0.0, 1.0, 1.0}"); 096 097 // Get font family names from the Font class in Java. 098 // This includes logical font names, per Font class in Java: 099 // Dialog, DialogInput, Monospaced, Serif, SansSerif, or Symbol. 100 fontFamily = new StringParameter(this, "fontFamily"); 101 fontFamily.setExpression("SansSerif"); 102 103 String[] families = GraphicsEnvironment.getLocalGraphicsEnvironment() 104 .getAvailableFontFamilyNames(); 105 106 for (String familie : families) { 107 fontFamily.addChoice(familie); 108 } 109 110 bold = new Parameter(this, "bold"); 111 bold.setExpression("false"); 112 bold.setTypeEquals(BaseType.BOOLEAN); 113 114 italic = new Parameter(this, "italic"); 115 italic.setExpression("false"); 116 italic.setTypeEquals(BaseType.BOOLEAN); 117 118 anchor = new StringParameter(this, "anchor"); 119 anchor.setExpression("northwest"); 120 anchor.addChoice("center"); 121 anchor.addChoice("east"); 122 anchor.addChoice("north"); 123 anchor.addChoice("northeast"); 124 anchor.addChoice("northwest"); 125 anchor.addChoice("south"); 126 anchor.addChoice("southeast"); 127 anchor.addChoice("southwest"); 128 anchor.addChoice("west"); 129 } 130 131 /////////////////////////////////////////////////////////////////// 132 //// parameters //// 133 134 /** Indication of which point of the text should be aligned to the 135 * grid. The possible values are "center", "east", "north", 136 * "northeast", "northwest" (the default), "south", "sountheast", 137 * "southwest", or "west". 138 */ 139 public StringParameter anchor; 140 141 /** A boolean indicating whether the font should be bold. 142 * This defaults to false. 143 */ 144 public Parameter bold; 145 146 /** The font family. This is a string that defaults to "SansSerif". 147 */ 148 public StringParameter fontFamily; 149 150 /** A boolean indicating whether the font should be italic. 151 * This defaults to false. 152 */ 153 public Parameter italic; 154 155 /** The text color. This is a string representing an array with 156 * four elements, red, green, blue, and alpha, where alpha is 157 * transparency. The default is "{0.0, 0.0, 0.0, 1.0}", which 158 * represents an opaque black. 159 */ 160 public ColorAttribute textColor; 161 162 /** The text size. This is an int that defaults to 14. 163 */ 164 public Parameter textSize; 165 166 /////////////////////////////////////////////////////////////////// 167 //// public methods //// 168 169 /** React to a changes in the attributes by changing the icon. 170 * @param attribute The attribute that changed. 171 * @exception IllegalActionException If the change is not acceptable 172 * to this container (should not be thrown). 173 */ 174 @Override 175 public void attributeChanged(Attribute attribute) 176 throws IllegalActionException { 177 if (attribute == anchor) { 178 String anchorValue = anchor.stringValue(); 179 if (anchorValue.equals("center")) { 180 _icon.setAnchor(SwingConstants.CENTER); 181 } else if (anchorValue.equals("east")) { 182 _icon.setAnchor(SwingConstants.EAST); 183 } else if (anchorValue.equals("north")) { 184 _icon.setAnchor(SwingConstants.NORTH); 185 } else if (anchorValue.equals("northeast")) { 186 _icon.setAnchor(SwingConstants.NORTH_EAST); 187 } else if (anchorValue.equals("south")) { 188 _icon.setAnchor(SwingConstants.SOUTH); 189 } else if (anchorValue.equals("southeast")) { 190 _icon.setAnchor(SwingConstants.SOUTH_EAST); 191 } else if (anchorValue.equals("southwest")) { 192 _icon.setAnchor(SwingConstants.SOUTH_WEST); 193 } else if (anchorValue.equals("west")) { 194 _icon.setAnchor(SwingConstants.WEST); 195 } else { 196 _icon.setAnchor(SwingConstants.NORTH_WEST); 197 } 198 } else if ((attribute == fontFamily || attribute == textSize 199 || attribute == bold || attribute == italic) 200 && !_inAttributeChanged) { 201 try { 202 // Prevent redundant actions here... When we evaluate the 203 // _other_ attribute here (whichever one did _not_ trigger 204 // this call, it will likely trigger another call to 205 // attributeChanged(), which will result in this action 206 // being performed twice. 207 _inAttributeChanged = true; 208 209 int sizeValue = ((IntToken) textSize.getToken()).intValue(); 210 String familyValue = fontFamily.stringValue(); 211 int styleValue = Font.PLAIN; 212 213 if (((BooleanToken) bold.getToken()).booleanValue()) { 214 styleValue = styleValue | Font.BOLD; 215 } 216 217 if (((BooleanToken) italic.getToken()).booleanValue()) { 218 styleValue = styleValue | Font.ITALIC; 219 } 220 221 Font fontValue = new Font(familyValue, styleValue, sizeValue); 222 _icon.setFont(fontValue); 223 } finally { 224 _inAttributeChanged = false; 225 } 226 } else if (attribute == textColor) { 227 Color colorValue = textColor.asColor(); 228 _icon.setTextColor(colorValue); 229 } else { 230 super.attributeChanged(attribute); 231 } 232 } 233 234 /** Clone the object into the specified workspace. 235 * @param workspace The workspace for the new object. 236 * @return A new AbstractTextAttribute. 237 * @exception CloneNotSupportedException If any of the attributes 238 * cannot be cloned. 239 */ 240 @Override 241 public Object clone(Workspace workspace) throws CloneNotSupportedException { 242 AbstractTextAttribute result = (AbstractTextAttribute) super.clone( 243 workspace); 244 result._icon = (TextIcon) result.getAttribute("_icon"); 245 return result; 246 } 247 248 /////////////////////////////////////////////////////////////////// 249 //// protected members //// 250 251 /** The text icon. */ 252 protected TextIcon _icon; 253 254 /////////////////////////////////////////////////////////////////// 255 //// private variables //// 256 private boolean _inAttributeChanged = false; 257}