Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Dumais2014-04-07 16:44:54 +0000
committerMarc Dumais2014-04-28 16:37:30 +0000
commit620def4c62f89669db94fd24323c4b223e97e0db (patch)
tree16cb18e8cfd0d5e980edd3f1b310745c541344cc /visualizer
parent8e871b492f5a00fa5c6974de19fe775cd93482ad (diff)
downloadorg.eclipse.cdt-620def4c62f89669db94fd24323c4b223e97e0db.tar.gz
org.eclipse.cdt-620def4c62f89669db94fd24323c4b223e97e0db.tar.xz
org.eclipse.cdt-620def4c62f89669db94fd24323c4b223e97e0db.zip
Bug 432854 - [visualizer] Add a new graphic object class supporting
nesting, virtual bounds and automatic scaling Change-Id: I8d38747af369e0c0d591abab5a76a00c7dc5a43a Reviewed-on: https://git.eclipse.org/r/25079 Tested-by: Hudson CI Reviewed-by: Marc Dumais <marc.dumais@ericsson.com>
Diffstat (limited to 'visualizer')
-rw-r--r--visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/VirtualBoundsGraphicObject.java419
1 files changed, 419 insertions, 0 deletions
diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/VirtualBoundsGraphicObject.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/VirtualBoundsGraphicObject.java
new file mode 100644
index 00000000000..ba1d1700e6b
--- /dev/null
+++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/VirtualBoundsGraphicObject.java
@@ -0,0 +1,419 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2014 Ericsson.
+ * 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:
+ * Marc Dumais (Ericsson) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.visualizer.ui.canvas;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Rectangle;
+
+/**
+ * Graphic object that can be used as a container for child objects. Each object
+ * is sized and positioned in virtual units, and positioned relative to the parent
+ * object's position. Setting the real (pixel) bounds of an object recursively sets
+ * the bounds of any contained child objects, taking into account its virtual
+ * bounds, compared to its parent.
+ * @since 1.1
+ */
+public class VirtualBoundsGraphicObject extends GraphicObject {
+
+ // --- members ---
+
+ /**
+ * Holds the virtual position and size of graphical object.
+ * Position is relative to parent object
+ */
+ protected Rectangle m_virtualBounds = new Rectangle(0,0,0,0);
+
+ /** List of children objects contained in this one */
+ protected ArrayList<VirtualBoundsGraphicObject> m_childrenObjects =
+ new ArrayList<VirtualBoundsGraphicObject>();
+
+ /** Map of contained objects and their identifying labels. for quick look-up */
+ protected HashMap<String, VirtualBoundsGraphicObject> m_childrenObjectsMap =
+ new HashMap<String, VirtualBoundsGraphicObject>();
+
+ /** Whether the container's boundaries should be drawn */
+ protected boolean m_drawContainerBounds = true;
+
+ /** Is the object selectable? */
+ protected boolean m_selectable = false;
+
+ /** Color to use when this object is Selected */
+ protected Color m_selectedColor = null;
+
+ /** Value for the margin in pixels */
+ protected int m_childMargin = 0;
+
+ /** Default for the margin in pixels */
+ protected static final int MARGIN_PIXELS_DEFAULT = 1;
+
+
+ // --- constructors/destructors ---
+
+ /** Constructor */
+ public VirtualBoundsGraphicObject() {
+ // default is not selectable
+ this(false, MARGIN_PIXELS_DEFAULT);
+ }
+
+ /** Alternate constructor */
+ public VirtualBoundsGraphicObject(boolean selectable, int childMargin) {
+ m_selectable = selectable;
+ setDrawContainerBounds(true);
+ m_childMargin = childMargin;
+ }
+
+ /** Dispose method - recursively dispose this object and children objects */
+ @Override
+ public void dispose() {
+ super.dispose();
+ if (m_childrenObjects != null) {
+ for (VirtualBoundsGraphicObject o : m_childrenObjects) {
+ o.dispose();
+ }
+ m_childrenObjects.clear();
+ m_childrenObjects = null;
+ }
+ if (m_childrenObjectsMap != null) {
+ m_childrenObjectsMap.clear();
+ m_childrenObjectsMap = null;
+ }
+ }
+
+
+ // --- Object methods ---
+
+ /** Returns string representation. */
+ @Override
+ public String toString() {
+ return String.format("Class: %s, Real bounds: %s, Virtual bounds: %s" +
+ ", Draw container bounds: %s ",
+ this.getClass().getSimpleName(),
+ this.getBounds().toString(),
+ m_virtualBounds.toString(),
+ m_drawContainerBounds
+ );
+ }
+
+
+ // --- accessors ---
+
+ /**
+ * Sets whether the container's boundary should be drawn / filled-in.
+ * If false, indicates child objects are displayed without showing
+ * the parent container.
+ */
+ public void setDrawContainerBounds(boolean draw) {
+ m_drawContainerBounds = draw;
+ }
+
+ /** Sets whether the object is selectable */
+ public void setSelectable(boolean sel) {
+ m_selectable = sel;
+ }
+
+ /** Returns whether the object is selectable */
+ public boolean isSelectable() {
+ return m_selectable;
+ }
+
+ /** Set the color used to highlight a selection */
+ public void setSelectedColor(Color color) {
+ m_selectedColor = color;
+ }
+
+ /** Get the color used to highlight a selection */
+ public Color getSelectedColor() {
+ return m_selectedColor;
+ }
+
+ /** Set the margin to be inserted between a parent and a child object,
+ * in pixels */
+ public void setChildMargin(int margin) {
+ m_childMargin = margin;
+ }
+
+ // --- methods ---
+
+
+ /**
+ * Sets the absolute bounds (in pixels) of this container object. If it has
+ * children objects, recursively set their absolute bounds.
+ * Overridden to delegate to setBounds(int,int,int,int) in this class,
+ * rather than the base class.
+ */
+ @Override
+ public void setBounds(Rectangle bounds) {
+ setBounds(bounds.x, bounds.y, bounds.width, bounds.height);
+ }
+
+ /**
+ * Sets the absolute bounds (in pixels) of this container object. If it has
+ * children objects, recursively set their absolute bounds.
+ */
+ @Override
+ public void setBounds(int x, int y, int w, int h) {
+ super.setBounds(x, y, w, h);
+ for(VirtualBoundsGraphicObject o : m_childrenObjects) {
+ o.setBounds(virtualToRealBounds(o.getVirtualBounds()));
+ }
+ }
+
+ /**
+ * Set bounds of current object relative to its container.
+ * The x and y coordinate are relative to the parent container.
+ * The unit is arbitrary integer but have to be consistent between
+ * parent and children. Width and height must be greater than zero.
+ */
+ public void setVirtualBounds(int[] bounds) {
+ m_virtualBounds.x = bounds[0];
+ m_virtualBounds.y = bounds[1];
+ m_virtualBounds.width = bounds[2];
+ m_virtualBounds.height = bounds[3];
+ checkVirtualBounds();
+ }
+
+ /**
+ * Set bounds of current object relative to its container.
+ * The x and y coordinate are relative to the parent container.
+ * The unit is arbitrary integer but have to be consistent between
+ * parent and children. Width and height must be greater than zero.
+ */
+ public void setVirtualBounds(Rectangle bounds) {
+ m_virtualBounds = bounds;
+ checkVirtualBounds();
+ }
+
+ /**
+ * Set bounds of current object relative to its container.
+ * The x and y coordinate are relative to the parent container.
+ * The unit is arbitrary integer but have to be consistent between
+ * parent and children. Width and height must be greater than zero.
+ */
+ public void setVirtualBounds(int x, int y, int width, int height) {
+ m_virtualBounds.x = x;
+ m_virtualBounds.y = y;
+ m_virtualBounds.width = width;
+ m_virtualBounds.height = height;
+ checkVirtualBounds();
+ }
+
+ /** Get the relative bounds of current object, relative to its parent container */
+ public Rectangle getVirtualBounds() {
+ return m_virtualBounds;
+ }
+
+ /** Performs a sanity check of the virtual bounds of this object */
+ private void checkVirtualBounds() {
+ if (m_virtualBounds.x < 0) {
+ throw new IllegalArgumentException("Illegal x: " + m_virtualBounds.x);
+ }
+ if (m_virtualBounds.y < 0) {
+ throw new IllegalArgumentException("Illegal y: " + m_virtualBounds.y);
+ }
+ if (m_virtualBounds.width <= 0) {
+ throw new IllegalArgumentException("Illegal width: " + m_virtualBounds.width);
+ }
+ if (m_virtualBounds.height <= 0) {
+ throw new IllegalArgumentException("Illegal height: " + m_virtualBounds.height);
+ }
+ }
+
+ /**
+ * Returns the computed absolute (canvas) bounds of passed child object,
+ * considering its virtual bounds compared to its parent's (current object)
+ */
+ public Rectangle virtualToRealBounds(Rectangle childsVirtualBounds) {
+ float ox = 0.0f;
+ float oy = 0.0f;
+ float ow = 0.0f;
+ float oh = 0.0f;
+
+ ox = (float) this.getBounds().x + childsVirtualBounds.x
+ * ( (float) this.getBounds().width / (this.getVirtualBounds().width) );
+ oy = (float) this.getBounds().y + childsVirtualBounds.y
+ * ( (float) this.getBounds().height / this.getVirtualBounds().height );
+ ow = ( (float) childsVirtualBounds.width
+ / this.getVirtualBounds().width) * this.getBounds().width;
+ oh = ( (float) childsVirtualBounds.height
+ / this.getVirtualBounds().height) * this.getBounds().height;
+
+ // add margin
+ ox += m_childMargin;
+ oy += m_childMargin;
+ ow -= 2 * m_childMargin;
+ oh -= 2 * m_childMargin;
+
+ // make sure computed width and height are positive
+ ow = (ow > 0) ? ow : 0.0f;
+ oh = (oh > 0) ? oh : 0.0f;
+ return new Rectangle(Math.round(ox), Math.round(oy), Math.round(ow), Math.round(oh));
+ }
+
+
+ /** Add children graphical object in this container. Provided label can be used to later retrieve object */
+ public VirtualBoundsGraphicObject addChildObject(String label, VirtualBoundsGraphicObject obj) {
+ m_childrenObjects.add(obj);
+ m_childrenObjectsMap.put(label, obj);
+ return obj;
+ }
+
+ /** Returns a list of child objects of a given derived class, optionally recursing through child objects */
+ public ArrayList<VirtualBoundsGraphicObject> getChildObjects(Class<?> type, boolean recurse) {
+ ArrayList<VirtualBoundsGraphicObject> objs = new ArrayList<VirtualBoundsGraphicObject>();
+
+ for (VirtualBoundsGraphicObject o : this.getAllObjects(recurse)) {
+ if(type.isInstance(o) ) {
+ objs.add(o);
+ }
+ }
+ return objs;
+ }
+
+ /** Searches recursively for a child object matching a label.
+ Returns null if object is not found */
+ public VirtualBoundsGraphicObject getObject(String label) {
+ return getObject(label, true);
+ }
+
+ /** Searches for a child object matching a label. Recurse flag
+ controls whether the search is recursive. */
+ public VirtualBoundsGraphicObject getObject(String label, boolean recurse) {
+ if (m_childrenObjectsMap.containsKey(label)) {
+ return m_childrenObjectsMap.get(label);
+ }
+ else if (recurse) {
+ for(VirtualBoundsGraphicObject o : m_childrenObjects) {
+ if (o.getObject(label) != null) {
+ return o.getObject(label, true);
+ }
+ }
+ }
+ return null;
+ }
+
+ /** Gets all objects from this container. Optionally recurse to all sub-objects */
+ public ArrayList<VirtualBoundsGraphicObject> getAllObjects(boolean recurse) {
+ ArrayList<VirtualBoundsGraphicObject> list = new ArrayList<VirtualBoundsGraphicObject>();
+ for (VirtualBoundsGraphicObject o : m_childrenObjects) {
+ list.add(o);
+ if (recurse) {
+ list.addAll(o.getAllObjects(recurse));
+ }
+ }
+ return list;
+ }
+
+ /** Returns a list of selectable objects */
+ public List<VirtualBoundsGraphicObject> getSelectableObjects() {
+ List<VirtualBoundsGraphicObject> list = new ArrayList<VirtualBoundsGraphicObject>();
+ for (VirtualBoundsGraphicObject o : m_childrenObjects) {
+ if (o.isSelectable()) {
+ list.add(o);
+ }
+ list.addAll(o.getSelectableObjects());
+ }
+ return list;
+ }
+
+ /**
+ * Returns whether an immediate child of current object reports
+ * having decorations to display
+ */
+ public boolean hasChildrenWithDecorations() {
+ for (VirtualBoundsGraphicObject o : getAllObjects(false)) {
+ if (o.hasDecorations()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ // --- paint methods ---
+
+ /**
+ * Invoked to allow element to paint itself on the viewer canvas
+ * Also paints any children objects(s)
+ */
+ @Override
+ public void paint(GC gc, boolean decorations) {
+ // 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);
+ }
+
+ if (!decorations) {
+ // Paint the object.
+ if (isVisible()) {
+ paintContent(gc);
+ }
+ }
+ else {
+ // Paint decorations
+ if (isVisible() && hasDecorations()) {
+ paintDecorations(gc);
+ }
+ }
+
+ // recursively paint children objects
+ if (m_childrenObjects != null) {
+ for (VirtualBoundsGraphicObject o : m_childrenObjects) {
+ o.paint(gc, decorations);
+ }
+ }
+
+ // Restore old state.
+ if (m_foreground != null && oldForeground != null)
+ gc.setForeground(oldForeground);
+ if (m_background != null && oldBackground != null)
+ gc.setBackground(oldBackground);
+ }
+
+ /**
+ * Invoked to allow element to paint itself on the viewer canvas.
+ */
+ @Override
+ public void paintContent(GC gc) {
+ if (m_drawContainerBounds) {
+ if (isSelected() && m_selectedColor != null) {
+ gc.setForeground(m_selectedColor);
+ }
+ else {
+ gc.setForeground(m_foreground);
+ }
+ gc.setBackground(m_background);
+ gc.fillRectangle(m_bounds);
+ super.paintContent(gc);
+ }
+ }
+
+ /**
+ * Recursively checks if children objects have decorations to draw.
+ * If overridden in a derived type, this behavior should be preserved
+ * to ensure that children's decorations are drawn.
+ */
+ @Override
+ public boolean hasDecorations() {
+ return hasChildrenWithDecorations();
+ }
+}

Back to the top