/******************************************************************************* * Copyright (c) 2012, 2015 Tilera Corporation and others. * 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 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. */ public Object getData() { return m_data; } /** Sets data object associated with this view element. */ 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. */ public boolean contains(int x, int y) { return m_bounds.contains(x,y); } /** Returns true if element bounds are within specified rectangle. */ 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 */ 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. */ 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)); } }