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
Line 
1package org.expeditee.gio;
2
3import java.util.Stack;
4
5import org.expeditee.core.Clip;
6import org.expeditee.core.EnforcedClipStack;
7import org.expeditee.core.EnforcedClipStack.EnforcedClipKey;
8import org.expeditee.core.Image;
9
10/**
11 * Helper-class for the graphics manager to maintain a stack of drawing
12 * surfaces. Should be sub-typed by the platform-specific graphics manager to
13 * use the appropriate surface class.
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;
33
34 /** Constructor specifying no root surface. */
35 public GraphicsSurfaceStack() {
36 this(null);
37 }
38
39 /** Constructor specifying the root surface. */
40 public GraphicsSurfaceStack(T rootSurface) {
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 }
48
49 /**
50 * Should be overridden by sub-types to allow a drawing surface to be extracted
51 * from an image.
52 */
53 public abstract T getSurfaceFromImage(Image image);
54
55 /**
56 * Should be overridden by sub-types to set the actual clip on a given surface.
57 */
58 public abstract void setSurfaceClip(T surface, Clip clip);
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) {
65 if (image == null) {
66 return;
67 }
68
69 _currentSurface = getSurfaceFromImage(image);
70 _currentImage = image;
71 _currentClipStack = new EnforcedClipStack();
72 _surfaceStack.push(_currentSurface);
73 _imageStack.push(image);
74 _clipStackStack.push(_currentClipStack);
75
76 }
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() {
83 if (_surfaceStack.isEmpty()) {
84 return null;
85 }
86
87 Image oldTop = _imageStack.pop();
88 _surfaceStack.pop();
89 _clipStackStack.pop();
90
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 }
100
101 return oldTop;
102 }
103
104 /** Gets a reference to the current drawing surface. */
105 public T getCurrentSurface() {
106 return _currentSurface;
107 }
108
109 /** Gets a reference to the top image on the stack. */
110 public Image getCurrentImage() {
111 return _currentImage;
112 }
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) {
119 EnforcedClipKey key = _currentClipStack.push(clip);
120 if (key != null) {
121 ensureClip();
122 }
123 return key;
124 }
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) {
130 Clip clip = _currentClipStack.pop(key);
131 if (clip != null) {
132 ensureClip();
133 }
134 return clip;
135 }
136
137 /** Returns a copy of the top of the current clip-stack. */
138 public Clip peekClip() {
139 return _currentClipStack.peek();
140 }
141
142 /** Ensures the current clip is applied to the underlying surface. */
143 public void ensureClip() {
144 setSurfaceClip(_currentSurface, _currentClipStack.peek());
145 }
146
147 /** Updates the root surface. Does not affect any stacked image surfaces. */
148 public void setRootSurface(T rootSurface) {
149 if (_currentSurface == _rootSurface) {
150 _currentSurface = rootSurface;
151 }
152 _rootSurface = rootSurface;
153
154 }
155}
Note: See TracBrowser for help on using the repository browser.