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

Last change on this file since 1097 was 1097, checked in by davidb, 6 years ago

Newly structured files from Corey's work on logic/graphics separation

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.Image;
8import org.expeditee.core.EnforcedClipStack.EnforcedClipKey;
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
13 * to 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 {
37 this(null);
38 }
39
40 /** Constructor specifying the root surface. */
41 public GraphicsSurfaceStack(T rootSurface)
42 {
43 setRootSurface(rootSurface);
44 _currentImage = null;
45 _surfaceStack = new Stack<T>();
46 _imageStack = new Stack<Image>();
47 _rootClipStack = _currentClipStack = new EnforcedClipStack();
48 _clipStackStack = new Stack<EnforcedClipStack>();
49 }
50
51 /** Should be overridden by sub-types to allow a drawing surface to be extracted from an image. */
52 public abstract T getSurfaceFromImage(Image image);
53
54 /** Should be overridden by sub-types to set the actual clip on a given surface. */
55 public abstract void setSurfaceClip(T surface, Clip clip);
56
57 /** Pushes a new image onto the stack, and sets it as the current drawing surface. */
58 public void push(Image image)
59 {
60 if (image == null) return;
61
62 _currentSurface = getSurfaceFromImage(image);
63 _currentImage = image;
64 _currentClipStack = new EnforcedClipStack();
65 _surfaceStack.push(_currentSurface);
66 _imageStack.push(image);
67 _clipStackStack.push(_currentClipStack);
68 }
69
70 /** Removes an image from the stack. The removed image is returned, or null if the root surface was current. */
71 public Image pop()
72 {
73 if (_surfaceStack.isEmpty()) return null;
74
75 Image oldTop = _imageStack.pop();
76 _surfaceStack.pop();
77 _clipStackStack.pop();
78
79 if (!_surfaceStack.isEmpty()) {
80 _currentSurface = _surfaceStack.peek();
81 _currentImage = _imageStack.peek();
82 _currentClipStack = _clipStackStack.peek();
83 } else {
84 _currentSurface = _rootSurface;
85 _currentImage = null;
86 _currentClipStack = _rootClipStack;
87 }
88
89 return oldTop;
90 }
91
92 /** Gets a reference to the current drawing surface. */
93 public T getCurrentSurface()
94 {
95 return _currentSurface;
96 }
97
98 /** Gets a reference to the top image on the stack. */
99 public Image getCurrentImage()
100 {
101 return _currentImage;
102 }
103
104 /** Pushes a new clip onto the stack, ensuring that it is a sub-area of the top of the stack. */
105 public EnforcedClipKey pushClip(Clip clip)
106 {
107 EnforcedClipKey key = _currentClipStack.push(clip);
108 if (key != null) ensureClip();
109 return key;
110 }
111
112 /** Pops the top of the current clip-stack if there given key corresponds to it. */
113 public Clip popClip(EnforcedClipKey key)
114 {
115 Clip clip = _currentClipStack.pop(key);
116 if (clip != null) ensureClip();
117 return clip;
118 }
119
120 /** Returns a copy of the top of the current clip-stack. */
121 public Clip peekClip()
122 {
123 return _currentClipStack.peek();
124 }
125
126 /** Ensures the current clip is applied to the underlying surface. */
127 public void ensureClip()
128 {
129 setSurfaceClip(_currentSurface, _currentClipStack.peek());
130 }
131
132 /** Updates the root surface. Does not affect any stacked image surfaces. */
133 public void setRootSurface(T rootSurface)
134 {
135 if (_currentSurface == _rootSurface) _currentSurface = rootSurface;
136 _rootSurface = rootSurface;
137
138 }
139}
Note: See TracBrowser for help on using the repository browser.