mirror of
https://github.com/octoleo/plantuml.git
synced 2024-11-24 22:07:33 +00:00
ScXml improvement
This commit is contained in:
parent
0dd8e23270
commit
a562d24aa4
@ -183,7 +183,7 @@ public class CommandCreateElementFull2 extends SingleLineCommand2<ClassDiagram>
|
||||
type = LeafType.DESCRIPTION;
|
||||
usymbol = diagram.getSkinParam().actorStyle().toUSymbol();
|
||||
} else if (symbol.equalsIgnoreCase("port")) {
|
||||
type = LeafType.PORT;
|
||||
type = LeafType.PORTIN;
|
||||
usymbol = null;
|
||||
} else if (symbol.equalsIgnoreCase("portin")) {
|
||||
type = LeafType.PORTIN;
|
||||
|
@ -211,9 +211,9 @@ public final class CommandFactoryNoteOnEntity implements SingleMultiFactoryComma
|
||||
final IEntity cl1;
|
||||
if (idShort == null) {
|
||||
cl1 = diagram.getLastEntity();
|
||||
if (cl1 == null) {
|
||||
if (cl1 == null)
|
||||
return CommandExecutionResult.error("Nothing to note to");
|
||||
}
|
||||
|
||||
} else {
|
||||
final Ident ident = diagram.buildLeafIdent(idShort);
|
||||
final Code code = diagram.V1972() ? ident : diagram.buildCode(idShort);
|
||||
@ -247,9 +247,9 @@ public final class CommandFactoryNoteOnEntity implements SingleMultiFactoryComma
|
||||
}
|
||||
|
||||
note.setColors(colors);
|
||||
if (url != null) {
|
||||
if (url != null)
|
||||
note.addUrl(url);
|
||||
}
|
||||
|
||||
CommandCreateClassMultilines.addTags(note, line0.get("TAGS", 0));
|
||||
|
||||
final Position position = Position.valueOf(StringUtils.goUpperCase(pos))
|
||||
@ -258,19 +258,15 @@ public final class CommandFactoryNoteOnEntity implements SingleMultiFactoryComma
|
||||
|
||||
final LinkType type = new LinkType(LinkDecor.NONE, LinkDecor.NONE).goDashed();
|
||||
if (position == Position.RIGHT) {
|
||||
link = new Link(diagram.getSkinParam().getCurrentStyleBuilder(), cl1, note, type,
|
||||
LinkArg.noDisplay(1));
|
||||
link = new Link(diagram.getSkinParam().getCurrentStyleBuilder(), cl1, note, type, LinkArg.noDisplay(1));
|
||||
link.setHorizontalSolitary(true);
|
||||
} else if (position == Position.LEFT) {
|
||||
link = new Link(diagram.getSkinParam().getCurrentStyleBuilder(), note, cl1, type,
|
||||
LinkArg.noDisplay(1));
|
||||
link = new Link(diagram.getSkinParam().getCurrentStyleBuilder(), note, cl1, type, LinkArg.noDisplay(1));
|
||||
link.setHorizontalSolitary(true);
|
||||
} else if (position == Position.BOTTOM) {
|
||||
link = new Link(diagram.getSkinParam().getCurrentStyleBuilder(), cl1, note, type,
|
||||
LinkArg.noDisplay(2));
|
||||
link = new Link(diagram.getSkinParam().getCurrentStyleBuilder(), cl1, note, type, LinkArg.noDisplay(2));
|
||||
} else if (position == Position.TOP) {
|
||||
link = new Link(diagram.getSkinParam().getCurrentStyleBuilder(), note, cl1, type,
|
||||
LinkArg.noDisplay(2));
|
||||
link = new Link(diagram.getSkinParam().getCurrentStyleBuilder(), note, cl1, type, LinkArg.noDisplay(2));
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
@ -42,9 +42,17 @@ public class EntityPort {
|
||||
private final String entityUid;
|
||||
private final String portId;
|
||||
|
||||
public EntityPort(String entityUid, String portName) {
|
||||
private EntityPort(String entityUid, String portId) {
|
||||
this.entityUid = entityUid;
|
||||
this.portId = portName == null ? null : Ports.encodePortNameToId(portName);
|
||||
this.portId = portId;
|
||||
}
|
||||
|
||||
public static EntityPort create(String entityUid, String portName) {
|
||||
return new EntityPort(entityUid, portName == null ? null : Ports.encodePortNameToId(portName));
|
||||
}
|
||||
|
||||
public static EntityPort forPort(String entityUid) {
|
||||
return new EntityPort(entityUid, "P");
|
||||
}
|
||||
|
||||
public String getFullString() {
|
||||
@ -72,4 +80,5 @@ public class EntityPort {
|
||||
public boolean equalsId(EntityPort other) {
|
||||
return this.entityUid.equals(other.entityUid);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
|
||||
public enum EntityPosition {
|
||||
|
||||
NORMAL, ENTRY_POINT, EXIT_POINT, INPUT_PIN, OUTPUT_PIN, EXPANSION_INPUT, EXPANSION_OUTPUT, PORT, PORTIN, PORTOUT;
|
||||
NORMAL, ENTRY_POINT, EXIT_POINT, INPUT_PIN, OUTPUT_PIN, EXPANSION_INPUT, EXPANSION_OUTPUT, PORTIN, PORTOUT;
|
||||
|
||||
public static final double RADIUS = 6;
|
||||
|
||||
@ -70,7 +70,7 @@ public enum EntityPosition {
|
||||
drawLine(ug, getPointOnCircle(xc, yc, -Math.PI / 4, radius),
|
||||
getPointOnCircle(xc, yc, Math.PI - Math.PI / 4, radius));
|
||||
}
|
||||
} else if (this == INPUT_PIN || this == OUTPUT_PIN || this == PORT) {
|
||||
} else if (this == INPUT_PIN || this == OUTPUT_PIN /*|| this == PORT*/) {
|
||||
final Shadowable rectangle = new URectangle(RADIUS * 2, RADIUS * 2);
|
||||
ug.draw(rectangle);
|
||||
} else if (this == EXPANSION_INPUT || this == EXPANSION_OUTPUT) {
|
||||
@ -121,14 +121,14 @@ public enum EntityPosition {
|
||||
throw new IllegalStateException();
|
||||
|
||||
if (this == ENTRY_POINT || this == EXIT_POINT)
|
||||
return ShapeType.CIRCLE;
|
||||
return ShapeType.RECTANGLE_PORT;
|
||||
|
||||
return ShapeType.RECTANGLE;
|
||||
}
|
||||
|
||||
public static EntityPosition fromStereotype(String label) {
|
||||
if ("<<port>>".equalsIgnoreCase(label))
|
||||
return PORT;
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
if ("<<entrypoint>>".equalsIgnoreCase(label))
|
||||
return ENTRY_POINT;
|
||||
@ -159,12 +159,16 @@ public enum EntityPosition {
|
||||
return EnumSet.of(EXIT_POINT, OUTPUT_PIN, EXPANSION_OUTPUT, PORTOUT);
|
||||
}
|
||||
|
||||
public static EnumSet<EntityPosition> getSame() {
|
||||
return EnumSet.of(PORT);
|
||||
// public static EnumSet<EntityPosition> getSame() {
|
||||
// return EnumSet.of(PORT);
|
||||
// }
|
||||
//
|
||||
public boolean isPort() {
|
||||
return /*this == PORT ||*/ this == PORTIN || this == PORTOUT;
|
||||
}
|
||||
|
||||
public boolean isPort() {
|
||||
return this == PORT || this == PORTIN || this == PORTOUT;
|
||||
public boolean usePortP() {
|
||||
return isPort() || this == EXIT_POINT || this == ENTRY_POINT;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -67,11 +67,10 @@ public class GroupRoot implements IGroup {
|
||||
@Override
|
||||
public Collection<ILeaf> getLeafsDirect() {
|
||||
final List<ILeaf> result = new ArrayList<>();
|
||||
for (ILeaf ent : entityFactory.leafs()) {
|
||||
if (ent.getParentContainer() == this) {
|
||||
for (ILeaf ent : entityFactory.leafs())
|
||||
if (ent.getParentContainer() == this)
|
||||
result.add(ent);
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.unmodifiableCollection(result);
|
||||
|
||||
}
|
||||
@ -157,18 +156,13 @@ public class GroupRoot implements IGroup {
|
||||
public Collection<IGroup> getChildren() {
|
||||
final List<IGroup> result = new ArrayList<>();
|
||||
if (entityFactory.namespaceSeparator.V1972()) {
|
||||
for (IGroup ent : entityFactory.groups()) {
|
||||
if (ent.getIdent().size() == 1) {
|
||||
for (IGroup ent : entityFactory.groups())
|
||||
if (ent.getIdent().size() == 1)
|
||||
result.add(ent);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
for (IGroup ent : entityFactory.groups()) {
|
||||
if (ent.getParentContainer() == this) {
|
||||
for (IGroup ent : entityFactory.groups())
|
||||
if (ent.getParentContainer() == this)
|
||||
result.add(ent);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableCollection(result);
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ public enum LeafType {
|
||||
|
||||
DOMAIN, REQUIREMENT,
|
||||
|
||||
PORT, PORTIN, PORTOUT,
|
||||
PORTIN, PORTOUT,
|
||||
|
||||
STILL_UNKNOWN;
|
||||
|
||||
|
@ -193,11 +193,17 @@ public class Link extends WithLinkType implements Hideable, Removeable {
|
||||
}
|
||||
|
||||
public EntityPort getEntityPort1(Bibliotekon bibliotekon) {
|
||||
return new EntityPort(bibliotekon.getNodeUid((ILeaf) cl1), port1);
|
||||
return getEntityPort((ILeaf) cl1, port1, bibliotekon);
|
||||
}
|
||||
|
||||
public EntityPort getEntityPort2(Bibliotekon bibliotekon) {
|
||||
return new EntityPort(bibliotekon.getNodeUid((ILeaf) cl2), port2);
|
||||
return getEntityPort((ILeaf) cl2, port2, bibliotekon);
|
||||
}
|
||||
|
||||
private EntityPort getEntityPort(ILeaf leaf, String port, Bibliotekon bibliotekon) {
|
||||
if (leaf.getEntityPosition().usePortP())
|
||||
return EntityPort.forPort(bibliotekon.getNodeUid(leaf));
|
||||
return EntityPort.create(bibliotekon.getNodeUid(leaf), port);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -329,9 +329,8 @@ final public class EntityImpl implements ILeaf, IGroup {
|
||||
}
|
||||
|
||||
public EntityPosition getEntityPosition() {
|
||||
checkNotGroup();
|
||||
if (leafType == LeafType.PORT)
|
||||
return EntityPosition.PORT;
|
||||
// if (leafType == LeafType.PORT)
|
||||
// return EntityPosition.PORT;
|
||||
|
||||
if (leafType == LeafType.PORTIN)
|
||||
return EntityPosition.PORTIN;
|
||||
|
@ -209,7 +209,7 @@ public class CommandCreateElementFull extends SingleLineCommand2<DescriptionDiag
|
||||
type = LeafType.PORTOUT;
|
||||
usymbol = null;
|
||||
} else if (symbol.equalsIgnoreCase("port")) {
|
||||
type = LeafType.PORT;
|
||||
type = LeafType.PORTIN;
|
||||
usymbol = null;
|
||||
} else if (symbol.equalsIgnoreCase("usecase")) {
|
||||
type = LeafType.USECASE;
|
||||
|
@ -90,10 +90,9 @@ import net.sourceforge.plantuml.ugraphic.color.HColors;
|
||||
|
||||
public class Cluster implements Moveable {
|
||||
|
||||
/* private */ static final String RANK_SAME = "same";
|
||||
// /* 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";
|
||||
|
||||
private final Cluster parentCluster;
|
||||
|
@ -58,6 +58,7 @@ public class ClusterDotString {
|
||||
|
||||
private final Cluster cluster;
|
||||
private final ISkinParam skinParam;
|
||||
private static final String ID_EE = "ee";
|
||||
|
||||
public ClusterDotString(Cluster cluster, ISkinParam skinParam) {
|
||||
this.cluster = cluster;
|
||||
@ -113,9 +114,9 @@ public class ClusterDotString {
|
||||
if (entityPositionsExceptNormal.size() > 0) {
|
||||
printClusterEntryExit(sb, stringBounder);
|
||||
if (hasPort())
|
||||
subgraphClusterNoLabel(sb, Cluster.ID_EE);
|
||||
subgraphClusterNoLabel(sb, ID_EE);
|
||||
else
|
||||
subgraphClusterWithLabel(sb, Cluster.ID_EE, label);
|
||||
subgraphClusterWithLabel(sb, ID_EE, label);
|
||||
|
||||
} else {
|
||||
sb.append("label=" + label + ";");
|
||||
@ -225,31 +226,29 @@ public class ClusterDotString {
|
||||
}
|
||||
|
||||
private void printClusterEntryExit(StringBuilder sb, StringBounder stringBounder) {
|
||||
printRanks(Cluster.RANK_SOURCE, withPositionProtected(stringBounder, EntityPosition.getInputs()), sb,
|
||||
stringBounder);
|
||||
printRanks(Cluster.RANK_SAME, withPositionProtected(stringBounder, EntityPosition.getSame()), sb,
|
||||
stringBounder);
|
||||
printRanks(Cluster.RANK_SINK, withPositionProtected(stringBounder, EntityPosition.getOutputs()), sb,
|
||||
stringBounder);
|
||||
printRanks(Cluster.RANK_SOURCE, withPosition(EntityPosition.getInputs()), sb, stringBounder);
|
||||
// printRanks(Cluster.RANK_SAME, withPosition(EntityPosition.getSame()), sb,
|
||||
// stringBounder);
|
||||
printRanks(Cluster.RANK_SINK, withPosition(EntityPosition.getOutputs()), sb, stringBounder);
|
||||
}
|
||||
|
||||
private void printRanks(String rank, List<? extends IShapePseudo> entries, StringBuilder sb,
|
||||
private void printRanks(String rank, List<? extends SvekNode> entries, StringBuilder sb,
|
||||
StringBounder stringBounder) {
|
||||
if (entries.size() > 0) {
|
||||
sb.append("{rank=" + rank + ";");
|
||||
for (IShapePseudo sh1 : entries)
|
||||
for (SvekNode sh1 : entries)
|
||||
sb.append(sh1.getUid() + ";");
|
||||
|
||||
sb.append("}");
|
||||
SvekUtils.println(sb);
|
||||
for (IShapePseudo sh2 : entries)
|
||||
for (SvekNode sh2 : entries)
|
||||
sh2.appendShape(sb, stringBounder);
|
||||
|
||||
SvekUtils.println(sb);
|
||||
if (hasPort()) {
|
||||
boolean arrow = false;
|
||||
String node = null;
|
||||
for (IShapePseudo sh : entries) {
|
||||
for (SvekNode sh : entries) {
|
||||
if (arrow)
|
||||
sb.append("->");
|
||||
|
||||
@ -268,28 +267,6 @@ public class ClusterDotString {
|
||||
}
|
||||
}
|
||||
|
||||
private List<? extends IShapePseudo> withPositionProtected(StringBounder stringBounder,
|
||||
Set<EntityPosition> targets) {
|
||||
final List<SvekNode> result = withPosition(targets);
|
||||
final double maxWith = getMaxWidthFromLabelForEntryExit(result, stringBounder);
|
||||
final double naturalSpace = 70;
|
||||
if (maxWith > naturalSpace)
|
||||
return addProtection(result, maxWith - naturalSpace);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<IShapePseudo> addProtection(List<? extends IShapePseudo> entries, double width) {
|
||||
final List<IShapePseudo> result = new ArrayList<>();
|
||||
result.add(entries.get(0));
|
||||
for (int i = 1; i < entries.size(); i++) {
|
||||
// Pseudo space for the label
|
||||
result.add(new ShapePseudoImpl("psd" + cluster.diagram.getUniqueSequence(), width, 5));
|
||||
result.add(entries.get(i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<SvekNode> withPosition(Set<EntityPosition> positions) {
|
||||
final List<SvekNode> result = new ArrayList<>();
|
||||
for (final Iterator<SvekNode> it = cluster.getNodes().iterator(); it.hasNext();) {
|
||||
@ -301,21 +278,6 @@ public class ClusterDotString {
|
||||
return result;
|
||||
}
|
||||
|
||||
private double getMaxWidthFromLabelForEntryExit(List<? extends IShapePseudo> entries, StringBounder stringBounder) {
|
||||
double result = -Double.MAX_VALUE;
|
||||
for (IShapePseudo node : entries) {
|
||||
final double w = getMaxWidthFromLabelForEntryExit(node, stringBounder);
|
||||
if (w > result)
|
||||
result = w;
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private double getMaxWidthFromLabelForEntryExit(IShapePseudo node, StringBounder stringBounder) {
|
||||
return node.getMaxWidthFromLabelForEntryExit(stringBounder);
|
||||
}
|
||||
|
||||
private boolean protection0(UmlDiagramType type) {
|
||||
if (skinParam.useSwimlanes(type))
|
||||
return false;
|
||||
|
@ -94,7 +94,8 @@ public class DotStringFactory implements Moveable {
|
||||
|
||||
this.colorSequence = new ColorSequence();
|
||||
this.stringBounder = stringBounder;
|
||||
this.root = new Cluster(dotData.getEntityFactory().getDiagram(), colorSequence, skinParam, dotData.getRootGroup());
|
||||
this.root = new Cluster(dotData.getEntityFactory().getDiagram(), colorSequence, skinParam,
|
||||
dotData.getRootGroup());
|
||||
this.current = root;
|
||||
}
|
||||
|
||||
@ -401,8 +402,7 @@ public class DotStringFactory implements Moveable {
|
||||
// corner1.manage(minX, minY);
|
||||
node.moveSvek(minX, minY);
|
||||
node.setPolygon(minX, minY, points);
|
||||
} else if (node.getType() == ShapeType.CIRCLE || node.getType() == ShapeType.CIRCLE_IN_RECT
|
||||
|| node.getType() == ShapeType.OVAL) {
|
||||
} else if (node.getType() == ShapeType.CIRCLE || node.getType() == ShapeType.OVAL) {
|
||||
final double cx = SvekUtils.getValue(svg, idx, "cx");
|
||||
final double cy = SvekUtils.getValue(svg, idx, "cy") + fullHeight;
|
||||
final double rx = SvekUtils.getValue(svg, idx, "rx");
|
||||
|
@ -170,8 +170,8 @@ public final class GeneralImageBuilder {
|
||||
if (leaf.getLeafType() == LeafType.ACTIVITY)
|
||||
return new EntityImageActivity(leaf, skinParam, bibliotekon);
|
||||
|
||||
if ((leaf.getLeafType() == LeafType.PORT) || (leaf.getLeafType() == LeafType.PORTIN)
|
||||
|| (leaf.getLeafType() == LeafType.PORTOUT)) {
|
||||
if (/*(leaf.getLeafType() == LeafType.PORT) || */leaf.getLeafType() == LeafType.PORTIN
|
||||
|| leaf.getLeafType() == LeafType.PORTOUT) {
|
||||
final Cluster parent = bibliotekon.getCluster(leaf.getParentContainer());
|
||||
return new EntityImagePort(leaf, skinParam, parent, bibliotekon, umlDiagramType.getStyleName());
|
||||
}
|
||||
|
@ -1,48 +0,0 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2023, Arnaud Roques
|
||||
*
|
||||
* Project Info: http://plantuml.com
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
* 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
|
||||
*
|
||||
*
|
||||
*/
|
||||
package net.sourceforge.plantuml.svek;
|
||||
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
|
||||
public interface IShapePseudo {
|
||||
|
||||
String getUid();
|
||||
|
||||
void appendShape(StringBuilder sb, StringBounder stringBounder);
|
||||
|
||||
double getMaxWidthFromLabelForEntryExit(StringBounder stringBounder);
|
||||
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2023, Arnaud Roques
|
||||
*
|
||||
* Project Info: http://plantuml.com
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
* 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
|
||||
*
|
||||
*
|
||||
*/
|
||||
package net.sourceforge.plantuml.svek;
|
||||
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
|
||||
public class ShapePseudoImpl implements IShapePseudo {
|
||||
|
||||
private final String uid;
|
||||
private final double width;
|
||||
private final double height;
|
||||
|
||||
public ShapePseudoImpl(String uid, double width, double height) {
|
||||
this.uid = uid;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public String getUid() {
|
||||
return uid;
|
||||
}
|
||||
|
||||
public void appendShape(StringBuilder sb, StringBounder stringBounder) {
|
||||
sb.append(uid + " [shape=rect,label=\"\"");
|
||||
sb.append(",width=" + SvekUtils.pixelToInches(width));
|
||||
sb.append(",height=" + SvekUtils.pixelToInches(height));
|
||||
sb.append("];");
|
||||
}
|
||||
|
||||
public double getMaxWidthFromLabelForEntryExit(StringBounder stringBounder) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
@ -43,7 +43,6 @@ public enum ShapeType {
|
||||
RECTANGLE_HTML_FOR_PORTS, //
|
||||
ROUND_RECTANGLE, //
|
||||
CIRCLE, //
|
||||
CIRCLE_IN_RECT, //
|
||||
OVAL, //
|
||||
DIAMOND, //
|
||||
OCTAGON, //
|
||||
|
@ -48,14 +48,15 @@ import net.sourceforge.plantuml.cucadiagram.ILeaf;
|
||||
import net.sourceforge.plantuml.cucadiagram.entity.EntityImpl;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.posimo.Positionable;
|
||||
import net.sourceforge.plantuml.svek.image.AbstractEntityImageBorder;
|
||||
import net.sourceforge.plantuml.svek.image.EntityImageDescription;
|
||||
import net.sourceforge.plantuml.svek.image.EntityImageLollipopInterface;
|
||||
import net.sourceforge.plantuml.svek.image.EntityImagePort;
|
||||
import net.sourceforge.plantuml.svek.image.EntityImageStateBorder;
|
||||
import net.sourceforge.plantuml.ugraphic.Shadowable;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.UPolygon;
|
||||
|
||||
public class SvekNode implements Positionable, IShapePseudo, Hideable {
|
||||
public class SvekNode implements Positionable, Hideable {
|
||||
|
||||
private final ShapeType type;
|
||||
private Dimension2D dimImage;
|
||||
@ -164,7 +165,46 @@ public class SvekNode implements Positionable, IShapePseudo, Hideable {
|
||||
SvekUtils.println(sb);
|
||||
}
|
||||
|
||||
private void appendLabelHtmlSpecialForPort(StringBuilder sb, StringBounder stringBounder2) {
|
||||
private double getMaxWidthFromLabelForEntryExit(StringBounder stringBounder) {
|
||||
if (image instanceof EntityImagePort) {
|
||||
final EntityImagePort im = (EntityImagePort) image;
|
||||
return im.getMaxWidthFromLabelForEntryExit(stringBounder);
|
||||
}
|
||||
if (image instanceof EntityImageStateBorder) {
|
||||
final EntityImageStateBorder im = (EntityImageStateBorder) image;
|
||||
return im.getMaxWidthFromLabelForEntryExit(stringBounder);
|
||||
}
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
private void appendLabelHtmlSpecialForPort(StringBuilder sb, StringBounder stringBounder) {
|
||||
final int width1 = (int) getWidth();
|
||||
final int width2 = (int) getMaxWidthFromLabelForEntryExit(stringBounder);
|
||||
if (width2 > 40)
|
||||
appendLabelHtmlSpecialForPortHtml(sb, stringBounder, width2 - 40);
|
||||
else
|
||||
appendLabelHtmlSpecialForPortBasic(sb, stringBounder);
|
||||
}
|
||||
|
||||
private void appendLabelHtmlSpecialForPortHtml(StringBuilder sb, StringBounder stringBounder, int fullWidth) {
|
||||
if (fullWidth < 10)
|
||||
fullWidth = 10;
|
||||
sb.append(uid);
|
||||
sb.append(" [");
|
||||
sb.append("shape=plaintext");
|
||||
sb.append(",");
|
||||
sb.append("label=<");
|
||||
sb.append("<TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">");
|
||||
sb.append("<TR><TD WIDTH=\"" + fullWidth + "\" HEIGHT=\"1\" COLSPAN=\"3\"></TD></TR>");
|
||||
sb.append("<TR><TD></TD><TD FIXEDSIZE=\"TRUE\" PORT=\"P\" BORDER=\"1\" COLOR=\""
|
||||
+ StringUtils.sharp000000(color) + "\" WIDTH=\"" + (int) getWidth() + "\" HEIGHT=\"" + (int) getHeight()
|
||||
+ "\"></TD><TD></TD></TR>");
|
||||
sb.append("<TR><TD WIDTH=\"" + fullWidth + "\" HEIGHT=\"1\" COLSPAN=\"3\"></TD></TR>");
|
||||
sb.append("</TABLE>");
|
||||
sb.append(">];");
|
||||
}
|
||||
|
||||
private void appendLabelHtmlSpecialForPortBasic(StringBuilder sb, StringBounder stringBounder) {
|
||||
sb.append(uid);
|
||||
sb.append(" [");
|
||||
sb.append("shape=rect");
|
||||
@ -294,8 +334,6 @@ public class SvekNode implements Positionable, IShapePseudo, Hideable {
|
||||
sb.append("shape=diamond");
|
||||
else if (type == ShapeType.CIRCLE)
|
||||
sb.append("shape=circle");
|
||||
else if (type == ShapeType.CIRCLE_IN_RECT)
|
||||
sb.append("shape=circle");
|
||||
else if (type == ShapeType.OVAL)
|
||||
sb.append("shape=ellipse");
|
||||
else if (type == ShapeType.ROUND_RECTANGLE)
|
||||
@ -349,16 +387,6 @@ public class SvekNode implements Positionable, IShapePseudo, Hideable {
|
||||
this.minY += deltaY;
|
||||
}
|
||||
|
||||
public double getMaxWidthFromLabelForEntryExit(StringBounder stringBounder) {
|
||||
if (image instanceof AbstractEntityImageBorder) {
|
||||
final AbstractEntityImageBorder im = (AbstractEntityImageBorder) image;
|
||||
return im.getMaxWidthFromLabelForEntryExit(stringBounder);
|
||||
} else {
|
||||
final Dimension2D dim = image.calculateDimension(stringBounder);
|
||||
return dim.getWidth();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isHidden() {
|
||||
return image.isHidden();
|
||||
}
|
||||
|
@ -82,11 +82,6 @@ public abstract class AbstractEntityImageBorder extends AbstractEntityImage {
|
||||
return entityPosition.getDimension(rankdir);
|
||||
}
|
||||
|
||||
public double getMaxWidthFromLabelForEntryExit(StringBounder stringBounder) {
|
||||
final Dimension2D dimDesc = desc.calculateDimension(stringBounder);
|
||||
return dimDesc.getWidth();
|
||||
}
|
||||
|
||||
public ShapeType getShapeType() {
|
||||
return entityPosition.getShapeType();
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ public class EntityImageLollipopInterface extends AbstractEntityImage {
|
||||
}
|
||||
|
||||
public ShapeType getShapeType() {
|
||||
return ShapeType.CIRCLE_IN_RECT;
|
||||
return ShapeType.CIRCLE;
|
||||
}
|
||||
|
||||
private double angle;
|
||||
|
@ -42,6 +42,7 @@ import net.sourceforge.plantuml.ISkinParam;
|
||||
import net.sourceforge.plantuml.awt.geom.Dimension2D;
|
||||
import net.sourceforge.plantuml.cucadiagram.EntityPosition;
|
||||
import net.sourceforge.plantuml.cucadiagram.ILeaf;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.graphic.color.ColorType;
|
||||
import net.sourceforge.plantuml.style.PName;
|
||||
import net.sourceforge.plantuml.style.SName;
|
||||
@ -106,5 +107,11 @@ public class EntityImageStateBorder extends AbstractEntityImageBorder {
|
||||
private UStroke getUStroke() {
|
||||
return new UStroke(1.5);
|
||||
}
|
||||
|
||||
public double getMaxWidthFromLabelForEntryExit(StringBounder stringBounder) {
|
||||
final Dimension2D dimDesc = desc.calculateDimension(stringBounder);
|
||||
return dimDesc.getWidth();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ public class Version {
|
||||
}
|
||||
|
||||
public static int beta() {
|
||||
final int beta = 4;
|
||||
final int beta = 5;
|
||||
return beta;
|
||||
}
|
||||
|
||||
|
@ -52,10 +52,15 @@ import javax.xml.transform.stream.StreamResult;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import net.sourceforge.plantuml.Guillemet;
|
||||
import net.sourceforge.plantuml.cucadiagram.Display;
|
||||
import net.sourceforge.plantuml.cucadiagram.EntityUtils;
|
||||
import net.sourceforge.plantuml.cucadiagram.IEntity;
|
||||
import net.sourceforge.plantuml.cucadiagram.IGroup;
|
||||
import net.sourceforge.plantuml.cucadiagram.ILeaf;
|
||||
import net.sourceforge.plantuml.cucadiagram.LeafType;
|
||||
import net.sourceforge.plantuml.cucadiagram.Link;
|
||||
import net.sourceforge.plantuml.cucadiagram.Stereotype;
|
||||
import net.sourceforge.plantuml.statediagram.StateDiagram;
|
||||
import net.sourceforge.plantuml.xml.XmlFactories;
|
||||
|
||||
@ -76,34 +81,54 @@ public class ScxmlStateDiagramStandard {
|
||||
scxml.setAttribute("xmlns", "http://www.w3.org/2005/07/scxml");
|
||||
scxml.setAttribute("version", "1.0");
|
||||
final String initial = getInitial();
|
||||
if (initial != null) {
|
||||
if (initial != null)
|
||||
scxml.setAttribute("initial", initial);
|
||||
}
|
||||
|
||||
document.appendChild(scxml);
|
||||
|
||||
for (final IEntity ent : diagram.getLeafsvalues()) {
|
||||
scxml.appendChild(createState(ent));
|
||||
}
|
||||
for (final IEntity ent : diagram.getLeafsvalues())
|
||||
if (EntityUtils.groupRoot(ent.getParentContainer()))
|
||||
scxml.appendChild(createState(ent));
|
||||
|
||||
for (IGroup ent : diagram.getGroups(false))
|
||||
if (EntityUtils.groupRoot(ent.getParentContainer()))
|
||||
exportGroup(scxml, ent);
|
||||
|
||||
}
|
||||
|
||||
private Element exportGroup(Element dest, IGroup ent) {
|
||||
final Element gr = createGroup(ent);
|
||||
dest.appendChild(gr);
|
||||
for (ILeaf leaf : ent.getLeafsDirect())
|
||||
gr.appendChild(createState(leaf));
|
||||
for (IGroup child : ent.getChildren())
|
||||
exportGroup(gr, child);
|
||||
return gr;
|
||||
}
|
||||
|
||||
private String getInitial() {
|
||||
for (final IEntity ent : diagram.getLeafsvalues()) {
|
||||
if (ent.getLeafType() == LeafType.CIRCLE_START) {
|
||||
for (final IEntity ent : diagram.getLeafsvalues())
|
||||
if (ent.getLeafType() == LeafType.CIRCLE_START)
|
||||
return getId(ent);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Element createGroup(IEntity entity) {
|
||||
return createState(entity);
|
||||
}
|
||||
|
||||
private Element createState(IEntity entity) {
|
||||
final Element state = document.createElement("state");
|
||||
state.setAttribute("id", getId(entity));
|
||||
for (final Link link : diagram.getLinks()) {
|
||||
if (link.getEntity1() == entity) {
|
||||
addLink(state, link);
|
||||
}
|
||||
final Stereotype stereotype = entity.getStereotype();
|
||||
if (stereotype != null) {
|
||||
state.setAttribute("stereotype", stereotype.getLabels(Guillemet.NONE).get(0));
|
||||
}
|
||||
for (final Link link : diagram.getLinks())
|
||||
if (link.getEntity1() == entity)
|
||||
addLink(state, link);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
@ -33,20 +33,22 @@ Expected result MUST be put between triple brackets
|
||||
|
||||
{{{
|
||||
<?xml version="1.0" encoding="UTF-8"?><scxml xmlns="http://www.w3.org/2005/07/scxml" initial="startcounter" version="1.0">
|
||||
<state id="count_start"/>
|
||||
<state id="count_done"/>
|
||||
<state id="count_val[3:0]"/>
|
||||
<state id="startcounter">
|
||||
<transition target="count_idle"/>
|
||||
</state>
|
||||
<state id="count_idle">
|
||||
<transition event="count_start" target="count_ongoing"/>
|
||||
</state>
|
||||
<state id="count_ongoing">
|
||||
<transition event="count_val != MAX_VAL" target="count_finish"/>
|
||||
</state>
|
||||
<state id="count_finish">
|
||||
<transition target="count_idle"/>
|
||||
<state id="counter">
|
||||
<state id="count_start"/>
|
||||
<state id="count_done"/>
|
||||
<state id="count_val[3:0]"/>
|
||||
<state id="startcounter">
|
||||
<transition target="count_idle"/>
|
||||
</state>
|
||||
<state id="count_idle">
|
||||
<transition event="count_start" target="count_ongoing"/>
|
||||
</state>
|
||||
<state id="count_ongoing">
|
||||
<transition event="count_val != MAX_VAL" target="count_finish"/>
|
||||
</state>
|
||||
<state id="count_finish">
|
||||
<transition target="count_idle"/>
|
||||
</state>
|
||||
</state>
|
||||
</scxml>
|
||||
}}}
|
||||
|
118
test/nonreg/scxml/SCXML0003_Test.java
Normal file
118
test/nonreg/scxml/SCXML0003_Test.java
Normal file
@ -0,0 +1,118 @@
|
||||
package nonreg.scxml;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/*
|
||||
|
||||
|
||||
https://github.com/plantuml/plantuml/issues/1101
|
||||
|
||||
|
||||
Test diagram MUST be put between triple quotes
|
||||
|
||||
"""
|
||||
@startuml
|
||||
|
||||
state module {
|
||||
state Somp {
|
||||
state entry1 <<inputPin>>
|
||||
state entry2 <<inputPin>>
|
||||
state sin
|
||||
sin -> sin2
|
||||
}
|
||||
|
||||
state flop{
|
||||
state sig_in <<inputPin>>
|
||||
state sig_ff <<outputPin>>
|
||||
state flop_0: sig_ff := 0
|
||||
state flop_1: sig_ff := 1
|
||||
[*] -> flop_0
|
||||
flop_0 -> flop_1 : sig_in
|
||||
|
||||
}
|
||||
|
||||
state counter{
|
||||
state count_start <<inputPin>>
|
||||
state count_done <<outputPin>>
|
||||
state "count_val[3:0]" <<outputPin>>
|
||||
[*] -> count_idle
|
||||
count_idle --> count_ongoing: count_start
|
||||
state count_idle: count_val := 0
|
||||
state count_ongoing: count_val := count_val +1
|
||||
count_ongoing -> count_finish: count_val != MAX_VAL
|
||||
state count_finish: count_done:=1
|
||||
count_finish -> count_idle
|
||||
|
||||
}
|
||||
state ex <<inputPin>>
|
||||
state exitAx <<inputPin>>
|
||||
|
||||
exitAx --> entry1
|
||||
sig_ff -> entry2 : "!"
|
||||
|
||||
|
||||
}
|
||||
@enduml
|
||||
"""
|
||||
|
||||
Expected result MUST be put between triple brackets
|
||||
|
||||
{{{
|
||||
<?xml version="1.0" encoding="UTF-8"?><scxml xmlns="http://www.w3.org/2005/07/scxml" initial="startflop" version="1.0">
|
||||
<state id="module">
|
||||
<state id="ex" stereotype="inputPin"/>
|
||||
<state id="exitAx" stereotype="inputPin">
|
||||
<transition target="entry1"/>
|
||||
</state>
|
||||
<state id="Somp">
|
||||
<state id="entry1" stereotype="inputPin"/>
|
||||
<state id="entry2" stereotype="inputPin"/>
|
||||
<state id="sin">
|
||||
<transition target="sin2"/>
|
||||
</state>
|
||||
<state id="sin2"/>
|
||||
</state>
|
||||
<state id="flop">
|
||||
<state id="sig_in" stereotype="inputPin"/>
|
||||
<state id="sig_ff" stereotype="outputPin">
|
||||
<transition event=""!"" target="entry2"/>
|
||||
</state>
|
||||
<state id="flop_0">
|
||||
<transition event="sig_in" target="flop_1"/>
|
||||
</state>
|
||||
<state id="flop_1"/>
|
||||
<state id="startflop">
|
||||
<transition target="flop_0"/>
|
||||
</state>
|
||||
</state>
|
||||
<state id="counter">
|
||||
<state id="count_start" stereotype="inputPin"/>
|
||||
<state id="count_done" stereotype="outputPin"/>
|
||||
<state id="count_val[3:0]" stereotype="outputPin"/>
|
||||
<state id="startcounter">
|
||||
<transition target="count_idle"/>
|
||||
</state>
|
||||
<state id="count_idle">
|
||||
<transition event="count_start" target="count_ongoing"/>
|
||||
</state>
|
||||
<state id="count_ongoing">
|
||||
<transition event="count_val != MAX_VAL" target="count_finish"/>
|
||||
</state>
|
||||
<state id="count_finish">
|
||||
<transition target="count_idle"/>
|
||||
</state>
|
||||
</state>
|
||||
</state>
|
||||
</scxml>
|
||||
}}}
|
||||
*/
|
||||
public class SCXML0003_Test extends ScXmlTest {
|
||||
|
||||
@Test
|
||||
void testSimple() throws IOException {
|
||||
checkXmlAndDescription("(18 entities)");
|
||||
}
|
||||
|
||||
}
|
55
test/nonreg/scxml/SCXML0004_Test.java
Normal file
55
test/nonreg/scxml/SCXML0004_Test.java
Normal file
@ -0,0 +1,55 @@
|
||||
package nonreg.scxml;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/*
|
||||
|
||||
|
||||
https://github.com/plantuml/plantuml/issues/1101
|
||||
|
||||
|
||||
Test diagram MUST be put between triple quotes
|
||||
|
||||
"""
|
||||
@startuml
|
||||
|
||||
state module {
|
||||
state flop
|
||||
state Somp {
|
||||
state entry1 <<inputPin>>
|
||||
state entry2 <<inputPin>>
|
||||
state sin
|
||||
sin -> sin2
|
||||
}
|
||||
}
|
||||
@enduml
|
||||
"""
|
||||
|
||||
Expected result MUST be put between triple brackets
|
||||
|
||||
{{{
|
||||
<?xml version="1.0" encoding="UTF-8"?><scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0">
|
||||
<state id="module">
|
||||
<state id="flop"/>
|
||||
<state id="Somp">
|
||||
<state id="entry1" stereotype="inputPin"/>
|
||||
<state id="entry2" stereotype="inputPin"/>
|
||||
<state id="sin">
|
||||
<transition target="sin2"/>
|
||||
</state>
|
||||
<state id="sin2"/>
|
||||
</state>
|
||||
</state>
|
||||
</scxml>
|
||||
}}}
|
||||
*/
|
||||
public class SCXML0004_Test extends ScXmlTest {
|
||||
|
||||
@Test
|
||||
void testSimple() throws IOException {
|
||||
checkXmlAndDescription("(5 entities)");
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user