mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-23 16:23:52 +02:00
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>
This commit is contained in:
parent
8e871b492f
commit
620def4c62
3 changed files with 556 additions and 0 deletions
|
@ -12,6 +12,7 @@ Require-Bundle: org.eclipse.core.runtime,
|
|||
org.eclipse.debug.core,
|
||||
org.eclipse.swt,
|
||||
org.eclipse.cdt.launch;bundle-version="6.1.0",
|
||||
org.eclipse.cdt.visualizer.ui,
|
||||
org.eclipse.cdt.gdb;bundle-version="7.0.0"
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 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.tests.dsf.gdb.tests;
|
||||
|
||||
import org.eclipse.cdt.visualizer.ui.canvas.VirtualBoundsGraphicObject;
|
||||
import org.eclipse.swt.graphics.Rectangle;
|
||||
import org.junit.Test;
|
||||
|
||||
public class VisualizerVirtualBoundsGraphicObjectTest {
|
||||
|
||||
|
||||
// testcases
|
||||
|
||||
/**
|
||||
* Test that VirtualBoundsGraphicObject scale correctly.
|
||||
* To do that create a hierarchy of graphical object using virtual coordinates
|
||||
* and sizes (bounds). Then set the real, pixel-bounds for the outer-most object.
|
||||
* Verify that child objects end-up with expected pixel bounds.
|
||||
*
|
||||
* Also test retrieval of child objects.
|
||||
*/
|
||||
@Test
|
||||
public void testVirtualBoundsGraphicObjectRelativeSizingAndRetrieval() throws Exception {
|
||||
|
||||
// we create the graphical objects with no margin, so as to make the sizes
|
||||
// easier to predict / understand, for this test
|
||||
VirtualBoundsGraphicObject containerA = new VirtualBoundsGraphicObject(true, 0);
|
||||
VirtualBoundsGraphicObject containerB = new VirtualBoundsGraphicObject(true, 0);
|
||||
VirtualBoundsGraphicObject containerC = new VirtualBoundsGraphicObject(true, 0);
|
||||
VirtualBoundsGraphicObject containerD = new VirtualBoundsGraphicObject(true, 0);
|
||||
VirtualBoundsGraphicObject containerE = new VirtualBoundsGraphicObject(true, 0);
|
||||
VirtualBoundsGraphicObject containerF = new VirtualBoundsGraphicObject(true, 0);
|
||||
|
||||
// Add B within A
|
||||
containerA.addChildObject("B", containerB);
|
||||
|
||||
// A - The outer-most container - is a virtual square of size 10x10
|
||||
containerA.setVirtualBounds(new Rectangle(0, 0, 10, 10));
|
||||
// Relative to A, B starts at (1,1) and is of size 8x8
|
||||
containerB.setVirtualBounds(new Rectangle(1, 1, 8, 8));
|
||||
|
||||
// Add C, D and E within B
|
||||
containerB.addChildObject("C", containerC);
|
||||
containerB.addChildObject("D", containerD);
|
||||
containerB.addChildObject("E", containerE);
|
||||
|
||||
// Relative to B, C starts at (3,2) and is of size 2x2
|
||||
containerC.setVirtualBounds(new Rectangle(3, 2, 2, 2));
|
||||
// Relative to B, D starts at (3,5) and is of size 2x2
|
||||
containerD.setVirtualBounds(new Rectangle(3, 5, 2, 2));
|
||||
// Relative to B, E starts at (6,1) and is of size 1x6
|
||||
containerE.setVirtualBounds(new Rectangle(6, 1, 1, 6));
|
||||
|
||||
// Add F within C
|
||||
containerC.addChildObject("F", containerF);
|
||||
|
||||
// Relative to C, F starts at (1,1) and is of size 1x1
|
||||
containerF.setVirtualBounds(new Rectangle(1, 1, 1, 1));
|
||||
|
||||
// Define the real pixel bounds of the outer-most container -
|
||||
// the pixel coordinates of all children objects will be
|
||||
// computed recursively
|
||||
containerA.setBounds(100, 50, 100, 100);
|
||||
|
||||
// check computed bounds for containerA
|
||||
org.junit.Assert.assertEquals(100, containerA.getBounds().x);
|
||||
org.junit.Assert.assertEquals(50, containerA.getBounds().y);
|
||||
org.junit.Assert.assertEquals(100, containerA.getBounds().width);
|
||||
org.junit.Assert.assertEquals(100, containerA.getBounds().height);
|
||||
|
||||
// check computed bounds for containerB
|
||||
org.junit.Assert.assertEquals(110, containerB.getBounds().x);
|
||||
org.junit.Assert.assertEquals(60, containerB.getBounds().y);
|
||||
org.junit.Assert.assertEquals(80, containerB.getBounds().width);
|
||||
org.junit.Assert.assertEquals(80, containerB.getBounds().height);
|
||||
|
||||
// check computed bounds for containerC
|
||||
org.junit.Assert.assertEquals(140, containerC.getBounds().x);
|
||||
org.junit.Assert.assertEquals(80, containerC.getBounds().y);
|
||||
org.junit.Assert.assertEquals(20, containerC.getBounds().width);
|
||||
org.junit.Assert.assertEquals(20, containerC.getBounds().height);
|
||||
|
||||
// check computed bounds for containerD
|
||||
org.junit.Assert.assertEquals(140, containerD.getBounds().x);
|
||||
org.junit.Assert.assertEquals(110, containerD.getBounds().y);
|
||||
org.junit.Assert.assertEquals(20, containerD.getBounds().width);
|
||||
org.junit.Assert.assertEquals(20, containerD.getBounds().height);
|
||||
|
||||
// check computed bounds for containerE
|
||||
org.junit.Assert.assertEquals(170, containerE.getBounds().x);
|
||||
org.junit.Assert.assertEquals(70, containerE.getBounds().y);
|
||||
org.junit.Assert.assertEquals(10, containerE.getBounds().width);
|
||||
org.junit.Assert.assertEquals(60, containerE.getBounds().height);
|
||||
|
||||
// check computed bounds for containerF
|
||||
org.junit.Assert.assertEquals(150, containerF.getBounds().x);
|
||||
org.junit.Assert.assertEquals(90, containerF.getBounds().y);
|
||||
org.junit.Assert.assertEquals(10, containerF.getBounds().width);
|
||||
org.junit.Assert.assertEquals(10, containerF.getBounds().height);
|
||||
|
||||
|
||||
// check recursive object retrieval returns expected number of child objects, for A
|
||||
org.junit.Assert.assertEquals(5, containerA.getAllObjects(true).size());
|
||||
|
||||
// check recursive object retrieval returns expected number of child objects, for B
|
||||
org.junit.Assert.assertEquals(4, containerB.getAllObjects(true).size());
|
||||
|
||||
// check non-recursive object retrieval returns expected number of (1st level) child objects, for A
|
||||
org.junit.Assert.assertEquals(1, containerA.getAllObjects(false).size());
|
||||
|
||||
// check object retrieval returns expected number of "selectable" child objects, for C
|
||||
org.junit.Assert.assertEquals(1, containerC.getSelectableObjects().size());
|
||||
|
||||
// check specific children-object retrieval
|
||||
VirtualBoundsGraphicObject obj = containerA.getObject("D");
|
||||
org.junit.Assert.assertEquals(containerD, obj);
|
||||
|
||||
// check another specific object retrieval
|
||||
obj = containerC.getObject("F");
|
||||
org.junit.Assert.assertEquals(containerF, obj);
|
||||
|
||||
// Check the retrieval of a non-existing object
|
||||
obj = containerC.getObject("blablabla");
|
||||
org.junit.Assert.assertEquals(null, obj);
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue