1
2
3
4
5
6
7
8
9
10
11 package de.jaret.util.ui.table.renderer;
12
13 import java.util.List;
14
15 import org.eclipse.jface.viewers.ILabelProvider;
16 import org.eclipse.swt.SWT;
17 import org.eclipse.swt.graphics.Color;
18 import org.eclipse.swt.graphics.GC;
19 import org.eclipse.swt.graphics.Image;
20 import org.eclipse.swt.graphics.Point;
21 import org.eclipse.swt.graphics.Rectangle;
22 import org.eclipse.swt.printing.Printer;
23 import org.eclipse.swt.widgets.Display;
24
25 import de.jaret.util.ui.table.JaretTable;
26 import de.jaret.util.ui.table.model.IColumn;
27 import de.jaret.util.ui.table.model.IHierarchicalTableViewState;
28 import de.jaret.util.ui.table.model.IRow;
29 import de.jaret.util.ui.table.model.ITableNode;
30 import de.jaret.util.ui.table.model.StdHierarchicalTableModel;
31
32 /***
33 * A renderer for rendering the hierarchy (as a tree) of a hierarchical tree model.
34 *
35 * @author Peter Kliem
36 * @version $Id: TableHierarchyRenderer.java 1077 2010-12-17 12:03:27Z kliem $
37 */
38 public class TableHierarchyRenderer extends CellRendererBase implements IHierarchyRenderer {
39 /*** size of the plus/minus signs. */
40 protected int SIZE = 12;
41
42 protected int SIGNINSETS = 3;
43
44 protected boolean _drawTree = true;
45
46 protected int _levelWidth = 30;
47
48 protected boolean _drawIcons = false;
49
50 protected boolean _drawLabels = false;
51
52 protected boolean _drawBorder = false;
53
54 protected boolean _drawFullSelection = true;
55
56 protected ILabelProvider _labelProvider = null;
57
58 /*** type of nodemarks to draw: 0 none, 1 +/-, 2 triangles. */
59 protected int _nodeMarkType = 2;
60
61 /***
62 * Create the renderer for a printer device.
63 * @param printer printer device
64 */
65 public TableHierarchyRenderer(Printer printer) {
66 super(printer);
67 SIZE = scaleX(SIZE);
68 SIGNINSETS = scaleX(SIGNINSETS);
69 }
70
71 /***
72 * Create the renderer for use with the display.
73 */
74 public TableHierarchyRenderer() {
75 super(null);
76 }
77
78 /***
79 * {@inheritDoc}
80 */
81 public void draw(GC gc, JaretTable jaretTable, ICellStyle cellStyle, Rectangle drawingArea, IRow row,
82 IColumn column, boolean drawFocus, boolean selected, boolean printing) {
83 int offx;
84 offx = scaleX(_levelWidth);
85 ITableNode node = (ITableNode) row;
86 int level = node.getLevel();
87 boolean leaf = node.getChildren().size() == 0;
88 boolean expanded = ((IHierarchicalTableViewState) jaretTable.getTableViewState()).isExpanded(node);
89
90 int x = drawingArea.x + offx * level + SIZE / 2;
91
92 int y = drawingArea.y + (drawingArea.height - SIZE) / 2;
93
94 if (leaf && !_drawIcons) {
95 drawLeaf(gc, SIZE, x, y);
96 } else if (expanded && !leaf) {
97 if (_nodeMarkType == 1) {
98 drawMinus(gc, SIZE, x, y);
99 } else if (_nodeMarkType == 2) {
100 drawTriangleDown(gc, SIZE, x, y);
101 }
102 } else if (!leaf) {
103 if (_nodeMarkType == 1) {
104 drawPlus(gc, SIZE, x, y);
105 } else if (_nodeMarkType == 2) {
106 drawTriangleRight(gc, SIZE, x, y);
107 }
108 }
109 if (_nodeMarkType != 0) {
110 x += SIZE + 4;
111 }
112
113 if (_drawBorder) {
114 gc.drawRectangle(drawingArea);
115 }
116
117
118 Rectangle labelrect = drawingArea;
119
120 if (_labelProvider != null && (_drawIcons || _drawLabels)) {
121 int labelx = x;
122 String label = _labelProvider.getText(row);
123 labelrect = new Rectangle(x, y, 0, 0);
124 if (label != null) {
125 Point extent = gc.stringExtent(label);
126 labelrect.y = drawingArea.y+(drawingArea.height-extent.y)/2;
127
128 labelrect.width += extent.x;
129 labelrect.height = Math.max(labelrect.height, extent.y);
130 }
131
132
133 if (_drawIcons) {
134 Image img = _labelProvider.getImage(row);
135 if (img != null) {
136 if (!printing) {
137 gc.drawImage(img, x, y);
138 labelx += img.getBounds().width;
139 labelrect.width += img.getBounds().width;
140 labelrect.height = img.getBounds().height;
141 } else {
142 gc.drawImage(img, 0, 0, img.getBounds().width, img.getBounds().height, x, y, scaleX(img
143 .getBounds().width), scaleY(img.getBounds().height));
144 labelx += scaleX(img.getBounds().width);
145 labelrect.width += scaleX(img.getBounds().width);
146 labelrect.height = scaleY(img.getBounds().height);
147 }
148 }
149 }
150 if (_drawLabels) {
151 gc.drawString(label, labelx, labelrect.y);
152 }
153 }
154
155
156 if (_drawTree) {
157
158 if (printing) {
159 gc.setLineWidth(3);
160 }
161 gc.setLineStyle(SWT.LINE_DOT);
162 int midy = drawingArea.y + ((drawingArea.height - SIZE) / 2) + SIZE / 2;
163 int icoy = drawingArea.y + ((drawingArea.height - SIZE) / 2) + SIZE;
164 int icox = drawingArea.x + offx * (level) + SIZE - SIZE / 2;
165 int midx = drawingArea.x + +offx * (level) + SIZE;
166 int beginx = drawingArea.x + offx * (level - 1) + SIZE;
167 int endx = drawingArea.x + offx * (level + 1) + SIZE;
168
169
170 gc.drawLine(beginx, midy, icox, midy);
171
172
173 gc.drawLine(beginx, drawingArea.y, beginx, midy);
174
175
176 if ((!leaf && expanded)) {
177 gc.drawLine(midx, icoy, midx, drawingArea.y + drawingArea.height);
178 }
179
180 boolean hasMoreSiblings = true;
181 if (jaretTable.getTableModel() instanceof StdHierarchicalTableModel) {
182 StdHierarchicalTableModel model = (StdHierarchicalTableModel) jaretTable.getTableModel();
183 hasMoreSiblings = model.moreSiblings(node, node.getLevel());
184 }
185
186
187
188
189
190
191
192
193
194 if (jaretTable.getTableModel() instanceof StdHierarchicalTableModel) {
195 StdHierarchicalTableModel model = (StdHierarchicalTableModel) jaretTable.getTableModel();
196 for (int i = 0; i < level; i++) {
197 if (model.moreSiblings(node, i)) {
198 x = drawingArea.x + offx * i + SIZE;
199 gc.drawLine(x, drawingArea.y, x, drawingArea.y + drawingArea.height);
200 }
201 }
202 }
203
204 gc.setLineStyle(SWT.LINE_SOLID);
205 gc.setLineWidth(1);
206 }
207
208 Rectangle selectionRect = labelrect;
209 if (_drawFullSelection) {
210 selectionRect = drawingArea;
211 }
212
213 if (drawFocus) {
214 drawFocus(gc, selectionRect);
215 }
216 drawSelection(gc, selectionRect, cellStyle, selected, printing);
217
218 }
219
220 protected void drawPlus(GC gc, int size, int x, int y) {
221 gc.drawLine(x + SIGNINSETS, y + size / 2, x + size - SIGNINSETS, y + size / 2);
222 gc.drawLine(x + size / 2, y + SIGNINSETS, x + size / 2, y + size - SIGNINSETS);
223 gc.drawRectangle(x, y, size, size);
224 }
225
226 protected void drawMinus(GC gc, int size, int x, int y) {
227 gc.drawLine(x + SIGNINSETS, y + size / 2, x + size - SIGNINSETS, y + size / 2);
228 gc.drawRectangle(x, y, size, size);
229 }
230
231 protected void drawTriangleDown(GC gc, int size, int x, int y) {
232 Color bg = gc.getBackground();
233 gc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
234 int[] pArray = new int[] { x, y, x + size, y, x + size / 2, y + size - 3 };
235 gc.fillPolygon(pArray);
236 gc.setBackground(bg);
237 }
238
239 protected void drawTriangleRight(GC gc, int size, int x, int y) {
240 Color bg = gc.getBackground();
241 gc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
242 int[] pArray = new int[] { x, y, x + size - 3, y + size / 2, x, y + size };
243 gc.fillPolygon(pArray);
244 gc.setBackground(bg);
245 }
246
247 protected void drawLeaf(GC gc, int size, int x, int y) {
248 Color bg = gc.getBackground();
249 gc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
250 gc.fillOval(x + size / 2, y + size / 2, size / 2, size / 2);
251 gc.setBackground(bg);
252 }
253
254 /***
255 * {@inheritDoc}
256 */
257 public boolean contains(Rectangle drawingArea, int x, int y) {
258 return true;
259 }
260
261 /***
262 * {@inheritDoc}
263 */
264 public int getPreferredWidth() {
265 return scaleX(SIZE + 4);
266 }
267
268 /***
269 * {@inheritDoc}
270 */
271 public void dispose() {
272 if (_labelProvider != null) {
273 _labelProvider.dispose();
274 }
275 }
276
277 /***
278 * @return Returns the labelProvider.
279 */
280 public ILabelProvider getLabelProvider() {
281 return _labelProvider;
282 }
283
284 /***
285 * @param labelProvider The labelProvider to set.
286 */
287 public void setLabelProvider(ILabelProvider labelProvider) {
288 _labelProvider = labelProvider;
289 }
290
291 /***
292 * @return Returns the levelWidth.
293 */
294 public int getLevelWidth() {
295 return _levelWidth;
296 }
297
298 /***
299 * @param levelWidth The levelWidth to set.
300 */
301 public void setLevelWidth(int levelWidth) {
302 _levelWidth = levelWidth;
303 }
304
305 /***
306 * @return Returns the drawIcons.
307 */
308 public boolean getDrawIcons() {
309 return _drawIcons;
310 }
311
312 /***
313 * @param drawIcons The drawIcons to set.
314 */
315 public void setDrawIcons(boolean drawIcons) {
316 this._drawIcons = drawIcons;
317 }
318
319 /***
320 * @return Returns the drawLabels.
321 */
322 public boolean getDrawLabels() {
323 return _drawLabels;
324 }
325
326 /***
327 * @param drawLabels The drawLabels to set.
328 */
329 public void setDrawLabels(boolean drawLabels) {
330 this._drawLabels = drawLabels;
331 }
332
333 /***
334 * {@inheritDoc}
335 */
336 public ICellRenderer createPrintRenderer(Printer printer) {
337 TableHierarchyRenderer r = new TableHierarchyRenderer(printer);
338 r.setDrawIcons(_drawIcons);
339 r.setDrawLabels(_drawLabels);
340 r.setLevelWidth(_levelWidth);
341 r.setLabelProvider(_labelProvider);
342 return r;
343 }
344
345 /***
346 * {@inheritDoc}
347 */
348 public int getPreferredWidth(List<IRow> rows, IColumn column) {
349 return -1;
350 }
351
352 /***
353 * {@inheritDoc}
354 */
355 public int getPreferredHeight(IRow row, IColumn column) {
356 return -1;
357 }
358
359 /***
360 * {@inheritDoc}
361 */
362 public boolean isInActiveArea(IRow row, Rectangle drawingArea, int xx, int yy) {
363 int offx = scaleX(_levelWidth);
364 ITableNode node = (ITableNode) row;
365 int level = node.getLevel();
366 boolean leaf = node.getChildren().size() == 0;
367
368 if (leaf) {
369 return false;
370 }
371
372 int x = drawingArea.x + offx * level + SIZE / 2;
373 int y = drawingArea.y + (drawingArea.height - SIZE) / 2;
374
375 return x <= xx && xx <= x + SIZE && y <= yy && yy <= y + SIZE;
376 }
377
378 public boolean getDrawBorder() {
379 return _drawBorder;
380 }
381
382 public void setDrawBorder(boolean drawBorder) {
383 _drawBorder = drawBorder;
384 }
385
386 public boolean getDrawTree() {
387 return _drawTree;
388 }
389
390 public void setDrawTree(boolean drawTree) {
391 _drawTree = drawTree;
392 }
393
394 public boolean getDrawFullSelection() {
395 return _drawFullSelection;
396 }
397
398 public void setDrawFUllSelection(boolean drawFullSelection) {
399 _drawFullSelection = drawFullSelection;
400 }
401
402 }