source: trunk/src/org/expeditee/gui/FrameGraphics.java@ 1415

Last change on this file since 1415 was 1415, checked in by bln4, 5 years ago

Renamed Frame.getItems() to Frame.getSortedItems() to better represent its functionality.

-> org.apollo.ApolloGestureActions
-> org.apollo.ApolloSystem
-> org.expeditee.actions.Actions
-> org.expeditee.actions.Debug
-> org.expeditee.actions.ExploratorySearchActions
-> org.expeditee.actions.JfxBrowserActions
-> org.expeditee.actions.Misc
-> org.expeditee.actions.Navigation
-> org.expeditee.actions.ScriptBase
-> org.expeditee.actions.Simple
-> org.expeditee.agents.ComputeTree
-> org.expeditee.agents.CopyTree
-> org.expeditee.agents.DisplayComet
-> org.expeditee.agents.DisplayTree
-> org.expeditee.agents.DisplayTreeLeaves
-> org.expeditee.agents.GraphFramesetLinks
-> org.expeditee.agents.TreeProcessor
-> org.expeditee.gio.gesture.StandardGestureActions
-> org.expeditee.gui.DisplayController
-> org.expeditee.gui.FrameCreator
-> org.expeditee.gui.FrameIO
-> org.expeditee.io.DefaultTreeWriter
-> org.expeditee.io.JavaWriter
-> org.expeditee.io.PDF2Writer
-> org.expeditee.io.TXTWriter
-> org.expeditee.io.WebParser
-> org.expeditee.io.flowlayout.XGroupItem
-> org.expeditee.items.Dot
-> org.expeditee.items.Item
-> org.expeditee.items.ItemUtils
-> org.expeditee.network.FrameShare
-> org.expeditee.stats.TreeStats


Created ItemsList class to wrap ArrayList<Item>. Frames now use this new class to store its body list (used for display) as well as its primaryBody and surrogateBody.

-> org.expeditee.agents.Format
-> org.expeditee.agents.HFormat
-> org.expeditee.gio.gesture.StandardGestureActions
-> org.expeditee.gui.Frame
-> org.expeditee.gui.FrameUtils


Refactorted Frame.setResort(bool) to Frame.invalidateSorted() to better function how it is intended to with a more accurate name.

-> org.expeditee.agents.Sort


When writing out .exp files and getting attributes to respond to LEFT + RIGHT click, boolean items are by default true. This has always been the case. An ammendment to this is that defaults can now be established.
Also added 'EnterClick' functionality. If cursored over a item with this property and you press enter, it acts as if you have clicked on it instead.

-> org.expeditee.assets.resources-public.framesets.authentication.1.exp to 6.exp
-> org.expeditee.gio.gesture.StandardGestureActions
-> org.expeditee.gio.input.KBMInputEvent
-> org.expeditee.gio.javafx.JavaFXConversions
-> org.expeditee.gio.swing.SwingConversions
-> org.expeditee.gui.AttributeUtils
-> org.expeditee.io.Conversion
-> org.expeditee.io.DefaultFrameWriter
-> org.expeditee.items.Item


Fixed a bug caused by calling Math.abs on Integer.MIN_VALUE returning unexpected result. Due to zero being a thing, you cannot represent Math.abs(Integer.MIN_VALUE) in a Integer object. The solution is to use Integer.MIN_VALUE + 1 instead of Integer.MIN_VALUE.

-> org.expeditee.core.bounds.CombinationBounds
-> org.expeditee.io.flowlayout.DimensionExtent


Recoded the contains function in EllipticalBounds so that intersection tests containing circles work correctly.

-> org.expeditee.core.bounds.EllipticalBounds


Added toString() to PolygonBounds to allow for useful printing during debugging.

-> org.expeditee.core.bounds.PolygonBounds

Implemented Surrogate Mode!

-> org.expeditee.encryption.io.EncryptedExpReader
-> org.expeditee.encryption.io.EncryptedExpWriter
-> org.expeditee.encryption.items.surrogates.EncryptionDetail
-> org.expeditee.encryption.items.surrogates.Label
-> org.expeditee.gui.FrameUtils
-> org.expeditee.gui.ItemsList
-> org.expeditee.items.Item
-> org.expeditee.items.Text


