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

Last change on this file since 1540 was 1540, checked in by bnemhaus, 4 years ago

Removed reliance of System.getProperty("user.name") by introducing some functions and a variable to Browser to be used instead. All previous occurrences of System.getProperty("user.name") now use these functions.

At the time, introduced new piping into various functions related to the creation and management of profile frames that distinguished between a profile name and a user name. This allows functions to be more specific about what is being used. For example, when modifying the users profile frames (in the profiles directory) that users profile name can be used instead of naming the variable 'username'. This distinction is important because while username's can end with numbers, profile names cannot and therefore get an 'A' on the end.

File size: 12.0 KB
Line 
1/**
2 * Dot.java
3 * Copyright (C) 2010 New Zealand Digital Library, http://expeditee.org
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19package org.expeditee.items;
20
21import java.util.ArrayList;
22import java.util.LinkedList;
23import java.util.List;
24
25import org.expeditee.core.Colour;
26import org.expeditee.core.Dimension;
27import org.expeditee.core.Fill;
28import org.expeditee.core.Point;
29import org.expeditee.core.bounds.AxisAlignedBoxBounds;
30import org.expeditee.core.bounds.Bounds;
31import org.expeditee.core.bounds.PolygonBounds;
32import org.expeditee.gio.EcosystemManager;
33import org.expeditee.gio.GraphicsManager;
34import org.expeditee.gui.DisplayController;
35import org.expeditee.gui.Frame;
36
37/**
38 * Represents a point on the screen. All Point objects are stored as x,y pairs
39 * with an Item ID. Note: Lines and all combinates of lines (rectangles, etc)
40 * are represented only as Points that share line IDs.
41 *
42 * @author jdm18
43 *
44 */
45public class Dot extends Item {
46
47 // Standard Item variables
48
49 // private static final int _MINIMUM_DOT_SIZE = 6;
50
51 private static final int MINIMUM_DOT_SIZE = 2;
52
53 public Dot(int id) {
54 super();
55 setID(id);
56 }
57
58 /**
59 * Constructs a new Point with the given x,y coordinates and Item ID.
60 *
61 * @param x
62 * The x coordinate of this point
63 * @param y
64 * The y coordinate of this point
65 * @param id
66 * The Item ID of this Point
67 */
68 public Dot(int x, int y, int id) {
69 super();
70 setID(id);
71 setPosition(x, y);
72 }
73
74 @Override
75 public void setColor(Colour c) {
76 super.setColor(c);
77
78 // update the colour of any lines
79 for (Line line : getLines())
80 line.setColor(c);
81 }
82
83 @Override
84 public void setAnchorLeft(Integer anchor) {
85 if (!isLineEnd()) {
86 super.setAnchorLeft(anchor);
87 return;
88 }
89
90 invalidateFill();
91 invalidateCommonTrait(ItemAppearence.PreMoved);
92
93 this._anchoring.setLeftAnchor(anchor);
94
95 int oldX = getX();
96 if (anchor != null) {
97 float deltaX = anchor - oldX;
98 anchorConnected(AnchorEdgeType.Left, deltaX);
99 }
100
101 invalidateCommonTrait(ItemAppearence.PostMoved);
102 invalidateFill();
103 }
104
105 @Override
106 public void setAnchorCenterX(Integer anchor) {
107 if (!isLineEnd()) {
108 super.setAnchorCenterX(anchor);
109 return;
110 }
111
112 invalidateFill();
113 invalidateCommonTrait(ItemAppearence.PreMoved);
114
115 this._anchoring.setCenterXAnchor(anchor);
116
117 int oldX = getX();
118 if (anchor != null) {
119 int centreX = DisplayController.getFramePaintArea().getCentreX();
120 int alignedToLeft = centreX + anchor;
121 int alignedToCenter = alignedToLeft - (getBoundsWidth() / 2);
122 float deltaX = alignedToCenter - oldX;
123 anchorConnected(AnchorEdgeType.CenterX, deltaX);
124 }
125
126 invalidateCommonTrait(ItemAppearence.PostMoved);
127 invalidateFill();
128 }
129
130 @Override
131 public void setAnchorRight(Integer anchor) {
132 if (!isLineEnd()) {
133 super.setAnchorRight(anchor);
134 return;
135 }
136 invalidateFill();
137 invalidateCommonTrait(ItemAppearence.PreMoved);
138
139 this._anchoring.setRightAnchor(anchor);
140
141 int oldX = getX();
142 if (anchor != null) {
143 float deltaX = DisplayController.getFramePaintAreaWidth() - anchor - getBoundsWidth() - oldX;
144
145 anchorConnected(AnchorEdgeType.Right, deltaX);
146 }
147
148 invalidateCommonTrait(ItemAppearence.PostMoved);
149 invalidateFill();
150 }
151
152 @Override
153 public void setAnchorTop(Integer anchor) {
154 if (!isLineEnd()) {
155 super.setAnchorTop(anchor);
156 return;
157 }
158 invalidateFill();
159 invalidateCommonTrait(ItemAppearence.PreMoved);
160
161 this._anchoring.setTopAnchor(anchor);
162
163 int oldY = getY();
164 if (anchor != null) {
165 float deltaY = anchor - oldY;
166 anchorConnected(AnchorEdgeType.Top, deltaY);
167 }
168
169 invalidateCommonTrait(ItemAppearence.PostMoved);
170 invalidateFill();
171 }
172
173 @Override
174 public void setAnchorCenterY(Integer anchor) {
175 if (!isLineEnd()) {
176 super.setAnchorCenterY(anchor);
177 return;
178 }
179 invalidateFill();
180 invalidateCommonTrait(ItemAppearence.PreMoved);
181
182 this._anchoring.setCenterYAnchor(anchor);
183
184 int oldY = getY();
185 if (anchor != null) {
186 int alignedToTop = DisplayController.getFramePaintArea().getCentreY() + anchor;
187 float alignedToCenter = alignedToTop - (getBoundsHeight() / 2);
188 float deltaY = alignedToCenter - oldY;
189 anchorConnected(AnchorEdgeType.CenterY, deltaY);
190 }
191
192 invalidateCommonTrait(ItemAppearence.PostMoved);
193 invalidateFill();
194 }
195
196 @Override
197 public void setAnchorBottom(Integer anchor) {
198 if (!isLineEnd()) {
199 super.setAnchorBottom(anchor);
200 return;
201 }
202 invalidateFill();
203 invalidateCommonTrait(ItemAppearence.PreMoved);
204
205 this._anchoring.setBottomAnchor(anchor);
206
207 int oldY = getY();
208 if (anchor != null) {
209 float deltaY = DisplayController.getFramePaintAreaHeight() - anchor - getBoundsHeight() - oldY;
210 anchorConnected(AnchorEdgeType.Bottom, deltaY);
211 }
212
213 invalidateCommonTrait(ItemAppearence.PostMoved);
214 invalidateFill();
215 }
216
217
218
219 @Override
220 public void paint() {
221 GraphicsManager g = EcosystemManager.getGraphicsManager();
222 if (isHighlighted() /* && !FreeItems.getInstance().contains(this) */) {
223 Colour highlightColor = getHighlightColor();
224 Fill fill = new Fill(highlightColor);
225 // g.setStroke()
226 // Draw the highlighting rectangle surrounding the dot
227 // this is drawn even if its part of a rectangle
228
229 if (isVectorItem()) invalidateBounds();
230
231 AxisAlignedBoxBounds bounds = getBoundingBox();
232 if (_highlightMode == HighlightMode.Enclosed || this.getConnected().size() <= 1) { // Make sure single dots are highlighted filled
233 g.drawRectangle(bounds.getTopLeft(), bounds.getSize(), 0.0f, fill, highlightColor, DOT_STROKE, null);
234 } else if (_highlightMode == HighlightMode.Connected) {
235 g.drawRectangle(bounds.getTopLeft(), bounds.getSize(), 0.0f, null, highlightColor, HIGHLIGHT_STROKE, null);
236 System.err.println("Dot::paint:Painting Dot with colour: " + highlightColor);
237 } else if (_highlightMode == HighlightMode.Normal) {
238 g.drawOval(bounds.getCentre(), bounds.getSize(), 0.0f, fill, highlightColor, DOT_STROKE);
239 }
240 // System.out.println(_mode.toString());
241 }
242
243 // dots on lines are hidden
244 if (getLines().size() > 0) return;
245
246 int thick = (int) getThickness();
247 if (thick < MINIMUM_DOT_SIZE) thick = MINIMUM_DOT_SIZE;
248
249 Fill fill = _filled ? new Fill(getPaintColor()) : null;
250
251 // TODO: On testing, this code doesn't seem to work (can't change to any type except square). cts16
252 switch (_type) {
253 case circle:
254 g.drawOval(
255 new Point(getX(), getY()),
256 new Dimension(thick, thick),
257 0.0,
258 fill,
259 getPaintColor(),
260 null
261 );
262 break;
263 case diamond:
264 PolygonBounds diamond = PolygonBounds.getDiamond(thick, thick).translate(getX(), getY()).close();
265 g.drawPolygon(diamond, null, null, 0.0, fill, getPaintColor(), null);
266 break;
267 case triangle:
268 PolygonBounds triangle = PolygonBounds.getTriangle(thick, thick).translate(getX(), getY()).close();
269 g.drawPolygon(triangle, null, null, 0.0, fill, getPaintColor(), null);
270 break;
271 case roundSquare:
272 int arc = thick / 4;
273 g.drawRectangle(
274 new Point(getX(), getY()),
275 new Dimension(thick, thick),
276 0.0,
277 fill,
278 getPaintColor(),
279 null,
280 new Dimension(arc, arc)
281 );
282 break;
283 default:
284 g.drawRectangle(
285 new Point(getX(), getY()),
286 new Dimension(thick, thick),
287 0.0,
288 fill,
289 getPaintColor(),
290 null,
291 null
292 );
293 }
294
295 }
296
297 /**
298 * Updates the bounds surrounding this Dot.
299 * TODO: Standardise Dot minimum size. cts16
300 */
301 public Bounds updateBounds()
302 {
303 int thick = Math.round(getThickness());
304
305 // Sets a minimum size for the dot
306 thick = Math.max(thick, getGravity() * 2);
307
308 // Include the gravity in the thickness
309 thick += 2 * getGravity();
310
311
312 int x = getX() - thick / 2;
313 int y = getY() - thick / 2;
314
315 return new AxisAlignedBoxBounds(x, y, thick, thick);
316 }
317
318 @Override
319 public Item copy() {
320 Dot copy = new Dot(getX(), getY(), getID());
321
322 Item.DuplicateItem(this, copy);
323
324 return copy;
325 }
326
327 @Override
328 public void setHighlightColorToDefault() {
329 super.setHighlightColorToDefault();
330
331 //return Item.DEFAULT_CURSOR;
332 }
333
334 @Override
335 public void setAnnotation(boolean val) {
336 DisplayController.setCursorPosition(this.getPosition());
337 Item.replaceDot(this, '@');
338 }
339
340 @Override
341 public Item merge(Item merger, int mouseX, int mouseY) {
342 // if the item being merged with is another Dot
343 if (merger instanceof Dot) {
344 if (merger.hasEnclosures() || hasEnclosures())
345 return merger;
346
347 Item dot = (Item) merger;
348 merger.setPosition(this.getPosition());
349 // prevent concurrency issues if removing lines
350 List<Line> lines = new ArrayList<Line>();
351 lines.addAll(dot.getLines());
352
353 for (Line line : lines) {
354 // remove lines that are in common
355 if (getLines().contains(line)) {
356 dot.removeLine(line);
357 removeLine(line);
358 } else {
359 // check for duplicated lines as a result of merging
360 Item check = (Item) line.getOppositeEnd(dot);
361 boolean dup = false;
362
363 for (Line l : getLines()) {
364 Item opposite = l.getOppositeEnd(this);
365
366 if (check == opposite) {
367 line.getStartItem().removeLine(line);
368 line.getEndItem().removeLine(line);
369 dup = true;
370 break;
371 }
372 }
373
374 if (!dup)
375 line.replaceLineEnd(dot, this);
376 }
377 }
378
379 setThickness(dot.getThickness());
380 setColor(dot.getColor());
381 setFillColor(dot.getFillColor());
382
383 return null;
384 }
385
386 if (merger instanceof Text) {
387 merger.setPosition(this.getPosition());
388 List<Line> lines = new LinkedList<Line>();
389 lines.addAll(getLines());
390 for (Line line : lines)
391 line.replaceLineEnd(this, merger);
392 this.delete();
393 return merger;
394 }
395
396 // if the item being merged with is a Line
397 if (merger instanceof Line) {
398 Line line = (Line) merger;
399 // if this dot is part of the line then keep it, otherwise it
400 // can be removed
401 if (line.getOppositeEnd(this) != null && getLines().contains(line))
402 return merger;
403 else
404 return null;
405 }
406
407 return merger;
408 }
409
410 @Override
411 public String getTypeAndID() {
412 return "P " + getID();
413 }
414
415 @Override
416 public void delete() {
417 super.delete();
418
419 for (Line l : this.getLines())
420 l.delete();
421 }
422
423 @Override
424 public void anchor() {
425 Frame current = getParentOrCurrentFrame();
426 // This is to make lines anchored across frames be on one frame
427 for (Line l : getLines()) {
428 Frame parent = l.getOppositeEnd(this).getParent();
429 if (parent != null && parent != current) {
430 this.setParent(parent);
431 if (DisplayController.getCurrentSide() == DisplayController.TwinFramesSide.LEFT)
432 this.setX(this.getX() - DisplayController.getTwinFramesSeparatorX());
433 else
434 this.setX(this.getX() + DisplayController.getTwinFramesSeparatorX());
435 }
436 break;
437 }
438
439 super.anchor();
440
441 // TODO is the code below needed... what for?
442 for (Line line : getLines()) {
443 if (line.getID() < 0 && !current.getSortedItems().contains(line)) {
444 line.setID(current.getNextItemID());
445 line.setHighlightColorToDefault();
446 // Mike: Why was this line here?
447 // anchor(line);
448 }
449 }
450 }
451
452 @Override
453 public void addLine(Line line) {
454 super.addLine(line);
455 line.setColor(getColor());
456 line.setThickness(getThickness());
457 line.setLinePattern(getLinePattern());
458 }
459
460 @Override
461 public void lineColorChanged(Colour c) {
462 if (getColor() != c) {
463 setColor(c);
464 }
465 }
466
467 @Override
468 public boolean dontSave() {
469 if (getThickness() <= 1 && (getLines().size() == 0)
470 && getConstraints().size() == 0) {
471 return true;
472 }
473 return super.dontSave();
474 }
475
476 @Override
477 public float getSize()
478 {
479 return getThickness();
480 }
481}
Note: See TracBrowser for help on using the repository browser.