diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/ArrowAndNoteBox.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/ArrowAndNoteBox.java index cae003f8176..574e3367e37 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/ArrowAndNoteBox.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/ArrowAndNoteBox.java @@ -105,9 +105,6 @@ public double getPreferredWidth(StringBounder stringBounder) { double result = w; for (NoteBox noteBox : noteBoxes) { result += noteBox.getPreferredWidth(stringBounder); - if (noteBox.getNotePosition() == NotePosition.RIGHT) { - result += noteBox.getRightShift(arrow.getStartingY()); - } } return result; } diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageSelfArrow.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageSelfArrow.java index 9bd8b51053b..d1c8a2db614 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageSelfArrow.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageSelfArrow.java @@ -51,13 +51,15 @@ class MessageSelfArrow extends Arrow { private final LivingParticipantBox p1; private final double deltaX; private final double deltaY; + private final boolean isReverse; public MessageSelfArrow(double startingY, Rose skin, ArrowComponent arrow, LivingParticipantBox p1, double deltaY, - Url url, double deltaX) { + Url url, double deltaX, boolean isReverse) { super(startingY, skin, arrow, url); this.p1 = p1; this.deltaY = deltaY; this.deltaX = deltaX; + this.isReverse = isReverse; } @Override @@ -92,7 +94,10 @@ public double getStartingX(StringBounder stringBounder) { // } final double pos2 = p1.getLiveThicknessAt(stringBounder, getArrowYStartLevel(stringBounder)).getSegment() .getPos2(); - return pos2 + deltaX; + if (isReverse) + return pos2 + deltaX - getPreferredWidth(stringBounder); + else + return pos2 + deltaX; } @Override @@ -143,4 +148,8 @@ public LivingParticipantBox getParticipantAt(StringBounder stringBounder, NotePo public double getActualWidth(StringBounder stringBounder) { return getPreferredWidth(stringBounder); } + + public boolean isReverse() { + return isReverse; + } } diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Abstract.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Abstract.java index b7f01cb2a00..d1842494639 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Abstract.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Abstract.java @@ -119,8 +119,14 @@ protected final NoteBox createNoteBox(StringBounder stringBounder, Arrow arrow, final NoteBox noteBox = new NoteBox(arrow.getStartingY(), noteComp, p, null, noteOnMessage.getPosition(), noteOnMessage.getUrl()); - if (arrow instanceof MessageSelfArrow && noteOnMessage.getPosition() == NotePosition.RIGHT) { - noteBox.pushToRight(arrow.getPreferredWidth(stringBounder)); + if (arrow instanceof MessageSelfArrow) { + boolean isReverseSelfArrow = ((MessageSelfArrow) arrow).isReverse(); + if (!isReverseSelfArrow && noteOnMessage.getPosition() == NotePosition.RIGHT) { + noteBox.pushToRight(arrow.getPreferredWidth(stringBounder)); + } + if (isReverseSelfArrow && noteOnMessage.getPosition() == NotePosition.LEFT) { + noteBox.pushToRight(-arrow.getPreferredWidth(stringBounder)); + } } // if (arrow instanceof MessageExoArrow) { // final MessageExoType type = ((MessageExoArrow) arrow).getType(); diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Message.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Message.java index 4939c98089e..a135d8f2750 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Message.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Message.java @@ -216,7 +216,7 @@ private MessageSelfArrow createMessageSelfArrow() { final ArrowComponent comp = getDrawingSet().getSkin().createComponentArrow(styles, getConfig(), getDrawingSet().getSkinParam(), getMessage().getLabelNumbered()); return new MessageSelfArrow(posY, getDrawingSet().getSkin(), comp, getLivingParticipantBox1(), deltaY, - getMessage().getUrl(), deltaX); + getMessage().getUrl(), deltaX,getConfig().isReverseDefine()); } private double getHalfLifeWidth() { diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationExoTile.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationExoTile.java index 1601a6f639e..36cf8cb1835 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationExoTile.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationExoTile.java @@ -188,6 +188,9 @@ private Real getPoint1(final StringBounder stringBounder) { if (message.getType().isRightBorder()) return livingSpace.getPosC(stringBounder); + if (isShortArrow()) + return livingSpace.getPosC(stringBounder).addFixed(-getPreferredWidth(stringBounder)); + return tileArguments.getXOrigin(); } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileSelf.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileSelf.java index 03e15a84e7f..435f2fbf9cd 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileSelf.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileSelf.java @@ -119,7 +119,7 @@ public void drawU(UGraphic ug) { final StringBounder stringBounder = ug.getStringBounder(); final Component comp = getComponent(stringBounder); final XDimension2D dim = comp.getPreferredDimension(stringBounder); - double x1 = getPoint1(stringBounder).getCurrentValue(); + double x1 = getMinX().getCurrentValue(); final int levelIgnore = livingSpace1.getLevelAt(this, EventsHistoryMode.IGNORE_FUTURE_ACTIVATE); final int levelConsidere = livingSpace1.getLevelAt(this, EventsHistoryMode.CONSIDERE_FUTURE_DEACTIVATE); Log.info("CommunicationTileSelf::drawU levelIgnore=" + levelIgnore + " levelConsidere=" + levelConsidere); @@ -194,7 +194,7 @@ private Real getPoint1(final StringBounder stringBounder) { public Real getMinX() { if (isReverseDefine()) { - return getPoint1(getStringBounder()); + return livingSpace1.getPosC(getStringBounder()).addFixed(-getCompWidth()); } return getPoint1(getStringBounder()); } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileSelfNoteLeft.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileSelfNoteLeft.java new file mode 100644 index 00000000000..a196397fb6b --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileSelfNoteLeft.java @@ -0,0 +1,137 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2024, Arnaud Roques + * + * Project Info: https://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * https://plantuml.com/patreon (only 1$ per month!) + * https://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.sequencediagram.teoz; + +import net.sourceforge.plantuml.klimt.UTranslate; +import net.sourceforge.plantuml.klimt.drawing.UGraphic; +import net.sourceforge.plantuml.klimt.font.StringBounder; +import net.sourceforge.plantuml.klimt.geom.XDimension2D; +import net.sourceforge.plantuml.klimt.shape.UDrawable; +import net.sourceforge.plantuml.real.Real; +import net.sourceforge.plantuml.sequencediagram.AbstractMessage; +import net.sourceforge.plantuml.sequencediagram.Event; +import net.sourceforge.plantuml.sequencediagram.Note; +import net.sourceforge.plantuml.skin.Area; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.ComponentType; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.skin.rose.Rose; +import net.sourceforge.plantuml.style.ISkinParam; + +public class CommunicationTileSelfNoteLeft extends AbstractTile { + + private final CommunicationTileSelf tile; + private final AbstractMessage message; + private final Rose skin; + private final ISkinParam skinParam; + private final Note noteOnMessage; + private final YGauge yGauge; + + public Event getEvent() { + return message; + } + + @Override + public double getContactPointRelative() { + return tile.getContactPointRelative(); + } + + public CommunicationTileSelfNoteLeft(CommunicationTileSelf tile, AbstractMessage message, Rose skin, ISkinParam skinParam, + Note noteOnMessage, YGauge currentY) { + super(((AbstractTile) tile).getStringBounder(), currentY); + this.tile = tile; + this.message = message; + this.skin = skin; + this.skinParam = skinParam; + this.noteOnMessage = noteOnMessage; + this.yGauge = YGauge.create(currentY.getMax(), getPreferredHeight()); + } + + @Override + public YGauge getYGauge() { + return yGauge; + } + + @Override + final protected void callbackY_internal(TimeHook y) { + super.callbackY_internal(y); + tile.callbackY(y); + } + + private Component getComponent(StringBounder stringBounder) { + final Component comp = skin.createComponentNote(noteOnMessage.getUsedStyles(), ComponentType.NOTE, + noteOnMessage.getSkinParamBackcolored(skinParam), noteOnMessage.getDisplay(), + noteOnMessage.getColors()); + return comp; + } + + private Real getNotePosition(StringBounder stringBounder) { + final Component comp = getComponent(stringBounder); + final XDimension2D dim = comp.getPreferredDimension(stringBounder); + //return livingSpace.getPosC(stringBounder).addFixed(-dim.getWidth()); + return tile.getMinX().addFixed(-dim.getWidth()); + } + + public void drawU(UGraphic ug) { + final StringBounder stringBounder = ug.getStringBounder(); + final Component comp = getComponent(stringBounder); + final XDimension2D dim = comp.getPreferredDimension(stringBounder); + final Area area = Area.create(dim.getWidth(), dim.getHeight()); + tile.drawU(ug); + final Real p = getNotePosition(stringBounder); + + comp.drawU(ug.apply(UTranslate.dx(p.getCurrentValue())), area, (Context2D) ug); + } + + public double getPreferredHeight() { + final Component comp = getComponent(getStringBounder()); + final XDimension2D dim = comp.getPreferredDimension(getStringBounder()); + return Math.max(tile.getPreferredHeight(), dim.getHeight()); + } + + public void addConstraints() { + tile.addConstraints(); + } + + public Real getMinX() { + return getNotePosition(getStringBounder()); + } + + public Real getMaxX() { + return tile.getMaxX(); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/TileBuilder.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/TileBuilder.java index 597316a1170..ae162a52be5 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/TileBuilder.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/TileBuilder.java @@ -105,7 +105,10 @@ public static List buildOne(Iterator it, TileArguments tileArgument } for (Note noteOnMessage : msg.getNoteOnMessages()) { final NotePosition notePosition = noteOnMessage.getPosition(); - if (notePosition == NotePosition.LEFT) + if (notePosition == NotePosition.LEFT && msg.isSelfMessage()) + result = new CommunicationTileSelfNoteLeft((CommunicationTileSelf) result, msg, skin, skinParam, + noteOnMessage, currentY); + else if (notePosition == NotePosition.LEFT) result = new CommunicationTileNoteLeft(result, msg, skin, skinParam, reverse ? livingSpace2 : livingSpace1, noteOnMessage, currentY); else if (notePosition == NotePosition.RIGHT && msg.isSelfMessage()) diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseSelfArrow.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseSelfArrow.java index 5f28a2f3f20..e020ac0e067 100644 --- a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseSelfArrow.java +++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseSelfArrow.java @@ -106,10 +106,10 @@ protected void drawInternalU(UGraphic ug, Area area) { x2 += 2 * ComponentRoseArrow.spaceCrossX; if (getArrowConfiguration().isReverseDefine()) { - ug2.apply(new UTranslate(-xRight, textHeight)).draw(ULine.hline(xRight - x1)); - ug2.apply(new UTranslate(-xRight, textHeight)).draw(ULine.vline(arrowHeight)); - ug2.apply(new UTranslate(-xRight, textHeight + arrowHeight)).draw(ULine.hline(xRight - x2)); - final UPolygon polygon = getPolygon().translate(0, textHeight + arrowHeight); + ug2.apply(new UTranslate(-xRight+getPreferredWidth(stringBounder), textHeight)).draw(ULine.hline(xRight - x1)); + ug2.apply(new UTranslate(-xRight+getPreferredWidth(stringBounder), textHeight)).draw(ULine.vline(arrowHeight)); + ug2.apply(new UTranslate(-xRight+getPreferredWidth(stringBounder), textHeight + arrowHeight)).draw(ULine.hline(xRight - x2)); + final UPolygon polygon = getPolygon().translate(+getPreferredWidth(stringBounder), textHeight + arrowHeight); ug.apply(getForegroundColor().bg()).apply(UTranslate.dx(x2)).draw(polygon); } else { @@ -153,11 +153,7 @@ protected void drawInternalU(UGraphic ug, Area area) { } } - if (getArrowConfiguration().isReverseDefine()) - getTextBlock().drawU(ug.apply(UTranslate.dx(-getPureTextWidth(stringBounder)))); - else - getTextBlock().drawU(ug.apply(UTranslate.dx(getMarginX1()))); - + getTextBlock().drawU(ug.apply(UTranslate.dx(getMarginX1()))); } private UPolygon getPolygon() {