2011-08-08 17:48:29 +00:00
|
|
|
/* ========================================================================
|
|
|
|
* PlantUML : a free UML diagram generator
|
|
|
|
* ========================================================================
|
|
|
|
*
|
2019-01-16 18:34:41 +00:00
|
|
|
* (C) Copyright 2009-2020, Arnaud Roques
|
2011-08-08 17:48:29 +00:00
|
|
|
*
|
2016-03-06 16:47:34 +00:00
|
|
|
* Project Info: http://plantuml.com
|
2011-08-08 17:48:29 +00:00
|
|
|
*
|
2017-03-15 19:13:31 +00:00
|
|
|
* If you like this project or if you find it useful, you can support us at:
|
|
|
|
*
|
|
|
|
* http://plantuml.com/patreon (only 1$ per month!)
|
|
|
|
* http://plantuml.com/paypal
|
|
|
|
*
|
2011-08-08 17:48:29 +00:00
|
|
|
* This file is part of PlantUML.
|
|
|
|
*
|
|
|
|
* PlantUML is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* PlantUML distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
2013-12-10 19:36:50 +00:00
|
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
2011-08-08 17:48:29 +00:00
|
|
|
* License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
|
|
|
* USA.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Original Author: Arnaud Roques
|
2020-05-07 14:12:08 +00:00
|
|
|
* Contribution : Hisashi Miyashita
|
2011-08-08 17:48:29 +00:00
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
package net.sourceforge.plantuml.svek;
|
|
|
|
|
|
|
|
import java.awt.geom.Dimension2D;
|
2013-12-10 19:36:50 +00:00
|
|
|
import java.awt.geom.Point2D;
|
2011-08-08 17:48:29 +00:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.Collections;
|
2016-04-04 19:05:10 +00:00
|
|
|
import java.util.EnumSet;
|
2011-08-08 17:48:29 +00:00
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.HashSet;
|
|
|
|
import java.util.Iterator;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
2021-05-09 21:14:40 +00:00
|
|
|
import java.util.Objects;
|
2011-08-08 17:48:29 +00:00
|
|
|
import java.util.Set;
|
|
|
|
|
2018-07-27 21:56:46 +00:00
|
|
|
import net.sourceforge.plantuml.AlignmentParam;
|
2011-08-08 17:48:29 +00:00
|
|
|
import net.sourceforge.plantuml.ColorParam;
|
|
|
|
import net.sourceforge.plantuml.Dimension2DDouble;
|
2013-12-10 19:36:50 +00:00
|
|
|
import net.sourceforge.plantuml.FontParam;
|
|
|
|
import net.sourceforge.plantuml.ISkinParam;
|
2015-09-28 20:42:17 +00:00
|
|
|
import net.sourceforge.plantuml.SkinParamUtils;
|
2011-08-08 17:48:29 +00:00
|
|
|
import net.sourceforge.plantuml.UmlDiagramType;
|
2013-12-10 19:36:50 +00:00
|
|
|
import net.sourceforge.plantuml.Url;
|
2020-12-01 21:39:27 +00:00
|
|
|
import net.sourceforge.plantuml.UseStyle;
|
2013-12-10 19:36:50 +00:00
|
|
|
import net.sourceforge.plantuml.cucadiagram.EntityPosition;
|
|
|
|
import net.sourceforge.plantuml.cucadiagram.EntityUtils;
|
2011-09-08 10:42:27 +00:00
|
|
|
import net.sourceforge.plantuml.cucadiagram.IEntity;
|
2013-12-10 19:36:50 +00:00
|
|
|
import net.sourceforge.plantuml.cucadiagram.IGroup;
|
|
|
|
import net.sourceforge.plantuml.cucadiagram.Stereotype;
|
2015-04-07 18:18:37 +00:00
|
|
|
import net.sourceforge.plantuml.cucadiagram.dot.GraphvizVersion;
|
2017-12-11 21:02:10 +00:00
|
|
|
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
|
2011-09-08 10:42:27 +00:00
|
|
|
import net.sourceforge.plantuml.graphic.StringBounder;
|
2011-08-08 17:48:29 +00:00
|
|
|
import net.sourceforge.plantuml.graphic.TextBlock;
|
2015-04-07 18:18:37 +00:00
|
|
|
import net.sourceforge.plantuml.graphic.USymbol;
|
2015-09-28 20:42:17 +00:00
|
|
|
import net.sourceforge.plantuml.graphic.color.ColorType;
|
2017-12-11 21:02:10 +00:00
|
|
|
import net.sourceforge.plantuml.graphic.color.Colors;
|
2011-09-08 10:42:27 +00:00
|
|
|
import net.sourceforge.plantuml.posimo.Moveable;
|
2011-08-08 17:48:29 +00:00
|
|
|
import net.sourceforge.plantuml.skin.rose.Rose;
|
2019-08-26 17:07:21 +00:00
|
|
|
import net.sourceforge.plantuml.style.PName;
|
|
|
|
import net.sourceforge.plantuml.style.SName;
|
|
|
|
import net.sourceforge.plantuml.style.Style;
|
|
|
|
import net.sourceforge.plantuml.style.StyleSignature;
|
2013-12-10 19:36:50 +00:00
|
|
|
import net.sourceforge.plantuml.svek.image.EntityImageState;
|
2016-07-25 19:25:28 +00:00
|
|
|
import net.sourceforge.plantuml.ugraphic.UComment;
|
2011-08-08 17:48:29 +00:00
|
|
|
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
2011-09-08 10:42:27 +00:00
|
|
|
import net.sourceforge.plantuml.ugraphic.ULine;
|
2011-08-08 17:48:29 +00:00
|
|
|
import net.sourceforge.plantuml.ugraphic.URectangle;
|
|
|
|
import net.sourceforge.plantuml.ugraphic.UStroke;
|
2013-12-10 19:36:50 +00:00
|
|
|
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
2020-03-18 10:50:02 +00:00
|
|
|
import net.sourceforge.plantuml.ugraphic.color.HColor;
|
|
|
|
import net.sourceforge.plantuml.ugraphic.color.HColorBackground;
|
2020-04-26 18:31:41 +00:00
|
|
|
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
|
2015-04-07 18:18:37 +00:00
|
|
|
import net.sourceforge.plantuml.utils.UniqueSequence;
|
2011-08-08 17:48:29 +00:00
|
|
|
|
2011-09-08 10:42:27 +00:00
|
|
|
public class Cluster implements Moveable {
|
2011-08-08 17:48:29 +00:00
|
|
|
|
2020-05-07 14:12:08 +00:00
|
|
|
private static final String RANK_SAME = "same";
|
|
|
|
private static final String RANK_SOURCE = "source";
|
|
|
|
private static final String RANK_SINK = "sink";
|
|
|
|
private static final String ID_EE = "ee";
|
|
|
|
public final static String CENTER_ID = "za";
|
|
|
|
|
2020-02-18 21:24:31 +00:00
|
|
|
private final Cluster parentCluster;
|
2013-12-10 19:36:50 +00:00
|
|
|
private final IGroup group;
|
2021-05-14 08:42:57 +00:00
|
|
|
private final List<SvekNode> nodes = new ArrayList<>();
|
|
|
|
private final List<Cluster> children = new ArrayList<>();
|
2011-08-08 17:48:29 +00:00
|
|
|
private final int color;
|
|
|
|
private final int colorTitle;
|
2013-12-10 19:36:50 +00:00
|
|
|
private final ISkinParam skinParam;
|
2011-08-08 17:48:29 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
private int titleAndAttributeWidth;
|
|
|
|
private int titleAndAttributeHeight;
|
|
|
|
private TextBlock ztitle;
|
|
|
|
private TextBlock zstereo;
|
2011-09-08 10:42:27 +00:00
|
|
|
|
|
|
|
private double xTitle;
|
|
|
|
private double yTitle;
|
|
|
|
|
|
|
|
private double minX;
|
|
|
|
private double minY;
|
|
|
|
private double maxX;
|
|
|
|
private double maxY;
|
|
|
|
|
|
|
|
public void moveSvek(double deltaX, double deltaY) {
|
|
|
|
this.xTitle += deltaX;
|
|
|
|
this.minX += deltaX;
|
|
|
|
this.maxX += deltaX;
|
|
|
|
this.yTitle += deltaY;
|
|
|
|
this.minY += deltaY;
|
|
|
|
this.maxY += deltaY;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-05-07 14:12:08 +00:00
|
|
|
private Set<EntityPosition> entityPositionsExceptNormal() {
|
|
|
|
final Set<EntityPosition> result = EnumSet.<EntityPosition>noneOf(EntityPosition.class);
|
2022-02-01 20:21:45 +00:00
|
|
|
for (SvekNode sh : nodes)
|
|
|
|
if (sh.getEntityPosition() != EntityPosition.NORMAL)
|
2020-05-07 14:12:08 +00:00
|
|
|
result.add(sh.getEntityPosition());
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2020-05-07 14:12:08 +00:00
|
|
|
return Collections.unmodifiableSet(result);
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
public Cluster(ColorSequence colorSequence, ISkinParam skinParam, IGroup root) {
|
2020-02-18 21:24:31 +00:00
|
|
|
this(null, colorSequence, skinParam, root);
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
2015-04-07 18:18:37 +00:00
|
|
|
private ColorParam border;
|
|
|
|
|
2020-02-18 21:24:31 +00:00
|
|
|
private Cluster(Cluster parentCluster, ColorSequence colorSequence, ISkinParam skinParam, IGroup group) {
|
2022-02-01 20:21:45 +00:00
|
|
|
if (group == null)
|
2013-12-10 19:36:50 +00:00
|
|
|
throw new IllegalStateException();
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2020-02-18 21:24:31 +00:00
|
|
|
this.parentCluster = parentCluster;
|
2011-08-08 17:48:29 +00:00
|
|
|
this.group = group;
|
2022-02-01 20:21:45 +00:00
|
|
|
if (group.getUSymbol() != null)
|
2015-04-07 18:18:37 +00:00
|
|
|
border = group.getUSymbol().getColorParamBorder();
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2011-08-08 17:48:29 +00:00
|
|
|
this.color = colorSequence.getValue();
|
|
|
|
this.colorTitle = colorSequence.getValue();
|
2021-11-15 18:27:27 +00:00
|
|
|
this.skinParam = group.getColors().mute(skinParam);
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
return super.toString() + " " + group;
|
|
|
|
}
|
|
|
|
|
2020-02-18 21:24:31 +00:00
|
|
|
public final Cluster getParentCluster() {
|
|
|
|
return parentCluster;
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
2021-02-02 10:12:15 +00:00
|
|
|
public void addNode(SvekNode node) {
|
2021-05-14 08:42:57 +00:00
|
|
|
this.nodes.add(Objects.requireNonNull(node));
|
2020-02-18 21:24:31 +00:00
|
|
|
node.setCluster(this);
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
2021-02-02 10:12:15 +00:00
|
|
|
public final List<SvekNode> getNodes() {
|
2020-02-18 21:24:31 +00:00
|
|
|
return Collections.unmodifiableList(nodes);
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
2021-04-20 20:19:49 +00:00
|
|
|
private List<SvekNode> getNodesOrderedTop(Collection<SvekLine> lines) {
|
2021-05-14 08:42:57 +00:00
|
|
|
final List<SvekNode> firsts = new ArrayList<>();
|
|
|
|
final Set<String> tops = new HashSet<>();
|
2021-02-02 10:12:15 +00:00
|
|
|
final Map<String, SvekNode> shs = new HashMap<String, SvekNode>();
|
2020-02-18 21:24:31 +00:00
|
|
|
|
2021-02-02 10:12:15 +00:00
|
|
|
for (final Iterator<SvekNode> it = nodes.iterator(); it.hasNext();) {
|
|
|
|
final SvekNode node = it.next();
|
2020-02-18 21:24:31 +00:00
|
|
|
shs.put(node.getUid(), node);
|
|
|
|
if (node.isTop() && node.getEntityPosition() == EntityPosition.NORMAL) {
|
|
|
|
firsts.add(node);
|
|
|
|
tops.add(node.getUid());
|
2013-12-10 19:36:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 20:19:49 +00:00
|
|
|
for (SvekLine l : lines) {
|
2016-07-04 19:06:50 +00:00
|
|
|
if (tops.contains(l.getStartUidPrefix())) {
|
2021-02-02 10:12:15 +00:00
|
|
|
final SvekNode sh = shs.get(l.getEndUidPrefix());
|
2022-02-01 20:21:45 +00:00
|
|
|
if (sh != null && sh.getEntityPosition() == EntityPosition.NORMAL)
|
2013-12-10 19:36:50 +00:00
|
|
|
firsts.add(0, sh);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (l.isInverted()) {
|
2021-02-02 10:12:15 +00:00
|
|
|
final SvekNode sh = shs.get(l.getStartUidPrefix());
|
2022-02-01 20:21:45 +00:00
|
|
|
if (sh != null && sh.getEntityPosition() == EntityPosition.NORMAL)
|
2013-12-10 19:36:50 +00:00
|
|
|
firsts.add(0, sh);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return firsts;
|
|
|
|
}
|
|
|
|
|
2021-04-20 20:19:49 +00:00
|
|
|
private List<SvekNode> getNodesOrderedWithoutTop(Collection<SvekLine> lines) {
|
2021-05-14 08:42:57 +00:00
|
|
|
final List<SvekNode> all = new ArrayList<>(nodes);
|
|
|
|
final Set<String> tops = new HashSet<>();
|
2021-02-02 10:12:15 +00:00
|
|
|
final Map<String, SvekNode> shs = new HashMap<String, SvekNode>();
|
2013-12-10 19:36:50 +00:00
|
|
|
|
2021-02-02 10:12:15 +00:00
|
|
|
for (final Iterator<SvekNode> it = all.iterator(); it.hasNext();) {
|
|
|
|
final SvekNode sh = it.next();
|
2013-12-10 19:36:50 +00:00
|
|
|
if (sh.getEntityPosition() != EntityPosition.NORMAL) {
|
|
|
|
it.remove();
|
|
|
|
continue;
|
|
|
|
}
|
2011-08-08 17:48:29 +00:00
|
|
|
shs.put(sh.getUid(), sh);
|
|
|
|
if (sh.isTop()) {
|
|
|
|
tops.add(sh.getUid());
|
|
|
|
it.remove();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 20:19:49 +00:00
|
|
|
for (SvekLine l : lines) {
|
2016-07-04 19:06:50 +00:00
|
|
|
if (tops.contains(l.getStartUidPrefix())) {
|
2021-02-02 10:12:15 +00:00
|
|
|
final SvekNode sh = shs.get(l.getEndUidPrefix());
|
2022-02-01 20:21:45 +00:00
|
|
|
if (sh != null)
|
2013-12-10 19:36:50 +00:00
|
|
|
all.remove(sh);
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
2013-12-10 19:36:50 +00:00
|
|
|
|
2011-08-08 17:48:29 +00:00
|
|
|
if (l.isInverted()) {
|
2021-02-02 10:12:15 +00:00
|
|
|
final SvekNode sh = shs.get(l.getStartUidPrefix());
|
2022-02-01 20:21:45 +00:00
|
|
|
if (sh != null)
|
2013-12-10 19:36:50 +00:00
|
|
|
all.remove(sh);
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return all;
|
|
|
|
}
|
|
|
|
|
|
|
|
public final List<Cluster> getChildren() {
|
|
|
|
return Collections.unmodifiableList(children);
|
|
|
|
}
|
|
|
|
|
2020-02-18 21:24:31 +00:00
|
|
|
public Cluster createChild(int titleAndAttributeWidth, int titleAndAttributeHeight, TextBlock title,
|
|
|
|
TextBlock stereo, ColorSequence colorSequence, ISkinParam skinParam, IGroup g) {
|
|
|
|
final Cluster child = new Cluster(this, colorSequence, skinParam, g);
|
2013-12-10 19:36:50 +00:00
|
|
|
child.titleAndAttributeWidth = titleAndAttributeWidth;
|
|
|
|
child.titleAndAttributeHeight = titleAndAttributeHeight;
|
|
|
|
child.ztitle = title;
|
|
|
|
child.zstereo = stereo;
|
2011-08-08 17:48:29 +00:00
|
|
|
this.children.add(child);
|
|
|
|
return child;
|
|
|
|
}
|
|
|
|
|
2020-02-18 21:24:31 +00:00
|
|
|
public final Set<IGroup> getGroups() {
|
|
|
|
return Collections.singleton(group);
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
public final int getTitleAndAttributeWidth() {
|
|
|
|
return titleAndAttributeWidth;
|
|
|
|
}
|
|
|
|
|
|
|
|
public final int getTitleAndAttributeHeight() {
|
|
|
|
return titleAndAttributeHeight;
|
|
|
|
}
|
|
|
|
|
|
|
|
public double getWidth() {
|
|
|
|
return maxX - minX;
|
|
|
|
}
|
|
|
|
|
|
|
|
public double getMinX() {
|
|
|
|
return minX;
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
public ClusterPosition getClusterPosition() {
|
|
|
|
return new ClusterPosition(minX, minY, maxX, maxY);
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void setTitlePosition(double x, double y) {
|
|
|
|
this.xTitle = x;
|
|
|
|
this.yTitle = y;
|
|
|
|
}
|
|
|
|
|
2020-03-18 10:50:02 +00:00
|
|
|
private static HColor getColor(ColorParam colorParam, ISkinParam skinParam, Stereotype stereotype) {
|
2019-01-16 18:34:41 +00:00
|
|
|
return SkinParamUtils.getColor(skinParam, stereotype, colorParam);
|
2015-04-07 18:18:37 +00:00
|
|
|
}
|
|
|
|
|
2022-02-01 20:21:45 +00:00
|
|
|
static public StyleSignature getDefaultStyleDefinition(SName diagramStyleName, USymbol symbol) {
|
|
|
|
if (diagramStyleName == SName.stateDiagram)
|
2021-09-19 17:05:24 +00:00
|
|
|
return StyleSignature.of(SName.root, SName.element, SName.stateDiagram, SName.state, SName.group);
|
2022-02-01 20:21:45 +00:00
|
|
|
if (symbol == null)
|
|
|
|
return StyleSignature.of(SName.root, SName.element, diagramStyleName, SName.group);
|
|
|
|
return StyleSignature.of(SName.root, SName.element, diagramStyleName, SName.group, symbol.getSName());
|
2019-08-26 17:07:21 +00:00
|
|
|
}
|
|
|
|
|
2021-09-19 17:05:24 +00:00
|
|
|
static public StyleSignature getDefaultStyleDefinitionStateGroup(Stereotype stereotype) {
|
|
|
|
if (stereotype == null)
|
|
|
|
return StyleSignature.of(SName.root, SName.element, SName.stateDiagram, SName.state, SName.group);
|
|
|
|
return StyleSignature.of(SName.root, SName.element, SName.stateDiagram, SName.state, SName.group)
|
|
|
|
.with(stereotype);
|
|
|
|
}
|
|
|
|
|
2020-06-14 20:35:42 +00:00
|
|
|
public void drawU(UGraphic ug, UStroke strokeForState, UmlDiagramType umlDiagramType, ISkinParam skinParam2) {
|
2022-02-01 20:21:45 +00:00
|
|
|
if (group.isHidden())
|
2018-03-09 21:37:34 +00:00
|
|
|
return;
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2019-12-10 21:45:49 +00:00
|
|
|
final String fullName = group.getCodeGetName();
|
2022-02-01 20:21:45 +00:00
|
|
|
if (fullName.startsWith("##") == false)
|
2017-12-11 21:02:10 +00:00
|
|
|
ug.draw(new UComment("cluster " + fullName));
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2020-03-18 10:50:02 +00:00
|
|
|
HColor borderColor;
|
2021-09-19 17:05:24 +00:00
|
|
|
Style style = null;
|
2021-10-17 09:02:33 +00:00
|
|
|
final double rounded;
|
|
|
|
final double shadowing;
|
2020-12-01 21:39:27 +00:00
|
|
|
if (UseStyle.useBetaStyle()) {
|
2022-02-01 20:21:45 +00:00
|
|
|
final USymbol uSymbol = group.getUSymbol() == null ? USymbol.PACKAGE : group.getUSymbol();
|
|
|
|
final StyleSignature tmp = getDefaultStyleDefinition(umlDiagramType.getStyleName(), uSymbol);
|
|
|
|
style = tmp.with(group.getStereotype()).getMergedStyle(skinParam.getCurrentStyleBuilder());
|
2021-10-17 09:02:33 +00:00
|
|
|
shadowing = style.value(PName.Shadowing).asDouble();
|
2022-02-01 20:21:45 +00:00
|
|
|
if (group.getColors().getColor(ColorType.LINE) != null)
|
|
|
|
borderColor = group.getColors().getColor(ColorType.LINE);
|
|
|
|
else
|
|
|
|
borderColor = style.value(PName.LineColor).asColor(skinParam2.getThemeStyle(),
|
|
|
|
skinParam2.getIHtmlColorSet());
|
2021-10-17 09:02:33 +00:00
|
|
|
if (umlDiagramType == UmlDiagramType.STATE)
|
|
|
|
rounded = style.value(PName.RoundCorner).asDouble();
|
|
|
|
else
|
|
|
|
rounded = IEntityImage.CORNER;
|
2019-08-26 17:07:21 +00:00
|
|
|
|
2015-04-07 18:18:37 +00:00
|
|
|
} else {
|
2022-02-01 20:21:45 +00:00
|
|
|
if (group.getUSymbol() == null)
|
2021-10-17 09:02:33 +00:00
|
|
|
shadowing = skinParam2.shadowing2(group.getStereotype(), USymbol.PACKAGE.getSkinParameter()) ? 3 : 0;
|
2022-02-01 20:21:45 +00:00
|
|
|
else
|
2021-10-17 09:02:33 +00:00
|
|
|
shadowing = skinParam2.shadowing2(group.getStereotype(), group.getUSymbol().getSkinParameter()) ? 3 : 0;
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2021-10-17 09:02:33 +00:00
|
|
|
rounded = IEntityImage.CORNER;
|
2022-02-01 20:21:45 +00:00
|
|
|
if (umlDiagramType == UmlDiagramType.STATE)
|
2021-04-20 20:19:49 +00:00
|
|
|
borderColor = getColor(ColorParam.stateBorder, skinParam, group.getStereotype());
|
2022-02-01 20:21:45 +00:00
|
|
|
else if (umlDiagramType == UmlDiagramType.ACTIVITY)
|
2021-04-20 20:19:49 +00:00
|
|
|
borderColor = getColor(ColorParam.packageBorder, skinParam, group.getStereotype());
|
2022-02-01 20:21:45 +00:00
|
|
|
else
|
2021-04-20 20:19:49 +00:00
|
|
|
borderColor = getColor(ColorParam.packageBorder, skinParam, group.getStereotype());
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2015-04-07 18:18:37 +00:00
|
|
|
}
|
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
final Url url = group.getUrl99();
|
2022-02-01 20:21:45 +00:00
|
|
|
if (url != null)
|
2013-12-10 19:36:50 +00:00
|
|
|
ug.startUrl(url);
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
try {
|
2022-02-01 20:21:45 +00:00
|
|
|
if (entityPositionsExceptNormal().size() > 0)
|
2016-03-06 16:47:34 +00:00
|
|
|
manageEntryExitPoint(ug.getStringBounder());
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2016-03-06 16:47:34 +00:00
|
|
|
if (skinParam.useSwimlanes(umlDiagramType)) {
|
|
|
|
drawSwinLinesState(ug, borderColor);
|
2013-12-10 19:36:50 +00:00
|
|
|
return;
|
|
|
|
}
|
2016-03-06 16:47:34 +00:00
|
|
|
final boolean isState = umlDiagramType == UmlDiagramType.STATE;
|
2022-01-26 19:41:21 +00:00
|
|
|
|
|
|
|
if (isState && group.getUSymbol() == null) {
|
2022-02-01 20:21:45 +00:00
|
|
|
if (group.getColors().getSpecificLineStroke() != null)
|
2021-11-15 18:27:27 +00:00
|
|
|
strokeForState = group.getColors().getSpecificLineStroke();
|
2022-02-01 20:21:45 +00:00
|
|
|
|
|
|
|
if (group.getColors().getColor(ColorType.LINE) != null)
|
2021-11-15 18:27:27 +00:00
|
|
|
borderColor = group.getColors().getColor(ColorType.LINE);
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2021-10-17 09:02:33 +00:00
|
|
|
drawUState(ug, borderColor, skinParam2, strokeForState, umlDiagramType, rounded, shadowing);
|
2013-12-10 19:36:50 +00:00
|
|
|
return;
|
|
|
|
}
|
2019-08-26 17:07:21 +00:00
|
|
|
PackageStyle packageStyle = group.getPackageStyle();
|
2022-02-01 20:21:45 +00:00
|
|
|
if (packageStyle == null)
|
2020-06-21 20:31:45 +00:00
|
|
|
packageStyle = skinParam2.packageStyle();
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2015-04-07 18:18:37 +00:00
|
|
|
if (border != null) {
|
2020-03-18 10:50:02 +00:00
|
|
|
final HColor tmp = skinParam2.getHtmlColor(border, group.getStereotype(), false);
|
2022-02-01 20:21:45 +00:00
|
|
|
if (tmp != null)
|
2015-04-07 18:18:37 +00:00
|
|
|
borderColor = tmp;
|
|
|
|
}
|
|
|
|
|
2020-06-14 20:35:42 +00:00
|
|
|
final UStroke stroke;
|
2022-02-01 20:21:45 +00:00
|
|
|
if (UseStyle.useBetaStyle())
|
2021-11-15 18:27:27 +00:00
|
|
|
stroke = getStrokeInternal(group, skinParam2, style);
|
2022-02-01 20:21:45 +00:00
|
|
|
else
|
2021-11-15 18:27:27 +00:00
|
|
|
stroke = getStrokeInternal(group, skinParam2, null);
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2021-09-19 17:05:24 +00:00
|
|
|
HColor backColor = getBackColor(umlDiagramType, style);
|
2022-02-01 20:21:45 +00:00
|
|
|
backColor = getBackColor(backColor, skinParam2, group.getStereotype(), umlDiagramType.getStyleName(),
|
|
|
|
group.getUSymbol());
|
2013-12-10 19:36:50 +00:00
|
|
|
if (ztitle != null || zstereo != null) {
|
2020-02-18 21:24:31 +00:00
|
|
|
final double roundCorner = group.getUSymbol() == null ? 0
|
2021-04-20 20:19:49 +00:00
|
|
|
: group.getUSymbol().getSkinParameter().getRoundCorner(skinParam, group.getStereotype());
|
2016-12-14 21:01:03 +00:00
|
|
|
|
2019-08-26 17:07:21 +00:00
|
|
|
final ClusterDecoration decoration = new ClusterDecoration(packageStyle, group.getUSymbol(), ztitle,
|
2020-06-14 20:35:42 +00:00
|
|
|
zstereo, minX, minY, maxX, maxY, stroke);
|
2019-08-26 17:07:21 +00:00
|
|
|
decoration.drawU(ug, backColor, borderColor, shadowing, roundCorner,
|
2021-06-27 16:50:40 +00:00
|
|
|
skinParam2.getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null, false, null),
|
2019-05-24 19:59:31 +00:00
|
|
|
skinParam2.getStereotypeAlignment());
|
2013-12-10 19:36:50 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
final URectangle rect = new URectangle(maxX - minX, maxY - minY);
|
2019-08-26 17:07:21 +00:00
|
|
|
rect.setDeltaShadow(shadowing);
|
2020-04-19 16:04:39 +00:00
|
|
|
ug = ug.apply(backColor.bg()).apply(borderColor);
|
2013-12-10 19:36:50 +00:00
|
|
|
ug.apply(new UStroke(2)).apply(new UTranslate(minX, minY)).draw(rect);
|
|
|
|
|
|
|
|
} finally {
|
2022-02-01 20:21:45 +00:00
|
|
|
if (url != null)
|
2020-05-17 21:15:50 +00:00
|
|
|
ug.closeUrl();
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
2011-09-08 10:42:27 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
}
|
2011-09-08 10:42:27 +00:00
|
|
|
|
2021-11-15 18:27:27 +00:00
|
|
|
static public UStroke getStrokeInternal(IGroup group, ISkinParam skinParam, Style style) {
|
|
|
|
final Colors colors = group.getColors();
|
2022-02-01 20:21:45 +00:00
|
|
|
if (colors.getSpecificLineStroke() != null)
|
2017-12-11 21:02:10 +00:00
|
|
|
return colors.getSpecificLineStroke();
|
2022-02-01 20:21:45 +00:00
|
|
|
|
|
|
|
if (style != null)
|
2021-11-15 18:27:27 +00:00
|
|
|
return style.getStroke();
|
2022-02-01 20:21:45 +00:00
|
|
|
|
|
|
|
if (group.getUSymbol() != null && group.getUSymbol() != USymbol.PACKAGE)
|
2017-12-11 21:02:10 +00:00
|
|
|
return group.getUSymbol().getSkinParameter().getStroke(skinParam, group.getStereotype());
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2020-06-14 20:35:42 +00:00
|
|
|
return GeneralImageBuilder.getForcedStroke(group.getStereotype(), skinParam);
|
2015-04-07 18:18:37 +00:00
|
|
|
}
|
|
|
|
|
2016-03-06 16:47:34 +00:00
|
|
|
public void manageEntryExitPoint(StringBounder stringBounder) {
|
2021-05-14 08:42:57 +00:00
|
|
|
final Collection<ClusterPosition> insides = new ArrayList<>();
|
|
|
|
final List<Point2D> points = new ArrayList<>();
|
2022-02-01 20:21:45 +00:00
|
|
|
for (SvekNode sh : nodes)
|
|
|
|
if (sh.getEntityPosition() == EntityPosition.NORMAL)
|
2013-12-10 19:36:50 +00:00
|
|
|
insides.add(sh.getClusterPosition());
|
2022-02-01 20:21:45 +00:00
|
|
|
else
|
2013-12-10 19:36:50 +00:00
|
|
|
points.add(sh.getClusterPosition().getPointCenter());
|
2022-02-01 20:21:45 +00:00
|
|
|
|
|
|
|
for (Cluster in : children)
|
2013-12-10 19:36:50 +00:00
|
|
|
insides.add(in.getClusterPosition());
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
final FrontierCalculator frontierCalculator = new FrontierCalculator(getClusterPosition(), insides, points);
|
2022-02-01 20:21:45 +00:00
|
|
|
if (titleAndAttributeHeight > 0 && titleAndAttributeWidth > 0)
|
2013-12-10 19:36:50 +00:00
|
|
|
frontierCalculator.ensureMinWidth(titleAndAttributeWidth + 10);
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
final ClusterPosition forced = frontierCalculator.getSuggestedPosition();
|
|
|
|
xTitle += ((forced.getMinX() - minX) + (forced.getMaxX() - maxX)) / 2;
|
|
|
|
minX = forced.getMinX();
|
|
|
|
minY = forced.getMinY();
|
|
|
|
maxX = forced.getMaxX();
|
|
|
|
maxY = forced.getMaxY();
|
|
|
|
yTitle = minY + IEntityImage.MARGIN;
|
|
|
|
final double widthTitle = ztitle.calculateDimension(stringBounder).getWidth();
|
|
|
|
xTitle = minX + ((maxX - minX - widthTitle) / 2);
|
|
|
|
}
|
|
|
|
|
2020-03-18 10:50:02 +00:00
|
|
|
private void drawSwinLinesState(UGraphic ug, HColor borderColor) {
|
2022-02-01 20:21:45 +00:00
|
|
|
if (ztitle != null)
|
2020-03-18 10:50:02 +00:00
|
|
|
ztitle.drawU(ug.apply(UTranslate.dx(xTitle)));
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2020-03-18 10:50:02 +00:00
|
|
|
final ULine line = ULine.vline(maxY - minY);
|
2020-04-19 16:04:39 +00:00
|
|
|
ug = ug.apply(borderColor);
|
2020-03-18 10:50:02 +00:00
|
|
|
ug.apply(UTranslate.dx(minX)).draw(line);
|
|
|
|
ug.apply(UTranslate.dx(maxX)).draw(line);
|
2013-12-10 19:36:50 +00:00
|
|
|
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
2021-09-19 17:05:24 +00:00
|
|
|
private HColor getColorLegacy(ISkinParam skinParam, ColorParam colorParam, Stereotype stereo) {
|
2019-01-16 18:34:41 +00:00
|
|
|
return new Rose().getHtmlColor(skinParam, stereo, colorParam);
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
2020-03-18 10:50:02 +00:00
|
|
|
private void drawUState(UGraphic ug, HColor borderColor, ISkinParam skinParam2, UStroke stroke,
|
2021-10-17 09:02:33 +00:00
|
|
|
UmlDiagramType umlDiagramType, double rounded, double shadowing) {
|
2011-08-08 17:48:29 +00:00
|
|
|
final Dimension2D total = new Dimension2DDouble(maxX - minX, maxY - minY);
|
2013-12-10 19:36:50 +00:00
|
|
|
final double suppY;
|
2022-02-01 20:21:45 +00:00
|
|
|
if (ztitle == null)
|
2013-12-10 19:36:50 +00:00
|
|
|
suppY = 0;
|
2022-02-01 20:21:45 +00:00
|
|
|
else
|
2013-12-10 19:36:50 +00:00
|
|
|
suppY = ztitle.calculateDimension(ug.getStringBounder()).getHeight() + IEntityImage.MARGIN
|
|
|
|
+ IEntityImage.MARGIN_LINE;
|
|
|
|
|
2021-09-19 17:05:24 +00:00
|
|
|
final Style styleGroup = getDefaultStyleDefinitionStateGroup(group.getStereotype())
|
|
|
|
.getMergedStyle(skinParam.getCurrentStyleBuilder());
|
|
|
|
|
|
|
|
HColor stateBack = getBackColor(umlDiagramType, styleGroup);
|
2022-02-01 20:21:45 +00:00
|
|
|
if (stateBack == null)
|
2021-09-19 17:05:24 +00:00
|
|
|
stateBack = getColorLegacy(skinParam2, ColorParam.stateBackground, group.getStereotype());
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2021-09-19 17:05:24 +00:00
|
|
|
final HColor background = getColorLegacy(skinParam2, ColorParam.background, null);
|
|
|
|
|
|
|
|
// final Style style = getStyle(FontParam.STATE_ATTRIBUTE, skinParam2);
|
|
|
|
|
|
|
|
final TextBlock attribute = GeneralImageBuilder.stateHeader(group, styleGroup, skinParam2);
|
2013-12-10 19:36:50 +00:00
|
|
|
final double attributeHeight = attribute.calculateDimension(ug.getStringBounder()).getHeight();
|
2020-10-12 20:56:58 +00:00
|
|
|
if (total.getWidth() == 0) {
|
|
|
|
System.err.println("Cluster::drawUState issue");
|
|
|
|
return;
|
|
|
|
}
|
2020-02-18 21:24:31 +00:00
|
|
|
final RoundedContainer r = new RoundedContainer(total, suppY,
|
|
|
|
attributeHeight + (attributeHeight > 0 ? IEntityImage.MARGIN : 0), borderColor, stateBack, background,
|
2021-10-17 09:02:33 +00:00
|
|
|
stroke, rounded, shadowing);
|
|
|
|
r.drawU(ug.apply(new UTranslate(minX, minY)));
|
2011-08-08 17:48:29 +00:00
|
|
|
|
2022-02-01 20:21:45 +00:00
|
|
|
if (ztitle != null)
|
2013-12-10 19:36:50 +00:00
|
|
|
ztitle.drawU(ug.apply(new UTranslate(xTitle, yTitle)));
|
2011-08-08 17:48:29 +00:00
|
|
|
|
2022-02-01 20:21:45 +00:00
|
|
|
if (attributeHeight > 0)
|
2020-12-14 18:31:06 +00:00
|
|
|
attribute.drawU(
|
2013-12-10 19:36:50 +00:00
|
|
|
ug.apply(new UTranslate(minX + IEntityImage.MARGIN, minY + suppY + IEntityImage.MARGIN / 2.0)));
|
|
|
|
|
|
|
|
final Stereotype stereotype = group.getStereotype();
|
|
|
|
final boolean withSymbol = stereotype != null && stereotype.isWithOOSymbol();
|
2022-02-01 20:21:45 +00:00
|
|
|
if (withSymbol)
|
2020-04-19 16:04:39 +00:00
|
|
|
EntityImageState.drawSymbol(ug.apply(borderColor), maxX, maxY);
|
2013-12-10 19:36:50 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2011-08-08 17:48:29 +00:00
|
|
|
public void setPosition(double minX, double minY, double maxX, double maxY) {
|
|
|
|
this.minX = minX;
|
|
|
|
this.maxX = maxX;
|
|
|
|
this.minY = minY;
|
|
|
|
this.maxY = maxY;
|
2020-12-01 21:39:27 +00:00
|
|
|
}
|
2011-08-08 17:48:29 +00:00
|
|
|
|
2020-12-01 21:39:27 +00:00
|
|
|
private Style getStyle(FontParam fontParam, ISkinParam skinParam) {
|
|
|
|
return fontParam.getStyleDefinition(SName.stateDiagram).getMergedStyle(skinParam.getCurrentStyleBuilder());
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
2021-04-20 20:19:49 +00:00
|
|
|
private boolean isThereALinkFromOrToGroup(Collection<SvekLine> lines) {
|
2022-02-01 20:21:45 +00:00
|
|
|
for (SvekLine line : lines)
|
|
|
|
if (line.isLinkFromOrTo(group))
|
2013-12-10 19:36:50 +00:00
|
|
|
return true;
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
return false;
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
2021-04-20 20:19:49 +00:00
|
|
|
public void printCluster1(StringBuilder sb, Collection<SvekLine> lines, StringBounder stringBounder) {
|
2022-02-01 20:21:45 +00:00
|
|
|
for (SvekNode node : getNodesOrderedTop(lines))
|
2020-02-18 21:24:31 +00:00
|
|
|
node.appendShape(sb, stringBounder);
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
}
|
2011-08-08 17:48:29 +00:00
|
|
|
|
2020-05-07 14:12:08 +00:00
|
|
|
private List<IShapePseudo> addProtection(List<? extends IShapePseudo> entries, double width) {
|
2021-05-14 08:42:57 +00:00
|
|
|
final List<IShapePseudo> result = new ArrayList<>();
|
2013-12-10 19:36:50 +00:00
|
|
|
result.add(entries.get(0));
|
|
|
|
for (int i = 1; i < entries.size(); i++) {
|
2020-05-07 14:12:08 +00:00
|
|
|
// Pseudo space for the label
|
2013-12-10 19:36:50 +00:00
|
|
|
result.add(new ShapePseudoImpl("psd" + UniqueSequence.getValue(), width, 5));
|
|
|
|
result.add(entries.get(i));
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2020-05-07 14:12:08 +00:00
|
|
|
private double getMaxWidthFromLabelForEntryExit(List<? extends IShapePseudo> entries, StringBounder stringBounder) {
|
2013-12-10 19:36:50 +00:00
|
|
|
double result = -Double.MAX_VALUE;
|
2020-05-07 14:12:08 +00:00
|
|
|
for (IShapePseudo node : entries) {
|
2020-02-18 21:24:31 +00:00
|
|
|
final double w = getMaxWidthFromLabelForEntryExit(node, stringBounder);
|
2022-02-01 20:21:45 +00:00
|
|
|
if (w > result)
|
2013-12-10 19:36:50 +00:00
|
|
|
result = w;
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2020-05-07 14:12:08 +00:00
|
|
|
private double getMaxWidthFromLabelForEntryExit(IShapePseudo node, StringBounder stringBounder) {
|
2020-02-18 21:24:31 +00:00
|
|
|
return node.getMaxWidthFromLabelForEntryExit(stringBounder);
|
2013-12-10 19:36:50 +00:00
|
|
|
}
|
|
|
|
|
2020-05-07 14:12:08 +00:00
|
|
|
private void printRanks(String rank, List<? extends IShapePseudo> entries, StringBuilder sb,
|
|
|
|
StringBounder stringBounder) {
|
2013-12-10 19:36:50 +00:00
|
|
|
if (entries.size() > 0) {
|
2020-05-07 14:12:08 +00:00
|
|
|
sb.append("{rank=" + rank + ";");
|
2022-02-01 20:21:45 +00:00
|
|
|
for (IShapePseudo sh1 : entries)
|
2020-05-07 14:12:08 +00:00
|
|
|
sb.append(sh1.getUid() + ";");
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
sb.append("}");
|
2020-05-07 14:12:08 +00:00
|
|
|
SvekUtils.println(sb);
|
2022-02-01 20:21:45 +00:00
|
|
|
for (IShapePseudo sh2 : entries)
|
2020-05-07 14:12:08 +00:00
|
|
|
sh2.appendShape(sb, stringBounder);
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2020-05-07 14:12:08 +00:00
|
|
|
SvekUtils.println(sb);
|
|
|
|
if (hasPort()) {
|
|
|
|
boolean arrow = false;
|
|
|
|
String node = null;
|
|
|
|
for (IShapePseudo sh : entries) {
|
2022-02-01 20:21:45 +00:00
|
|
|
if (arrow)
|
2020-05-07 14:12:08 +00:00
|
|
|
sb.append("->");
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2020-05-07 14:12:08 +00:00
|
|
|
arrow = true;
|
|
|
|
node = sh.getUid();
|
|
|
|
sb.append(node);
|
|
|
|
}
|
|
|
|
sb.append(';');
|
|
|
|
SvekUtils.println(sb);
|
|
|
|
sb.append(node + "->" + empty() + ";");
|
|
|
|
SvekUtils.println(sb);
|
2013-12-10 19:36:50 +00:00
|
|
|
}
|
2020-05-07 14:12:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private List<? extends IShapePseudo> withPositionProtected(StringBounder stringBounder,
|
|
|
|
Set<EntityPosition> targets) {
|
2021-02-02 10:12:15 +00:00
|
|
|
final List<SvekNode> result = withPosition(targets);
|
2020-05-07 14:12:08 +00:00
|
|
|
final double maxWith = getMaxWidthFromLabelForEntryExit(result, stringBounder);
|
|
|
|
final double naturalSpace = 70;
|
2022-02-01 20:21:45 +00:00
|
|
|
if (maxWith > naturalSpace)
|
2020-05-07 14:12:08 +00:00
|
|
|
return addProtection(result, maxWith - naturalSpace);
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2020-05-07 14:12:08 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2021-02-02 10:12:15 +00:00
|
|
|
private List<SvekNode> withPosition(Set<EntityPosition> positions) {
|
2021-05-14 08:42:57 +00:00
|
|
|
final List<SvekNode> result = new ArrayList<>();
|
2021-02-02 10:12:15 +00:00
|
|
|
for (final Iterator<SvekNode> it = nodes.iterator(); it.hasNext();) {
|
|
|
|
final SvekNode sh = it.next();
|
2022-02-01 20:21:45 +00:00
|
|
|
if (positions.contains(sh.getEntityPosition()))
|
2020-05-07 14:12:08 +00:00
|
|
|
result.add(sh);
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
}
|
2020-05-07 14:12:08 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void printClusterEntryExit(StringBuilder sb, StringBounder stringBounder) {
|
|
|
|
printRanks(RANK_SOURCE, withPositionProtected(stringBounder, EntityPosition.getInputs()), sb, stringBounder);
|
|
|
|
printRanks(RANK_SAME, withPositionProtected(stringBounder, EntityPosition.getSame()), sb, stringBounder);
|
|
|
|
printRanks(RANK_SINK, withPositionProtected(stringBounder, EntityPosition.getOutputs()), sb, stringBounder);
|
2013-12-10 19:36:50 +00:00
|
|
|
}
|
2011-08-08 17:48:29 +00:00
|
|
|
|
2021-04-20 20:19:49 +00:00
|
|
|
public SvekNode printCluster2(StringBuilder sb, Collection<SvekLine> lines, StringBounder stringBounder,
|
|
|
|
DotMode dotMode, GraphvizVersion graphvizVersion, UmlDiagramType type) {
|
2013-12-10 19:36:50 +00:00
|
|
|
|
2021-02-02 10:12:15 +00:00
|
|
|
SvekNode added = null;
|
|
|
|
for (SvekNode node : getNodesOrderedWithoutTop(lines)) {
|
2020-02-18 21:24:31 +00:00
|
|
|
node.appendShape(sb, stringBounder);
|
2020-05-07 14:12:08 +00:00
|
|
|
added = node;
|
2013-12-10 19:36:50 +00:00
|
|
|
}
|
|
|
|
|
2018-05-01 17:26:04 +00:00
|
|
|
if (skinParam.useRankSame() && dotMode != DotMode.NO_LEFT_RIGHT_AND_XLABEL
|
2022-02-01 20:21:45 +00:00
|
|
|
&& graphvizVersion.ignoreHorizontalLinks() == false)
|
2013-12-10 19:36:50 +00:00
|
|
|
appendRankSame(sb, lines);
|
|
|
|
|
2022-02-01 20:21:45 +00:00
|
|
|
for (Cluster child : getChildren())
|
2015-04-07 18:18:37 +00:00
|
|
|
child.printInternal(sb, lines, stringBounder, dotMode, graphvizVersion, type);
|
2011-08-08 17:48:29 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
return added;
|
|
|
|
}
|
|
|
|
|
2021-04-20 20:19:49 +00:00
|
|
|
private void appendRankSame(StringBuilder sb, Collection<SvekLine> lines) {
|
2013-12-10 19:36:50 +00:00
|
|
|
for (String same : getRankSame(lines)) {
|
2011-08-08 17:48:29 +00:00
|
|
|
sb.append(same);
|
|
|
|
SvekUtils.println(sb);
|
|
|
|
}
|
2013-12-10 19:36:50 +00:00
|
|
|
}
|
2011-08-08 17:48:29 +00:00
|
|
|
|
2021-04-20 20:19:49 +00:00
|
|
|
private Set<String> getRankSame(Collection<SvekLine> lines) {
|
2021-05-14 08:42:57 +00:00
|
|
|
final Set<String> rankSame = new HashSet<>();
|
2021-04-20 20:19:49 +00:00
|
|
|
for (SvekLine l : lines) {
|
2022-02-01 20:21:45 +00:00
|
|
|
if (l.hasEntryPoint())
|
2013-12-10 19:36:50 +00:00
|
|
|
continue;
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2016-07-04 19:06:50 +00:00
|
|
|
final String startUid = l.getStartUidPrefix();
|
|
|
|
final String endUid = l.getEndUidPrefix();
|
2013-12-10 19:36:50 +00:00
|
|
|
if (isInCluster(startUid) && isInCluster(endUid)) {
|
|
|
|
final String same = l.rankSame();
|
2022-02-01 20:21:45 +00:00
|
|
|
if (same != null)
|
2013-12-10 19:36:50 +00:00
|
|
|
rankSame.add(same);
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
}
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
2013-12-10 19:36:50 +00:00
|
|
|
return rankSame;
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void fillRankMin(Set<String> rankMin) {
|
2022-02-01 20:21:45 +00:00
|
|
|
for (SvekNode sh : getNodes())
|
|
|
|
if (sh.isTop())
|
2011-08-08 17:48:29 +00:00
|
|
|
rankMin.add(sh.getUid());
|
|
|
|
|
2022-02-01 20:21:45 +00:00
|
|
|
for (Cluster child : getChildren())
|
2011-08-08 17:48:29 +00:00
|
|
|
child.fillRankMin(rankMin);
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private boolean isInCluster(String uid) {
|
2022-02-01 20:21:45 +00:00
|
|
|
for (SvekNode node : nodes)
|
|
|
|
if (node.getUid().equals(uid))
|
2011-08-08 17:48:29 +00:00
|
|
|
return true;
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2011-08-08 17:48:29 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getClusterId() {
|
|
|
|
return "cluster" + color;
|
|
|
|
}
|
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
public static String getSpecialPointId(IEntity group) {
|
|
|
|
return CENTER_ID + group.getUid();
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
2015-04-07 18:18:37 +00:00
|
|
|
private boolean protection0(UmlDiagramType type) {
|
2022-02-01 20:21:45 +00:00
|
|
|
if (skinParam.useSwimlanes(type))
|
2013-12-10 19:36:50 +00:00
|
|
|
return false;
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
return true;
|
|
|
|
}
|
2011-09-08 10:42:27 +00:00
|
|
|
|
2015-04-07 18:18:37 +00:00
|
|
|
private boolean protection1(UmlDiagramType type) {
|
2022-02-01 20:21:45 +00:00
|
|
|
if (group.getUSymbol() == USymbol.NODE)
|
2015-04-07 18:18:37 +00:00
|
|
|
return true;
|
2022-02-01 20:21:45 +00:00
|
|
|
|
|
|
|
if (skinParam.useSwimlanes(type))
|
2013-12-10 19:36:50 +00:00
|
|
|
return false;
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-04-07 18:18:37 +00:00
|
|
|
public String getMinPoint(UmlDiagramType type) {
|
2022-02-01 20:21:45 +00:00
|
|
|
if (skinParam.useSwimlanes(type))
|
2013-12-10 19:36:50 +00:00
|
|
|
return "minPoint" + color;
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2015-04-07 18:18:37 +00:00
|
|
|
public String getMaxPoint(UmlDiagramType type) {
|
2022-02-01 20:21:45 +00:00
|
|
|
if (skinParam.useSwimlanes(type))
|
2013-12-10 19:36:50 +00:00
|
|
|
return "maxPoint" + color;
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2015-04-07 18:18:37 +00:00
|
|
|
private String getSourceInPoint(UmlDiagramType type) {
|
2022-02-01 20:21:45 +00:00
|
|
|
if (skinParam.useSwimlanes(type))
|
2013-12-10 19:36:50 +00:00
|
|
|
return "sourceIn" + color;
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2015-04-07 18:18:37 +00:00
|
|
|
private String getSinkInPoint(UmlDiagramType type) {
|
2022-02-01 20:21:45 +00:00
|
|
|
if (skinParam.useSwimlanes(type))
|
2013-12-10 19:36:50 +00:00
|
|
|
return "sinkIn" + color;
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2021-04-20 20:19:49 +00:00
|
|
|
private void printInternal(StringBuilder sb, Collection<SvekLine> lines, StringBounder stringBounder,
|
|
|
|
DotMode dotMode, GraphvizVersion graphvizVersion, UmlDiagramType type) {
|
2015-04-07 18:18:37 +00:00
|
|
|
final boolean thereALinkFromOrToGroup2 = isThereALinkFromOrToGroup(lines);
|
|
|
|
boolean thereALinkFromOrToGroup1 = thereALinkFromOrToGroup2;
|
|
|
|
final boolean useProtectionWhenThereALinkFromOrToGroup = graphvizVersion
|
|
|
|
.useProtectionWhenThereALinkFromOrToGroup();
|
2022-02-01 20:21:45 +00:00
|
|
|
if (useProtectionWhenThereALinkFromOrToGroup == false)
|
2015-04-07 18:18:37 +00:00
|
|
|
thereALinkFromOrToGroup1 = false;
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2015-04-07 18:18:37 +00:00
|
|
|
// final boolean thereALinkFromOrToGroup1 = false;
|
2022-02-01 20:21:45 +00:00
|
|
|
if (thereALinkFromOrToGroup1)
|
2020-05-07 14:12:08 +00:00
|
|
|
subgraphClusterNoLabel(sb, "a");
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2020-05-07 14:12:08 +00:00
|
|
|
final Set<EntityPosition> entityPositionsExceptNormal = entityPositionsExceptNormal();
|
2022-02-01 20:21:45 +00:00
|
|
|
if (entityPositionsExceptNormal.size() > 0)
|
|
|
|
for (SvekLine line : lines)
|
|
|
|
if (line.isLinkFromOrTo(group))
|
2013-12-10 19:36:50 +00:00
|
|
|
line.setProjectionCluster(this);
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2015-04-07 18:18:37 +00:00
|
|
|
boolean protection0 = protection0(type);
|
|
|
|
boolean protection1 = protection1(type);
|
2020-05-07 14:12:08 +00:00
|
|
|
if (entityPositionsExceptNormal.size() > 0 || useProtectionWhenThereALinkFromOrToGroup == false) {
|
2013-12-10 19:36:50 +00:00
|
|
|
protection0 = false;
|
|
|
|
protection1 = false;
|
|
|
|
}
|
2016-07-04 19:06:50 +00:00
|
|
|
// if (graphvizVersion.modeSafe()) {
|
|
|
|
// protection0 = false;
|
|
|
|
// protection1 = false;
|
|
|
|
// }
|
2022-02-01 20:21:45 +00:00
|
|
|
if (protection0)
|
2020-05-07 14:12:08 +00:00
|
|
|
subgraphClusterNoLabel(sb, "p0");
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2011-08-08 17:48:29 +00:00
|
|
|
sb.append("subgraph " + getClusterId() + " {");
|
|
|
|
sb.append("style=solid;");
|
2020-04-26 18:31:41 +00:00
|
|
|
sb.append("color=\"" + DotStringFactory.sharp000000(color) + "\";");
|
2011-08-08 17:48:29 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
final String label;
|
2016-04-04 19:05:10 +00:00
|
|
|
if (isLabel()) {
|
2013-12-10 19:36:50 +00:00
|
|
|
final StringBuilder sblabel = new StringBuilder("<");
|
2021-04-20 20:19:49 +00:00
|
|
|
SvekLine.appendTable(sblabel, getTitleAndAttributeWidth(), getTitleAndAttributeHeight() - 5, colorTitle);
|
2013-12-10 19:36:50 +00:00
|
|
|
sblabel.append(">");
|
|
|
|
label = sblabel.toString();
|
2018-09-23 12:15:14 +00:00
|
|
|
final HorizontalAlignment align = skinParam.getHorizontalAlignment(AlignmentParam.packageTitleAlignment,
|
2021-06-27 16:50:40 +00:00
|
|
|
null, false, null);
|
2017-12-11 21:02:10 +00:00
|
|
|
sb.append("labeljust=\"" + align.getGraphVizValue() + "\";");
|
2013-12-10 19:36:50 +00:00
|
|
|
} else {
|
|
|
|
label = "\"\"";
|
|
|
|
}
|
|
|
|
|
2020-05-07 14:12:08 +00:00
|
|
|
if (entityPositionsExceptNormal.size() > 0) {
|
2013-12-10 19:36:50 +00:00
|
|
|
printClusterEntryExit(sb, stringBounder);
|
2022-02-01 20:21:45 +00:00
|
|
|
if (hasPort())
|
2020-05-07 14:12:08 +00:00
|
|
|
subgraphClusterNoLabel(sb, ID_EE);
|
2022-02-01 20:21:45 +00:00
|
|
|
else
|
2020-05-07 14:12:08 +00:00
|
|
|
subgraphClusterWithLabel(sb, ID_EE, label);
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
} else {
|
|
|
|
sb.append("label=" + label + ";");
|
|
|
|
SvekUtils.println(sb);
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
2022-02-01 20:21:45 +00:00
|
|
|
if (thereALinkFromOrToGroup2)
|
2013-12-10 19:36:50 +00:00
|
|
|
sb.append(getSpecialPointId(group) + " [shape=point,width=.01,label=\"\"];");
|
2022-02-01 20:21:45 +00:00
|
|
|
|
|
|
|
if (thereALinkFromOrToGroup1)
|
2020-05-07 14:12:08 +00:00
|
|
|
subgraphClusterNoLabel(sb, "i");
|
2022-02-01 20:21:45 +00:00
|
|
|
|
|
|
|
if (protection1)
|
2020-05-07 14:12:08 +00:00
|
|
|
subgraphClusterNoLabel(sb, "p1");
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2015-04-07 18:18:37 +00:00
|
|
|
if (skinParam.useSwimlanes(type)) {
|
2013-12-10 19:36:50 +00:00
|
|
|
sb.append("{rank = source; ");
|
2015-04-07 18:18:37 +00:00
|
|
|
sb.append(getSourceInPoint(type));
|
2013-12-10 19:36:50 +00:00
|
|
|
sb.append(" [shape=point,width=.01,label=\"\"];");
|
2015-04-07 18:18:37 +00:00
|
|
|
sb.append(getMinPoint(type) + "->" + getSourceInPoint(type) + " [weight=999];");
|
2013-12-10 19:36:50 +00:00
|
|
|
sb.append("}");
|
|
|
|
SvekUtils.println(sb);
|
|
|
|
sb.append("{rank = sink; ");
|
2015-04-07 18:18:37 +00:00
|
|
|
sb.append(getSinkInPoint(type));
|
2013-12-10 19:36:50 +00:00
|
|
|
sb.append(" [shape=point,width=.01,label=\"\"];");
|
|
|
|
sb.append("}");
|
2015-04-07 18:18:37 +00:00
|
|
|
sb.append(getSinkInPoint(type) + "->" + getMaxPoint(type) + " [weight=999];");
|
2013-12-10 19:36:50 +00:00
|
|
|
SvekUtils.println(sb);
|
|
|
|
}
|
|
|
|
SvekUtils.println(sb);
|
2016-08-25 20:45:37 +00:00
|
|
|
printCluster1(sb, lines, stringBounder);
|
2020-05-07 14:12:08 +00:00
|
|
|
|
2021-02-02 10:12:15 +00:00
|
|
|
final SvekNode added = printCluster2(sb, lines, stringBounder, dotMode, graphvizVersion, type);
|
2022-02-01 20:21:45 +00:00
|
|
|
if (entityPositionsExceptNormal.size() > 0)
|
2020-05-07 14:12:08 +00:00
|
|
|
if (hasPort()) {
|
|
|
|
sb.append(empty() + " [shape=rect,width=.01,height=.01,label=");
|
|
|
|
sb.append(label);
|
|
|
|
sb.append("];");
|
2020-06-21 20:31:45 +00:00
|
|
|
} else if (added == null) {
|
2020-05-07 14:12:08 +00:00
|
|
|
sb.append(empty() + " [shape=point,width=.01,label=\"\"];");
|
|
|
|
}
|
2022-02-01 20:21:45 +00:00
|
|
|
SvekUtils.println(sb);
|
2020-05-07 14:12:08 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
sb.append("}");
|
2022-02-01 20:21:45 +00:00
|
|
|
if (protection1)
|
2011-09-08 10:42:27 +00:00
|
|
|
sb.append("}");
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2015-04-07 18:18:37 +00:00
|
|
|
if (thereALinkFromOrToGroup1) {
|
2013-12-10 19:36:50 +00:00
|
|
|
sb.append("}");
|
2011-08-08 17:48:29 +00:00
|
|
|
sb.append("}");
|
|
|
|
}
|
2022-02-01 20:21:45 +00:00
|
|
|
if (entityPositionsExceptNormal.size() > 0)
|
2011-09-08 10:42:27 +00:00
|
|
|
sb.append("}");
|
2022-02-01 20:21:45 +00:00
|
|
|
|
|
|
|
if (protection0)
|
2011-08-08 17:48:29 +00:00
|
|
|
sb.append("}");
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2011-08-08 17:48:29 +00:00
|
|
|
SvekUtils.println(sb);
|
|
|
|
}
|
|
|
|
|
2020-05-07 14:12:08 +00:00
|
|
|
private boolean hasPort() {
|
2022-02-01 20:21:45 +00:00
|
|
|
for (EntityPosition pos : entityPositionsExceptNormal())
|
|
|
|
if (pos.isPort())
|
2020-05-07 14:12:08 +00:00
|
|
|
return true;
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2020-05-07 14:12:08 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private String empty() {
|
2020-06-21 20:31:45 +00:00
|
|
|
// return "empty" + color;
|
|
|
|
// We use the same node with one for thereALinkFromOrToGroup2 as an empty
|
|
|
|
// because we cannot put a new node in the nested inside of the cluster
|
|
|
|
// if thereALinkFromOrToGroup2 is enabled.
|
|
|
|
return getSpecialPointId(group);
|
2020-05-07 14:12:08 +00:00
|
|
|
}
|
|
|
|
|
2016-04-04 19:05:10 +00:00
|
|
|
public boolean isLabel() {
|
|
|
|
return getTitleAndAttributeHeight() > 0 && getTitleAndAttributeWidth() > 0;
|
|
|
|
}
|
|
|
|
|
2020-05-07 14:12:08 +00:00
|
|
|
private void subgraphClusterNoLabel(StringBuilder sb, String id) {
|
|
|
|
subgraphClusterWithLabel(sb, id, "\"\"");
|
2013-12-10 19:36:50 +00:00
|
|
|
}
|
|
|
|
|
2020-05-07 14:12:08 +00:00
|
|
|
private void subgraphClusterWithLabel(StringBuilder sb, String id, String label) {
|
|
|
|
sb.append("subgraph " + getClusterId() + id + " {");
|
2013-12-10 19:36:50 +00:00
|
|
|
sb.append("label=" + label + ";");
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public int getColor() {
|
|
|
|
return color;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getTitleColor() {
|
|
|
|
return colorTitle;
|
|
|
|
}
|
|
|
|
|
2021-09-19 17:05:24 +00:00
|
|
|
private final HColor getBackColor(UmlDiagramType umlDiagramType, Style style) {
|
2022-02-01 20:21:45 +00:00
|
|
|
if (EntityUtils.groupRoot(group))
|
2011-09-08 10:42:27 +00:00
|
|
|
return null;
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2021-11-15 18:27:27 +00:00
|
|
|
final HColor result = group.getColors().getColor(ColorType.BACK);
|
2022-02-01 20:21:45 +00:00
|
|
|
if (result != null)
|
2011-09-08 10:42:27 +00:00
|
|
|
return result;
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2015-04-07 18:18:37 +00:00
|
|
|
final Stereotype stereo = group.getStereotype();
|
2021-09-19 17:05:24 +00:00
|
|
|
|
2022-02-01 20:21:45 +00:00
|
|
|
if (UseStyle.useBetaStyle())
|
2021-09-19 17:05:24 +00:00
|
|
|
return style.value(PName.BackGroundColor).asColor(skinParam.getThemeStyle(), skinParam.getIHtmlColorSet());
|
|
|
|
|
2015-04-07 18:18:37 +00:00
|
|
|
final USymbol sym = group.getUSymbol() == null ? USymbol.PACKAGE : group.getUSymbol();
|
2020-02-18 21:24:31 +00:00
|
|
|
final ColorParam backparam = umlDiagramType == UmlDiagramType.ACTIVITY ? ColorParam.partitionBackground
|
|
|
|
: sym.getColorParamBack();
|
2020-03-18 10:50:02 +00:00
|
|
|
final HColor c1 = skinParam.getHtmlColor(backparam, stereo, false);
|
2022-02-01 20:21:45 +00:00
|
|
|
if (c1 != null)
|
2015-04-07 18:18:37 +00:00
|
|
|
return c1;
|
2022-02-01 20:21:45 +00:00
|
|
|
|
|
|
|
if (parentCluster == null)
|
2011-09-08 10:42:27 +00:00
|
|
|
return null;
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2021-09-19 17:05:24 +00:00
|
|
|
return parentCluster.getBackColor(umlDiagramType, style);
|
2011-09-08 10:42:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isClusterOf(IEntity ent) {
|
2022-02-01 20:21:45 +00:00
|
|
|
if (ent.isGroup() == false)
|
2011-09-08 10:42:27 +00:00
|
|
|
return false;
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
return group == ent;
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|
|
|
|
|
2022-02-01 20:21:45 +00:00
|
|
|
public static HColor getBackColor(HColor backColor, ISkinParam skinParam, Stereotype stereotype, SName styleName,
|
|
|
|
USymbol symbol) {
|
2020-12-01 21:39:27 +00:00
|
|
|
if (UseStyle.useBetaStyle()) {
|
2022-02-01 20:21:45 +00:00
|
|
|
final Style style = getDefaultStyleDefinition(styleName, symbol)
|
|
|
|
.getMergedStyle(skinParam.getCurrentStyleBuilder());
|
|
|
|
if (backColor == null)
|
2021-05-06 21:23:05 +00:00
|
|
|
backColor = style.value(PName.BackGroundColor).asColor(skinParam.getThemeStyle(),
|
|
|
|
skinParam.getIHtmlColorSet());
|
2022-02-01 20:21:45 +00:00
|
|
|
|
|
|
|
if (backColor == null || backColor.equals(HColorUtils.transparent()))
|
2021-11-08 13:56:52 +00:00
|
|
|
backColor = new HColorBackground(skinParam.getBackgroundColor());
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2019-08-26 17:07:21 +00:00
|
|
|
return backColor;
|
|
|
|
}
|
2022-02-01 20:21:45 +00:00
|
|
|
if (backColor == null)
|
2015-08-05 20:17:01 +00:00
|
|
|
backColor = skinParam.getHtmlColor(ColorParam.packageBackground, stereotype, false);
|
2022-02-01 20:21:45 +00:00
|
|
|
|
|
|
|
if (backColor == null)
|
2015-08-05 20:17:01 +00:00
|
|
|
backColor = skinParam.getHtmlColor(ColorParam.background, stereotype, false);
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2020-05-07 14:12:08 +00:00
|
|
|
if (backColor == null
|
|
|
|
|| backColor.equals(HColorUtils.transparent()) /* || stateBack instanceof HtmlColorTransparent */) {
|
2021-11-08 13:56:52 +00:00
|
|
|
final HColor tmp = skinParam.getBackgroundColor();
|
2020-05-30 15:20:23 +00:00
|
|
|
backColor = new HColorBackground(tmp);
|
2013-12-10 19:36:50 +00:00
|
|
|
}
|
2015-08-05 20:17:01 +00:00
|
|
|
return backColor;
|
2013-12-10 19:36:50 +00:00
|
|
|
}
|
|
|
|
|
2015-04-07 18:18:37 +00:00
|
|
|
public double checkFolderPosition(Point2D pt, StringBounder stringBounder) {
|
|
|
|
if (getClusterPosition().isPointJustUpper(pt)) {
|
2022-02-01 20:21:45 +00:00
|
|
|
if (ztitle == null)
|
2015-04-07 18:18:37 +00:00
|
|
|
return 0;
|
2022-02-01 20:21:45 +00:00
|
|
|
|
2015-04-07 18:18:37 +00:00
|
|
|
final Dimension2D dimTitle = ztitle.calculateDimension(stringBounder);
|
|
|
|
|
2022-02-01 20:21:45 +00:00
|
|
|
if (pt.getX() < getClusterPosition().getMinX() + dimTitle.getWidth())
|
2015-04-07 18:18:37 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
return getClusterPosition().getMinY() - pt.getY() + dimTitle.getHeight();
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-12-10 19:36:50 +00:00
|
|
|
// public Point2D projection(double x, double y) {
|
|
|
|
// final double v1 = Math.abs(minX - x);
|
|
|
|
// final double v2 = Math.abs(maxX - x);
|
|
|
|
// final double v3 = Math.abs(minY - y);
|
|
|
|
// final double v4 = Math.abs(maxY - y);
|
|
|
|
// if (v1 <= v2 && v1 <= v3 && v1 <= v4) {
|
|
|
|
// return new Point2D.Double(minX, y);
|
|
|
|
// }
|
|
|
|
// if (v2 <= v1 && v2 <= v3 && v2 <= v4) {
|
|
|
|
// return new Point2D.Double(maxX, y);
|
|
|
|
// }
|
|
|
|
// if (v3 <= v1 && v3 <= v2 && v3 <= v4) {
|
|
|
|
// return new Point2D.Double(x, minY);
|
|
|
|
// }
|
|
|
|
// if (v4 <= v1 && v4 <= v1 && v4 <= v3) {
|
|
|
|
// return new Point2D.Double(x, maxY);
|
|
|
|
// }
|
|
|
|
// throw new IllegalStateException();
|
|
|
|
// }
|
|
|
|
|
2011-08-08 17:48:29 +00:00
|
|
|
}
|