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

Last change on this file since 1545 was 1545, checked in by bnemhaus, 3 years ago

Expeditee now respects the users antialiasing setting. The previous system

  1. Attempted to respect antialiasing by checking the setting and enabling it if the setting was true
  2. In the process of painting the frame some special items (link marks etc) want to use antialiasing reguardless of setting. This was achieved by turning antialiasing on, doing the thing and then turning it off. This unfortunately meant that, in the scenario that the users antialiasing setting is on, it gets turned off after drawing one of these special items and doesn't get turn on again until all items have been drawn.

The new system still always turns antialiasing on for these special items, but instead of turning it off after, it returns it to the setting it was previously on. This is achieved with two new functions: setTransientAntialiasingOn() and setTransientAntialiasingOff().

On a related note, there was also an issue with some polygons being drawn with a thickness of 0.0f, which was causing them to antialias badly. They now have a thickness of 1.0f.

File size: 11.9 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.Stroke;
30import org.expeditee.core.bounds.AxisAlignedBoxBounds;
31import org.expeditee.core.bounds.Bounds;
32import org.expeditee.core.bounds.PolygonBounds;
33import org.expeditee.gio.EcosystemManager;
34import org.expeditee.gio.GraphicsManager;
35import org.expeditee.gui.DisplayController;
36import org.expeditee.gui.Frame;
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 setAnchorCenterX(Integer anchor) {
108 if (!isLineEnd()) {
109 super.setAnchorCenterX(anchor);
110 return;
111 }
112
113 invalidateFill();
114 invalidateCommonTrait(ItemAppearence.PreMoved);
115
116 this._anchoring.setCenterXAnchor(anchor);
117
118 int oldX = getX();
119 if (anchor != null) {
120 int centreX = DisplayController.getFramePaintArea().getCentreX();
121 int alignedToLeft = centreX + anchor;
122 int alignedToCenter = alignedToLeft - (getBoundsWidth() / 2);
123 float deltaX = alignedToCenter - oldX;
124 anchorConnected(AnchorEdgeType.CenterX, deltaX);
125 }
126
127 invalidateCommonTrait(ItemAppearence.PostMoved);
128 invalidateFill();
129 }
130
131 @Override
132 public void setAnchorRight(Integer anchor) {
133 if (!isLineEnd()) {
134 super.setAnchorRight(anchor);
135 return;
136 }
137 invalidateFill();
138 invalidateCommonTrait(ItemAppearence.PreMoved);
139
140 this._anchoring.setRightAnchor(anchor);
141
142 int oldX = getX();
143 if (anchor != null) {
144 float deltaX = DisplayController.getFramePaintAreaWidth() - anchor - getBoundsWidth() - oldX;
145
146 anchorConnected(AnchorEdgeType.Right, deltaX);
147 }
148
149 invalidateCommonTrait(ItemAppearence.PostMoved);
150 invalidateFill();
151 }
152
153 @Override
154 public void setAnchorTop(Integer anchor) {
155 if (!isLineEnd()) {
156 super.setAnchorTop(anchor);
157 return;
158 }
159 invalidateFill();
160 invalidateCommonTrait(ItemAppearence.PreMoved);
161
162 this._anchoring.setTopAnchor(anchor);
163
164 int oldY = getY();
165 if (anchor != null) {
166 float deltaY = anchor - oldY;
167 anchorConnected(AnchorEdgeType.Top, deltaY);
168 }
169
170 invalidateCommonTrait(ItemAppearence.PostMoved);
171 invalidateFill();
172 }
173
174 @Override
175 public void setAnchorCenterY(Integer anchor) {
176 if (!isLineEnd()) {
177 super.setAnchorCenterY(anchor);
178 return;
179 }
180 invalidateFill();
181 invalidateCommonTrait(ItemAppearence.PreMoved);
182
183 this._anchoring.setCenterYAnchor(anchor);
184
185 int oldY = getY();
186 if (anchor != null) {
187 int alignedToTop = DisplayController.getFramePaintArea().getCentreY() + anchor;
188 float alignedToCenter = alignedToTop - (getBoundsHeight() / 2);
189 float deltaY = alignedToCenter - oldY;
190 anchorConnected(AnchorEdgeType.CenterY, deltaY);
191 }
192
193 invalidateCommonTrait(ItemAppearence.PostMoved);
194 invalidateFill();
195 }
196
197 @Override
198 public void setAnchorBottom(Integer anchor) {
199 if (!isLineEnd()) {
200 super.setAnchorBottom(anchor);
201 return;
202 }
203 invalidateFill();
204 invalidateCommonTrait(ItemAppearence.PreMoved);
205
206 this._anchoring.setBottomAnchor(anchor);
207
208 int oldY = getY();
209 if (anchor != null) {
210 float deltaY = DisplayController.getFramePaintAreaHeight() - anchor - getBoundsHeight() - oldY;
211 anchorConnected(AnchorEdgeType.Bottom, deltaY);
212 }
213
214 invalidateCommonTrait(ItemAppearence.PostMoved);
215 invalidateFill();
216 }
217
218
219
220 @Override
221 public void paint() {
222 GraphicsManager g = EcosystemManager.getGraphicsManager();
223 if (isHighlighted() /* && !FreeItems.getInstance().contains(this) */) {
224 Colour highlightColor = getHighlightColor();
225 Fill fill = new Fill(highlightColor);
226 // g.setStroke()
227 // Draw the highlighting rectangle surrounding the dot
228 // this is drawn even if its part of a rectangle
229
230 if (isVectorItem()) invalidateBounds();
231
232 AxisAlignedBoxBounds bounds = getBoundingBox();
233 if (_highlightMode == HighlightMode.Enclosed || this.getConnected().size() <= 1) { // Make sure single dots are highlighted filled
234 g.drawRectangle(bounds.getTopLeft(), bounds.getSize(), 0.0f, fill, highlightColor, DOT_STROKE, null);
235 } else if (_highlightMode == HighlightMode.Connected) {
236 g.drawRectangle(bounds.getTopLeft(), bounds.getSize(), 0.0f, null, highlightColor, HIGHLIGHT_STROKE, null);
237 } else if (_highlightMode == HighlightMode.Normal) {
238 g.drawOval(bounds.getCentre(), bounds.getSize(), 0.0f, fill, highlightColor, DOT_STROKE);
239 }
240 }
241
242 // dots on lines are hidden
243 if (getLines().size() > 0) return;
244
245 int thick = (int) getThickness();
246 if (thick < MINIMUM_DOT_SIZE) thick = MINIMUM_DOT_SIZE;
247
248 Fill fill = _filled ? new Fill(getPaintColor()) : null;
249
250 // TODO: On testing, this code doesn't seem to work (can't change to any type except square). cts16
251 switch (_type) {
252 case circle:
253 g.drawOval(
254 new Point(getX(), getY()),
255 new Dimension(thick, thick),
256 0.0,
257 fill,
258 getPaintColor(),
259 null
260 );
261 break;
262 case diamond:
263 PolygonBounds diamond = PolygonBounds.getDiamond(thick, thick).translate(getX(), getY()).close();
264 g.drawPolygon(diamond, null, null, 0.0, fill, getPaintColor(), null);
265 break;
266 case triangle:
267 PolygonBounds triangle = PolygonBounds.getTriangle(thick, thick).translate(getX(), getY()).close();
268 g.drawPolygon(triangle, null, null, 0.0, fill, getPaintColor(), null);
269 break;
270 case roundSquare:
271 int arc = thick / 4;
272 g.drawRectangle(
273 new Point(getX(), getY()),
274 new Dimension(thick, thick),
275 0.0,
276 fill,
277 getPaintColor(),
278 null,
279 new Dimension(arc, arc)
280 );
281 break;
282 default:
283 g.drawRectangle(
284 new Point(getX(), getY()),
285 new Dimension(thick, thick),
286 0.0,
287 fill,
288 getPaintColor(),
289 null,
290 null
291 );
292 }
293
294 }
295
296 /**
297 * Updates the bounds surrounding this Dot.
298 * TODO: Standardise Dot minimum size. cts16
299 */
300 public Bounds updateBounds()
301 {
302 int thick = Math.round(getThickness());
303
304 // Sets a minimum size for the dot
305 thick = Math.max(thick, getGravity() * 2);
306
307 // Include the gravity in the thickness
308 thick += 2 * getGravity();
309
310
311 int x = getX() - thick / 2;
312 int y = getY() - thick / 2;
313
314 return new AxisAlignedBoxBounds(x, y, thick, thick);
315 }
316
317 @Override
318 public Item copy() {
319 Dot copy = new Dot(getX(), getY(), getID());
320
321 Item.DuplicateItem(this, copy);
322
323 return copy;
324 }
325
326 @Override
327 public void setHighlightColorToDefault() {
328 super.setHighlightColorToDefault();
329
330 //return Item.DEFAULT_CURSOR;
331 }
332
333 @Override
334 public void setAnnotation(boolean val) {
335 DisplayController.setCursorPosition(this.getPosition());
336 Item.replaceDot(this, '@');
337 }
338
339 @Override
340 public Item merge(Item merger, int mouseX, int mouseY) {
341 // if the item being merged with is another Dot
342 if (merger instanceof Dot) {
343 if (merger.hasEnclosures() || hasEnclosures())
344 return merger;
345
346 Item dot = (Item) merger;
347 merger.setPosition(this.getPosition());
348 // prevent concurrency issues if removing lines
349 List<Line> lines = new ArrayList<Line>();
350 lines.addAll(dot.getLines());
351
352 for (Line line : lines) {
353 // remove lines that are in common
354 if (getLines().contains(line)) {
355 dot.removeLine(line);
356 removeLine(line);
357 } else {
358 // check for duplicated lines as a result of merging
359 Item check = (Item) line.getOppositeEnd(dot);
360 boolean dup = false;
361
362 for (Line l : getLines()) {
363 Item opposite = l.getOppositeEnd(this);
364
365 if (check == opposite) {
366 line.getStartItem().removeLine(line);
367 line.getEndItem().removeLine(line);
368 dup = true;
369 break;
370 }
371 }
372
373 if (!dup)
374 line.replaceLineEnd(dot, this);
375 }
376 }
377
378 setThickness(dot.getThickness());
379 setColor(dot.getColor());
380 setFillColor(dot.getFillColor());
381
382 return null;
383 }
384
385 if (merger instanceof Text) {
386 merger.setPosition(this.getPosition());
387 List<Line> lines = new LinkedList<Line>();
388 lines.addAll(getLines());
389 for (Line line : lines)
390 line.replaceLineEnd(this, merger);
391 this.delete();
392 return merger;
393 }
394
395 // if the item being merged with is a Line
396 if (merger instanceof Line) {
397 Line line = (Line) merger;
398 // if this dot is part of the line then keep it, otherwise it
399 // can be removed
400 if (line.getOppositeEnd(this) != null && getLines().contains(line))
401 return merger;
402 else
403 return null;
404 }
405
406 return merger;
407 }
408
409 @Override
410 public String getTypeAndID() {
411 return "P " + getID();
412 }
413
414 @Override
415 public void delete() {
416 super.delete();
417
418 for (Line l : this.getLines())
419 l.delete();
420 }
421
422 @Override
423 public void anchor() {
424 Frame current = getParentOrCurrentFrame();
425 // This is to make lines anchored across frames be on one frame
426 for (Line l : getLines()) {
427 Frame parent = l.getOppositeEnd(this).getParent();
428 if (parent != null && parent != current) {
429 this.setParent(parent);
430 if (DisplayController.getCurrentSide() == DisplayController.TwinFramesSide.LEFT)
431 this.setX(this.getX() - DisplayController.getTwinFramesSeparatorX());
432 else
433 this.setX(this.getX() + DisplayController.getTwinFramesSeparatorX());
434 }
435 break;
436 }
437
438 super.anchor();
439
440 // TODO is the code below needed... what for?
441 for (Line line : getLines()) {
442 if (line.getID() < 0 && !current.getSortedItems().contains(line)) {
443 line.setID(current.getNextItemID());
444 line.setHighlightColorToDefault();
445 // Mike: Why was this line here?
446 // anchor(line);
447 }
448 }
449 }
450
451 @Override
452 public void addLine(Line line) {
453 super.addLine(line);
454 line.setColor(getColor());
455 line.setThickness(getThickness());
456 line.setLinePattern(getLinePattern());
457 }
458
459 @Override
460 public void lineColorChanged(Colour c) {
461 if (getColor() != c) {
462 setColor(c);
463 }
464 }
465
466 @Override
467 public boolean dontSave() {
468 if (getThickness() <= 1 && (getLines().size() == 0)
469 && getConstraints().size() == 0) {
470 return true;
471 }
472 return super.dontSave();
473 }
474
475 @Override
476 public float getSize()
477 {
478 return getThickness();
479 }
480}
Note: See TracBrowser for help on using the repository browser.