source: trunk/src/org/expeditee/gio/GraphicsSurfaceStack.java@ 1500

Last change on this file since 1500 was 1163, checked in by bln4, 6 years ago
File size: 4.1 KB
RevLine 
[1097]1package org.expeditee.gio;
2
3import java.util.Stack;
4
5import org.expeditee.core.Clip;
6import org.expeditee.core.EnforcedClipStack;
[1163]7import org.expeditee.core.EnforcedClipStack.EnforcedClipKey;
[1097]8import org.expeditee.core.Image;
9
10/**
11 * Helper-class for the graphics manager to maintain a stack of drawing
[1142]12 * surfaces. Should be sub-typed by the platform-specific graphics manager to
13 * use the appropriate surface class.
[1097]14 */
15public abstract class GraphicsSurfaceStack<T> {
16
17 /** The root surface corresponds to drawing directly into the window. */
18 private T _rootSurface;
19 /** The surface that drawing commands should draw into. */
20 private T _currentSurface;
21 /** The stack of drawing surfaces. */
22 private Stack<T> _surfaceStack;
23 /** The image that produced the current drawing surface. */
24 private Image _currentImage;
25 /** The stack of images that produced the surfaces in the surface stack. */
26 private Stack<Image> _imageStack;
27 /** The clip-stack for the root surface. */
28 private EnforcedClipStack _rootClipStack;
29 /** The clip-stack for the current surface. */
30 private EnforcedClipStack _currentClipStack;
31 /** The clip-stack for each drawing surface. */
32 private Stack<EnforcedClipStack> _clipStackStack;
[1142]33
[1097]34 /** Constructor specifying no root surface. */
[1142]35 public GraphicsSurfaceStack() {
[1097]36 this(null);
37 }
[1142]38
[1097]39 /** Constructor specifying the root surface. */
[1142]40 public GraphicsSurfaceStack(T rootSurface) {
[1097]41 setRootSurface(rootSurface);
42 _currentImage = null;
43 _surfaceStack = new Stack<T>();
44 _imageStack = new Stack<Image>();
45 _rootClipStack = _currentClipStack = new EnforcedClipStack();
46 _clipStackStack = new Stack<EnforcedClipStack>();
47 }
[1142]48
49 /**
50 * Should be overridden by sub-types to allow a drawing surface to be extracted
51 * from an image.
52 */
[1097]53 public abstract T getSurfaceFromImage(Image image);
[1142]54
55 /**
56 * Should be overridden by sub-types to set the actual clip on a given surface.
57 */
[1097]58 public abstract void setSurfaceClip(T surface, Clip clip);
[1142]59
60 /**
61 * Pushes a new image onto the stack, and sets it as the current drawing
62 * surface.
63 */
64 public void push(Image image) {
[1163]65 if (image == null) {
[1142]66 return;
[1163]67 }
68
[1097]69 _currentSurface = getSurfaceFromImage(image);
70 _currentImage = image;
71 _currentClipStack = new EnforcedClipStack();
72 _surfaceStack.push(_currentSurface);
73 _imageStack.push(image);
74 _clipStackStack.push(_currentClipStack);
[1163]75
[1097]76 }
[1142]77
78 /**
79 * Removes an image from the stack. The removed image is returned, or null if
80 * the root surface was current.
81 */
82 public Image pop() {
[1163]83 if (_surfaceStack.isEmpty()) {
[1142]84 return null;
[1163]85 }
[1142]86
[1097]87 Image oldTop = _imageStack.pop();
88 _surfaceStack.pop();
89 _clipStackStack.pop();
[1142]90
[1097]91 if (!_surfaceStack.isEmpty()) {
92 _currentSurface = _surfaceStack.peek();
93 _currentImage = _imageStack.peek();
94 _currentClipStack = _clipStackStack.peek();
95 } else {
96 _currentSurface = _rootSurface;
97 _currentImage = null;
98 _currentClipStack = _rootClipStack;
99 }
[1142]100
[1097]101 return oldTop;
102 }
[1142]103
[1097]104 /** Gets a reference to the current drawing surface. */
[1142]105 public T getCurrentSurface() {
[1097]106 return _currentSurface;
107 }
[1142]108
[1097]109 /** Gets a reference to the top image on the stack. */
[1142]110 public Image getCurrentImage() {
[1097]111 return _currentImage;
112 }
[1142]113
114 /**
115 * Pushes a new clip onto the stack, ensuring that it is a sub-area of the top
116 * of the stack.
117 */
118 public EnforcedClipKey pushClip(Clip clip) {
[1097]119 EnforcedClipKey key = _currentClipStack.push(clip);
[1163]120 if (key != null) {
[1142]121 ensureClip();
[1163]122 }
[1097]123 return key;
124 }
[1142]125
126 /**
127 * Pops the top of the current clip-stack if there given key corresponds to it.
128 */
129 public Clip popClip(EnforcedClipKey key) {
[1097]130 Clip clip = _currentClipStack.pop(key);
[1163]131 if (clip != null) {
[1142]132 ensureClip();
[1163]133 }
[1097]134 return clip;
135 }
[1142]136
[1097]137 /** Returns a copy of the top of the current clip-stack. */
[1142]138 public Clip peekClip() {
[1097]139 return _currentClipStack.peek();
140 }
[1142]141
[1097]142 /** Ensures the current clip is applied to the underlying surface. */
[1142]143 public void ensureClip() {
[1097]144 setSurfaceClip(_currentSurface, _currentClipStack.peek());
145 }
[1142]146
[1097]147 /** Updates the root surface. Does not affect any stacked image surfaces. */
[1142]148 public void setRootSurface(T rootSurface) {
[1163]149 if (_currentSurface == _rootSurface) {
[1142]150 _currentSurface = rootSurface;
[1163]151 }
[1097]152 _rootSurface = rootSurface;
[1142]153
[1097]154 }
155}
Note: See TracBrowser for help on using the repository browser.