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

Last change on this file since 1258 was 1258, checked in by davidb, 5 years ago

Changed how DisplayController width, height and size are retrieved. Now does this top-level, rather than going through the AxisAlignmentBox. In doing so, can now control for when the window size has you yet been correctly mapped to the screen, and fall back to pre-defined MINIMUM defaults

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