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

Address TODOs


Signed-off-by: default avatarUlrich Schöpp <schoepp@fortiss.org>
Issue-Ref: 4181
parent 0f7b46de
Branches
Tags
1 merge request!163Improve usability of diagram viewer
Pipeline #32231 failed
DiagramCoordinate.java 6b00aec99054d4cd19003a72bd4e5e774ac6a641 GREEN DiagramCoordinate.java 6b00aec99054d4cd19003a72bd4e5e774ac6a641 GREEN
DiagramLayers.java aa1f95dbae290c8b00202abe4385b01b8f36e5ab GREEN DiagramLayers.java aa1f95dbae290c8b00202abe4385b01b8f36e5ab GREEN
DiagramViewer.java 504ae4708be551d72bf4dee5ef9fbfbdbadef18f RED DiagramViewer.java f57cb00ccedd1ef37e5ce33f2df04989b81329a4 YELLOW
DiagramViewerDefaultTags.java 6230763252409c60009ab8887b4ef582cf883229 GREEN DiagramViewerDefaultTags.java 6230763252409c60009ab8887b4ef582cf883229 GREEN
DiagramViewerFeatures.java 3dd78d9c117fc156924a151c6f8d770c53c103bc GREEN DiagramViewerFeatures.java 3dd78d9c117fc156924a151c6f8d770c53c103bc GREEN
DiagramViewerSelection.java e833f592543bc97077907d980a39b123fc4044e6 GREEN DiagramViewerSelection.java e833f592543bc97077907d980a39b123fc4044e6 GREEN
EDragGesture.java 5cfa098d3877db11981c2750e5e103156d62fc5e GREEN EDragGesture.java 5cfa098d3877db11981c2750e5e103156d62fc5e GREEN
FeedbackChange.java b088fa89af648f1674f2f9c1f7f99d585ce801ca GREEN FeedbackChange.java b088fa89af648f1674f2f9c1f7f99d585ce801ca GREEN
GridCanvasVisual.java d8499f9458032ececff706c170d5f747daf20050 RED GridCanvasVisual.java e7c83211e0fce2b0d55aac77d0203950286646b9 YELLOW
MVCBundleManager.java 18667b4ed98da124b7c1bc7a103e95232df9ad49 GREEN MVCBundleManager.java 18667b4ed98da124b7c1bc7a103e95232df9ad49 GREEN
MouseState.java 3d9993f799d5d74bc74ac03b46e4a1857c4d267e GREEN MouseState.java 3d9993f799d5d74bc74ac03b46e4a1857c4d267e GREEN
SVGExporter.java cbbd1eceb2910fd5c1693e05c5303a193127b9db GREEN SVGExporter.java cbbd1eceb2910fd5c1693e05c5303a193127b9db GREEN
...@@ -13,6 +13,8 @@ import static java.lang.Math.abs; ...@@ -13,6 +13,8 @@ import static java.lang.Math.abs;
import static java.lang.Math.max; import static java.lang.Math.max;
import static java.lang.Math.min; import static java.lang.Math.min;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import static javafx.geometry.Orientation.HORIZONTAL;
import static javafx.geometry.Orientation.VERTICAL;
import static javafx.geometry.VPos.TOP; import static javafx.geometry.VPos.TOP;
import static javafx.scene.layout.GridPane.setHgrow; import static javafx.scene.layout.GridPane.setHgrow;
import static javafx.scene.layout.GridPane.setVgrow; import static javafx.scene.layout.GridPane.setVgrow;
...@@ -145,19 +147,18 @@ public class DiagramViewer { ...@@ -145,19 +147,18 @@ public class DiagramViewer {
// viewer pane // viewer pane
viewerPane = new Pane(); viewerPane = new Pane();
layers.boundsInLocalProperty().addListener((obs, ov, nv) -> { layers.boundsInLocalProperty().addListener((obs, ov, nv) -> {
updateHorizontalScrollbar(); updateScrollBars();
updateVerticalScrollbar();
}); });
layers.getTransforms().add(transform); layers.getTransforms().add(transform);
viewerPane.getChildren().add(layers); viewerPane.getChildren().add(layers);
viewerPane.widthProperty().addListener(evt -> { viewerPane.widthProperty().addListener(evt -> {
updateGridCanvasSize(); updateGridCanvasSize();
updateHorizontalScrollbar(); updateScrollBars();
}); });
viewerPane.heightProperty().addListener(evt -> { viewerPane.heightProperty().addListener(evt -> {
updateGridCanvasSize(); updateGridCanvasSize();
updateVerticalScrollbar(); updateScrollBars();
}); });
// focus event handling // focus event handling
viewerPane.focusedProperty().addListener((obs, ov, nv) -> { viewerPane.focusedProperty().addListener((obs, ov, nv) -> {
...@@ -177,29 +178,11 @@ public class DiagramViewer { ...@@ -177,29 +178,11 @@ public class DiagramViewer {
setHgrow(viewerPane, ALWAYS); setHgrow(viewerPane, ALWAYS);
setVgrow(viewerPane, ALWAYS); setVgrow(viewerPane, ALWAYS);
// TODO factorize to method createScrollBar(javafx.geometry.Orientation) verticalScrollbar = createContentScrollBar(VERTICAL);
// vertical scrollbar
verticalScrollbar = new ScrollBar();
verticalScrollbar.setOrientation(Orientation.VERTICAL);
scrolledPane.add(verticalScrollbar, 2, 1); scrolledPane.add(verticalScrollbar, 2, 1);
verticalScrollbar.valueProperty().addListener((obs, ov, nv) -> {
hideContextMenu();
// TODO (SB): Use "speaking" variable name
Point2D p1 = layers.parentToLocal(0, 0);
transform.appendTranslation(0, -nv.doubleValue() + p1.getY());
viewerManager.gridCanvasVisual.updateNodes(layers);
});
// TODO Use createScrollbar(javafx.geometry.Orientation) horizontalScrollbar = createContentScrollBar(HORIZONTAL);
// horizontal scrollbar
horizontalScrollbar = new ScrollBar();
scrolledPane.add(horizontalScrollbar, 1, 2); scrolledPane.add(horizontalScrollbar, 1, 2);
horizontalScrollbar.valueProperty().addListener((obs, ov, nv) -> {
hideContextMenu();
Point2D p1 = layers.parentToLocal(0, 0);
transform.appendTranslation(-nv.doubleValue() + p1.getX(), 0);
viewerManager.gridCanvasVisual.updateNodes(layers);
});
viewerPane.getChildren().add(debugLabel); viewerPane.getChildren().add(debugLabel);
debugLabel.setLayoutX(20); debugLabel.setLayoutX(20);
...@@ -235,6 +218,26 @@ public class DiagramViewer { ...@@ -235,6 +218,26 @@ public class DiagramViewer {
contentDragController.registerEventFilters(viewerPane); contentDragController.registerEventFilters(viewerPane);
} }
/** Constructs a scrollbar controlling the content */
private ScrollBar createContentScrollBar(Orientation orientation) {
ScrollBar scrollbar = new ScrollBar();
scrollbar.setOrientation(orientation);
scrollbar.valueProperty().addListener((obs, ov, nv) -> {
hideContextMenu();
Point2D diagramTranslation = layers.parentToLocal(0, 0);
switch(orientation) {
case HORIZONTAL:
transform.appendTranslation(-nv.doubleValue() + diagramTranslation.getX(), 0);
break;
case VERTICAL:
transform.appendTranslation(0, -nv.doubleValue() + diagramTranslation.getY());
break;
}
viewerManager.gridCanvasVisual.updateNodes(layers);
});
return scrollbar;
}
/** Returns viewerPane. */ /** Returns viewerPane. */
/* package */ Pane getViewerPane() { /* package */ Pane getViewerPane() {
return viewerPane; return viewerPane;
...@@ -286,55 +289,43 @@ public class DiagramViewer { ...@@ -286,55 +289,43 @@ public class DiagramViewer {
return exporter.export(); return exporter.export();
} }
// TOOD (SB): Factorize commonalities with updateHorizontalScrollbar() /** Updates the scrollbars. */
/** Updates the vertical scrollbar. */ private void updateScrollBars() {
private void updateVerticalScrollbar() {
// The size of the content (in diagram coordinates) // The size of the content (in diagram coordinates)
Bounds contentBounds = layers.getBoundsInLocal(); Bounds contentBounds = layers.getBoundsInLocal();
double contentHeight = contentBounds.getHeight(); double contentHeight = contentBounds.getHeight();
double contentWidth = contentBounds.getWidth();
// The size of the visible content (in diagram coordinates) // The size of the visible content (in diagram coordinates)
Bounds visibleBounds = layers.parentToLocal(viewerPane.getLayoutBounds()); Bounds visibleBounds = layers.parentToLocal(viewerPane.getLayoutBounds());
double visibleWidth = visibleBounds.getWidth();
double visibleHeight = visibleBounds.getHeight(); double visibleHeight = visibleBounds.getHeight();
verticalScrollbar.setMin(0); verticalScrollbar.setMin(0);
horizontalScrollbar.setMin(0);
verticalScrollbar.setMax(contentHeight); verticalScrollbar.setMax(contentHeight);
horizontalScrollbar.setMax(contentWidth);
Point2D o = layers.parentToLocal(0, 0);
verticalScrollbar.setValue(o.getY()); Point2D diagramTopLeft = layers.parentToLocal(0, 0);
verticalScrollbar.setValue(diagramTopLeft.getY());
// Including blank space to the bottom, the height of the horizontalScrollbar.setValue(diagramTopLeft.getX());
// content is (contentHeight + visibleHeight), of which
// visibleHeight is visible. Since the scrollbar // Including blank space to the bottom, the height of the content
// goes from 0 to contentHeight, this means we need: // is (contentHeight + visibleHeight), of which visibleHeight is
// contentHeight / visibleAmount == (contentHeight + visibleHeight) / visibleHeight // visible. Since the vertical scrollbar goes from 0 to contentHeight,
// TODO (SB): create local variable visibleAmount (and use it later for // this means we need:
// verticalScrollbar.setBlockIncrement) // contentHeight / verticalVisibleAmount
verticalScrollbar // == (contentHeight + visibleHeight) / visibleHeight
.setVisibleAmount(contentHeight * visibleHeight / (contentHeight + visibleHeight)); // Hence:
double verticalVisibleAmount =
contentHeight * visibleHeight / (contentHeight + visibleHeight);
double horizontalVisibleAmount =
contentWidth * visibleWidth / (contentWidth + visibleWidth);
verticalScrollbar.setVisibleAmount(verticalVisibleAmount);
horizontalScrollbar.setVisibleAmount(horizontalVisibleAmount);
verticalScrollbar.setUnitIncrement(1); verticalScrollbar.setUnitIncrement(1);
verticalScrollbar.setBlockIncrement(verticalScrollbar.getVisibleAmount());
}
/** Updates the horizontal scrollbar. */
private void updateHorizontalScrollbar() {
// The size of the content (in diagram coordinates)
Bounds contentBounds = layers.getBoundsInLocal();
double contentWidth = contentBounds.getWidth();
// The size of the visible content (in diagram coordinates)
Bounds visibleBounds = layers.parentToLocal(viewerPane.getLayoutBounds());
double visibleWidth = visibleBounds.getWidth();
horizontalScrollbar.setMin(0);
horizontalScrollbar.setMax(contentBounds.getWidth());
Point2D o = layers.parentToLocal(0, 0);
horizontalScrollbar.setValue(o.getX());
horizontalScrollbar
.setVisibleAmount(contentWidth * visibleWidth / (contentWidth + visibleWidth));
horizontalScrollbar.setUnitIncrement(1); horizontalScrollbar.setUnitIncrement(1);
verticalScrollbar.setBlockIncrement(verticalScrollbar.getVisibleAmount());
horizontalScrollbar.setBlockIncrement(horizontalScrollbar.getVisibleAmount()); horizontalScrollbar.setBlockIncrement(horizontalScrollbar.getVisibleAmount());
} }
...@@ -473,8 +464,7 @@ public class DiagramViewer { ...@@ -473,8 +464,7 @@ public class DiagramViewer {
void appendContentTransform(Transform t) { void appendContentTransform(Transform t) {
transform.append(t); transform.append(t);
enforceBounds(); enforceBounds();
updateHorizontalScrollbar(); updateScrollBars();
updateVerticalScrollbar();
viewerManager.gridCanvasVisual.updateNodes(layers); viewerManager.gridCanvasVisual.updateNodes(layers);
} }
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
package org.fortiss.tooling.common.ui.javafx.lwfxef; package org.fortiss.tooling.common.ui.javafx.lwfxef;
import static java.lang.Double.doubleToLongBits; import static java.lang.Double.doubleToLongBits;
import static java.lang.Math.abs;
import java.util.Objects; import java.util.Objects;
...@@ -144,12 +143,10 @@ final class GridCanvasVisual implements IVisual { ...@@ -144,12 +143,10 @@ final class GridCanvasVisual implements IVisual {
/** Returns the zoom factor from current content transformation. */ /** Returns the zoom factor from current content transformation. */
private double getZoomFactor() { private double getZoomFactor() {
Point2D p0 = viewer.getLayers().sceneToLocal(pane.localToScene(0, 0)); Point2D unitVector = new Point2D(1, 1);
Point2D p1 = viewer.getLayers().sceneToLocal(pane.localToScene(1, 1)); Point2D transformedVector =
viewer.getLayers().getLocalToParentTransform().deltaTransform(unitVector);
// TODO (SB): Add check against division by zero. (assert() if we are sure that it will not return transformedVector.getX();
// happen, otherwise maybe throw a RuntimeException)
return 1 / abs(p1.getX() - p0.getX());
} }
/** Structure to represent the current location of the grid. */ /** Structure to represent the current location of the grid. */
...@@ -190,7 +187,7 @@ final class GridCanvasVisual implements IVisual { ...@@ -190,7 +187,7 @@ final class GridCanvasVisual implements IVisual {
private double vSpacing; private double vSpacing;
/** Zoom factor. */ /** Zoom factor. */
private double zf; private double zoomFactor;
/** Grid indicator size. */ /** Grid indicator size. */
private double indicatorSize; private double indicatorSize;
...@@ -208,10 +205,14 @@ final class GridCanvasVisual implements IVisual { ...@@ -208,10 +205,14 @@ final class GridCanvasVisual implements IVisual {
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(backgroundColor, hSpacing, indicatorColor, indicatorSize, return Objects.hash(backgroundColor, hSpacing, indicatorColor, indicatorSize,
indicatorType, vSpacing, zf); indicatorType, vSpacing, zoomFactor);
} }
/** {@inheritDoc} */ /**
* Auto-generated (by Eclipse) deep equality method.
*
* {@inheritDoc}
*/
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if(this == obj) { if(this == obj) {
...@@ -225,16 +226,16 @@ final class GridCanvasVisual implements IVisual { ...@@ -225,16 +226,16 @@ final class GridCanvasVisual implements IVisual {
} }
GridParameters other = (GridParameters)obj; GridParameters other = (GridParameters)obj;
// TODO Add comment to explain the condition. In particular, the use of // Compare all member variables individually for equality.
// doubleToLongBits() is not obvious. Also, splitting the expression into several // The equality of doubles is tested using {@code doubleToLongBits},
// variables (with self-explanatory names) might improve understandability // as explained in {@link java.lang.Double#equals(Object)}.
return Objects.equals(backgroundColor, other.backgroundColor) && return Objects.equals(backgroundColor, other.backgroundColor) &&
doubleToLongBits(hSpacing) == doubleToLongBits(other.hSpacing) && doubleToLongBits(hSpacing) == doubleToLongBits(other.hSpacing) &&
Objects.equals(indicatorColor, other.indicatorColor) && Objects.equals(indicatorColor, other.indicatorColor) &&
doubleToLongBits(indicatorSize) == doubleToLongBits(other.indicatorSize) && doubleToLongBits(indicatorSize) == doubleToLongBits(other.indicatorSize) &&
indicatorType == other.indicatorType && indicatorType == other.indicatorType &&
doubleToLongBits(vSpacing) == doubleToLongBits(other.vSpacing) && doubleToLongBits(vSpacing) == doubleToLongBits(other.vSpacing) &&
abs(zf - other.zf) < 0.00001; doubleToLongBits(zoomFactor) == doubleToLongBits(other.zoomFactor);
} }
} }
...@@ -245,7 +246,7 @@ final class GridCanvasVisual implements IVisual { ...@@ -245,7 +246,7 @@ final class GridCanvasVisual implements IVisual {
GridParameters parameters = new GridParameters(); GridParameters parameters = new GridParameters();
parameters.hSpacing = features.getHorizontalSpacing(); parameters.hSpacing = features.getHorizontalSpacing();
parameters.vSpacing = features.getVerticalSpacing(); parameters.vSpacing = features.getVerticalSpacing();
parameters.zf = getZoomFactor(); parameters.zoomFactor = getZoomFactor();
parameters.indicatorType = features.getIndicatorType(); parameters.indicatorType = features.getIndicatorType();
parameters.backgroundColor = features.getBackgroundColor(); parameters.backgroundColor = features.getBackgroundColor();
parameters.indicatorColor = features.getIndicatorColor(); parameters.indicatorColor = features.getIndicatorColor();
...@@ -254,8 +255,8 @@ final class GridCanvasVisual implements IVisual { ...@@ -254,8 +255,8 @@ final class GridCanvasVisual implements IVisual {
paintCanvas(parameters); paintCanvas(parameters);
GridOffset gridOffset = getGridOffset(); GridOffset gridOffset = getGridOffset();
double zfhs = parameters.zf * parameters.hSpacing; double zfhs = parameters.zoomFactor * parameters.hSpacing;
double zfvs = parameters.zf * parameters.vSpacing; double zfvs = parameters.zoomFactor * parameters.vSpacing;
gridCanvas.relocate(-gridOffset.insets.getX() * zfhs, -gridOffset.insets.getY() * zfvs); gridCanvas.relocate(-gridOffset.insets.getX() * zfhs, -gridOffset.insets.getY() * zfvs);
pane.getChildren().removeAll(leftOuterBorder, topOuterBorder); pane.getChildren().removeAll(leftOuterBorder, topOuterBorder);
...@@ -280,8 +281,8 @@ final class GridCanvasVisual implements IVisual { ...@@ -280,8 +281,8 @@ final class GridCanvasVisual implements IVisual {
/** Draw gridCanvas with the given parameters. */ /** Draw gridCanvas with the given parameters. */
private void paintCanvas(GridParameters parameters) { private void paintCanvas(GridParameters parameters) {
double targetCanvasWidth = width + parameters.zf * parameters.hSpacing; double targetCanvasWidth = width + parameters.zoomFactor * parameters.hSpacing;
double targetCanvasHeight = height + parameters.zf * parameters.vSpacing; double targetCanvasHeight = height + parameters.zoomFactor * parameters.vSpacing;
boolean resized = false; boolean resized = false;
resized |= gridCanvas.getWidth() != targetCanvasWidth; resized |= gridCanvas.getWidth() != targetCanvasWidth;
...@@ -313,9 +314,9 @@ final class GridCanvasVisual implements IVisual { ...@@ -313,9 +314,9 @@ final class GridCanvasVisual implements IVisual {
// draw grid indicators // draw grid indicators
gc.setStroke(parameters.indicatorColor); gc.setStroke(parameters.indicatorColor);
gc.setFill(parameters.indicatorColor); gc.setFill(parameters.indicatorColor);
double zfhs = parameters.zf * parameters.hSpacing; double zfhs = parameters.zoomFactor * parameters.hSpacing;
double zfvs = parameters.zf * parameters.vSpacing; double zfvs = parameters.zoomFactor * parameters.vSpacing;
double isize = parameters.indicatorSize * parameters.zf; double isize = parameters.indicatorSize * parameters.zoomFactor;
for(double x = zfhs; x < gridCanvas.getWidth(); x += zfhs) { for(double x = zfhs; x < gridCanvas.getWidth(); x += zfhs) {
for(double y = zfvs; y < gridCanvas.getHeight(); y += zfvs) { for(double y = zfvs; y < gridCanvas.getHeight(); y += zfvs) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment