Skip to content

Commit

Permalink
Added new Figure Container to serve as light weight drawing container
Browse files Browse the repository at this point in the history
Using pure Figure just as layout container for other figures is very
heavy weight as the graphics state is saved and restored very often. For
pure layout containers this would not be necessary. This new figure can
help to reduce memory footprint and drawing performance for these cases.
  • Loading branch information
azoitl authored and ptziegler committed Apr 2, 2024
1 parent 121f906 commit 5c1bcd4
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 11 deletions.
47 changes: 47 additions & 0 deletions org.eclipse.draw2d/src/org/eclipse/draw2d/Container.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*******************************************************************************
* Copyright (c) 2024 Johannes Kepler University Linz
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Alois Zoitl - initial API and implementation
*******************************************************************************/

package org.eclipse.draw2d;

/**
* Lightweight Container which just draws the children according to the given
* layout.
*
* This Container does not maintain any graphics state and delegates that to its
* children. This can save memory and increase drawing performance for larger
* graphs with deep nested figures.
*
* A Container can not have any border and does not draw any background.
*
* This class is currently in development its API may
* change: @noreference, @noextend and @noinstantiate
*
* @since 3.16
*/
public class Container extends Figure {

public Container(LayoutManager manager) {
setLayoutManager(manager);
}

@Override
public final void paint(Graphics graphics) {
getChildren().stream().filter(IFigure::isVisible).forEach(child -> child.paint(graphics));
}

@Override
public final void setLayoutManager(LayoutManager manager) {
super.setLayoutManager(manager);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*******************************************************************************/
package org.eclipse.gef.examples.flow.figures;

import org.eclipse.draw2d.Container;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Dimension;
Expand All @@ -30,8 +31,7 @@ public class SubgraphFigure extends Figure {
IFigure header;

public SubgraphFigure(IFigure header, IFigure footer) {
contents = new Figure();
contents.setLayoutManager(new DummyLayout());
contents = new Container(new DummyLayout());
add(contents);
add(this.header = header);
add(this.footer = footer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

import java.util.Map;

import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.Container;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.draw2d.graph.CompoundDirectedGraph;
Expand Down Expand Up @@ -72,10 +72,11 @@ protected void createEditPolicies() {

@Override
protected IFigure createFigure() {
Figure f = new Figure() {
return new Container(new GraphLayoutManager(this)) {
@Override
public void setBounds(Rectangle rect) {
int x = bounds.x, y = bounds.y;
int x = bounds.x;
int y = bounds.y;

boolean resize = (rect.width != bounds.width) || (rect.height != bounds.height);
boolean translate = (rect.x != x) || (rect.y != y);
Expand All @@ -96,8 +97,6 @@ public void setBounds(Rectangle rect) {
}
}
};
f.setLayoutManager(new GraphLayoutManager(this));
return f;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.eclipse.draw2d.ChangeListener;
import org.eclipse.draw2d.Clickable;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Container;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
Expand Down Expand Up @@ -161,7 +162,7 @@ private void checkActiveEntrySync() {
@Override
public IFigure createFigure() {

Figure figure = new Figure() {
Figure figure = new Container(new BorderLayout()) {
@Override
public Dimension getPreferredSize(int wHint, int hHint) {
if (PaletteStackEditPart.this.getChildren().isEmpty()) {
Expand All @@ -170,15 +171,13 @@ public Dimension getPreferredSize(int wHint, int hHint) {
return super.getPreferredSize(wHint, hHint);
}
};
figure.setLayoutManager(new BorderLayout());

contentsFigure = new Figure();
StackLayout stackLayout = new StackLayout();
// make it so the stack layout does not allow the invisible figures to
// contribute
// to its bounds
stackLayout.setObserveVisibility(true);
contentsFigure.setLayoutManager(stackLayout);
contentsFigure = new Container(stackLayout);
figure.add(contentsFigure, BorderLayout.CENTER);

arrowFigure = new RolloverArrow();
Expand Down

4 comments on commit 5c1bcd4

@ptziegler
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@azoitl

Something I noticed while playing around with this figure:

Because Container overwrites the paint() method, any border that is set to this figure isn't drawn. However, the insets of the border are still taken into consideration when doing the layout. This leads to "ghost" borders where they shouldn't be any.

When using Container (with border):
image

When using Figure (without border):
image

Because the Container doesn't support borders, my expectation would've been for both figures to look the same.

@ptziegler
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A similar issue shows up for the setOpaque() method. Because the background is never painted, those figures are inherently transparent.

@azoitl
Copy link
Contributor Author

@azoitl azoitl commented on 5c1bcd4 May 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ptziegler that are two good points where I agree with you that the Container should definitly ignore. Should we create a dedicated issue to collect these items? I guess it makes sense that I review a second time Figure and check what elements should be ignored or forbidden.

@ptziegler
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@azoitl I've created #441

Please sign in to comment.