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