source: trunk/src/org/expeditee/gui/DisplayIO.java@ 306

Last change on this file since 306 was 306, checked in by ra33, 16 years ago

Added some HELP actions
More mail stuff... and networking stuff
Can now save frames and send messages to peers
Also version control prevent versions from being lost

File size: 22.3 KB
Line 
1package org.expeditee.gui;
2
3import java.awt.AWTException;
4import java.awt.Color;
5import java.awt.Cursor;
6import java.awt.Image;
7import java.awt.Point;
8import java.awt.Robot;
9import java.awt.Toolkit;
10import java.awt.geom.Point2D;
11import java.awt.image.MemoryImageSource;
12import java.util.ArrayList;
13import java.util.Collection;
14import java.util.HashSet;
15import java.util.LinkedList;
16import java.util.List;
17import java.util.Stack;
18
19import javax.swing.JOptionPane;
20
21import org.expeditee.items.Item;
22import org.expeditee.items.ItemParentStateChangedEvent;
23import org.expeditee.items.Permission;
24import org.expeditee.items.Picture;
25import org.expeditee.items.Text;
26import org.expeditee.stats.SessionStats;
27import org.expeditee.taskmanagement.EntitySaveManager;
28
29/**
30 * This Interface is used by the Frame to control all display input and output.
31 *
32 * @author jdm18
33 *
34 */
35public class DisplayIO {
36
37 private static final int SMALL_CURSOR_SIZE = 16;
38
39 private static final int MEDIUM_CURSOR_SIZE = 32;
40
41 private static final int LARGE_CURSOR_SIZE = 64;
42
43 /**
44 * The color to be used to highlight the linked parent item, when the user
45 * navigates backwards.
46 */
47 public static final Color BACK_HIGHLIGHT_COLOR = Color.MAGENTA;
48
49 private static Browser _Browser;
50
51 // The current Frame being displayed on the screen.
52 private static Frame _CurrentFrames[] = new Frame[2];
53
54 // Maintains the list of frames visited thus-far for back-tracking
55 @SuppressWarnings("unchecked")
56 private static Stack<String>[] _VisitedFrames = new Stack[2];
57 @SuppressWarnings("unchecked")
58 private static Stack<String>[] _BackedUpFrames = new Stack[2];
59
60 // used to change the mouse cursor position on the screen
61 private static Robot _Robot;
62
63 private static boolean _TwinFrames = false;
64
65 /** Notified whenever the frame changes */
66 private static HashSet<DisplayIOObserver> _displayIOObservers = new HashSet<DisplayIOObserver>();
67
68 /**
69 * The title to display in the Title bar.
70 */
71 public static final String TITLE = "Exp15Sep2008A";
72
73 private DisplayIO() {
74 }
75
76 public static void Init(Browser browser) {
77 _Browser = browser;
78 try {
79 _Robot = new Robot();
80 } catch (AWTException e) {
81 e.printStackTrace();
82 }
83
84 Point mouse = _Browser.getMousePosition();
85 if (mouse != null) {
86 FrameMouseActions.MouseX = mouse.x;
87 FrameMouseActions.MouseY = mouse.y;
88 }
89
90 _VisitedFrames[0] = new Stack<String>();
91 _VisitedFrames[1] = new Stack<String>();
92 _BackedUpFrames[0] = new Stack<String>();
93 _BackedUpFrames[1] = new Stack<String>();
94 }
95
96 /**
97 * Notifies observers that the frame has changed.
98 */
99 private static void fireFrameChanged() {
100 for (DisplayIOObserver observer : _displayIOObservers) {
101 observer.frameChanged();
102 }
103 }
104
105 /**
106 * Adds a DisplayIOObserver to the DisplayIO. DisplayIOObserver's are
107 * notified when frame changes.
108 *
109 * @see #removeDisplayIOObserver(DisplayIOObserver)
110 *
111 * @param observer
112 * The observer to add
113 *
114 * @throws NullPointerException
115 * If observer is null.
116 */
117 public static void addDisplayIOObserver(DisplayIOObserver observer) {
118 if (observer == null) throw new NullPointerException("observer");
119 _displayIOObservers.add(observer);
120 }
121
122 /**
123 * Removes a DisplayIOObserver from the DisplayIO.
124 *
125 * @see #addDisplayIOObserver(DisplayIOObserver)
126 *
127 * @param observer
128 * The observer to add
129 *
130 * @throws NullPointerException
131 * If observer is null.
132 */
133 public static void removeDisplayIOObserver(DisplayIOObserver observer) {
134 if (observer == null) throw new NullPointerException("observer");
135 _displayIOObservers.remove(observer);
136 }
137
138 public static void setTextCursor(Text text, int cursorMovement) {
139 setTextCursor(text, cursorMovement, false, false);
140 }
141
142 public static void setTextCursor(Text text, int cursorMovement,
143 boolean newSize, boolean isShiftDown) {
144
145 int size = Math.round(text.getSize());
146 Point2D.Float newMouse = text.moveCursor(cursorMovement, DisplayIO
147 .getFloatMouseX(), FrameMouseActions.MouseY, isShiftDown);
148
149 if (!newSize && cursorType == Item.TEXT_CURSOR) {
150 if (cursorMovement != 0)
151 DisplayIO.setCursorPosition(newMouse, false);
152 return;
153 }
154
155 cursorType = Item.TEXT_CURSOR;
156
157 // Do some stuff to adjust the cursor size based on the font size
158 final int MEDIUM_CURSOR_CUTOFF = 31;
159 final int LARGE_CURSOR_CUTOFF = 62;
160
161 int cursorSize = LARGE_CURSOR_SIZE;
162 int hotspotPos = 0;
163 int start = 0;
164
165 if (size < MEDIUM_CURSOR_CUTOFF) {
166 cursorSize = MEDIUM_CURSOR_SIZE;
167 start = cursorSize - size - 2;
168 hotspotPos = cursorSize - (size + 2) / 4;
169 } else if (size < LARGE_CURSOR_CUTOFF) {
170 hotspotPos = cursorSize - (size - 5) / 4;
171 start = cursorSize - size - 2;
172 } else {
173 int FIXED_CURSOR_MIN = 77;
174 if (size >= FIXED_CURSOR_MIN) {
175 hotspotPos = cursorSize - 2;
176 } else {
177 hotspotPos = size - (FIXED_CURSOR_MIN - cursorSize);
178 }
179 }
180
181 int[] pixels = new int[cursorSize * cursorSize];
182
183 for (int i = start; i < cursorSize; i++)
184 pixels[i * cursorSize] = pixels[(i * cursorSize) + 1] = 0xFF000000;
185
186 Image image = Toolkit.getDefaultToolkit().createImage(
187 new MemoryImageSource(cursorSize, cursorSize, pixels, 0,
188 cursorSize));
189 Cursor textCursor = Toolkit.getDefaultToolkit().createCustomCursor(
190 image, new Point(0, hotspotPos), "textcursor");
191 _Browser.setCursor(textCursor);
192 if (cursorMovement != Text.NONE)
193 DisplayIO.setCursorPosition(newMouse, false);
194 }
195
196 /**
197 * Sets the type of cursor the display should be using
198 *
199 * @param type
200 * The type of cursor to display, using constants defined in the
201 * Cursor class.
202 */
203 public static void setCursor(int type) {
204 // avoid flicker when not changing
205 if (type == cursorType || type == Item.UNCHANGED_CURSOR)
206 return;
207
208 cursorType = type;
209
210 if (type == Item.HIDDEN_CURSOR) {
211 int[] pixels = new int[SMALL_CURSOR_SIZE * SMALL_CURSOR_SIZE];
212 Image image = Toolkit.getDefaultToolkit().createImage(
213 new MemoryImageSource(SMALL_CURSOR_SIZE, SMALL_CURSOR_SIZE,
214 pixels, 0, SMALL_CURSOR_SIZE));
215 Cursor transparentCursor = Toolkit.getDefaultToolkit()
216 .createCustomCursor(image, new Point(0, 0),
217 "invisiblecursor");
218 _Browser.setCursor(transparentCursor);
219 } else
220 _Browser.setCursor(new Cursor(type));
221 }
222
223 private static int cursorType = Item.DEFAULT_CURSOR;
224
225 public static int getCursor() {
226 return cursorType;
227 }
228
229 /**
230 * Moves the mouse cursor to the given x,y coordinates on the screen
231 *
232 * @param x
233 * The x coordinate
234 * @param y
235 * The y coordinate
236 */
237 public static void setCursorPosition(float x, float y) {
238 setCursorPosition(x, y, true);
239 }
240
241 public static void setCursorPosition(float x, float y, boolean forceArrow) {
242 // Adjust the position to move the mouse to to account for being in
243 // TwinFramesMode
244 if (_TwinFrames) {
245 if (getCurrentSide() == 1) {
246 int middle = getMiddle();
247 x += middle;
248 }
249 }
250
251 float deltax = x - FrameMouseActions.MouseX;
252 float deltay = y - FrameMouseActions.MouseY;
253
254 // When the Robot moves the cursor... a short time later a mouseMoved
255 // event is generated...
256 // We want to ignore this event by remembering the location the robot
257 // was shifted to.
258 FrameMouseActions.setLastRobotMove(x, y);
259
260 if (FreeItems.itemsAttachedToCursor()) {
261 List<Item> toMove = FreeItems.getInstance();
262 for (Item move : toMove) {
263 move.setPosition(move.getX() + deltax, move.getY() + deltay);
264 }
265 }
266
267 // cheat
268 FrameMouseActions.setForceArrow(forceArrow);
269 int mouseX = (int) _Browser.getContentPane().getLocationOnScreen()
270 .getX()
271 + Math.round(x);
272 int mouseY = (int) _Browser.getContentPane().getLocationOnScreen()
273 .getY()
274 + Math.round(y);
275 _Robot.mouseMove(mouseX, mouseY);
276 // System.out.println("MouseMoved: " + x + "," + y);
277 }
278
279 public static void resetCursorOffset() {
280 FrameMouseActions.resetOffset();
281 }
282
283 /**
284 * Sets the current cursor position in the current frame
285 *
286 * @param pos
287 */
288 public static void setCursorPosition(Point2D.Float pos) {
289 setCursorPosition(pos.x, pos.y);
290 }
291
292 public static void setCursorPosition(Point pos) {
293 setCursorPosition(pos.x, pos.y);
294 }
295
296 public static void setCursorPosition(Point pos, boolean forceArrow) {
297 setCursorPosition(pos.x, pos.y, forceArrow);
298 }
299
300 public static void setCursorPosition(Point2D.Float pos, boolean forceArrow) {
301 setCursorPosition(pos.x, pos.y, forceArrow);
302 }
303
304 /**
305 * Returns the top item (last added) of the Back-Stack (which is popped off)
306 *
307 * @return The name of the last Frame added to the back-stack
308 */
309 public static String getLastFrame() {
310 int side = getCurrentSide();
311
312 if (_VisitedFrames[side].size() > 0)
313 return _VisitedFrames[side].pop();
314 else
315 return null;
316 }
317
318 /**
319 * Adds the given Frame to the back-stack
320 *
321 * @param frame
322 * The Frame to add
323 */
324 public static void addToBack(Frame toAdd) {
325 int side = getCurrentSide();
326
327 // // do not allow duplicate frames
328 // if (_VisitedFrames[side].size() > 0)
329 // if (_VisitedFrames[side].peek().equals(toAdd.getName())) {
330 // return;
331 // }
332
333 Item ip = FrameUtils.getCurrentItem();
334 if (ip == null)
335 _VisitedFrames[side].push(toAdd.getName());
336 else
337 _VisitedFrames[side].push(toAdd.getName());
338 // System.out.println("Added: " + _VisitedFrames[side].size());
339 }
340
341 public static String removeFromBack() {
342 int side = getCurrentSide();
343
344 // there must be a frame to go back to
345 if (_VisitedFrames[side].size() > 0) {
346 return _VisitedFrames[side].pop();
347 }
348 return null;
349 }
350
351 /**
352 * Returns a 'peek' at the end element on the back-stack of the current
353 * side. If the back-stack is empty, null is returned.
354 *
355 * @return The name of the most recent Frame added to the back-stack, or
356 * null if the back-stack is empty.
357 */
358 public static String peekFromBackUpStack() {
359 int side = getCurrentSide();
360
361 // check that the stack is not empty
362 if (_VisitedFrames[side].size() > 0)
363 return _VisitedFrames[side].peek();
364
365 // if the stack is empty, return null
366 return null;
367 }
368
369 public static void setCurrentFrame(Frame frame, boolean incrementStats) {
370 if (frame == null)
371 return;
372
373 if (_TwinFrames) {
374 if (_CurrentFrames[0] == null) {
375 _CurrentFrames[0] = frame;
376 fireFrameChanged();
377 return;
378 }
379 if (_CurrentFrames[1] == null) {
380 _CurrentFrames[1] = frame;
381 fireFrameChanged();
382 return;
383 }
384 }
385
386 // if this is already the current frame
387 if (frame == getCurrentFrame()) {
388 FrameGraphics.Repaint();
389 MessageBay.displayMessage(frame.getName()
390 + " is already the current frame.");
391 return;
392 } else if(incrementStats) {
393 SessionStats.AccessedFrame();
394 }
395
396 // Invalidate free items
397 if (!FreeItems.getInstance().isEmpty() && getCurrentFrame() != null) {
398
399 // Empty free items temporarily so that the old frames buffer is
400 // repainted
401 // without the free items.
402 ArrayList<? extends Item> tmp = (ArrayList<? extends Item>) FreeItems
403 .getInstance().clone();
404 FreeItems.getInstance().clear(); // NOTE: This will invalidate
405 // all the cleared free items
406 FrameGraphics.refresh(true);
407 FreeItems.getInstance().addAll(tmp);
408
409 }
410
411 // Changing frames is a Save point for saveable entities:
412 EntitySaveManager.getInstance().saveAll();
413
414 if (_TwinFrames) {
415 // if the same frame is being shown in both sides, load a fresh
416 // copy from disk
417 if (_CurrentFrames[getOppositeSide()] == frame
418 || _CurrentFrames[getOppositeSide()].hasOverlay(frame)) {
419 FrameIO.SuspendCache();
420 frame = FrameIO.LoadFrame(frame.getName());
421 FrameIO.ResumeCache();
422 }
423
424 // If the frames are the same then the items for the
425 // frame that is just about to hide will still be in view
426 // so only notify items that they are hidden if the
427 // frames differ.
428 if (_CurrentFrames[getCurrentSide()] != null
429 && _CurrentFrames[0] != _CurrentFrames[1]) {
430 for (Item i : _CurrentFrames[getCurrentSide()].getItems()) {
431 i.onParentStateChanged(new ItemParentStateChangedEvent(
432 _CurrentFrames[getCurrentSide()],
433 ItemParentStateChangedEvent.EVENT_TYPE_HIDDEN));
434 }
435 }
436 _CurrentFrames[getCurrentSide()] = frame;
437
438 // BROOK : TODO... overlays and loadable widgets
439 for (Item i : _CurrentFrames[getCurrentSide()].getItems()) {
440 i.onParentStateChanged(new ItemParentStateChangedEvent(
441 _CurrentFrames[getCurrentSide()],
442 ItemParentStateChangedEvent.EVENT_TYPE_SHOWN));
443 }
444 } else {
445
446 // Notifying items on the frame being hidden that they
447 // are about to be hidden.
448 // ie. Widgets use this method to remove themselves from the JPanel
449 List<Frame> currentOnlyOverlays = new LinkedList<Frame>();
450 List<Frame> nextOnlyOverlays = new LinkedList<Frame>();
451 List<Frame> sharedOverlays = new LinkedList<Frame>();
452
453 // Get all overlayed frames seen by the next frame
454 for (Overlay o : frame.getOverlays()) {
455 if (!nextOnlyOverlays.contains(o))
456 nextOnlyOverlays.add(o.Frame);
457 }
458
459 // Get all overlayed frames seen by the current frame
460 if (_CurrentFrames[getCurrentSide()] != null) {
461 for (Overlay o : _CurrentFrames[getCurrentSide()].getOverlays()) {
462 if (!currentOnlyOverlays.contains(o))
463 currentOnlyOverlays.add(o.Frame);
464 }
465 }
466
467 // Extract shared overlays between the current and next frame
468 for (Frame of : currentOnlyOverlays) {
469 if (nextOnlyOverlays.contains(of)) {
470 sharedOverlays.add(of);
471 }
472 }
473
474 // The first set, currentOnlyOverlays, must be notified that they
475 // are hidden
476 Collection<Item> items = new LinkedList<Item>();
477
478 // Notify items that will not be in view any more
479 if (_CurrentFrames[getCurrentSide()] != null) {
480 List<Frame> seen = new LinkedList<Frame>();
481 seen.addAll(sharedOverlays); // Signify that seen all shared
482 // overlays
483 seen.remove(_CurrentFrames[getCurrentSide()]); // must ensure
484 // excluded
485
486 // Get all items seen from the current frame - including all
487 // possible non-shared overlays
488 items = _CurrentFrames[getCurrentSide()].getAllItems();
489 for (Frame f : seen)
490 items.removeAll(f.getAllItems());
491
492 // Notify items that they are hidden
493 for (Item i : items) {
494 i.onParentStateChanged(new ItemParentStateChangedEvent(
495 _CurrentFrames[getCurrentSide()],
496 ItemParentStateChangedEvent.EVENT_TYPE_HIDDEN));
497 }
498 }
499
500 // Set the new frame
501 _CurrentFrames[getCurrentSide()] = frame;
502 frame.refreshSize();
503 // Notify items on the frame being displayed that they are in view
504 // ie. widgets use this method to add themselves to the content pane
505 items.clear();
506
507 // Notify overlay items that they are shown
508 for (Item i : frame.getOverlayItems()) {
509 Overlay owner = frame.getOverlayOwner(i);
510 // if (owner == null) i.onParentFameShown(false, 0);
511 // else ...
512 assert (owner != null);
513 i
514 .onParentStateChanged(new ItemParentStateChangedEvent(
515 frame,
516 ItemParentStateChangedEvent.EVENT_TYPE_SHOWN_VIA_OVERLAY,
517 owner.permission));
518 }
519
520 for (Item i : frame.getItems()) {
521 i.onParentStateChanged(new ItemParentStateChangedEvent(frame,
522 ItemParentStateChangedEvent.EVENT_TYPE_SHOWN));
523 }
524 }
525 frame.refreshItemPermissions(Permission.full);
526 FrameMouseActions.getInstance().refreshHighlights();
527 FrameGraphics.refresh(false);
528 fireFrameChanged();
529 }
530
531 public static void UpdateTitle() {
532 StringBuffer title = new StringBuffer(TITLE);
533
534 if (FrameGraphics.isAudienceMode())
535 title.append(" - Audience Mode");
536 else if (FrameGraphics.isXRayMode())
537 title.append(" - X-Ray Mode");
538 else
539 title.append(" [").append(SessionStats.getShortStats()).append(']');
540
541 _Browser.setTitle(title.toString());
542 }
543
544 public static int getCurrentSide() {
545 if (_Browser == null)
546 return 0;
547
548 if (_TwinFrames
549 && FrameMouseActions.MouseX >= (_Browser.getWidth() / 2F)
550 && _CurrentFrames[1] != null)
551 return 1;
552
553 if (_CurrentFrames[0] == null && _CurrentFrames[1] != null)
554 return 1;
555
556 return 0;
557 }
558
559 private static int getOppositeSide() {
560 if (getCurrentSide() == 0)
561 return 1;
562
563 return 0;
564 }
565
566 public static int FrameOnSide(Frame toFind) {
567 if (_CurrentFrames[0] == toFind)
568 return 0;
569
570 if (_CurrentFrames[1] == toFind)
571 return 1;
572
573 return -1;
574 }
575
576 /**
577 * Returns the Frame currently being displayed on the screen.
578 *
579 * @return The Frame currently displayed.
580 */
581 public static Frame getCurrentFrame() {
582 return _CurrentFrames[getCurrentSide()];
583 }
584
585 public static Frame getOppositeFrame() {
586 return _CurrentFrames[getOppositeSide()];
587 }
588
589 public static Frame[] getFrames() {
590 return _CurrentFrames;
591 }
592
593 public static int getMiddle() {
594 return _Browser.getWidth() / 2;
595 }
596
597 public static int getHeight() {
598 return _Browser.getHeight();
599 }
600
601 /**
602 * Returns the current mouse X coordinate. This coordinate is relative to
603 * the left edge of the frame the mouse is in. It takes into account the
604 * user being in twin frames mode.
605 *
606 * @return The X coordinate of the mouse.
607 */
608 public static float getFloatMouseX() {
609 if (_TwinFrames
610 && FrameMouseActions.MouseY < FrameGraphics.getMaxSize().height)
611 return FrameMouseActions.MouseX % (_Browser.getWidth() / 2);
612
613 return FrameMouseActions.MouseX;
614 }
615
616 /**
617 * Returns the current mouse X coordinate. This coordinate is relative to
618 * the left edge of the frame the mouse is in. It takes into account the
619 * user being in twin frames mode.
620 *
621 * @return The X coordinate of the mouse.
622 */
623 public static int getMouseX() {
624 return Math.round(getFloatMouseX());
625 }
626
627 public static boolean Back() {
628 int side = getCurrentSide();
629
630 // there must be a frame to go back to
631 if (_VisitedFrames[side].size() < 1) {
632 MessageBay.displayMessageOnce("You are already on the home frame");
633 return false;
634 }
635
636 if (!FrameUtils.LeavingFrame(getCurrentFrame())) {
637 MessageBay.displayMessage("Error navigating back");
638 return false;
639 }
640
641 String oldFrame = getCurrentFrame().getName().toLowerCase();
642
643 // do not get a cached version (in case it is in the other window)
644 if (isTwinFramesOn())
645 FrameIO.SuspendCache();
646 Frame frame = FrameIO.LoadFrame(removeFromBack());
647 // If the top frame on the backup stack is the current frame go back
648 // again... or if it has been deleted
649 //Recursively backup the stack
650 if(frame == null || frame.equals(getCurrentFrame())) {
651 Back();
652 return false;
653 }
654
655 if (isTwinFramesOn()) {
656 FrameIO.ResumeCache();
657 }
658 _BackedUpFrames[side].push(oldFrame);
659 FrameUtils.DisplayFrame(frame, false);
660 FrameMouseActions.setHighlightHold(true);
661
662 for (Item i : frame.getItems()) {
663 if (i.getLink() != null
664 && i.getAbsoluteLink().toLowerCase().equals(oldFrame)) {
665 if (i.getHighlightMode() != Item.HighlightMode.Normal) {
666 i.setHighlightMode(Item.HighlightMode.Normal,
667 BACK_HIGHLIGHT_COLOR);
668 }
669 // check if its an @f item and if so update the buffer
670 if (i instanceof Picture) {
671 Picture p = (Picture) i;
672 p.refresh();
673 }
674 }
675 }
676 FrameGraphics.requestRefresh(true);
677 return true;
678 }
679
680 public static boolean Forward() {
681 int side = getCurrentSide();
682
683 // there must be a frame to go back to
684 if (_BackedUpFrames[side].size() == 0) {
685 return false;
686 }
687
688 if (!FrameUtils.LeavingFrame(getCurrentFrame())) {
689 MessageBay.displayMessage("Error navigating forward");
690 return false;
691 }
692
693 String oldFrame = getCurrentFrame().getName().toLowerCase();
694
695 // do not get a cached version (in case it is in the other window)
696 if (isTwinFramesOn())
697 FrameIO.SuspendCache();
698 Frame frame = FrameIO.LoadFrame(_BackedUpFrames[side].pop());
699 // If the top frame on the backup stack is the current frame go back
700 // again... or if it has been deleted
701 //Recursively backup the stack
702 if(frame == null || frame.equals(getCurrentFrame())) {
703 Forward();
704 return false;
705 }
706
707 if (isTwinFramesOn()) {
708 FrameIO.ResumeCache();
709 }
710 _VisitedFrames[side].push(oldFrame);
711 FrameUtils.DisplayFrame(frame, false);
712 FrameGraphics.requestRefresh(true);
713 return true;
714 }
715
716 /**
717 * Toggles the display of frames between TwinFrames mode and Single frame
718 * mode.
719 */
720 public static void ToggleTwinFrames() {
721 // determine which side is the active side
722 int opposite = getOppositeSide();
723 int current = getCurrentSide();
724 _TwinFrames = !_TwinFrames;
725
726 // if TwinFrames is being turned on
727 if (_TwinFrames) {
728 // if this is the first time TwinFrames has been toggled on,
729 // load the user's first frame
730 if (_VisitedFrames[opposite].size() == 0) {
731 FrameIO.SuspendCache();
732 setCurrentFrame(FrameIO.LoadFrame(UserSettings.FirstFrame), true);
733 FrameIO.ResumeCache();
734 } else {
735 // otherwise, restore the frame from the side's back-stack
736 setCurrentFrame(FrameIO.LoadFrame(_VisitedFrames[opposite]
737 .pop()), true);
738 }
739
740 // else, TwinFrames is being turned off
741 } else {
742 // add the frame to the back-stack
743 Frame hiding = _CurrentFrames[opposite];
744 FrameUtils.LeavingFrame(hiding);
745 _VisitedFrames[opposite].add(hiding.getName());
746 _CurrentFrames[opposite] = null;
747 _CurrentFrames[current].refreshSize();
748 }
749 if (_CurrentFrames[current] != null)
750 _CurrentFrames[current].refreshSize();
751 if (_CurrentFrames[opposite] != null)
752 _CurrentFrames[opposite]
753 .refreshSize();
754
755 FrameGraphics.Clear();
756 FrameGraphics.requestRefresh(false);
757 FrameGraphics.Repaint();
758 }
759
760 public static boolean isTwinFramesOn() {
761 return _TwinFrames;
762 }
763
764 public static void Reload(int side) {
765 if (side < 0)
766 return;
767
768 FrameIO.SuspendCache();
769 _CurrentFrames[side] = FrameIO
770 .LoadFrame(_CurrentFrames[side].getName());
771 FrameIO.ResumeCache();
772 }
773
774 public static boolean DisplayConfirmDialog(String message, String title,
775 int type, int options, int res) {
776 return JOptionPane.showConfirmDialog(_Browser, message, title, options,
777 type) == res;
778 }
779
780 public static final int RESULT_OK = JOptionPane.OK_OPTION;
781
782 public static final int OPTIONS_OK_CANCEL = JOptionPane.OK_CANCEL_OPTION;
783
784 public static final int TYPE_WARNING = JOptionPane.WARNING_MESSAGE;
785
786 public static void pressMouse(int buttons) {
787 _Robot.mousePress(buttons);
788 }
789
790 public static void releaseMouse(int buttons) {
791 _Robot.mouseRelease(buttons);
792 }
793
794 public static void clickMouse(int buttons) {
795 _Robot.mousePress(buttons);
796 _Robot.mouseRelease(buttons);
797 }
798
799 /**
800 * Moves the cursor the end of this item.
801 *
802 * @param i
803 */
804 public static void MoveCursorToEndOfItem(Item i) {
805 setTextCursor((Text) i, Text.END, true, false);
806 }
807
808 public static void translateCursor(int deltaX, int deltaY) {
809 setCursorPosition(FrameMouseActions.MouseX + deltaX,
810 FrameMouseActions.MouseY + deltaY, false);
811 }
812
813 public static void clearBackedUpFrames() {
814 _BackedUpFrames[getCurrentSide()].clear();
815 }
816}
Note: See TracBrowser for help on using the repository browser.