From 6ecebd9cf66636635691d21887f2db90f84047c1 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Tue, 7 Jul 2020 13:58:59 +0200 Subject: [PATCH] tx diagram to fixed size, coin control lock --- drongo | 2 +- .../sparrow/control/TransactionDiagram.java | 160 ++++++++++++------ .../com/sparrowwallet/sparrow/wallet/send.css | 5 +- .../sparrowwallet/sparrow/wallet/send.fxml | 140 +++++++-------- 4 files changed, 179 insertions(+), 128 deletions(-) diff --git a/drongo b/drongo index 5d14be5c..6135338d 160000 --- a/drongo +++ b/drongo @@ -1 +1 @@ -Subproject commit 5d14be5c9c8cfaaa0fbf9d362b6609873dce38e0 +Subproject commit 6135338df24589ce77584c57d470f2d8d44fa995 diff --git a/src/main/java/com/sparrowwallet/sparrow/control/TransactionDiagram.java b/src/main/java/com/sparrowwallet/sparrow/control/TransactionDiagram.java index fee6a1d1..2c4ecd77 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/TransactionDiagram.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/TransactionDiagram.java @@ -5,9 +5,6 @@ import com.sparrowwallet.drongo.wallet.BlockTransactionHashIndex; import com.sparrowwallet.drongo.wallet.WalletNode; import com.sparrowwallet.drongo.wallet.WalletTransaction; import com.sparrowwallet.sparrow.glyphfont.FontAwesome5; -import javafx.beans.property.DoubleProperty; -import javafx.beans.property.ReadOnlyDoubleProperty; -import javafx.beans.property.SimpleDoubleProperty; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Group; @@ -23,21 +20,11 @@ import org.controlsfx.glyphfont.Glyph; import java.util.*; public class TransactionDiagram extends GridPane { - private static final int MAX_UTXOS = 5; + private static final int MAX_UTXOS = 8; + private static final double DIAGRAM_HEIGHT = 230.0; private WalletTransaction walletTx; - public TransactionDiagram() { - int columns = 5; - double[] percentWidth = {20, 20, 10, 20, 30}; - - for(int i = 0; i < columns; i++) { - ColumnConstraints columnConstraints = new ColumnConstraints(); - columnConstraints.setPercentWidth(percentWidth[i]); - getColumnConstraints().add(columnConstraints); - } - } - public void update(WalletTransaction walletTx) { if(walletTx == null) { getChildren().clear(); @@ -50,23 +37,26 @@ public class TransactionDiagram extends GridPane { public void update() { Map displayedUtxos = getDisplayedUtxos(); - Pane inputsPane = getInputsLabels(displayedUtxos); - GridPane.setConstraints(inputsPane, 0, 0); + Pane inputsTypePane = getInputsType(displayedUtxos); + GridPane.setConstraints(inputsTypePane, 0, 0); - Pane inputsLinesPane = getInputsLines(displayedUtxos); - GridPane.setConstraints(inputsLinesPane, 1, 0); + Pane inputsPane = getInputsLabels(displayedUtxos); + GridPane.setConstraints(inputsPane, 1, 0); + + Node inputsLinesPane = getInputsLines(displayedUtxos); + GridPane.setConstraints(inputsLinesPane, 2, 0); Pane txPane = getTransactionPane(); - GridPane.setConstraints(txPane, 2, 0); + GridPane.setConstraints(txPane, 3, 0); Pane outputsLinesPane = getOutputsLines(); - GridPane.setConstraints(outputsLinesPane, 3, 0); + GridPane.setConstraints(outputsLinesPane, 4, 0); Pane outputsPane = getOutputsLabels(); - GridPane.setConstraints(outputsPane, 4, 0); + GridPane.setConstraints(outputsPane, 5, 0); getChildren().clear(); - getChildren().addAll(inputsPane, inputsLinesPane, txPane, outputsLinesPane, outputsPane); + getChildren().addAll(inputsTypePane, inputsPane, inputsLinesPane, txPane, outputsLinesPane, outputsPane); } private Map getDisplayedUtxos() { @@ -90,8 +80,64 @@ public class TransactionDiagram extends GridPane { } } + private Pane getInputsType(Map displayedUtxos) { + StackPane stackPane = new StackPane(); + + if(walletTx.isCoinControlUsed()) { + VBox pane = new VBox(); + double width = 22.0; + Group group = new Group(); + VBox.setVgrow(group, Priority.ALWAYS); + + Line widthLine = new Line(); + widthLine.setStartX(0); + widthLine.setEndX(width); + widthLine.getStyleClass().add("boundary"); + + Line topYaxis = new Line(); + topYaxis.setStartX(width * 0.5); + topYaxis.setStartY(DIAGRAM_HEIGHT * 0.5 - 20.0); + topYaxis.setEndX(width * 0.5); + topYaxis.setEndY(0); + topYaxis.getStyleClass().add("inputs-type"); + + Line topBracket = new Line(); + topBracket.setStartX(width * 0.5); + topBracket.setStartY(0); + topBracket.setEndX(width); + topBracket.setEndY(0); + topBracket.getStyleClass().add("inputs-type"); + + Line bottomYaxis = new Line(); + bottomYaxis.setStartX(width * 0.5); + bottomYaxis.setStartY(DIAGRAM_HEIGHT); + bottomYaxis.setEndX(width * 0.5); + bottomYaxis.setEndY(DIAGRAM_HEIGHT * 0.5 + 20.0); + bottomYaxis.getStyleClass().add("inputs-type"); + + Line bottomBracket = new Line(); + bottomBracket.setStartX(width * 0.5); + bottomBracket.setStartY(DIAGRAM_HEIGHT); + bottomBracket.setEndX(width); + bottomBracket.setEndY(DIAGRAM_HEIGHT); + bottomBracket.getStyleClass().add("inputs-type"); + + group.getChildren().addAll(widthLine, topYaxis, topBracket, bottomYaxis, bottomBracket); + pane.getChildren().add(group); + + Glyph lockGlyph = getLockGlyph(); + lockGlyph.getStyleClass().add("inputs-type"); + Tooltip tooltip = new Tooltip("Coin control active"); + lockGlyph.setTooltip(tooltip); + stackPane.getChildren().addAll(pane, lockGlyph); + } + + return stackPane; + } + private Pane getInputsLabels(Map displayedUtxos) { VBox inputsBox = new VBox(); + inputsBox.setMaxWidth(150); inputsBox.setPadding(new Insets(0, 10, 0, 10)); inputsBox.minHeightProperty().bind(minHeightProperty()); inputsBox.setAlignment(Pos.CENTER_RIGHT); @@ -144,24 +190,28 @@ public class TransactionDiagram extends GridPane { yaxisLine.setStartX(0); yaxisLine.setStartY(0); yaxisLine.setEndX(0); - yaxisLine.endYProperty().bind(this.heightProperty()); - yaxisLine.getStyleClass().add("y-axis"); + yaxisLine.setEndY(DIAGRAM_HEIGHT); + yaxisLine.getStyleClass().add("boundary"); group.getChildren().add(yaxisLine); + double width = 140.0; int numUtxos = displayedUtxos.size(); for(int i = 1; i <= numUtxos; i++) { CubicCurve curve = new CubicCurve(); curve.getStyleClass().add("input-line"); curve.setStartX(0); - curve.startYProperty().bind(getScaledProperty(this.heightProperty(), (double)i / (numUtxos + 1), 20)); - curve.endXProperty().bind(pane.widthProperty()); - curve.endYProperty().bind(getScaledProperty(this.heightProperty(), 0.5, 0)); + double scaleFactor = (double)i / (numUtxos + 1); + int nodeHeight = 17; + double additional = (0.5 - scaleFactor) * ((double)nodeHeight); + curve.setStartY(scale(DIAGRAM_HEIGHT, scaleFactor, additional)); + curve.setEndX(width); + curve.setEndY(scale(DIAGRAM_HEIGHT, 0.5, 0)); - curve.controlX1Property().bind(getScaledProperty(pane.widthProperty(), 0.2, 0)); - curve.controlY1Property().bind(curve.startYProperty()); - curve.controlX2Property().bind(getScaledProperty(pane.widthProperty(), 0.8, 0)); - curve.controlY2Property().bind(curve.endYProperty()); + curve.setControlX1(scale(width, 0.2, 0)); + curve.setControlY1(curve.getStartY()); + curve.setControlX2(scale(width, 0.8, 0)); + curve.setControlY2(curve.getEndY()); group.getChildren().add(curve); } @@ -170,22 +220,8 @@ public class TransactionDiagram extends GridPane { return pane; } - private static DoubleProperty getScaledProperty(ReadOnlyDoubleProperty property, double scaleFactor, int nodeHeight) { - SimpleDoubleProperty scaledProperty = new SimpleDoubleProperty(scale(property.doubleValue(), scaleFactor, nodeHeight)); - property.addListener((observable, oldValue, newValue) -> { - scaledProperty.set(scale(newValue.doubleValue(), scaleFactor, nodeHeight)); - }); - - return scaledProperty; - } - - private static double scale(Double value, double scaleFactor, int nodeHeight) { - double scaled = value * (1.0 - scaleFactor); - if(nodeHeight > 0) { - scaled += (0.5 - scaleFactor) * ( (double)nodeHeight ); - } - - return scaled; + private static double scale(Double value, double scaleFactor, double additional) { + return value * (1.0 - scaleFactor) + additional; } private Pane getOutputsLines() { @@ -198,22 +234,26 @@ public class TransactionDiagram extends GridPane { yaxisLine.setStartY(0); yaxisLine.setEndX(0); yaxisLine.endYProperty().bind(this.heightProperty()); - yaxisLine.getStyleClass().add("y-axis"); + yaxisLine.getStyleClass().add("boundary"); group.getChildren().add(yaxisLine); + double width = 140.0; int numOutputs = (walletTx.getChangeNode() == null ? 2 : 3); for(int i = 1; i <= numOutputs; i++) { CubicCurve curve = new CubicCurve(); curve.getStyleClass().add("output-line"); curve.setStartX(0); - curve.startYProperty().bind(getScaledProperty(this.heightProperty(), 0.5, 0)); - curve.endXProperty().bind(pane.widthProperty()); - curve.endYProperty().bind(getScaledProperty(this.heightProperty(), (double)i / (numOutputs + 1), 20)); + curve.setStartY(scale(DIAGRAM_HEIGHT, 0.5, 0)); + curve.setEndX(width); + double scaleFactor = (double)i / (numOutputs + 1); + int nodeHeight = 20; + double additional = (0.5 - scaleFactor) * ((double)nodeHeight); + curve.setEndY(scale(DIAGRAM_HEIGHT, scaleFactor, additional)); - curve.controlX1Property().bind(getScaledProperty(pane.widthProperty(), 0.2, 0)); + curve.setControlX1(scale(width, 0.2, 0)); curve.controlY1Property().bind(curve.startYProperty()); - curve.controlX2Property().bind(getScaledProperty(pane.widthProperty(), 0.8, 0)); + curve.setControlX2(scale(width, 0.8, 0)); curve.controlY2Property().bind(curve.endYProperty()); group.getChildren().add(curve); @@ -225,7 +265,8 @@ public class TransactionDiagram extends GridPane { private Pane getOutputsLabels() { VBox outputsBox = new VBox(); - outputsBox.setPadding(new Insets(0, 30, 0, 10)); + outputsBox.setMaxWidth(150); + outputsBox.setPadding(new Insets(0, 20, 0, 10)); outputsBox.setAlignment(Pos.CENTER_LEFT); outputsBox.getChildren().add(createSpacer()); @@ -248,7 +289,6 @@ public class TransactionDiagram extends GridPane { } boolean highFee = (walletTx.getFeePercentage() > 0.1); - String feeDesc = "Fee"; Label feeLabel = highFee ? new Label("High Fee", getWarningGlyph()) : new Label("Fee", getFeeGlyph()); feeLabel.getStyleClass().addAll("output-label", "fee-label"); String percentage = String.format("%.2f", walletTx.getFeePercentage() * 100.0); @@ -263,6 +303,7 @@ public class TransactionDiagram extends GridPane { private Pane getTransactionPane() { VBox txPane = new VBox(); + txPane.setPadding(new Insets(0, 10, 0, 10)); txPane.setAlignment(Pos.CENTER); txPane.getChildren().add(createSpacer()); @@ -310,6 +351,13 @@ public class TransactionDiagram extends GridPane { return feeWarningGlyph; } + private Glyph getLockGlyph() { + Glyph lockGlyph = new Glyph("Font Awesome 5 Free Solid", FontAwesome5.Glyph.LOCK); + lockGlyph.getStyleClass().add("lock-icon"); + lockGlyph.setFontSize(12); + return lockGlyph; + } + private static class AdditionalBlockTransactionHashIndex extends BlockTransactionHashIndex { private final List additionalInputs; diff --git a/src/main/resources/com/sparrowwallet/sparrow/wallet/send.css b/src/main/resources/com/sparrowwallet/sparrow/wallet/send.css index 50a06e84..a93c578c 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/wallet/send.css +++ b/src/main/resources/com/sparrowwallet/sparrow/wallet/send.css @@ -40,7 +40,7 @@ -fx-min-height: 230px; } -#transactionDiagram .y-axis { +#transactionDiagram .boundary { -fx-stroke: transparent; } @@ -52,8 +52,9 @@ -fx-text-fill: rgb(202, 18, 67); } -#transactionDiagram .input-line, #transactionDiagram .output-line { +#transactionDiagram .inputs-type, #transactionDiagram .input-line, #transactionDiagram .output-line { -fx-fill: transparent; + -fx-text-fill: #696c77; -fx-stroke: #696c77; -fx-stroke-width: 1px; } \ No newline at end of file diff --git a/src/main/resources/com/sparrowwallet/sparrow/wallet/send.fxml b/src/main/resources/com/sparrowwallet/sparrow/wallet/send.fxml index 7239f9b0..a5205ff2 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/wallet/send.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/wallet/send.fxml @@ -22,76 +22,78 @@
- - - - - - - - - - - - -
-
- - - - - - - - - - - - - - - - - -
-
-
-
- - - - - - - - - - - - - - - - - -
-
- - - - - - - - - + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + +
+ + - - - -
+