| /******************************************************************************* |
| * 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(); |
| } |
| } |