Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 565a4c3ac3e6c6579812a4fabd9244f190f29527 (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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/*******************************************************************************
 * Copyright (c) 2012, 2014 Tilera Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     William R. Swanson (Tilera Corporation)
 *     Xavier Raynaud (Kalray) - Bug 430804
 *******************************************************************************/

package org.eclipse.cdt.visualizer.ui.canvas;

import java.util.ArrayList;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;


// ---------------------------------------------------------------------------
// GraphicCanvas
// ---------------------------------------------------------------------------

/**
 * Viewer canvas -- base class for canvas that displays a collection
 * of persistent, repositionable graphic objects.
 * 
 * Note: painting is done in order objects were added,
 * so objects added last are drawn "on top" of others.
 * Use raise/lower methods to change the object z-ordering, if needed.
 */
public class GraphicCanvas extends BufferedCanvas
{
	// --- members ---
	
	/** Viewer elements. */
	protected ArrayList<IGraphicObject> m_objects = null;
	
	
	// --- constructors/destructors ---
	
	/** Constructor. */
	public GraphicCanvas(Composite parent) {
		super(parent);
		m_objects = new ArrayList<IGraphicObject>();
		Listener mouseListener = new Listener() {
			public void handleEvent(Event event) {
				switch (event.type) {
				case SWT.MouseEnter:
				case SWT.MouseMove:
					IGraphicObject obj = getGraphicObject(event.x, event.y);
					if (obj instanceof ITooltipProvider) {
						String tooltip = ((ITooltipProvider) obj).getTooltip(event.x, event.y);
						setToolTipText(tooltip);
					}
					break;
				}
			}
		};
		addListener(SWT.MouseMove, mouseListener);
		addListener(SWT.MouseEnter, mouseListener);
	}
	
	/** Dispose method. */
	public void dispose() {
		if (m_objects != null) {
			m_objects.clear();
			m_objects = null;
		}
		super.dispose();
	}
	
	
	// --- object management methods ---

	/** Removes all elements */
	public void clear() {
		m_objects.clear();
	}
	
	/** Adds an element */
	public IGraphicObject add(IGraphicObject element) {
		if (! m_objects.contains(element)) {
			m_objects.add(element);
		}
		return element;
	}
	
	/** Removes an element */
	public void remove(IGraphicObject element) {
		m_objects.remove(element);
	}
	
	/** Raises an element to top of repaint z-ordering */
	public void raiseToFront(IGraphicObject element) {
		if (m_objects.contains(element)) {
			m_objects.remove(element);
			m_objects.add(element);
		}
	}
	
	/** Lowers an element to bottom of repaint z-ordering */
	public void lowerToBack(IGraphicObject element) {
		if (m_objects.contains(element)) {
			m_objects.remove(element);
			m_objects.add(0, element);
		}
	}

	
	// --- painting methods ---
	
	/** Paints elements on canvas. */
	public void paintCanvas(GC gc) {
		// paint background first
		clearCanvas(gc);
		
		// we paint object list from start to end,
		// so end of the list is "top" in z-ordering

		// allow objects to draw themselves
		for (IGraphicObject gobj : m_objects) {
			gobj.paint(gc, false);
		}

		// allow objects to paint any "decorations" on top of other stuff
		for (IGraphicObject gobj : m_objects) {
			if (gobj.hasDecorations())
				gobj.paint(gc, true);
		}
	}
	
	
	// --- point-to-object accessors ---
	
	/** Returns first graphic object found under specified point */
	public IGraphicObject getGraphicObject(int x, int y) {
		return getGraphicObject(null, x, y);
	}

	/** Returns first graphic object found under specified point.
	 *  If type argument is non-null, returns first object assignable to specified type.
	 */
	public IGraphicObject getGraphicObject(Class<?> type, int x, int y) {
		IGraphicObject result = null;
		
		// note: have to search list in reverse order we draw it,
		// so we hit items "on top" in the z-ordering first
		int count = (m_objects == null) ? 0 : m_objects.size();
		for (int i=count-1; i>=0; i--) {
			IGraphicObject gobj = m_objects.get(i);
			if (gobj.contains(x, y)) {
				if (type != null) {
					Class<?> objType = gobj.getClass();
					if (! type.isAssignableFrom(objType)) continue;
				}
				result = gobj;
				break;
			}
		}
		
		return result;
	}
	
	// --- model data accessors ---
	
	/** Returns graphic object (if any) that has specified data value. */
	public IGraphicObject getGraphicObjectFor(Object value) {
		IGraphicObject result = null;
		for (IGraphicObject gobj : m_objects) {
			if (gobj.getData() == value) {
				result = gobj;
				break;
			}
		}
		return result;
	}
	
	/** Returns data value (if any) for the specified graphic element. */
	public Object getDataFor(IGraphicObject IGraphicObject) {
		return (IGraphicObject == null) ? null : IGraphicObject.getData();
	}
}

Back to the top