Internalize lttng.ui APIs
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng.ui / src / org / eclipse / linuxtools / internal / lttng / ui / views / latency / listeners / AbstractPaintListener.java
1 /*******************************************************************************
2 * Copyright (c) 2010, 2011 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Philippe Sawicki (INF4990.A2010@gmail.com) - Initial API and implementation
11 * Mathieu Denis (mathieu.denis55@gmail.com) - Refactored code
12 * Bernd Hufmann - Adapted to new model-view-controller design, display improvements
13 *******************************************************************************/
14 package org.eclipse.linuxtools.internal.lttng.ui.views.latency.listeners;
15
16 import org.eclipse.linuxtools.internal.lttng.ui.views.latency.AbstractViewer;
17 import org.eclipse.linuxtools.internal.lttng.ui.views.latency.model.Config;
18 import org.eclipse.swt.SWT;
19 import org.eclipse.swt.events.PaintEvent;
20 import org.eclipse.swt.events.PaintListener;
21 import org.eclipse.swt.graphics.Color;
22 import org.eclipse.swt.graphics.Font;
23 import org.eclipse.swt.graphics.GC;
24 import org.eclipse.swt.graphics.Image;
25 import org.eclipse.swt.graphics.Point;
26 import org.eclipse.swt.graphics.Rectangle;
27 import org.eclipse.swt.widgets.Display;
28
29 /**
30 * <b><u>AbstractPaintListener</u></b>
31 * <p>
32 * Abstract paint listener. Draws the graphs on the view canvas.
33 *
34 * @author Philippe Sawicki
35 */
36 public abstract class AbstractPaintListener implements PaintListener {
37
38 // ------------------------------------------------------------------------
39 // Attributes
40 // ------------------------------------------------------------------------
41
42 /**
43 * Default colors and fonts
44 */
45 protected final Color DEFAULT_DATA_COLOR = new Color(Display.getDefault(), 74, 112, 139);
46 protected final static Color DEFAULT_LABEL_COLOR = Display.getCurrent().getSystemColor(SWT.COLOR_BLACK);
47 protected final static Color DEFAULT_TEXT_COLOR = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GRAY);
48 protected final static Color DEFAULT_DATA_BACKGROUND_COLOR = Display.getCurrent().getSystemColor(SWT.COLOR_WHITE);
49 protected final static Color DEFAULT_CURRENT_EVENT_COLOR = Display.getCurrent().getSystemColor(SWT.COLOR_RED);
50
51 protected final Font DEFAULT_TITLE_FONT = new Font(Display.getDefault(), "Arial", 10, SWT.BOLD); //$NON-NLS-1$
52 protected final Font DEFAULT_VALUES_FONT = new Font(Display.getDefault(), "Arial", 7, SWT.NORMAL); //$NON-NLS-1$
53 protected final Font DEFAULT_LABEL_FONT = new Font(Display.getDefault(), "Arial", 8, SWT.NORMAL); //$NON-NLS-1$
54
55 /**
56 * A reference to the listener's view.
57 */
58 protected AbstractViewer fViewer;
59
60 /**
61 * Graph title
62 */
63 protected String fGraphTitle;
64
65 /**
66 * X-axis label.
67 */
68 protected String fXAxisLabel;
69
70 /**
71 * Y-axis label.
72 */
73 protected String fYAxisLabel;
74
75 /**
76 * Horizontal offset for the x-axis label.
77 */
78 protected int fXAxisLabelOffset;
79
80 /**
81 * Vertical offset for the horizontal axis offset.
82 */
83 protected int fHorizontalAxisYOffset = 20;
84
85 /**
86 * Graph padding.
87 */
88 protected int fPadding = Config.GRAPH_PADDING;
89
90 /**
91 * Graph client area.
92 */
93 protected Rectangle fClientArea = new Rectangle(0, 0, 1, 1);
94
95 /**
96 * Foreground color.
97 */
98 protected Color fForegroundColor;
99
100 /**
101 * Background color.
102 */
103 protected Color fBackgroundColor;
104
105 /**
106 * Data plotting color.
107 */
108 protected Color fDataColor;
109
110 /**
111 * Axis label color.
112 */
113 protected Color fLabelColor;
114
115 /**
116 * Text color.
117 */
118 protected Color fTextColor;
119
120 /**
121 * Data background color.
122 */
123 protected Color fDataBackgroundColor;
124
125 /**
126 * Color for current event time line.
127 */
128 protected Color fCurrentEventColor;
129
130 /**
131 * Original canvas font.
132 */
133 protected Font fOriginalFont;
134
135 /**
136 * Font for the title of the graph.
137 */
138 protected Font fTitleFont;
139
140 /**
141 * Font for the values on the horizontal and vertical axis.
142 */
143 protected Font fValuesFont;
144
145 /**
146 * Font for the horizontal and vertical labels.
147 */
148 protected Font fLabelFont;
149
150 /**
151 * Horizontal offset for the axis arrow.
152 */
153 protected final int ARROW_DELTA_X = 10;
154
155 /**
156 * Vertical offset for the axis arrow.
157 */
158 protected final int ARROW_DELTA_Y = 4;
159
160 /**
161 * Max horizontal distance between ticks.
162 */
163 protected final int MAX_WIDTH_BETWEEN_TICKS = 40;
164
165 /**
166 * Max vertical distance between ticks.
167 */
168 protected final int MAX_HEIGHT_BETWEEN_TICKS = 30;
169
170 /**
171 * Max characters that can be displayed on the vertical axis.
172 */
173 protected final int MAX_CHAR_VERTICAL_DISPLAY = 5;
174
175 /**
176 * Draw label each "drawLabelEachNTicks_" ticks.
177 */
178 protected int fDrawLabelEachNTicks = 1;
179
180 /**
181 * Image drawn on the canvas.
182 */
183 protected Image fImage;
184
185 /**
186 * Paint canvas, where the values are plotted.
187 */
188 protected GC fAxisImage;
189
190 /**
191 * Is the paint listener initialized ?
192 */
193 protected boolean fInitialized = false;
194
195 /**
196 * Draw area.
197 */
198 protected Rectangle fDrawArea;
199
200 /**
201 * Right padding (in pixels).
202 */
203 protected int fPaddingRight = Config.GRAPH_PADDING;
204
205 /**
206 * Top padding (in pixels).
207 */
208 protected int fPaddingTop = Config.GRAPH_PADDING;
209
210 /**
211 * Vertical axis offset (in pixels).
212 */
213 protected int fVerticalAxisOffset = 2 * Config.GRAPH_PADDING;
214
215 /**
216 * Vertical axis factor for values (10^delta). When values larger than MAX_CHAR_VERTICAL_DISPLAY.
217 */
218 protected int fDelta = 0;
219
220 /**
221 * The barWidth of a bar
222 */
223 protected int fBarWith = Config.DEFAULT_HISTOGRAM_BAR_WIDTH;
224
225 /**
226 * Minimum value on horizontal axis
227 */
228 protected long fXMin = -1;
229
230 /**
231 * Maximum value on horizontal axis
232 */
233 protected long fXMax = -1;
234
235 /**
236 * Minimum value on vertical axis
237 */
238 protected long fYMin = -1;
239
240 /**
241 * Maximum value on vertical axis
242 */
243 protected long fYMax = -1;
244
245 // ------------------------------------------------------------------------
246 // Constructors
247 // ------------------------------------------------------------------------
248
249 /**
250 * Constructor.
251 * @param view
252 * A reference to the listener's view.
253 */
254 public AbstractPaintListener(AbstractViewer view) {
255 fViewer = view;
256 fDataColor = DEFAULT_DATA_COLOR;
257 fLabelColor = DEFAULT_LABEL_COLOR;
258 fTextColor = DEFAULT_TEXT_COLOR;
259 fDataBackgroundColor = DEFAULT_DATA_BACKGROUND_COLOR;
260 fCurrentEventColor = DEFAULT_CURRENT_EVENT_COLOR;
261
262 fTitleFont = DEFAULT_TITLE_FONT;
263 fValuesFont = DEFAULT_VALUES_FONT;
264 fLabelFont = DEFAULT_LABEL_FONT;
265 }
266
267 // ------------------------------------------------------------------------
268 // Accessors
269 // ------------------------------------------------------------------------
270
271 /**
272 * Returns the draw area height.
273 * @return The draw area height.
274 */
275 public double getHeight() {
276 return (fClientArea.height - 2.0 * fPadding - fHorizontalAxisYOffset - fPaddingTop);
277 }
278
279 /**
280 * Returns the histogram's draw area width.
281 * @return The histogram's draw area width.
282 */
283 public double getWidth() {
284 return (fClientArea.width - 2.0 * fPadding - fVerticalAxisOffset - fPaddingRight); // width of the plot area;
285 }
286
287 /**
288 * Returns the histogram's draw area padding.
289 * @return The histogram's draw area padding.
290 */
291 public int getPadding() {
292 return fPadding;
293 }
294
295 /**
296 * Returns the histogram's draw area top padding.
297 * @return The histogram's draw area top padding.
298 */
299 public int getPaddingTop() {
300 return fPaddingTop;
301 }
302
303 /**
304 * Returns the histogram's vertical axis offset.
305 * @return The histogram's vertical axis offset.
306 */
307 public int getVerticalAxisOffset() {
308 return fVerticalAxisOffset;
309 }
310
311 /**
312 * Returns the histogram's horizontal axis offset.
313 * @return The histogram's horizontal axis offset.
314 */
315 public int getHorizontalAxisYOffset() {
316 return fHorizontalAxisYOffset;
317 }
318
319 /**
320 * Returns the horizontal minimum value
321 * @return The horizontal minimum value.
322 */
323 public long getXMin() {
324 return fXMin;
325 }
326
327 /**
328 * Returns the horizontal maximum value
329 * @return The horizontal maximum value.
330 */
331 public long getXMax() {
332 return fXMax;
333 }
334
335 /**
336 * Returns the horizontal minimum value
337 * @return The horizontal minimum value.
338 */
339 public long getYMin() {
340 return fYMin;
341 }
342
343 /**
344 * Returns the vertical maximum value
345 * @return The vertical maximum value.
346 */
347 public long getYMax() {
348 return fYMax;
349 }
350
351 // ------------------------------------------------------------------------
352 // Operations
353 // ------------------------------------------------------------------------
354
355 /**
356 * Disposes local resources (e.g. colors or fonts)
357 */
358 public void dispose() {
359 DEFAULT_DATA_COLOR.dispose();
360 DEFAULT_TITLE_FONT.dispose();
361 DEFAULT_VALUES_FONT.dispose();
362 DEFAULT_LABEL_FONT.dispose();
363 }
364
365 /*
366 * (non-Javadoc)
367 * @see org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events.PaintEvent)
368 */
369 @Override
370 public void paintControl(PaintEvent e) {
371 fClientArea = fViewer.getClientArea();
372
373 fForegroundColor = e.gc.getForeground();
374 fBackgroundColor = e.gc.getBackground();
375 fOriginalFont = e.gc.getFont();
376
377 scale();
378
379 if (!fInitialized) {
380 fImage = new Image(Display.getDefault(), fViewer.getBounds());
381
382 fAxisImage = new GC(fImage);
383
384 fAxisImage.setForeground(fForegroundColor);
385 fAxisImage.setBackground(fBackgroundColor);
386 fAxisImage.fillRectangle(fImage.getBounds());
387
388 fInitialized = true;
389 }
390
391 paintGraphTitle();
392 paintBackground();
393 paintHorizontalAxis();
394 paintVerticalAxis();
395 paintContent();
396
397 e.gc.drawImage(fImage, 0, 0);
398 }
399
400 /**
401 * Paints the title of the graph.
402 */
403 public void paintGraphTitle() {
404 if (fGraphTitle != null) {
405 fAxisImage.setFont(fTitleFont);
406 fAxisImage.setForeground(fLabelColor);
407 fAxisImage.setBackground(fBackgroundColor);
408
409 int zoomFactor = fViewer.getZoomFactor() / fViewer.getZoomIncrement() + 1;
410 int labelWidth = fAxisImage.stringExtent(fGraphTitle).x;
411 // Draws the zoom factor in the title only if there is one
412 if (fViewer.getZoomFactor() > 1)
413 fAxisImage.drawText(fGraphTitle + " (" + zoomFactor + "x)", (fViewer.getBounds().width - fPadding - labelWidth) / 2, 0); //$NON-NLS-1$ //$NON-NLS-2$
414 else
415 fAxisImage.drawText(fGraphTitle, (fViewer.getBounds().width - fPadding - labelWidth) / 2, 0);
416 }
417 }
418
419 /**
420 * Paints the background of the draw area.
421 */
422 public void paintBackground() {
423 fAxisImage.setBackground(fDataBackgroundColor);
424
425 fAxisImage.fillRectangle(fPadding + fVerticalAxisOffset, fPadding + fPaddingTop, (int)getWidth() + 1, (int)getHeight());
426 }
427
428 /**
429 * Paints the horizontal axis.
430 */
431 public void paintHorizontalAxis() {
432 fAxisImage.setForeground(fForegroundColor);
433
434 int y = fClientArea.height - fPadding - fHorizontalAxisYOffset;
435
436 fAxisImage.drawLine(fClientArea.x + fPadding + fVerticalAxisOffset, y, fClientArea.width - fPadding, y);
437
438 paintHorizontalArrow(fClientArea.width - fPadding, y);
439 // Draw the axis graphic details only if there are some data points (i.e. do not draw the axis graphic details
440 // if the window timerange is so small that no latency can be computed, or if there are no matching events in
441 // the timerange (for example, when an experiment has many traces with a large time gap between the logged
442 // events sets).
443 if (fXMin != Long.MAX_VALUE && fXMax != Long.MIN_VALUE && fXMin != fXMax) {
444 paintHorizontalTicks(y);
445 paintHorizontalAxisValues(y + 30);
446 }
447 paintHorizontalAxisLabel(y + fHorizontalAxisYOffset - 5);
448 }
449
450 /**
451 * Paints the vertical axis.
452 */
453 public void paintVerticalAxis() {
454 fAxisImage.setForeground(fForegroundColor);
455
456 int x = fClientArea.x + fPadding + fVerticalAxisOffset;
457
458 fAxisImage.drawLine(x, fPadding, x, fClientArea.height - fPadding - fHorizontalAxisYOffset);
459
460 paintVerticalArrow(x, fClientArea.y + fPadding);
461 // Draw the axis graphic details only if there are some data points (i.e. do not draw the axis graphic details
462 // if the window timerange is so small that no latency can be computed, or if there are no matching events in
463 // the timerange (for example, when an experiment has many traces with a large time gap between the logged
464 // events sets).
465 if (fXMin != Long.MAX_VALUE && fXMax != Long.MIN_VALUE && fXMin != fXMax) {
466 paintVerticalTicks(x);
467 paintVerticalAxisValues(x);
468 }
469 paintVerticalAxisLabel(x);
470 }
471
472 /**
473 * Paints the arrow on the horizontal axis.
474 * @param x
475 * The x-coordinate of the point where the arrow points.
476 * @param y
477 * The y-coordinate of the point where the arrow points.
478 */
479 public void paintHorizontalArrow(int x, int y) {
480 // Arrow top line
481 fAxisImage.drawLine(x - ARROW_DELTA_X, y - ARROW_DELTA_Y, x, y);
482 // Arrow bottom line
483 fAxisImage.drawLine(x - ARROW_DELTA_X, y + ARROW_DELTA_Y, x, y);
484 }
485
486 /**
487 * Paints the arrow on the vertical axis.
488 * @param x
489 * The x-coordinate of the point where the arrow points.
490 * @param y
491 * The y-coordinate of the point where the arrow points.
492 */
493 public void paintVerticalArrow(int x, int y) {
494 // Arrow left line
495 fAxisImage.drawLine(x - ARROW_DELTA_Y, y + ARROW_DELTA_X, x, y);
496 // Arrow right line
497 fAxisImage.drawLine(x + ARROW_DELTA_Y, y + ARROW_DELTA_X, x, y);
498 }
499
500 /**
501 * Paints the horizontal ticks.
502 * @param y
503 * The y coordinate where to draw the axis.
504 */
505 public void paintHorizontalTicks(int y) {
506 if (fXMin >= 0L && fXMax >= 0L) {
507 int nbTicks = (int)(getWidth()) / MAX_WIDTH_BETWEEN_TICKS + 1;
508
509 for (int i = 0; i < nbTicks; i++) {
510 if (i % fDrawLabelEachNTicks == 0) {
511 int x = i * MAX_WIDTH_BETWEEN_TICKS + fPadding + fVerticalAxisOffset;
512 fAxisImage.drawLine(x, y, x, y + 3);
513 }
514 }
515 }
516 }
517
518 /**
519 * Paints the horizontal axis values.
520 * @param y
521 * The y coordinate where to draw the axis.
522 */
523 public void paintHorizontalAxisValues(int y) {
524 if (fXMin >= 0L && fXMax >= 0L) {
525 fAxisImage.setForeground(fTextColor);
526 fAxisImage.setBackground(fBackgroundColor);
527
528 double width = getWidth();
529 int nbTicks = ((int)getWidth()) / MAX_WIDTH_BETWEEN_TICKS + 1;
530
531 for (int i = 0; i < nbTicks; i++) {
532 if (i % fDrawLabelEachNTicks == 0) {
533 int x = i * MAX_WIDTH_BETWEEN_TICKS + fPadding + fVerticalAxisOffset;
534
535 long currentValue = (i * MAX_WIDTH_BETWEEN_TICKS)* (long)((fXMax - fXMin) / width) + fXMin;
536 String currentLabel = formatStringForHorizontalAxis(currentValue);
537
538 fAxisImage.setFont(fValuesFont);
539 fAxisImage.drawText(currentLabel, x, y - 24);
540 }
541 }
542 }
543 }
544
545 /**
546 * Paints the horizontal axis label.
547 * @param y
548 * The y-coordinate where to draw the label.
549 */
550 public void paintHorizontalAxisLabel(int y) {
551 if (fXAxisLabel != null) {
552 fAxisImage.setFont(fLabelFont);
553 fAxisImage.setForeground(fLabelColor);
554
555 int labelWidth = fAxisImage.stringExtent(fXAxisLabel).x;
556
557 fAxisImage.drawText(fXAxisLabel, fClientArea.width - fPadding - labelWidth, y);
558 }
559 }
560
561 /**
562 * Paints the vertical axis ticks.
563 * @param x
564 * The x-coordinate where to draw the ticks.
565 */
566 public void paintVerticalTicks(int x) {
567 if (fYMin != 0L && fYMax != 0L) {
568 int nbTicks = (int)(getHeight() / MAX_HEIGHT_BETWEEN_TICKS + 1);
569
570 for (int i = 0; i < nbTicks; i++) {
571 int y = fClientArea.height - fPadding - fHorizontalAxisYOffset - i * MAX_HEIGHT_BETWEEN_TICKS;
572 fAxisImage.drawLine(x - 3, y, x, y);
573 }
574 }
575 }
576
577 /**
578 * Paints the vertical axis values.
579 * @param x
580 * The x-coordinate where to draw the values.
581 */
582 public void paintVerticalAxisValues(int x) {
583 if (fYMin >= 0L && fYMax >= 0L) {
584 fAxisImage.setForeground(fTextColor);
585 fAxisImage.setBackground(fBackgroundColor);
586
587 double height = getHeight();
588 int nbTicks = (int)(height / MAX_HEIGHT_BETWEEN_TICKS + 1);
589
590 // System.out.println("nbTicks = " + nbTicks);
591
592 for (int i = 0; i < nbTicks; i++) {
593 int y = fClientArea.height - fPadding - fHorizontalAxisYOffset - i * MAX_HEIGHT_BETWEEN_TICKS;
594
595 long currentValue = (i * MAX_HEIGHT_BETWEEN_TICKS)* (long)((fYMax - fYMin) / height) + fYMin;
596 String currentLabel = formatStringForVerticalAxis(currentValue);
597
598 fAxisImage.setFont(fValuesFont);
599
600 Point textDimensions = fAxisImage.stringExtent(currentLabel);
601 fAxisImage.drawText(currentLabel, x - textDimensions.x - 5, y - textDimensions.y / 2);
602 }
603 }
604 }
605
606 /**
607 * Increases the bar width.
608 */
609 public void increaseBarWitdh() {
610 fBarWith = fBarWith << 1;
611 if (fBarWith > Config.MAX_HISTOGRAM_BAR_WIDTH) {
612 fBarWith = Config.MAX_HISTOGRAM_BAR_WIDTH;
613 }
614 }
615
616 /**
617 * Decreases the bar width.
618 */
619 public void decreaseBarWitdh() {
620 fBarWith = fBarWith >> 1;
621 if (fBarWith < Config.MIN_HISTOGRAM_BAR_WIDTH) {
622 fBarWith = Config.MIN_HISTOGRAM_BAR_WIDTH;
623 }
624 }
625
626
627 /**
628 * Paints the vertical axis label.
629 * @param x
630 * The x-coordinate where to draw the label.
631 */
632 public void paintVerticalAxisLabel(int x) {
633 if (fYAxisLabel != null) {
634 fAxisImage.setFont(fLabelFont);
635 fAxisImage.setForeground(fLabelColor);
636 fAxisImage.setBackground(fBackgroundColor);
637
638 if (fDelta >= 1)
639 fAxisImage.drawText(fYAxisLabel + " (x10^" + fDelta + ")", x + 10, fHorizontalAxisYOffset - 5); //$NON-NLS-1$//$NON-NLS-2$
640 else
641 fAxisImage.drawText(fYAxisLabel, x + 10, fPadding);
642 }
643 }
644
645 /**
646 * Adds points to the graph and draws them to the canvas.
647 * @param points
648 * The buffer of points to draw.
649 * @param nbPoints
650 * The number of points in the buffer.
651 */
652 abstract public String formatToolTipLabel(int x, int y);
653
654 /**
655 * Method to be implemented to scale the model data to the actual screen size.
656 */
657 abstract public void scale();
658
659 /**
660 * Called for drawing elements after points are added to the graph.
661 */
662 abstract public void paintContent();
663
664 /**
665 * Clears the image and prepares it for redrawing.
666 */
667 public void clear() {
668 fInitialized = false;
669 fXMin = -1;
670 fXMax = -1;
671 fYMin = -1;
672 fYMax = -1;
673 }
674
675 /**
676 * Draw horizontal label each "nbTicks" ticks.
677 * @param nbTicks
678 * The draw interval.
679 */
680 public void setDrawLabelEachNTicks(int nbTicks) {
681 fDrawLabelEachNTicks = nbTicks;
682 }
683
684 /**
685 * Sets the title of the graph.
686 * @param graphTitle
687 * The title of the graph.
688 */
689 public void setGraphTitle(String graphTitle) {
690 fGraphTitle = graphTitle;
691 }
692
693 /**
694 * Sets the horizontal axis label.
695 * @param xAxisLabel
696 * The horizontal axis label.
697 * @param offset
698 * The horizontal axis draw offset (in pixels).
699 */
700 public void setXAxisLabel(String xAxisLabel, int offset) {
701 fXAxisLabel = xAxisLabel;
702 fXAxisLabelOffset = offset;
703 }
704
705 /**
706 * Sets the vertical axis label.
707 * @param yAxisLabel
708 * The vertical axis label.
709 */
710 public void setYAxisLabel(String yAxisLabel) {
711 fYAxisLabel = yAxisLabel;
712 }
713
714 /**
715 * Returns a string representing the given value.
716 *
717 * @param value
718 * The numeric value to convert to String.
719 * @return The String-formatted value.
720 */
721 public String formatStringForHorizontalAxis(long value) {
722 return String.valueOf(value);
723 }
724
725 /**
726 * Returns a string representing the given value.
727 *
728 * @param value
729 * The numeric value to convert to String.
730 * @return The String-formatted value.
731 */
732 public String formatStringForVerticalAxis(long value) {
733 return String.valueOf(value);
734 }
735 }
This page took 0.049438 seconds and 5 git commands to generate.