source: trunk/src/org/expeditee/items/Dot.java@ 115

Last change on this file since 115 was 115, checked in by ra33, 16 years ago

added functionality for dockable @v's

File size: 7.5 KB
Line 
1package org.expeditee.items;
2
3import java.awt.Color;
4import java.awt.Graphics2D;
5import java.awt.Polygon;
6import java.awt.Rectangle;
7import java.util.ArrayList;
8import java.util.LinkedList;
9import java.util.List;
10
11import org.expeditee.gui.DisplayIO;
12import org.expeditee.gui.Frame;
13import org.expeditee.gui.FrameKeyboardActions;
14
15/**
16 * Represents a point on the screen. All Point objects are stored as x,y pairs
17 * with an Item ID. Note: Lines and all combinates of lines (rectangles, etc)
18 * are represented only as Points that share line IDs.
19 *
20 * @author jdm18
21 *
22 */
23public class Dot extends Item {
24
25 // Standard Item variables
26
27 private static final int _MINIMUM_DOT_SIZE = 6;
28
29 private int _pointType = Item.POINTTYPE_SQUARE;
30
31 private boolean _filled = true;
32
33 public Dot(int id) {
34 super();
35 setID(id);
36 }
37
38 /**
39 * Constructs a new Point with the given x,y coordinates and Item ID.
40 *
41 * @param x
42 * The x coordinate of this point
43 * @param y
44 * The y coordinate of this point
45 * @param id
46 * The Item ID of this Point
47 */
48 public Dot(int x, int y, int id) {
49 super();
50 setID(id);
51 setPosition(x, y);
52 }
53
54 public void setPointType(int type) {
55 _pointType = type;
56 }
57
58 public void useFilledPoints(boolean val) {
59 _filled = val;
60 }
61
62 /**
63 * Sets the 'thickness' of this Dot, that is, how many pixels this Dot
64 * should be.
65 *
66 * @param thick
67 * The number of pixels to use when displaying this Dot The Dot
68 * is displayed as a thick x thick square.
69 */
70 @Override
71 public void setThickness(float thick) {
72 super.setThickness(thick);
73
74 updatePolygon();
75 }
76
77 @Override
78 public void setColor(Color c) {
79 super.setColor(c);
80
81 // update the colour of any lines
82 for (Line line : getLines())
83 line.setColor(c);
84 }
85
86 @Override
87 public void paint(Graphics2D g) {
88 if (isHighlighted() /* && !Frame.FreeItems.contains(this) */) {
89 Color highlightColor = getHighlightColor();
90 g.setColor(highlightColor);
91 g.setStroke(HIGHLIGHT_STROKE);
92 //g.setStroke()
93 // Draw the highlighting rectangle surrounding the dot
94 // this is drawn even if its part of a rectangle
95 Rectangle rect = getPolygon().getBounds();
96 if (_mode == HighlightMode.Enclosed ||
97 // Make sure single dots are highlighted filled
98 this.getConnected().size() <= 1)
99 g.fillRect(rect.x, rect.y, rect.width, rect.height);
100 else if (_mode == HighlightMode.Connected)
101 g.drawRect(rect.x, rect.y, rect.width, rect.height);
102 else if (_mode == HighlightMode.Normal) {
103 g.fillOval(rect.x, rect.y, rect.width, rect.height);
104 }
105 //System.out.println(_mode.toString());
106 }
107
108 // dots on lines are hidden
109 if (getLines().size() > 0)
110 return;
111
112 g.setColor(getPaintColor());
113
114 int thick = (int) getThickness();
115 if (thick < 2)
116 thick = 2;
117
118 int width = thick / 2;
119
120 if (_pointType == Item.POINTTYPE_CIRCLE) {
121 int points = 40;
122
123 double radians = 0.0;
124 int xPoints[] = new int[points];
125 int yPoints[] = new int[xPoints.length];
126
127 for (int i = 0; i < xPoints.length; i++) {
128 xPoints[i] = getX() + (int) (width * Math.cos(radians));
129 yPoints[i] = getY() + (int) (width * Math.sin(radians));
130 radians += (2.0 * Math.PI) / xPoints.length;
131 }
132
133 if (_filled)
134 g.fillPolygon(new Polygon(xPoints, yPoints, xPoints.length));
135 else
136 g.drawPolygon(new Polygon(xPoints, yPoints, xPoints.length));
137 } else {
138 if (_filled)
139 g.fillRect(getX() - width, getY() - width, thick, thick);
140 else
141 g.drawRect(getX() - width, getY() - width, thick, thick);
142 }
143
144 }
145
146 /**
147 * Updates the points of the polygon surrounding this Dot
148 */
149 public void updatePolygon() {
150 int thick = Math.round(getThickness());
151 // Sets a minimum size for the dot
152 thick = Math.max(thick, _MINIMUM_DOT_SIZE);
153
154 int x = getX() - thick / 2;
155 int y = getY() - thick / 2;
156
157 _poly = new Polygon();
158 _poly.addPoint(x - getGravity(), y - getGravity());
159 _poly.addPoint(x + thick + getGravity(), y - getGravity());
160 _poly.addPoint(x + thick + getGravity(), y + thick + getGravity());
161 _poly.addPoint(x - getGravity(), y + thick + getGravity());
162 }
163
164 @Override
165 public Item copy() {
166 Dot copy = new Dot(getX(), getY(), getID());
167
168 Item.DuplicateItem(this, copy);
169
170 copy.setThickness(getThickness());
171 copy.setPointType(_pointType);
172 copy.useFilledPoints(_filled);
173
174 return copy;
175 }
176
177 @Override
178 public int setHighlightColor() {
179 super.setHighlightColor();
180
181 return Item.DEFAULT_CURSOR;
182 }
183
184 @Override
185 public void setAnnotation(boolean val) {
186 DisplayIO.setCursorPosition(this.getPosition());
187 FrameKeyboardActions.replaceDot(this, '@');
188 }
189
190 @Override
191 public Item merge(Item merger, int mouseX, int mouseY) {
192 // if the item being merged with is another Dot
193 if (merger instanceof Dot) {
194 if(merger.hasEnclosures() || hasEnclosures())
195 return merger;
196
197 Item dot = (Item) merger;
198 merger.setPosition(this.getPosition());
199 // prevent concurrency issues if removing lines
200 List<Line> lines = new ArrayList<Line>();
201 lines.addAll(dot.getLines());
202
203 for (Line line : lines) {
204 // remove lines that are in common
205 if (getLines().contains(line)) {
206 dot.removeLine(line);
207 removeLine(line);
208 } else {
209 // check for duplicated lines as a result of merging
210 Item check = (Item) line.getOppositeEnd(dot);
211 boolean dup = false;
212
213 for (Line l : getLines()) {
214 Item opposite = l.getOppositeEnd(this);
215
216 if (check == opposite) {
217 line.getStartItem().removeLine(line);
218 line.getEndItem().removeLine(line);
219 dup = true;
220 break;
221 }
222 }
223
224 if (!dup)
225 line.replaceLineEnd(dot, this);
226 }
227 }
228
229 setThickness(dot.getThickness());
230 setColor(dot.getColor());
231 setFillColor(dot.getFillColor());
232
233 return null;
234 }
235
236 if (merger instanceof Text) {
237 merger.setPosition(this.getPosition());
238 List<Line> lines = new LinkedList<Line>();
239 lines.addAll(getLines());
240 for (Line line : lines)
241 line.replaceLineEnd(this, merger);
242 this.delete();
243 return merger;
244 }
245
246 // if the item being merged with is a Line
247 if (merger instanceof Line) {
248 Line line = (Line) merger;
249 // if this dot is part of the line then keep it, otherwise it
250 // can be removed
251 if (line.getOppositeEnd(this) != null && getLines().contains(line))
252 return merger;
253 else
254 return null;
255 }
256
257 return merger;
258 }
259
260 @Override
261 public String getTypeAndID() {
262 return "P " + getID();
263 }
264
265 @Override
266 public void delete() {
267 super.delete();
268
269 for (Line l : this.getLines())
270 l.delete();
271 }
272
273 @Override
274 public void anchor() {
275 Frame current = getParentOrCurrentFrame();
276 //This is to make lines anchored across frames be on one frame
277 for(Line l: getLines()) {
278 Frame parent = l.getOppositeEnd(this).getParent();
279 if (parent != null && parent != current) {
280 this.setParent(parent);
281 if(DisplayIO.getCurrentSide() == 0)
282 this.setX(this.getX() - DisplayIO.getMiddle());
283 else
284 this.setX(this.getX() + DisplayIO.getMiddle());
285 }
286 break;
287 }
288
289 super.anchor();
290
291 //TODO is the code below needed... what for?
292 for (Line line : getLines()) {
293 if (line.getID() < 0 && !current.getItems().contains(line)) {
294 line.setID(current.getNextItemID());
295 line.setHighlightColor();
296 // Mike: Why was this line here?
297 //anchor(line);
298 }
299 }
300 }
301
302 @Override
303 public void addLine(Line line) {
304 super.addLine(line);
305 line.setColor(getColor());
306 line.setThickness(getThickness());
307 line.setLinePattern(getLinePattern());
308 }
309
310 @Override
311 public void lineColorChanged(Color c) {
312 if (getColor() != c) {
313 setColor(c);
314 }
315 }
316}
Note: See TracBrowser for help on using the repository browser.