blob: 28c5da4b28b5d16f79b2a4c8098c932dd130176c [file] [log] [blame]
/*******************************************************************************
* 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<>();
Listener mouseListener = new Listener() {
@Override
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. */
@Override
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. */
@Override
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();
}
}