1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-05-31 23:50:49 +00:00

version 8056

This commit is contained in:
Arnaud Roques 2017-02-15 22:34:36 +01:00
parent a2cbfb5712
commit c7252cdf63
65 changed files with 1090 additions and 183 deletions

View File

@ -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>

View File

@ -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;
}

View File

@ -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),

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -129,5 +129,10 @@ public interface ISkinParam extends ISkinSimple {
public SplitParam getSplitParam();
public int swimlaneWidth();
public UmlDiagramType getUmlDiagramType();
public HtmlColor getHoverPathColor();
}

View File

@ -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);
}
}

View File

@ -246,4 +246,12 @@ public class SkinParamDelegator implements ISkinParam {
return skinParam.swimlaneWidth();
}
public UmlDiagramType getUmlDiagramType() {
return skinParam.getUmlDiagramType();
}
public HtmlColor getHoverPathColor() {
return skinParam.getHoverPathColor();
}
}

View File

@ -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) {

View File

@ -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);

View File

@ -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", "\\((.+?)\\)"))), //

View File

@ -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);
}

View File

@ -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());

View File

@ -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));

View File

@ -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,

View File

@ -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);

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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();
}

View File

@ -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) {

View File

@ -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() {
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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)) {

View File

@ -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();
}

View File

@ -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);

View File

@ -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(

View File

@ -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;

View File

@ -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) {

View File

@ -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) {

View File

@ -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);
}

View File

@ -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());

View File

@ -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();
}

View File

@ -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();

View File

@ -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) {

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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]*$"));
}

View File

@ -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();
}

View 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.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();
}
}

View 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.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();
}
}

View File

@ -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

View 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);
}
}

View File

@ -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);
}
}

View 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);
}
}

View 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);
}
}

View File

@ -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));
}
}

View File

@ -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);
}
}

View File

@ -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());

View 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;
}
}

View File

@ -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);
}

View File

@ -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) {

View File

@ -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,15 +180,27 @@ 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);
}
public TimeTick getNow() {
// if (now == null) {
// throw new IllegalStateException();
// }
// if (now == null) {
// throw new IllegalStateException();
// }
return now;
}
public void setLastPlayer(Player player) {
this.lastPlayer = player;
}
public Player getLastPlayer() {
return lastPlayer;
}
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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();

View File

@ -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;

View File

@ -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) {

View File

@ -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);

View File

@ -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);

View File

@ -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() {