blob: eb466698966b86d65e94ccb6cebe2118548054b7 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012, 2015 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
* Marc Dumais (Ericsson) - Bug 458644
*******************************************************************************/
package org.eclipse.cdt.visualizer.ui.canvas;
import java.io.File;
import java.io.FileNotFoundException;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
// ---------------------------------------------------------------------------
// GraphicObject
// ---------------------------------------------------------------------------
/**
* Graphic object base class.
* Base class for objects that can be displayed and manipulated on a GraphicCanvas.
*/
public class GraphicObject implements IGraphicObject, ITooltipProvider {
// --- members ---
/** Data object, if any, associated with this graphic object. */
protected Object m_data = null;
/** Bounding rectangle of this element. */
protected Rectangle m_bounds = new Rectangle(0, 0, 0, 0);
/** Whether this element is visible. */
protected boolean m_visible = true;
/** Whether this element is selected. */
protected boolean m_selected = false;
/** Foreground color (null means inherit from canvas) */
protected Color m_foreground = null;
/** Background color (null means inherit from canvas) */
protected Color m_background = null;
// --- enums ---
/**
* Pre-defined sizes/positions for super-imposing images on graphic objects.
* @since 1.3
*/
public enum ImageSizeAndPosition {
/** Image occupies upper-left quadrant of graphic object's area */
UPPER_LEFT_QUADRANT(new Rectangle(0, 0, 50, 50)),
/** Image occupies upper-right quadrant of graphic object's area */
UPPER_RIGHT_QUADRANT(new Rectangle(50, 0, 50, 50)),
/** Image occupies lower-left quadrant of graphic object's area */
LOWER_LEFT_QUADRANT(new Rectangle(0, 50, 50, 50)),
/** Image occupies lower-right quadrant of graphic object's area */
LOWER_RIGHT_QUADRANT(new Rectangle(50, 50, 50, 50)),
/** Image occupies lower-right 1/8 of graphic object's area */
LOWER_RIGHT_HEIGHTH(new Rectangle(75, 75, 25, 25)),
/** Image occupies upper-left 7/8 of graphic object's area */
UPPER_LEFT_SEVENTH_HEIGHTH(new Rectangle(0, 0, 75, 75)),
/** Image completely occupies the graphic object's area */
MAXSIZE(new Rectangle(0, 0, 100, 100));
private Rectangle value;
private ImageSizeAndPosition(Rectangle sizeAndPos) {
value = sizeAndPos;
}
public Rectangle getValue() {
return value;
}
}
// --- constructors/destructors ---
/** Constructor. */
public GraphicObject() {
}
/** Constructor. */
public GraphicObject(int x, int y, int width, int height) {
m_bounds.x = x;
m_bounds.y = y;
m_bounds.width = width;
m_bounds.height = height;
}
/** Constructor. */
public GraphicObject(Rectangle bounds) {
m_bounds.x = bounds.x;
m_bounds.y = bounds.y;
m_bounds.width = bounds.width;
m_bounds.height = bounds.height;
}
/** Constructor. */
public GraphicObject(Object data) {
m_data = data;
}
/** Constructor. */
public GraphicObject(int x, int y, int width, int height, Object data) {
m_bounds.x = x;
m_bounds.y = y;
m_bounds.width = width;
m_bounds.height = height;
m_data = data;
}
/** Constructor. */
public GraphicObject(Rectangle bounds, Object data) {
m_bounds.x = bounds.x;
m_bounds.y = bounds.y;
m_bounds.width = bounds.width;
m_bounds.height = bounds.height;
m_data = data;
}
/** Dispose method. */
public void dispose() {
m_data = null;
}
// --- accessors ---
/** Gets data object associated with this view element. */
@Override
public Object getData() {
return m_data;
}
/** Sets data object associated with this view element. */
@Override
public void setData(Object data) {
m_data = data;
}
/** Gets x location of this element */
public int getX() {
return m_bounds.x;
}
/** Sets x location of this element */
public void setX(int x) {
m_bounds.x = x;
}
/** Gets y location of this element */
public int getY() {
return m_bounds.y;
}
/** Sets y location of this element */
public void setY(int y) {
m_bounds.y = y;
}
/** Sets x/y position of this element */
public void setPosition(int x, int y) {
m_bounds.x = x;
m_bounds.y = y;
}
/** Gets width of this element */
public int getWidth() {
return m_bounds.width;
}
/** Sets width of this element */
public void setWidth(int w) {
m_bounds.width = w;
}
/** Gets y location of this element */
public int getHeight() {
return m_bounds.height;
}
/** Sets y location of this element */
public void setHeight(int h) {
m_bounds.height = h;
}
/** Sets width/height of this element */
public void setSize(int w, int h) {
m_bounds.width = w;
m_bounds.height = h;
}
/** Gets bounding rectangle of this element. */
public Rectangle getBounds() {
return m_bounds;
}
/** Sets bounding rectangle of this element. */
public void setBounds(int x, int y, int w, int h) {
m_bounds.x = x;
m_bounds.y = y;
m_bounds.width = w;
m_bounds.height = h;
}
/** Sets bounding rectangle of this element. */
public void setBounds(Rectangle bounds) {
m_bounds.x = bounds.x;
m_bounds.y = bounds.y;
m_bounds.width = bounds.width;
m_bounds.height = bounds.height;
}
/** Returns true if element bounds contains point. */
@Override
public boolean contains(int x, int y) {
return m_bounds.contains(x, y);
}
/** Returns true if element bounds are within specified rectangle. */
@Override
public boolean isWithin(Rectangle region) {
return (region.x <= m_bounds.x && region.y <= m_bounds.y
&& region.x + region.width >= m_bounds.x + m_bounds.width
&& region.y + region.height >= m_bounds.y + m_bounds.height);
}
/** Gets whether this element is visible. */
public boolean isVisible() {
return m_visible;
}
/** Sets whether this element is visible. */
public void setVisible(boolean visible) {
m_visible = visible;
}
/** Gets whether this element is selected. */
public boolean isSelected() {
return m_selected;
}
/** Sets whether this element is selected. */
public void setSelected(boolean selected) {
m_selected = selected;
}
/** Sets foreground color (null means inherit from container) */
public void setForeground(Color color) {
m_foreground = color;
}
/** Gets foreground color (null means inherit from container) */
public Color getForeground() {
return m_foreground;
}
/** Sets foreground color (null means inherit from container) */
public void setBackground(Color color) {
m_background = color;
}
/** Gets background color (null means inherit from container) */
public Color getBackground() {
return m_background;
}
// --- methods ---
/** Invoked to allow element to paint itself on the viewer canvas */
@Override
public void paint(GC gc, boolean decorations) {
if (isVisible()) {
// Set GC to reflect object properties, if set.
Color oldForeground = null;
Color oldBackground = null;
if (m_foreground != null) {
oldForeground = gc.getForeground();
gc.setForeground(m_foreground);
}
if (m_background != null) {
oldBackground = gc.getBackground();
gc.setBackground(m_background);
}
// Paint the object.
if (!decorations)
paintContent(gc);
else
paintDecorations(gc);
// Restore old state.
if (m_foreground != null)
gc.setForeground(oldForeground);
if (m_background != null)
gc.setBackground(oldBackground);
}
}
/**
* Paints content of graphic object.
* GC has already been set to this object's
* current foreground/background colors.
* Default implementation draws object's bounding box.
*/
public void paintContent(GC gc) {
// Draw boundary rectangle of object.
gc.drawRectangle(m_bounds);
// Display selection as thicker boundary.
if (isSelected()) {
int x = m_bounds.x + 1;
int y = m_bounds.y + 1;
int width = m_bounds.width - 2;
if (width < 0)
width = 0;
int height = m_bounds.height - 2;
if (height < 0)
height = 0;
gc.drawRectangle(x, y, width, height);
}
}
/** Returns true if object has decorations to paint. */
@Override
public boolean hasDecorations() {
return false;
}
/** Invoked to allow element to paint decorations
* on top of other items drawn on top of it.
*/
public void paintDecorations(GC gc) {
}
/**
* @since 1.1
*/
@Override
public String getTooltip(int x, int y) {
return null;
}
/**
* Draws an image on the current canvas graphic element. Where the image is
* located, relative to the graphic object and it's horizontal and vertical
* scale is configurable.
*
* @param gc
* @param imgPath : Absolute path and name of image to display
* by this margin, in each dimension.
* @param imgRelPositionAndScale : Rectangle object, where x, y are in % and
* represent the relative position where the upper left corner of the image
* will be positioned, relative to the parent graphic object.
* The width and height are in % and represent the scale of the object relative
* to the parent object. For example. a relative width and height of 25 means
* that the image will be scaled to be 1/4 of the width and height of the parent
* graphic object.
* @throws FileNotFoundException
* @since 1.3
*/
public void drawImage(GC gc, String imgPath, Rectangle imgRelPositionAndScale) throws FileNotFoundException {
// by default no margin
drawImageWithMargin(gc, imgPath, imgRelPositionAndScale, 0);
}
/**
* Draws an image on the current canvas graphic element. Where the image is
* located, relative to the graphic object and it's horizontal and vertical
* scale is configurable.
*
* @param gc
* @param imgPath : Absolute path and name of image to draw
* @param sizeAndpos : ImageSizeAndPosition enum value
* represent the relative position where the upper left corner of the image
* will be positioned, relative to the parent graphic object.
* The width and height are in % and represent the scale of the object relative
* to the parent object. For example. a relative width and height of 25 means
* that the image will be scaled to be 1/4 of the width and height of the parent
* graphic object.
* @throws FileNotFoundException
* @since 1.3
*/
public void drawImage(GC gc, String imgPath, ImageSizeAndPosition sizeAndpos) throws FileNotFoundException {
drawImageWithMargin(gc, imgPath, sizeAndpos.getValue(), 0);
}
/**
* Draws an image on the current canvas graphic element. Where the image is
* located, relative to the graphic object and it's horizontal and vertical
* scale is configurable. This version of the method allows to specify a margin,
* in pixels, that is to be left, by reducing the size of the image
*
* @param gc
* @param imgPath : Absolute path and name of image to draw
* @param sizeAndpos : ImageSizeAndPosition enum value
* represent the relative position where the upper left corner of the image
* will be positioned, relative to the parent graphic object.
* The width and height are in % and represent the scale of the object relative
* to the parent object. For example. a relative width and height of 25 means
* that the image will be scaled to be 1/4 of the width and height of the parent
* graphic object.
* @param margin: margin in pixels: the image will be reduced in size
* by this margin, in each dimension.
* @throws FileNotFoundException
* @since 1.3
*/
public void drawImageWithMargin(GC gc, String imgPath, ImageSizeAndPosition sizeAndpos, int margin)
throws FileNotFoundException {
drawImageWithMargin(gc, imgPath, sizeAndpos.getValue(), margin);
}
/**
* Draws an image on the current canvas graphic element. Where the image is
* located, relative to the graphic object and it's horizontal and vertical
* scale is configurable. This version of the method allows to specify a margin,
* in pixels, that is to be left, by reducing the size of the image
*
* @param gc
* @param imgPath : Absolute path and name of image to draw
* @param imgRelPositionAndScale : Rectangle object, where x, y are in % and
* represent the relative position where the upper left corner of the image
* will be positioned, relative to the parent graphic object.
* The width and height are in % and represent the scale of the object relative
* to the parent object. For example. a relative width and height of 25 means
* that the image will be scaled to be 1/4 of the width and height of the parent
* graphic object.
* @param margin: margin in pixels: the image will be reduced in size
* by this margin, in each dimension.
* @throws FileNotFoundException
* @since 1.3
*/
public void drawImageWithMargin(GC gc, String imgPath, Rectangle imgRelPositionAndScale, int margin)
throws FileNotFoundException {
File file = new File(imgPath);
if (!file.exists()) {
throw new FileNotFoundException();
}
if (margin < 0)
margin = 0;
// extract params
int imgPosX = imgRelPositionAndScale.x;
int imgPosY = imgRelPositionAndScale.y;
int imgScaleW = imgRelPositionAndScale.width;
int imgScaleH = imgRelPositionAndScale.height;
// compute wanted image pixel position and size
float posX = (m_bounds.x + (float) m_bounds.width * imgPosX / 100) + margin;
float posY = (m_bounds.y + (float) m_bounds.height * imgPosY / 100) + margin;
float width = ((float) m_bounds.width * imgScaleW / 100) - 2 * margin;
float height = ((float) m_bounds.height * imgScaleH / 100) - 2 * margin;
Image img = new Image(gc.getDevice(), imgPath);
// draw image
gc.drawImage(img, 0, 0, img.getBounds().width, img.getBounds().height, Math.round(posX), Math.round(posY),
Math.round(width), Math.round(height));
}
}