mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-24 12:46:45 +00:00
tx diagram to fixed size, coin control lock
This commit is contained in:
parent
c8e38de5aa
commit
6ecebd9cf6
4 changed files with 179 additions and 128 deletions
2
drongo
2
drongo
|
@ -1 +1 @@
|
|||
Subproject commit 5d14be5c9c8cfaaa0fbf9d362b6609873dce38e0
|
||||
Subproject commit 6135338df24589ce77584c57d470f2d8d44fa995
|
|
@ -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<BlockTransactionHashIndex, WalletNode> 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<BlockTransactionHashIndex, WalletNode> getDisplayedUtxos() {
|
||||
|
@ -90,8 +80,64 @@ public class TransactionDiagram extends GridPane {
|
|||
}
|
||||
}
|
||||
|
||||
private Pane getInputsType(Map<BlockTransactionHashIndex, WalletNode> 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<BlockTransactionHashIndex, WalletNode> 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<BlockTransactionHashIndex> additionalInputs;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
<BorderPane stylesheets="@send.css, @wallet.css, @../script.css, @../general.css" styleClass="wallet-pane" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.sparrowwallet.sparrow.wallet.SendController">
|
||||
<center>
|
||||
<VBox>
|
||||
<GridPane styleClass="send-form" hgap="10.0" vgap="10.0">
|
||||
<padding>
|
||||
<Insets left="25.0" right="25.0" top="25.0" />
|
||||
|
@ -88,10 +89,11 @@
|
|||
</yAxis>
|
||||
</FeeRatesChart>
|
||||
</AnchorPane>
|
||||
<StackPane GridPane.columnIndex="0" GridPane.rowIndex="2" GridPane.columnSpan="3">
|
||||
<TransactionDiagram fx:id="transactionDiagram" />
|
||||
</StackPane>
|
||||
</GridPane>
|
||||
<AnchorPane>
|
||||
<TransactionDiagram fx:id="transactionDiagram" maxWidth="700" maxHeight="230" AnchorPane.rightAnchor="100" />
|
||||
</AnchorPane>
|
||||
</VBox>
|
||||
</center>
|
||||
<bottom>
|
||||
<AnchorPane>
|
||||
|
|
Loading…
Reference in a new issue