???? Use Integer.MAX_VALUE cast to a float instead of Float.MAX_VALUE. This fixed some bug which I cannot remember.

-> org.expeditee.gio.TextLayoutManager
-> org.expeditee.gio.swing.SwingTextLayoutManager


Improved solution for dealing with the F10 key taking focus away from Expeditee due to it being a assessibility key.

-> org.expeditee.gio.swing.SwingInputManager


Renamed variable visibleItems in FrameGraphics.paintFrame to itemsToPaintCanditates to better represent functional intent.

-> org.expeditee.gui.FrameGraphics


Improved checking for if personal resources exist before recreating them

-> org.expeditee.gui.FrameIO


Repeated messages to message bay now have a visual feedback instead of just a beep. This visual feedback is in the form of a count of the amount of times it has repeated.

-> org.expeditee.gui.MessageBay


Updated comment on the Vector class to explain what vectors are.

-> org.expeditee.gui.Vector


Added constants to represent all of the property keys in DefaultFrameReader and DefaultFrameWriter.

-> org.expeditee.io.DefaultFrameReader
-> org.expeditee.io.DefaultFrameWriter


Updated the KeyList setting to be more heirarcial with how users will store their Secrets.

-> org.expeditee.settings.identity.secrets.KeyList

File size: 20.6 KB
Line 
1/**
2 * FrameGraphics.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.gui;
20
21import java.util.Collection;
22import java.util.Collections;
23import java.util.Comparator;
24import java.util.HashSet;
25import java.util.LinkedList;
26import java.util.List;
27import java.util.ListIterator;
28
29import org.expeditee.core.Clip;
30import org.expeditee.core.Colour;
31import org.expeditee.core.Dimension;
32import org.expeditee.core.Image;
33import org.expeditee.core.bounds.PolygonBounds;
34import org.expeditee.gio.EcosystemManager;
35import org.expeditee.gio.input.KBMInputEvent.Key;
36import org.expeditee.gio.input.StandardInputEventListeners;
37import org.expeditee.items.Circle;
38import org.expeditee.items.Dot;
39import org.expeditee.items.Item;
40import org.expeditee.items.Item.HighlightMode;
41import org.expeditee.items.Line;
42import org.expeditee.items.UserAppliedPermission;
43import org.expeditee.items.XRayable;
44import org.expeditee.items.widgets.Widget;
45import org.expeditee.items.widgets.WidgetEdge;
46import org.expeditee.settings.UserSettings;
47
48public class FrameGraphics {
49
50 // Final passes to rendering the current frame
51 private static LinkedList<FrameRenderPass> _frameRenderPasses = new LinkedList<FrameRenderPass>();
52
53 private static Item _lastToolTippedItem = null;
54
55 /** Static-only class. */
56 private FrameGraphics()
57 {
58 }
59
60 /**
61 * Gets an image of the given frame that has the given dimensions. If clip
62 * is not null, only the areas inside clip are guaranteed to be drawn.
63 */
64 public static Image getFrameImage(Frame toPaint, Clip clip, Dimension size)
65 {
66 return getFrameImage(toPaint, clip, size, true, true);
67 }
68
69 /**
70 * Gets an image of the given frame that has the given dimensions. If clip
71 * is not null, only the areas inside clip are guaranteed to be drawn.
72 */
73 public static Image getFrameImage(Frame toPaint, Clip clip, Dimension size, boolean isActualFrame, boolean createVolatile)
74 {
75 if (toPaint == null) {
76 return null;
77 }
78
79 // the buffer is not valid, so it must be recreated
80 if (!toPaint.isBufferValid()) {
81
82 Image buffer = toPaint.getBuffer();
83 // Get the size if it hasn't been given
84 if (size == null) {
85 // Can't get the size if there is no buffer
86 if (buffer == null) {
87 return null;
88 } else {
89 size = buffer.getSize();
90 }
91 }
92
93 if (buffer == null || !buffer.getSize().equals(size)) {
94 buffer = Image.createImage(size.width, size.height, createVolatile);
95 toPaint.setBuffer(buffer);
96 clip = null;
97 }
98
99 EcosystemManager.getGraphicsManager().pushDrawingSurface(buffer);
100 EcosystemManager.getGraphicsManager().pushClip(clip);
101 paintFrame(toPaint, isActualFrame, createVolatile);
102 EcosystemManager.getGraphicsManager().popDrawingSurface();
103 }
104
105 return toPaint.getBuffer();
106 }
107
108 /** TODO: Comment. cts16 */
109 public static void paintFrame(Frame toPaint, boolean isActualFrame, boolean createVolitile)
110 {
111 Clip clip = EcosystemManager.getGraphicsManager().peekClip();
112
113 // Prepare render passes
114 if (isActualFrame) {
115 for (FrameRenderPass pass : _frameRenderPasses) {
116 clip = pass.paintStarted(clip);
117 }
118 }
119
120 // TODO: Revise images and clip - VERY IMPORTANT
121
122 // Nicer looking lines, but may be too jerky while
123 // rubber-banding on older machines
124 if (UserSettings.AntiAlias.get()) {
125 EcosystemManager.getGraphicsManager().setAntialiasing(true);
126 }
127
128 // If we are doing @f etc... then have a clear background if its the default background color
129 Colour backgroundColor = null;
130
131 // Need to allow transparency for frameImages
132 if (createVolitile) {
133 backgroundColor = toPaint.getPaintBackgroundColor();
134 } else {
135 backgroundColor = toPaint.getBackgroundColor();
136 if (backgroundColor == null) {
137 backgroundColor = Item.TRANSPARENT;
138 }
139 }
140
141 EcosystemManager.getGraphicsManager().clear(backgroundColor);
142
143 List<Item> itemsToPaintCanditates = new LinkedList<Item>();
144 List<Widget> paintWidgets;
145
146 if (isActualFrame) {
147 // Add all the items for this frame and any other from other
148 // frames
149 itemsToPaintCanditates.addAll(toPaint.getAllItems());
150 paintWidgets = toPaint.getAllOverlayWidgets();
151 paintWidgets.addAll(toPaint.getInteractiveWidgets());
152 } else {
153 itemsToPaintCanditates.addAll(toPaint.getVisibleItems());
154 itemsToPaintCanditates.addAll(toPaint.getVectorItems());
155 paintWidgets = toPaint.getInteractiveWidgets();
156 }
157
158 HashSet<Item> paintedFillsAndLines = new HashSet<Item>();
159 // FIRST: Paint widgets swing gui (not expeditee gui) .
160 // Note that these are the anchored widgets
161 ListIterator<Widget> widgetItor = paintWidgets.listIterator(paintWidgets.size());
162 while (widgetItor.hasPrevious()) {
163 // Paint first-in-last-serve ordering - like swing
164 // If it is done the other way around then widgets are covered up by
165 // the box that is supposed to be underneath
166 Widget iw = widgetItor.previous();
167 if (clip == null || clip.getBounds() == null || clip.getBounds().intersects(iw.getBounds())) {
168 paintedFillsAndLines.addAll(iw.getItems());
169 //iw.paint(bg);
170 //PaintItem(bg, iw.getItems().get(4));
171
172 }
173 }
174
175
176 // Filter out items that do not need to be painted
177 List<Item> paintItems;
178 HashSet<Item> fillOnlyItems = null; // only contains items that do
179 // not need drawing but fills
180 // might
181
182 if (clip == null) {
183 paintItems = itemsToPaintCanditates;
184 } else {
185 fillOnlyItems = new HashSet<Item>();
186 paintItems = new LinkedList<Item>();
187 for (Item i : itemsToPaintCanditates) {
188 if (clip == null || i.isInDrawingArea(clip.getBounds())) {
189 paintItems.add(i);
190 } else if (i.isEnclosed()) {
191 // just add all fill items despite possibility of fills
192 // not being in clip
193 // because it will be faster than having to test twice
194 // for fills that do need
195 // repainting.
196 fillOnlyItems.add(i);
197 }
198 }
199 }
200
201 // Only paint files and lines once ... between anchored AND free items
202 PaintPictures(paintItems, fillOnlyItems, paintedFillsAndLines);
203 PaintLines(itemsToPaintCanditates);
204
205
206 widgetItor = paintWidgets.listIterator(paintWidgets.size());
207 while (widgetItor.hasPrevious()) {
208 // Paint first-in-last-serve ordering - like swing
209 // If it is done the other way around then widgets are covered up by
210 // the box that is supposed to be underneath
211 Widget iw = widgetItor.previous();
212 if (clip == null || clip.isNotClipped() || clip.getBounds().intersects(iw.getClip().getBounds())) {
213 iw.paint();
214 PaintItem(iw.getItems().get(4));
215 }
216 }
217
218
219 // Filter out free items that do not need to be painted
220 // This is efficient in cases with animation while free items exist
221
222 List<Item> freeItemsToPaint = new LinkedList<Item>();
223 // Dont paint the free items for the other frame in twin frames mode
224 // if (toPaint == DisplayIO.getCurrentFrame()) {
225 if (clip == null || clip.isNotClipped()) {
226 freeItemsToPaint = FreeItems.getInstance();
227 } else {
228 freeItemsToPaint = new LinkedList<Item>();
229 fillOnlyItems.clear();
230 for (Item i : FreeItems.getInstance()) {
231 if (i.isInDrawingArea(clip.getBounds())) {
232 freeItemsToPaint.add(i);
233 } else if (i.isEnclosed()) {
234 fillOnlyItems.add(i);
235 }
236 }
237 }
238 // }
239
240 if (isActualFrame && toPaint == DisplayController.getCurrentFrame()) {
241 PaintPictures(freeItemsToPaint, fillOnlyItems, paintedFillsAndLines);
242 }
243
244 // TODO if we can get transparency with FreeItems.getInstance()...
245 // then text can be done before freeItems
246 PaintNonLinesNonPicture(paintItems);
247
248 // toPaint.setBufferValid(true);
249
250 if (isActualFrame && !DisplayController.isAudienceMode()) {
251 PaintItem(toPaint.getNameItem());
252 }
253
254 if (DisplayController.isTwinFramesOn()) {
255 List<Item> lines = new LinkedList<Item>();
256 for (Item i : freeItemsToPaint) {
257 if (i instanceof Line) {
258 Line line = (Line) i;
259
260 if (toPaint == DisplayController.getCurrentFrame()) {
261 // If exactly one end of the line is floating...
262
263 if (line.getEndItem().isFloating()
264 ^ line.getStartItem().isFloating()) {
265 // Line l = TransposeLine(line,
266 // line.getEndItem(),
267 // toPaint, 0, 0);
268 // if (l == null)
269 // l = TransposeLine(line,
270 // line.getStartItem(), toPaint, 0, 0);
271 // if (l == null)
272 // l = line;
273 // lines.add(l);
274 } else {
275 // lines.add(line);
276 }
277 } else {
278 // if (line.getEndItem().isFloating()
279 // ^ line.getStartItem().isFloating()) {
280 // lines.add(TransposeLine(line,
281 // line.getEndItem(), toPaint,
282 // FrameMouseActions.getY(), -DisplayIO
283 // .getMiddle()));
284 // lines.add(TransposeLine(line, line
285 // .getStartItem(), toPaint,
286 // FrameMouseActions.getY(), -DisplayIO
287 // .getMiddle()));
288 // }
289 }
290 }
291 }
292
293 if (isActualFrame) {
294 PaintLines(lines);
295 }
296 } else {
297 if (isActualFrame) {
298 PaintLines(freeItemsToPaint);
299 }
300 }
301
302 if (isActualFrame && toPaint == DisplayController.getCurrentFrame()) {
303 PaintNonLinesNonPicture(freeItemsToPaint);
304 }
305
306 // Repaint popups / drags... As well as final passes
307 if (isActualFrame) {
308 for (FrameRenderPass pass : _frameRenderPasses) {
309 pass.paintPreLayeredPanePass();
310 }
311
312 //if (PopupManager.getInstance() != null) PopupManager.getInstance().paintLayeredPane(clip == null ? null : clip.getBounds());
313
314 for (FrameRenderPass pass : _frameRenderPasses) {
315 pass.paintFinalPass();
316 }
317 }
318
319 // paint tooltip
320 if(!FreeItems.hasItemsAttachedToCursor()) {
321 Item current = FrameUtils.getCurrentItem();
322 if(current != null) {
323 current.paintTooltip();
324 }
325 if (_lastToolTippedItem != null) {
326 _lastToolTippedItem.clearTooltips();
327 }
328 _lastToolTippedItem = current;
329 }
330
331 if (FreeItems.hasCursor() && DisplayController.getCursor() == Item.DEFAULT_CURSOR) {
332 PaintNonLinesNonPicture(FreeItems.getCursor());
333 }
334 }
335
336 private static void PaintNonLinesNonPicture(List<Item> toPaint)
337 {
338 for (Item i : toPaint) {
339 if (!(i instanceof Line) && !(i instanceof XRayable)) {
340 PaintItem(i);
341 }
342 }
343 }
344
345 /**
346 * Paint the lines that are not part of an enclosure.
347 *
348 * @param g
349 * @param toPaint
350 */
351 private static void PaintLines(List<Item> toPaint)
352 {
353 // Use this set to keep track of the items that have been painted
354 Collection<Item> done = new HashSet<Item>();
355 for (Item i : toPaint) {
356 if (i instanceof Line) {
357 Line l = (Line) i;
358 if (done.contains(l)) {
359 l.paintArrows();
360 } else {
361 // When painting a line all connected lines are painted too
362 done.addAll(l.getAllConnected());
363 if (l.getStartItem().getEnclosedArea() == 0) {
364 PaintItem(i);
365 }
366 }
367 }
368 }
369 }
370
371 /**
372 * Paint filled areas and their surrounding lines as well as pictures. Note:
373 * floating widgets are painted as fills
374 *
375 * @param g
376 * @param toPaint
377 */
378 private static void PaintPictures(List<Item> toPaint, HashSet<Item> fillOnlyItems, HashSet<Item> done)
379 {
380
381 List<Item> toFill = new LinkedList<Item>();
382
383 for (Item i : toPaint) {
384 // Ignore items that have already been done!
385 // Also ignore invisible items..
386 // TODO possibly ignore invisible items before coming to this method?
387 if (done.contains(i)) {
388 continue;
389 }
390
391 if (i instanceof XRayable) {
392 toFill.add(i);
393 done.addAll(i.getConnected());
394 } else if (i.hasEnclosures()) {
395 for (Item enclosure : i.getEnclosures()) {
396 if (!toFill.contains(enclosure)) {
397 toFill.add(enclosure);
398 }
399 }
400 done.addAll(i.getConnected());
401 } else if (i.isLineEnd() && (!DisplayController.isAudienceMode() || !i.isConnectedToAnnotation())) {
402 toFill.add(i);
403 done.addAll(i.getAllConnected());
404 }
405 }
406
407 if (fillOnlyItems != null) {
408 for (Item i : fillOnlyItems) {
409 if (done.contains(i)) {
410 continue;
411 } else if (!DisplayController.isAudienceMode() || !i.isConnectedToAnnotation()) {
412 toFill.add(i);
413 }
414 done.addAll(i.getAllConnected());
415 }
416 }
417
418 // Sort the items to fill
419 Collections.sort(toFill, new Comparator<Item>() {
420 @Override
421 public int compare(Item a, Item b) {
422 Double aArea = a.getEnclosedArea();
423 Double bArea = b.getEnclosedArea();
424 int cmp = aArea.compareTo(bArea);
425 if (cmp == 0) {
426 // Shapes to the left go underneath
427 PolygonBounds pA = a.getEnclosedShape();
428 PolygonBounds pB = b.getEnclosedShape();
429 if (pA == null || pB == null) {
430 return 0;
431 }
432 return new Integer(pA.getMinX()).compareTo(pB.getMinX());
433 }
434 return cmp * -1;
435 }
436 });
437
438 for (Item i : toFill) {
439 if (i instanceof XRayable) {
440 PaintItem(i);
441 } else {
442 // Paint the fill and lines
443 i.paintFill();
444 List<Line> lines = i.getLines();
445 if (lines.size() > 0) {
446 PaintItem(lines.get(0));
447 }
448 }
449 }
450 }
451
452 /** Displays the given Item on the screen. */
453 public static void PaintItem(Item i)
454 {
455 if (i == null) {
456 return;
457 }
458
459 // do not paint annotation items in audience mode
460 if (!DisplayController.isAudienceMode() || (!i.isConnectedToAnnotation() && !i.isAnnotation()) || i == FrameUtils.getLastEdited())
461 {
462 i.paint();
463 }
464 }
465
466 /**
467 * Highlights an item on the screen Note: All graphics are handled by the
468 * Item itself.
469 *
470 * @param i
471 * The Item to highlight.
472 * @param val
473 * True if the highlighting is being shown, false if it is being
474 * erased.
475 * @return the item that was highlighted
476 */
477 public static Item Highlight(Item i) {
478 if ((i instanceof Line)) {
479 // Check if within 20% of the end of the line
480 Line l = (Line) i;
481 Item toDisconnect = l.getEndPointToDisconnect(DisplayController.getMousePosition());
482
483 // Brook: Widget Edges do not have such a context
484 if (toDisconnect != null && !(i instanceof WidgetEdge)) {
485 Item.HighlightMode newMode = toDisconnect.getHighlightMode();
486 if (FreeItems.hasItemsAttachedToCursor()) {
487 newMode = Item.HighlightMode.Normal;
488 }
489 // unhighlight all the other dots
490 for (Item conn : toDisconnect.getAllConnected()) {
491 conn.setHighlightMode(Item.HighlightMode.None);
492 conn.setHighlightColorToDefault();
493 }
494 l.setHighlightMode(newMode);
495 l.setHighlightColorToDefault();
496 // highlight the dot that will be in disconnect mode
497 toDisconnect.setHighlightMode(newMode);
498 toDisconnect.setHighlightColorToDefault();
499 i = toDisconnect;
500 } else {
501 if (StandardInputEventListeners.kbmStateListener.isKeyDown(Key.SHIFT)) {
502 for(Item j : i.getAllConnected()) {
503 if(j instanceof Dot && !j.equals(i)) {
504 j.setHighlightMode(HighlightMode.None);
505 j.setHighlightColorToDefault();
506 }
507 }
508 l.getStartItem().setHighlightMode(HighlightMode.Connected);
509 l.getStartItem().setHighlightColorToDefault();
510 l.getEndItem().setHighlightMode(HighlightMode.Connected);
511 l.getEndItem().setHighlightColorToDefault();
512 } else {
513 for(Item j : i.getAllConnected()) {
514 if(j instanceof Dot && !j.equals(i)) {
515 j.setHighlightMode(HighlightMode.Connected);
516 j.setHighlightColorToDefault();
517 }
518 }
519 }
520// Collection<Item> connected = i.getAllConnected();
521// for (Item conn : connected) {
522// conn.setHighlightMode(Item.HighlightMode.Connected);
523// }
524 }
525 } else if (i instanceof Circle) {
526 i.setHighlightMode(Item.HighlightMode.Connected);
527 i.setHighlightColorToDefault();
528 } else if (!i.isVisible()) {
529 changeHighlightMode(i, Item.HighlightMode.Connected, null);
530 } else if (i instanceof Dot) {
531 // highlight the dot
532 if (i.hasPermission(UserAppliedPermission.full)) {
533 changeHighlightMode(i, Item.HighlightMode.Normal, Item.HighlightMode.None);
534 } else {
535 changeHighlightMode(i, Item.HighlightMode.Connected, Item.HighlightMode.Connected);
536 }
537 // highlight connected dots, but only if there aren't items being carried on the cursor
538 if(FreeItems.getInstance().size() == 0) {
539 if (StandardInputEventListeners.kbmStateListener.isKeyDown(Key.SHIFT)) {
540 for(Item j : i.getAllConnected()) {
541 if(j instanceof Dot && !j.equals(i)) {
542 j.setHighlightMode(HighlightMode.Connected);
543 j.setHighlightColorToDefault();
544 }
545 }
546 } else {
547 for(Item j : i.getAllConnected()) {
548 if(j instanceof Dot && !j.equals(i)) {
549 j.setHighlightMode(HighlightMode.None);
550 j.setHighlightColorToDefault();
551 }
552 }
553 for(Line l : i.getLines()) {
554 Item j = l.getOppositeEnd(i);
555 j.setHighlightMode(HighlightMode.Connected);
556 j.setHighlightColorToDefault();
557 }
558 }
559 }
560 } else {
561 // FrameGraphics.ChangeSelectionMode(i,
562 // Item.SelectedMode.Normal);
563 // For polygons need to make sure all other endpoints are
564 // unHighlighted
565 if (i.hasPermission(UserAppliedPermission.full)) {
566 changeHighlightMode(i, Item.HighlightMode.Normal, Item.HighlightMode.None);
567 } else {
568 changeHighlightMode(i, Item.HighlightMode.Connected, Item.HighlightMode.Connected);
569 }
570 }
571 DisplayController.requestRefresh(true);
572 return i;
573 }
574
575 public static void changeHighlightMode(Item item, Item.HighlightMode newMode)
576 {
577 changeHighlightMode(item, newMode, newMode);
578 }
579
580 public static void changeHighlightMode(Item item, Item.HighlightMode newMode, Item.HighlightMode connectedNewMode)
581 {
582 if (item == null) {
583 return;
584 }
585
586 if (item.hasVector()) {
587 for (Item i : item.getParentOrCurrentFrame().getVectorItems()) {
588 if (i.getEditTarget() == item) {
589 i.setHighlightMode(newMode);
590 i.setHighlightColorToDefault();
591 }
592 }
593 item.setHighlightMode(newMode);
594 item.setHighlightColorToDefault();
595 } else {
596 // Mike: TODO comment on why the line below is used!!
597 // I forgot already!! Oops
598 boolean freeItem = FreeItems.getInstance().contains(item);
599 for (Item i : item.getAllConnected()) {
600 if (/* freeItem || */!FreeItems.getInstance().contains(i)) {
601 i.setHighlightMode(connectedNewMode);
602 i.setHighlightColorToDefault();
603 }
604 }
605 if (!freeItem && newMode != connectedNewMode) {
606 item.setHighlightMode(newMode);
607 item.setHighlightColorToDefault();
608 }
609 }
610 DisplayController.requestRefresh(true);
611 }
612
613 /*
614 *
615 * FrameRenderPass stuff. (TODO: Not sure if this is used for anything? In Apollo. cts16)
616 *
617 */
618
619 /**
620 * Adds a FinalFrameRenderPass to the frame-render pipeline...
621 *
622 * Note that the last added FinalFrameRenderPass will be rendered at the
623 * very top.
624 *
625 * @param pass
626 * The pass to add. If already added then nothing results in the
627 * call.
628 *
629 * @throws NullPointerException
630 * If pass is null.
631 */
632 public static void addFrameRenderPass(FrameRenderPass pass) {
633 if (pass == null) {
634 throw new NullPointerException("pass");
635 }
636
637 if (!_frameRenderPasses.contains(pass)) {
638 _frameRenderPasses.add(pass);
639 }
640 }
641
642 /**
643 * Adds a FinalFrameRenderPass to the frame-render pipeline...
644 *
645 * Note that the last added FinalFrameRenderPass will be rendered at the
646 * very top.
647 *
648 * @param pass
649 * The pass to remove
650 *
651 */
652 public static void removeFrameRenderPass(FrameRenderPass pass) {
653 _frameRenderPasses.remove(pass);
654 }
655
656 /**
657 * A FinalFrameRenderPass is invoked at the very final stages for rendering
658 * a frame: that is, after the popups are drawn.
659 *
660 * There can be many applications for FinalFrameRenderPass. Such as tool
661 * tips, balloons, or drawing items at the highest Z-order in special
662 * situations.
663 *
664 * Although if there are multiples FinalFrameRenderPasses attach to the
665 * frame painter then it is not guaranteed to be rendered very last.
666 *
667 * @see FrameGraphics#addFinalFrameRenderPass(org.expeditee.gui.FrameGraphics.FrameRenderPass)
668 * @see FrameGraphics#removeFinalFrameRenderPass(org.expeditee.gui.FrameGraphics.FrameRenderPass)
669 *
670 * @author Brook Novak
671 */
672 public interface FrameRenderPass {
673
674 /**
675 *
676 * @param currentClip
677 *
678 * @return The clip that the pass should use instead. i.e. if there are
679 * any effects that cannot invalidate prior to paint call.
680 */
681 Clip paintStarted(Clip currentClip);
682
683 void paintFinalPass();
684
685 void paintPreLayeredPanePass();
686 }
687
688}
Note: See TracBrowser for help on using the repository browser.