comparison dwtx/draw2d/UpdateManager.d @ 98:95307ad235d9

Added Draw2d code, still work in progress
author Frank Benoit <benoit@tionex.de>
date Sun, 03 Aug 2008 00:52:14 +0200
parents
children
comparison
equal deleted inserted replaced
96:b492ba44e44d 98:95307ad235d9
1 /*******************************************************************************
2 * Copyright (c) 2000, 2005 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 * Port to the D programming language:
11 * Frank Benoit <benoit@tionex.de>
12 *******************************************************************************/
13 module dwtx.draw2d.UpdateManager;
14
15 import dwt.dwthelper.utils;
16 import dwt.dwthelper.Runnable;
17 import dwtx.dwtxhelper.Collection;
18
19 import dwt.graphics.GC;
20 import dwtx.draw2d.geometry.Rectangle;
21 import dwtx.draw2d.IFigure;
22 import dwtx.draw2d.UpdateListener;
23 import dwtx.draw2d.GraphicsSource;
24
25 /**
26 * Update managers handle the job of laying out and repainting figures. A desirable
27 * implementation is to batches work to be done and collapses any redundant work. For
28 * example, clients may be making multiple changes to figures, which require laying out
29 * the same container or repainting the same region.
30 * <P>
31 * The update manager receives requests to validate certain figures, and repaint certain
32 * areas of figures. An update manager could process every request synchronously, or it
33 * could batch these requests and process them asynchronously.
34 * <P>
35 * The update process occurs in two phases. The first phase is laying out invalid figures.
36 * This phase comes first because it usually introduces additional damage regions. In some
37 * cases, while validating figures, new invalid figures may be appended to the update
38 * manager. Of course, damage regions will be reported too as figures are layed out.
39 * <P>
40 * The second phase is to repaint all damaged areas. The update manager will typically
41 * batch, clip, and union, all rectangles and perform a single paint of the overall
42 * damaged area.
43 *
44 */
45 public abstract class UpdateManager {
46
47 private UpdateListener listeners[];
48 private bool disposed;
49
50 /**
51 * Adds the dirty region defined by the coordinates on the IFigure <b>figure</b>. The
52 * update manager should repaint the dirty region in a timely fashion.
53 *
54 * @param figure the dirty figure
55 * @param x the x coordinate of the dirty region
56 * @param y the y coordinate of the dirty region
57 * @param w the width of the dirty region
58 * @param h the height of the dirty region
59 */
60 public abstract void addDirtyRegion(IFigure figure, int x, int y, int w, int h);
61
62 /**
63 * @see #addDirtyRegion(IFigure, int, int, int, int)
64 */
65 public void addDirtyRegion(IFigure figure, Rectangle rect) {
66 addDirtyRegion(figure, rect.x, rect.y, rect.width, rect.height);
67 }
68
69 /**
70 * Causes an update to occur at some time, and the given runnable to be executed
71 * following the update.
72 * @since 3.1
73 * @param run the runnable
74 */
75 public void runWithUpdate(Runnable run) { }
76
77 /**
78 * The receiver should call validate() on the IFigure <i>figure</i> in a timely fashion.
79 *
80 * @param figure the invalid figure
81 */
82 public abstract void addInvalidFigure(IFigure figure);
83
84 /**
85 * Adds the given listener to the list of listeners to be notified of painting and
86 * validation.
87 * @param listener the listener to add
88 */
89 public void addUpdateListener(UpdateListener listener) {
90 if (listener is null)
91 throw new IllegalArgumentException("");
92 if (listeners is null) {
93 listeners = new UpdateListener[1];
94 listeners[0] = listener;
95 } else {
96 int oldSize = listeners.length;
97 UpdateListener newListeners[] = new UpdateListener[oldSize + 1];
98 SimpleType!(UpdateListener).arraycopy(listeners, 0, newListeners, 0, oldSize);
99 newListeners[oldSize] = listener;
100 listeners = newListeners;
101 }
102 }
103
104 /**
105 * Called when the EditPartViewer is being disposed.
106 */
107 public void dispose() {
108 disposed = true;
109 }
110
111 /**
112 * Notifies listeners that painting is about to occur, passing them the damaged rectangle
113 * and the map of dirty regions.
114 * @param damage the damaged rectangle
115 * @param dirtyRegions map of dirty regions to figures
116 */
117 protected void firePainting(Rectangle damage, Map dirtyRegions) {
118 UpdateListener localListeners[] = listeners;
119 for (int i = 0; i < localListeners.length; i++)
120 localListeners[i].notifyPainting(damage, dirtyRegions);
121 }
122
123 /**
124 * Notifies listeners that validation is about to occur.
125 */
126 protected void fireValidating() {
127 UpdateListener localListeners[] = listeners;
128 for (int i = 0; i < localListeners.length; i++)
129 localListeners[i].notifyValidating();
130 }
131
132 /**
133 * @return whether this update manager has been disposed.
134 */
135 protected bool isDisposed() {
136 return disposed;
137 }
138
139 /**
140 * Forces an update to occur. Update managers will perform updates automatically, but may
141 * do so asynchronously. Calling this method forces a synchronous update.
142 */
143 public abstract void performUpdate();
144
145 void paint(GC gc) {
146 performUpdate(new Rectangle(gc.getClipping()));
147 }
148
149 /**
150 * Performs an update on the given exposed rectangle.
151 * @param exposed the exposed rectangle
152 */
153 public abstract void performUpdate(Rectangle exposed);
154
155 /**
156 * Removes one occurrence of the given UpdateListener by identity.
157 * @param listener the listener to remove
158 */
159 public void removeUpdateListener(UpdateListener listener) {
160 if (listener is null)
161 throw new IllegalArgumentException("");
162 for (int index = 0; index < listeners.length; index++)
163 if (listeners[index] is listener) {
164 int newSize = listeners.length - 1;
165 UpdateListener newListeners[] = null;
166 if (newSize !is 0) {
167 newListeners = new UpdateListener[newSize];
168 SimpleType!(UpdateListener).arraycopy(listeners, 0, newListeners, 0, index);
169 SimpleType!(UpdateListener).arraycopy(listeners, index + 1, newListeners, index, newSize - index);
170 } else {
171 newListeners = new UpdateListener[0];
172 }
173 listeners = newListeners;
174 return;
175 }
176 }
177
178 /**
179 * Sets the GraphicsSource for this update manager.
180 * @param gs the new GraphicsSource
181 */
182 public abstract void setGraphicsSource(GraphicsSource gs);
183
184 /**
185 * Sets the root figure.
186 * @param figure the new root figure
187 */
188 public abstract void setRoot(IFigure figure);
189
190 /**
191 * Performs a partial update if supported (validation only). Fires notification to
192 * listeners that validation has been performed. By default this method calls {@link
193 * #performUpdate()}. Subclasses should override this method to support validation
194 * without repainting.
195 *
196 * @since 3.2
197 */
198 public void performValidation() {
199 performUpdate();
200 }
201
202 }