1
2
3
4
5
6
7
8
9
10
11 package de.jaret.util.ui.table.renderer;
12
13 import org.eclipse.jface.resource.ImageDescriptor;
14 import org.eclipse.jface.resource.ImageRegistry;
15 import org.eclipse.swt.SWT;
16 import org.eclipse.swt.graphics.Color;
17 import org.eclipse.swt.graphics.Font;
18 import org.eclipse.swt.graphics.FontData;
19 import org.eclipse.swt.graphics.GC;
20 import org.eclipse.swt.graphics.Image;
21 import org.eclipse.swt.graphics.ImageData;
22 import org.eclipse.swt.graphics.Point;
23 import org.eclipse.swt.graphics.RGB;
24 import org.eclipse.swt.graphics.Rectangle;
25 import org.eclipse.swt.graphics.Transform;
26 import org.eclipse.swt.printing.Printer;
27 import org.eclipse.swt.widgets.Display;
28
29 import de.jaret.util.swt.SwtGraphicsHelper;
30 import de.jaret.util.ui.table.model.IColumn;
31
32 /***
33 * Default header renderer for the jaret table. The header renderer will render a simple header view. The renderer
34 * supports rotating the header text from 0 to 90 degrees anti-clock wise. If a rotation is set, the header is drawn
35 * using a white background. Several properties allow changing the drawing (always consider writing a specialized
36 * renderer!).
37 *
38 * @author Peter Kliem
39 * @version $Id: DefaultTableHeaderRenderer.java 1077 2010-12-17 12:03:27Z kliem $
40 */
41 public class DefaultTableHeaderRenderer extends RendererBase implements ITableHeaderRenderer {
42 /*** Alignment enumeration. */
43 public enum Alignment {
44 LEFT, CENTER, RIGHT
45 };
46
47 /*** default background rgb for non rotated drawing. */
48 private static RGB DEFAULTBACKGROUND = new RGB(220, 220, 220);
49
50 /*** Alignment: default left. */
51 protected Alignment _alignment = Alignment.LEFT;
52
53 /*** true if the header box should be drawn. */
54 protected boolean _drawBox = true;
55
56 /*** background rgb value. */
57 protected RGB _backgroundRGB = DEFAULTBACKGROUND;
58 /*** allocated background color. */
59 protected Color _bgColor;
60
61 /*** FOntadat of the font to use. */
62 protected FontData _fontData;
63 /*** font when aquired. */
64 protected Font _font;
65
66 /*** rotation of the header text. */
67 protected int _rotation = 0;
68
69 /*** Transformations for rotated text. */
70 protected Transform _transform;
71 /*** inverse transformation to reset gc. */
72 protected Transform _transformInv;
73
74 protected ImageRegistry _imageRegistry;
75
76 /*** key for uowards arrow. */
77 protected static final String UP = "up";
78 /*** key for downwards arrow. */
79 protected static final String DOWN = "down";
80 /*** width reserved for the sorting area. */
81 protected static final int SORTINGAREAINDICATORWIDTH = 16;
82
83 /*** preferred height to use when more space is available. */
84 private static final int PREFHEIGHT = 20;
85
86 /***
87 * Construct a header renderer for printing.
88 *
89 * @param printer printer device
90 */
91 public DefaultTableHeaderRenderer(Printer printer) {
92 super(printer);
93 }
94
95 /***
96 * Construct header renderer for a display.
97 */
98 public DefaultTableHeaderRenderer() {
99 super(null);
100 }
101
102 /***
103 * Set the rotation of the header text. Please note that you have to call <code>redraw()</code> on the table
104 * yourself if you change the rotation while the table is showing.
105 *
106 * @param rotation rotation in degrees anti clockwise between 0 and 90 degrees.
107 */
108 public void setRotation(int rotation) {
109 if (rotation < 0 || rotation > 90) {
110 throw new IllegalArgumentException("Rotation range 0..90");
111 }
112 if (_rotation != rotation) {
113 disposeTransformations();
114 _rotation = rotation;
115 _transform = new Transform(Display.getCurrent());
116 _transformInv = new Transform(Display.getCurrent());
117 _transform.rotate(-rotation);
118 _transformInv.rotate(-rotation);
119 _transformInv.invert();
120 }
121 }
122
123 /***
124 * {@inheritDoc}
125 */
126 public void draw(GC gc, Rectangle drawingArea, IColumn column, int sortingOrder, boolean sortDir, boolean printing) {
127 Color bg = gc.getBackground();
128 Font font = gc.getFont();
129 String label = column.getHeaderLabel();
130
131 if (_fontData != null && _font == null) {
132 _font = new Font(gc.getDevice(), _fontData);
133 }
134 if (_font != null) {
135 gc.setFont(_font);
136 }
137
138 if (_rotation == 0) {
139
140
141
142 if (_bgColor == null) {
143 _bgColor = new Color(gc.getDevice(), _backgroundRGB);
144 }
145
146 gc.setBackground(_bgColor);
147
148
149
150
151
152
153
154
155 gc.fillRectangle(drawingArea);
156 if (sortingOrder > 0) {
157 Image img = getImageRegistry().get(sortDir ? DOWN : UP);
158 gc.drawImage(img, drawingArea.x + 2, drawingArea.y + drawingArea.height - img.getBounds().height - 1);
159 }
160
161 if (_drawBox) {
162 gc.drawRectangle(drawingArea.x, drawingArea.y, drawingArea.width - 1, drawingArea.height - 1);
163 } else {
164 gc.drawLine(drawingArea.x, drawingArea.y + drawingArea.height - 1, drawingArea.width - 1, drawingArea.y
165 + drawingArea.height - 1);
166 }
167
168
169 Point extent = gc.stringExtent(label);
170 int topY = drawingArea.y+(drawingArea.height-extent.y)/2;
171 int offx = column.supportsSorting() ? SORTINGAREAINDICATORWIDTH : 2;
172 if (_alignment.equals(Alignment.LEFT)) {
173 gc.drawString(label, drawingArea.x + offx, topY);
174 } else if (_alignment.equals(Alignment.CENTER)) {
175 Rectangle rect = new Rectangle(drawingArea.x + offx, topY, drawingArea.width
176 - offx, drawingArea.height - 2 * scaleY(2));
177 SwtGraphicsHelper.drawStringCentered(gc, label, rect);
178 } else if (_alignment.equals(Alignment.RIGHT)) {
179 SwtGraphicsHelper.drawStringRightAlignedVTop(gc, label, drawingArea.x + drawingArea.width,
180 topY);
181 }
182 } else {
183
184 gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE));
185 Point extent = gc.stringExtent(label);
186 float[] cords = {(float) (drawingArea.x + ((drawingArea.width - extent.x / 2) / 2)),
187 (float) (drawingArea.y + drawingArea.height - 9)};
188 _transformInv.transform(cords);
189
190 gc.setTransform(_transform);
191 gc.drawString(label, (int) cords[0], (int) cords[1]);
192 gc.setTransform(null);
193 }
194
195 gc.setFont(font);
196 gc.setBackground(bg);
197 }
198
199 /***
200 * {@inheritDoc}
201 */
202 public boolean disableClipping() {
203
204 return _rotation != 0;
205 }
206
207 /***
208 * {@inheritDoc}
209 */
210 public void dispose() {
211 disposeTransformations();
212 if (_imageRegistry != null) {
213 _imageRegistry.dispose();
214 }
215 if (_bgColor != null) {
216 _bgColor.dispose();
217 }
218 if (_font != null) {
219 _font.dispose();
220 }
221
222 }
223
224 private ImageRegistry getImageRegistry() {
225 if (_imageRegistry == null) {
226 _imageRegistry = new ImageRegistry();
227 ImageDescriptor imgDesc = new LocalResourceImageDescriptor(
228 "/de/jaret/util/ui/table/resource/smallarrow_down.gif");
229 _imageRegistry.put(DOWN, imgDesc.createImage());
230 imgDesc = new LocalResourceImageDescriptor("/de/jaret/util/ui/table/resource/smallarrow_up.gif");
231 _imageRegistry.put(UP, imgDesc.createImage());
232 }
233 return _imageRegistry;
234 }
235
236 public class LocalResourceImageDescriptor extends ImageDescriptor {
237 String rscString;
238
239 /***
240 *
241 */
242 public LocalResourceImageDescriptor(String rscString) {
243 this.rscString = rscString;
244 }
245
246 /***
247 * {@inheritDoc}
248 */
249 public ImageData getImageData() {
250 Image img = new Image(Display.getCurrent(), this.getClass().getResourceAsStream(rscString));
251 return img.getImageData();
252 }
253 }
254
255 /***
256 * Dispose the transformations.
257 *
258 */
259 private void disposeTransformations() {
260 if (_transform != null) {
261 _transform.dispose();
262 }
263 if (_transformInv != null) {
264 _transformInv.dispose();
265 }
266 }
267
268 /***
269 * {@inheritDoc}
270 */
271 public boolean isSortingClick(Rectangle drawingArea, IColumn column, int x, int y) {
272 return x - drawingArea.x < SORTINGAREAINDICATORWIDTH;
273 }
274
275 /***
276 * {@inheritDoc}
277 */
278 public ITableHeaderRenderer getPrintRenderer(Printer printer) {
279 return new DefaultTableHeaderRenderer(printer);
280 }
281
282 /***
283 * Retrieve the alignment for the header label (only when not rotated).
284 *
285 * @return the alignment
286 */
287 public Alignment getAlignment() {
288 return _alignment;
289 }
290
291 /***
292 * Set the alignment for the header label (not used when rotated).
293 *
294 * @param alignment alignment to be used
295 */
296 public void setAlignment(Alignment alignment) {
297 _alignment = alignment;
298 }
299
300 /***
301 * Retrieve whether the header is drawn boxed.
302 *
303 * @return true if a box is drawn around the header
304 */
305 public boolean getDrawBox() {
306 return _drawBox;
307 }
308
309 /***
310 * Set whether the header should be drawn boxed.
311 *
312 * @param drawBox true for boxed drawing
313 */
314 public void setDrawBox(boolean drawBox) {
315 _drawBox = drawBox;
316 }
317
318 /***
319 * Get the background RGB value of the header (non rotated only).
320 *
321 * @return the RGB value for the background
322 */
323 public RGB getBackgroundRGB() {
324 return _backgroundRGB;
325 }
326
327 /***
328 * Set the background rgb value. The color will be aquired when used. Will only be used when non rotated.
329 *
330 * @param backgroundRGB the RGB value
331 */
332 public void setBackgroundRGB(RGB backgroundRGB) {
333 if (_bgColor != null) {
334 _bgColor.dispose();
335 _bgColor = null;
336 }
337 _backgroundRGB = backgroundRGB;
338 }
339
340 /***
341 * Get the fontdata for the font used to render the header label.
342 *
343 * @return the fontdata
344 */
345 public FontData getFontData() {
346 return _fontData;
347 }
348
349 /***
350 * Set the fontdata for the font to render the header. The font will be aquired when used.
351 *
352 * @param fontData fontdat ato use
353 */
354 public void setFontData(FontData fontData) {
355 if (_font != null) {
356 _font.dispose();
357 _font = null;
358 }
359 _fontData = fontData;
360 }
361
362 }