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

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