Commit | Line | Data |
---|---|---|
73005152 | 1 | /********************************************************************** |
11252342 | 2 | * Copyright (c) 2005, 2013 IBM Corporation, Ericsson |
73005152 BH |
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 | |
abbdd66a AM |
7 | * |
8 | * Contributors: | |
c8422608 AM |
9 | * IBM - Initial API and implementation |
10 | * Bernd Hufmann - Updated for TMF | |
73005152 | 11 | **********************************************************************/ |
c8422608 | 12 | |
73005152 BH |
13 | package org.eclipse.linuxtools.tmf.ui.views.uml2sd; |
14 | ||
73005152 BH |
15 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IColor; |
16 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IFont; | |
17 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC; | |
18 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IImage; | |
19 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.impl.ColorImpl; | |
20 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref; | |
21 | import org.eclipse.swt.SWT; | |
22 | import org.eclipse.swt.graphics.Color; | |
23 | import org.eclipse.swt.graphics.Font; | |
24 | import org.eclipse.swt.graphics.FontData; | |
25 | import org.eclipse.swt.graphics.GC; | |
26 | import org.eclipse.swt.graphics.Image; | |
27 | import org.eclipse.swt.graphics.Point; | |
28 | import org.eclipse.swt.graphics.Rectangle; | |
29 | import org.eclipse.swt.widgets.Display; | |
30 | ||
31 | /** | |
df0b8ff4 BH |
32 | * <p> |
33 | * This class implements the graphical context for the sequence diagram widgets. | |
34 | * </p> | |
abbdd66a AM |
35 | * |
36 | * @version 1.0 | |
df0b8ff4 | 37 | * @author sveyrier |
73005152 BH |
38 | */ |
39 | public class NGC implements IGC { | |
40 | ||
df0b8ff4 BH |
41 | // ------------------------------------------------------------------------ |
42 | // Attributes | |
43 | // ------------------------------------------------------------------------ | |
abbdd66a | 44 | |
df0b8ff4 BH |
45 | /** |
46 | * The graphical context. | |
47 | */ | |
eb63f5ff | 48 | protected GC fContext; |
df0b8ff4 BH |
49 | /** |
50 | * The reference to the sequence diagram view. | |
51 | */ | |
eb63f5ff | 52 | protected SDWidget fView; |
df0b8ff4 BH |
53 | /** |
54 | * A reference to the last used font. | |
55 | */ | |
eb63f5ff | 56 | protected Font fTempFont = null; |
df0b8ff4 BH |
57 | /** |
58 | * The color of the gradient. | |
59 | */ | |
eb63f5ff | 60 | protected IColor fGradientColor = null; |
df0b8ff4 BH |
61 | /** |
62 | * The color of the background. | |
63 | */ | |
eb63f5ff | 64 | protected IColor fBackground = null; |
df0b8ff4 BH |
65 | /** |
66 | * The color of the foreground. | |
67 | */ | |
eb63f5ff | 68 | protected IColor fForeground = null; |
df0b8ff4 | 69 | /** |
eb63f5ff | 70 | * The current visible y screen bounds |
df0b8ff4 | 71 | */ |
eb63f5ff | 72 | protected int fVisibleY; |
df0b8ff4 | 73 | /** |
eb63f5ff | 74 | * The current visible x screen bound. |
df0b8ff4 | 75 | */ |
eb63f5ff | 76 | protected int fVisibleX; |
df0b8ff4 | 77 | /** |
abbdd66a | 78 | * The current yx value (view visible height - visible screen bounds) |
df0b8ff4 | 79 | */ |
73005152 | 80 | protected int yx; |
df0b8ff4 | 81 | /** |
abbdd66a | 82 | * The current xx value (view visible width - visible screen bounds) |
df0b8ff4 | 83 | */ |
73005152 | 84 | protected int xx; |
df0b8ff4 | 85 | /** |
abbdd66a | 86 | * <code>true</code> to draw with focus else <code>false</code>. |
df0b8ff4 | 87 | */ |
eb63f5ff | 88 | protected boolean fDrawWithFocus = false; |
73005152 | 89 | |
df0b8ff4 BH |
90 | /** |
91 | * The static visible screen bounds. | |
92 | */ | |
eb63f5ff | 93 | private static int fVisibleScreenBounds = 0; |
abbdd66a AM |
94 | |
95 | ||
df0b8ff4 BH |
96 | // ------------------------------------------------------------------------ |
97 | // Constructors | |
98 | // ------------------------------------------------------------------------ | |
99 | ||
100 | /** | |
101 | * Default constructor. | |
abbdd66a | 102 | * |
df0b8ff4 BH |
103 | * @param scrollView A sequence diagram view reference. |
104 | * @param gc A graphical context. | |
105 | */ | |
73005152 | 106 | public NGC(SDWidget scrollView, GC gc) { |
eb63f5ff BH |
107 | fContext = gc; |
108 | fView = scrollView; | |
73005152 BH |
109 | } |
110 | ||
df0b8ff4 BH |
111 | // ------------------------------------------------------------------------ |
112 | // Methods | |
113 | // ------------------------------------------------------------------------ | |
114 | ||
73005152 BH |
115 | @Override |
116 | public void setLineStyle(int style) { | |
eb63f5ff | 117 | fContext.setLineStyle(style); |
73005152 BH |
118 | } |
119 | ||
120 | @Override | |
121 | public int getLineStyle() { | |
eb63f5ff | 122 | return fContext.getLineStyle(); |
73005152 BH |
123 | } |
124 | ||
125 | @Override | |
126 | public int getContentsX() { | |
eb63f5ff | 127 | return Math.round(fView.getContentsX() / fView.fZoomValue); |
73005152 BH |
128 | } |
129 | ||
130 | @Override | |
131 | public int getContentsY() { | |
eb63f5ff | 132 | return Math.round(fView.getContentsY() / fView.fZoomValue); |
73005152 BH |
133 | } |
134 | ||
135 | @Override | |
136 | public int getVisibleWidth() { | |
eb63f5ff | 137 | return Math.round(fView.getVisibleWidth() / fView.fZoomValue); |
73005152 BH |
138 | } |
139 | ||
140 | @Override | |
141 | public int getVisibleHeight() { | |
eb63f5ff | 142 | return Math.round(fView.getVisibleHeight() / fView.fZoomValue); |
73005152 BH |
143 | } |
144 | ||
145 | @Override | |
146 | public int contentsToViewX(int x) { | |
eb63f5ff | 147 | return fView.contentsToViewX(x); |
73005152 BH |
148 | } |
149 | ||
150 | @Override | |
151 | public int contentsToViewY(int y) { | |
eb63f5ff | 152 | return fView.contentsToViewY(y); |
73005152 BH |
153 | } |
154 | ||
df0b8ff4 BH |
155 | /** |
156 | * Get code for drawings at given x and y position. | |
abbdd66a | 157 | * |
df0b8ff4 BH |
158 | * @param x The x position |
159 | * @param y The y position. | |
160 | * @return A code for top, bottom, right and left | |
161 | */ | |
73005152 BH |
162 | protected byte code(int x, int y) { |
163 | byte c = 0; | |
eb63f5ff BH |
164 | fVisibleY = fVisibleScreenBounds; |
165 | fVisibleX = fVisibleScreenBounds; | |
166 | yx = fView.getVisibleHeight() + fVisibleScreenBounds; | |
167 | xx = fView.getVisibleWidth() + fVisibleScreenBounds; | |
df0b8ff4 | 168 | if (y > yx) { |
73005152 | 169 | c |= 0x01; // top |
eb63f5ff | 170 | } else if (y < fVisibleY) { |
73005152 | 171 | c |= 0x02; // bottom |
df0b8ff4 | 172 | } |
abbdd66a | 173 | |
df0b8ff4 | 174 | if (x > xx) { |
73005152 | 175 | c |= 0x04; // right |
eb63f5ff | 176 | } else if (x < fVisibleX) { |
73005152 | 177 | c |= 0x08; // left |
df0b8ff4 | 178 | } |
73005152 BH |
179 | return c; |
180 | } | |
181 | ||
182 | @Override | |
183 | public void drawLine(int x1, int y1, int x2, int y2) { | |
abbdd66a AM |
184 | int localX1 = x1; |
185 | int localY1 = y1; | |
eb63f5ff BH |
186 | int localX2 = x2; |
187 | int localY2 = y2; | |
abbdd66a | 188 | |
eb63f5ff BH |
189 | localX1 = Math.round(localX1 * fView.fZoomValue); |
190 | localY1 = Math.round(localY1 * fView.fZoomValue); | |
191 | localX2 = Math.round(localX2 * fView.fZoomValue); | |
192 | localY2 = Math.round(localY2 * fView.fZoomValue); | |
193 | localX1 = fView.contentsToViewX(localX1); | |
194 | localY1 = fView.contentsToViewY(localY1); | |
195 | localX2 = fView.contentsToViewX(localX2); | |
196 | localY2 = fView.contentsToViewY(localY2); | |
197 | ||
198 | byte code1 = code(localX1, localY1); | |
199 | byte code2 = code(localX2, localY2); | |
73005152 BH |
200 | byte codex; |
201 | boolean draw = false; | |
202 | boolean end = false; | |
203 | int x = 0, y = 0; | |
204 | ||
205 | do { | |
206 | if (code1 == 0 && code2 == 0) { | |
207 | draw = true; | |
208 | end = true; | |
209 | } else if ((code1 & code2) != 0) { | |
210 | end = true; | |
211 | } else { | |
212 | codex = (code1 != 0) ? code1 : code2; | |
df0b8ff4 | 213 | if ((codex & 0x01) != 0) { // top |
eb63f5ff | 214 | x = localX1 + ((localX2 - localX1) * (yx - localY1)) / (localY2 - localY1); |
73005152 | 215 | y = yx; |
df0b8ff4 | 216 | } else if ((codex & 0x02) != 0) { // bottom |
eb63f5ff BH |
217 | x = localX1 + ((localX2 - localX1) * (fVisibleY - localY1)) / (localY2 - localY1); |
218 | y = fVisibleY; | |
df0b8ff4 | 219 | } else if ((codex & 0x04) != 0) { // right |
eb63f5ff | 220 | y = localY1 + ((localY2 - localY1) * (xx - localX1)) / (localX2 - localX1); |
73005152 | 221 | x = xx; |
df0b8ff4 | 222 | } else if ((codex & 0x08) != 0) { // left |
eb63f5ff BH |
223 | y = localY1 + ((localY2 - localY1) * (fVisibleX - localX1)) / (localX2 - localX1); |
224 | x = fVisibleX; | |
73005152 BH |
225 | } |
226 | ||
227 | if (codex == code1) { | |
eb63f5ff BH |
228 | localX1 = x; |
229 | localY1 = y; | |
230 | code1 = code(localX1, localY1); | |
73005152 | 231 | } else { |
eb63f5ff BH |
232 | localX2 = x; |
233 | localY2 = y; | |
234 | code2 = code(localX2, localY2); | |
73005152 BH |
235 | } |
236 | } | |
237 | } while (!end); | |
df0b8ff4 | 238 | |
73005152 | 239 | if (draw) { |
eb63f5ff | 240 | fContext.drawLine(localX1, localY1, localX2, localY2); |
73005152 BH |
241 | } |
242 | } | |
243 | ||
244 | @Override | |
245 | public void drawRectangle(int x, int y, int width, int height) { | |
eb63f5ff BH |
246 | int localX = x; |
247 | int localY = y; | |
248 | int localWidth = width; | |
249 | int localHeight = height; | |
abbdd66a | 250 | |
eb63f5ff | 251 | localX = Math.round(localX * fView.fZoomValue); |
73005152 | 252 | // Workaround to avoid problems for some special cases (not very nice) |
eb63f5ff BH |
253 | if (localY != getContentsY()) { |
254 | localY = Math.round(localY * fView.fZoomValue); | |
255 | localY = fView.contentsToViewY(localY); | |
256 | } else { | |
257 | localY = 0; | |
258 | } | |
259 | localWidth = Math.round(localWidth * fView.fZoomValue); | |
260 | localHeight = Math.round(localHeight * fView.fZoomValue); | |
261 | localX = fView.contentsToViewX(localX); | |
262 | ||
263 | if (localX < -fVisibleScreenBounds) { | |
264 | localWidth = localWidth + localX + fVisibleScreenBounds; | |
265 | localX = -fVisibleScreenBounds; | |
266 | } | |
267 | if (localY < -fVisibleScreenBounds) { | |
268 | localHeight = localHeight + localY + fVisibleScreenBounds; | |
269 | localY = -fVisibleScreenBounds; | |
270 | } | |
271 | if ((localWidth < -fVisibleScreenBounds) && (localX + localWidth < -fVisibleScreenBounds)) { | |
272 | localWidth = -fVisibleScreenBounds; | |
273 | } else if (localWidth + localX > fView.getVisibleWidth() + fVisibleScreenBounds) { | |
274 | localWidth = fView.getVisibleWidth() + fVisibleScreenBounds - localX; | |
275 | } | |
276 | if ((localHeight < -fVisibleScreenBounds) && (localY + localHeight < -fVisibleScreenBounds)) { | |
277 | localHeight = -fVisibleScreenBounds; | |
278 | } else if (localHeight + localY > fView.getVisibleHeight() + fVisibleScreenBounds) { | |
279 | localHeight = fView.getVisibleHeight() + fVisibleScreenBounds - localY; | |
280 | } | |
281 | fContext.drawRectangle(localX, localY, localWidth, localHeight); | |
73005152 | 282 | } |
abbdd66a | 283 | |
73005152 BH |
284 | @Override |
285 | public void drawFocus(int x, int y, int width, int height) { | |
eb63f5ff BH |
286 | int localX = x; |
287 | int localY = y; | |
288 | int localWidth = width; | |
289 | int localHeight = height; | |
290 | ||
73005152 BH |
291 | IColor bC = getBackground(); |
292 | IColor fC = getForeground(); | |
293 | ||
eb63f5ff BH |
294 | if (localWidth < 0) { |
295 | localX = localX + localWidth; | |
296 | localWidth = -localWidth; | |
73005152 BH |
297 | } |
298 | ||
eb63f5ff BH |
299 | if (localHeight < 0) { |
300 | localY = localY + localHeight; | |
301 | localHeight = -localHeight; | |
73005152 BH |
302 | } |
303 | ||
eb63f5ff BH |
304 | localX = Math.round(localX * fView.fZoomValue); |
305 | localY = Math.round(localY * fView.fZoomValue); | |
306 | localWidth = Math.round(localWidth * fView.fZoomValue); | |
307 | localHeight = Math.round(localHeight * fView.fZoomValue); | |
73005152 | 308 | |
3145ec83 BH |
309 | setForeground(SDViewPref.getInstance().getForeGroundColorSelection()); |
310 | setBackground(SDViewPref.getInstance().getBackGroundColorSelection()); | |
73005152 | 311 | |
eb63f5ff | 312 | fContext.drawFocus(fView.contentsToViewX(localX - 1), fView.contentsToViewY(localY - 1), localWidth + 3, localHeight + 3); |
73005152 BH |
313 | |
314 | setBackground(bC); | |
315 | setForeground(fC); | |
316 | } | |
317 | ||
318 | @Override | |
319 | public void fillPolygon(int[] points) { | |
320 | int len = (points.length / 2) * 2; | |
321 | int[] localPoint = new int[len]; | |
322 | for (int i = 0; i < len; i++) { | |
eb63f5ff | 323 | localPoint[i] = fView.contentsToViewX(Math.round(points[i] * fView.fZoomValue)); |
73005152 | 324 | i++; |
eb63f5ff | 325 | localPoint[i] = fView.contentsToViewY(Math.round(points[i] * fView.fZoomValue)); |
73005152 | 326 | } |
abbdd66a AM |
327 | |
328 | if (validatePolygonHeight(localPoint) <= 0) { | |
73005152 | 329 | return; |
abbdd66a AM |
330 | } |
331 | ||
eb63f5ff | 332 | fContext.fillPolygon(localPoint); |
73005152 BH |
333 | } |
334 | ||
335 | @Override | |
336 | public void drawPolygon(int[] points) { | |
337 | int len = (points.length / 2) * 2; | |
338 | int[] localPoint = new int[len]; | |
339 | for (int i = 0; i < len; i++) { | |
eb63f5ff | 340 | localPoint[i] = fView.contentsToViewX(Math.round(points[i] * fView.fZoomValue)); |
73005152 | 341 | i++; |
eb63f5ff | 342 | localPoint[i] = fView.contentsToViewY(Math.round(points[i] * fView.fZoomValue)); |
73005152 | 343 | } |
abbdd66a | 344 | |
df0b8ff4 | 345 | if (validatePolygonHeight(localPoint) <= 0) { |
73005152 | 346 | return; |
df0b8ff4 | 347 | } |
73005152 | 348 | |
eb63f5ff | 349 | fContext.drawPolygon(localPoint); |
73005152 BH |
350 | } |
351 | ||
73005152 BH |
352 | @Override |
353 | public void fillRectangle(int x, int y, int width, int height) { | |
eb63f5ff BH |
354 | int localX = x; |
355 | int localY = y; | |
356 | int localWidth = width; | |
357 | int localHeight = height; | |
358 | ||
359 | localX = Math.round(localX * fView.fZoomValue); | |
73005152 | 360 | // Workaround to avoid problems for some special cases (not very nice) |
eb63f5ff BH |
361 | if (localY != getContentsY()) { |
362 | localY = Math.round(localY * fView.fZoomValue); | |
363 | localY = fView.contentsToViewY(localY) + 1; | |
df0b8ff4 | 364 | } else { |
eb63f5ff | 365 | localY = 1; |
df0b8ff4 | 366 | } |
eb63f5ff BH |
367 | localWidth = Math.round(localWidth * fView.fZoomValue) - 1; |
368 | localHeight = Math.round(localHeight * fView.fZoomValue) - 1; | |
369 | localX = fView.contentsToViewX(localX) + 1; | |
370 | if (localX < -fVisibleScreenBounds) { | |
371 | localWidth = localWidth + localX + fVisibleScreenBounds; | |
372 | localX = -fVisibleScreenBounds; | |
73005152 | 373 | } |
eb63f5ff BH |
374 | if (localY < -fVisibleScreenBounds) { |
375 | localHeight = localHeight + localY + fVisibleScreenBounds; | |
376 | localY = -fVisibleScreenBounds; | |
73005152 | 377 | } |
eb63f5ff BH |
378 | if ((localWidth < -fVisibleScreenBounds) && (localX + localWidth < -fVisibleScreenBounds)) { |
379 | localWidth = -fVisibleScreenBounds; | |
380 | } else if (localWidth + localX > fView.getVisibleWidth() + fVisibleScreenBounds) { | |
381 | localWidth = fView.getVisibleWidth() + fVisibleScreenBounds - localX; | |
df0b8ff4 | 382 | } |
eb63f5ff BH |
383 | if ((localHeight < -fVisibleScreenBounds) && (localY + localHeight < -fVisibleScreenBounds)) { |
384 | localHeight = -fVisibleScreenBounds; | |
385 | } else if (localHeight + localY > fView.getVisibleHeight() + fVisibleScreenBounds) { | |
386 | localHeight = fView.getVisibleHeight() + fVisibleScreenBounds - localY; | |
df0b8ff4 | 387 | } |
eb63f5ff | 388 | fContext.fillRectangle(localX, localY, localWidth, localHeight); |
73005152 BH |
389 | } |
390 | ||
391 | @Override | |
eb63f5ff BH |
392 | public void fillGradientRectangle(int x, int y, int width, int height, boolean isVertical) { |
393 | int localX = x; | |
394 | int localY = y; | |
395 | int localWidth = width; | |
396 | int localHeight = height; | |
abbdd66a | 397 | |
eb63f5ff BH |
398 | localX = Math.round(localX * fView.fZoomValue); |
399 | localY = Math.round(localY * fView.fZoomValue); | |
400 | localWidth = Math.round(localWidth * fView.fZoomValue); | |
401 | localHeight = Math.round(localHeight * fView.fZoomValue); | |
402 | IColor tempColor = fForeground; | |
403 | setForeground(fGradientColor); | |
404 | localX = fView.contentsToViewX(localX); | |
405 | localY = fView.contentsToViewY(localY); | |
73005152 | 406 | |
eb63f5ff BH |
407 | if (localX < -fVisibleScreenBounds) { |
408 | localWidth = localWidth + localX + fVisibleScreenBounds; | |
409 | localX = -fVisibleScreenBounds; | |
73005152 | 410 | } |
eb63f5ff BH |
411 | if (localY < -fVisibleScreenBounds) { |
412 | localHeight = localHeight + localY + fVisibleScreenBounds; | |
413 | localY = -fVisibleScreenBounds; | |
73005152 | 414 | } |
df0b8ff4 | 415 | |
eb63f5ff BH |
416 | if ((localWidth < -fVisibleScreenBounds) && (localX + localWidth < -fVisibleScreenBounds)) { |
417 | localWidth = -fVisibleScreenBounds; | |
418 | } else if (localWidth + localX > fView.getVisibleWidth() + fVisibleScreenBounds) { | |
419 | localWidth = fView.getVisibleWidth() + fVisibleScreenBounds - localX; | |
df0b8ff4 | 420 | } |
eb63f5ff BH |
421 | if ((localHeight < -fVisibleScreenBounds) && (localY + localHeight < -fVisibleScreenBounds)) { |
422 | localHeight = -fVisibleScreenBounds; | |
423 | } else if (localHeight + localY > fView.getVisibleHeight() + fVisibleScreenBounds) { | |
424 | localHeight = fView.getVisibleHeight() + fVisibleScreenBounds - localY; | |
df0b8ff4 | 425 | } |
eb63f5ff BH |
426 | if (isVertical) { |
427 | fContext.fillGradientRectangle(localX, localY, localWidth, localHeight, isVertical); | |
73005152 BH |
428 | } |
429 | else { | |
eb63f5ff | 430 | fContext.fillGradientRectangle(localX + localWidth, localY, -localWidth, localHeight + 1, isVertical); |
73005152 BH |
431 | } |
432 | setForeground(tempColor); | |
433 | } | |
434 | ||
73005152 BH |
435 | @Override |
436 | public int textExtent(String name) { | |
abbdd66a | 437 | return fContext.textExtent(name).x; |
73005152 BH |
438 | } |
439 | ||
440 | @Override | |
eb63f5ff BH |
441 | public void drawText(String string, int x, int y, boolean isTrans) { |
442 | int localX = x; | |
443 | int localY = y; | |
abbdd66a | 444 | |
eb63f5ff BH |
445 | localX = Math.round(localX * fView.fZoomValue); |
446 | localY = Math.round(localY * fView.fZoomValue); | |
447 | fContext.drawText(string, fView.contentsToViewX(localX), fView.contentsToViewY(localY), isTrans); | |
448 | if (fDrawWithFocus) { | |
449 | Point r = fContext.textExtent(string); | |
450 | fContext.drawFocus(localX - 1, localY - 1, r.x + 2, r.y + 2); | |
73005152 BH |
451 | } |
452 | } | |
453 | ||
454 | @Override | |
455 | public void drawText(String string, int x, int y) { | |
eb63f5ff BH |
456 | int localX = x; |
457 | int localY = y; | |
458 | ||
459 | localX = Math.round(localX * fView.fZoomValue); | |
460 | localY = Math.round(localY * fView.fZoomValue); | |
461 | fContext.drawText(string, fView.contentsToViewX(localX), fView.contentsToViewY(localY), true); | |
462 | if (fDrawWithFocus) { | |
463 | Point r = fContext.textExtent(string); | |
464 | fContext.drawFocus(localX - 1, localY - 1, r.x + 2, r.y + 2); | |
73005152 BH |
465 | } |
466 | } | |
467 | ||
468 | @Override | |
469 | public void fillOval(int x, int y, int width, int height) { | |
eb63f5ff BH |
470 | int localX = x; |
471 | int localY = y; | |
472 | int localWidth = width; | |
473 | int localHeight = height; | |
abbdd66a | 474 | |
eb63f5ff BH |
475 | localX = Math.round(localX * fView.fZoomValue); |
476 | localY = Math.round(localY * fView.fZoomValue); | |
477 | localWidth = Math.round(localWidth * fView.fZoomValue); | |
478 | localHeight = Math.round(localHeight * fView.fZoomValue); | |
479 | fContext.fillOval(fView.contentsToViewX(localX), fView.contentsToViewY(localY), localWidth, localHeight); | |
73005152 BH |
480 | } |
481 | ||
482 | @Override | |
483 | public IColor getBackground() { | |
eb63f5ff BH |
484 | if ((fBackground != null) && (fBackground.getColor() instanceof Color) && (!((Color) (fBackground.getColor())).isDisposed())) { |
485 | return fBackground; | |
df0b8ff4 | 486 | } |
73005152 BH |
487 | return ColorImpl.getSystemColor(SWT.COLOR_WHITE); |
488 | } | |
489 | ||
490 | @Override | |
491 | public IColor getForeground() { | |
eb63f5ff BH |
492 | if ((fForeground != null) && (fForeground.getColor() instanceof Color) && (!((Color) (fForeground.getColor())).isDisposed())) { |
493 | return fForeground; | |
df0b8ff4 | 494 | } |
73005152 BH |
495 | return ColorImpl.getSystemColor(SWT.COLOR_WHITE); |
496 | } | |
497 | ||
498 | @Override | |
499 | public void setBackground(IColor color) { | |
df0b8ff4 | 500 | if (color == null) { |
73005152 | 501 | return; |
df0b8ff4 | 502 | } |
73005152 | 503 | if (color.getColor() instanceof Color) { |
eb63f5ff BH |
504 | fContext.setBackground((Color) color.getColor()); |
505 | fBackground = color; | |
73005152 BH |
506 | } |
507 | } | |
508 | ||
509 | @Override | |
510 | public void setForeground(IColor color) { | |
df0b8ff4 | 511 | if (color == null) { |
73005152 | 512 | return; |
df0b8ff4 | 513 | } |
73005152 BH |
514 | if (color.getColor() instanceof Color) { |
515 | Color c = (Color) color.getColor(); | |
516 | if (!c.isDisposed()) { | |
eb63f5ff BH |
517 | fContext.setForeground(c); |
518 | fForeground = color; | |
73005152 BH |
519 | } |
520 | } | |
521 | } | |
522 | ||
523 | @Override | |
524 | public void setGradientColor(IColor color) { | |
df0b8ff4 | 525 | if (color == null) { |
73005152 | 526 | return; |
df0b8ff4 BH |
527 | } |
528 | if (color.getColor() instanceof Color) { | |
eb63f5ff | 529 | fGradientColor = color; |
df0b8ff4 | 530 | } |
73005152 BH |
531 | } |
532 | ||
533 | @Override | |
534 | public void setLineWidth(int width) { | |
eb63f5ff BH |
535 | if (fView.isPrinting()) { |
536 | fContext.setLineWidth(width * 2); | |
df0b8ff4 BH |
537 | } |
538 | else { | |
eb63f5ff | 539 | fContext.setLineWidth(width); |
df0b8ff4 | 540 | } |
73005152 BH |
541 | } |
542 | ||
543 | @Override | |
544 | public int getLineWidth() { | |
eb63f5ff | 545 | return fContext.getLineWidth(); |
73005152 BH |
546 | } |
547 | ||
df0b8ff4 BH |
548 | /** |
549 | * Method to draw a text in rectangle. (Linux GTK Workaround) | |
abbdd66a | 550 | * |
df0b8ff4 BH |
551 | * @param string The text to draw. |
552 | * @param x The x position. | |
553 | * @param y The y position. | |
554 | * @param isTransparent true for transparent else false | |
555 | */ | |
556 | protected void localDrawText(String string, int x, int y, boolean isTransparent) { | |
eb63f5ff | 557 | Point r = fContext.textExtent(string); |
df0b8ff4 | 558 | if (!isTransparent) { |
eb63f5ff | 559 | fContext.fillRectangle(x, y, r.x, r.y); |
df0b8ff4 | 560 | } |
eb63f5ff BH |
561 | fContext.drawText(string, x, y, isTransparent); |
562 | if ((fDrawWithFocus) && (string.length() > 1)) { | |
563 | fContext.drawFocus(x - 1, y - 1, r.x + 2, r.y + 2); | |
df0b8ff4 | 564 | } |
73005152 BH |
565 | } |
566 | ||
567 | @Override | |
eb63f5ff | 568 | public void drawTextTruncatedCentred(String name, int xValue, int yValue, int width, int height, boolean trans) { |
3145ec83 BH |
569 | int localX = xValue; |
570 | int localY = yValue; | |
571 | int localWidth = width; | |
572 | int localHeight = height; | |
573 | ||
eb63f5ff | 574 | Point tx = fContext.textExtent(name); |
3145ec83 | 575 | localX = Math.round(localX * fView.fZoomValue); |
73005152 BH |
576 | int y = 0; |
577 | // Workaround to avoid round problems for some special cases (not very nice) | |
3145ec83 BH |
578 | if (localY != getContentsY()) { |
579 | localY = Math.round(localY * fView.fZoomValue); | |
580 | y = fView.contentsToViewY(localY); | |
581 | } | |
582 | localWidth = Math.round(localWidth * fView.fZoomValue); | |
583 | localHeight = Math.round(localHeight * fView.fZoomValue); | |
584 | int x = fView.contentsToViewX(localX); | |
585 | if (tx.y > localHeight) { | |
73005152 | 586 | return; |
df0b8ff4 | 587 | } |
abbdd66a | 588 | |
73005152 | 589 | // Adjust height and y |
eb63f5ff | 590 | if (y < -fVisibleScreenBounds) { |
3145ec83 | 591 | localHeight = localHeight + y + fVisibleScreenBounds; |
eb63f5ff | 592 | y = -fVisibleScreenBounds; |
73005152 | 593 | } |
3145ec83 BH |
594 | if ((localHeight < -fVisibleScreenBounds) && (y + localHeight < -fVisibleScreenBounds)) { |
595 | localHeight = -fVisibleScreenBounds; | |
596 | } else if (localHeight + y > fView.getVisibleHeight() + fVisibleScreenBounds) { | |
597 | localHeight = fView.getVisibleHeight() + fVisibleScreenBounds - y; | |
df0b8ff4 | 598 | } |
abbdd66a | 599 | |
3145ec83 BH |
600 | if (tx.x <= localWidth) { |
601 | localDrawText(name, x + 1 + (localWidth - tx.x) / 2, y + 1 + (localHeight - tx.y) / 2, trans); | |
73005152 BH |
602 | } else { |
603 | String nameToDisplay = name; | |
3145ec83 | 604 | for (int i = name.length() - 1; i >= 0 && fContext.textExtent(nameToDisplay).x >= localWidth; i--) { |
73005152 | 605 | nameToDisplay = name.substring(0, i); |
df0b8ff4 | 606 | } |
73005152 | 607 | int dotCount = 0; |
df0b8ff4 | 608 | for (int i = 1; i <= 3 && nameToDisplay.length() - i > 0; i++) { |
73005152 | 609 | dotCount++; |
df0b8ff4 | 610 | } |
73005152 BH |
611 | nameToDisplay = nameToDisplay.substring(0, nameToDisplay.length() - dotCount); |
612 | StringBuffer buf = new StringBuffer(nameToDisplay); | |
613 | for (int i = 0; i < dotCount; i++) { | |
614 | buf.append("."); //$NON-NLS-1$ | |
73005152 BH |
615 | } |
616 | nameToDisplay = buf.toString(); | |
3145ec83 | 617 | localDrawText(nameToDisplay, x + 1 + (localWidth - fContext.textExtent(nameToDisplay).x) / 2, y + 1 + (localHeight - fContext.textExtent(nameToDisplay).y) / 2, trans); |
73005152 BH |
618 | } |
619 | } | |
620 | ||
621 | @Override | |
eb63f5ff BH |
622 | public void drawTextTruncated(String name, int xValue, int yValue, int width, int height, boolean trans) { |
623 | int localX = xValue; | |
624 | int localY = yValue; | |
625 | int localWidth = width; | |
626 | int localHeight = height; | |
abbdd66a | 627 | |
eb63f5ff BH |
628 | localX = Math.round(localX * fView.fZoomValue); |
629 | localY = Math.round(localY * fView.fZoomValue); | |
630 | localWidth = Math.round(localWidth * fView.fZoomValue); | |
631 | localHeight = Math.round(localHeight * fView.fZoomValue); | |
632 | int x = fView.contentsToViewX(localX); | |
633 | int y = fView.contentsToViewY(localY); | |
634 | if (fContext.textExtent(name).x <= localWidth) { | |
635 | localDrawText(name, x + 1, y + 1 + localHeight, trans); | |
73005152 BH |
636 | } else { |
637 | String nameToDisplay = name; | |
eb63f5ff | 638 | for (int i = name.length() - 1; i >= 0 && fContext.textExtent(nameToDisplay).x >= localWidth; i--) { |
73005152 | 639 | nameToDisplay = name.substring(0, i); |
df0b8ff4 | 640 | } |
73005152 | 641 | int dotCount = 0; |
eb63f5ff | 642 | for (int i = 1; i <= 3 && nameToDisplay.length() - i > 0; i++) { |
73005152 | 643 | dotCount++; |
eb63f5ff | 644 | } |
73005152 BH |
645 | nameToDisplay = nameToDisplay.substring(0, nameToDisplay.length() - dotCount); |
646 | ||
647 | StringBuffer buf = new StringBuffer(nameToDisplay); | |
648 | ||
649 | for (int i = 0; i < dotCount; i++) { | |
650 | buf.append("."); //$NON-NLS-1$ | |
73005152 BH |
651 | } |
652 | nameToDisplay = buf.toString(); | |
eb63f5ff | 653 | localDrawText(nameToDisplay, x + 1, y + 1 + localHeight, trans); |
73005152 BH |
654 | } |
655 | } | |
656 | ||
657 | @Override | |
eb63f5ff BH |
658 | public void drawImage(IImage image, int xValue, int yValue, int maxWith, int maxHeight) { |
659 | int localX = xValue; | |
660 | int localY = yValue; | |
abbdd66a | 661 | |
73005152 | 662 | Image img = null; |
eb63f5ff | 663 | if (image != null && image.getImage() instanceof Image) { |
73005152 | 664 | img = (Image) image.getImage(); |
eb63f5ff BH |
665 | } else { |
666 | localX = Math.round(localX * fView.fZoomValue); | |
667 | localY = Math.round(localY * fView.fZoomValue); | |
668 | int x = fView.contentsToViewX(localX); | |
669 | int y = fView.contentsToViewY(localY); | |
670 | float tempZoom = fView.fZoomValue; | |
73005152 BH |
671 | int width = Math.round(maxWith * tempZoom); |
672 | int height = Math.round(maxHeight * tempZoom); | |
eb63f5ff BH |
673 | fContext.setBackground(fView.getDisplay().getSystemColor(SWT.COLOR_RED)); |
674 | fContext.fillRectangle(x, y, width, height); | |
73005152 BH |
675 | return; |
676 | } | |
eb63f5ff BH |
677 | localX = Math.round(localX * fView.fZoomValue); |
678 | localY = Math.round(localY * fView.fZoomValue); | |
679 | int x = fView.contentsToViewX(localX); | |
680 | int y = fView.contentsToViewY(localY); | |
73005152 BH |
681 | Rectangle b = ((Image) image.getImage()).getBounds(); |
682 | int width = b.width; | |
683 | int height = b.height; | |
df0b8ff4 | 684 | if (width > maxWith) { |
73005152 | 685 | width = maxWith; |
df0b8ff4 BH |
686 | } |
687 | if (height > maxHeight) { | |
73005152 | 688 | height = maxHeight; |
df0b8ff4 | 689 | } |
eb63f5ff | 690 | float tempZoom = fView.fZoomValue; |
73005152 BH |
691 | width = Math.round(width * tempZoom); |
692 | height = Math.round(height * tempZoom); | |
693 | ||
eb63f5ff BH |
694 | if (fView.fIsPrinting && width > 0 && height > 0) { |
695 | Image dbuffer = new Image(fView.getDisplay(), width, height); | |
73005152 BH |
696 | GC tempgc = new GC(dbuffer); |
697 | tempgc.drawImage(img, 0, 0, b.width, b.height, 0, 0, width, height); | |
eb63f5ff BH |
698 | Image dbuffer2 = new Image(fView.getDisplay(), dbuffer.getImageData()); |
699 | fContext.drawImage(dbuffer2, x, y); | |
73005152 BH |
700 | tempgc.dispose(); |
701 | dbuffer.dispose(); | |
702 | dbuffer2.dispose(); | |
703 | } else { | |
eb63f5ff | 704 | fContext.drawImage(img, 0, 0, b.width, b.height, x, y, width, height); |
73005152 BH |
705 | } |
706 | } | |
707 | ||
708 | @Override | |
709 | public void drawArc(int x, int y, int width, int height, int startAngle, int endAngle) { | |
3145ec83 BH |
710 | int localX = x; |
711 | int localY = y; | |
712 | int localWidth = width; | |
713 | int localHeight = height; | |
714 | ||
715 | localX = Math.round(localX * fView.fZoomValue); | |
716 | localY = Math.round(localY * fView.fZoomValue); | |
717 | localWidth = Math.round(localWidth * fView.fZoomValue); | |
718 | localHeight = Math.round(localHeight * fView.fZoomValue); | |
719 | if (localWidth == 0 || localHeight == 0 || endAngle == 0) { | |
73005152 | 720 | return; |
df0b8ff4 | 721 | } |
3145ec83 | 722 | fContext.drawArc(fView.contentsToViewX(localX), fView.contentsToViewY(localY), localWidth, localHeight, startAngle, endAngle); |
73005152 BH |
723 | } |
724 | ||
725 | @Override | |
726 | public void setFont(IFont font) { | |
727 | if (font.getFont() != null && ((Font) font.getFont()).getFontData().length > 0) { | |
728 | FontData fontData = ((Font) font.getFont()).getFontData()[0]; | |
eb63f5ff BH |
729 | if (SDViewPref.getInstance().fontLinked() || fView.fIsPrinting) { |
730 | int h = Math.round(fontData.getHeight() * fView.fZoomValue); | |
df0b8ff4 | 731 | if (h > 0) { |
73005152 | 732 | fontData.setHeight(h); |
df0b8ff4 | 733 | } |
73005152 | 734 | } |
eb63f5ff BH |
735 | if (fTempFont != null) { |
736 | fTempFont.dispose(); | |
df0b8ff4 | 737 | } |
eb63f5ff BH |
738 | fTempFont = new Font(Display.getCurrent(), fontData); |
739 | fContext.setFont(fTempFont); | |
73005152 BH |
740 | } |
741 | } | |
742 | ||
743 | @Override | |
744 | public int getFontHeight(IFont font) { | |
745 | if (font.getFont() != null && (font.getFont() instanceof Font) && ((Font) font.getFont()).getFontData().length > 0) { | |
eb63f5ff BH |
746 | Font toRestore = fContext.getFont(); |
747 | fContext.setFont((Font) font.getFont()); | |
748 | int height = fContext.textExtent("lp").y;//$NON-NLS-1$ | |
749 | fContext.setFont(toRestore); | |
73005152 BH |
750 | return height; |
751 | } | |
752 | return 0; | |
753 | } | |
754 | ||
df0b8ff4 BH |
755 | /** |
756 | * Returns the current font height. | |
abbdd66a | 757 | * |
df0b8ff4 BH |
758 | * @return the current font height. |
759 | */ | |
73005152 | 760 | protected int getCurrentFontHeight() { |
eb63f5ff | 761 | return fContext.textExtent("lp").y; //$NON-NLS-1$ |
73005152 BH |
762 | } |
763 | ||
764 | @Override | |
765 | public int getFontWidth(IFont font) { | |
766 | if ((font.getFont() != null) && (font.getFont() instanceof Font)) { | |
eb63f5ff BH |
767 | Font toRestore = fContext.getFont(); |
768 | fContext.setFont((Font) font.getFont()); | |
769 | int width = fContext.getFontMetrics().getAverageCharWidth(); | |
770 | fContext.setFont(toRestore); | |
73005152 BH |
771 | return width; |
772 | } | |
773 | return 0; | |
774 | } | |
775 | ||
df0b8ff4 BH |
776 | /** |
777 | * Disposes all created resources. | |
778 | */ | |
73005152 | 779 | public void dispose() { |
eb63f5ff BH |
780 | if (fTempFont != null) { |
781 | fTempFont.dispose(); | |
df0b8ff4 | 782 | } |
eb63f5ff BH |
783 | fTempFont = null; |
784 | if (fContext != null) { | |
785 | fContext.dispose(); | |
df0b8ff4 | 786 | } |
eb63f5ff | 787 | fContext = null; |
73005152 BH |
788 | } |
789 | ||
790 | @Override | |
791 | public float getZoom() { | |
eb63f5ff BH |
792 | if (fView != null) { |
793 | return fView.fZoomValue; | |
abbdd66a | 794 | } |
eb63f5ff | 795 | return 1; |
73005152 BH |
796 | } |
797 | ||
798 | @Override | |
799 | public int getLineDotStyle() { | |
800 | return SWT.LINE_DOT; | |
801 | } | |
802 | ||
803 | @Override | |
804 | public int getLineDashStyle() { | |
805 | return SWT.LINE_DASH; | |
806 | } | |
807 | ||
808 | @Override | |
809 | public int getLineSolidStyle() { | |
810 | return SWT.LINE_SOLID; | |
811 | } | |
812 | ||
813 | @Override | |
814 | public IColor createColor(int r, int g, int b) { | |
815 | return new ColorImpl(Display.getDefault(), r, g, b); | |
816 | } | |
817 | ||
73005152 BH |
818 | @Override |
819 | public void setDrawTextWithFocusStyle(boolean focus) { | |
eb63f5ff | 820 | fDrawWithFocus = focus; |
73005152 | 821 | } |
abbdd66a | 822 | |
df0b8ff4 BH |
823 | /** |
824 | * Returns the screen bounds. | |
abbdd66a | 825 | * |
df0b8ff4 BH |
826 | * @return the screen bounds. |
827 | */ | |
e6ace8bb | 828 | protected static int getVscreenBounds() { |
eb63f5ff | 829 | return fVisibleScreenBounds; |
e6ace8bb BH |
830 | } |
831 | ||
df0b8ff4 BH |
832 | /** |
833 | * Sets the visible screen bounds. | |
abbdd66a | 834 | * |
df0b8ff4 BH |
835 | * @param vBounds the screen bounds. |
836 | */ | |
e6ace8bb | 837 | protected static void setVscreenBounds(int vBounds) { |
eb63f5ff | 838 | fVisibleScreenBounds = vBounds; |
e6ace8bb | 839 | } |
abbdd66a | 840 | |
df0b8ff4 BH |
841 | // ------------------------------------------------------------------------ |
842 | // Helper methods | |
843 | // ------------------------------------------------------------------------ | |
abbdd66a | 844 | |
df0b8ff4 BH |
845 | /** |
846 | * Validates the polygon height | |
abbdd66a | 847 | * |
df0b8ff4 BH |
848 | * @param localPoint array of points |
849 | * @return height | |
850 | */ | |
851 | private int validatePolygonHeight(int[] localPoint) { | |
852 | int i = 1; | |
853 | int max = 0; | |
854 | int min = Integer.MAX_VALUE; | |
855 | while (i < localPoint.length) { | |
abbdd66a | 856 | max = Math.abs(localPoint[i]) > Math.abs(max) ? localPoint[i] : max; |
df0b8ff4 BH |
857 | min = Math.abs(localPoint[i]) < Math.abs(min) ? localPoint[i] : min; |
858 | i+=2; | |
859 | } | |
860 | int height = max - min; | |
eb63f5ff BH |
861 | if (min < -fVisibleScreenBounds) { |
862 | height = height + min + fVisibleScreenBounds; | |
863 | min = -fVisibleScreenBounds; | |
864 | } | |
865 | if ((height < -fVisibleScreenBounds) && (min + height < -fVisibleScreenBounds)) { | |
866 | height = -fVisibleScreenBounds; | |
867 | } else if (height + min > fView.getVisibleHeight() + fVisibleScreenBounds) { | |
868 | height = fView.getVisibleHeight() + fVisibleScreenBounds - min; | |
df0b8ff4 BH |
869 | } |
870 | return height; | |
871 | } | |
73005152 | 872 | } |