Update to new Create offer UI

This commit is contained in:
Manfred Karrer 2014-09-04 02:52:16 +02:00
parent 17f738e3a5
commit 40107785ab
20 changed files with 1193 additions and 616 deletions

View file

@ -1,13 +1,22 @@
/*
Theme colors:
logo colors:
blue: 0096c9
dark grey: #333333
main bg grey: dddddd
content bg grey: f4f4f4
*/
/* Create offer */
#direction-icon-label {
-fx-font-weight:bold;
-fx-font-size:16;
-fx-text-fill: #333;
}
#input-description-label {
-fx-font-size: 11;
-fx-alignment: center;
@ -28,6 +37,19 @@ content bg grey: f4f4f4
-fx-border-insets: 0 0 0 -2;
}
#info-link {
-fx-padding: 0 0 0 -2;
}
#totals-separator {
-fx-background: #aaa;
}
#payment-info {
-fx-background-color: #f4f4f4;
}
/* Registration */
#wizard-title-deactivated {
-fx-font-weight: bold;
@ -193,15 +215,11 @@ content bg grey: f4f4f4
-fx-padding: 4 4 4 4;
}
#address-label {
#address-text-field {
-fx-cursor: hand;
-fx-text-fill: #0096c9;
-fx-underline: true;
-fx-background-color: #FAFAFA;
-fx-border-radius: 4;
-fx-padding: 4 4 4 4;
}
#address-label:hover {
#address-text-field:hover {
-fx-text-fill: black;
}
@ -303,10 +321,17 @@ content bg grey: f4f4f4
-fx-outer-border,
-fx-inner-border,
-fx-body-color;
-fx-background-insets: 0 0 -1 0, 0, 1.5, 2;
-fx-background-insets: 0 0 -1 0, 0, 1, 2;
-fx-background-radius: 3px, 3px, 2px, 1px;
}
#clickable-icon {
-fx-text-fill: #0096c9;
-fx-cursor: hand;
}
#clickable-icon:hover {
-fx-text-fill: #666;
}
#form-title {
-fx-font-weight: bold;

View file

