expand transaction diagram in popup on click

This commit is contained in:
Craig Raw 2022-02-02 16:03:08 +02:00
parent 9bf53ab0cd
commit ca928fc136
22 changed files with 329 additions and 47 deletions

View file

@ -424,7 +424,9 @@ public class AppController implements Initializable {
Stage stage = new Stage(); Stage stage = new Stage();
stage.setTitle("About " + MainApp.APP_NAME); stage.setTitle("About " + MainApp.APP_NAME);
stage.initStyle(org.controlsfx.tools.Platform.getCurrent() == org.controlsfx.tools.Platform.OSX ? StageStyle.UNDECORATED : StageStyle.DECORATED); stage.initStyle(StageStyle.UNDECORATED);
stage.initOwner(tabs.getScene().getWindow());
stage.initModality(Modality.WINDOW_MODAL);
stage.setResizable(false); stage.setResizable(false);
Scene scene = new Scene(root); Scene scene = new Scene(root);
AppServices.onEscapePressed(scene, stage::close); AppServices.onEscapePressed(scene, stage::close);

View file

@ -6,6 +6,7 @@ import com.sparrowwallet.sparrow.io.Config;
import javafx.beans.property.LongProperty; import javafx.beans.property.LongProperty;
import javafx.beans.property.SimpleLongProperty; import javafx.beans.property.SimpleLongProperty;
import javafx.scene.control.ContextMenu; import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem; import javafx.scene.control.MenuItem;
import javafx.scene.control.Tooltip; import javafx.scene.control.Tooltip;
import javafx.scene.input.Clipboard; import javafx.scene.input.Clipboard;
@ -15,7 +16,7 @@ import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols; import java.text.DecimalFormatSymbols;
import java.util.Locale; import java.util.Locale;
public class CoinLabel extends CopyableLabel { public class CoinLabel extends Label {
public static final DecimalFormat BTC_FORMAT = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH)); public static final DecimalFormat BTC_FORMAT = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
private final LongProperty valueProperty = new SimpleLongProperty(-1); private final LongProperty valueProperty = new SimpleLongProperty(-1);
@ -28,7 +29,6 @@ public class CoinLabel extends CopyableLabel {
public CoinLabel(String text) { public CoinLabel(String text) {
super(text); super(text);
BTC_FORMAT.setMaximumFractionDigits(8);
valueProperty().addListener((observable, oldValue, newValue) -> setValueAsText((Long)newValue, Config.get().getBitcoinUnit())); valueProperty().addListener((observable, oldValue, newValue) -> setValueAsText((Long)newValue, Config.get().getBitcoinUnit()));
tooltip = new Tooltip(); tooltip = new Tooltip();
contextMenu = new CoinContextMenu(); contextMenu = new CoinContextMenu();
@ -77,7 +77,7 @@ public class CoinLabel extends CopyableLabel {
private class CoinContextMenu extends ContextMenu { private class CoinContextMenu extends ContextMenu {
public CoinContextMenu() { public CoinContextMenu() {
MenuItem copySatsValue = new MenuItem("Copy Value in Satoshis"); MenuItem copySatsValue = new MenuItem("Copy Value in sats");
copySatsValue.setOnAction(AE -> { copySatsValue.setOnAction(AE -> {
hide(); hide();
ClipboardContent content = new ClipboardContent(); ClipboardContent content = new ClipboardContent();

View file

@ -0,0 +1,94 @@
package com.sparrowwallet.sparrow.control;
import com.sparrowwallet.drongo.BitcoinUnit;
import com.sparrowwallet.drongo.protocol.Transaction;
import com.sparrowwallet.sparrow.io.Config;
import javafx.beans.property.LongProperty;
import javafx.beans.property.SimpleLongProperty;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.Tooltip;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import java.util.Locale;
public class CopyableCoinLabel extends CopyableLabel {
private final LongProperty valueProperty = new SimpleLongProperty(-1);
private final Tooltip tooltip;
private final CoinContextMenu contextMenu;
public CopyableCoinLabel() {
this("Unknown");
}
public CopyableCoinLabel(String text) {
super(text);
valueProperty().addListener((observable, oldValue, newValue) -> setValueAsText((Long)newValue, Config.get().getBitcoinUnit()));
tooltip = new Tooltip();
contextMenu = new CoinContextMenu();
}
public final LongProperty valueProperty() {
return valueProperty;
}
public final long getValue() {
return valueProperty.get();
}
public final void setValue(long value) {
this.valueProperty.set(value);
}
public void refresh() {
refresh(Config.get().getBitcoinUnit());
}
public void refresh(BitcoinUnit bitcoinUnit) {
setValueAsText(getValue(), bitcoinUnit);
}
private void setValueAsText(Long value, BitcoinUnit bitcoinUnit) {
setTooltip(tooltip);
setContextMenu(contextMenu);
String satsValue = String.format(Locale.ENGLISH, "%,d", value) + " sats";
String btcValue = CoinLabel.getBTCFormat().format(value.doubleValue() / Transaction.SATOSHIS_PER_BITCOIN) + " BTC";
BitcoinUnit unit = bitcoinUnit;
if(unit == null || unit.equals(BitcoinUnit.AUTO)) {
unit = (value >= BitcoinUnit.getAutoThreshold() ? BitcoinUnit.BTC : BitcoinUnit.SATOSHIS);
}
if(unit.equals(BitcoinUnit.BTC)) {
tooltip.setText(satsValue);
setText(btcValue);
} else {
tooltip.setText(btcValue);
setText(satsValue);
}
}
private class CoinContextMenu extends ContextMenu {
public CoinContextMenu() {
MenuItem copySatsValue = new MenuItem("Copy Value in sats");
copySatsValue.setOnAction(AE -> {
hide();
ClipboardContent content = new ClipboardContent();
content.putString(Long.toString(getValue()));
Clipboard.getSystemClipboard().setContent(content);
});
MenuItem copyBtcValue = new MenuItem("Copy Value in BTC");
copyBtcValue.setOnAction(AE -> {
hide();
ClipboardContent content = new ClipboardContent();
content.putString(CoinLabel.getBTCFormat().format((double)getValue() / Transaction.SATOSHIS_PER_BITCOIN));
Clipboard.getSystemClipboard().setContent(content);
});
getItems().addAll(copySatsValue, copyBtcValue);
}
}
}

View file

@ -34,4 +34,18 @@ public class TextUtils {
helper.setText(DEFAULT_TEXT); helper.setText(DEFAULT_TEXT);
return d; return d;
} }
public static double computeTextHeight(Font font, String text) {
helper.setText(text);
helper.setFont(font);
helper.setWrappingWidth(0.0D);
helper.setLineSpacing(0.0D);
double d = Math.ceil(helper.getLayoutBounds().getHeight());
helper.setWrappingWidth(DEFAULT_WRAPPING_WIDTH);
helper.setLineSpacing(DEFAULT_LINE_SPACING);
helper.setText(DEFAULT_TEXT);
return d;
}
} }

View file

@ -18,18 +18,24 @@ import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import javafx.event.EventHandler;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.Group; import javafx.scene.Group;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay; import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.Tooltip; import javafx.scene.control.Tooltip;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*; import javafx.scene.layout.*;
import javafx.scene.shape.Circle; import javafx.scene.shape.Circle;
import javafx.scene.shape.CubicCurve; import javafx.scene.shape.CubicCurve;
import javafx.scene.shape.Line; import javafx.scene.shape.Line;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.util.Duration; import javafx.util.Duration;
import org.controlsfx.glyphfont.FontAwesome; import org.controlsfx.glyphfont.FontAwesome;
import org.controlsfx.glyphfont.Glyph; import org.controlsfx.glyphfont.Glyph;
@ -40,16 +46,68 @@ import java.util.stream.Collectors;
public class TransactionDiagram extends GridPane { public class TransactionDiagram extends GridPane {
private static final int MAX_UTXOS = 8; private static final int MAX_UTXOS = 8;
private static final int REDUCED_MAX_UTXOS = MAX_UTXOS - 2; private static final int REDUCED_MAX_UTXOS = MAX_UTXOS - 2;
private static final int EXPANDED_MAX_UTXOS = 20;
private static final int MAX_PAYMENTS = 6; private static final int MAX_PAYMENTS = 6;
private static final int REDUCED_MAX_PAYMENTS = MAX_PAYMENTS - 2; private static final int REDUCED_MAX_PAYMENTS = MAX_PAYMENTS - 2;
private static final int EXPANDED_MAX_PAYMENTS = 18;
private static final double DIAGRAM_HEIGHT = 210.0; private static final double DIAGRAM_HEIGHT = 210.0;
private static final double REDUCED_DIAGRAM_HEIGHT = DIAGRAM_HEIGHT - 60; private static final double REDUCED_DIAGRAM_HEIGHT = DIAGRAM_HEIGHT - 60;
private static final double EXPANDED_DIAGRAM_HEIGHT = 500;
private static final int TOOLTIP_SHOW_DELAY = 50; private static final int TOOLTIP_SHOW_DELAY = 50;
private static final int RELATIVE_SIZE_MAX_RADIUS = 7; private static final int RELATIVE_SIZE_MAX_RADIUS = 7;
private static final int ROW_HEIGHT = 27;
private WalletTransaction walletTx; private WalletTransaction walletTx;
private final BooleanProperty finalProperty = new SimpleBooleanProperty(false); private final BooleanProperty finalProperty = new SimpleBooleanProperty(false);
private final ObjectProperty<OptimizationStrategy> optimizationStrategyProperty = new SimpleObjectProperty<>(OptimizationStrategy.EFFICIENCY); private final ObjectProperty<OptimizationStrategy> optimizationStrategyProperty = new SimpleObjectProperty<>(OptimizationStrategy.EFFICIENCY);
private boolean expanded;
private TransactionDiagram expandedDiagram;
private final EventHandler<MouseEvent> expandedDiagramHandler = new EventHandler<>() {
@Override
public void handle(MouseEvent event) {
if(!event.isConsumed()) {
Stage stage = new Stage();
stage.setTitle(walletTx.getPayments().iterator().next().getLabel());
stage.initStyle(StageStyle.UNDECORATED);
stage.initOwner(TransactionDiagram.this.getScene().getWindow());
stage.initModality(Modality.WINDOW_MODAL);
stage.setResizable(false);
VBox vBox = new VBox(20);
vBox.getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm());
vBox.getStylesheets().add(AppServices.class.getResource("wallet/wallet.css").toExternalForm());
vBox.getStylesheets().add(AppServices.class.getResource("wallet/send.css").toExternalForm());
vBox.setPadding(new Insets(20, 40, 20, 50));
expandedDiagram = new TransactionDiagram();
expandedDiagram.setId("transactionDiagram");
expandedDiagram.setExpanded(true);
updateExpandedDiagram();
HBox buttonBox = new HBox();
buttonBox.setAlignment(Pos.CENTER_RIGHT);
Button button = new Button("Close");
button.setOnAction(e -> {
stage.close();
});
buttonBox.getChildren().add(button);
vBox.getChildren().addAll(expandedDiagram, buttonBox);
Scene scene = new Scene(vBox);
AppServices.onEscapePressed(scene, stage::close);
AppServices.setStageIcon(stage);
stage.setScene(scene);
stage.setOnShowing(e -> {
AppServices.moveToActiveWindowScreen(stage, 600, 460);
});
stage.setOnHidden(e -> {
expandedDiagram = null;
});
stage.show();
}
}
};
public void update(WalletTransaction walletTx) { public void update(WalletTransaction walletTx) {
setMinHeight(getDiagramHeight()); setMinHeight(getDiagramHeight());
@ -60,6 +118,10 @@ public class TransactionDiagram extends GridPane {
} else { } else {
this.walletTx = walletTx; this.walletTx = walletTx;
update(); update();
setOnMouseClicked(expandedDiagramHandler);
if(expandedDiagram != null) {
updateExpandedDiagram();
}
} }
} }
@ -87,6 +149,24 @@ public class TransactionDiagram extends GridPane {
getChildren().clear(); getChildren().clear();
} }
private void updateExpandedDiagram() {
expandedDiagram.setFinal(isFinal());
expandedDiagram.setOptimizationStrategy(getOptimizationStrategy());
expandedDiagram.walletTx = walletTx;
List<Map<BlockTransactionHashIndex, WalletNode>> utxoSets = expandedDiagram.getDisplayedUtxoSets();
int maxSetSize = utxoSets.stream().mapToInt(Map::size).max().orElse(0);
int maxRows = Math.max(maxSetSize * utxoSets.size(), walletTx.getPayments().size() + 2);
double diagramHeight = Math.max(DIAGRAM_HEIGHT, Math.min(EXPANDED_DIAGRAM_HEIGHT, maxRows * ROW_HEIGHT));
expandedDiagram.setMinHeight(diagramHeight);
expandedDiagram.setMaxHeight(diagramHeight);
expandedDiagram.update();
if(expandedDiagram.getScene() != null && expandedDiagram.getScene().getWindow() instanceof Stage stage) {
stage.sizeToScene();
}
}
public void update() { public void update() {
List<Map<BlockTransactionHashIndex, WalletNode>> displayedUtxoSets = getDisplayedUtxoSets(); List<Map<BlockTransactionHashIndex, WalletNode>> displayedUtxoSets = getDisplayedUtxoSets();
@ -287,17 +367,19 @@ public class TransactionDiagram extends GridPane {
private Pane getInputsLabels(List<Map<BlockTransactionHashIndex, WalletNode>> displayedUtxoSets) { private Pane getInputsLabels(List<Map<BlockTransactionHashIndex, WalletNode>> displayedUtxoSets) {
VBox inputsBox = new VBox(); VBox inputsBox = new VBox();
inputsBox.setMaxWidth(150); inputsBox.setMaxWidth(isExpanded() ? 300 : 150);
inputsBox.setPrefWidth(150); inputsBox.setPrefWidth(isExpanded() ? 230 : 150);
inputsBox.setPadding(new Insets(0, 10, 0, 10)); inputsBox.setPadding(new Insets(0, 10, 0, 10));
inputsBox.minHeightProperty().bind(minHeightProperty()); inputsBox.minHeightProperty().bind(minHeightProperty());
inputsBox.setAlignment(Pos.CENTER_RIGHT); inputsBox.setAlignment(Pos.CENTER_RIGHT);
inputsBox.getChildren().add(createSpacer()); inputsBox.getChildren().add(createSpacer());
double labelHeight = TextUtils.computeTextHeight(AppServices.getMonospaceFont(), "0") + 1;
for(Map<BlockTransactionHashIndex, WalletNode> displayedUtxos : displayedUtxoSets) { for(Map<BlockTransactionHashIndex, WalletNode> displayedUtxos : displayedUtxoSets) {
for(BlockTransactionHashIndex input : displayedUtxos.keySet()) { for(BlockTransactionHashIndex input : displayedUtxos.keySet()) {
WalletNode walletNode = displayedUtxos.get(input); WalletNode walletNode = displayedUtxos.get(input);
String desc = getInputDescription(input); String desc = getInputDescription(input);
Label label = new Label(desc); Label label = new Label(desc);
label.setPrefHeight(labelHeight);
label.getStyleClass().add("utxo-label"); label.getStyleClass().add("utxo-label");
Button excludeUtxoButton = new Button(""); Button excludeUtxoButton = new Button("");
@ -307,8 +389,10 @@ public class TransactionDiagram extends GridPane {
}); });
Tooltip tooltip = new Tooltip(); Tooltip tooltip = new Tooltip();
Long inputValue = null;
if(walletNode != null) { if(walletNode != null) {
tooltip.setText("Spending " + getSatsValue(input.getValue()) + " sats from " + (isFinal() ? walletTx.getWallet().getFullDisplayName() : "") + " " + walletNode + "\n" + input.getHashAsString() + ":" + input.getIndex() + "\n" + walletTx.getWallet().getAddress(walletNode)); inputValue = input.getValue();
tooltip.setText("Spending " + getSatsValue(inputValue) + " sats from " + (isFinal() ? walletTx.getWallet().getFullDisplayName() : "") + " " + walletNode + "\n" + input.getHashAsString() + ":" + input.getIndex() + "\n" + walletTx.getWallet().getAddress(walletNode));
tooltip.getStyleClass().add("input-label"); tooltip.getStyleClass().add("input-label");
if(input.getLabel() == null || input.getLabel().isEmpty()) { if(input.getLabel() == null || input.getLabel().isEmpty()) {
@ -335,13 +419,16 @@ public class TransactionDiagram extends GridPane {
label.setGraphic(walletTx.isTwoPersonCoinjoin() ? getQuestionGlyph() : getWarningGlyph()); label.setGraphic(walletTx.isTwoPersonCoinjoin() ? getQuestionGlyph() : getWarningGlyph());
label.setOnMouseClicked(event -> { label.setOnMouseClicked(event -> {
EventManager.get().post(new SorobanInitiatedEvent(walletTx.getWallet())); EventManager.get().post(new SorobanInitiatedEvent(walletTx.getWallet()));
closeExpanded();
event.consume();
}); });
} else { } else {
if(walletTx.getInputTransactions() != null && walletTx.getInputTransactions().get(input.getHash()) != null) { if(walletTx.getInputTransactions() != null && walletTx.getInputTransactions().get(input.getHash()) != null) {
BlockTransaction blockTransaction = walletTx.getInputTransactions().get(input.getHash()); BlockTransaction blockTransaction = walletTx.getInputTransactions().get(input.getHash());
TransactionOutput txOutput = blockTransaction.getTransaction().getOutputs().get((int) input.getIndex()); TransactionOutput txOutput = blockTransaction.getTransaction().getOutputs().get((int) input.getIndex());
Address fromAddress = txOutput.getScript().getToAddress(); Address fromAddress = txOutput.getScript().getToAddress();
tooltip.setText("Input of " + getSatsValue(txOutput.getValue()) + " sats\n" + input.getHashAsString() + ":" + input.getIndex() + (fromAddress != null ? "\n" + fromAddress : "")); inputValue = txOutput.getValue();
tooltip.setText("Input of " + getSatsValue(inputValue) + " sats\n" + input.getHashAsString() + ":" + input.getIndex() + (fromAddress != null ? "\n" + fromAddress : ""));
} else { } else {
tooltip.setText(input.getHashAsString() + ":" + input.getIndex()); tooltip.setText(input.getHashAsString() + ":" + input.getIndex());
} }
@ -355,7 +442,21 @@ public class TransactionDiagram extends GridPane {
label.setTooltip(tooltip); label.setTooltip(tooltip);
} }
inputsBox.getChildren().add(label); HBox inputBox = new HBox();
inputBox.setAlignment(Pos.CENTER_RIGHT);
inputBox.getChildren().add(label);
if(isExpanded() && inputValue != null) {
label.setMinWidth(120);
Region region = new Region();
HBox.setHgrow(region, Priority.ALWAYS);
CoinLabel amountLabel = new CoinLabel();
amountLabel.setValue(inputValue);
amountLabel.setMinWidth(TextUtils.computeTextWidth(amountLabel.getFont(), amountLabel.getText(), 0.0D) + 2);
inputBox.getChildren().addAll(region, amountLabel);
}
inputsBox.getChildren().add(inputBox);
inputsBox.getChildren().add(createSpacer()); inputsBox.getChildren().add(createSpacer());
} }
} }
@ -505,7 +606,8 @@ public class TransactionDiagram extends GridPane {
private Pane getOutputsLabels(List<Payment> displayedPayments) { private Pane getOutputsLabels(List<Payment> displayedPayments) {
VBox outputsBox = new VBox(); VBox outputsBox = new VBox();
outputsBox.setMaxWidth(150); outputsBox.setMaxWidth(isExpanded() ? 350 : 150);
outputsBox.setPrefWidth(isExpanded() ? 230 : 150);
outputsBox.setPadding(new Insets(0, 20, 0, 10)); outputsBox.setPadding(new Insets(0, 20, 0, 10));
outputsBox.setAlignment(Pos.CENTER_LEFT); outputsBox.setAlignment(Pos.CENTER_LEFT);
outputsBox.getChildren().add(createSpacer()); outputsBox.getChildren().add(createSpacer());
@ -527,7 +629,20 @@ public class TransactionDiagram extends GridPane {
recipientTooltip.setShowDelay(new Duration(TOOLTIP_SHOW_DELAY)); recipientTooltip.setShowDelay(new Duration(TOOLTIP_SHOW_DELAY));
recipientTooltip.setShowDuration(Duration.INDEFINITE); recipientTooltip.setShowDuration(Duration.INDEFINITE);
recipientLabel.setTooltip(recipientTooltip); recipientLabel.setTooltip(recipientTooltip);
outputNodes.add(new OutputNode(recipientLabel, payment.getAddress(), payment.getAmount())); HBox paymentBox = new HBox();
paymentBox.setAlignment(Pos.CENTER_LEFT);
paymentBox.getChildren().add(recipientLabel);
if(isExpanded()) {
Region region = new Region();
region.setMinWidth(20);
HBox.setHgrow(region, Priority.ALWAYS);
CoinLabel amountLabel = new CoinLabel();
amountLabel.setValue(payment.getAmount());
amountLabel.setMinWidth(TextUtils.computeTextWidth(amountLabel.getFont(), amountLabel.getText(), 0.0D) + 2);
paymentBox.getChildren().addAll(region, amountLabel);
}
outputNodes.add(new OutputNode(paymentBox, payment.getAddress(), payment.getAmount()));
} }
for(Map.Entry<WalletNode, Long> changeEntry : walletTx.getChangeMap().entrySet()) { for(Map.Entry<WalletNode, Long> changeEntry : walletTx.getChangeMap().entrySet()) {
@ -536,6 +651,7 @@ public class TransactionDiagram extends GridPane {
boolean overGapLimit = (changeNode.getIndex() - defaultChangeNode.getIndex()) > walletTx.getWallet().getGapLimit(); boolean overGapLimit = (changeNode.getIndex() - defaultChangeNode.getIndex()) > walletTx.getWallet().getGapLimit();
HBox actionBox = new HBox(); HBox actionBox = new HBox();
actionBox.setAlignment(Pos.CENTER_LEFT);
Address changeAddress = walletTx.getChangeAddress(changeNode); Address changeAddress = walletTx.getChangeAddress(changeNode);
String changeDesc = changeAddress.toString().substring(0, 8) + "..."; String changeDesc = changeAddress.toString().substring(0, 8) + "...";
Label changeLabel = new Label(changeDesc, overGapLimit ? getChangeWarningGlyph() : getChangeGlyph()); Label changeLabel = new Label(changeDesc, overGapLimit ? getChangeWarningGlyph() : getChangeGlyph());
@ -563,6 +679,17 @@ public class TransactionDiagram extends GridPane {
actionBox.getChildren().add(replaceChangeLabel); actionBox.getChildren().add(replaceChangeLabel);
} }
if(isExpanded()) {
changeLabel.setMinWidth(120);
Region region = new Region();
region.setMinWidth(20);
HBox.setHgrow(region, Priority.ALWAYS);
CoinLabel amountLabel = new CoinLabel();
amountLabel.setValue(changeEntry.getValue());
amountLabel.setMinWidth(TextUtils.computeTextWidth(amountLabel.getFont(), amountLabel.getText(), 0.0D) + 2);
actionBox.getChildren().addAll(region, amountLabel);
}
outputNodes.add(new OutputNode(actionBox, changeAddress, changeEntry.getValue())); outputNodes.add(new OutputNode(actionBox, changeAddress, changeEntry.getValue()));
} }
@ -584,7 +711,21 @@ public class TransactionDiagram extends GridPane {
feeTooltip.setShowDelay(new Duration(TOOLTIP_SHOW_DELAY)); feeTooltip.setShowDelay(new Duration(TOOLTIP_SHOW_DELAY));
feeTooltip.setShowDuration(Duration.INDEFINITE); feeTooltip.setShowDuration(Duration.INDEFINITE);
feeLabel.setTooltip(feeTooltip); feeLabel.setTooltip(feeTooltip);
outputsBox.getChildren().add(feeLabel);
HBox feeBox = new HBox();
feeBox.setAlignment(Pos.CENTER_LEFT);
feeBox.getChildren().add(feeLabel);
if(isExpanded()) {
Region region = new Region();
region.setMinWidth(20);
HBox.setHgrow(region, Priority.ALWAYS);
CoinLabel amountLabel = new CoinLabel();
amountLabel.setValue(walletTx.getFee());
amountLabel.setMinWidth(TextUtils.computeTextWidth(amountLabel.getFont(), amountLabel.getText(), 0.0D) + 2);
feeBox.getChildren().addAll(region, amountLabel);
}
outputsBox.getChildren().add(feeBox);
outputsBox.getChildren().add(createSpacer()); outputsBox.getChildren().add(createSpacer());
return outputsBox; return outputsBox;
@ -613,6 +754,10 @@ public class TransactionDiagram extends GridPane {
} }
public double getDiagramHeight() { public double getDiagramHeight() {
if(isExpanded()) {
return getMaxHeight();
}
if(isReducedHeight()) { if(isReducedHeight()) {
return REDUCED_DIAGRAM_HEIGHT; return REDUCED_DIAGRAM_HEIGHT;
} }
@ -621,6 +766,10 @@ public class TransactionDiagram extends GridPane {
} }
private int getMaxUtxos() { private int getMaxUtxos() {
if(isExpanded()) {
return EXPANDED_MAX_UTXOS;
}
if(isReducedHeight()) { if(isReducedHeight()) {
return REDUCED_MAX_UTXOS; return REDUCED_MAX_UTXOS;
} }
@ -629,6 +778,10 @@ public class TransactionDiagram extends GridPane {
} }
private int getMaxPayments() { private int getMaxPayments() {
if(isExpanded()) {
return EXPANDED_MAX_PAYMENTS;
}
if(isReducedHeight()) { if(isReducedHeight()) {
return REDUCED_MAX_PAYMENTS; return REDUCED_MAX_PAYMENTS;
} }
@ -834,6 +987,8 @@ public class TransactionDiagram extends GridPane {
}); });
userAddGlyph.setOnMouseClicked(event -> { userAddGlyph.setOnMouseClicked(event -> {
EventManager.get().post(new SorobanInitiatedEvent(walletTx.getWallet())); EventManager.get().post(new SorobanInitiatedEvent(walletTx.getWallet()));
closeExpanded();
event.consume();
}); });
return userAddGlyph; return userAddGlyph;
} }
@ -853,6 +1008,8 @@ public class TransactionDiagram extends GridPane {
}); });
coinsGlyph.setOnMouseClicked(event -> { coinsGlyph.setOnMouseClicked(event -> {
EventManager.get().post(new SorobanInitiatedEvent(walletTx.getWallet())); EventManager.get().post(new SorobanInitiatedEvent(walletTx.getWallet()));
closeExpanded();
event.consume();
}); });
} else { } else {
coinsGlyph.getStyleClass().add("coins-icon"); coinsGlyph.getStyleClass().add("coins-icon");
@ -861,6 +1018,12 @@ public class TransactionDiagram extends GridPane {
return coinsGlyph; return coinsGlyph;
} }
private void closeExpanded() {
if(isExpanded() && this.getScene() != null && this.getScene().getWindow() instanceof Stage stage) {
stage.close();
}
}
public boolean isFinal() { public boolean isFinal() {
return finalProperty.get(); return finalProperty.get();
} }
@ -885,6 +1048,14 @@ public class TransactionDiagram extends GridPane {
this.optimizationStrategyProperty.set(optimizationStrategy); this.optimizationStrategyProperty.set(optimizationStrategy);
} }
public boolean isExpanded() {
return expanded;
}
public void setExpanded(boolean expanded) {
this.expanded = expanded;
}
private static class PayjoinBlockTransactionHashIndex extends BlockTransactionHashIndex { private static class PayjoinBlockTransactionHashIndex extends BlockTransactionHashIndex {
public PayjoinBlockTransactionHashIndex() { public PayjoinBlockTransactionHashIndex() {
super(Sha256Hash.ZERO_HASH, 0, new Date(), 0L, 0, 0); super(Sha256Hash.ZERO_HASH, 0, new Date(), 0L, 0, 0);

View file

@ -132,7 +132,7 @@ public class HeadersController extends TransactionFormController implements Init
private CopyableLabel virtualSize; private CopyableLabel virtualSize;
@FXML @FXML
private CoinLabel fee; private CopyableCoinLabel fee;
@FXML @FXML
private CopyableLabel feeRate; private CopyableLabel feeRate;

View file

@ -44,7 +44,7 @@ public class InputController extends TransactionFormController implements Initia
private Hyperlink linkedOutpoint; private Hyperlink linkedOutpoint;
@FXML @FXML
private CoinLabel spends; private CopyableCoinLabel spends;
@FXML @FXML
private CopyableLabel from; private CopyableLabel from;

View file

@ -7,7 +7,7 @@ import com.sparrowwallet.drongo.psbt.PSBTInput;
import com.sparrowwallet.drongo.wallet.BlockTransaction; import com.sparrowwallet.drongo.wallet.BlockTransaction;
import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.Keystore;
import com.sparrowwallet.sparrow.EventManager; import com.sparrowwallet.sparrow.EventManager;
import com.sparrowwallet.sparrow.control.CoinLabel; import com.sparrowwallet.sparrow.control.CopyableCoinLabel;
import com.sparrowwallet.sparrow.control.CopyableLabel; import com.sparrowwallet.sparrow.control.CopyableLabel;
import com.sparrowwallet.sparrow.event.BitcoinUnitChangedEvent; import com.sparrowwallet.sparrow.event.BitcoinUnitChangedEvent;
import com.sparrowwallet.sparrow.event.BlockTransactionFetchedEvent; import com.sparrowwallet.sparrow.event.BlockTransactionFetchedEvent;
@ -31,7 +31,7 @@ public class InputsController extends TransactionFormController implements Initi
private CopyableLabel count; private CopyableLabel count;
@FXML @FXML
private CoinLabel total; private CopyableCoinLabel total;
@FXML @FXML
private CopyableLabel signatures; private CopyableLabel signatures;

View file

@ -31,7 +31,7 @@ public class OutputController extends TransactionFormController implements Initi
private Fieldset outputFieldset; private Fieldset outputFieldset;
@FXML @FXML
private CoinLabel value; private CopyableCoinLabel value;
@FXML @FXML
private CopyableLabel to; private CopyableLabel to;

View file

@ -4,7 +4,7 @@ import com.google.common.eventbus.Subscribe;
import com.sparrowwallet.drongo.protocol.Transaction; import com.sparrowwallet.drongo.protocol.Transaction;
import com.sparrowwallet.drongo.protocol.TransactionOutput; import com.sparrowwallet.drongo.protocol.TransactionOutput;
import com.sparrowwallet.sparrow.EventManager; import com.sparrowwallet.sparrow.EventManager;
import com.sparrowwallet.sparrow.control.CoinLabel; import com.sparrowwallet.sparrow.control.CopyableCoinLabel;
import com.sparrowwallet.sparrow.control.CopyableLabel; import com.sparrowwallet.sparrow.control.CopyableLabel;
import com.sparrowwallet.sparrow.event.BitcoinUnitChangedEvent; import com.sparrowwallet.sparrow.event.BitcoinUnitChangedEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
@ -21,7 +21,7 @@ public class OutputsController extends TransactionFormController implements Init
private CopyableLabel count; private CopyableLabel count;
@FXML @FXML
private CoinLabel total; private CopyableCoinLabel total;
@FXML @FXML
private PieChart outputsPie; private PieChart outputsPie;

View file

@ -42,13 +42,13 @@ public class TransactionsController extends WalletFormController implements Init
private static final DateFormat LOG_DATE_FORMAT = new SimpleDateFormat("[MMM dd HH:mm:ss]"); private static final DateFormat LOG_DATE_FORMAT = new SimpleDateFormat("[MMM dd HH:mm:ss]");
@FXML @FXML
private CoinLabel balance; private CopyableCoinLabel balance;
@FXML @FXML
private FiatLabel fiatBalance; private FiatLabel fiatBalance;
@FXML @FXML
private CoinLabel mempoolBalance; private CopyableCoinLabel mempoolBalance;
@FXML @FXML
private FiatLabel fiatMempoolBalance; private FiatLabel fiatMempoolBalance;
@ -228,7 +228,7 @@ public class TransactionsController extends WalletFormController implements Init
public void walletHistoryStatus(WalletHistoryStatusEvent event) { public void walletHistoryStatus(WalletHistoryStatusEvent event) {
transactionsTable.updateHistoryStatus(event); transactionsTable.updateHistoryStatus(event);
if(event.getWallet() != null && getWalletForm().getWallet() == event.getWallet()) { if(event.getWallet() != null && getWalletForm() != null && getWalletForm().getWallet() == event.getWallet()) {
String logMessage = event.getStatusMessage(); String logMessage = event.getStatusMessage();
if(logMessage == null) { if(logMessage == null) {
if(event instanceof WalletHistoryFinishedEvent) { if(event instanceof WalletHistoryFinishedEvent) {

View file

@ -53,13 +53,13 @@ public class UtxosController extends WalletFormController implements Initializab
private static final Logger log = LoggerFactory.getLogger(UtxosController.class); private static final Logger log = LoggerFactory.getLogger(UtxosController.class);
@FXML @FXML
private CoinLabel balance; private CopyableCoinLabel balance;
@FXML @FXML
private FiatLabel fiatBalance; private FiatLabel fiatBalance;
@FXML @FXML
private CoinLabel mempoolBalance; private CopyableCoinLabel mempoolBalance;
@FXML @FXML
private FiatLabel fiatMempoolBalance; private FiatLabel fiatMempoolBalance;

View file

@ -11,6 +11,7 @@ import com.sparrowwallet.drongo.wallet.Wallet;
import com.sparrowwallet.sparrow.AppServices; import com.sparrowwallet.sparrow.AppServices;
import com.sparrowwallet.sparrow.EventManager; import com.sparrowwallet.sparrow.EventManager;
import com.sparrowwallet.sparrow.control.CoinLabel; import com.sparrowwallet.sparrow.control.CoinLabel;
import com.sparrowwallet.sparrow.control.CopyableCoinLabel;
import com.sparrowwallet.sparrow.control.CopyableLabel; import com.sparrowwallet.sparrow.control.CopyableLabel;
import com.sparrowwallet.sparrow.event.WalletMasterMixConfigChangedEvent; import com.sparrowwallet.sparrow.event.WalletMasterMixConfigChangedEvent;
import com.sparrowwallet.sparrow.io.Config; import com.sparrowwallet.sparrow.io.Config;
@ -62,7 +63,7 @@ public class WhirlpoolController {
private VBox selectedPool; private VBox selectedPool;
@FXML @FXML
private CoinLabel poolFee; private CopyableCoinLabel poolFee;
@FXML @FXML
private Label poolInsufficient; private Label poolInsufficient;
@ -83,7 +84,7 @@ public class WhirlpoolController {
private Label nbOutputs; private Label nbOutputs;
@FXML @FXML
private CoinLabel discountFee; private CopyableCoinLabel discountFee;
private String walletId; private String walletId;
private Wallet wallet; private Wallet wallet;
@ -273,7 +274,7 @@ public class WhirlpoolController {
OptionalLong optMinValue = allPoolsService.getValue().stream().mapToLong(pool1 -> pool1.getPremixValueMin() + pool1.getFeeValue()).min(); OptionalLong optMinValue = allPoolsService.getValue().stream().mapToLong(pool1 -> pool1.getPremixValueMin() + pool1.getFeeValue()).min();
if(optMinValue.isPresent() && totalUtxoValue < optMinValue.getAsLong()) { if(optMinValue.isPresent() && totalUtxoValue < optMinValue.getAsLong()) {
String satsValue = String.format(Locale.ENGLISH, "%,d", optMinValue.getAsLong()) + " sats"; String satsValue = String.format(Locale.ENGLISH, "%,d", optMinValue.getAsLong()) + " sats";
String btcValue = CoinLabel.BTC_FORMAT.format((double)optMinValue.getAsLong() / Transaction.SATOSHIS_PER_BITCOIN) + " BTC"; String btcValue = CoinLabel.getBTCFormat().format((double)optMinValue.getAsLong() / Transaction.SATOSHIS_PER_BITCOIN) + " BTC";
poolInsufficient.setText("No available pools. Select a value over " + (Config.get().getBitcoinUnit() == BitcoinUnit.BTC ? btcValue : satsValue) + "."); poolInsufficient.setText("No available pools. Select a value over " + (Config.get().getBitcoinUnit() == BitcoinUnit.BTC ? btcValue : satsValue) + ".");
} }
}); });

View file

@ -26,7 +26,7 @@
<HBox><Label text="If you find Sparrow useful, consider donating at "/><Hyperlink text="https://sparrowwallet.com/donate" onAction="#openDonate"/></HBox> <HBox><Label text="If you find Sparrow useful, consider donating at "/><Hyperlink text="https://sparrowwallet.com/donate" onAction="#openDonate"/></HBox>
</VBox> </VBox>
<HBox styleClass="button-area" alignment="BOTTOM_RIGHT" VBox.vgrow="SOMETIMES"> <HBox styleClass="button-area" alignment="BOTTOM_RIGHT" VBox.vgrow="SOMETIMES">
<Button text="Done" onAction="#close" /> <Button text="Close" onAction="#close" />
</HBox> </HBox>
</VBox> </VBox>
</StackPane> </StackPane>

View file

@ -13,7 +13,7 @@
<?import org.controlsfx.control.SegmentedButton?> <?import org.controlsfx.control.SegmentedButton?>
<?import com.sparrowwallet.sparrow.control.CopyableLabel?> <?import com.sparrowwallet.sparrow.control.CopyableLabel?>
<?import com.sparrowwallet.sparrow.control.IdLabel?> <?import com.sparrowwallet.sparrow.control.IdLabel?>
<?import com.sparrowwallet.sparrow.control.CoinLabel?> <?import com.sparrowwallet.sparrow.control.CopyableCoinLabel?>
<?import javafx.scene.control.Button?> <?import javafx.scene.control.Button?>
<?import org.controlsfx.glyphfont.Glyph?> <?import org.controlsfx.glyphfont.Glyph?>
<?import javafx.scene.control.ComboBox?> <?import javafx.scene.control.ComboBox?>
@ -143,7 +143,7 @@
<Form GridPane.columnIndex="1" GridPane.rowIndex="2" styleClass="details-lower"> <Form GridPane.columnIndex="1" GridPane.rowIndex="2" styleClass="details-lower">
<Fieldset text="Fee" inputGrow="SOMETIMES"> <Fieldset text="Fee" inputGrow="SOMETIMES">
<Field text="Amount:"> <Field text="Amount:">
<CoinLabel fx:id="fee" /> <CopyableCoinLabel fx:id="fee" />
</Field> </Field>
<Field text="Rate:"> <Field text="Rate:">
<CopyableLabel fx:id="feeRate" /> <CopyableLabel fx:id="feeRate" />

View file

@ -13,7 +13,7 @@
<?import com.sparrowwallet.sparrow.control.RelativeTimelockSpinner?> <?import com.sparrowwallet.sparrow.control.RelativeTimelockSpinner?>
<?import com.sparrowwallet.sparrow.control.CopyableLabel?> <?import com.sparrowwallet.sparrow.control.CopyableLabel?>
<?import com.sparrowwallet.sparrow.control.IdLabel?> <?import com.sparrowwallet.sparrow.control.IdLabel?>
<?import com.sparrowwallet.sparrow.control.CoinLabel?> <?import com.sparrowwallet.sparrow.control.CopyableCoinLabel?>
<?import com.sparrowwallet.sparrow.control.AddressLabel?> <?import com.sparrowwallet.sparrow.control.AddressLabel?>
<?import com.sparrowwallet.sparrow.control.UnlabeledToggleSwitch?> <?import com.sparrowwallet.sparrow.control.UnlabeledToggleSwitch?>
<?import com.sparrowwallet.sparrow.control.ScriptArea?> <?import com.sparrowwallet.sparrow.control.ScriptArea?>
@ -37,7 +37,7 @@
<Hyperlink fx:id="linkedOutpoint" styleClass="id" visible="false" /> <Hyperlink fx:id="linkedOutpoint" styleClass="id" visible="false" />
</Field> </Field>
<Field text="Spends:"> <Field text="Spends:">
<CoinLabel fx:id="spends" /> <CopyableCoinLabel fx:id="spends" />
<CopyableLabel fx:id="from" text="from" /> <CopyableLabel fx:id="from" text="from" />
<AddressLabel fx:id="address" /> <AddressLabel fx:id="address" />
</Field> </Field>

View file

@ -6,7 +6,7 @@
<?import tornadofx.control.*?> <?import tornadofx.control.*?>
<?import javafx.scene.chart.PieChart?> <?import javafx.scene.chart.PieChart?>
<?import com.sparrowwallet.sparrow.control.CopyableLabel?> <?import com.sparrowwallet.sparrow.control.CopyableLabel?>
<?import com.sparrowwallet.sparrow.control.CoinLabel?> <?import com.sparrowwallet.sparrow.control.CopyableCoinLabel?>
<GridPane hgap="10.0" vgap="10.0" styleClass="tx-pane" stylesheets="@inputs.css, @transaction.css, @../general.css" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.sparrowwallet.sparrow.transaction.InputsController"> <GridPane hgap="10.0" vgap="10.0" styleClass="tx-pane" stylesheets="@inputs.css, @transaction.css, @../general.css" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.sparrowwallet.sparrow.transaction.InputsController">
<padding> <padding>
@ -25,7 +25,7 @@
<CopyableLabel fx:id="count" /> <CopyableLabel fx:id="count" />
</Field> </Field>
<Field text="Total:"> <Field text="Total:">
<CoinLabel fx:id="total" /> <CopyableCoinLabel fx:id="total" />
</Field> </Field>
</Fieldset> </Fieldset>
</Form> </Form>

View file

@ -12,7 +12,7 @@
<?import tornadofx.control.Form?> <?import tornadofx.control.Form?>
<?import javafx.geometry.Insets?> <?import javafx.geometry.Insets?>
<?import com.sparrowwallet.sparrow.control.CopyableLabel?> <?import com.sparrowwallet.sparrow.control.CopyableLabel?>
<?import com.sparrowwallet.sparrow.control.CoinLabel?> <?import com.sparrowwallet.sparrow.control.CopyableCoinLabel?>
<?import com.sparrowwallet.sparrow.control.AddressLabel?> <?import com.sparrowwallet.sparrow.control.AddressLabel?>
<?import com.sparrowwallet.sparrow.control.ScriptArea?> <?import com.sparrowwallet.sparrow.control.ScriptArea?>
@ -31,7 +31,7 @@
<Form GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.rowIndex="0"> <Form GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.rowIndex="0">
<Fieldset fx:id="outputFieldset" inputGrow="SOMETIMES" text="Output"> <Fieldset fx:id="outputFieldset" inputGrow="SOMETIMES" text="Output">
<Field text="Sends:"> <Field text="Sends:">
<CoinLabel fx:id="value"/> <CopyableCoinLabel fx:id="value"/>
<CopyableLabel fx:id="to" text="to" /> <CopyableLabel fx:id="to" text="to" />
<AddressLabel fx:id="address" /> <AddressLabel fx:id="address" />
</Field> </Field>

View file

@ -6,7 +6,7 @@
<?import tornadofx.control.*?> <?import tornadofx.control.*?>
<?import javafx.scene.chart.PieChart?> <?import javafx.scene.chart.PieChart?>
<?import com.sparrowwallet.sparrow.control.CopyableLabel?> <?import com.sparrowwallet.sparrow.control.CopyableLabel?>
<?import com.sparrowwallet.sparrow.control.CoinLabel?> <?import com.sparrowwallet.sparrow.control.CopyableCoinLabel?>
<GridPane hgap="10.0" vgap="10.0" styleClass="tx-pane" stylesheets="@outputs.css, @transaction.css, @../general.css" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.sparrowwallet.sparrow.transaction.OutputsController"> <GridPane hgap="10.0" vgap="10.0" styleClass="tx-pane" stylesheets="@outputs.css, @transaction.css, @../general.css" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.sparrowwallet.sparrow.transaction.OutputsController">
<padding> <padding>
@ -25,7 +25,7 @@
<CopyableLabel fx:id="count" /> <CopyableLabel fx:id="count" />
</Field> </Field>
<Field text="Total:"> <Field text="Total:">
<CoinLabel fx:id="total" /> <CopyableCoinLabel fx:id="total" />
</Field> </Field>
</Fieldset> </Fieldset>
</Form> </Form>

View file

@ -12,7 +12,7 @@
<?import tornadofx.control.Form?> <?import tornadofx.control.Form?>
<?import tornadofx.control.Fieldset?> <?import tornadofx.control.Fieldset?>
<?import tornadofx.control.Field?> <?import tornadofx.control.Field?>
<?import com.sparrowwallet.sparrow.control.CoinLabel?> <?import com.sparrowwallet.sparrow.control.CopyableCoinLabel?>
<?import com.sparrowwallet.sparrow.control.FiatLabel?> <?import com.sparrowwallet.sparrow.control.FiatLabel?>
<?import com.sparrowwallet.sparrow.control.CopyableLabel?> <?import com.sparrowwallet.sparrow.control.CopyableLabel?>
<?import org.controlsfx.glyphfont.Glyph?> <?import org.controlsfx.glyphfont.Glyph?>
@ -35,10 +35,10 @@
<Form GridPane.columnIndex="0" GridPane.rowIndex="0"> <Form GridPane.columnIndex="0" GridPane.rowIndex="0">
<Fieldset inputGrow="SOMETIMES" text="Transactions" styleClass="header"> <Fieldset inputGrow="SOMETIMES" text="Transactions" styleClass="header">
<Field text="Balance:"> <Field text="Balance:">
<CoinLabel fx:id="balance"/><Region HBox.hgrow="ALWAYS"/><FiatLabel fx:id="fiatBalance" minWidth="110" /> <CopyableCoinLabel fx:id="balance"/><Region HBox.hgrow="ALWAYS"/><FiatLabel fx:id="fiatBalance" minWidth="110" />
</Field> </Field>
<Field text="Mempool:"> <Field text="Mempool:">
<CoinLabel fx:id="mempoolBalance" /><Region HBox.hgrow="ALWAYS"/><FiatLabel fx:id="fiatMempoolBalance" minWidth="110" /> <CopyableCoinLabel fx:id="mempoolBalance" /><Region HBox.hgrow="ALWAYS"/><FiatLabel fx:id="fiatMempoolBalance" minWidth="110" />
</Field> </Field>
<Field text="Transactions:"> <Field text="Transactions:">
<CopyableLabel fx:id="transactionCount" /> <CopyableLabel fx:id="transactionCount" />

View file

@ -14,7 +14,7 @@
<?import tornadofx.control.Form?> <?import tornadofx.control.Form?>
<?import tornadofx.control.Fieldset?> <?import tornadofx.control.Fieldset?>
<?import tornadofx.control.Field?> <?import tornadofx.control.Field?>
<?import com.sparrowwallet.sparrow.control.CoinLabel?> <?import com.sparrowwallet.sparrow.control.CopyableCoinLabel?>
<?import com.sparrowwallet.sparrow.control.FiatLabel?> <?import com.sparrowwallet.sparrow.control.FiatLabel?>
<?import com.sparrowwallet.sparrow.control.CopyableLabel?> <?import com.sparrowwallet.sparrow.control.CopyableLabel?>
@ -35,10 +35,10 @@
<Form GridPane.columnIndex="0" GridPane.rowIndex="0"> <Form GridPane.columnIndex="0" GridPane.rowIndex="0">
<Fieldset inputGrow="SOMETIMES" text="Unspent Transaction Outputs" styleClass="header"> <Fieldset inputGrow="SOMETIMES" text="Unspent Transaction Outputs" styleClass="header">
<Field text="Balance:"> <Field text="Balance:">
<CoinLabel fx:id="balance"/><Region HBox.hgrow="ALWAYS"/><FiatLabel fx:id="fiatBalance" minWidth="110" /> <CopyableCoinLabel fx:id="balance"/><Region HBox.hgrow="ALWAYS"/><FiatLabel fx:id="fiatBalance" minWidth="110" />
</Field> </Field>
<Field text="Mempool:"> <Field text="Mempool:">
<CoinLabel fx:id="mempoolBalance" /><Region HBox.hgrow="ALWAYS"/><FiatLabel fx:id="fiatMempoolBalance" minWidth="110" /> <CopyableCoinLabel fx:id="mempoolBalance" /><Region HBox.hgrow="ALWAYS"/><FiatLabel fx:id="fiatMempoolBalance" minWidth="110" />
</Field> </Field>
<Field text="UTXOs:"> <Field text="UTXOs:">
<CopyableLabel fx:id="utxoCount" /> <CopyableLabel fx:id="utxoCount" />

View file

@ -10,7 +10,7 @@
<?import javafx.scene.image.ImageView?> <?import javafx.scene.image.ImageView?>
<?import javafx.scene.image.Image?> <?import javafx.scene.image.Image?>
<?import javafx.geometry.Insets?> <?import javafx.geometry.Insets?>
<?import com.sparrowwallet.sparrow.control.CoinLabel?> <?import com.sparrowwallet.sparrow.control.CopyableCoinLabel?>
<?import com.sparrowwallet.sparrow.control.CopyableLabel?> <?import com.sparrowwallet.sparrow.control.CopyableLabel?>
<StackPane prefHeight="460.0" prefWidth="600.0" stylesheets="@whirlpool.css, @../general.css" styleClass="whirlpool-pane" fx:controller="com.sparrowwallet.sparrow.whirlpool.WhirlpoolController" xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml"> <StackPane prefHeight="460.0" prefWidth="600.0" stylesheets="@whirlpool.css, @../general.css" styleClass="whirlpool-pane" fx:controller="com.sparrowwallet.sparrow.whirlpool.WhirlpoolController" xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml">
<VBox spacing="20"> <VBox spacing="20">
@ -131,10 +131,10 @@
</HBox> </HBox>
<HBox styleClass="field-box"> <HBox styleClass="field-box">
<Label text="Pool Fee:" styleClass="field-label" /> <Label text="Pool Fee:" styleClass="field-label" />
<CoinLabel fx:id="poolFee" /> <CopyableCoinLabel fx:id="poolFee" />
<HBox fx:id="discountFeeBox" alignment="CENTER_LEFT"> <HBox fx:id="discountFeeBox" alignment="CENTER_LEFT">
<Label text=" (discounted to " /> <Label text=" (discounted to " />
<CoinLabel fx:id="discountFee" /> <CopyableCoinLabel fx:id="discountFee" />
<Label text=")" /> <Label text=")" />
</HBox> </HBox>
</HBox> </HBox>