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

Last change on this file since 282 was 282, 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 Rectangle rect = getPolygon().getBounds();
123 if (_mode == HighlightMode.Enclosed ||
124 // Make sure single dots are highlighted filled
125 this.getConnected().size() <= 1)
126 g.fillRect(rect.x, rect.y, rect.width, rect.height);
127 else if (_mode == HighlightMode.Connected)
128 g.drawRect(rect.x, rect.y, rect.width, rect.height);
129 else if (_mode == HighlightMode.Normal) {
130 g.fillOval(rect.x, rect.y, rect.width, rect.height);
131 }
132 // System.out.println(_mode.toString());
133 }
134
135 // dots on lines are hidden
136 if (getLines().size() > 0)
137 return;
138
139 g.setColor(getPaintColor());
140
141 int thick = (int) getThickness();
142 if (thick < MINIMUM_DOT_SIZE)
143 thick = MINIMUM_DOT_SIZE;
144
145 int width = thick / 2;
146
147 if (_pointType == Item.POINTTYPE_CIRCLE) {
148 int points = 40;
149
150 double radians = 0.0;
151 int xPoints[] = new int[points];
152 int yPoints[] = new int[xPoints.length];
153
154 for (int i = 0; i < xPoints.length; i++) {
155 xPoints[i] = getX() + (int) (width * Math.cos(radians));
156 yPoints[i] = getY() + (int) (width * Math.sin(radians));
157 radians += (2.0 * Math.PI) / xPoints.length;
158 }
159
160 if (_filled)
161 g.fillPolygon(new Polygon(xPoints, yPoints, xPoints.length));
162 else
163 g.drawPolygon(new Polygon(xPoints, yPoints, xPoints.length));
164 } else {
165 if (_filled)
166 g.fillRect(getX() - width, getY() - width, thick, thick);
167 else
168 g.drawRect(getX() - width, getY() - width, thick, thick);
169 }
170
171 }
172
173 /**
174 * Updates the points of the polygon surrounding this Dot
175 */
176 public void updatePolygon() {
177 int thick = Math.round(getThickness());
178 // Sets a minimum size for the dot
179 thick = Math.max(thick, _MINIMUM_DOT_SIZE);
180
181 int x = getX() - thick / 2;
182 int y = getY() - thick / 2;
183
184 _poly = new Polygon();
185 _poly.addPoint(x - getGravity(), y - getGravity());
186 _poly.addPoint(x + thick + getGravity(), y - getGravity());
187 _poly.addPoint(x + thick + getGravity(), y + thick + getGravity());
188 _poly.addPoint(x - getGravity(), y + thick + getGravity());
189 }
190
191 @Override
192 public Item copy() {
193 Dot copy = new Dot(getX(), getY(), getID());
194
195 Item.DuplicateItem(this, copy);
196
197 copy.setThickness(getThickness());
198 copy.setPointType(_pointType);
199 copy.useFilledPoints(_filled);
200
201 return copy;
202 }
203
204 @Override
205 public int setHighlightColor() {
206 super.setHighlightColor();
207
208 return Item.DEFAULT_CURSOR;
209 }
210
211 @Override
212 public void setAnnotation(boolean val) {
213 DisplayIO.setCursorPosition(this.getPosition());
214 FrameKeyboardActions.replaceDot(this, '@');
215 }
216
217 @Override
218 public Item merge(Item merger, int mouseX, int mouseY) {
219 // if the item being merged with is another Dot
220 if (merger instanceof Dot) {
221 if (merger.hasEnclosures() || hasEnclosures())
222 return merger;
223
224 Item dot = (Item) merger;
225 merger.setPosition(this.getPosition());
226 // prevent concurrency issues if removing lines
227 List<Line> lines = new ArrayList<Line>();
228 lines.addAll(dot.getLines());
229
230 for (Line line : lines) {
231 // remove lines that are in common
232 if (getLines().contains(line)) {
233 dot.removeLine(line);
234 removeLine(line);
235 } else {
236 // check for duplicated lines as a result of merging
237 Item check = (Item) line.getOppositeEnd(dot);
238 boolean dup = false;
239
240 for (Line l : getLines()) {
241 Item opposite = l.getOppositeEnd(this);
242
243 if (check == opposite) {
244 line.getStartItem().removeLine(line);
245 line.getEndItem().removeLine(line);
246 dup = true;
247 break;
248 }
249 }
250
251 if (!dup)
252 line.replaceLineEnd(dot, this);
253 }
254 }
255
256 setThickness(dot.getThickness());
257 setColor(dot.getColor());
258 setFillColor(dot.getFillColor());
259
260 return null;
261 }
262
263 if (merger instanceof Text) {
264 merger.setPosition(this.getPosition());
265 List<Line> lines = new LinkedList<Line>();
266 lines.addAll(getLines());
267 for (Line line : lines)
268 line.replaceLineEnd(this, merger);
269 this.delete();
270 return merger;
271 }
272
273 // if the item being merged with is a Line
274 if (merger instanceof Line) {
275 Line line = (Line) merger;
276 // if this dot is part of the line then keep it, otherwise it
277 // can be removed
278 if (line.getOppositeEnd(this) != null && getLines().contains(line))
279 return merger;
280 else
281 return null;
282 }
283
284 return merger;
285 }
286
287 @Override
288 public String getTypeAndID() {
289 return "P " + getID();
290 }
291
292 @Override
293 public void delete() {
294 super.delete();
295
296 for (Line l : this.getLines())
297 l.delete();
298 }
299
300 @Override
301 public void anchor() {
302 Frame current = getParentOrCurrentFrame();
303 // This is to make lines anchored across frames be on one frame
304 for (Line l : getLines()) {
305 Frame parent = l.getOppositeEnd(this).getParent();
306 if (parent != null && parent != current) {
307 this.setParent(parent);
308 if (DisplayIO.getCurrentSide() == 0)
309 this.setX(this.getX() - DisplayIO.getMiddle());
310 else
311 this.setX(this.getX() + DisplayIO.getMiddle());
312 }
313 break;
314 }
315
316 super.anchor();
317
318 // TODO is the code below needed... what for?
319 for (Line line : getLines()) {
320 if (line.getID() < 0 && !current.getItems().contains(line)) {
321 line.setID(current.getNextItemID());
322 line.setHighlightColor();
323 // Mike: Why was this line here?
324 // anchor(line);
325 }
326 }
327 }
328
329 @Override
330 public void addLine(Line line) {
331 super.addLine(line);
332 line.setColor(getColor());
333 line.setThickness(getThickness());
334 line.setLinePattern(getLinePattern());
335 }
336
337 @Override
338 public void lineColorChanged(Color c) {
339 if (getColor() != c) {
340 setColor(c);
341 }
342 }
343
344 @Override
345 public boolean dontSave() {
346 if (getThickness() <= 1 && (getLines().size() == 0)
347 && getConstraints().size() == 0) {
348 return true;
349 }
350 return super.dontSave();
351 }
352}
Note: See TracBrowser for help on using the repository browser.