mirror of
https://github.com/octoleo/plantuml.git
synced 2024-12-22 10:59:01 +00:00
version 8056
This commit is contained in:
parent
a2cbfb5712
commit
c7252cdf63
5
pom.xml
5
pom.xml
@ -30,13 +30,12 @@
|
||||
Script Author: Julien Eluard
|
||||
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>net.sourceforge.plantuml</groupId>
|
||||
<artifactId>plantuml</artifactId>
|
||||
<version>8055-SNAPSHOT</version>
|
||||
<version>8057-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>PlantUML</name>
|
||||
|
@ -81,7 +81,7 @@ public class BlockUml {
|
||||
this.data = new ArrayList<CharSequence2>(strings);
|
||||
}
|
||||
|
||||
public String getFileOrDirname() {
|
||||
public String getFileOrDirname(FileFormat defaultFileFormat) {
|
||||
if (OptionFlags.getInstance().isWord()) {
|
||||
return null;
|
||||
}
|
||||
@ -104,6 +104,9 @@ public class BlockUml {
|
||||
if (result.startsWith("file://")) {
|
||||
result = result.substring("file://".length());
|
||||
}
|
||||
if (result.contains(".") == false) {
|
||||
result = result + defaultFileFormat.getFileSuffix();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -44,16 +44,16 @@ public enum ColorParam {
|
||||
activityStart(HtmlColorUtils.BLACK),
|
||||
activityEnd(HtmlColorUtils.BLACK),
|
||||
activityBar(HtmlColorUtils.BLACK),
|
||||
activityArrow(HtmlColorUtils.MY_RED, ColorType.ARROW),
|
||||
// activityArrow(HtmlColorUtils.MY_RED, ColorType.ARROW),
|
||||
swimlaneBorder(HtmlColorUtils.BLACK),
|
||||
|
||||
usecaseBorder(HtmlColorUtils.MY_RED, ColorType.LINE),
|
||||
usecaseBackground(HtmlColorUtils.MY_YELLOW, true, ColorType.BACK),
|
||||
usecaseArrow(HtmlColorUtils.MY_RED, ColorType.ARROW),
|
||||
// usecaseArrow(HtmlColorUtils.MY_RED, ColorType.ARROW),
|
||||
|
||||
objectBackground(HtmlColorUtils.MY_YELLOW, true, ColorType.BACK),
|
||||
objectBorder(HtmlColorUtils.MY_RED, ColorType.LINE),
|
||||
objectArrow(HtmlColorUtils.MY_RED, ColorType.ARROW),
|
||||
// objectArrow(HtmlColorUtils.MY_RED, ColorType.ARROW),
|
||||
|
||||
classHeaderBackground(null, true, ColorType.BACK),
|
||||
classBackground(HtmlColorUtils.MY_YELLOW, true, ColorType.BACK),
|
||||
@ -63,7 +63,7 @@ public enum ColorParam {
|
||||
stereotypeABackground(HtmlColorUtils.COL_A9DCDF),
|
||||
stereotypeIBackground(HtmlColorUtils.COL_B4A7E5),
|
||||
stereotypeEBackground(HtmlColorUtils.COL_EB937F),
|
||||
classArrow(HtmlColorUtils.MY_RED, ColorType.ARROW),
|
||||
// classArrow(HtmlColorUtils.MY_RED, ColorType.ARROW),
|
||||
|
||||
packageBackground(HtmlColorUtils.MY_YELLOW, true, ColorType.BACK),
|
||||
packageBorder(HtmlColorUtils.BLACK, ColorType.LINE),
|
||||
@ -79,7 +79,7 @@ public enum ColorParam {
|
||||
|
||||
stateBackground(HtmlColorUtils.MY_YELLOW, true, ColorType.BACK),
|
||||
stateBorder(HtmlColorUtils.MY_RED, ColorType.LINE),
|
||||
stateArrow(HtmlColorUtils.MY_RED, ColorType.ARROW),
|
||||
// stateArrow(HtmlColorUtils.MY_RED, ColorType.ARROW),
|
||||
stateStart(HtmlColorUtils.BLACK),
|
||||
stateEnd(HtmlColorUtils.BLACK),
|
||||
|
||||
@ -109,7 +109,7 @@ public enum ColorParam {
|
||||
sequenceLifeLineBackground(HtmlColorUtils.WHITE, true, ColorType.BACK),
|
||||
sequenceLifeLineBorder(HtmlColorUtils.MY_RED, ColorType.LINE),
|
||||
sequenceNewpageSeparator(HtmlColorUtils.BLACK, ColorType.LINE),
|
||||
sequenceArrow(HtmlColorUtils.MY_RED),
|
||||
// sequenceArrow(HtmlColorUtils.MY_RED),
|
||||
sequenceBoxBorder(HtmlColorUtils.MY_RED, ColorType.LINE),
|
||||
sequenceBoxBackground(HtmlColorUtils.COL_DDDDDD, true, ColorType.BACK),
|
||||
|
||||
|
@ -49,9 +49,10 @@ public class FileFormatOption implements Serializable {
|
||||
private final boolean withMetadata;
|
||||
private final boolean useRedForError;
|
||||
private final String svgLinkTarget;
|
||||
private final String hoverColor;
|
||||
|
||||
public FileFormatOption(FileFormat fileFormat) {
|
||||
this(fileFormat, null, true, false, "_top", false);
|
||||
this(fileFormat, null, true, false, "_top", false, null);
|
||||
}
|
||||
|
||||
public StringBounder getDefaultStringBounder() {
|
||||
@ -67,11 +68,12 @@ public class FileFormatOption implements Serializable {
|
||||
}
|
||||
|
||||
public FileFormatOption(FileFormat fileFormat, boolean withMetadata) {
|
||||
this(fileFormat, null, false, false, "_top", false);
|
||||
this(fileFormat, null, false, false, "_top", false, null);
|
||||
}
|
||||
|
||||
private FileFormatOption(FileFormat fileFormat, AffineTransform at, boolean withMetadata, boolean useRedForError,
|
||||
String svgLinkTarget, boolean debugsvek) {
|
||||
String svgLinkTarget, boolean debugsvek, String hoverColor) {
|
||||
this.hoverColor = hoverColor;
|
||||
this.fileFormat = fileFormat;
|
||||
this.affineTransform = at;
|
||||
this.withMetadata = withMetadata;
|
||||
@ -81,11 +83,15 @@ public class FileFormatOption implements Serializable {
|
||||
}
|
||||
|
||||
public FileFormatOption withUseRedForError() {
|
||||
return new FileFormatOption(fileFormat, affineTransform, withMetadata, true, svgLinkTarget, debugsvek);
|
||||
return new FileFormatOption(fileFormat, affineTransform, withMetadata, true, svgLinkTarget, debugsvek, hoverColor);
|
||||
}
|
||||
|
||||
public FileFormatOption withSvgLinkTarget(String target) {
|
||||
return new FileFormatOption(fileFormat, affineTransform, withMetadata, useRedForError, target, debugsvek);
|
||||
public FileFormatOption withSvgLinkTarget(String svgLinkTarget) {
|
||||
return new FileFormatOption(fileFormat, affineTransform, withMetadata, useRedForError, svgLinkTarget, debugsvek, hoverColor);
|
||||
}
|
||||
|
||||
public FileFormatOption withHoverColor(String hoverColor) {
|
||||
return new FileFormatOption(fileFormat, affineTransform, withMetadata, useRedForError, svgLinkTarget, debugsvek, hoverColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -115,4 +121,8 @@ public class FileFormatOption implements Serializable {
|
||||
return debugsvek;
|
||||
}
|
||||
|
||||
public final String getHoverColor() {
|
||||
return hoverColor;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -42,8 +42,9 @@ interface FontParamConstant {
|
||||
public enum FontParam {
|
||||
ACTIVITY(12, Font.PLAIN), //
|
||||
ACTIVITY_DIAMOND(11, Font.PLAIN), //
|
||||
ACTIVITY_ARROW(11, Font.PLAIN), //
|
||||
GENERIC_ARROW(13, Font.PLAIN), //
|
||||
// ACTIVITY_ARROW(11, Font.PLAIN), //
|
||||
// GENERIC_ARROW(13, Font.PLAIN), //
|
||||
ARROW(13, Font.PLAIN), //
|
||||
CIRCLED_CHARACTER(17, Font.BOLD, FontParamConstant.COLOR, "Monospaced"), //
|
||||
OBJECT_ATTRIBUTE(10, Font.PLAIN), //
|
||||
OBJECT(12, Font.PLAIN), //
|
||||
@ -73,7 +74,7 @@ public enum FontParam {
|
||||
NODE(14, Font.PLAIN), //
|
||||
DATABASE(14, Font.PLAIN), //
|
||||
QUEUE(14, Font.PLAIN), //
|
||||
SEQUENCE_ARROW(13, Font.PLAIN), //
|
||||
// SEQUENCE_ARROW(13, Font.PLAIN), //
|
||||
SEQUENCE_BOX(13, Font.BOLD), //
|
||||
SEQUENCE_DIVIDER(13, Font.BOLD), //
|
||||
SEQUENCE_REFERENCE(13, Font.PLAIN), //
|
||||
@ -110,7 +111,6 @@ public enum FontParam {
|
||||
SEQUENCE_STEREOTYPE(14, Font.ITALIC), //
|
||||
PARTITION(14, Font.PLAIN); //
|
||||
|
||||
|
||||
private final int defaultSize;
|
||||
private final int fontStyle;
|
||||
private final String defaultColor;
|
||||
@ -128,6 +128,9 @@ public enum FontParam {
|
||||
}
|
||||
|
||||
public final int getDefaultSize(ISkinParam skinParam) {
|
||||
if (this == ARROW && skinParam.getUmlDiagramType() == UmlDiagramType.ACTIVITY) {
|
||||
return 11;
|
||||
}
|
||||
if (this == CLASS_ATTRIBUTE) {
|
||||
return 11;
|
||||
}
|
||||
|
@ -130,4 +130,9 @@ public interface ISkinParam extends ISkinSimple {
|
||||
|
||||
public int swimlaneWidth();
|
||||
|
||||
public UmlDiagramType getUmlDiagramType();
|
||||
|
||||
public HtmlColor getHoverPathColor();
|
||||
|
||||
|
||||
}
|
@ -30,8 +30,6 @@
|
||||
*/
|
||||
package net.sourceforge.plantuml;
|
||||
|
||||
import h.stack;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@ -76,6 +74,7 @@ public class SkinParam implements ISkinParam {
|
||||
private final Map<String, String> params = new HashMap<String, String>();
|
||||
private Rankdir rankdir = Rankdir.TOP_TO_BOTTOM;
|
||||
private String dotExecutable;
|
||||
private final UmlDiagramType type;
|
||||
|
||||
public String getDotExecutable() {
|
||||
return dotExecutable;
|
||||
@ -89,8 +88,16 @@ public class SkinParam implements ISkinParam {
|
||||
params.put(cleanForKey(key), StringUtils.trin(value));
|
||||
}
|
||||
|
||||
public static SkinParam noShadowing() {
|
||||
final SkinParam result = new SkinParam();
|
||||
private SkinParam(UmlDiagramType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public static SkinParam create(UmlDiagramType type) {
|
||||
return new SkinParam(type);
|
||||
}
|
||||
|
||||
public static SkinParam noShadowing(UmlDiagramType type) {
|
||||
final SkinParam result = new SkinParam(type);
|
||||
result.setParam("shadowing", "false");
|
||||
return result;
|
||||
}
|
||||
@ -101,16 +108,17 @@ public class SkinParam implements ISkinParam {
|
||||
// key = replaceSmart(key, "partition", "package");
|
||||
key = replaceSmart(key, "sequenceparticipant", "participant");
|
||||
key = replaceSmart(key, "sequenceactor", "actor");
|
||||
if (key.contains("arrow")) {
|
||||
key = key.replaceAll("activityarrow|objectarrow|classarrow|componentarrow|statearrow|usecasearrow",
|
||||
"genericarrow");
|
||||
}
|
||||
// // key = key.replaceAll("activityarrow", "genericarrow");
|
||||
// // key = key.replaceAll("objectarrow", "genericarrow");
|
||||
// // key = key.replaceAll("classarrow", "genericarrow");
|
||||
// // key = key.replaceAll("componentarrow", "genericarrow");
|
||||
// // key = key.replaceAll("statearrow", "genericarrow");
|
||||
// // key = key.replaceAll("usecasearrow", "genericarrow");
|
||||
// if (key.contains("arrow")) {
|
||||
// key = key.replaceAll("activityarrow|objectarrow|classarrow|componentarrow|statearrow|usecasearrow",
|
||||
// "genericarrow");
|
||||
// }
|
||||
key = key.replaceAll("activityarrow", "arrow");
|
||||
key = key.replaceAll("objectarrow", "arrow");
|
||||
key = key.replaceAll("classarrow", "arrow");
|
||||
key = key.replaceAll("componentarrow", "arrow");
|
||||
key = key.replaceAll("statearrow", "arrow");
|
||||
key = key.replaceAll("usecasearrow", "arrow");
|
||||
key = key.replaceAll("sequencearrow", "arrow");
|
||||
final Matcher2 m = stereoPattern.matcher(key);
|
||||
if (m.find()) {
|
||||
final String s = m.group(1);
|
||||
@ -819,4 +827,16 @@ public class SkinParam implements ISkinParam {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public HtmlColor getHoverPathColor() {
|
||||
final String value = getValue("pathhovercolor");
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return getIHtmlColorSet().getColorIfValid(value, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -246,4 +246,12 @@ public class SkinParamDelegator implements ISkinParam {
|
||||
return skinParam.swimlaneWidth();
|
||||
}
|
||||
|
||||
public UmlDiagramType getUmlDiagramType() {
|
||||
return skinParam.getUmlDiagramType();
|
||||
}
|
||||
|
||||
public HtmlColor getHoverPathColor() {
|
||||
return skinParam.getHoverPathColor();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ public class SourceFileReader implements ISourceFileReader {
|
||||
final List<GeneratedImage> result = new ArrayList<GeneratedImage>();
|
||||
|
||||
for (BlockUml blockUml : builder.getBlockUmls()) {
|
||||
String newName = blockUml.getFileOrDirname();
|
||||
String newName = blockUml.getFileOrDirname(fileFormatOption.getFileFormat());
|
||||
Log.info("name from block=" + newName);
|
||||
File suggested = null;
|
||||
if (newName != null) {
|
||||
|
@ -62,6 +62,7 @@ import net.sourceforge.plantuml.fun.IconLoader;
|
||||
import net.sourceforge.plantuml.graphic.GraphicPosition;
|
||||
import net.sourceforge.plantuml.graphic.GraphicStrings;
|
||||
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
|
||||
import net.sourceforge.plantuml.graphic.HtmlColor;
|
||||
import net.sourceforge.plantuml.graphic.HtmlColorUtils;
|
||||
import net.sourceforge.plantuml.graphic.UDrawable;
|
||||
import net.sourceforge.plantuml.graphic.VerticalAlignment;
|
||||
@ -95,7 +96,7 @@ public abstract class UmlDiagram extends AbstractPSystem implements Diagram, Ann
|
||||
private Scale scale;
|
||||
private Animation animation;
|
||||
|
||||
private final SkinParam skinParam = new SkinParam();
|
||||
private final SkinParam skinParam = SkinParam.create(getUmlDiagramType());
|
||||
|
||||
final public void setTitle(DisplayPositionned title) {
|
||||
this.title = title;
|
||||
@ -215,7 +216,12 @@ public abstract class UmlDiagram extends AbstractPSystem implements Diagram, Ann
|
||||
final protected ImageData exportDiagramNow(OutputStream os, int index, FileFormatOption fileFormatOption)
|
||||
throws IOException {
|
||||
|
||||
final HtmlColor hover = getSkinParam().getHoverPathColor();
|
||||
fileFormatOption = fileFormatOption.withSvgLinkTarget(getSkinParam().getSvgLinkTarget());
|
||||
if (hover != null) {
|
||||
fileFormatOption = fileFormatOption.withHoverColor(StringUtils.getAsHtml(getSkinParam().getColorMapper()
|
||||
.getMappedColor(hover)));
|
||||
}
|
||||
|
||||
if (fileFormatOption.getFileFormat() == FileFormat.PDF) {
|
||||
return exportDiagramInternalPdf(os, index);
|
||||
|
@ -52,7 +52,7 @@ public class CommandWhile3 extends SingleLineCommand2<ActivityDiagram3> {
|
||||
new RegexLeaf("^"), //
|
||||
ColorParser.exp4(), //
|
||||
new RegexLeaf("while"), //
|
||||
new RegexLeaf("TEST", "[%s]*\\((.+?)\\)"), //
|
||||
new RegexLeaf("TEST", "[%s]*\\((.*?)\\)"), //
|
||||
new RegexOptional(new RegexConcat(//
|
||||
new RegexLeaf("[%s]*(is|equals?)[%s]*"), //
|
||||
new RegexLeaf("YES", "\\((.+?)\\)"))), //
|
||||
|
@ -77,7 +77,7 @@ public class FtileFactoryDelegator implements FtileFactory {
|
||||
if (Display.isNull(display)) {
|
||||
return null;
|
||||
}
|
||||
final FontConfiguration fontConfiguration = new FontConfiguration(skinParam(), FontParam.ACTIVITY_ARROW, null);
|
||||
final FontConfiguration fontConfiguration = new FontConfiguration(skinParam(), FontParam.ARROW, null);
|
||||
return display.create(fontConfiguration, HorizontalAlignment.LEFT, skinParam(), CreoleMode.SIMPLE_LINE);
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ public class FtileFactoryDelegatorCreateGroup extends FtileFactoryDelegator {
|
||||
@Override
|
||||
public Ftile createGroup(Ftile list, Display name, HtmlColor backColor, HtmlColor titleColor, PositionedNote note,
|
||||
HtmlColor borderColor) {
|
||||
final HtmlColor arrowColor = rose.getHtmlColor(skinParam(), ColorParam.activityArrow);
|
||||
final HtmlColor arrowColor = rose.getHtmlColor(skinParam(), ColorParam.arrow);
|
||||
Ftile result = new FtileGroup(list, name, null, arrowColor, backColor, titleColor, skinParam(), borderColor);
|
||||
if (note != null) {
|
||||
result = new FtileWithNotes(result, Collections.singleton(note), skinParam());
|
||||
|
@ -69,7 +69,7 @@ public class FtileFactoryDelegatorIf extends FtileFactoryDelegator {
|
||||
ColorParam.activityBackground) : branch0.getColor();
|
||||
final Rainbow arrowColor = HtmlColorAndStyle.build(skinParam());
|
||||
|
||||
final FontConfiguration fcArrow = new FontConfiguration(skinParam(), FontParam.ACTIVITY_ARROW, null);
|
||||
final FontConfiguration fcArrow = new FontConfiguration(skinParam(), FontParam.ARROW, null);
|
||||
// .changeColor(fontColor(FontParam.ACTIVITY_DIAMOND));
|
||||
if (thens.size() > 1) {
|
||||
if (pragma.useVerticalIf()/* OptionFlags.USE_IF_VERTICAL */)
|
||||
@ -79,7 +79,7 @@ public class FtileFactoryDelegatorIf extends FtileFactoryDelegator {
|
||||
conditionStyle, thens, elseBranch, fcArrow, topInlinkRendering, afterEndwhile);
|
||||
}
|
||||
final FontParam testParam = conditionStyle == ConditionStyle.INSIDE ? FontParam.ACTIVITY_DIAMOND
|
||||
: FontParam.ACTIVITY_ARROW;
|
||||
: FontParam.ARROW;
|
||||
final FontConfiguration fcTest = new FontConfiguration(skinParam(), testParam, null)
|
||||
.changeColor(fontColor(FontParam.ACTIVITY_DIAMOND));
|
||||
|
||||
|
@ -78,7 +78,7 @@ public class FtileFactoryDelegatorRepeat extends FtileFactoryDelegator {
|
||||
final Rainbow endRepeatLinkColor = endRepeatLinkRendering == null ? null : endRepeatLinkRendering.getRainbow();
|
||||
|
||||
final FontConfiguration fcDiamond = new FontConfiguration(skinParam(), FontParam.ACTIVITY_DIAMOND, null);
|
||||
final FontConfiguration fcArrow = new FontConfiguration(skinParam(), FontParam.ACTIVITY_ARROW, null);
|
||||
final FontConfiguration fcArrow = new FontConfiguration(skinParam(), FontParam.ARROW, null);
|
||||
|
||||
Ftile result = FtileRepeat.create(backRepeatLinkRendering, swimlane, swimlaneOut, repeat, test, yes, out,
|
||||
borderColor, backColor, arrowColor, endRepeatLinkColor, conditionStyle, this.skinParam(), fcDiamond,
|
||||
|
@ -60,14 +60,14 @@ public class FtileFactoryDelegatorWhile extends FtileFactoryDelegator {
|
||||
|
||||
final ConditionStyle conditionStyle = skinParam().getConditionStyle();
|
||||
final FontParam testParam = conditionStyle == ConditionStyle.INSIDE ? FontParam.ACTIVITY_DIAMOND
|
||||
: FontParam.ACTIVITY_ARROW;
|
||||
: FontParam.ARROW;
|
||||
final FontConfiguration fcTest = new FontConfiguration(skinParam(), testParam, null);
|
||||
|
||||
final LinkRendering endInlinkRendering = whileBlock.getOutLinkRendering();
|
||||
final Rainbow endInlinkColor = endInlinkRendering == null || endInlinkRendering.getRainbow().size() == 0 ? arrowColor
|
||||
: endInlinkRendering.getRainbow();
|
||||
|
||||
final FontConfiguration fontArrow = new FontConfiguration(skinParam(), FontParam.ACTIVITY_ARROW, null);
|
||||
final FontConfiguration fontArrow = new FontConfiguration(skinParam(), FontParam.ARROW, null);
|
||||
|
||||
return FtileWhile.create(swimlane, whileBlock, test, borderColor, backColor, arrowColor, yes, out,
|
||||
endInlinkColor, afterEndwhile, fontArrow, getFactory(), conditionStyle, fcTest);
|
||||
|
@ -33,6 +33,8 @@ package net.sourceforge.plantuml.activitydiagram3.ftile.vcompact;
|
||||
import java.awt.geom.Dimension2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@ -464,6 +466,14 @@ class FtileIfLongHorizontal extends AbstractFtile {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Ftile> getMyChildren() {
|
||||
final List<Ftile> result = new ArrayList<Ftile>(tiles);
|
||||
result.add(tile2);
|
||||
return Collections.unmodifiableList(result);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public UTranslate getTranslateFor(Ftile child, StringBounder stringBounder) {
|
||||
if (child == tile2) {
|
||||
@ -472,6 +482,9 @@ class FtileIfLongHorizontal extends AbstractFtile {
|
||||
if (couples.contains(child)) {
|
||||
return getTranslateCouple1(child, stringBounder);
|
||||
}
|
||||
if (tiles.contains(child)) {
|
||||
return getTranslate1(child, stringBounder);
|
||||
}
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
@ -162,8 +162,8 @@ public class FtileWithNotes extends AbstractFtile {
|
||||
|
||||
public void drawU(UGraphic ug) {
|
||||
final StringBounder stringBounder = ug.getStringBounder();
|
||||
ug.apply(getTranslateForLeft(stringBounder)).draw(left);
|
||||
ug.apply(getTranslateForRight(stringBounder)).draw(right);
|
||||
left.drawU(ug.apply(getTranslateForLeft(stringBounder)));
|
||||
right.drawU(ug.apply(getTranslateForRight(stringBounder)));
|
||||
ug.apply(getTranslate(stringBounder)).draw(tile);
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,7 @@ public abstract class ParallelFtilesBuilder {
|
||||
if (Display.isNull(display)) {
|
||||
return null;
|
||||
}
|
||||
final FontConfiguration fontConfiguration = new FontConfiguration(skinParam(), FontParam.ACTIVITY_ARROW, null);
|
||||
final FontConfiguration fontConfiguration = new FontConfiguration(skinParam(), FontParam.ARROW, null);
|
||||
return display.create(fontConfiguration, HorizontalAlignment.LEFT, skinParam(), CreoleMode.SIMPLE_LINE);
|
||||
}
|
||||
|
||||
|
@ -30,11 +30,13 @@
|
||||
*/
|
||||
package net.sourceforge.plantuml.activitydiagram3.ftile.vertical;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import net.sourceforge.plantuml.ISkinParam;
|
||||
import net.sourceforge.plantuml.activitydiagram3.ftile.AbstractFtile;
|
||||
import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile;
|
||||
import net.sourceforge.plantuml.activitydiagram3.ftile.FtileGeometry;
|
||||
import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane;
|
||||
import net.sourceforge.plantuml.graphic.HtmlColor;
|
||||
@ -55,6 +57,11 @@ public class FtileCircleEnd extends AbstractFtile {
|
||||
private final HtmlColor backColor;
|
||||
private final Swimlane swimlane;
|
||||
|
||||
@Override
|
||||
public Collection<Ftile> getMyChildren() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public FtileCircleEnd(ISkinParam skinParam, HtmlColor backColor, Swimlane swimlane) {
|
||||
super(skinParam);
|
||||
this.backColor = backColor;
|
||||
|
@ -30,11 +30,13 @@
|
||||
*/
|
||||
package net.sourceforge.plantuml.activitydiagram3.ftile.vertical;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import net.sourceforge.plantuml.ISkinParam;
|
||||
import net.sourceforge.plantuml.activitydiagram3.ftile.AbstractFtile;
|
||||
import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile;
|
||||
import net.sourceforge.plantuml.activitydiagram3.ftile.FtileGeometry;
|
||||
import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane;
|
||||
import net.sourceforge.plantuml.graphic.HtmlColor;
|
||||
@ -57,6 +59,11 @@ public class FtileCircleStart extends AbstractFtile {
|
||||
this.swimlane = swimlane;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Ftile> getMyChildren() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public Set<Swimlane> getSwimlanes() {
|
||||
if (swimlane == null) {
|
||||
return Collections.emptySet();
|
||||
|
@ -30,11 +30,13 @@
|
||||
*/
|
||||
package net.sourceforge.plantuml.activitydiagram3.ftile.vertical;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import net.sourceforge.plantuml.ISkinParam;
|
||||
import net.sourceforge.plantuml.activitydiagram3.ftile.AbstractFtile;
|
||||
import net.sourceforge.plantuml.activitydiagram3.ftile.Ftile;
|
||||
import net.sourceforge.plantuml.activitydiagram3.ftile.FtileGeometry;
|
||||
import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane;
|
||||
import net.sourceforge.plantuml.graphic.HtmlColor;
|
||||
@ -52,6 +54,11 @@ public class FtileCircleStop extends AbstractFtile {
|
||||
private final HtmlColor backColor;
|
||||
private final Swimlane swimlane;
|
||||
|
||||
@Override
|
||||
public Collection<Ftile> getMyChildren() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public FtileCircleStop(ISkinParam skinParam, HtmlColor backColor, Swimlane swimlane) {
|
||||
super(skinParam);
|
||||
this.backColor = backColor;
|
||||
|
@ -164,14 +164,17 @@ public class LinkType {
|
||||
sb.append("arrowtail=empty");
|
||||
sb.append(",arrowhead=none");
|
||||
sb.append(",dir=back");
|
||||
} else if (isEmpty1 == false && isEmpty2) {
|
||||
sb.append("arrowtail=none");
|
||||
sb.append(",arrowhead=empty");
|
||||
// } else if (isEmpty1 == false && isEmpty2) {
|
||||
// sb.append("arrowtail=none");
|
||||
// sb.append(",arrowhead=empty");
|
||||
}
|
||||
|
||||
final double arrowsize = Math.max(decor1.getArrowSize(), decor2.getArrowSize());
|
||||
if (arrowsize > 0) {
|
||||
sb.append(",arrowsize=" + arrowsize);
|
||||
if (sb.length() > 0) {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append("arrowsize=" + arrowsize);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ public class HtmlColorAndStyle {
|
||||
}
|
||||
|
||||
public static Rainbow build(ISkinParam skinParam) {
|
||||
return fromColor(rose.getHtmlColor(skinParam, ColorParam.activityArrow));
|
||||
return fromColor(rose.getHtmlColor(skinParam, ColorParam.arrow));
|
||||
}
|
||||
|
||||
private HtmlColorAndStyle(HtmlColor color) {
|
||||
|
@ -199,7 +199,11 @@ public class QuoteUtils {
|
||||
"Vf guvf n aba-mreb-fhz tnzr?", "Abj gung'f n cebcre vagebqhpgvba.",
|
||||
"Rirelguvat unf punatrq naq vg jba'g fgbc punatvat nalgvzr fbba.",
|
||||
"Jung znxrf lbh qvssrerag znxrf lbh qnatrebhf", "Qviretrapr vf rkgerzryl qnatrebhf",
|
||||
"V'z Qviretrag. Naq V pna'g or pbagebyyrq", "Znl gur bqqf or rire va lbhe snibe");
|
||||
"V'z Qviretrag. Naq V pna'g or pbagebyyrq", "Znl gur bqqf or rire va lbhe snibe",
|
||||
"Ab WninFpevcg senzrjbexf jrer perngrq qhevat gur jevgvat bs guvf zrffntr.",
|
||||
"P'rfg cerffr-cherr dhv g'nf vagreebtr ?",
|
||||
"Ybbx, nygreangvir snpgf ner abg snpgf. Gurl'er snyfrubbqf",
|
||||
"Guvf vf abg n penfu, guvf vf zber bs na nygreangvir erfhyg.");
|
||||
|
||||
private QuoteUtils() {
|
||||
}
|
||||
|
@ -94,6 +94,10 @@ public class SymbolContext {
|
||||
return new SymbolContext(backColor, foreColor, stroke, shadowing, deltaShadow, roundCorner);
|
||||
}
|
||||
|
||||
public SymbolContext withForeColor(HtmlColor foreColor) {
|
||||
return new SymbolContext(backColor, foreColor, stroke, shadowing, deltaShadow, roundCorner);
|
||||
}
|
||||
|
||||
public SymbolContext withRoundCorner(double roundCorner) {
|
||||
return new SymbolContext(backColor, foreColor, stroke, shadowing, deltaShadow, roundCorner);
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ public class CucaDiagramFileMakerHectorB1 implements CucaDiagramFileMaker {
|
||||
final double y2 = getY(pinLink.getPin2());
|
||||
|
||||
final Rose rose = new Rose();
|
||||
final HtmlColor color = rose.getHtmlColor(diagram.getSkinParam(), ColorParam.classArrow);
|
||||
final HtmlColor color = rose.getHtmlColor(diagram.getSkinParam(), ColorParam.arrow);
|
||||
final List<Box2D> b = new ArrayList<Box2D>();
|
||||
final SmartConnection connection = new SmartConnection(x1, y1, x2, y2, b);
|
||||
connection.draw(ug, color);
|
||||
|
@ -480,7 +480,7 @@ public class CucaDiagramFileMakerJDot implements CucaDiagramFileMaker {
|
||||
private TextBlock getLabel(Link link) {
|
||||
final double marginLabel = 1; // startUid.equals(endUid) ? 6 : 1;
|
||||
ISkinParam skinParam = diagram.getSkinParam();
|
||||
final FontConfiguration labelFont = new FontConfiguration(skinParam, FontParam.GENERIC_ARROW, null);
|
||||
final FontConfiguration labelFont = new FontConfiguration(skinParam, FontParam.ARROW, null);
|
||||
final TextBlock label = link.getLabel().create(labelFont,
|
||||
skinParam.getDefaultTextAlignment(HorizontalAlignment.CENTER), skinParam);
|
||||
if (TextBlockUtils.isEmpty(label, stringBounder)) {
|
||||
|
@ -79,15 +79,15 @@ public class JDotPath implements UDrawable {
|
||||
|
||||
private ColorParam getArrowColorParam() {
|
||||
if (diagram.getUmlDiagramType() == UmlDiagramType.CLASS) {
|
||||
return ColorParam.classArrow;
|
||||
return ColorParam.arrow;
|
||||
} else if (diagram.getUmlDiagramType() == UmlDiagramType.OBJECT) {
|
||||
return ColorParam.objectArrow;
|
||||
return ColorParam.arrow;
|
||||
} else if (diagram.getUmlDiagramType() == UmlDiagramType.DESCRIPTION) {
|
||||
return ColorParam.usecaseArrow;
|
||||
return ColorParam.arrow;
|
||||
} else if (diagram.getUmlDiagramType() == UmlDiagramType.ACTIVITY) {
|
||||
return ColorParam.activityArrow;
|
||||
return ColorParam.arrow;
|
||||
} else if (diagram.getUmlDiagramType() == UmlDiagramType.STATE) {
|
||||
return ColorParam.stateArrow;
|
||||
return ColorParam.arrow;
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ public class GTileNode extends AbstractTextBlock implements GTile {
|
||||
|
||||
public static SheetBlock1 getTextBlock(final Display display) {
|
||||
final Rose rose = new Rose();
|
||||
final SkinParam skinParam = new SkinParam();
|
||||
final SkinParam skinParam = SkinParam.create(null);
|
||||
final HtmlColor fontColor = rose.getFontColor(skinParam, FontParam.NOTE);
|
||||
final UFont fontNote = skinParam.getFont(null, false, FontParam.NOTE);
|
||||
|
||||
|
@ -107,7 +107,7 @@ public class PostIt {
|
||||
final HtmlColor noteBackgroundColor = new HtmlColorSetSimple().getColorIfValid("#FBFB77");
|
||||
final HtmlColor borderColor = HtmlColorUtils.MY_RED;
|
||||
|
||||
final SkinParam param = SkinParam.noShadowing();
|
||||
final SkinParam param = SkinParam.noShadowing(null);
|
||||
final UFont fontNote = param.getFont(null, false, FontParam.NOTE);
|
||||
final FontConfiguration font2 = fontNote.toFont2(HtmlColorUtils.BLACK, true, HtmlColorUtils.BLUE, 8);
|
||||
final ComponentRoseNote note = new ComponentRoseNote(
|
||||
|
@ -124,7 +124,7 @@ class PrintSkin extends AbstractPSystem {
|
||||
private void printComponent(ComponentType type) {
|
||||
println(type.name());
|
||||
final Component comp = skin.createComponent(type, ArrowConfiguration.withDirectionNormal(),
|
||||
SkinParam.noShadowing(), Display.create(toPrint));
|
||||
SkinParam.noShadowing(null), Display.create(toPrint));
|
||||
if (comp == null) {
|
||||
println("null");
|
||||
return;
|
||||
|
@ -78,7 +78,7 @@ public class PSystemProject extends AbstractPSystem {
|
||||
PngIO.write(im, os, fileFormatOption.isWithMetadata() ? getMetadata() : null, 96);
|
||||
} else if (fileFormat == FileFormat.SVG) {
|
||||
final UGraphicSvg svg = new UGraphicSvg(colorMapper, StringUtils.getAsHtml(background), false, 1.0,
|
||||
fileFormatOption.getSvgLinkTarget());
|
||||
fileFormatOption.getSvgLinkTarget(), fileFormatOption.getHoverColor());
|
||||
diagram.draw(svg, 0, 0);
|
||||
svg.createXml(os);
|
||||
} else if (fileFormat == FileFormat.EPS) {
|
||||
|
@ -77,7 +77,7 @@ public class PSystemProject2 extends AbstractPSystem {
|
||||
PngIO.write(im, os, fileFormatOption.isWithMetadata() ? getMetadata() : null, 96);
|
||||
} else if (fileFormat == FileFormat.SVG) {
|
||||
final UGraphicSvg svg = new UGraphicSvg(colorMapper, StringUtils.getAsHtml(background), false, 1.0,
|
||||
fileFormatOption.getSvgLinkTarget());
|
||||
fileFormatOption.getSvgLinkTarget(), fileFormatOption.getHoverColor());
|
||||
diagram.draw(svg, 0, 0);
|
||||
svg.createXml(os);
|
||||
} else if (fileFormat == FileFormat.EPS) {
|
||||
|
@ -86,17 +86,17 @@ public class Rose implements Skin {
|
||||
// final FontConfiguration fc = new FontConfiguration(fontArrow, HtmlColorUtils.BLACK);
|
||||
// stringsToDisplay = DisplayUtils.breakLines(stringsToDisplay, fc, param, param.maxMessageSize());
|
||||
// }
|
||||
final HtmlColor sequenceArrow = config.getColor() == null ? getHtmlColor(param, ColorParam.sequenceArrow)
|
||||
final HtmlColor sequenceArrow = config.getColor() == null ? getHtmlColor(param, ColorParam.arrow)
|
||||
: config.getColor();
|
||||
if (config.getArrowDirection() == ArrowDirection.SELF) {
|
||||
return new ComponentRoseSelfArrow(sequenceArrow, getUFont2(param, FontParam.SEQUENCE_ARROW),
|
||||
return new ComponentRoseSelfArrow(sequenceArrow, getUFont2(param, FontParam.ARROW),
|
||||
stringsToDisplay, config, param, param.maxMessageSize(), param.strictUmlStyle() == false);
|
||||
}
|
||||
final HorizontalAlignment messageHorizontalAlignment = param.getHorizontalAlignment(
|
||||
AlignParam.SEQUENCE_MESSAGE_ALIGN, config.getArrowDirection());
|
||||
final HorizontalAlignment textHorizontalAlignment = param.getHorizontalAlignment(
|
||||
AlignParam.SEQUENCE_MESSAGETEXT_ALIGN, config.getArrowDirection());
|
||||
return new ComponentRoseArrow(sequenceArrow, getUFont2(param, FontParam.SEQUENCE_ARROW), stringsToDisplay,
|
||||
return new ComponentRoseArrow(sequenceArrow, getUFont2(param, FontParam.ARROW), stringsToDisplay,
|
||||
config, messageHorizontalAlignment, param, textHorizontalAlignment, param.maxMessageSize(),
|
||||
param.strictUmlStyle() == false);
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ public final class DotDataImageBuilder {
|
||||
}
|
||||
try {
|
||||
final ISkinParam skinParam = dotData.getSkinParam();
|
||||
final FontConfiguration labelFont = new FontConfiguration(skinParam, FontParam.GENERIC_ARROW, null);
|
||||
final FontConfiguration labelFont = new FontConfiguration(skinParam, FontParam.ARROW, null);
|
||||
|
||||
final Line line = new Line(link, dotStringFactory.getColorSequence(), skinParam, stringBounder,
|
||||
labelFont, dotStringFactory.getBibliotekon(), dotData.getPragma());
|
||||
|
@ -89,15 +89,15 @@ public final class SvekResult extends AbstractTextBlock implements IEntityImage,
|
||||
|
||||
private ColorParam getArrowColorParam() {
|
||||
if (dotData.getUmlDiagramType() == UmlDiagramType.CLASS) {
|
||||
return ColorParam.classArrow;
|
||||
return ColorParam.arrow;
|
||||
} else if (dotData.getUmlDiagramType() == UmlDiagramType.OBJECT) {
|
||||
return ColorParam.objectArrow;
|
||||
return ColorParam.arrow;
|
||||
} else if (dotData.getUmlDiagramType() == UmlDiagramType.DESCRIPTION) {
|
||||
return ColorParam.usecaseArrow;
|
||||
return ColorParam.arrow;
|
||||
} else if (dotData.getUmlDiagramType() == UmlDiagramType.ACTIVITY) {
|
||||
return ColorParam.activityArrow;
|
||||
return ColorParam.arrow;
|
||||
} else if (dotData.getUmlDiagramType() == UmlDiagramType.STATE) {
|
||||
return ColorParam.stateArrow;
|
||||
return ColorParam.arrow;
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ public class EntityImageDescription extends AbstractEntityImage {
|
||||
final Display codeDisplay = Display.getWithNewlines(entity.getCode());
|
||||
final TextBlock desc = (entity.getDisplay().equals(codeDisplay) && symbol instanceof USymbolFolder)
|
||||
|| entity.getDisplay().isWhite() ? TextBlockUtils.empty(0, 0) : new BodyEnhanced(entity.getDisplay(),
|
||||
symbol.getFontParam(), getSkinParam(), HorizontalAlignment.CENTER, stereotype,
|
||||
symbol.getFontParam(), getSkinParam(), HorizontalAlignment.LEFT, stereotype,
|
||||
symbol.manageHorizontalLine(), false, false, entity);
|
||||
|
||||
this.url = entity.getUrl99();
|
||||
|
@ -62,6 +62,7 @@ import net.sourceforge.plantuml.ugraphic.UPath;
|
||||
import net.sourceforge.plantuml.ugraphic.USegment;
|
||||
import net.sourceforge.plantuml.ugraphic.USegmentType;
|
||||
|
||||
import org.w3c.dom.CDATASection;
|
||||
import org.w3c.dom.Comment;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
@ -109,11 +110,11 @@ public class SvgGraphics {
|
||||
}
|
||||
}
|
||||
|
||||
public SvgGraphics(double scale) {
|
||||
this(null, scale);
|
||||
public SvgGraphics(double scale, String hover) {
|
||||
this(null, scale, hover);
|
||||
}
|
||||
|
||||
public SvgGraphics(String backcolor, double scale) {
|
||||
public SvgGraphics(String backcolor, double scale, String hover) {
|
||||
try {
|
||||
this.scale = scale;
|
||||
this.document = getDocument();
|
||||
@ -130,12 +131,23 @@ public class SvgGraphics {
|
||||
this.filterUid = "b" + getRandomString(rnd);
|
||||
this.shadowId = "f" + getRandomString(rnd);
|
||||
this.gradientId = "g" + getRandomString(rnd);
|
||||
if (hover != null) {
|
||||
defs.appendChild(getPathHover(hover));
|
||||
}
|
||||
} catch (ParserConfigurationException e) {
|
||||
e.printStackTrace();
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private Element getPathHover(String hover) {
|
||||
final Element style = simpleElement("style");
|
||||
final CDATASection cdata = document.createCDATASection("path:hover { stroke: " + hover + " !important;}");
|
||||
style.setAttribute("type", "text/css");
|
||||
style.appendChild(cdata);
|
||||
return style;
|
||||
}
|
||||
|
||||
private static String getRandomString(final Random rnd) {
|
||||
String result = Integer.toString(Math.abs(rnd.nextInt()), 36);
|
||||
while (result.length() < 6) {
|
||||
|
@ -34,10 +34,12 @@ public class ChangeState implements Comparable<ChangeState> {
|
||||
|
||||
private final TimeTick when;
|
||||
private final String state;
|
||||
private final String comment;
|
||||
|
||||
public ChangeState(TimeTick when, String state) {
|
||||
public ChangeState(TimeTick when, String state, String comment) {
|
||||
this.when = when;
|
||||
this.state = state;
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
public int compareTo(ChangeState other) {
|
||||
@ -52,4 +54,8 @@ public class ChangeState implements Comparable<ChangeState> {
|
||||
return state;
|
||||
}
|
||||
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,63 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2017, Arnaud Roques
|
||||
*
|
||||
* Project Info: http://plantuml.com
|
||||
*
|
||||
* 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.timingdiagram;
|
||||
|
||||
import net.sourceforge.plantuml.command.CommandExecutionResult;
|
||||
import net.sourceforge.plantuml.command.SingleLineCommand2;
|
||||
import net.sourceforge.plantuml.command.regex.RegexConcat;
|
||||
import net.sourceforge.plantuml.command.regex.RegexLeaf;
|
||||
import net.sourceforge.plantuml.command.regex.RegexResult;
|
||||
|
||||
public class CommandAtPlayer extends SingleLineCommand2<TimingDiagram> {
|
||||
|
||||
public CommandAtPlayer() {
|
||||
super(getRegexConcat());
|
||||
}
|
||||
|
||||
private static RegexConcat getRegexConcat() {
|
||||
return new RegexConcat(new RegexLeaf("^"), //
|
||||
new RegexLeaf("@"), //
|
||||
new RegexLeaf("PLAYER", CommandTimeMessage.PLAYER_CODE), //
|
||||
new RegexLeaf("[%s]*$"));
|
||||
}
|
||||
|
||||
@Override
|
||||
final protected CommandExecutionResult executeArg(TimingDiagram diagram, RegexResult arg) {
|
||||
final String code = arg.get("PLAYER", 0);
|
||||
final Player player = diagram.getPlayer(code);
|
||||
if (player == null) {
|
||||
return CommandExecutionResult.error("No such participant " + code);
|
||||
}
|
||||
diagram.setLastPlayer(player);
|
||||
return CommandExecutionResult.ok();
|
||||
}
|
||||
|
||||
}
|
@ -44,7 +44,7 @@ public class CommandAtTime extends SingleLineCommand2<TimingDiagram> {
|
||||
|
||||
private static RegexConcat getRegexConcat() {
|
||||
return new RegexConcat(new RegexLeaf("^"), //
|
||||
TimeTickBuilder.expressionAt("TIME"), //
|
||||
TimeTickBuilder.expressionAtWithArobase("TIME"), //
|
||||
new RegexLeaf("[%s]*$"));
|
||||
}
|
||||
|
||||
|
@ -36,17 +36,18 @@ import net.sourceforge.plantuml.command.regex.RegexConcat;
|
||||
import net.sourceforge.plantuml.command.regex.RegexLeaf;
|
||||
import net.sourceforge.plantuml.command.regex.RegexResult;
|
||||
|
||||
public class CommandChangeState extends SingleLineCommand2<TimingDiagram> {
|
||||
public class CommandChangeState1 extends SingleLineCommand2<TimingDiagram> {
|
||||
|
||||
public CommandChangeState() {
|
||||
public CommandChangeState1() {
|
||||
super(getRegexConcat());
|
||||
}
|
||||
|
||||
private static RegexConcat getRegexConcat() {
|
||||
return new RegexConcat(new RegexLeaf("^"), //
|
||||
new RegexLeaf("CODE", "([\\p{L}0-9_.@]+)"), //
|
||||
new RegexLeaf("CODE", CommandTimeMessage.PLAYER_CODE), //
|
||||
new RegexLeaf("[%s]*is[%s]*"), //
|
||||
new RegexLeaf("STATE", "(.*?)"), //
|
||||
new RegexLeaf("STATE", "([^:]*?)"), //
|
||||
new RegexLeaf("COMMENT", "(?:[%s]*:[%s]*(.*?))?"), //
|
||||
new RegexLeaf("[%s]*$"));
|
||||
}
|
||||
|
||||
@ -57,8 +58,9 @@ public class CommandChangeState extends SingleLineCommand2<TimingDiagram> {
|
||||
if (player == null) {
|
||||
return CommandExecutionResult.error("Unkown \"" + code + "\"");
|
||||
}
|
||||
final String comment = arg.get("COMMENT", 0);
|
||||
final TimeTick now = diagram.getNow();
|
||||
player.setState(now, arg.get("STATE", 0));
|
||||
player.setState(now, arg.get("STATE", 0), comment);
|
||||
return CommandExecutionResult.ok();
|
||||
}
|
||||
|
@ -0,0 +1,68 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2017, Arnaud Roques
|
||||
*
|
||||
* Project Info: http://plantuml.com
|
||||
*
|
||||
* 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.timingdiagram;
|
||||
|
||||
import net.sourceforge.plantuml.command.CommandExecutionResult;
|
||||
import net.sourceforge.plantuml.command.SingleLineCommand2;
|
||||
import net.sourceforge.plantuml.command.regex.RegexConcat;
|
||||
import net.sourceforge.plantuml.command.regex.RegexLeaf;
|
||||
import net.sourceforge.plantuml.command.regex.RegexResult;
|
||||
|
||||
public class CommandChangeState2 extends SingleLineCommand2<TimingDiagram> {
|
||||
|
||||
public CommandChangeState2() {
|
||||
super(getRegexConcat());
|
||||
}
|
||||
|
||||
private static RegexConcat getRegexConcat() {
|
||||
return new RegexConcat(new RegexLeaf("^"), //
|
||||
new RegexLeaf("[%s]*"), //
|
||||
TimeTickBuilder.expressionAtWithoutArobase("TIME"), //
|
||||
new RegexLeaf("[%s]*is[%s]*"), //
|
||||
new RegexLeaf("STATE", "([^:]*?)"), //
|
||||
new RegexLeaf("COMMENT", "(?:[%s]*:[%s]*(.*?))?"), //
|
||||
new RegexLeaf("[%s]*$"));
|
||||
}
|
||||
|
||||
@Override
|
||||
final protected CommandExecutionResult executeArg(TimingDiagram diagram, RegexResult arg) {
|
||||
final Player player = diagram.getLastPlayer();
|
||||
if (player == null) {
|
||||
return CommandExecutionResult.error("Missing @ line before this");
|
||||
}
|
||||
final TimeTick tick = TimeTickBuilder.parseTimeTick("TIME", arg, diagram);
|
||||
final String comment = arg.get("COMMENT", 0);
|
||||
player.setState(tick, arg.get("STATE", 0), comment);
|
||||
diagram.addTime(tick);
|
||||
return CommandExecutionResult.ok();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2017, Arnaud Roques
|
||||
*
|
||||
* Project Info: http://plantuml.com
|
||||
*
|
||||
* 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.timingdiagram;
|
||||
|
||||
import net.sourceforge.plantuml.command.CommandExecutionResult;
|
||||
import net.sourceforge.plantuml.command.SingleLineCommand2;
|
||||
import net.sourceforge.plantuml.command.regex.RegexConcat;
|
||||
import net.sourceforge.plantuml.command.regex.RegexLeaf;
|
||||
import net.sourceforge.plantuml.command.regex.RegexResult;
|
||||
|
||||
public class CommandConstraint extends SingleLineCommand2<TimingDiagram> {
|
||||
|
||||
public CommandConstraint() {
|
||||
super(getRegexConcat());
|
||||
}
|
||||
|
||||
private static RegexConcat getRegexConcat() {
|
||||
return new RegexConcat(new RegexLeaf("^"), //
|
||||
new RegexLeaf("PART1", "(" + CommandTimeMessage.PLAYER_CODE + ")?"), //
|
||||
TimeTickBuilder.expressionAtWithArobase("TIME1"), //
|
||||
new RegexLeaf("[%s]*"), //
|
||||
new RegexLeaf("ARROW", "\\<(-+)\\>"), //
|
||||
new RegexLeaf("[%s]*"), //
|
||||
TimeTickBuilder.expressionAtWithArobase("TIME2"), //
|
||||
new RegexLeaf("[%s]*"), //
|
||||
new RegexLeaf("MESSAGE", "(?::[%s]*(.*))?"), //
|
||||
new RegexLeaf("[%s]*$"));
|
||||
}
|
||||
|
||||
@Override
|
||||
final protected CommandExecutionResult executeArg(TimingDiagram diagram, RegexResult arg) {
|
||||
final String part1 = arg.get("PART1", 0);
|
||||
final Player player1;
|
||||
if (part1 == null) {
|
||||
player1 = diagram.getLastPlayer();
|
||||
if (player1 == null) {
|
||||
return CommandExecutionResult.error("You have to provide a participant");
|
||||
}
|
||||
} else {
|
||||
player1 = diagram.getPlayer(part1);
|
||||
}
|
||||
final TimeTick tick1 = TimeTickBuilder.parseTimeTick("TIME1", arg, diagram);
|
||||
diagram.updateNow(tick1);
|
||||
final TimeTick tick2 = TimeTickBuilder.parseTimeTick("TIME2", arg, diagram);
|
||||
player1.createConstraint(tick1, tick2, arg.get("MESSAGE", 0));
|
||||
return CommandExecutionResult.ok();
|
||||
}
|
||||
|
||||
}
|
@ -38,21 +38,24 @@ import net.sourceforge.plantuml.command.regex.RegexResult;
|
||||
|
||||
public class CommandTimeMessage extends SingleLineCommand2<TimingDiagram> {
|
||||
|
||||
public static final String PLAYER_CODE = "([\\p{L}_][\\p{L}0-9_.]*)";
|
||||
|
||||
public CommandTimeMessage() {
|
||||
super(getRegexConcat());
|
||||
}
|
||||
|
||||
private static RegexConcat getRegexConcat() {
|
||||
return new RegexConcat(new RegexLeaf("^"), //
|
||||
new RegexLeaf("PART1", "([\\p{L}0-9_.]+)"), //
|
||||
TimeTickBuilder.optionalExpressionAt("TIME1"), //
|
||||
new RegexLeaf("PART1", PLAYER_CODE), //
|
||||
TimeTickBuilder.optionalExpressionAtWithArobase("TIME1"), //
|
||||
new RegexLeaf("[%s]*"), //
|
||||
new RegexLeaf("ARROW", "(-+)\\>"), //
|
||||
new RegexLeaf("[%s]*"), //
|
||||
new RegexLeaf("PART2", "([\\p{L}0-9_.]+)"), //
|
||||
TimeTickBuilder.optionalExpressionAt("TIME2"), //
|
||||
new RegexLeaf("PART2", PLAYER_CODE), //
|
||||
TimeTickBuilder.optionalExpressionAtWithArobase("TIME2"), //
|
||||
new RegexLeaf("[%s]*"), //
|
||||
new RegexLeaf("MESSAGE", "(?::[%s]*(.*))?"), new RegexLeaf("[%s]*$"));
|
||||
new RegexLeaf("MESSAGE", "(?::[%s]*(.*))?"), //
|
||||
new RegexLeaf("[%s]*$"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
68
src/net/sourceforge/plantuml/timingdiagram/HexaShape.java
Normal file
68
src/net/sourceforge/plantuml/timingdiagram/HexaShape.java
Normal file
@ -0,0 +1,68 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2017, Arnaud Roques
|
||||
*
|
||||
* Project Info: http://plantuml.com
|
||||
*
|
||||
* 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.timingdiagram;
|
||||
|
||||
import net.sourceforge.plantuml.graphic.SymbolContext;
|
||||
import net.sourceforge.plantuml.graphic.UDrawable;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.UPolygon;
|
||||
|
||||
public class HexaShape implements UDrawable {
|
||||
|
||||
private final double width;
|
||||
private final double height;
|
||||
private final SymbolContext context;
|
||||
|
||||
private final double delta = 12;
|
||||
|
||||
private HexaShape(double width, double height, SymbolContext context) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public static HexaShape create(double width, double height, SymbolContext context) {
|
||||
return new HexaShape(width, height, context);
|
||||
}
|
||||
|
||||
public void drawU(UGraphic ug) {
|
||||
ug = context.apply(ug);
|
||||
final UPolygon polygon = new UPolygon();
|
||||
polygon.addPoint(delta, 0);
|
||||
polygon.addPoint(width - delta, 0);
|
||||
polygon.addPoint(width, height / 2);
|
||||
polygon.addPoint(width - delta, height);
|
||||
polygon.addPoint(delta, height);
|
||||
polygon.addPoint(0, height / 2);
|
||||
ug.draw(polygon);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -31,11 +31,14 @@ package net.sourceforge.plantuml.timingdiagram;
|
||||
|
||||
import java.awt.geom.Dimension2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Point2D.Double;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.plantuml.Dimension2DDouble;
|
||||
import net.sourceforge.plantuml.FontParam;
|
||||
import net.sourceforge.plantuml.ISkinParam;
|
||||
import net.sourceforge.plantuml.cucadiagram.Display;
|
||||
@ -43,22 +46,25 @@ import net.sourceforge.plantuml.graphic.FontConfiguration;
|
||||
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
|
||||
import net.sourceforge.plantuml.graphic.HtmlColorUtils;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.graphic.SymbolContext;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
import net.sourceforge.plantuml.ugraphic.UChangeColor;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.ULine;
|
||||
import net.sourceforge.plantuml.ugraphic.URectangle;
|
||||
import net.sourceforge.plantuml.ugraphic.UStroke;
|
||||
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
|
||||
public class Histogram implements TimeDrawing {
|
||||
|
||||
private final List<ChangeState> changes = new ArrayList<ChangeState>();
|
||||
private final List<TimeConstraint> constraints = new ArrayList<TimeConstraint>();
|
||||
|
||||
private List<String> allStates = new ArrayList<String>();
|
||||
private final double stepHeight = 20;
|
||||
|
||||
private final ISkinParam skinParam;
|
||||
private final TimingRuler ruler;
|
||||
private String initialState;
|
||||
|
||||
public Histogram(TimingRuler ruler, ISkinParam skinParam) {
|
||||
this.ruler = ruler;
|
||||
@ -69,30 +75,29 @@ public class Histogram implements TimeDrawing {
|
||||
final double x = ruler.getPosInPixel(tick);
|
||||
final List<String> states = getStatesAt(tick);
|
||||
if (states.size() == 1) {
|
||||
final int num = getStateNumFor(states.get(0));
|
||||
return new IntricatedPoint(new Point2D.Double(x, num * stepHeight), new Point2D.Double(x, num * stepHeight));
|
||||
final double y = getStateYFor(states.get(0));
|
||||
return new IntricatedPoint(new Point2D.Double(x, y), new Point2D.Double(x, y));
|
||||
}
|
||||
assert states.size() == 2;
|
||||
final int num1 = getStateNumFor(states.get(0));
|
||||
final int num2 = getStateNumFor(states.get(1));
|
||||
assert num1 != num2;
|
||||
return new IntricatedPoint(new Point2D.Double(x, num1 * stepHeight), new Point2D.Double(x, num2 * stepHeight));
|
||||
// if (isTransition(tick)) {
|
||||
// return new IntricatedPoint(new Point2D.Double(x, state * stepHeight), new Point2D.Double(x, state
|
||||
// * stepHeight + stepHeight));
|
||||
// }
|
||||
// return new IntricatedPoint(new Point2D.Double(x, state * stepHeight), new Point2D.Double(x, state *
|
||||
// stepHeight));
|
||||
final double y1 = getStateYFor(states.get(0));
|
||||
final double y2 = getStateYFor(states.get(1));
|
||||
assert y1 != y2;
|
||||
return new IntricatedPoint(new Point2D.Double(x, y1), new Point2D.Double(x, y2));
|
||||
}
|
||||
|
||||
private int getStateNumFor(String state) {
|
||||
// final String state = getStateAt(tick);
|
||||
return allStates.size() - 1 - allStates.indexOf(state);
|
||||
private double getStateYFor(String state) {
|
||||
return (allStates.size() - 1 - allStates.indexOf(state)) * stepHeight;
|
||||
}
|
||||
|
||||
private List<String> getStatesAt(TimeTick tick) {
|
||||
for (int i = 0; i < changes.size(); i++) {
|
||||
if (changes.get(i).getWhen().compareTo(tick) == 0) {
|
||||
if (i == 0 && initialState == null) {
|
||||
return Arrays.asList(changes.get(i).getState());
|
||||
}
|
||||
if (i == 0 && initialState != null) {
|
||||
return Arrays.asList(initialState, changes.get(i).getState());
|
||||
}
|
||||
return Arrays.asList(changes.get(i - 1).getState(), changes.get(i).getState());
|
||||
}
|
||||
if (changes.get(i).getWhen().compareTo(tick) > 0) {
|
||||
@ -120,20 +125,31 @@ public class Histogram implements TimeDrawing {
|
||||
return -stepHeight * allStates.indexOf(state);
|
||||
}
|
||||
|
||||
private SymbolContext getContext() {
|
||||
return new SymbolContext(HtmlColorUtils.COL_D7E0F2, HtmlColorUtils.COL_038048).withStroke(new UStroke(1.5));
|
||||
}
|
||||
|
||||
public void drawU(UGraphic ug) {
|
||||
ug = ug.apply(new UChangeColor(HtmlColorUtils.COL_038048)).apply(new UStroke(1.5));
|
||||
final UTranslate deltaY = new UTranslate(0, stepHeight * (allStates.size() - 1));
|
||||
// System.err.println("changes=" + changes);
|
||||
ug = getContext().apply(ug);
|
||||
final UTranslate deltaY = new UTranslate(0, getFullDeltaY());
|
||||
if (initialState != null) {
|
||||
drawHLine(ug, getInitialPoint(), getInitialWidth());
|
||||
}
|
||||
for (int i = 0; i < changes.size() - 1; i++) {
|
||||
final Point2D pt = getPoint(i);
|
||||
final Point2D pt2 = getPoint(i + 1);
|
||||
final double len = pt2.getX() - pt.getX();
|
||||
ug.apply(new UTranslate(pt).compose(deltaY)).draw(new ULine(len, 0));
|
||||
drawHLine(ug, pt, len);
|
||||
}
|
||||
final Point2D pt = getPoint(changes.size() - 1);
|
||||
final double len = ruler.getWidth() - pt.getX();
|
||||
ug.apply(new UTranslate(pt).compose(deltaY)).draw(new ULine(len, 0));
|
||||
drawHLine(ug, pt, len);
|
||||
|
||||
if (initialState != null) {
|
||||
final Point2D before = getInitialPoint();
|
||||
final Point2D current = getPoint(0);
|
||||
ug.apply(new UTranslate(current).compose(deltaY)).draw(new ULine(0, before.getY() - current.getY()));
|
||||
}
|
||||
for (int i = 1; i < changes.size(); i++) {
|
||||
final Point2D before = getPoint(i - 1);
|
||||
final Point2D current = getPoint(i);
|
||||
@ -142,19 +158,55 @@ public class Histogram implements TimeDrawing {
|
||||
|
||||
for (int i = 0; i < changes.size(); i++) {
|
||||
final Point2D ptLabel = getPoint(i);
|
||||
final TextBlock label = getStateTextBlock(changes.get(i).getState());
|
||||
final String comment = changes.get(i).getComment();
|
||||
if (comment == null) {
|
||||
continue;
|
||||
}
|
||||
final TextBlock label = getTextBlock(comment);
|
||||
final Dimension2D dim = label.calculateDimension(ug.getStringBounder());
|
||||
label.drawU(ug.apply(new UTranslate(ptLabel).compose(deltaY).compose(new UTranslate(2, -dim.getHeight()))));
|
||||
}
|
||||
|
||||
for (TimeConstraint constraint : constraints) {
|
||||
final String state1 = last(getStatesAt(constraint.getTick1()));
|
||||
final String state2 = getStatesAt(constraint.getTick2()).get(0);
|
||||
final double y1 = getStateYFor(state1);
|
||||
final double y2 = getStateYFor(state2);
|
||||
constraint.drawU(ug.apply(new UTranslate(0, y1 - stepHeight / 2)), ruler, skinParam);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static String last(List<String> list) {
|
||||
return list.get(list.size() - 1);
|
||||
}
|
||||
|
||||
private Double getInitialPoint() {
|
||||
return new Point2D.Double(-getInitialWidth(), yOfState(initialState));
|
||||
}
|
||||
|
||||
private void drawHLine(UGraphic ug, final Point2D pt, final double len) {
|
||||
final UTranslate deltaY = new UTranslate(0, getFullDeltaY());
|
||||
final UTranslate pos = new UTranslate(pt).compose(deltaY);
|
||||
ug = ug.apply(pos);
|
||||
final SymbolContext context = getContext();
|
||||
final double height = -pt.getY();
|
||||
if (height > 0) {
|
||||
context.withForeColor(context.getBackColor()).apply(ug).draw(new URectangle(len, height));
|
||||
}
|
||||
ug.draw(new ULine(len, 0));
|
||||
}
|
||||
|
||||
private double getFullDeltaY() {
|
||||
return stepHeight * (allStates.size() - 1);
|
||||
}
|
||||
|
||||
private FontConfiguration getFontConfiguration() {
|
||||
return new FontConfiguration(skinParam, FontParam.ACTIVITY, null);
|
||||
}
|
||||
|
||||
private TextBlock getStateTextBlock(String state) {
|
||||
final Display display = Display.getWithNewlines(state);
|
||||
private TextBlock getTextBlock(String value) {
|
||||
final Display display = Display.getWithNewlines(value);
|
||||
return display.create(getFontConfiguration(), HorizontalAlignment.LEFT, skinParam);
|
||||
}
|
||||
|
||||
@ -162,4 +214,50 @@ public class Histogram implements TimeDrawing {
|
||||
return stepHeight * allStates.size() + 10;
|
||||
}
|
||||
|
||||
public TextBlock getWidthHeader(StringBounder stringBounder) {
|
||||
return new TextBlock() {
|
||||
|
||||
public void drawU(UGraphic ug) {
|
||||
for (String state : allStates) {
|
||||
final TextBlock label = getTextBlock(state);
|
||||
final Dimension2D dim = label.calculateDimension(ug.getStringBounder());
|
||||
label.drawU(ug.apply(new UTranslate(0, getFullDeltaY() + yOfState(state) - dim.getHeight())));
|
||||
}
|
||||
}
|
||||
|
||||
public Dimension2D calculateDimension(StringBounder stringBounder) {
|
||||
double width = 0;
|
||||
for (String state : allStates) {
|
||||
final TextBlock label = getTextBlock(state);
|
||||
final Dimension2D dim = label.calculateDimension(stringBounder);
|
||||
width = Math.max(width, dim.getWidth());
|
||||
}
|
||||
if (initialState != null) {
|
||||
width += getInitialWidth();
|
||||
}
|
||||
return new Dimension2DDouble(width, getFullDeltaY());
|
||||
}
|
||||
|
||||
public Rectangle2D getInnerPosition(String member, StringBounder stringBounder) {
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public void setInitialState(String initialState) {
|
||||
this.initialState = initialState;
|
||||
if (initialState != null) {
|
||||
allStates.add(initialState);
|
||||
}
|
||||
}
|
||||
|
||||
private double getInitialWidth() {
|
||||
return stepHeight * 2;
|
||||
}
|
||||
|
||||
public void addConstraint(TimeConstraint constraint) {
|
||||
this.constraints.add(constraint);
|
||||
}
|
||||
|
||||
}
|
||||
|
77
src/net/sourceforge/plantuml/timingdiagram/PentaAShape.java
Normal file
77
src/net/sourceforge/plantuml/timingdiagram/PentaAShape.java
Normal file
@ -0,0 +1,77 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2017, Arnaud Roques
|
||||
*
|
||||
* Project Info: http://plantuml.com
|
||||
*
|
||||
* 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.timingdiagram;
|
||||
|
||||
import net.sourceforge.plantuml.graphic.SymbolContext;
|
||||
import net.sourceforge.plantuml.graphic.UDrawable;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.UPath;
|
||||
import net.sourceforge.plantuml.ugraphic.UPolygon;
|
||||
|
||||
public class PentaAShape implements UDrawable {
|
||||
|
||||
private final double width;
|
||||
private final double height;
|
||||
private final SymbolContext context;
|
||||
|
||||
private final double delta = 12;
|
||||
|
||||
private PentaAShape(double width, double height, SymbolContext context) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public static PentaAShape create(double width, double height, SymbolContext context) {
|
||||
return new PentaAShape(width, height, context);
|
||||
}
|
||||
|
||||
public void drawU(UGraphic ug) {
|
||||
final UPolygon polygon = new UPolygon();
|
||||
polygon.addPoint(0, 0);
|
||||
polygon.addPoint(width - delta, 0);
|
||||
polygon.addPoint(width, height / 2);
|
||||
polygon.addPoint(width - delta, height);
|
||||
polygon.addPoint(0, height);
|
||||
|
||||
context.withForeColor(context.getBackColor()).apply(ug).draw(polygon);
|
||||
|
||||
final UPath path = new UPath();
|
||||
path.moveTo(0, 0);
|
||||
path.lineTo(width - delta, 0);
|
||||
path.lineTo(width, height / 2);
|
||||
path.lineTo(width - delta, height);
|
||||
path.lineTo(0, height);
|
||||
|
||||
context.apply(ug).draw(path);
|
||||
|
||||
}
|
||||
|
||||
}
|
76
src/net/sourceforge/plantuml/timingdiagram/PentaBShape.java
Normal file
76
src/net/sourceforge/plantuml/timingdiagram/PentaBShape.java
Normal file
@ -0,0 +1,76 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2017, Arnaud Roques
|
||||
*
|
||||
* Project Info: http://plantuml.com
|
||||
*
|
||||
* 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.timingdiagram;
|
||||
|
||||
import net.sourceforge.plantuml.graphic.SymbolContext;
|
||||
import net.sourceforge.plantuml.graphic.UDrawable;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.UPath;
|
||||
import net.sourceforge.plantuml.ugraphic.UPolygon;
|
||||
|
||||
public class PentaBShape implements UDrawable {
|
||||
|
||||
private final double width;
|
||||
private final double height;
|
||||
private final SymbolContext context;
|
||||
|
||||
private final double delta = 12;
|
||||
|
||||
private PentaBShape(double width, double height, SymbolContext context) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public static PentaBShape create(double width, double height, SymbolContext context) {
|
||||
return new PentaBShape(width, height, context);
|
||||
}
|
||||
|
||||
public void drawU(UGraphic ug) {
|
||||
final UPolygon polygon = new UPolygon();
|
||||
polygon.addPoint(delta, 0);
|
||||
polygon.addPoint(width, 0);
|
||||
polygon.addPoint(width, height);
|
||||
polygon.addPoint(delta, height);
|
||||
polygon.addPoint(0, height / 2);
|
||||
|
||||
context.withForeColor(context.getBackColor()).apply(ug).draw(polygon);
|
||||
|
||||
final UPath path = new UPath();
|
||||
path.moveTo(width, 0);
|
||||
path.lineTo(delta, 0);
|
||||
path.lineTo(0, height / 2);
|
||||
path.lineTo(delta, height);
|
||||
path.lineTo(width, height);
|
||||
context.apply(ug).draw(path);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -31,6 +31,8 @@ package net.sourceforge.plantuml.timingdiagram;
|
||||
|
||||
import java.awt.geom.Dimension2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
@ -56,8 +58,10 @@ public class Player implements TextBlock, TimeProjected {
|
||||
private final TimingStyle type;
|
||||
private final ISkinParam skinParam;
|
||||
private final TimingRuler ruler;
|
||||
private String initialState;
|
||||
|
||||
private final Set<ChangeState> changes = new TreeSet<ChangeState>();
|
||||
private final List<TimeConstraint> constraints = new ArrayList<TimeConstraint>();
|
||||
|
||||
public Player(String code, String full, TimingStyle type, ISkinParam skinParam, TimingRuler ruler) {
|
||||
this.code = code;
|
||||
@ -78,8 +82,20 @@ public class Player implements TextBlock, TimeProjected {
|
||||
drawLine(ug.apply(new UChangeColor(HtmlColorUtils.BLACK)).apply(new UStroke(1.0)), -TimingDiagram.marginX1,
|
||||
dimTitle.getHeight() + 1, dimTitle.getWidth() + 1, dimTitle.getHeight() + 1,
|
||||
dimTitle.getWidth() + 1 + 10, 0);
|
||||
}
|
||||
|
||||
getTimeDrawing().drawU(ug.apply(getTranslateForTimeDrawing(ug.getStringBounder())));
|
||||
public void drawContent(UGraphic ug) {
|
||||
ug = ug.apply(getTranslateForTimeDrawing(ug.getStringBounder()));
|
||||
getTimeDrawing().drawU(ug);
|
||||
}
|
||||
|
||||
public void drawWidthHeader(UGraphic ug) {
|
||||
ug = ug.apply(getTranslateForTimeDrawing(ug.getStringBounder()));
|
||||
getTimeDrawing().getWidthHeader(ug.getStringBounder()).drawU(ug);
|
||||
}
|
||||
|
||||
public double getGetWidthHeader(StringBounder stringBounder) {
|
||||
return getTimeDrawing().getWidthHeader(stringBounder).calculateDimension(stringBounder).getWidth();
|
||||
}
|
||||
|
||||
private void drawLine(UGraphic ug, double... coord) {
|
||||
@ -102,18 +118,31 @@ public class Player implements TextBlock, TimeProjected {
|
||||
return full.create(getFontConfiguration(), HorizontalAlignment.LEFT, skinParam);
|
||||
}
|
||||
|
||||
private TimeDrawing cached;
|
||||
|
||||
private TimeDrawing getTimeDrawing() {
|
||||
if (cached == null) {
|
||||
cached = computeTimeDrawing();
|
||||
}
|
||||
return cached;
|
||||
}
|
||||
|
||||
private TimeDrawing computeTimeDrawing() {
|
||||
final TimeDrawing result;
|
||||
if (type == TimingStyle.ROBUST) {
|
||||
if (type == TimingStyle.CONCISE) {
|
||||
result = new Ribbon(ruler, skinParam);
|
||||
} else if (type == TimingStyle.CONCISE) {
|
||||
} else if (type == TimingStyle.ROBUST) {
|
||||
result = new Histogram(ruler, skinParam);
|
||||
} else {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
result.setInitialState(initialState);
|
||||
for (ChangeState change : changes) {
|
||||
result.addChange(change);
|
||||
}
|
||||
for (TimeConstraint constraint : constraints) {
|
||||
result.addConstraint(constraint);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -132,8 +161,12 @@ public class Player implements TextBlock, TimeProjected {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setState(TimeTick now, String state) {
|
||||
this.changes.add(new ChangeState(now, state));
|
||||
public void setState(TimeTick now, String state, String comment) {
|
||||
if (now == null) {
|
||||
this.initialState = state;
|
||||
} else {
|
||||
this.changes.add(new ChangeState(now, state, comment));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -143,4 +176,8 @@ public class Player implements TextBlock, TimeProjected {
|
||||
return point.translated(translation);
|
||||
}
|
||||
|
||||
public void createConstraint(TimeTick tick1, TimeTick tick2, String message) {
|
||||
this.constraints.add(new TimeConstraint(tick1, tick2, message));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -41,20 +41,22 @@ import net.sourceforge.plantuml.graphic.FontConfiguration;
|
||||
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
|
||||
import net.sourceforge.plantuml.graphic.HtmlColorUtils;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.graphic.SymbolContext;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
import net.sourceforge.plantuml.ugraphic.UChangeColor;
|
||||
import net.sourceforge.plantuml.graphic.TextBlockUtils;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.ULine;
|
||||
import net.sourceforge.plantuml.ugraphic.UStroke;
|
||||
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
|
||||
public class Ribbon implements TimeDrawing {
|
||||
|
||||
private final List<ChangeState> changes = new ArrayList<ChangeState>();
|
||||
private final List<TimeConstraint> constraints = new ArrayList<TimeConstraint>();
|
||||
|
||||
private final double delta = 12;
|
||||
private final ISkinParam skinParam;
|
||||
private final TimingRuler ruler;
|
||||
private String initialState;
|
||||
|
||||
public Ribbon(TimingRuler ruler, ISkinParam skinParam) {
|
||||
this.ruler = ruler;
|
||||
@ -63,7 +65,7 @@ public class Ribbon implements TimeDrawing {
|
||||
|
||||
public IntricatedPoint getTimeProjection(StringBounder stringBounder, TimeTick tick) {
|
||||
final double x = ruler.getPosInPixel(tick);
|
||||
final double y = delta * 0.5;
|
||||
final double y = delta * 0.5 + getHeightForConstraints();
|
||||
for (ChangeState change : changes) {
|
||||
if (change.getWhen().compareTo(tick) == 0) {
|
||||
return new IntricatedPoint(new Point2D.Double(x, y), new Point2D.Double(x, y));
|
||||
@ -84,59 +86,110 @@ public class Ribbon implements TimeDrawing {
|
||||
return new FontConfiguration(skinParam, FontParam.ACTIVITY, null);
|
||||
}
|
||||
|
||||
private TextBlock getStateTextBlock(ChangeState state) {
|
||||
final Display display = Display.getWithNewlines(state.getState());
|
||||
private TextBlock getTextBlock(String value) {
|
||||
final Display display = Display.getWithNewlines(value);
|
||||
return display.create(getFontConfiguration(), HorizontalAlignment.LEFT, skinParam);
|
||||
}
|
||||
|
||||
public void drawU(UGraphic ug) {
|
||||
ug = ug.apply(new UTranslate(0, 0.5 * delta));
|
||||
|
||||
// System.err.println("changes=" + changes);
|
||||
UGraphic ugDown = ug.apply(new UTranslate(0, getHeightForConstraints()));
|
||||
|
||||
final TextBlock inital;
|
||||
final StringBounder stringBounder = ugDown.getStringBounder();
|
||||
if (initialState == null) {
|
||||
inital = null;
|
||||
} else {
|
||||
inital = getTextBlock(initialState);
|
||||
drawPentaA(ugDown.apply(new UTranslate(-getInitialWidth(stringBounder), -delta / 2)),
|
||||
getInitialWidth(stringBounder));
|
||||
}
|
||||
|
||||
for (int i = 0; i < changes.size() - 1; i++) {
|
||||
final double a = getPosInPixel(changes.get(i));
|
||||
final double b = getPosInPixel(changes.get(i + 1));
|
||||
assert b > a;
|
||||
draw1(ug.apply(new UTranslate(a, 0)), b - a, true);
|
||||
draw2(ug.apply(new UTranslate(a, 0)), b - a, true);
|
||||
drawHexa(ugDown.apply(new UTranslate(a, -delta / 2)), b - a);
|
||||
}
|
||||
final double a = getPosInPixel(changes.get(changes.size() - 1));
|
||||
draw1(ug.apply(new UTranslate(a, 0)), ruler.getWidth() - a, false);
|
||||
draw2(ug.apply(new UTranslate(a, 0)), ruler.getWidth() - a, false);
|
||||
drawPentaB(ugDown.apply(new UTranslate(a, -delta / 2)), ruler.getWidth() - a);
|
||||
|
||||
ugDown = ugDown.apply(new UTranslate(0, delta / 2));
|
||||
|
||||
if (inital != null) {
|
||||
final Dimension2D dimInital = inital.calculateDimension(stringBounder);
|
||||
inital.drawU(ugDown.apply(new UTranslate(-getDelta() - dimInital.getWidth(), -dimInital.getHeight() / 2)));
|
||||
}
|
||||
for (ChangeState change : changes) {
|
||||
final TextBlock state = getStateTextBlock(change);
|
||||
final Dimension2D dim = state.calculateDimension(ug.getStringBounder());
|
||||
final TextBlock state = getTextBlock(change.getState());
|
||||
final Dimension2D dim = state.calculateDimension(stringBounder);
|
||||
final double x = ruler.getPosInPixel(change.getWhen());
|
||||
state.drawU(ug.apply(new UTranslate(x + getDelta(), -dim.getHeight() / 2)));
|
||||
state.drawU(ugDown.apply(new UTranslate(x + getDelta(), -dim.getHeight() / 2)));
|
||||
final String commentString = change.getComment();
|
||||
if (commentString != null) {
|
||||
final TextBlock comment = getTextBlock(commentString);
|
||||
final Dimension2D dimComment = comment.calculateDimension(stringBounder);
|
||||
comment.drawU(ugDown.apply(new UTranslate(x + getDelta(), -delta - dimComment.getHeight())));
|
||||
}
|
||||
}
|
||||
|
||||
for (TimeConstraint constraint : constraints) {
|
||||
constraint.drawU(ug.apply(new UTranslate(0, 15)), ruler, skinParam);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void draw1(UGraphic ug, double len, boolean withEnd) {
|
||||
ug = ug.apply(new UChangeColor(HtmlColorUtils.COL_038048)).apply(new UStroke(1.5));
|
||||
ug.draw(new ULine(delta, delta));
|
||||
ug.apply(new UTranslate(delta, delta)).draw(new ULine(len - 2 * delta, 0));
|
||||
if (withEnd) {
|
||||
ug.apply(new UTranslate(len - delta, delta)).draw(new ULine(delta, -delta));
|
||||
}
|
||||
private double getInitialWidth(final StringBounder stringBounder) {
|
||||
return getTextBlock(initialState).calculateDimension(stringBounder).getWidth() + 2 * delta;
|
||||
}
|
||||
|
||||
private void draw2(UGraphic ug, double len, boolean withEnd) {
|
||||
ug = ug.apply(new UChangeColor(HtmlColorUtils.COL_038048)).apply(new UStroke(1.5));
|
||||
ug.draw(new ULine(delta, -delta));
|
||||
ug.apply(new UTranslate(delta, -delta)).draw(new ULine(len - 2 * delta, 0));
|
||||
if (withEnd) {
|
||||
ug.apply(new UTranslate(len - delta, -delta)).draw(new ULine(delta, delta));
|
||||
private SymbolContext getContext() {
|
||||
return new SymbolContext(HtmlColorUtils.COL_D7E0F2, HtmlColorUtils.COL_038048).withStroke(new UStroke(1.5));
|
||||
}
|
||||
|
||||
private void drawHexa(UGraphic ug, double len) {
|
||||
final HexaShape shape = HexaShape.create(len, 2 * delta, getContext());
|
||||
shape.drawU(ug);
|
||||
}
|
||||
|
||||
private void drawPentaB(UGraphic ug, double len) {
|
||||
final PentaBShape shape = PentaBShape.create(len, 2 * delta, getContext());
|
||||
shape.drawU(ug);
|
||||
}
|
||||
|
||||
private void drawPentaA(UGraphic ug, double len) {
|
||||
final PentaAShape shape = PentaAShape.create(len, 2 * delta, getContext());
|
||||
shape.drawU(ug);
|
||||
}
|
||||
|
||||
private double getHeightForConstraints() {
|
||||
if (constraints.size() == 0) {
|
||||
return 0;
|
||||
}
|
||||
return 30;
|
||||
}
|
||||
|
||||
public double getHeight() {
|
||||
return 3 * delta;
|
||||
return 3 * delta + getHeightForConstraints();
|
||||
}
|
||||
|
||||
public double getDelta() {
|
||||
return delta;
|
||||
}
|
||||
|
||||
public TextBlock getWidthHeader(StringBounder stringBounder) {
|
||||
if (initialState != null) {
|
||||
return TextBlockUtils.empty(getInitialWidth(stringBounder), 2 * delta);
|
||||
}
|
||||
return TextBlockUtils.empty(0, 0);
|
||||
}
|
||||
|
||||
public void setInitialState(String initialState) {
|
||||
this.initialState = initialState;
|
||||
}
|
||||
|
||||
public void addConstraint(TimeConstraint constraint) {
|
||||
this.constraints.add(constraint);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -94,9 +94,10 @@ public class TimeArrow implements UDrawable {
|
||||
return new TimeArrow(translate.getTranslated(start), translate.getTranslated(end), label, spriteContainer);
|
||||
}
|
||||
|
||||
private Point2D onCircle(double alpha, double radius) {
|
||||
final double x = end.getX() - Math.sin(alpha) * radius;
|
||||
final double y = end.getY() - Math.cos(alpha) * radius;
|
||||
public static Point2D onCircle(Point2D pt, double alpha) {
|
||||
final double radius = 8;
|
||||
final double x = pt.getX() - Math.sin(alpha) * radius;
|
||||
final double y = pt.getY() - Math.cos(alpha) * radius;
|
||||
return new Point2D.Double(x, y);
|
||||
}
|
||||
|
||||
@ -107,13 +108,13 @@ public class TimeArrow implements UDrawable {
|
||||
|
||||
public void drawU(UGraphic ug) {
|
||||
final double angle = getAngle();
|
||||
ug = ug.apply(new UChangeColor(HtmlColorUtils.BLUE)).apply(new UStroke(1.5));
|
||||
ug = ug.apply(new UChangeColor(HtmlColorUtils.BLUE)).apply(new UStroke());
|
||||
final ULine line = new ULine(end.getX() - start.getX(), end.getY() - start.getY());
|
||||
ug.apply(new UTranslate(start)).draw(line);
|
||||
|
||||
final double delta = 20.0 * Math.PI / 180.0;
|
||||
final Point2D pt1 = onCircle(angle + delta, 8);
|
||||
final Point2D pt2 = onCircle(angle - delta, 8);
|
||||
final Point2D pt1 = onCircle(end, angle + delta);
|
||||
final Point2D pt2 = onCircle(end, angle - delta);
|
||||
|
||||
final UPolygon polygon = new UPolygon();
|
||||
polygon.addPoint(pt1.getX(), pt1.getY());
|
||||
|
116
src/net/sourceforge/plantuml/timingdiagram/TimeConstraint.java
Normal file
116
src/net/sourceforge/plantuml/timingdiagram/TimeConstraint.java
Normal file
@ -0,0 +1,116 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2017, Arnaud Roques
|
||||
*
|
||||
* Project Info: http://plantuml.com
|
||||
*
|
||||
* 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.timingdiagram;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.geom.Dimension2D;
|
||||
import java.awt.geom.Point2D;
|
||||
|
||||
import net.sourceforge.plantuml.ISkinParam;
|
||||
import net.sourceforge.plantuml.cucadiagram.Display;
|
||||
import net.sourceforge.plantuml.graphic.FontConfiguration;
|
||||
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
|
||||
import net.sourceforge.plantuml.graphic.HtmlColorUtils;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
import net.sourceforge.plantuml.ugraphic.UChangeBackColor;
|
||||
import net.sourceforge.plantuml.ugraphic.UChangeColor;
|
||||
import net.sourceforge.plantuml.ugraphic.UFont;
|
||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.ULine;
|
||||
import net.sourceforge.plantuml.ugraphic.UPolygon;
|
||||
import net.sourceforge.plantuml.ugraphic.UTranslate;
|
||||
|
||||
public class TimeConstraint {
|
||||
|
||||
private final TimeTick tick1;
|
||||
private final TimeTick tick2;
|
||||
private final Display label;
|
||||
|
||||
public TimeConstraint(TimeTick tick1, TimeTick tick2, String label) {
|
||||
this.tick1 = tick1;
|
||||
this.tick2 = tick2;
|
||||
this.label = Display.getWithNewlines(label);
|
||||
}
|
||||
|
||||
public final TimeTick getTick1() {
|
||||
return tick1;
|
||||
}
|
||||
|
||||
public final TimeTick getTick2() {
|
||||
return tick2;
|
||||
}
|
||||
|
||||
public final Display getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
private TextBlock getTextBlock(Display display, ISkinParam skinParam) {
|
||||
return display.create(getFontConfiguration(), HorizontalAlignment.LEFT, skinParam);
|
||||
}
|
||||
|
||||
private FontConfiguration getFontConfiguration() {
|
||||
final UFont font = new UFont("Serif", Font.PLAIN, 14);
|
||||
return new FontConfiguration(font, HtmlColorUtils.BLACK, HtmlColorUtils.BLUE, false);
|
||||
}
|
||||
|
||||
public void drawU(UGraphic ug, TimingRuler ruler, ISkinParam skinParam) {
|
||||
ug = ug.apply(new UChangeColor(HtmlColorUtils.RED)).apply(new UChangeBackColor(HtmlColorUtils.RED));
|
||||
final double x1 = ruler.getPosInPixel(tick1);
|
||||
final double x2 = ruler.getPosInPixel(tick2);
|
||||
final ULine line = new ULine(x2 - x1, 0);
|
||||
|
||||
ug = ug.apply(new UTranslate(x1, 0));
|
||||
ug.draw(line);
|
||||
|
||||
ug.draw(getPolygon(-Math.PI / 2, new Point2D.Double(0, 0)));
|
||||
ug.draw(getPolygon(Math.PI / 2, new Point2D.Double(x2 - x1, 0)));
|
||||
|
||||
final TextBlock text = getTextBlock(label, skinParam);
|
||||
final Dimension2D dimText = text.calculateDimension(ug.getStringBounder());
|
||||
final double x = (x2 - x1 - dimText.getWidth()) / 2;
|
||||
final UTranslate tr = new UTranslate(x, -5 - dimText.getHeight());
|
||||
text.drawU(ug.apply(tr));
|
||||
|
||||
}
|
||||
|
||||
private UPolygon getPolygon(final double angle, final Point2D end) {
|
||||
final double delta = 20.0 * Math.PI / 180.0;
|
||||
final Point2D pt1 = TimeArrow.onCircle(end, angle + delta);
|
||||
final Point2D pt2 = TimeArrow.onCircle(end, angle - delta);
|
||||
|
||||
final UPolygon polygon = new UPolygon();
|
||||
polygon.addPoint(pt1.getX(), pt1.getY());
|
||||
polygon.addPoint(pt2.getX(), pt2.getY());
|
||||
polygon.addPoint(end.getX(), end.getY());
|
||||
|
||||
return polygon;
|
||||
}
|
||||
|
||||
}
|
@ -29,6 +29,8 @@
|
||||
*/
|
||||
package net.sourceforge.plantuml.timingdiagram;
|
||||
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.graphic.TextBlock;
|
||||
import net.sourceforge.plantuml.graphic.UDrawable;
|
||||
|
||||
public interface TimeDrawing extends TimeProjected, UDrawable {
|
||||
@ -37,4 +39,10 @@ public interface TimeDrawing extends TimeProjected, UDrawable {
|
||||
|
||||
public void addChange(ChangeState change);
|
||||
|
||||
public TextBlock getWidthHeader(StringBounder stringBounder);
|
||||
|
||||
public void setInitialState(String initialState);
|
||||
|
||||
public void addConstraint(TimeConstraint constraint);
|
||||
|
||||
}
|
||||
|
@ -34,14 +34,19 @@ import net.sourceforge.plantuml.command.regex.RegexResult;
|
||||
|
||||
public class TimeTickBuilder {
|
||||
|
||||
private static final String REGEX = "@(\\+?)(\\d+)";
|
||||
private static final String WITHOUT_AROBASE = "(\\+?)(\\d+)";
|
||||
private static final String WITH_AROBASE = "@" + WITHOUT_AROBASE;
|
||||
|
||||
public static RegexLeaf expressionAt(String name) {
|
||||
return new RegexLeaf(name, REGEX);
|
||||
public static RegexLeaf expressionAtWithoutArobase(String name) {
|
||||
return new RegexLeaf(name, WITHOUT_AROBASE);
|
||||
}
|
||||
|
||||
public static RegexLeaf optionalExpressionAt(String name) {
|
||||
return new RegexLeaf(name, "(?:" + REGEX + ")?");
|
||||
public static RegexLeaf expressionAtWithArobase(String name) {
|
||||
return new RegexLeaf(name, WITH_AROBASE);
|
||||
}
|
||||
|
||||
public static RegexLeaf optionalExpressionAtWithArobase(String name) {
|
||||
return new RegexLeaf(name, "(?:" + WITH_AROBASE + ")?");
|
||||
}
|
||||
|
||||
public static TimeTick parseTimeTick(String name, RegexResult arg, Clock clock) {
|
||||
|
@ -59,6 +59,7 @@ public class TimingDiagram extends UmlDiagram implements Clock {
|
||||
private final List<TimeMessage> messages = new ArrayList<TimeMessage>();
|
||||
private final TimingRuler ruler = new TimingRuler(getSkinParam());
|
||||
private TimeTick now;
|
||||
private Player lastPlayer;
|
||||
|
||||
public DiagramDescription getDescription() {
|
||||
return new DiagramDescriptionImpl("(Timing Diagram)", getClass());
|
||||
@ -94,29 +95,43 @@ public class TimingDiagram extends UmlDiagram implements Clock {
|
||||
private final double marginX2 = 5;
|
||||
|
||||
private void drawInternal(UGraphic ug) {
|
||||
final UTranslate lastTranslate = getUTranslateForPlayer(null, ug.getStringBounder());
|
||||
final double totalWith = ruler.getWidth() + marginX1 + marginX2;
|
||||
final StringBounder stringBounder = ug.getStringBounder();
|
||||
final UTranslate lastTranslate = getUTranslateForPlayer(null, stringBounder);
|
||||
final double withBeforeRuler = getWithBeforeRuler(stringBounder);
|
||||
final double totalWith = withBeforeRuler + ruler.getWidth() + marginX1 + marginX2;
|
||||
|
||||
final ULine border = new ULine(0, lastTranslate.getDy());
|
||||
final UStroke borderStroke = new UStroke(1.7);
|
||||
ug.apply(new UChangeColor(HtmlColorUtils.BLACK)).apply(borderStroke).draw(border);
|
||||
ug.apply(new UChangeColor(HtmlColorUtils.BLACK)).apply(borderStroke).apply(new UTranslate(totalWith, 0))
|
||||
.draw(border);
|
||||
// ug.apply(new UChangeColor(HtmlColorUtils.BLACK)).apply(new UStroke(2.0)).draw(border);
|
||||
|
||||
ug = ug.apply(new UTranslate(marginX1, 0));
|
||||
|
||||
for (Player player : players.values()) {
|
||||
final UGraphic playerUg = ug.apply(getUTranslateForPlayer(player, ug.getStringBounder()));
|
||||
final UGraphic playerUg = ug.apply(getUTranslateForPlayer(player, stringBounder));
|
||||
player.drawU(playerUg);
|
||||
player.drawContent(playerUg.apply(new UTranslate(withBeforeRuler, 0)));
|
||||
player.drawWidthHeader(playerUg);
|
||||
playerUg.apply(new UChangeColor(HtmlColorUtils.BLACK)).apply(borderStroke)
|
||||
.apply(new UTranslate(-marginX1, 0)).draw(new ULine(totalWith, 0));
|
||||
}
|
||||
ug = ug.apply(new UTranslate(withBeforeRuler, 0));
|
||||
ruler.draw(ug.apply(lastTranslate));
|
||||
for (TimeMessage timeMessage : messages) {
|
||||
drawMessages(ug, timeMessage);
|
||||
}
|
||||
}
|
||||
|
||||
private double getWithBeforeRuler(StringBounder stringBounder) {
|
||||
double width = 0;
|
||||
for (Player player : players.values()) {
|
||||
width = Math.max(width, player.getGetWidthHeader(stringBounder));
|
||||
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
private void drawMessages(UGraphic ug, TimeMessage message) {
|
||||
final Player player1 = message.getPlayer1();
|
||||
final Player player2 = message.getPlayer2();
|
||||
@ -149,7 +164,9 @@ public class TimingDiagram extends UmlDiagram implements Clock {
|
||||
}
|
||||
|
||||
public void createLifeLine(String code, String full, TimingStyle type) {
|
||||
players.put(code, new Player(code, full, type, getSkinParam(), ruler));
|
||||
final Player player = new Player(code, full, type, getSkinParam(), ruler);
|
||||
players.put(code, player);
|
||||
lastPlayer = player;
|
||||
}
|
||||
|
||||
public void createTimeMessage(Player player1, TimeTick time1, Player player2, TimeTick time2, String label) {
|
||||
@ -163,6 +180,10 @@ public class TimingDiagram extends UmlDiagram implements Clock {
|
||||
ruler.addTime(time);
|
||||
}
|
||||
|
||||
public void updateNow(TimeTick time) {
|
||||
this.now = time;
|
||||
}
|
||||
|
||||
public Player getPlayer(String code) {
|
||||
return players.get(code);
|
||||
}
|
||||
@ -174,4 +195,12 @@ public class TimingDiagram extends UmlDiagram implements Clock {
|
||||
return now;
|
||||
}
|
||||
|
||||
public void setLastPlayer(Player player) {
|
||||
this.lastPlayer = player;
|
||||
}
|
||||
|
||||
public Player getLastPlayer() {
|
||||
return lastPlayer;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -51,9 +51,12 @@ public class TimingDiagramFactory extends UmlDiagramFactory {
|
||||
addCommonCommands(cmds);
|
||||
|
||||
cmds.add(new CommandLifeLine());
|
||||
cmds.add(new CommandChangeState());
|
||||
cmds.add(new CommandChangeState1());
|
||||
cmds.add(new CommandChangeState2());
|
||||
cmds.add(new CommandAtTime());
|
||||
cmds.add(new CommandAtPlayer());
|
||||
cmds.add(new CommandTimeMessage());
|
||||
cmds.add(new CommandConstraint());
|
||||
|
||||
return cmds;
|
||||
}
|
||||
|
@ -106,6 +106,9 @@ public class TimingRuler {
|
||||
}
|
||||
|
||||
private TimeTick getMax() {
|
||||
if (times.size() == 0) {
|
||||
throw new IllegalStateException("Empty list!");
|
||||
}
|
||||
return times.get(times.size() - 1);
|
||||
}
|
||||
|
||||
|
@ -151,7 +151,7 @@ public class FontChecker {
|
||||
}
|
||||
|
||||
private String getSvgImage(char c) throws IOException, TransformerException {
|
||||
final SvgGraphics svg = new SvgGraphics(1.0);
|
||||
final SvgGraphics svg = new SvgGraphics(1.0, null);
|
||||
svg.setStrokeColor("black");
|
||||
svg.svgImage(getBufferedImage(c), 0, 0);
|
||||
final ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
|
@ -359,7 +359,8 @@ public class ImageBuilder {
|
||||
case PNG:
|
||||
return createUGraphicPNG(colorMapper, dpiFactor, dim, mybackcolor, animationArg, dx, dy);
|
||||
case SVG:
|
||||
return createUGraphicSVG(colorMapper, dpiFactor, dim, mybackcolor, fileFormatOption.getSvgLinkTarget());
|
||||
return createUGraphicSVG(colorMapper, dpiFactor, dim, mybackcolor, fileFormatOption.getSvgLinkTarget(),
|
||||
fileFormatOption.getHoverColor());
|
||||
case EPS:
|
||||
return new UGraphicEps(colorMapper, EpsStrategy.getDefault2());
|
||||
case EPS_TEXT:
|
||||
@ -380,18 +381,18 @@ public class ImageBuilder {
|
||||
}
|
||||
|
||||
private UGraphic2 createUGraphicSVG(ColorMapper colorMapper, double scale, Dimension2D dim, HtmlColor mybackcolor,
|
||||
String svgLinkTarget) {
|
||||
String svgLinkTarget, String hover) {
|
||||
Color backColor = Color.WHITE;
|
||||
if (mybackcolor instanceof HtmlColorSimple) {
|
||||
backColor = colorMapper.getMappedColor(mybackcolor);
|
||||
}
|
||||
final UGraphicSvg ug;
|
||||
if (mybackcolor instanceof HtmlColorGradient) {
|
||||
ug = new UGraphicSvg(colorMapper, (HtmlColorGradient) mybackcolor, false, scale, svgLinkTarget);
|
||||
ug = new UGraphicSvg(colorMapper, (HtmlColorGradient) mybackcolor, false, scale, svgLinkTarget, hover);
|
||||
} else if (backColor == null || backColor.equals(Color.WHITE)) {
|
||||
ug = new UGraphicSvg(colorMapper, false, scale, svgLinkTarget);
|
||||
ug = new UGraphicSvg(colorMapper, false, scale, svgLinkTarget, hover);
|
||||
} else {
|
||||
ug = new UGraphicSvg(colorMapper, StringUtils.getAsHtml(backColor), false, scale, svgLinkTarget);
|
||||
ug = new UGraphicSvg(colorMapper, StringUtils.getAsHtml(backColor), false, scale, svgLinkTarget, hover);
|
||||
}
|
||||
return ug;
|
||||
|
||||
|
@ -67,7 +67,8 @@ public abstract class UGraphicUtils {
|
||||
PngIO.write(im, os, fileFormatOption.isWithMetadata() ? metadata : null, 96);
|
||||
} else if (fileFormat == FileFormat.SVG) {
|
||||
final UGraphicSvg svg = new UGraphicSvg(colorMapper, StringUtils.getAsHtml(colorMapper
|
||||
.getMappedColor(background)), false, 1.0, fileFormatOption.getSvgLinkTarget());
|
||||
.getMappedColor(background)), false, 1.0, fileFormatOption.getSvgLinkTarget(),
|
||||
fileFormatOption.getHoverColor());
|
||||
image.drawU(svg);
|
||||
svg.createXml(os);
|
||||
} else if (fileFormat == FileFormat.EPS) {
|
||||
|
@ -76,16 +76,16 @@ public class UGraphicSvg extends AbstractUGraphic<SvgGraphics> implements ClipCo
|
||||
register();
|
||||
}
|
||||
|
||||
public UGraphicSvg(ColorMapper colorMapper, String backcolor, boolean textAsPath, double scale, String linkTarget) {
|
||||
this(colorMapper, new SvgGraphics(backcolor, scale), textAsPath, linkTarget);
|
||||
public UGraphicSvg(ColorMapper colorMapper, String backcolor, boolean textAsPath, double scale, String linkTarget, String hover) {
|
||||
this(colorMapper, new SvgGraphics(backcolor, scale, hover), textAsPath, linkTarget);
|
||||
}
|
||||
|
||||
public UGraphicSvg(ColorMapper colorMapper, boolean textAsPath, double scale, String linkTarget) {
|
||||
this(colorMapper, new SvgGraphics(scale), textAsPath, linkTarget);
|
||||
public UGraphicSvg(ColorMapper colorMapper, boolean textAsPath, double scale, String linkTarget, String hover) {
|
||||
this(colorMapper, new SvgGraphics(scale, hover), textAsPath, linkTarget);
|
||||
}
|
||||
|
||||
public UGraphicSvg(ColorMapper mapper, HtmlColorGradient gr, boolean textAsPath, double scale, String linkTarget) {
|
||||
this(mapper, new SvgGraphics(scale), textAsPath, linkTarget);
|
||||
public UGraphicSvg(ColorMapper mapper, HtmlColorGradient gr, boolean textAsPath, double scale, String linkTarget, String hover) {
|
||||
this(mapper, new SvgGraphics(scale, hover), textAsPath, linkTarget);
|
||||
|
||||
final SvgGraphics svg = getGraphicObject();
|
||||
svg.paintBackcolorGradient(mapper, gr);
|
||||
|
@ -175,7 +175,8 @@ public class PSystemVersion extends AbstractPSystem {
|
||||
add(strings, "<u>Word Macro</u>: Alain Bertucat & Matthieu Sabatier", withTag);
|
||||
add(strings, "<u>Word Add-in</u>: Adriaan van den Brand", withTag);
|
||||
add(strings, "<u>J2V8 & viz.js integration</u>: Andreas Studer", withTag);
|
||||
add(strings, "<u>Eclipse Plugin</u>: Claude Durif & Anne Pecoil", withTag);
|
||||
add(strings, "<u>Official Eclipse Plugin</u>: Hallvard Tr\u00E6tteberg", withTag);
|
||||
add(strings, "<u>Original Eclipse Plugin</u>: Claude Durif & Anne Pecoil", withTag);
|
||||
add(strings, "<u>Servlet & XWiki</u>: Maxime Sinclair", withTag);
|
||||
add(strings, "<u>Site design</u>: Raphael Cotisson", withTag);
|
||||
add(strings, "<u>Logo</u>: Benjamin Croizet", withTag);
|
||||
|
@ -36,7 +36,7 @@ import java.util.Date;
|
||||
public class Version {
|
||||
|
||||
public static int version() {
|
||||
return 8055;
|
||||
return 8056;
|
||||
}
|
||||
|
||||
public static String versionString() {
|
||||
@ -68,7 +68,7 @@ public class Version {
|
||||
}
|
||||
|
||||
public static long compileTime() {
|
||||
return 1485969540264L;
|
||||
return 1487187608733L;
|
||||
}
|
||||
|
||||
public static String compileTimeString() {
|
||||
|
Loading…
Reference in New Issue
Block a user