@ -43,13 +43,16 @@ import org.slf4j.LoggerFactory;
* There can be only 1 errorMessageDisplays at a time we use static field for it.
* The position is derived from the position of the textField itself or if set from the layoutReference node.
*/
//TODO There are some rare situation where it behaves buggy. Needs further investigation and improvements. Also
// consider replacement with controlsFX components.
public class InputTextField extends TextField {
private static final Logger log = LoggerFactory.getLogger(InputTextField.class);
private Effect invalidEffect = new DropShadow(BlurType.GAUSSIAN, Color.RED, 4, 0.0, 0, 0);
private final Effect invalidEffect = new DropShadow(BlurType.GAUSSIAN, Color.RED, 4, 0.0, 0, 0);
final ObjectProperty<InputValidator.ValidationResult> amountValidationResult = new SimpleObjectProperty<>(new
InputValidator.ValidationResult(true));
private final ObjectProperty<InputValidator.ValidationResult> amountValidationResult = new SimpleObjectProperty<>
(new
InputValidator.ValidationResult(true));
private static PopOver errorMessageDisplay;
private Region layoutReference = this;
@ -100,7 +103,7 @@ public class InputTextField extends TextField {
///////////////////////////////////////////////////////////////////////////////////////////
/**
* @param layoutReference The node used as reference for positioning. If not set explicitely the
* @param layoutReference The node used as reference for positioning. If not set explicitly the
* ValidatingTextField instance is used.
*/
public void setLayoutReference(Region layoutReference) {
@ -123,18 +126,21 @@ public class InputTextField extends TextField {
private void applyErrorMessage(InputValidator.ValidationResult validationResult) {
if (validationResult.isValid) {
if (errorMessageDisplay != null) {
if (errorMessageDisplay != null)
errorMessageDisplay.hide();
}
}
else {
if (errorMessageDisplay == null)
createErrorPopOver(validationResult.errorMessage);
else
((Label) errorMessageDisplay.getContentNode()).setText(validationResult.errorMessage);
errorMessageDisplay.show(getScene().getWindow(), getErrorPopupPosition().getX(),
getErrorPopupPosition().getY());
if (getScene() != null)
errorMessageDisplay.show(getScene().getWindow(), getErrorPopupPosition().getX(),
getErrorPopupPosition().getY());
InputTextField.errorMessageDisplay.setDetached(false);
}
}
@ -142,8 +148,10 @@ public class InputTextField extends TextField {
Window window = getScene().getWindow();
Point2D point;
point = layoutReference.localToScene(0, 0);
double x = point.getX() + window.getX() + layoutReference.getWidth() + 20;
double y = point.getY() + window.getY() + Math.floor(getHeight() / 2);
double x = Math.floor(point.getX() + window.getX() + layoutReference.getWidth() + 20 - getPadding().getLeft() -
getPadding().getRight());
double y = Math.floor(point.getY() + window.getY() + getHeight() / 2 - getPadding().getTop() - getPadding()
.getBottom());
return new Point2D(x, y);
}
@ -152,9 +160,11 @@ public class InputTextField extends TextField {
Label errorLabel = new Label(errorMessage);
errorLabel.setId("validation-error");
errorLabel.setPadding(new Insets(0, 10, 0, 10));
errorLabel.setOnMouseClicked(e -> hideErrorMessageDisplay());
InputTextField.errorMessageDisplay = new PopOver(errorLabel);
InputTextField.errorMessageDisplay.setDetachable(false);
InputTextField.errorMessageDisplay.setDetachable(true);
InputTextField.errorMessageDisplay.setDetachedTitle("Close");
InputTextField.errorMessageDisplay.setArrowIndent(5);
}

View file

@ -30,24 +30,37 @@ import javafx.application.Platform;
import org.controlsfx.control.action.Action;
import org.controlsfx.dialog.Dialog;
import org.controlsfx.dialog.DialogStyle;
import org.controlsfx.dialog.Dialogs;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Collection of controlsfx Popups
*/
public class Popups {
private static final Logger log = LoggerFactory.getLogger(Popups.class);
// Information
public static void openInformationPopup(String title, String message) {
openInformationPopup(title, message, null);
openInformationPopup(title, message, null, null);
}
public static void openInformationPopup(String title, String message, String masthead) {
List<Action> actions = new ArrayList<>();
actions.add(Dialog.Actions.CLOSE);
openInformationPopup(title, message, masthead, actions);
}
public static void openInformationPopup(String title, String message, String masthead, List<Action> actions) {
Dialogs.create()
.owner(BitSquare.getPrimaryStage())
.title(title)
.message(message)
.masthead(masthead)
.actions(actions)
.style(DialogStyle.UNDECORATED)
.showInformation();
}

View file

@ -34,6 +34,7 @@ import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.*;
@ -65,9 +66,10 @@ public class AddressTextField extends AnchorPane {
///////////////////////////////////////////////////////////////////////////////////////////
public AddressTextField() {
Label addressLabel = new Label();
addressLabel.setFocusTraversable(false);
addressLabel.setId("address-label");
TextField addressLabel = new TextField();
addressLabel.setId("address-text-field");
addressLabel.setEditable(false);
addressLabel.textProperty().bind(address);
addressLabel.setOnMouseClicked(mouseEvent -> {
try {
@ -79,6 +81,11 @@ public class AddressTextField extends AnchorPane {
"Perhaps you don't have one installed?");
}
});
addressLabel.focusTraversableProperty().set(focusTraversableProperty().get());
focusedProperty().addListener((ov, oldValue, newValue) -> {
addressLabel.requestFocus();
log.debug("foc");
});
Label copyIcon = new Label();
copyIcon.setLayoutY(3);

View file

@ -28,7 +28,9 @@ import com.google.bitcoin.core.Coin;
import com.google.bitcoin.core.TransactionConfidence;
import javafx.scene.control.*;
import javafx.scene.effect.*;
import javafx.scene.layout.*;
import javafx.scene.paint.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -40,6 +42,9 @@ public class BalanceTextField extends AnchorPane {
private final Tooltip progressIndicatorTooltip;
private final ConfidenceProgressIndicator progressIndicator;
private final Effect fundedEffect = new DropShadow(BlurType.GAUSSIAN, Color.GREEN, 4, 0.0, 0, 0);
private final Effect notFundedEffect = new DropShadow(BlurType.GAUSSIAN, Color.ORANGERED, 4, 0.0, 0, 0);
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
@ -123,6 +128,10 @@ public class BalanceTextField extends AnchorPane {
private void updateBalance(Coin balance) {
balanceTextField.setText(BSFormatter.formatCoin(balance));
if (balance.isPositive())
balanceTextField.setEffect(fundedEffect);
else
balanceTextField.setEffect(notFundedEffect);
}
}

View file

@ -18,38 +18,79 @@
package io.bitsquare.gui.trade.createoffer;
import io.bitsquare.gui.CachedCodeBehind;
import io.bitsquare.gui.MainController;
import io.bitsquare.gui.NavigationItem;
import io.bitsquare.gui.components.InputTextField;
import io.bitsquare.gui.components.Popups;
import io.bitsquare.gui.components.btc.AddressTextField;
import io.bitsquare.gui.components.btc.BalanceTextField;
import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator;
import io.bitsquare.gui.help.Help;
import io.bitsquare.gui.help.HelpId;
import io.bitsquare.gui.trade.TradeController;
import io.bitsquare.gui.util.ImageUtil;
import io.bitsquare.trade.orderbook.OrderBookFilter;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import javax.inject.Inject;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Point2D;
import javafx.geometry.VPos;
import javafx.scene.control.*;
import javafx.scene.image.*;
import javafx.scene.input.*;
import javafx.scene.layout.*;
import javafx.scene.text.*;
import javafx.stage.Window;
import de.jensd.fx.fontawesome.AwesomeDude;
import de.jensd.fx.fontawesome.AwesomeIcon;
import org.controlsfx.control.PopOver;
import org.controlsfx.control.action.AbstractAction;
import org.controlsfx.control.action.Action;
import org.controlsfx.dialog.Dialog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// TODO Implement other positioning method in InoutTextField to display it over the field instead of right side
// priceAmountHBox is too large after redesign as to be used as layoutReference.
public class CreateOfferCB extends CachedCodeBehind<CreateOfferPM> {
private static final Logger log = LoggerFactory.getLogger(CreateOfferCB.class);
@FXML private Label buyLabel, confirmationLabel, txTitleLabel, collateralLabel;
private boolean detailsVisible;
private boolean advancedScreenInited;
private ImageView expand;
private ImageView collapse;
private PopOver totalToPayInfoPopover;
@FXML private ScrollPane scrollPane;
@FXML private ImageView payFundsInfoIcon, showDetailsInfoIcon;
@FXML private TextFlow payFundsInfoTextFlow, showDetailsInfoLabel;
@FXML private Pane priceAmountPane, payFundsPane, showDetailsPane;
@FXML private Label buyLabel, priceAmountTitleLabel, addressLabel,
balanceLabel, payFundsTitleLabel, totalToPayLabel, totalToPayInfoIconLabel,
showDetailsTitleLabel, bankAccountTypeLabel, bankAccountCurrencyLabel, bankAccountCountyLabel,
acceptedCountriesLabel, acceptedCountriesLabelIcon, acceptedLanguagesLabel, acceptedLanguagesLabelIcon,
acceptedArbitratorsLabel, acceptedArbitratorsLabelIcon;
@FXML private Button showPaymentInfoScreenButton, showAdvancedSettingsButton, placeOfferButton;
@FXML private InputTextField amountTextField, minAmountTextField, priceTextField, volumeTextField;
@FXML private Button placeOfferButton, closeButton;
@FXML private TextField totalToPayTextField, collateralTextField, bankAccountTypeTextField,
@FXML private TextField acceptedArbitratorsTextField, totalToPayTextField, bankAccountTypeTextField,
bankAccountCurrencyTextField, bankAccountCountyTextField, acceptedCountriesTextField,
acceptedLanguagesTextField,
totalFeesTextField, transactionIdTextField;
@FXML private ConfidenceProgressIndicator progressIndicator;
acceptedLanguagesTextField;
@FXML private AddressTextField addressTextField;
@FXML private BalanceTextField balanceTextField;
@ -59,7 +100,7 @@ public class CreateOfferCB extends CachedCodeBehind<CreateOfferPM> {
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
CreateOfferCB(CreateOfferPM presentationModel) {
private CreateOfferCB(CreateOfferPM presentationModel) {
super(presentationModel);
}
@ -74,14 +115,15 @@ public class CreateOfferCB extends CachedCodeBehind<CreateOfferPM> {
setupBindings();
setupListeners();
configTextFieldValidators();
balanceTextField.setup(presentationModel.getWalletFacade(), presentationModel.address.get());
}
@SuppressWarnings("EmptyMethod")
public void activate() {
super.activate();
}
@SuppressWarnings("EmptyMethod")
public void deactivate() {
super.deactivate();
}
@ -90,7 +132,7 @@ public class CreateOfferCB extends CachedCodeBehind<CreateOfferPM> {
public void terminate() {
super.terminate();
// Used to re-enable createOfferButton in OrderBookController
// Used to reset disable state of createOfferButton in OrderBookController
if (parentController != null) ((TradeController) parentController).onCreateOfferViewRemoved();
}
@ -109,22 +151,91 @@ public class CreateOfferCB extends CachedCodeBehind<CreateOfferPM> {
///////////////////////////////////////////////////////////////////////////////////////////
@FXML
public void onPlaceOffer() {
presentationModel.placeOffer();
private void onPlaceOffer() {
presentationModel.onPlaceOffer();
}
@FXML
public void onClose() {
private void onShowPayFundsScreen() {
priceAmountPane.setId("form-group-background");
priceAmountTitleLabel.setId("form-group-title");
showPaymentInfoScreenButton.setVisible(false);
payFundsPane.setVisible(true);
totalToPayLabel.setVisible(true);
totalToPayInfoIconLabel.setVisible(true);
totalToPayTextField.setVisible(true);
addressLabel.setVisible(true);
addressTextField.setVisible(true);
balanceLabel.setVisible(true);
balanceTextField.setVisible(true);
payFundsInfoIcon.setVisible(true);
payFundsInfoTextFlow.setVisible(true);
showAdvancedSettingsButton.setVisible(true);
if (expand == null) {
expand = ImageUtil.getIconImageView(ImageUtil.EXPAND);
collapse = ImageUtil.getIconImageView(ImageUtil.COLLAPSE);
}
showAdvancedSettingsButton.setGraphic(expand);
setupTotalToPayInfoIconLabel();
presentationModel.onShowPayFundsScreen();
}
@FXML
private void onToggleShowAdvancedSettings() {
detailsVisible = !detailsVisible;
if (detailsVisible) {
showAdvancedSettingsButton.setText("Hide advanced settings");
showAdvancedSettingsButton.setGraphic(collapse);
showDetailsScreen();
}
else {
showAdvancedSettingsButton.setText("Show advanced settings");
showAdvancedSettingsButton.setGraphic(expand);
hideDetailsScreen();
}
}
@FXML
private void onOpenGeneralHelp() {
Help.openWindow(HelpId.CREATE_OFFER_GENERAL);
}
@FXML
private void onOpenFundingHelp() {
Help.openWindow(HelpId.CREATE_OFFER_FUNDING);
}
@FXML
private void onOpenAdvancedSettingsHelp() {
Help.openWindow(HelpId.CREATE_OFFER_ADVANCED);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Navigation
///////////////////////////////////////////////////////////////////////////////////////////
private void openSettings() {
MainController.GET_INSTANCE().loadViewAndGetChildController(NavigationItem.SETTINGS);
}
private void close() {
TabPane tabPane = ((TabPane) (root.getParent().getParent()));
tabPane.getTabs().remove(tabPane.getSelectionModel().getSelectedItem());
}
///////////////////////////////////////////////////////////////////////////////////////////
// Private Methods
///////////////////////////////////////////////////////////////////////////////////////////
private void setupListeners() {
scrollPane.setOnScroll(e -> InputTextField.hideErrorMessageDisplay());
// focus out
amountTextField.focusedProperty().addListener((o, oldValue, newValue) -> {
presentationModel.onFocusOutAmountTextField(oldValue, newValue, amountTextField.getText());
@ -172,14 +283,46 @@ public class CreateOfferCB extends CachedCodeBehind<CreateOfferPM> {
}
});
presentationModel.requestPlaceOfferFailed.addListener((o, oldValue, newValue) -> {
if (newValue && presentationModel.requestPlaceOfferErrorMessage.get() != null) {
presentationModel.requestPlaceOfferErrorMessage.addListener((o, oldValue, newValue) -> {
if (newValue != null) {
Popups.openErrorPopup("Error", "An error occurred when placing the offer.\n" +
presentationModel.requestPlaceOfferErrorMessage.get());
}
});
presentationModel.showTransactionPublishedScreen.addListener((o, oldValue, newValue) -> {
if (newValue != null) {
// Dialogs are a bit limited. There is no callback for the InformationDialog button click, so we added
// our own actions.
List<Action> actions = new ArrayList<>();
actions.add(new AbstractAction("Copy transaction ID") {
@Override
public void handle(ActionEvent actionEvent) {
Clipboard clipboard = Clipboard.getSystemClipboard();
ClipboardContent content = new ClipboardContent();
content.putString(presentationModel.transactionId.get());
clipboard.setContent(content);
}
});
actions.add(new AbstractAction("Close") {
@Override
public void handle(ActionEvent actionEvent) {
try {
close();
} catch (Exception e) {
e.printStackTrace();
}
Dialog.Actions.CLOSE.handle(actionEvent);
}
});
Popups.openInformationPopup("Offer published",
"The Bitcoin network transaction ID for the offer payment is: " +
presentationModel.transactionId.get(),
"Your offer has been successfully published to the distributed orderbook.",
actions);
}
});
}
private void setupBindings() {
@ -190,10 +333,7 @@ public class CreateOfferCB extends CachedCodeBehind<CreateOfferPM> {
priceTextField.textProperty().bindBidirectional(presentationModel.price);
volumeTextField.textProperty().bindBidirectional(presentationModel.volume);
collateralLabel.textProperty().bind(presentationModel.collateralLabel);
collateralTextField.textProperty().bind(presentationModel.collateral);
totalToPayTextField.textProperty().bind(presentationModel.totalToPay);
totalFeesTextField.textProperty().bind(presentationModel.totalFees);
addressTextField.amountAsCoinProperty().bind(presentationModel.totalToPayAsCoin);
addressTextField.paymentLabelProperty().bind(presentationModel.paymentLabel);
@ -205,7 +345,7 @@ public class CreateOfferCB extends CachedCodeBehind<CreateOfferPM> {
acceptedCountriesTextField.textProperty().bind(presentationModel.acceptedCountries);
acceptedLanguagesTextField.textProperty().bind(presentationModel.acceptedLanguages);
transactionIdTextField.textProperty().bind(presentationModel.transactionId);
acceptedArbitratorsTextField.textProperty().bind(presentationModel.acceptedArbitrators);
// Validation
amountTextField.amountValidationResultProperty().bind(presentationModel.amountValidationResult);
@ -216,14 +356,129 @@ public class CreateOfferCB extends CachedCodeBehind<CreateOfferPM> {
// buttons
placeOfferButton.visibleProperty().bind(presentationModel.isPlaceOfferButtonVisible);
placeOfferButton.disableProperty().bind(presentationModel.isPlaceOfferButtonDisabled);
closeButton.visibleProperty().bind(presentationModel.isCloseButtonVisible);
// closeButton.visibleProperty().bind(presentationModel.isCloseButtonVisible);
}
private void configTextFieldValidators() {
Region referenceNode = (Region) amountTextField.getParent();
amountTextField.setLayoutReference(referenceNode);
priceTextField.setLayoutReference(referenceNode);
volumeTextField.setLayoutReference(referenceNode);
private void showDetailsScreen() {
payFundsPane.setId("form-group-background");
payFundsTitleLabel.setId("form-group-title");
scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
scrollPane.layout();
if (!advancedScreenInited) {
initEditIcons();
advancedScreenInited = true;
}
toggleDetailsScreen(true);
}
private void initEditIcons() {
advancedScreenInited = true;
acceptedCountriesLabelIcon.setId("clickable-icon");
AwesomeDude.setIcon(acceptedCountriesLabelIcon, AwesomeIcon.EDIT_SIGN);
Tooltip.install(acceptedCountriesLabelIcon, new Tooltip("Open settings for editing"));
acceptedCountriesLabelIcon.setOnMouseClicked(e -> openSettings());
acceptedLanguagesLabelIcon.setId("clickable-icon");
AwesomeDude.setIcon(acceptedLanguagesLabelIcon, AwesomeIcon.EDIT_SIGN);
Tooltip.install(acceptedLanguagesLabelIcon, new Tooltip("Open settings for editing"));
acceptedLanguagesLabelIcon.setOnMouseClicked(e -> openSettings());
acceptedArbitratorsLabelIcon.setId("clickable-icon");
AwesomeDude.setIcon(acceptedArbitratorsLabelIcon, AwesomeIcon.EDIT_SIGN);
Tooltip.install(acceptedArbitratorsLabelIcon, new Tooltip("Open settings for editing"));
acceptedArbitratorsLabelIcon.setOnMouseClicked(e -> openSettings());
}
private void hideDetailsScreen() {
payFundsPane.setId("form-group-background-active");
payFundsTitleLabel.setId("form-group-title-active");
scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
scrollPane.layout();
toggleDetailsScreen(false);
}
private void toggleDetailsScreen(boolean visible) {
showDetailsPane.setVisible(visible);
showDetailsTitleLabel.setVisible(visible);
acceptedCountriesLabel.setVisible(visible);
acceptedCountriesLabelIcon.setVisible(visible);
acceptedCountriesTextField.setVisible(visible);
acceptedLanguagesLabel.setVisible(visible);
acceptedLanguagesLabelIcon.setVisible(visible);
acceptedLanguagesTextField.setVisible(visible);
acceptedArbitratorsLabel.setVisible(visible);
acceptedArbitratorsLabelIcon.setVisible(visible);
acceptedArbitratorsTextField.setVisible(visible);
bankAccountTypeLabel.setVisible(visible);
bankAccountTypeTextField.setVisible(visible);
bankAccountCurrencyLabel.setVisible(visible);
bankAccountCurrencyTextField.setVisible(visible);
bankAccountCountyLabel.setVisible(visible);
bankAccountCountyTextField.setVisible(visible);
showDetailsInfoIcon.setVisible(visible);
showDetailsInfoLabel.setVisible(visible);
}
private void setupTotalToPayInfoIconLabel() {
totalToPayInfoIconLabel.setId("clickable-icon");
AwesomeDude.setIcon(totalToPayInfoIconLabel, AwesomeIcon.QUESTION_SIGN);
GridPane infoGridPane = new GridPane();
infoGridPane.setHgap(5);
infoGridPane.setVgap(5);
infoGridPane.setPadding(new Insets(10, 10, 10, 10));
addPayInfoEntry(infoGridPane, 0, "Collateral (" + presentationModel.collateralLabel.get() + ")",
presentationModel.collateral.get());
addPayInfoEntry(infoGridPane, 1, "Offer fee:", presentationModel.offerFee.get());
addPayInfoEntry(infoGridPane, 2, "Bitcoin network fee:", presentationModel.networkFee.get());
Separator separator = new Separator();
separator.setOrientation(Orientation.HORIZONTAL);
separator.setStyle("-fx-background: #666;");
GridPane.setConstraints(separator, 1, 3);
infoGridPane.getChildren().add(separator);
addPayInfoEntry(infoGridPane, 4, "Total:", presentationModel.totalToPay.get());
totalToPayInfoIconLabel.setOnMouseEntered(e -> {
if (totalToPayInfoIconLabel.getScene() != null) {
totalToPayInfoPopover = new PopOver(infoGridPane);
totalToPayInfoPopover.setDetachable(false);
totalToPayInfoPopover.setArrowIndent(5);
totalToPayInfoPopover.show(totalToPayInfoIconLabel.getScene().getWindow(),
getPopupPosition().getX(),
getPopupPosition().getY());
}
});
totalToPayInfoIconLabel.setOnMouseExited(e -> {
if (totalToPayInfoPopover != null)
totalToPayInfoPopover.hide();
});
}
private void addPayInfoEntry(GridPane infoGridPane, int row, String labelText, String value) {
Label label = new Label(labelText);
TextField textField = new TextField(value);
textField.setEditable(false);
textField.setFocusTraversable(false);
textField.setId("payment-info");
GridPane.setConstraints(label, 0, row, 1, 1, HPos.RIGHT, VPos.CENTER);
GridPane.setConstraints(textField, 1, row);
infoGridPane.getChildren().addAll(label, textField);
}
private Point2D getPopupPosition() {
Window window = totalToPayInfoIconLabel.getScene().getWindow();
Point2D point = totalToPayInfoIconLabel.localToScene(0, 0);
double x = point.getX() + window.getX() + totalToPayInfoIconLabel.getWidth() + 20;
double y = point.getY() + window.getY() + Math.floor(totalToPayInfoIconLabel.getHeight() / 2);
return new Point2D(x, y);
}
}

View file

@ -17,10 +17,12 @@
package io.bitsquare.gui.trade.createoffer;
import io.bitsquare.arbitrator.Arbitrator;
import io.bitsquare.bank.BankAccount;
import io.bitsquare.btc.AddressEntry;
import io.bitsquare.btc.FeePolicy;
import io.bitsquare.btc.WalletFacade;
import io.bitsquare.btc.listeners.BalanceListener;
import io.bitsquare.gui.UIModel;
import io.bitsquare.locale.Country;
import io.bitsquare.settings.Settings;
@ -48,6 +50,9 @@ import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -68,7 +73,7 @@ class CreateOfferModel extends UIModel {
private final User user;
private final String offerId;
private Direction direction = null;
@Nullable private Direction direction = null;
AddressEntry addressEntry;
@ -81,7 +86,7 @@ class CreateOfferModel extends UIModel {
final LongProperty collateralAsLong = new SimpleLongProperty();
final BooleanProperty requestPlaceOfferSuccess = new SimpleBooleanProperty();
final BooleanProperty requestPlaceOfferFailed = new SimpleBooleanProperty();
final BooleanProperty isWalletFunded = new SimpleBooleanProperty();
final ObjectProperty<Coin> amountAsCoin = new SimpleObjectProperty<>();
final ObjectProperty<Coin> minAmountAsCoin = new SimpleObjectProperty<>();
@ -89,10 +94,12 @@ class CreateOfferModel extends UIModel {
final ObjectProperty<Fiat> volumeAsFiat = new SimpleObjectProperty<>();
final ObjectProperty<Coin> totalToPayAsCoin = new SimpleObjectProperty<>();
final ObjectProperty<Coin> collateralAsCoin = new SimpleObjectProperty<>();
final ObjectProperty<Coin> totalFeesAsCoin = new SimpleObjectProperty<>();
final ObjectProperty<Coin> offerFeeAsCoin = new SimpleObjectProperty<>();
final ObjectProperty<Coin> networkFeeAsCoin = new SimpleObjectProperty<>();
ObservableList<Country> acceptedCountries = FXCollections.observableArrayList();
ObservableList<Locale> acceptedLanguages = FXCollections.observableArrayList();
final ObservableList<Country> acceptedCountries = FXCollections.observableArrayList();
final ObservableList<Locale> acceptedLanguages = FXCollections.observableArrayList();
final ObservableList<Arbitrator> acceptedArbitrators = FXCollections.observableArrayList();
///////////////////////////////////////////////////////////////////////////////////////////
@ -121,10 +128,20 @@ class CreateOfferModel extends UIModel {
super.initialized();
// static data
totalFeesAsCoin.set(FeePolicy.CREATE_OFFER_FEE.add(FeePolicy.TX_FEE));
offerFeeAsCoin.set(FeePolicy.CREATE_OFFER_FEE);
networkFeeAsCoin.set(FeePolicy.TX_FEE);
if (walletFacade != null && walletFacade.getWallet() != null)
if (walletFacade != null && walletFacade.getWallet() != null) {
addressEntry = walletFacade.getAddressInfoByTradeID(offerId);
walletFacade.addBalanceListener(new BalanceListener(addressEntry.getAddress()) {
@Override
public void onBalanceChanged(@NotNull Coin balance) {
updateBalance(balance);
}
});
updateBalance(walletFacade.getBalanceForAddress(addressEntry.getAddress()));
}
}
@Override
@ -136,6 +153,7 @@ class CreateOfferModel extends UIModel {
collateralAsLong.set(settings.getCollateral());
acceptedCountries.setAll(settings.getAcceptedCountries());
acceptedLanguages.setAll(settings.getAcceptedLanguageLocales());
acceptedArbitrators.setAll(settings.getAcceptedArbitrators());
}
if (user != null) {
@ -148,11 +166,13 @@ class CreateOfferModel extends UIModel {
}
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
@ -171,13 +191,10 @@ class CreateOfferModel extends UIModel {
amountAsCoin.get(),
minAmountAsCoin.get(),
(transaction) -> {
requestPlaceOfferSuccess.set(true);
transactionId.set(transaction.getHashAsString());
requestPlaceOfferSuccess.set(true);
},
(errorMessage) -> {
requestPlaceOfferFailed.set(true);
requestPlaceOfferErrorMessage.set(errorMessage);
}
(errorMessage) -> requestPlaceOfferErrorMessage.set(errorMessage)
);
}
@ -213,8 +230,9 @@ class CreateOfferModel extends UIModel {
void calculateTotalToPay() {
calculateCollateral();
try {
if (collateralAsCoin.get() != null)
totalToPayAsCoin.set(collateralAsCoin.get().add(totalFeesAsCoin.get()));
if (collateralAsCoin.get() != null) {
totalToPayAsCoin.set(offerFeeAsCoin.get().add(networkFeeAsCoin.get()).add(collateralAsCoin.get()));
}
} catch (Throwable t) {
// Should be never reached
log.error(t.toString());
@ -238,16 +256,21 @@ class CreateOfferModel extends UIModel {
///////////////////////////////////////////////////////////////////////////////////////////
boolean isMinAmountLessOrEqualAmount() {
//noinspection SimplifiableIfStatement
if (minAmountAsCoin.get() != null && amountAsCoin.get() != null)
return !minAmountAsCoin.get().isGreaterThan(amountAsCoin.get());
return true;
}
private void updateBalance(@NotNull Coin balance) {
isWalletFunded.set(totalToPayAsCoin.get() != null && balance.compareTo(totalToPayAsCoin.get()) >= 0);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Setter/Getter
///////////////////////////////////////////////////////////////////////////////////////////
@Nullable
Direction getDirection() {
return direction;
}

View file

@ -41,6 +41,8 @@ import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -50,8 +52,8 @@ import static javafx.beans.binding.Bindings.createStringBinding;
class CreateOfferPM extends PresentationModel<CreateOfferModel> {
private static final Logger log = LoggerFactory.getLogger(CreateOfferPM.class);
private BtcValidator btcValidator = new BtcValidator();
private FiatValidator fiatValidator = new FiatValidator();
private final BtcValidator btcValidator = new BtcValidator();
private final FiatValidator fiatValidator = new FiatValidator();
final StringProperty amount = new SimpleStringProperty();
final StringProperty minAmount = new SimpleStringProperty();
@ -61,25 +63,25 @@ class CreateOfferPM extends PresentationModel<CreateOfferModel> {
final StringProperty totalToPay = new SimpleStringProperty();
final StringProperty directionLabel = new SimpleStringProperty();
final StringProperty collateralLabel = new SimpleStringProperty();
final StringProperty totalFees = new SimpleStringProperty();
final StringProperty offerFee = new SimpleStringProperty();
final StringProperty networkFee = new SimpleStringProperty();
final StringProperty bankAccountType = new SimpleStringProperty();
final StringProperty bankAccountCurrency = new SimpleStringProperty();
final StringProperty bankAccountCounty = new SimpleStringProperty();
final StringProperty acceptedCountries = new SimpleStringProperty();
final StringProperty acceptedLanguages = new SimpleStringProperty();
final StringProperty acceptedArbitrators = new SimpleStringProperty();
final StringProperty addressAsString = new SimpleStringProperty();
final StringProperty paymentLabel = new SimpleStringProperty();
final StringProperty transactionId = new SimpleStringProperty();
final StringProperty requestPlaceOfferErrorMessage = new SimpleStringProperty();
final BooleanProperty isCloseButtonVisible = new SimpleBooleanProperty();
final BooleanProperty isPlaceOfferButtonVisible = new SimpleBooleanProperty(true);
final BooleanProperty isPlaceOfferButtonVisible = new SimpleBooleanProperty(false);
final BooleanProperty isPlaceOfferButtonDisabled = new SimpleBooleanProperty(true);
final BooleanProperty showWarningAdjustedVolume = new SimpleBooleanProperty();
final BooleanProperty showWarningInvalidFiatDecimalPlaces = new SimpleBooleanProperty();
final BooleanProperty showWarningInvalidBtcDecimalPlaces = new SimpleBooleanProperty();
final BooleanProperty showTransactionPublishedScreen = new SimpleBooleanProperty();
final BooleanProperty requestPlaceOfferFailed = new SimpleBooleanProperty();
final ObjectProperty<InputValidator.ValidationResult> amountValidationResult = new SimpleObjectProperty<>();
final ObjectProperty<InputValidator.ValidationResult> minAmountValidationResult = new SimpleObjectProperty<>();
@ -123,16 +125,19 @@ class CreateOfferPM extends PresentationModel<CreateOfferModel> {
setupListeners();
}
@SuppressWarnings("EmptyMethod")
@Override
public void activate() {
super.activate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
@ -144,9 +149,9 @@ class CreateOfferPM extends PresentationModel<CreateOfferModel> {
///////////////////////////////////////////////////////////////////////////////////////////
// setOrderBookFilter is a one time call
void setOrderBookFilter(OrderBookFilter orderBookFilter) {
void setOrderBookFilter(@NotNull OrderBookFilter orderBookFilter) {
model.setDirection(orderBookFilter.getDirection());
directionLabel.set(model.getDirection() == Direction.BUY ? "Buy:" : "Sell:");
directionLabel.set(model.getDirection() == Direction.BUY ? "Buy Bitcoin" : "Sell Bitcoin");
// apply only if valid
if (orderBookFilter.getAmount() != null && isBtcInputValid(orderBookFilter.getAmount().toPlainString())
@ -165,13 +170,12 @@ class CreateOfferPM extends PresentationModel<CreateOfferModel> {
// UI actions (called by CB)
///////////////////////////////////////////////////////////////////////////////////////////
void placeOffer() {
void onPlaceOffer() {
model.requestPlaceOfferErrorMessage.set(null);
model.requestPlaceOfferFailed.set(false);
model.requestPlaceOfferSuccess.set(false);
isPlaceOfferButtonDisabled.set(true);
isPlaceOfferButtonVisible.set(true);
// isPlaceOfferButtonVisible.set(true);
model.placeOffer();
}
@ -181,6 +185,10 @@ class CreateOfferPM extends PresentationModel<CreateOfferModel> {
// UI events (called by CB)
///////////////////////////////////////////////////////////////////////////////////////////
public void onShowPayFundsScreen() {
isPlaceOfferButtonVisible.set(true);
}
// On focus out we do validation and apply the data to the model
void onFocusOutAmountTextField(Boolean oldValue, Boolean newValue, String userInput) {
if (oldValue && !newValue) {
@ -318,6 +326,10 @@ class CreateOfferPM extends PresentationModel<CreateOfferModel> {
}
validateInput();
});
model.isWalletFunded.addListener((ov, oldValue, newValue) -> {
if (newValue)
validateInput();
});
// Binding with Bindings.createObjectBinding does not work because of bi-directional binding
model.amountAsCoin.addListener((ov, oldValue, newValue) -> amount.set(formatCoin(newValue)));
@ -325,9 +337,9 @@ class CreateOfferPM extends PresentationModel<CreateOfferModel> {
model.priceAsFiat.addListener((ov, oldValue, newValue) -> price.set(formatFiat(newValue)));
model.volumeAsFiat.addListener((ov, oldValue, newValue) -> volume.set(formatFiat(newValue)));
model.requestPlaceOfferFailed.addListener((ov, oldValue, newValue) -> {
isPlaceOfferButtonDisabled.set(!newValue);
requestPlaceOfferFailed.set(newValue);
model.requestPlaceOfferErrorMessage.addListener((ov, oldValue, newValue) -> {
if (newValue != null)
isPlaceOfferButtonDisabled.set(false);
});
model.requestPlaceOfferSuccess.addListener((ov, oldValue, newValue) -> isPlaceOfferButtonVisible.set
(!newValue));
@ -337,6 +349,8 @@ class CreateOfferPM extends PresentationModel<CreateOfferModel> {
.countryLocalesToString(model.acceptedCountries)));
model.acceptedLanguages.addListener((Observable o) -> acceptedLanguages.set(BSFormatter
.languageLocalesToString(model.acceptedLanguages)));
model.acceptedArbitrators.addListener((Observable o) -> acceptedArbitrators.set(BSFormatter
.arbitratorsToString(model.acceptedArbitrators)));
}
private void setupBindings() {
@ -349,16 +363,19 @@ class CreateOfferPM extends PresentationModel<CreateOfferModel> {
(model.collateralAsLong.get()) + "):", model.collateralAsLong));
totalToPayAsCoin.bind(model.totalToPayAsCoin);
totalFees.bind(createStringBinding(() -> formatCoinWithCode(model.totalFeesAsCoin.get()),
model.totalFeesAsCoin));
offerFee.bind(createStringBinding(() -> formatCoinWithCode(model.offerFeeAsCoin.get()),
model.offerFeeAsCoin));
networkFee.bind(createStringBinding(() -> formatCoinWithCode(model.networkFeeAsCoin.get()),
model.offerFeeAsCoin));
bankAccountType.bind(Bindings.createStringBinding(() -> Localisation.get(model.bankAccountType.get()),
model.bankAccountType));
bankAccountCurrency.bind(model.bankAccountCurrency);
bankAccountCounty.bind(model.bankAccountCounty);
isCloseButtonVisible.bind(model.requestPlaceOfferSuccess);
requestPlaceOfferErrorMessage.bind(model.requestPlaceOfferErrorMessage);
showTransactionPublishedScreen.bind(model.requestPlaceOfferSuccess);
transactionId.bind(model.transactionId);
}
private void calculateVolume() {
@ -406,7 +423,8 @@ class CreateOfferPM extends PresentationModel<CreateOfferModel> {
isBtcInputValid(minAmount.get()).isValid &&
isBtcInputValid(price.get()).isValid &&
isBtcInputValid(volume.get()).isValid &&
model.isMinAmountLessOrEqualAmount())
model.isMinAmountLessOrEqualAmount() &&
model.isWalletFunded.get())
);
}

View file

@ -19,157 +19,350 @@
<?import io.bitsquare.gui.components.btc.AddressTextField?>
<?import io.bitsquare.gui.components.btc.BalanceTextField?>
<?import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator?>
<?import io.bitsquare.gui.components.InputTextField?>
<?import io.bitsquare.gui.components.VSpacer?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<AnchorPane fx:id="root" fx:controller="io.bitsquare.gui.trade.createoffer.CreateOfferCB"
prefHeight="500" prefWidth="800" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0"
AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0"
AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0"
xmlns:fx="http://javafx.com/fxml">
<GridPane hgap="5.0" vgap="5.0" AnchorPane.leftAnchor="20.0" AnchorPane.rightAnchor="10.0"
AnchorPane.topAnchor="10.0">
<ScrollPane fx:id="scrollPane" hbarPolicy="NEVER" vbarPolicy="NEVER" fitToWidth="true" fitToHeight="true"
AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"
AnchorPane.bottomAnchor="0.0">
<!-- group -->
<VSpacer GridPane.rowIndex="0" prefHeight="20"/>
<Pane GridPane.rowIndex="1" GridPane.columnSpan="2" GridPane.rowSpan="2" id="form-group-border">
<GridPane.margin>
<Insets top="-10" right="-10" bottom="-10" left="-10"/>
</GridPane.margin>
<Label layoutX="8" layoutY="-8" text="Create your offer:" id="form-group-label">
<padding>
<Insets left="5" right="7"/>
</padding>
<GridPane hgap="5.0" vgap="5.0">
<padding>
<Insets bottom="-10.0" left="25.0" top="30.0" right="25"/>
</padding>
<!--
Amount/Price group
-->
<Pane fx:id="priceAmountPane" id="form-group-background-active" GridPane.columnSpan="3"
GridPane.rowSpan="3">
<GridPane.margin>
<Insets right="-10" bottom="-10" left="-10" top="-10"/>
</GridPane.margin>
<Label fx:id="priceAmountTitleLabel" id="form-group-title-active"
text="Create your offer" layoutX="8" layoutY="-8">
<padding>
<Insets left="5" right="7"/>
</padding>
</Label>
</Pane>
<VBox alignment="CENTER" spacing="6" GridPane.rowSpan="2">
<GridPane.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="20.0"/>
</GridPane.margin>
<ImageView fitHeight="54.0" fitWidth="62.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@/images/buy_62_54.png"/>
</image>
</ImageView>
<Label fx:id="buyLabel" id="direction-icon-label" text="Buy Bitcoins" alignment="CENTER">
<padding>
<Insets top="-5.0"/>
</padding>
</Label>
</VBox>
<HBox GridPane.columnIndex="1" alignment="CENTER_LEFT" spacing="5">
<GridPane.margin>
<Insets right="10.0" top="20.0"/>
</GridPane.margin>
<VBox spacing="4">
<children>
<Label id="input-description-label" text="Amount of Bitcoin to buy" prefWidth="170"/>
<HBox>
<children>
<InputTextField fx:id="amountTextField" id="text-input-with-currency-text-field"
promptText="Enter amount" prefWidth="170" alignment="CENTER_RIGHT"/>
<Label id="currency-info-label" text="BTC"/>
</children>
</HBox>
</children>
</VBox>
<Label text="x">
<font>
<Font name="Helvetica" size="20.0"/>
</font>
<padding>
<Insets top="14.0" left="3" right="3"/>
</padding>
</Label>
<VBox spacing="4">
<children>
<Label id="input-description-label" text="Price per Bitcoin in EUR" prefWidth="170"/>
<HBox>
<children>
<InputTextField fx:id="priceTextField" id="text-input-with-currency-text-field"
promptText="Enter price" prefWidth="170" alignment="CENTER_RIGHT"/>
<Label id="currency-info-label" text="EUR" alignment="CENTER"/>
</children>
</HBox>
</children>
</VBox>
<Label text="=">
<font>
<Font name="Helvetica" size="20.0"/>
</font>
<padding>
<Insets top="14.0" left="2" right="2"/>
</padding>
</Label>
<VBox spacing="4">
<children>
<Label id="input-description-label" text="Amount in EUR to spend" prefWidth="170"/>
<HBox>
<children>
<InputTextField fx:id="volumeTextField" id="text-input-with-currency-text-field"
promptText="Trade volume" prefWidth="170" alignment="CENTER_RIGHT"/>
<Label id="currency-info-label" text="EUR"/>
</children>
</HBox>
</children>
</VBox>
</HBox>
<VBox GridPane.columnIndex="1" GridPane.rowIndex="1" spacing="4">
<GridPane.margin>
<Insets right="10.0" top="5.0" bottom="5.0"/>
</GridPane.margin>
<Label id="input-description-label" text="Minimum amount of Bitcoin" prefWidth="170.0"/>
<HBox>
<children>
<InputTextField fx:id="minAmountTextField" id="text-input-with-currency-text-field"
promptText="Enter min. amount" alignment="CENTER_RIGHT" prefWidth="170.0"/>
<Label id="currency-info-label" text="BTC"/>
</children>
</HBox>
</VBox>
<ImageView GridPane.rowIndex="2" fitHeight="24.0" fitWidth="24.0" pickOnBounds="true" preserveRatio="true"
GridPane.valignment="TOP">
<GridPane.margin>
<Insets right="2.0" top="4.0"/>
</GridPane.margin>
<Image fx:id="infoIcon" url="@/images/info_44.png"/>
</ImageView>
<TextFlow GridPane.columnIndex="1" GridPane.rowIndex="2" prefWidth="740.0">
<Label prefWidth="740.0" wrapText="true"
text="With the minimum amount you can attract more potential traders with giving them more flexibility. But note that there is no automatic creation of a new offer for the remaining amount in the case that a trader takes your offer with a lower amount as defined in the amount field. Your offer will be removed from the orderbook once a trader has taken your offer.">
</Label>
<GridPane.margin>
<Insets bottom="5.0"/>
</GridPane.margin>
<Hyperlink text="Read more..." id="info-link" onAction="#onOpenGeneralHelp"/>
</TextFlow>
<Button fx:id="showPaymentInfoScreenButton" text="Next step" id="show-details-button"
GridPane.columnIndex="1" GridPane.rowIndex="3" defaultButton="true"
onAction="#onShowPayFundsScreen">
<GridPane.margin>
<Insets top="15.0"/>
</GridPane.margin>
</Button>
<!--
Pay funds group
-->
<Pane fx:id="payFundsPane" id="form-group-background-active" GridPane.columnSpan="3"
GridPane.rowIndex="4" GridPane.rowSpan="4" visible="false">
<GridPane.margin>
<Insets right="-10" bottom="-10" left="-10" top="-10"/>
</GridPane.margin>
<Label fx:id="payFundsTitleLabel" text="Fund your trade wallet" id="form-group-title-active"
layoutX="8" layoutY="-8">
<padding>
<Insets left="5" right="7"/>
</padding>
</Label>
</Pane>
<HBox GridPane.rowIndex="4" spacing="4" alignment="CENTER_RIGHT">
<Label fx:id="totalToPayLabel" text="Funds needed for that trade:" visible="false"/>
<Label fx:id="totalToPayInfoIconLabel" visible="false"/>
<GridPane.margin>
<Insets top="10.0"/>
</GridPane.margin>
</HBox>
<TextField fx:id="totalToPayTextField" GridPane.columnIndex="1" GridPane.rowIndex="4"
editable="false" focusTraversable="false" visible="false">
<GridPane.margin>
<Insets top="10.0"/>
</GridPane.margin>
</TextField>
<Label fx:id="addressLabel" text="Trade wallet address:" GridPane.rowIndex="5" visible="false"/>
<AddressTextField fx:id="addressTextField" GridPane.columnIndex="1" GridPane.rowIndex="5"
focusTraversable="true" visible="false"/>
<Label fx:id="balanceLabel" text="Trade wallet balance:" GridPane.rowIndex="6" visible="false">
<GridPane.margin>
<Insets bottom="5.0"/>
</GridPane.margin>
</Label>
</Pane>
<BalanceTextField fx:id="balanceTextField" GridPane.columnIndex="1" GridPane.rowIndex="6"
focusTraversable="false" visible="false">
<GridPane.margin>
<Insets bottom="5.0"/>
</GridPane.margin>
</BalanceTextField>
<Label GridPane.rowIndex="1" fx:id="buyLabel"/>
<HBox GridPane.rowIndex="1" GridPane.columnIndex="1" spacing="5" GridPane.hgrow="NEVER" alignment="CENTER_LEFT">
<InputTextField fx:id="amountTextField" prefWidth="100.0" alignment="CENTER_RIGHT"/>
<Label text="BTC for price of "/>
<InputTextField fx:id="priceTextField" prefWidth="100.0" alignment="CENTER_RIGHT"/>
<Label text="EUR/BTC ="/>
<InputTextField fx:id="volumeTextField" prefWidth="100.0" alignment="CENTER_RIGHT"/>
<Label text="EUR in total"/>
</HBox>
<ImageView fx:id="payFundsInfoIcon" GridPane.rowIndex="7" GridPane.valignment="TOP" fitHeight="24.0"
fitWidth="24.0" pickOnBounds="true" preserveRatio="true" visible="false">
<GridPane.margin>
<Insets right="2.0" top="4.0"/>
</GridPane.margin>
<fx:reference source="infoIcon"/>
</ImageView>
<Label GridPane.rowIndex="2" text="Min. Amount (BTC):"/>
<InputTextField GridPane.rowIndex="2" GridPane.columnIndex="1" fx:id="minAmountTextField"/>
<TextFlow fx:id="payFundsInfoTextFlow" GridPane.columnIndex="1" GridPane.rowIndex="7" prefWidth="740.0"
visible="false">
<Label prefWidth="740.0" wrapText="true"
text="For every offer there is a dedicated trade wallet. You need to fund that trade wallet with the necessary BTC amount. Those funds are reserved and will be used in the case that your offer gets executed. If you cancel your offer you can withdraw your funds from that trading wallet. The only payment which will be done now when placing the offer is the offer fee payment.">
</Label>
<Hyperlink text="Read more..." id="info-link" onAction="#onOpenFundingHelp"/>
<GridPane.margin>
<Insets bottom="5.0"/>
</GridPane.margin>
</TextFlow>
<HBox spacing="10" GridPane.columnIndex="1" GridPane.rowIndex="8">
<GridPane.margin>
<Insets bottom="20" top="20.0"/>
</GridPane.margin>
<Button fx:id="showAdvancedSettingsButton" text="Show advanced settings"
onAction="#onToggleShowAdvancedSettings" visible="false"/>
<Button fx:id="placeOfferButton" text="Place offer" visible="false" defaultButton="true"
onAction="#onPlaceOffer"/>
</HBox>
<!-- group -->
<VSpacer GridPane.rowIndex="3" prefHeight="40"/>
<Pane GridPane.rowIndex="4" GridPane.columnSpan="2" GridPane.rowSpan="3" id="form-group-border">
<GridPane.margin>
<Insets top="-10" right="-10" bottom="-10" left="-10"/>
</GridPane.margin>
<Label layoutX="8" layoutY="-8" text="Fill your trade pocket:" id="form-group-label">
<padding>
<Insets left="5" right="7"/>
</padding>
<!--
Advanced settings group
-->
<Pane fx:id="showDetailsPane" id="form-group-background-active" GridPane.columnSpan="3"
GridPane.rowIndex="9" GridPane.rowSpan="7" visible="false">
<GridPane.margin>
<Insets right="-10" bottom="-10" left="-10" top="-10"/>
</GridPane.margin>
<Label fx:id="showDetailsTitleLabel" text="Advanced settings" id="form-group-title-active" layoutX="8"
layoutY="-8">
<padding>
<Insets left="5" right="7"/>
</padding>
</Label>
</Pane>
<HBox GridPane.rowIndex="9" spacing="4" alignment="CENTER_RIGHT">
<Label fx:id="acceptedCountriesLabel" text="Accepted countries:" visible="false"/>
<Label fx:id="acceptedCountriesLabelIcon" visible="false"/>
<GridPane.margin>
<Insets top="0.0"/>
</GridPane.margin>
</HBox>
<TextField fx:id="acceptedCountriesTextField" GridPane.columnIndex="1" GridPane.rowIndex="9" visible="false"
editable="false" focusTraversable="false"/>
<HBox GridPane.rowIndex="10" spacing="4" alignment="CENTER_RIGHT">
<Label fx:id="acceptedLanguagesLabel" text="Accepted languages:" visible="false"/>
<Label fx:id="acceptedLanguagesLabelIcon" visible="false"/>
</HBox>
<TextField fx:id="acceptedLanguagesTextField" GridPane.columnIndex="1" GridPane.rowIndex="10"
editable="false" focusTraversable="false" visible="false"/>
<HBox GridPane.rowIndex="11" spacing="4" alignment="CENTER_RIGHT">
<Label fx:id="acceptedArbitratorsLabel" text="Accepted arbitrators:" visible="false"/>
<Label fx:id="acceptedArbitratorsLabelIcon" visible="false"/>
</HBox>
<TextField fx:id="acceptedArbitratorsTextField" GridPane.columnIndex="1" GridPane.rowIndex="11"
editable="false" focusTraversable="false" visible="false"/>
<Label fx:id="bankAccountTypeLabel" text="Fiat transfer type:" GridPane.rowIndex="12" visible="false"/>
<TextField fx:id="bankAccountTypeTextField" GridPane.columnIndex="1" GridPane.rowIndex="12" editable="false"
focusTraversable="false" visible="false"/>
<Label fx:id="bankAccountCurrencyLabel" text="Currency:" GridPane.rowIndex="13" visible="false"/>
<TextField fx:id="bankAccountCurrencyTextField" GridPane.rowIndex="13" GridPane.columnIndex="1"
editable="false" focusTraversable="false" visible="false"/>
<Label fx:id="bankAccountCountyLabel" text="County of Fiat account:" GridPane.rowIndex="14" visible="false">
<GridPane.margin>
<Insets bottom="5.0"/>
</GridPane.margin>
</Label>
</Pane>
<TextField fx:id="bankAccountCountyTextField" GridPane.rowIndex="14" GridPane.columnIndex="1"
editable="false" focusTraversable="false" visible="false">
<GridPane.margin>
<Insets bottom="5.0"/>
</GridPane.margin>
</TextField>
<Label GridPane.rowIndex="4" text="Funds needed for that trade:"/>
<TextField GridPane.rowIndex="4" GridPane.columnIndex="1" fx:id="totalToPayTextField" editable="false"
focusTraversable="false"/>
<ImageView fx:id="showDetailsInfoIcon" GridPane.rowIndex="15" fitHeight="24.0" fitWidth="24.0"
pickOnBounds="true" preserveRatio="true" visible="false" GridPane.valignment="TOP">
<GridPane.margin>
<Insets right="2.0" top="4.0"/>
</GridPane.margin>
<fx:reference source="infoIcon"/>
</ImageView>
<Label GridPane.rowIndex="5" text="BTC address for funding:"/>
<AddressTextField GridPane.rowIndex="5" GridPane.columnIndex="1" fx:id="addressTextField"
focusTraversable="false"/>
<Label GridPane.rowIndex="6" text="Current balance:"/>
<BalanceTextField GridPane.rowIndex="6" GridPane.columnIndex="1" fx:id="balanceTextField"
focusTraversable="false"/>
<!-- button -->
<VSpacer GridPane.rowIndex="7" prefHeight="10"/>
<Button GridPane.rowIndex="8" GridPane.columnIndex="1" fx:id="placeOfferButton" onAction="#onPlaceOffer"
disable="true" defaultButton="true" text="Place offer"/>
<Button GridPane.rowIndex="8" GridPane.columnIndex="1" fx:id="closeButton" onAction="#onClose" visible="false"
defaultButton="true" focusTraversable="false" text="Close"/>
<TextFlow fx:id="showDetailsInfoLabel" GridPane.columnIndex="1" GridPane.rowIndex="15" prefWidth="740.0"
visible="false">
<Label prefWidth="740.0" wrapText="true"
text="Your trading partners must fulfill your offer restrictions. You can edit the accepted countries, languages and arbitrators in the settings. The Fiat account details are used from your current selected Fiat account (if you have multiple Fiat accounts).">
</Label>
<Hyperlink text="Read more..." id="info-link" onAction="#onOpenAdvancedSettingsHelp"/>
<GridPane.margin>
<Insets bottom="5.0"/>
</GridPane.margin>
</TextFlow>
<!-- group -->
<VSpacer GridPane.rowIndex="9" prefHeight="30"/>
<Pane GridPane.rowIndex="10" GridPane.columnSpan="2" GridPane.rowSpan="2" id="form-group-border">
<GridPane.margin>
<Insets top="-10" right="-10" bottom="-10" left="-10"/>
</GridPane.margin>
<Label layoutX="8" layoutY="-8" text="Collateral and fees:" id="form-group-label">
<padding>
<Insets left="5" right="7"/>
</padding>
</Label>
</Pane>
<columnConstraints>
<ColumnConstraints halignment="RIGHT" hgrow="SOMETIMES" minWidth="200"/>
<ColumnConstraints hgrow="ALWAYS"/>
</columnConstraints>
<Label GridPane.rowIndex="10" fx:id="collateralLabel" text="Collateral:"/>
<TextField GridPane.rowIndex="10" GridPane.columnIndex="1" fx:id="collateralTextField" editable="false"
focusTraversable="false"/>
<rowConstraints>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
</rowConstraints>
<Label GridPane.rowIndex="11" text="Offer Fee + transaction fee:"/>
<TextField GridPane.rowIndex="11" fx:id="totalFeesTextField" editable="false" focusTraversable="false"
GridPane.columnIndex="1"/>
<!-- group -->
<VSpacer GridPane.rowIndex="12" prefHeight="40"/>
<Pane GridPane.rowIndex="13" GridPane.columnSpan="2" GridPane.rowSpan="5" id="form-group-border">
<GridPane.margin>
<Insets top="-10" right="-10" bottom="-10" left="-10"/>
</GridPane.margin>
<Label layoutX="8" layoutY="-8" text="Your trade details:" id="form-group-label">
<padding>
<Insets left="5" right="7"/>
</padding>
</Label>
</Pane>
<Label text="Bank account type:" GridPane.rowIndex="13"/>
<TextField fx:id="bankAccountTypeTextField" editable="false" focusTraversable="false" GridPane.columnIndex="1"
GridPane.rowIndex="13"/>
<Label text="Bank account currency:" GridPane.rowIndex="14"/>
<TextField fx:id="bankAccountCurrencyTextField" editable="false" focusTraversable="false"
GridPane.columnIndex="1" GridPane.rowIndex="14"/>
<Label text="Bank account county:" GridPane.rowIndex="15"/>
<TextField fx:id="bankAccountCountyTextField" editable="false" focusTraversable="false" GridPane.columnIndex="1"
GridPane.rowIndex="15"/>
<Label text="Accepted countries:" GridPane.rowIndex="16"/>
<TextField fx:id="acceptedCountriesTextField" editable="false" focusTraversable="false" GridPane.columnIndex="1"
GridPane.rowIndex="16"/>
<Label text="Accepted languages:" GridPane.rowIndex="17"/>
<TextField fx:id="acceptedLanguagesTextField" editable="false" focusTraversable="false" GridPane.columnIndex="1"
GridPane.rowIndex="17"/>
<!-- on placed offer screen -->
<Label fx:id="txTitleLabel" text="Transaction ID:" visible="false" GridPane.rowIndex="14"/>
<TextField fx:id="transactionIdTextField" visible="false" editable="false" focusTraversable="false"
GridPane.columnIndex="1" GridPane.rowIndex="14"/>
<ConfidenceProgressIndicator fx:id="progressIndicator" visible="false" focusTraversable="false" progress="0"
GridPane.columnIndex="2" GridPane.halignment="LEFT"
GridPane.rowIndex="14" GridPane.rowSpan="2" GridPane.valignment="TOP">
<GridPane.margin>
<Insets top="2.0"/>
</GridPane.margin>
</ConfidenceProgressIndicator>
<Label fx:id="confirmationLabel" text="Checking confirmations..." visible="false" GridPane.columnIndex="3"
GridPane.rowIndex="14"/>
<columnConstraints>
<ColumnConstraints halignment="RIGHT" hgrow="SOMETIMES"/>
<ColumnConstraints hgrow="ALWAYS" minWidth="400"/>
<ColumnConstraints hgrow="SOMETIMES" prefWidth="20.0" minWidth="20"/>
<ColumnConstraints hgrow="SOMETIMES"/>
</columnConstraints>
</GridPane>
</GridPane>
</ScrollPane>
</AnchorPane>

View file

@ -264,6 +264,19 @@ public class BSFormatter {
return result;
}
public static String arbitratorsToString(List<Arbitrator> arbitrators) {
String result = "";
int i = 0;
for (Arbitrator arbitrator : arbitrators) {
result += arbitrator.getName();
i++;
if (i < arbitrators.size()) {
result += ", ";
}
}
return result;
}
public static String languageLocalesToString(List<Locale> languageLocales) {
String result = "";
int i = 0;

View file

@ -46,6 +46,9 @@ public class ImageUtil {
public static final String SELL = "/images/sell.png";
public static final String REMOVE = "/images/removeOffer.png";
public static final String EXPAND = "/images/expand.png";
public static final String COLLAPSE = "/images/collapse.png";
public static Image getIconImage(String iconName) {
return new Image(ImageUtil.class.getResourceAsStream(iconName));
}

View file

@ -61,7 +61,7 @@ public class BroadCastOfferFeeTx {
});
} catch (InsufficientMoneyException e) {
faultHandler.onFault(
"Offer fee payment failed because there is insufficient money in the trade pocket.", e);
"Offer fee payment failed because there is insufficient money in the trade wallet.", e);
} catch (Throwable t) {
faultHandler.onFault("Offer fee payment failed because an exception occurred.", t);
}

View file

@ -34,7 +34,7 @@ public class CreateOfferFeeTx {
try {
resultHandler.onResult(walletFacade.createOfferFeeTx(offerId));
} catch (InsufficientMoneyException e) {
faultHandler.onFault("Offer fee payment failed because there is insufficient money in the trade pocket. " +
faultHandler.onFault("Offer fee payment failed because there is insufficient money in the trade wallet. " +
"", e);
} catch (Throwable t) {
faultHandler.onFault("Offer fee payment failed because of an exception occurred. ", t);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 888 B

View file

@ -1,3 +1,20 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.settings.uimock;
import io.bitsquare.di.BitSquareModule;

View file

@ -1,3 +1,20 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.settings.uimock;
import io.bitsquare.di.BitSquareModule;

View file

@ -1,8 +1,24 @@
package io.bitsquare;
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.trade.createoffer;
import io.bitsquare.di.BitSquareModule;
import io.bitsquare.di.GuiceFXMLLoader;
import io.bitsquare.gui.NavigationItem;
import com.google.inject.Guice;
import com.google.inject.Injector;
@ -27,7 +43,7 @@ import org.slf4j.LoggerFactory;
public class UITestRunner extends Application {
private static final Logger log = LoggerFactory.getLogger(UITestRunner.class);
private Scene scene;
private Parent view;
private Pane view;
private Pane pane;
private boolean devTest = true;
@ -41,7 +57,7 @@ public class UITestRunner extends Application {
GuiceFXMLLoader.setInjector(injector);
pane = new StackPane();
scene = new Scene(pane, 1000, 750);
scene = new Scene(pane, 1000, 630);
scene.getAccelerators().put(KeyCombination.valueOf("Shortcut+S"), this::loadMainWindow);
loadMainWindow();
primaryStage.setScene(scene);
@ -51,10 +67,8 @@ public class UITestRunner extends Application {
public void loadMainWindow() {
log.debug("re load");
pane.getChildren().removeAll();
GuiceFXMLLoader loader = new GuiceFXMLLoader(getUrl(NavigationItem.CREATE_OFFER.getFxmlUrl()), false);
// GuiceFXMLLoader loader = new GuiceFXMLLoader(getUrl("/io/bitsquare/gui/trade/createoffer/CreateOfferView
// .fxml"), false);
GuiceFXMLLoader loader = new GuiceFXMLLoader(
getUrl("/io/bitsquare/gui/trade/createoffer/CreateOfferView.fxml"), false);
try {
view = loader.load();
} catch (IOException e) {
@ -84,6 +98,4 @@ public class UITestRunner extends Application {
return getClass().getResource(subPath);
}
}
}

View file

@ -37,12 +37,10 @@ import org.slf4j.LoggerFactory;
public class CreateOfferControllerUIMock implements Initializable {
private static final Logger log = LoggerFactory.getLogger(CreateOfferControllerUIMock.class);
public VBox priceAmountMinAmountBox;
public HBox priceAmountHBox;
public VBox priceAmountBuyIconBox;
@FXML private GridPane gridPane;
@FXML private VBox priceAmountMinAmountBox, priceAmountBuyIconBox;
@FXML private HBox priceAmountHBox;
@FXML private ImageView priceAmountInfoIcon, payFundsInfoIcon, paymentInfoIcon, showDetailsInfoIcon;
@FXML private Separator totalsSeparator;
@ -53,6 +51,7 @@ public class CreateOfferControllerUIMock implements Initializable {
showDetailsTitleLabel, bankAccountTypeLabel, bankAccountCurrencyLabel, bankAccountCountyLabel,
acceptedCountriesLabel, acceptedLanguagesLabel, acceptedArbitratorsLabel, showDetailsInfoLabel;
@FXML private Button showPaymentInfoScreenButton, showPayFundsScreenButton, showDetailsButton;
@FXML private TextField offerFeeTextField, networkFeeTextField, acceptedArbitratorsTextField;
@FXML private TextField addressTextField;
@FXML private TextField balanceTextField;
@ -208,18 +207,6 @@ public class CreateOfferControllerUIMock implements Initializable {
showDetailsInfoIcon.setVisible(true);
showDetailsInfoLabel.setVisible(true);
}
@FXML
private void showAdvancedScreen() {
}
@FXML
private void showSummaryScreen() {
}

View file

@ -1,3 +1,20 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.trade.createoffer.uimock;
import io.bitsquare.di.BitSquareModule;
@ -40,7 +57,7 @@ public class CreateOfferUIMockRunner extends Application {
GuiceFXMLLoader.setInjector(injector);
pane = new StackPane();
scene = new Scene(pane, 1000, 1200);
scene = new Scene(pane, 1000, 630);
scene.getAccelerators().put(KeyCombination.valueOf("Shortcut+S"), this::loadMainWindow);
loadMainWindow();
primaryStage.setScene(scene);

View file

@ -22,406 +22,364 @@
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<AnchorPane fx:id="root" prefHeight="1500.0" prefWidth="1000.0" style="-fx-background-color: f4f4f4;"
<AnchorPane fx:id="root" prefHeight="630.0" prefWidth="1000.0" style="-fx-background-color: f4f4f4;"
stylesheets="@../../../../../../../../main/java/io/bitsquare/gui/bitsquare.css"
AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0"
AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0" xmlns="http://javafx.com/javafx/8"
xmlns:fx="http://javafx.com/fxml/1"
AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0"
AnchorPane.topAnchor="10.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="io.bitsquare.gui.trade.createoffer.uimock.CreateOfferControllerUIMock">
<children>
<GridPane fx:id="gridPane" hgap="5.0" vgap="5.0" AnchorPane.leftAnchor="20.0" AnchorPane.rightAnchor="20.0"
AnchorPane.topAnchor="40.0">
<children>
<Pane id="form-group-background-active" fx:id="priceAmountPane" GridPane.columnSpan="3"
GridPane.rowSpan="3">
<GridPane.margin>
<Insets bottom="-10" left="-10" right="-10" top="-10"/>
</GridPane.margin>
<ScrollPane fitToHeight="true" fitToWidth="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<content>
<GridPane fx:id="gridPane" hgap="5.0" vgap="5.0">
<children>
<Label id="form-group-title-active" fx:id="priceAmountTitleLabel" layoutX="8" layoutY="-8"
text="Create your offer">
<padding>
<Insets left="5" right="7"/>
</padding>
</Label>
</children>
</Pane>
<VBox fx:id="priceAmountBuyIconBox" alignment="CENTER" spacing="6" GridPane.rowSpan="2">
<children>
<ImageView fitHeight="54.0" fitWidth="62.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../../../../../../../../main/resources/images/buy_black_62_54.png"/>
</image>
</ImageView>
<Label fx:id="buyLabel" alignment="CENTER" style="-fx-font-weight:bold; -fx-font-size:16;"
text="Buy Bitcoins" textAlignment="CENTER">
<padding>
<Insets top="-5.0"/>
</padding>
</Label>
</children>
<GridPane.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="20.0"/>
</GridPane.margin>
</VBox>
<HBox fx:id="priceAmountHBox" alignment="CENTER_LEFT" spacing="5" GridPane.columnIndex="1"
GridPane.columnSpan="2">
<children>
<VBox spacing="4">
<Pane id="form-group-background-active" fx:id="priceAmountPane" GridPane.columnSpan="3"
GridPane.rowSpan="3">
<GridPane.margin>
<Insets bottom="-10" left="-10" right="-10" top="-10"/>
</GridPane.margin>
<children>
<Label id="input-description-label" prefWidth="200.0" text="Amount of Bitcoin to buy:"/>
<Label id="form-group-title-active" fx:id="priceAmountTitleLabel" layoutX="8"
layoutY="-8" text="Create your offer">
<padding>
<Insets left="5" right="7"/>
</padding>
</Label>
</children>
</Pane>
<VBox fx:id="priceAmountBuyIconBox" alignment="CENTER" spacing="6" GridPane.rowSpan="2">
<children>
<ImageView fitHeight="54.0" fitWidth="62.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../../../../../../../../main/resources/images/buy_black_62_54.png"/>
</image>
</ImageView>
<Label fx:id="buyLabel" alignment="CENTER"
style="-fx-font-weight:bold; -fx-font-size:16;" text="Buy Bitcoins"
textAlignment="CENTER">
<padding>
<Insets top="-5.0"/>
</padding>
</Label>
</children>
<GridPane.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="20.0"/>
</GridPane.margin>
</VBox>
<HBox fx:id="priceAmountHBox" alignment="CENTER_LEFT" spacing="5" GridPane.columnIndex="1"
GridPane.columnSpan="2">
<children>
<VBox spacing="4">
<children>
<Label id="input-description-label" prefWidth="200.0"
text="Amount of Bitcoin to buy:"/>
<HBox>
<children>
<TextField id="text-input-with-currency-text-field"
fx:id="amountTextField" alignment="CENTER_RIGHT"
prefWidth="200.0" text="1.00"/>
<Label id="currency-info-label" text="BTC"/>
</children>
</HBox>
</children>
</VBox>
<Label text="x">
<font>
<Font name="Helvetica" size="20.0"/>
</font>
<padding>
<Insets top="14.0"/>
</padding>
</Label>
<VBox spacing="4">
<children>
<Label id="input-description-label" prefWidth="200.0"
text="Price per Bitcoin in EUR:"/>
<HBox>
<children>
<TextField id="text-input-with-currency-text-field"
fx:id="priceTextField" alignment="CENTER_RIGHT"
prefWidth="200.0" text="500.00"/>
<Label id="currency-info-label" text="EUR"/>
</children>
</HBox>
</children>
</VBox>
<Label text="=">
<font>
<Font name="Helvetica" size="20.0"/>
</font>
<padding>
<Insets top="14.0"/>
</padding>
</Label>
<VBox spacing="4">
<children>
<Label id="input-description-label" prefWidth="200.0"
text="Amount in EUR to spend:"/>
<HBox>
<children>
<TextField id="text-input-with-currency-text-field"
fx:id="volumeTextField" alignment="CENTER_RIGHT"
prefWidth="200.0" text="500.00"/>
<Label id="currency-info-label" text="EUR"/>
</children>
</HBox>
</children>
</VBox>
</children>
<GridPane.margin>
<Insets right="10.0" top="20.0"/>
</GridPane.margin>
</HBox>
<VBox fx:id="priceAmountMinAmountBox" spacing="4" GridPane.columnIndex="1"
GridPane.columnSpan="2" GridPane.rowIndex="1">
<children>
<Label id="input-description-label" prefWidth="200.0"
text="Minimum amount of Bitcoin:"/>
<HBox>
<children>
<TextField id="text-input-with-currency-text-field" fx:id="amountTextField"
alignment="CENTER_RIGHT" prefWidth="200.0" text="1.00"/>
<TextField id="text-input-with-currency-text-field" fx:id="minAmountTextField"
alignment="CENTER_RIGHT" prefWidth="200.0" text="0.10"/>
<Label id="currency-info-label" text="BTC"/>
</children>
</HBox>
</children>
<GridPane.margin>
<Insets right="10.0" top="5.0"/>
</GridPane.margin>
</VBox>
<Label text="x">
<font>
<Font name="Helvetica" size="20.0"/>
</font>
<padding>
<Insets top="14.0"/>
</padding>
<ImageView fx:id="priceAmountInfoIcon" fitHeight="24.0" fitWidth="24.0" pickOnBounds="true"
preserveRatio="true" GridPane.rowIndex="2" GridPane.valignment="TOP">
<image>
<Image fx:id="infoIcon"
url="@../../../../../../../../main/resources/images/info_44.png"/>
</image>
<GridPane.margin>
<Insets right="2.0" top="4.0"/>
</GridPane.margin>
</ImageView>
<Label fx:id="priceAmountInfoLabel" prefWidth="740.0"
text="With the minimum amount you can attract more potential traders with giving more flexibility. Your offer will be removed when it got executed. There is no automatic offer creation for the remaining amount. Open the help menu for more information."
wrapText="true" GridPane.columnIndex="1" GridPane.rowIndex="2">
<GridPane.margin>
<Insets bottom="5.0"/>
</GridPane.margin>
</Label>
<VBox spacing="4">
<children>
<Label id="input-description-label" prefWidth="200.0" text="Price per Bitcoin in EUR:"/>
<HBox>
<children>
<TextField id="text-input-with-currency-text-field" fx:id="priceTextField"
alignment="CENTER_RIGHT" prefWidth="200.0" text="500.00"/>
<Label id="currency-info-label" text="EUR"/>
</children>
</HBox>
</children>
</VBox>
<Button fx:id="showPaymentInfoScreenButton" defaultButton="true"
onAction="#showPaymentInfoScreen" text="Next step" visible="true"
GridPane.columnIndex="1" GridPane.rowIndex="3">
<GridPane.margin>
<Insets top="15.0"/>
</GridPane.margin>
</Button>
<Label text="=">
<font>
<Font name="Helvetica" size="20.0"/>
</font>
<padding>
<Insets top="14.0"/>
</padding>
<!--
pay funds
-->
<Pane id="form-group-background-active" fx:id="payFundsPane" visible="true"
GridPane.columnSpan="3" GridPane.rowIndex="11" GridPane.rowSpan="4">
<GridPane.margin>
<Insets bottom="-10.0" left="-10.0" right="-10.0" top="-10.0"/>
</GridPane.margin>
<children>
<Label id="form-group-title-active" fx:id="payFundsTitleLabel" layoutX="8" layoutY="-8"
text="Fund your trade wallet">
<padding>
<Insets left="5" right="7"/>
</padding>
</Label>
</children>
</Pane>
<Label fx:id="totalToPayLabel" text="Funds needed for that trade:" visible="true"
GridPane.rowIndex="11">
<GridPane.margin>
<Insets top="10.0"/>
</GridPane.margin>
</Label>
<TextField fx:id="totalToPayTextField" editable="false" focusTraversable="false"
text="0.111 BTC" visible="true" GridPane.columnIndex="1" GridPane.columnSpan="2"
GridPane.rowIndex="11">
<GridPane.margin>
<Insets top="10.0"/>
</GridPane.margin>
</TextField>
<Label fx:id="addressLabel" text="Trading wallet BTC address:" visible="true"
GridPane.rowIndex="12"/>
<TextField fx:id="addressTextField" editable="false" focusTraversable="false"
text="mkpymjfTk7WmG9YC4N9c9h1UzwPvMX3aNG" visible="true" GridPane.columnIndex="1"
GridPane.columnSpan="2" GridPane.rowIndex="12"/>
<Label fx:id="balanceLabel" text="Trading wallet balance:" visible="true"
GridPane.rowIndex="13"/>
<TextField fx:id="balanceTextField" editable="false" focusTraversable="false" text="0.00 BTC"
visible="true" GridPane.columnIndex="1" GridPane.columnSpan="2"
GridPane.rowIndex="13">
<GridPane.margin>
<Insets bottom="5.0"/>
</GridPane.margin>
</TextField>
<ImageView fx:id="payFundsInfoIcon" fitHeight="24.0" fitWidth="24.0" pickOnBounds="true"
preserveRatio="true" visible="true" GridPane.rowIndex="14" GridPane.valignment="TOP">
<image>
<fx:reference source="infoIcon"/>
</image>
<GridPane.margin>
<Insets right="2.0" top="4.0"/>
</GridPane.margin>
</ImageView>
<Label fx:id="payFundsInfoLabel" prefWidth="740.0"
text="You need to pay in the funds needed to your trade wallet. The fund will be reserved for the case that your offer get executed when accepted by a trader. If you cancel your offer you can withdraw your funds from that trading wallet. The only payment which will be done when placing the offer is the offer fee payment. Open the help menu for more information."
visible="true" wrapText="true" GridPane.columnIndex="1" GridPane.rowIndex="14">
<GridPane.margin>
<Insets bottom="5.0"/>
</GridPane.margin>
</Label>
<VBox spacing="4">
<HBox spacing="10" GridPane.columnIndex="1" GridPane.rowIndex="15">
<GridPane.margin>
<Insets bottom="30" top="20.0"/>
</GridPane.margin>
<children>
<Label id="input-description-label" prefWidth="200.0" text="Amount in EUR to spend:"/>
<HBox>
<children>
<TextField id="text-input-with-currency-text-field" fx:id="volumeTextField"
alignment="CENTER_RIGHT" prefWidth="200.0" text="500.00"/>
<Label id="currency-info-label" text="EUR"/>
</children>
</HBox>
</children>
</VBox>
</children>
<GridPane.margin>
<Insets right="10.0" top="20.0"/>
</GridPane.margin>
</HBox>
<VBox fx:id="priceAmountMinAmountBox" spacing="4" GridPane.columnIndex="1" GridPane.columnSpan="2"
GridPane.rowIndex="1">
<children>
<Label id="input-description-label" prefWidth="200.0" text="Minimum amount of Bitcoin:"/>
<HBox>
<children>
<TextField id="text-input-with-currency-text-field" fx:id="minAmountTextField"
alignment="CENTER_RIGHT" prefWidth="200.0" text="0.10"/>
<Label id="currency-info-label" text="BTC"/>
<Button fx:id="showDetailsButton" defaultButton="true" onAction="#showDetailsScreen"
text="Show offer restrictions" visible="true"/>
<Button fx:id="placeOfferButton" defaultButton="true" text="Place offer"
visible="true"/>
</children>
</HBox>
</children>
<GridPane.margin>
<Insets right="10.0" top="5.0"/>
</GridPane.margin>
</VBox>
<ImageView fx:id="priceAmountInfoIcon" fitHeight="24.0" fitWidth="24.0" pickOnBounds="true"
preserveRatio="true" GridPane.rowIndex="2" GridPane.valignment="TOP">
<image>
<Image fx:id="infoIcon" url="@../../../../../../../../main/resources/images/info_44.png"/>
</image>
<GridPane.margin>
<Insets right="2.0" top="4.0"/>
</GridPane.margin>
</ImageView>
<Label fx:id="priceAmountInfoLabel" prefWidth="740.0"
text="With the minimum amount you can attract more potential traders with giving more flexibility. Your offer will be removed when it got executed. There is no automatic offer creation for the remaining amount. Open the help menu for more information."
wrapText="true" GridPane.columnIndex="1" GridPane.rowIndex="2">
<GridPane.margin>
<Insets bottom="5.0"/>
</GridPane.margin>
</Label>
<!--
payment bank details screen
-->
<Pane id="form-group-background-active" fx:id="showDetailsPane" visible="true"
GridPane.columnSpan="3" GridPane.rowIndex="16" GridPane.rowSpan="7">
<GridPane.margin>
<Insets bottom="-10" left="-10" right="-10" top="-10"/>
</GridPane.margin>
<children>
<Label id="form-group-title-active" fx:id="showDetailsTitleLabel" layoutX="8"
layoutY="-8" text="Offer restrictions">
<padding>
<Insets left="5" right="7"/>
</padding>
</Label>
</children>
</Pane>
<Button fx:id="showPaymentInfoScreenButton" defaultButton="true" onAction="#showPaymentInfoScreen"
text="Next step" visible="true" GridPane.columnIndex="1" GridPane.rowIndex="3">
<GridPane.margin>
<Insets top="15.0"/>
</GridPane.margin>
</Button>
<!--
payment info
-->
<Pane id="form-group-background-active" fx:id="paymentInfoPane" visible="true" GridPane.columnSpan="3"
GridPane.rowIndex="4" GridPane.rowSpan="6">
<GridPane.margin>
<Insets bottom="-10" left="-10" right="-10" top="-10"/>
</GridPane.margin>
<children>
<Label id="form-group-title-active" fx:id="paymentInfoTitleLabel" layoutX="8" layoutY="-8"
text="Funding information">
<padding>
<Insets left="5" right="7"/>
</padding>
<Label fx:id="acceptedCountriesLabel" text="Accepted countries:" visible="true"
GridPane.rowIndex="16"/>
<TextField fx:id="acceptedCountriesTextField" editable="false" focusTraversable="false"
text="Spain, Austria, Germany" visible="true" GridPane.columnIndex="1"
GridPane.columnSpan="2" GridPane.rowIndex="16"/>
<Label fx:id="acceptedLanguagesLabel" text="Accepted languages:" visible="true"
GridPane.rowIndex="17"/>
<TextField fx:id="acceptedLanguagesTextField" editable="false" focusTraversable="false"
text="English, German, Spanish" visible="true" GridPane.columnIndex="1"
GridPane.columnSpan="2" GridPane.rowIndex="17"/>
<Label fx:id="acceptedArbitratorsLabel" text="Accepted arbitrators:" visible="true"
GridPane.rowIndex="18"/>
<TextField fx:id="acceptedArbitratorsTextField" editable="false" focusTraversable="false"
text="Manfred Karrer, okapacific, Adam Gibson" visible="true"
GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="18"/>
<Label fx:id="bankAccountTypeLabel" text="Bank account type:" visible="true"
GridPane.rowIndex="19"/>
<TextField fx:id="bankAccountTypeTextField" editable="false" focusTraversable="false"
text="Sepa" visible="true" GridPane.columnIndex="1" GridPane.columnSpan="2"
GridPane.rowIndex="19"/>
<Label fx:id="bankAccountCurrencyLabel" text="Bank account currency:" visible="true"
GridPane.rowIndex="20"/>
<TextField fx:id="bankAccountCurrencyTextField" editable="false" focusTraversable="false"
text="EUR" visible="true" GridPane.columnIndex="1" GridPane.columnSpan="2"
GridPane.rowIndex="20"/>
<Label fx:id="bankAccountCountyLabel" text="Bank account county:" visible="true"
GridPane.rowIndex="21"/>
<TextField fx:id="bankAccountCountyTextField" editable="false" focusTraversable="false"
text="Spain" visible="true" GridPane.columnIndex="1" GridPane.columnSpan="2"
GridPane.rowIndex="21"/>
<ImageView fx:id="showDetailsInfoIcon" fitHeight="24.0" fitWidth="24.0" pickOnBounds="true"
preserveRatio="true" visible="true" GridPane.rowIndex="22" GridPane.valignment="TOP">
<image>
<fx:reference source="infoIcon"/>
</image>
<GridPane.margin>
<Insets right="2.0" top="4.0"/>
</GridPane.margin>
</ImageView>
<Label fx:id="showDetailsInfoLabel" prefWidth="740.0"
text="Your trading partners must fulfill your offer restrictions. You can edit the accepted countries, languages and arbitrators in the settings. The bank account details are used from your current selected bank account (if you have multiple bank accounts). Open the help menu for more information."
visible="true" wrapText="true" GridPane.columnIndex="1" GridPane.rowIndex="22">
<GridPane.margin>
<Insets bottom="5.0"/>
</GridPane.margin>
</Label>
</children>
</Pane>
<Label fx:id="collateralLabel" text="Collateral:" visible="true" GridPane.rowIndex="4"/>
<TextField fx:id="collateralTextField" editable="false" focusTraversable="false" text="0.01 BTC"
visible="true" GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="4"/>
<columnConstraints>
<ColumnConstraints halignment="RIGHT" hgrow="SOMETIMES"/>
<ColumnConstraints hgrow="ALWAYS"/>
<ColumnConstraints hgrow="NEVER" prefWidth="25.0"/>
</columnConstraints>
<rowConstraints>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints minHeight="10.0" prefHeight="30.0"/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints minHeight="10.0" prefHeight="30.0"/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
</rowConstraints>
<opaqueInsets>
<Insets/>
</opaqueInsets>
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="40.0"/>
</padding>
<Label fx:id="offerFeeLabel" text="Offer fee:" visible="true" GridPane.rowIndex="5"/>
<TextField fx:id="offerFeeTextField" editable="false" focusTraversable="false" text="0.001 BTC"
visible="true" GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="5"/>
<Label fx:id="networkFeeLabel" text="Bitcoin network fee:" visible="true" GridPane.rowIndex="6"/>
<TextField fx:id="networkFeeTextField" editable="false" focusTraversable="false" text="0.0001 BTC"
visible="true" GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="6"/>
<Separator fx:id="totalsSeparator" maxWidth="100" orientation="HORIZONTAL" visible="true"
GridPane.columnIndex="1" GridPane.rowIndex="7">
<GridPane.margin>
<Insets bottom="-2"/>
</GridPane.margin>
</Separator>
<Label fx:id="summaryBtcLabel" text="Total funds needed:" visible="true"
GridPane.rowIndex="8"/>
<TextField fx:id="summaryBtcTextField" editable="false" focusTraversable="false" text="0.0111 BTC"
visible="true" GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="8"/>
<ImageView fx:id="paymentInfoIcon" fitHeight="24.0" fitWidth="24.0" pickOnBounds="true"
preserveRatio="true" visible="true" GridPane.rowIndex="9" GridPane.valignment="TOP">
<image>
<fx:reference source="infoIcon"/>
</image>
<GridPane.margin>
<Insets right="2.0" top="4.0"/>
</GridPane.margin>
</ImageView>
<Label fx:id="paymentInfoLabel" prefWidth="740.0"
text="The collateral helps to protect the trade process. It will be returned after a successful trade to your wallet. The offer fee will be used to support the arbitration system and the project. Open the help menu for more information."
visible="true" wrapText="true" GridPane.columnIndex="1" GridPane.rowIndex="9">
<GridPane.margin>
<Insets bottom="5.0"/>
</GridPane.margin>
</Label>
<Button fx:id="showPayFundsScreenButton" defaultButton="true" onAction="#showPayFundsScreen"
text="Continue" visible="true" GridPane.columnIndex="1" GridPane.rowIndex="10">
<GridPane.margin>
<Insets top="20.0"/>
</GridPane.margin>
</Button>
<!--
pay funds
-->
<Pane id="form-group-background-active" fx:id="payFundsPane" visible="true" GridPane.columnSpan="3"
GridPane.rowIndex="11" GridPane.rowSpan="4">
<GridPane.margin>
<Insets bottom="-10.0" left="-10.0" right="-10.0" top="-10.0"/>
</GridPane.margin>
<children>
<Label id="form-group-title-active" fx:id="payFundsTitleLabel" layoutX="8" layoutY="-8"
text="Fund your trade wallet">
<padding>
<Insets left="5" right="7"/>
</padding>
</Label>
</children>
</Pane>
<Label fx:id="totalToPayLabel" text="Funds needed for that trade:" visible="true"
GridPane.rowIndex="11">
<GridPane.margin>
<Insets top="10.0"/>
</GridPane.margin>
</Label>
<TextField fx:id="totalToPayTextField" editable="false" focusTraversable="false" text="0.111 BTC"
visible="true" GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="11">
<GridPane.margin>
<Insets top="10.0"/>
</GridPane.margin>
</TextField>
<Label fx:id="addressLabel" text="Trading wallet BTC address:" visible="true" GridPane.rowIndex="12"/>
<TextField fx:id="addressTextField" editable="false" focusTraversable="false"
text="mkpymjfTk7WmG9YC4N9c9h1UzwPvMX3aNG" visible="true" GridPane.columnIndex="1"
GridPane.columnSpan="2" GridPane.rowIndex="12"/>
<Label fx:id="balanceLabel" text="Trading wallet balance:" visible="true" GridPane.rowIndex="13"/>
<TextField fx:id="balanceTextField" editable="false" focusTraversable="false" text="0.00 BTC"
visible="true" GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="13">
<GridPane.margin>
<Insets bottom="5.0"/>
</GridPane.margin>
</TextField>
<ImageView fx:id="payFundsInfoIcon" fitHeight="24.0" fitWidth="24.0" pickOnBounds="true"
preserveRatio="true" visible="true" GridPane.rowIndex="14" GridPane.valignment="TOP">
<image>
<fx:reference source="infoIcon"/>
</image>
<GridPane.margin>
<Insets right="2.0" top="4.0"/>
</GridPane.margin>
</ImageView>
<Label fx:id="payFundsInfoLabel" prefWidth="740.0"
text="You need to pay in the funds needed to your trade wallet. The fund will be reserved for the case that your offer get executed when accepted by a trader. If you cancel your offer you can withdraw your funds from that trading wallet. The only payment which will be done when placing the offer is the offer fee payment. Open the help menu for more information."
visible="true" wrapText="true" GridPane.columnIndex="1" GridPane.rowIndex="14">
<GridPane.margin>
<Insets bottom="5.0"/>
</GridPane.margin>
</Label>
<HBox spacing="10" GridPane.columnIndex="1" GridPane.rowIndex="15">
<GridPane.margin>
<Insets bottom="30" top="20.0"/>
</GridPane.margin>
<children>
<Button fx:id="showDetailsButton" defaultButton="true" onAction="#showDetailsScreen"
text="Show offer restrictions" visible="true"/>
<Button fx:id="placeOfferButton" defaultButton="true" text="Place offer" visible="true"/>
</children>
</HBox>
<!--
payment bank details screen
-->
<Pane id="form-group-background-active" fx:id="showDetailsPane" visible="true" GridPane.columnSpan="3"
GridPane.rowIndex="16" GridPane.rowSpan="7">
<GridPane.margin>
<Insets bottom="-10" left="-10" right="-10" top="-10"/>
</GridPane.margin>
<children>
<Label id="form-group-title-active" fx:id="showDetailsTitleLabel" layoutX="8" layoutY="-8"
text="Offer restrictions">
<padding>
<Insets left="5" right="7"/>
</padding>
</Label>
</children>
</Pane>
<Label fx:id="acceptedCountriesLabel" text="Accepted countries:" visible="true"
GridPane.rowIndex="16"/>
<TextField fx:id="acceptedCountriesTextField" editable="false" focusTraversable="false"
text="Spain, Austria, Germany" visible="true" GridPane.columnIndex="1"
GridPane.columnSpan="2" GridPane.rowIndex="16"/>
<Label fx:id="acceptedLanguagesLabel" text="Accepted languages:" visible="true"
GridPane.rowIndex="17"/>
<TextField fx:id="acceptedLanguagesTextField" editable="false" focusTraversable="false"
text="English, German, Spanish" visible="true" GridPane.columnIndex="1"
GridPane.columnSpan="2" GridPane.rowIndex="17"/>
<Label fx:id="acceptedArbitratorsLabel" text="Accepted arbitrators:" visible="true"
GridPane.rowIndex="18"/>
<TextField fx:id="acceptedArbitratorsTextField" editable="false" focusTraversable="false"
text="Manfred Karrer, okapacific, Adam Gibson" visible="true" GridPane.columnIndex="1"
GridPane.columnSpan="2" GridPane.rowIndex="18"/>
<Label fx:id="bankAccountTypeLabel" text="Bank account type:" visible="true" GridPane.rowIndex="19"/>
<TextField fx:id="bankAccountTypeTextField" editable="false" focusTraversable="false" text="Sepa"
visible="true" GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="19"/>
<Label fx:id="bankAccountCurrencyLabel" text="Bank account currency:" visible="true"
GridPane.rowIndex="20"/>
<TextField fx:id="bankAccountCurrencyTextField" editable="false" focusTraversable="false" text="EUR"
visible="true" GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="20"/>
<Label fx:id="bankAccountCountyLabel" text="Bank account county:" visible="true"
GridPane.rowIndex="21"/>
<TextField fx:id="bankAccountCountyTextField" editable="false" focusTraversable="false" text="Spain"
visible="true" GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="21"/>
<ImageView fx:id="showDetailsInfoIcon" fitHeight="24.0" fitWidth="24.0" pickOnBounds="true"
preserveRatio="true" visible="true" GridPane.rowIndex="22" GridPane.valignment="TOP">
<image>
<fx:reference source="infoIcon"/>
</image>
<GridPane.margin>
<Insets right="2.0" top="4.0"/>
</GridPane.margin>
</ImageView>
<Label fx:id="showDetailsInfoLabel" prefWidth="740.0"
text="Your trading partners must fulfill your offer restrictions. You can edit the accepted countries, languages and arbitrators in the settings. The bank account details are used from your current selected bank account (if you have multiple bank accounts). Open the help menu for more information."
visible="true" wrapText="true" GridPane.columnIndex="1" GridPane.rowIndex="22">
<GridPane.margin>
<Insets bottom="5.0"/>
</GridPane.margin>
</Label>
</children>
<columnConstraints>
<ColumnConstraints halignment="RIGHT" hgrow="SOMETIMES"/>
<ColumnConstraints hgrow="ALWAYS"/>
<ColumnConstraints hgrow="NEVER" prefWidth="25.0"/>
</columnConstraints>
<rowConstraints>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints minHeight="10.0" prefHeight="30.0"/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints minHeight="10.0" prefHeight="30.0"/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
<RowConstraints/>
</rowConstraints>
</GridPane>
</GridPane>
</content>
</ScrollPane>
</children>
</AnchorPane>