mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-23 15:00:30 +01:00
Add coin selection options to withdrawal screen
This commit is contained in:
parent
52d6d8adc6
commit
ea5548f2ec
4 changed files with 89 additions and 30 deletions
|
@ -629,6 +629,9 @@ funds.deposit.generateAddress=Generate new address
|
|||
funds.deposit.selectUnused=Please select an unused address from the table above rather than generating a new one.
|
||||
|
||||
funds.withdrawal.arbitrationFee=Arbitration fee
|
||||
funds.withdrawal.inputs=Inputs selection
|
||||
funds.withdrawal.useAllInputs=Use all available inputs
|
||||
funds.withdrawal.useCustomInputs=Use custom inputs
|
||||
funds.withdrawal.receiverAmount=Receiver's amount
|
||||
funds.withdrawal.senderAmount=Sender's amount
|
||||
funds.withdrawal.feeExcluded=Amount excludes mining fee
|
||||
|
|
|
@ -23,6 +23,8 @@ import io.bisq.core.btc.listeners.BalanceListener;
|
|||
import io.bisq.core.btc.wallet.BtcWalletService;
|
||||
import io.bisq.gui.util.BSFormatter;
|
||||
import javafx.scene.control.Label;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bitcoinj.core.Address;
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
|
@ -35,6 +37,9 @@ class WithdrawalListItem {
|
|||
private final BSFormatter formatter;
|
||||
private Coin balance;
|
||||
private final String addressString;
|
||||
@Setter
|
||||
@Getter
|
||||
private boolean isSelected;
|
||||
|
||||
public WithdrawalListItem(AddressEntry addressEntry, BtcWalletService walletService,
|
||||
BSFormatter formatter) {
|
||||
|
|
|
@ -39,24 +39,33 @@
|
|||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
|
||||
</padding>
|
||||
|
||||
<Label fx:id="amountLabel" GridPane.rowIndex="0"/>
|
||||
<TextField fx:id="amountTextField" GridPane.rowIndex="0" GridPane.columnIndex="1" prefWidth="120"/>
|
||||
<RadioButton fx:id="feeExcludedRadioButton" GridPane.rowIndex="0" GridPane.columnIndex="2">
|
||||
<Label fx:id="inputsLabel" GridPane.rowIndex="0"/>
|
||||
<RadioButton fx:id="useAllInputsRadioButton" GridPane.rowIndex="0" GridPane.columnIndex="1">
|
||||
<padding>
|
||||
<Insets bottom="0.0" left="0.0" right="5.0" top="0.0"/>
|
||||
</padding>
|
||||
</RadioButton>
|
||||
<RadioButton fx:id="useCustomInputsRadioButton" GridPane.rowIndex="0" GridPane.columnIndex="2"/>
|
||||
|
||||
|
||||
<Label fx:id="amountLabel" GridPane.rowIndex="1"/>
|
||||
<TextField fx:id="amountTextField" GridPane.rowIndex="1" GridPane.columnIndex="1" prefWidth="120"/>
|
||||
<RadioButton fx:id="feeExcludedRadioButton" GridPane.rowIndex="1" GridPane.columnIndex="2">
|
||||
<padding>
|
||||
<Insets bottom="0.0" left="5.0" right="5.0" top="0.0"/>
|
||||
</padding>
|
||||
</RadioButton>
|
||||
<RadioButton fx:id="feeIncludedRadioButton" GridPane.rowIndex="0" GridPane.columnIndex="3"/>
|
||||
<RadioButton fx:id="feeIncludedRadioButton" GridPane.rowIndex="1" GridPane.columnIndex="3"/>
|
||||
|
||||
<Label fx:id="fromLabel" GridPane.rowIndex="1"/>
|
||||
<Label fx:id="fromLabel" GridPane.rowIndex="2"/>
|
||||
<TextField fx:id="withdrawFromTextField" editable="false" focusTraversable="false"
|
||||
GridPane.rowIndex="1" GridPane.columnIndex="1" GridPane.columnSpan="3"/>
|
||||
GridPane.rowIndex="2" GridPane.columnIndex="1" GridPane.columnSpan="3"/>
|
||||
|
||||
<Label fx:id="toLabel" GridPane.rowIndex="2"/>
|
||||
<TextField fx:id="withdrawToTextField" GridPane.rowIndex="2" GridPane.columnIndex="1" GridPane.columnSpan="3"/>
|
||||
<Label fx:id="toLabel" GridPane.rowIndex="3"/>
|
||||
<TextField fx:id="withdrawToTextField" GridPane.rowIndex="3" GridPane.columnIndex="1" GridPane.columnSpan="3"/>
|
||||
|
||||
<Button fx:id="withdrawButton" defaultButton="true" onAction="#onWithdraw"
|
||||
GridPane.rowIndex="3"
|
||||
GridPane.rowIndex="4"
|
||||
GridPane.columnIndex="1"/>
|
||||
|
||||
<columnConstraints>
|
||||
|
|
|
@ -42,7 +42,9 @@ import io.bisq.gui.main.overlays.windows.WalletPasswordWindow;
|
|||
import io.bisq.gui.util.BSFormatter;
|
||||
import io.bisq.gui.util.GUIUtil;
|
||||
import io.bisq.gui.util.validation.BtcAddressValidator;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
|
@ -71,7 +73,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
public class WithdrawalView extends ActivatableView<VBox, Void> {
|
||||
|
||||
@FXML
|
||||
Label amountLabel, fromLabel, toLabel;
|
||||
Label inputsLabel, amountLabel, fromLabel, toLabel;
|
||||
@FXML
|
||||
Button withdrawButton;
|
||||
@FXML
|
||||
|
@ -79,7 +81,7 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||
@FXML
|
||||
TextField withdrawFromTextField, withdrawToTextField, amountTextField;
|
||||
@FXML
|
||||
RadioButton feeExcludedRadioButton, feeIncludedRadioButton;
|
||||
RadioButton useAllInputsRadioButton, useCustomInputsRadioButton, feeExcludedRadioButton, feeIncludedRadioButton;
|
||||
@FXML
|
||||
TableColumn<WithdrawalListItem, WithdrawalListItem> addressColumn, balanceColumn, selectColumn;
|
||||
|
||||
|
@ -101,8 +103,9 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||
private Coin sendersAmount = Coin.ZERO;
|
||||
private ChangeListener<String> amountListener;
|
||||
private ChangeListener<Boolean> amountFocusListener;
|
||||
private ChangeListener<Toggle> feeToggleGroupListener;
|
||||
private ToggleGroup feeToggleGroup;
|
||||
private ChangeListener<Toggle> feeToggleGroupListener, inputsToggleGroupListener;
|
||||
private ToggleGroup feeToggleGroup, inputsToggleGroup;
|
||||
private final BooleanProperty useAllInputs = new SimpleBooleanProperty(true);
|
||||
private boolean feeExcluded;
|
||||
|
||||
|
||||
|
@ -130,6 +133,9 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
inputsLabel.setText(Res.getWithCol("funds.withdrawal.inputs"));
|
||||
useAllInputsRadioButton.setText(Res.get("funds.withdrawal.useAllInputs"));
|
||||
useCustomInputsRadioButton.setText(Res.get("funds.withdrawal.useCustomInputs"));
|
||||
amountLabel.setText(Res.getWithCol("funds.withdrawal.receiverAmount", Res.getBaseCurrencyCode()));
|
||||
feeExcludedRadioButton.setText(Res.get("funds.withdrawal.feeExcluded"));
|
||||
feeIncludedRadioButton.setText(Res.get("funds.withdrawal.feeIncluded"));
|
||||
|
@ -186,6 +192,23 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||
Res.getWithCol("funds.withdrawal.receiverAmount", Res.getBaseCurrencyCode()) :
|
||||
Res.getWithCol("funds.withdrawal.senderAmount", Res.getBaseCurrencyCode()));
|
||||
};
|
||||
|
||||
inputsToggleGroup = new ToggleGroup();
|
||||
useAllInputsRadioButton.setToggleGroup(inputsToggleGroup);
|
||||
useCustomInputsRadioButton.setToggleGroup(inputsToggleGroup);
|
||||
inputsToggleGroupListener = (observable, oldValue, newValue) -> {
|
||||
useAllInputs.set(newValue == useAllInputsRadioButton);
|
||||
|
||||
updateInputSelection();
|
||||
};
|
||||
}
|
||||
|
||||
private void updateInputSelection() {
|
||||
observableList.stream().forEach(item -> {
|
||||
item.setSelected(useAllInputs.get());
|
||||
selectForWithdrawal(item);
|
||||
});
|
||||
tableView.refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -200,8 +223,15 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||
amountTextField.focusedProperty().addListener(amountFocusListener);
|
||||
walletService.addBalanceListener(balanceListener);
|
||||
feeToggleGroup.selectedToggleProperty().addListener(feeToggleGroupListener);
|
||||
inputsToggleGroup.selectedToggleProperty().addListener(inputsToggleGroupListener);
|
||||
|
||||
if (feeToggleGroup.getSelectedToggle() == null)
|
||||
feeToggleGroup.selectToggle(feeExcludedRadioButton);
|
||||
|
||||
if (inputsToggleGroup.getSelectedToggle() == null)
|
||||
inputsToggleGroup.selectToggle(useAllInputsRadioButton);
|
||||
|
||||
updateInputSelection();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -212,6 +242,7 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||
amountTextField.textProperty().removeListener(amountListener);
|
||||
amountTextField.focusedProperty().removeListener(amountFocusListener);
|
||||
feeToggleGroup.selectedToggleProperty().removeListener(feeToggleGroupListener);
|
||||
inputsToggleGroup.selectedToggleProperty().removeListener(inputsToggleGroupListener);
|
||||
}
|
||||
|
||||
|
||||
|
@ -290,8 +321,8 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||
}
|
||||
}
|
||||
|
||||
private void selectForWithdrawal(WithdrawalListItem item, boolean isSelected) {
|
||||
if (isSelected)
|
||||
private void selectForWithdrawal(WithdrawalListItem item) {
|
||||
if (item.isSelected())
|
||||
selectedItems.add(item);
|
||||
else
|
||||
selectedItems.remove(item);
|
||||
|
@ -349,6 +380,8 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||
observableList.setAll(tradeManager.getAddressEntriesForAvailableBalanceStream()
|
||||
.map(addressEntry -> new WithdrawalListItem(addressEntry, walletService, formatter))
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
updateInputSelection();
|
||||
}
|
||||
|
||||
private void doWithdraw(Coin amount, Coin fee, FutureCallback<Transaction> callback) {
|
||||
|
@ -382,10 +415,6 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||
}
|
||||
|
||||
private void reset() {
|
||||
selectedItems = new HashSet<>();
|
||||
|
||||
tableView.getSelectionModel().clearSelection();
|
||||
|
||||
withdrawFromTextField.setText("");
|
||||
withdrawFromTextField.setPromptText(Res.get("funds.withdrawal.selectAddress"));
|
||||
withdrawFromTextField.setTooltip(null);
|
||||
|
@ -398,6 +427,9 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||
|
||||
withdrawToTextField.setText("");
|
||||
withdrawToTextField.setPromptText(Res.get("funds.withdrawal.fillDestAddress"));
|
||||
|
||||
selectedItems.clear();
|
||||
tableView.getSelectionModel().clearSelection();
|
||||
}
|
||||
|
||||
private Optional<Tradable> getTradable(WithdrawalListItem item) {
|
||||
|
@ -505,23 +537,33 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||
WithdrawalListItem> column) {
|
||||
return new TableCell<WithdrawalListItem, WithdrawalListItem>() {
|
||||
|
||||
CheckBox checkBox;
|
||||
CheckBox checkBox = new CheckBox();
|
||||
|
||||
@Override
|
||||
public void updateItem(final WithdrawalListItem item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (item != null && !empty) {
|
||||
if (checkBox == null) {
|
||||
checkBox = new CheckBox();
|
||||
checkBox.setOnAction(e -> selectForWithdrawal(item, checkBox.isSelected()));
|
||||
setGraphic(checkBox);
|
||||
}
|
||||
checkBox.setOnAction(e -> {
|
||||
item.setSelected(checkBox.isSelected());
|
||||
selectForWithdrawal(item);
|
||||
|
||||
// If all are selected we select useAllInputsRadioButton
|
||||
if (observableList.size() == selectedItems.size()) {
|
||||
inputsToggleGroup.selectToggle(useAllInputsRadioButton);
|
||||
} else {
|
||||
setGraphic(null);
|
||||
if (checkBox != null) {
|
||||
checkBox.setOnAction(null);
|
||||
checkBox = null;
|
||||
// We don't want to get deselected all when we activate the useCustomInputsRadioButton
|
||||
// so we temporarily disable the listener
|
||||
inputsToggleGroup.selectedToggleProperty().removeListener(inputsToggleGroupListener);
|
||||
inputsToggleGroup.selectToggle(useCustomInputsRadioButton);
|
||||
useAllInputs.set(false);
|
||||
inputsToggleGroup.selectedToggleProperty().addListener(inputsToggleGroupListener);
|
||||
}
|
||||
});
|
||||
setGraphic(checkBox);
|
||||
checkBox.setSelected(item.isSelected());
|
||||
} else {
|
||||
checkBox.setOnAction(null);
|
||||
setGraphic(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue