1
2
3
4
5
6
7
8
9
10
11 package de.jaret.util.ui.table.renderer;
12
13 import javax.swing.BoundedRangeModel;
14 import javax.swing.DefaultBoundedRangeModel;
15
16 import org.eclipse.swt.SWT;
17 import org.eclipse.swt.graphics.Color;
18 import org.eclipse.swt.graphics.Device;
19 import org.eclipse.swt.graphics.GC;
20 import org.eclipse.swt.graphics.Path;
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.IRow;
28
29 /***
30 * Fun renderer rendering an integer as a smiley.
31 *
32 * @TODO Printing
33 *
34 * @author Peter Kliem
35 * @version $Id: SmileyCellRenderer.java 179 2007-01-07 17:37:50Z olk $
36 */
37 public class SmileyCellRenderer extends CellRendererBase implements ICellRenderer {
38 private BoundedRangeModel _brModel = new DefaultBoundedRangeModel(50, 0, 0, 100);
39 private boolean _eyeBrows = true;
40 private boolean _colorChange = true;
41 /*** if true, rendering will be alwa limited to a maximal square, forcing the smiley to be a circle. */
42 private boolean _forceCircle = true;
43
44 private Color _neutral;
45 private Color _positive;
46 private Color _negative;
47 private Color _currentColor;
48 private Color _black;
49
50 private double _currentValue;
51
52 public SmileyCellRenderer(Printer printer) {
53 super(printer);
54 if (printer != null) {
55 _neutral = printer.getSystemColor(SWT.COLOR_YELLOW);
56 _positive = printer.getSystemColor(SWT.COLOR_GREEN);
57 _negative = printer.getSystemColor(SWT.COLOR_RED);
58 _black = printer.getSystemColor(SWT.COLOR_BLACK);
59
60 }
61 }
62
63 public SmileyCellRenderer() {
64 super(null);
65 _neutral = Display.getCurrent().getSystemColor(SWT.COLOR_YELLOW);
66 _positive = Display.getCurrent().getSystemColor(SWT.COLOR_GREEN);
67 _negative = Display.getCurrent().getSystemColor(SWT.COLOR_RED);
68 _black = Display.getCurrent().getSystemColor(SWT.COLOR_BLACK);
69 }
70
71 /***
72 * {@inheritDoc}
73 */
74 public void draw(GC gc, JaretTable jaretTable, ICellStyle cellStyle, Rectangle drawingArea, IRow row,
75 IColumn column, boolean drawFocus, boolean selected, boolean printing) {
76 drawBackground(gc, drawingArea, cellStyle, selected, printing);
77 Rectangle drect = drawBorder(gc, cellStyle, drawingArea, printing);
78 Rectangle rect = applyInsets(drect);
79 Object value = column.getValue(row);
80 if (value != null) {
81 saveGCAttributes(gc);
82 int val = ((Integer) value).intValue();
83 _brModel.setValue(val);
84 calcSmileFactor();
85
86 if (_forceCircle) {
87 int a = Math.min(rect.width, rect.height);
88 Rectangle nrect = new Rectangle(0, 0, a, a);
89 nrect.x = rect.x + (rect.width - a) / 2;
90 nrect.y = rect.y + (rect.height - a) / 2;
91 rect = nrect;
92 }
93
94 int width = rect.width;
95 int height = rect.height;
96 int offx = rect.x;
97 int offy = rect.y;
98 float foffx = (float) offx;
99 float foffy = (float) offy;
100
101 int lineWidth = height / 40;
102 if (!_colorChange) {
103 gc.setBackground(_neutral);
104 } else {
105 if (_currentValue >= 0) {
106 gc.setBackground(calcColor(_positive, printing));
107 } else {
108 gc.setBackground(calcColor(_negative, printing));
109 }
110 }
111
112 Device device = printing ? _printer : Display.getCurrent();
113 Path p = new Path(device);
114 p.addArc(foffx + 0 + lineWidth / 2, foffy + 0 + lineWidth / 2, width - 1 - lineWidth, height - 1
115 - lineWidth, 0, 360);
116 gc.fillPath(p);
117 gc.setForeground(_black);
118 gc.setLineWidth(lineWidth);
119 gc.drawPath(p);
120 p.dispose();
121
122 int y = height / 3;
123 int x1 = width / 3;
124 int x2 = width - width / 3;
125 int r = width / 30;
126
127 if (r == 0) {
128 r = 1;
129 }
130 gc.setBackground(_black);
131 gc.fillOval(offx + x1 - r, offy + y - r, 2 * r, 2 * r);
132 gc.fillOval(offx + x2 - r, offy + y - r, 2 * r, 2 * r);
133
134 if (_eyeBrows) {
135 gc.setLineWidth(lineWidth / 2);
136 int ebWidth = width / 10;
137 int yDist = height / 13;
138 int yOff = (int) (_currentValue * (double) height / 30);
139 int xShift = (int) (_currentValue * (double) width / 90);
140 p = new Path(device);
141 p.moveTo(foffx + x1 - ebWidth / 2 + xShift, foffy + y - yDist + yOff);
142 p.lineTo(foffx + x1 + ebWidth / 2 - xShift, foffy + y - yDist - yOff);
143 gc.drawPath(p);
144 p.dispose();
145
146 p = new Path(device);
147 p.moveTo(foffx + x2 - ebWidth / 2 + xShift, foffy + y - yDist - yOff);
148 p.lineTo(foffx + x2 + ebWidth / 2 - xShift, foffy + y - yDist + yOff);
149 gc.drawPath(p);
150 p.dispose();
151 }
152
153 gc.setLineWidth(lineWidth);
154 x1 = (int) (width / 4.5);
155 x2 = width - x1;
156 y = height - height / 3;
157 int midX = width / 2;
158 int offset = (int) (_currentValue * (double) height / 3);
159 p = new Path(Display.getCurrent());
160 p.moveTo(foffx + x1, foffy + y);
161 p.quadTo(foffx + midX, foffy + y + offset, foffx + x2, foffy + y);
162 gc.drawPath(p);
163 p.dispose();
164 restoreGCAttributes(gc);
165 }
166 if (drawFocus) {
167 drawFocus(gc, drect);
168 }
169 drawSelection(gc, drawingArea, cellStyle, selected, printing);
170
171 }
172
173 /***
174 * Scales the BoundedRangeModel to [-1, 1]
175 */
176 private void calcSmileFactor() {
177 int range = _brModel.getMaximum() - _brModel.getMinimum();
178 int mid = _brModel.getMinimum() + range / 2;
179 int value = _brModel.getValue();
180 _currentValue = (double) (value - mid) / (double) (range / 2);
181
182 if (_currentValue > 1) {
183 _currentValue = 1;
184 } else if (_currentValue < -1) {
185 _currentValue = -1;
186 }
187 }
188
189 /***
190 * Calculates the color beetween _neutral and the specified color
191 *
192 * @param destColor
193 * @return the mixed color
194 */
195 private Color calcColor(Color destColor, boolean printing) {
196 int rDiff = destColor.getRed() - _neutral.getRed();
197 int gDiff = destColor.getGreen() - _neutral.getGreen();
198 int bDiff = destColor.getBlue() - _neutral.getBlue();
199 double factor = Math.abs(_currentValue);
200 int r = (int) ((double) rDiff * factor);
201 int g = (int) ((double) gDiff * factor);
202 int b = (int) ((double) bDiff * factor);
203
204 if (_currentColor != null) {
205 _currentColor.dispose();
206 }
207 if (!printing) {
208 _currentColor = new Color(Display.getCurrent(), _neutral.getRed() + r, _neutral.getGreen() + g, _neutral
209 .getBlue()
210 - b);
211 } else {
212 _currentColor = new Color(_printer, _neutral.getRed() + r, _neutral.getGreen() + g, _neutral.getBlue() - b);
213 }
214 return _currentColor;
215 }
216
217 /***
218 * {@inheritDoc}
219 */
220 public void dispose() {
221 if (_currentColor != null) {
222 _currentColor.dispose();
223 }
224 }
225
226 /***
227 * {@inheritDoc}
228 */
229 public ICellRenderer createPrintRenderer(Printer printer) {
230
231
232 return new TextCellRenderer(printer);
233 }
234 }