Skip to content
Snippets Groups Projects
Commit ca396aa0 authored by Ulrich Schöpp's avatar Ulrich Schöpp Committed by Ulrich Schöpp
Browse files

Factor out text alignment


The position of aligned text depends on the width of the text,
which may change. This happens when a CSS stylesheet redefines
the default font. The diagram editor will open with slightly
misplaced text (e.g. on channels), which is only updated when one
moves the mouse. The class AlignedText updates the text
translation automatically when the text size changes.

Signed-off-by: default avatarUlrich Schöpp <schoepp@fortiss.org>
Issue-Ref: 4184
parent 9d49df7c
No related branches found
No related tags found
1 merge request!166Polish diagram appearance
......@@ -7,7 +7,7 @@ LayoutedLineLinkVisual.java 5fc26086e2f63afee403379ba8f09f5113d4c025 GREEN
LayoutedRectangularAnchorageContentVisualBase.java 9d5ab8fbad2900a26ec5ea620f9f1a2a1656da77 GREEN
LayoutedRectangularAnchorageDiagramVisualBase.java b9aa51cce71d8f6c4e400f6019b3cab0a1ed6df6 GREEN
LayoutedRectangularContentVisualBase.java 61698ffd771ee2ad798025df8195d1bc09c2c765 GREEN
NamedLayoutedCircularAnchorageContentVisual.java e1427071046afe94a6e6e1d54fec39387d94ee36 YELLOW
NamedLayoutedCircularAnchorageContentVisual.java b9fd5f93af193d2a1e2ea9c6d0b54d219a5224c4 YELLOW
NamedLayoutedCircularAnchorageDiagramVisual.java eb1e736d7715b86dbc3ca0551bb754157f71cc5f GREEN
NamedLayoutedCurveLinkVisual.java 7945b2f550d5e4804f44891294ee60cc8ffcbf1e GREEN
NamedLayoutedEllipticContentVisual.java f96a956c2f71b675eee56cfc613684397545da68 GREEN
......
......@@ -22,13 +22,11 @@ import org.fortiss.tooling.base.model.layout.ILayoutedModelElement;
import org.fortiss.tooling.common.ui.javafx.lwfxef.DiagramLayers;
import org.fortiss.tooling.common.ui.javafx.lwfxef.mvc.IContentAnchorageMVCBundle;
import org.fortiss.tooling.common.ui.javafx.lwfxef.visual.IVisual;
import org.fortiss.tooling.common.ui.javafx.lwfxef.visual.widgets.AlignedText;
import org.fortiss.tooling.kernel.model.INamedElement;
import javafx.geometry.Bounds;
import javafx.geometry.Pos;
import javafx.geometry.Rectangle2D;
import javafx.geometry.VPos;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
/**
* {@link IVisual} for layouted and named {@link IConnector}s of some content element within a
......@@ -39,15 +37,13 @@ import javafx.scene.text.TextAlignment;
public class NamedLayoutedCircularAnchorageContentVisual<T extends ILayoutedModelElement & INamedElement & IConnector>
extends LayoutedCircularAnchorageContentVisualBase<T> {
/** The name text label. */
private final Text nameText = new Text("");
private final AlignedText nameText = new AlignedText();
/** Constructor. */
public NamedLayoutedCircularAnchorageContentVisual(IContentAnchorageMVCBundle mvcb,
Class<T> modelType) {
super(mvcb, modelType);
nameText.setMouseTransparent(true);
nameText.setTextAlignment(TextAlignment.LEFT);
nameText.setTextOrigin(VPos.CENTER);
}
/** {@inheritDoc} */
......@@ -55,36 +51,39 @@ public class NamedLayoutedCircularAnchorageContentVisual<T extends ILayoutedMode
public void updateNodes(DiagramLayers layers) {
super.updateNodes(layers);
if(enableName()) {
Rectangle2D bounds = getCurrentBounds();
nameText.setX(bounds.getMaxX());
nameText.setY(bounds.getMinY() + bounds.getHeight() / 2);
nameText.setText(getName());
if(nameText.getParent() == null) {
layers.getVisualFeedbackLayer().add(nameText, getMVCBundle());
}
// Depending on the side, show text to left or top of anchorage.
Bounds textBounds = nameText.getBoundsInLocal();
double width = textBounds.getWidth() + bounds.getWidth();
double verticalMiddle = bounds.getHeight() / 2;
// Depending on the side, place the text off to the side.
Rectangle2D bounds = getCurrentBounds();
Rectangle2D attachedToBounds =
getMVCBundle().getAttachedTo().getVisual().getCurrentBounds();
// left
if(textBounds.getMaxX() >= attachedToBounds.getMinX() &&
textBounds.getMaxX() - width < attachedToBounds.getMinX() &&
textBounds.getMinX() - width >= 0) {
nameText.setX(nameText.getX() - width);
if(bounds.getMaxX() >= attachedToBounds.getMinX() &&
bounds.getMinX() < attachedToBounds.getMinX()) {
// left
nameText.setX(bounds.getMinX());
nameText.setY(bounds.getMinY() + bounds.getHeight() / 2);
nameText.setAlignment(Pos.CENTER_RIGHT);
} else if(bounds.getMaxY() >= attachedToBounds.getMinY() &&
bounds.getMinY() < attachedToBounds.getMinY()) {
// top
nameText.setX(bounds.getMaxX());
nameText.setY(bounds.getMinY());
nameText.setAlignment(Pos.BOTTOM_CENTER);
} else if(bounds.getMinY() <= attachedToBounds.getMaxY() &&
bounds.getMaxY() > attachedToBounds.getMaxY()) {
// bottom
nameText.setX(bounds.getMaxX());
nameText.setY(bounds.getMaxY());
nameText.setAlignment(Pos.TOP_CENTER);
} else {
// right
nameText.setX(bounds.getMaxX());
nameText.setY(bounds.getMinY() + bounds.getHeight() / 2);
nameText.setAlignment(Pos.CENTER_LEFT);
}
// top
if(textBounds.getMaxY() >= attachedToBounds.getMinY() &&
textBounds.getMaxY() - verticalMiddle < attachedToBounds.getMinY() &&
textBounds.getMinY() - verticalMiddle >= 0) {
nameText.setY(nameText.getY() - verticalMiddle);
}
// bottom
if(textBounds.getMinY() <= attachedToBounds.getMaxY() &&
textBounds.getMaxY() + bounds.getHeight() / 2 >= attachedToBounds.getMaxY()) {
nameText.setY(nameText.getY() + verticalMiddle);
if(nameText.getParent() == null) {
layers.getVisualFeedbackLayer().add(nameText, getMVCBundle());
}
} else if(nameText.getParent() != null) {
layers.getVisualFeedbackLayer().remove(nameText);
......
DiamondContentVisualBase.java a81e76e85706ad38b6c22bbcd1cc5a5696737e3d GREEN
LineLinkGraph.java 85a06a553f88f7b9fb4bd9c06411725d9fb160fc GREEN
LineLinkVisualBase.java 876d6872b1844568f055809b975d2471330f719f GREEN
LineSegment.java 9ab1b97ad372db763654ef783747fa0733bec55c GREEN
LineSegment.java 6628dcf949560c08b3445ea35ffb845c221c822e YELLOW
RectangularBorderLocation.java 824472c353534d1094ae4f735a30a231b885f050 GREEN
RectangularContentAnchorageVisualBase.java 39981dc29cac42d77c6ffe855ecc8ccad1689230 GREEN
RectangularContentVisualBase.java aeeda282f330180b1f339e3230810eccea2e7e7b GREEN
......
......@@ -14,9 +14,11 @@ import static javafx.scene.paint.Color.TRANSPARENT;
import org.fortiss.tooling.common.ui.javafx.lwfxef.DiagramLayers;
import org.fortiss.tooling.common.ui.javafx.lwfxef.DiagramLayers.ILayer;
import org.fortiss.tooling.common.ui.javafx.lwfxef.mvc.ILinkMVCBundle;
import org.fortiss.tooling.common.ui.javafx.lwfxef.visual.widgets.AlignedText;
import org.fortiss.tooling.common.ui.javafx.lwfxef.visual.widgets.LinkArrowWidget;
import javafx.geometry.Point2D;
import javafx.geometry.Pos;
import javafx.geometry.VPos;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
......@@ -46,7 +48,7 @@ final class LineSegment {
/** The arrow head widget. */
private final LinkArrowWidget arrowWidget;
/** Stores the label. */
private Text label;
private AlignedText label;
/** Stores the simulation label */
private Text simulationLabel;
/** Offset of simulation label in y direction. */
......@@ -83,9 +85,9 @@ final class LineSegment {
arrowWidget = null;
}
if(labelText != null) {
label = new Text(labelText);
label.setTextAlignment(TextAlignment.CENTER);
label.setTextOrigin(VPos.TOP);
label = new AlignedText();
label.setText(labelText);
label.setAlignment(Pos.BOTTOM_CENTER);
} else {
label = null;
}
......@@ -130,8 +132,7 @@ final class LineSegment {
if(label != null) {
label.setText(labelText);
double lx = (visibleLine.getStartX() + visibleLine.getEndX() -
label.getBoundsInLocal().getWidth()) / 2;
double lx = (visibleLine.getStartX() + visibleLine.getEndX()) / 2;
double ly = (visibleLine.getStartY() + visibleLine.getEndY()) / 2;
label.setX(lx);
label.setY(ly);
......@@ -224,7 +225,7 @@ final class LineSegment {
}
if(label != null) {
label.setText(labelText);
double lx = (sx + ex - label.getBoundsInLocal().getWidth()) / 2;
double lx = (sx + ex) / 2;
double ly = (sy + ey) / 2;
label.setX(lx);
label.setY(ly);
......
AlignedText.java f8bc913c77862b650d3f73de6309e71afb4b46b4 YELLOW
ExpandCollapseWidget.java f431b6a86f3ce1794c55b90f39a15cda4f92ea06 GREEN
LinkArrowWidget.java 5354f14ca9d53cc3df88afb1867a266dfde65199 GREEN
/*-------------------------------------------------------------------------+
| Copyright 2021 fortiss GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.tooling.common.ui.javafx.lwfxef.visual.widgets;
import javafx.geometry.Bounds;
import javafx.geometry.Pos;
import javafx.geometry.VPos;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
/**
* Text shape that automatically sets its translation to achieve text alignment.
*
*/
public class AlignedText extends Text {
/**
* The alignment to be achieved by setting the translation.
*/
private Pos alignment = Pos.BOTTOM_LEFT;
/**
*
*/
public AlignedText() {
super();
this.setTextAlignment(TextAlignment.LEFT);
this.setTextOrigin(VPos.TOP);
this.boundsInLocalProperty().addListener(o -> updatePosition());
this.baselineOffsetProperty().addListener(o -> updatePosition());
}
/** Returns alignment. */
public Pos getAlignment() {
return alignment;
}
/** Sets alignment. */
public void setAlignment(Pos alignment) {
this.alignment = alignment;
updatePosition();
}
/** Sets the translation. */
private void updatePosition() {
Bounds bounds = getBoundsInLocal();
double translateX = 0;
switch(alignment.getHpos()) {
case LEFT:
translateX = 0;
break;
case CENTER:
translateX = -bounds.getWidth() / 2;
break;
case RIGHT:
translateX = -bounds.getWidth();
break;
}
setTranslateX(translateX);
setTextOrigin(alignment.getVpos());
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment