001 /*
002 *
003 * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
004 *
005 */
006 package demo.sharededitor.models;
007
008 import java.awt.Color;
009 import java.awt.Font;
010 import java.awt.Graphics2D;
011 import java.awt.Image;
012 import java.awt.Rectangle;
013 import java.awt.Shape;
014 import java.awt.font.FontRenderContext;
015 import java.awt.font.TextAttribute;
016 import java.awt.font.TextLayout;
017 import java.awt.geom.AffineTransform;
018 import java.awt.geom.Rectangle2D;
019 import java.text.AttributedCharacterIterator;
020 import java.text.AttributedString;
021
022 import demo.sharededitor.ui.Fontable;
023 import demo.sharededitor.ui.Texturable;
024
025 public class Text extends BaseObject implements Fontable, Texturable {
026 private Shape shape = null;
027
028 protected Shape getShape() {
029 return shape;
030 }
031
032 private Shape[] anchors = new Shape[0];
033
034 protected Shape[] getAnchors() {
035 return anchors;
036 }
037
038 public boolean isAt(int x, int y) {
039 if (shape == null)
040 return false;
041
042 Shape bounds = new Rectangle2D.Double(shape.getBounds().x - 5, shape
043 .getBounds().y - 5, shape.getBounds().width + 5, shape
044 .getBounds().height + 5);
045 return bounds.contains(x, y);
046 }
047
048 public synchronized void move(int dx, int dy) {
049 this.x += dx;
050 this.y += dy;
051 notifyListeners(this);
052 }
053
054 public synchronized void resize(int x, int y) {
055 // we purposely don't allow the resizing operation for Text objects
056 }
057
058 public synchronized void clearTexture() {
059 super.clearTexture();
060 }
061
062 public synchronized void setTexture(Image image) {
063 super.setTexture(image);
064 notifyListeners(this);
065 }
066
067 private String fontName;
068
069 private int fontSize;
070
071 public synchronized void setFontInfo(String name, int size, String text) {
072 this.text = text;
073 this.fontName = name;
074 this.fontSize = size;
075 notifyListeners(this);
076 }
077
078 public synchronized void setFontName(String name) {
079 this.fontName = name;
080 notifyListeners(this);
081 }
082
083 public synchronized void setFontSize(int size) {
084 this.fontSize = size;
085 notifyListeners(this);
086 }
087
088 private String text;
089
090 public synchronized void setText(String text) {
091 this.text = text;
092 notifyListeners(this);
093 }
094
095 public String getText() {
096 return this.text;
097 }
098
099 public synchronized void appendToText(char c) {
100 if (!this.isInverted)
101 this.text += c;
102 else {
103 this.text = c + "";
104 this.isInverted = false;
105 }
106 notifyListeners(this);
107 }
108
109 private int x, y;
110
111 private synchronized void renderText(FontRenderContext frc,
112 boolean showCursor) {
113 String text = this.text;
114 if (showCursor || (text.length() == 0)) {
115 if (text.length() > 0)
116 text = this.isInverted ? text : text + "|";
117 else
118 text = "_";
119 }
120
121 AttributedString as = new AttributedString(text);
122 as.addAttribute(TextAttribute.FONT, new Font(this.fontName, Font.PLAIN,
123 this.fontSize));
124 AttributedCharacterIterator aci = as.getIterator();
125 TextLayout tl = new TextLayout(aci, frc);
126 this.shape = tl.getOutline(AffineTransform.getTranslateInstance(x, y));
127 }
128
129 public void draw(Graphics2D g, boolean showAnchors) {
130 renderText(g.getFontRenderContext(), showAnchors);
131 super.draw(g, showAnchors);
132 if (showAnchors) {
133 Rectangle bounds = shape.getBounds();
134 Shape border = new Rectangle2D.Double(bounds.x - 5, bounds.y - 5,
135 bounds.width + 5, bounds.height + 5);
136 if (this.isInverted) {
137 g.setXORMode(Color.LIGHT_GRAY);
138 g.fillRect(bounds.x - 5, bounds.y - 5, bounds.width + 5,
139 bounds.height + 5);
140 g.setPaintMode();
141 }
142 g.setColor(Color.LIGHT_GRAY);
143 g.draw(border);
144 }
145 }
146
147 private boolean isInverted;
148
149 public synchronized void selectAction(boolean flag) {
150 if (!this.isInverted)
151 return;
152 this.isInverted = false;
153 }
154
155 public synchronized void alternateSelectAction(boolean flag) {
156 if (this.isInverted)
157 return;
158 this.isInverted = true;
159 }
160
161 public Text() {
162 this.isInverted = false;
163 this.text = "";
164 }
165 }
|