Skip to main content
summaryrefslogtreecommitdiffstats
blob: 30acb440a437d93372b353da4630ee1c2c9542eb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*******************************************************************************
 * Copyright (c) 2009 Ericsson
 * 
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse Public License v1.0 which
 * accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *   William Bourque - Initial API and implementation
 *
 * Modifications:
 * 2010-07-16 Yuriy Vashchuk - Heritage corrections. Redraw bug correction.
 * 							   Double Buffering implementation.
 *******************************************************************************/
package org.eclipse.linuxtools.lttng.ui.views.histogram;

import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;

import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;

/**
 * <b><u>HistogramCanvasPaintListener</u></b>
 * <p>
 * Implementation of a PaintListener for the need of the HistogramCanvas
 * <p> 
 */
public class HistogramCanvasPaintListener implements PaintListener 
{
	private static ChildrenHistogramCanvas childrenCanvas = null;
	
	/**
	 * HistogramCanvasPaintListener default constructor
	 */	
	public HistogramCanvasPaintListener() {
	}
	
	/**
	 * HistogramCanvasPaintListener constructor
	 * 
	 * @param parentCanvas Related canvas
	 */
	public HistogramCanvasPaintListener(ChildrenHistogramCanvas newCanvas) {
		childrenCanvas = newCanvas;
	}
	
	/**
	 * Function called when the canvas need to redraw.<p>
	 * 
	 * @param event  The generated paint event when redraw is called.
	 */
	public void paintControl(PaintEvent event) {

		if (childrenCanvas.getSize().x > 0 && childrenCanvas.getSize().y > 0) {
			Image image = (Image) childrenCanvas.getData("double-buffer-image");
			
			// Creates new image only absolutely necessary.
			if (image == null
					|| image.getBounds().width != childrenCanvas.getBounds().width
					|| image.getBounds().height != childrenCanvas.getBounds().height) {

				image =	new Image(
						event.display,
						childrenCanvas.getBounds().width,
						childrenCanvas.getBounds().height
						);

				childrenCanvas.setData("double-buffer-image", image);
			}
			
			// Initializes the graphics context of the image. 
	        GC imageGC = new GC(image);
	        
			// First clear the whole canvas to have a clean section where to draw
			clearDrawingSection(imageGC, image, childrenCanvas);
	        
			// If the content is null or has rady to draw we quit the function here
			if ( (childrenCanvas.getHistogramContent() != null) && (childrenCanvas.getHistogramContent().getReadyUpToPosition() != 0) ) {
				
				// Call the function that draw the bars
				drawHistogram(imageGC, image);
				
				// Pinpoint a position if set
				if (childrenCanvas.getHistogramContent().getSelectedEventTimeInWindow() > 0 ) {
					drawSelectedEventInWindow(imageGC, image);
				}

				// Draws the buffer image onto the canvas. 
				event.gc.drawImage(image, 0, 0);
			}

			imageGC.dispose();
		}
	}
	
	/**
	 * Clear the drawing section of the canvas<p>
	 * This paint the whole background in EMPTY_BACKGROUND_COLOR, so we have something clean to draw on.
	 * 
	 * @param imageGC GC content.
	 * @param image Image content.
	 * @param ourCanvas Canvas to clean.
	 */
	public void clearDrawingSection(GC imageGC, Image image, HistogramCanvas ourCanvas) {
		imageGC.setBackground(ourCanvas.getDisplay().getSystemColor(HistogramConstant.EMPTY_BACKGROUND_COLOR));
		imageGC.setForeground(ourCanvas.getDisplay().getSystemColor(HistogramConstant.EMPTY_BACKGROUND_COLOR));

		// Fills background. 
        imageGC.fillRectangle(0, 0, image.getBounds().width + 1, image.getBounds().height + 1);		
	}
	
	// *** VERIFY ***
	// Is it good to put this synchronized?
	//
	/**
	 * Draw the histogram bars in the canvas.<p>
	 * Use existing elements in HistogramContent to draw bars on the cancas; 
	 * 	the element table in content need to be populated and have consistent value.  
	 * 
	 * @param imageGC GC content.
	 * @param image image content.
	 */
	public synchronized void drawHistogram(GC imageGC, Image image) {
		
		// This will be the color for all the bars that wil be draw below.
		imageGC.setBackground(childrenCanvas.getDisplay().getSystemColor(HistogramConstant.HISTOGRAM_BARS_COLOR));
		
		// *** NOTE *** 
		// Y Position in a canvas is REVERSED, so "0" is on top of the screen and "MAX" is on bottom.
		// Not very instinctive, isn't it?
		
		// Draw a bar from the left (pos X=0) until the pos=(NbBars*barWidth). If space is left, it will be blanked after.
	    for ( int x = 0; x < childrenCanvas.getHistogramContent().getReadyUpToPosition(); x++) {
	    	imageGC.fillRectangle(
	    			childrenCanvas.getHistogramContent().getBarsWidth() * x,
	    			image.getBounds().height - childrenCanvas.getHistogramContent().getElementByIndex(x).intervalHeight,
    				childrenCanvas.getHistogramContent().getBarsWidth(),
    				childrenCanvas.getHistogramContent().getElementByIndex(x).intervalHeight
    				);
	    }
		
	}
	
	/**
	 * Draw a certain event selected in the window.<p>
	 * 
	 * @param imageGC GC content.
	 * @param image image content.
	 */
	public synchronized void drawSelectedEventInWindow(GC imageGC, Image image) {
		
		final HistogramContent tmpContent = childrenCanvas.getHistogramContent();
		final int tmpBarWidth = tmpContent.getBarsWidth();
		final int position = tmpContent.getClosestXPositionFromTimestamp(tmpContent.getSelectedEventTimeInWindow());
		
		// This will be the color for all the bars that will be draw below.
		imageGC.setForeground(childrenCanvas.getDisplay().getSystemColor(HistogramConstant.SELECTED_EVENT_COLOR));
		imageGC.setLineWidth(HistogramConstant.SELECTION_LINE_WIDTH);
		imageGC.drawLine(
				tmpBarWidth * position,
				0,
				tmpBarWidth * position,
				image.getBounds().height
				);
		}
	
}

Back to the top