Show QR Code at funding screens, Remove QR Code Icon from AddressTextField, Add CopyIcon to Create Offer funding screen

This commit is contained in:
Manfred Karrer 2016-03-17 01:38:20 +01:00
parent 6721131ccf
commit 0350b6e5e7
5 changed files with 151 additions and 62 deletions

View File

@ -20,7 +20,6 @@ package io.bitsquare.gui.components;
import de.jensd.fx.fontawesome.AwesomeDude;
import de.jensd.fx.fontawesome.AwesomeIcon;
import io.bitsquare.common.util.Utilities;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.overlays.popups.Popup;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
@ -29,20 +28,12 @@ import javafx.beans.property.StringProperty;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.control.Tooltip;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.stage.Window;
import net.glxn.qrgen.QRCode;
import net.glxn.qrgen.image.ImageType;
import org.bitcoinj.core.Coin;
import org.bitcoinj.uri.BitcoinURI;
import org.controlsfx.control.PopOver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.net.URI;
public class AddressTextField extends AnchorPane {
@ -86,46 +77,12 @@ public class AddressTextField extends AnchorPane {
Utilities.copyToClipboard(address.get());
});
Label qrCode = new Label();
qrCode.getStyleClass().add("copy-icon");
qrCode.setLayoutY(3);
AwesomeDude.setIcon(qrCode, AwesomeIcon.QRCODE);
Tooltip.install(qrCode, new Tooltip("Show QR code for this address"));
qrCode.setOnMouseClicked(e -> {
if (address.get() != null && address.get().length() > 0) {
final byte[] imageBytes = QRCode
.from(getBitcoinURI())
.withSize(300, 220)
.to(ImageType.PNG)
.stream()
.toByteArray();
Image qrImage = new Image(new ByteArrayInputStream(imageBytes));
ImageView view = new ImageView(qrImage);
Pane pane = new Pane(view);
pane.setPrefSize(320, 240);
view.relocate(10, 10);
PopOver popOver = new PopOver(pane);
popOver.setDetachedTitle("Scan QR code for this address");
popOver.setDetached(true);
popOver.setOnHiding(windowEvent -> MainView.removeEffect());
Window window = getScene().getWindow();
double x = Math.round(window.getX() + (window.getWidth() - 320) / 2);
double y = Math.round(window.getY() + (window.getHeight() - 240) / 2);
popOver.show(getScene().getWindow(), x, y);
MainView.blur();
}
});
AnchorPane.setRightAnchor(qrCode, 5.0);
AnchorPane.setRightAnchor(copyIcon, 30.0);
AnchorPane.setRightAnchor(extWalletIcon, 55.0);
AnchorPane.setRightAnchor(textField, 77.0);
AnchorPane.setRightAnchor(copyIcon, 5.0);
AnchorPane.setRightAnchor(extWalletIcon, 30.0);
AnchorPane.setRightAnchor(textField, 55.0);
AnchorPane.setLeftAnchor(textField, 0.0);
getChildren().addAll(textField, extWalletIcon, copyIcon, qrCode);
getChildren().addAll(textField, extWalletIcon, copyIcon);
}
private void openExtWallet() {

View File

@ -64,6 +64,7 @@ public class TextFieldWithCopyIcon extends AnchorPane {
textField = new TextField();
textField.setEditable(false);
textField.textProperty().bindBidirectional(text);
AnchorPane.setRightAnchor(copyIcon, 5.0);
AnchorPane.setRightAnchor(textField, 30.0);
AnchorPane.setLeftAnchor(textField, 0.0);
textField.focusTraversableProperty().set(focusTraversableProperty().get());

View File

@ -28,10 +28,7 @@ import io.bitsquare.common.util.Utilities;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.common.view.ActivatableViewAndModel;
import io.bitsquare.gui.common.view.FxmlView;
import io.bitsquare.gui.components.AddressTextField;
import io.bitsquare.gui.components.BalanceTextField;
import io.bitsquare.gui.components.InputTextField;
import io.bitsquare.gui.components.TitledGroupBg;
import io.bitsquare.gui.components.*;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.account.AccountView;
import io.bitsquare.gui.main.account.content.arbitratorselection.ArbitratorSelectionView;
@ -41,6 +38,7 @@ import io.bitsquare.gui.main.funds.withdrawal.WithdrawalView;
import io.bitsquare.gui.main.offer.OfferView;
import io.bitsquare.gui.main.overlays.popups.Popup;
import io.bitsquare.gui.main.overlays.windows.OfferDetailsWindow;
import io.bitsquare.gui.main.overlays.windows.QRCodeWindow;
import io.bitsquare.gui.main.portfolio.PortfolioView;
import io.bitsquare.gui.main.portfolio.openoffer.OpenOffersView;
import io.bitsquare.gui.util.FormBuilder;
@ -56,15 +54,21 @@ import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.*;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.scene.text.Font;
import javafx.stage.Window;
import javafx.util.StringConverter;
import net.glxn.qrgen.QRCode;
import net.glxn.qrgen.image.ImageType;
import org.bitcoinj.core.Coin;
import org.bitcoinj.uri.BitcoinURI;
import org.controlsfx.control.PopOver;
import org.jetbrains.annotations.NotNull;
import javax.inject.Inject;
import java.io.ByteArrayInputStream;
import java.util.concurrent.TimeUnit;
import static io.bitsquare.gui.util.FormBuilder.*;
@ -85,10 +89,11 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
private TitledGroupBg payFundsPane;
private Button nextButton, cancelButton1, cancelButton2, placeOfferButton;
private InputTextField amountTextField, minAmountTextField, priceTextField, volumeTextField;
private TextField totalToPayTextField, currencyTextField;
private TextField currencyTextField;
private Label directionLabel, amountDescriptionLabel, addressLabel, balanceLabel, totalToPayLabel, totalToPayInfoIconLabel, amountBtcLabel, priceCurrencyLabel,
volumeCurrencyLabel, minAmountBtcLabel, priceDescriptionLabel, volumeDescriptionLabel, spinnerInfoLabel, currencyTextFieldLabel,
currencyComboBoxLabel;
private TextFieldWithCopyIcon totalToPayTextField;
private ComboBox<PaymentAccount> paymentAccountsComboBox;
private ComboBox<TradeCurrency> currencyComboBox;
private PopOver totalToPayInfoPopover;
@ -112,6 +117,7 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
private int gridRow = 0;
private final Preferences preferences;
private ChangeListener<String> tradeCurrencyCodeListener;
private ImageView qrCodeImageView;
///////////////////////////////////////////////////////////////////////////////////////////
@ -301,6 +307,7 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
totalToPayTextField.setVisible(true);
addressLabel.setVisible(true);
addressTextField.setVisible(true);
qrCodeImageView.setVisible(true);
balanceLabel.setVisible(true);
balanceTextField.setVisible(true);
placeOfferButton.setVisible(true);
@ -308,6 +315,15 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
//root.requestFocus();
setupTotalToPayInfoIconLabel();
final byte[] imageBytes = QRCode
.from(getBitcoinURI())
.withSize(98, 98) // code has 41 elements 8 px is border with 98 we get double scale and min. border
.to(ImageType.PNG)
.stream()
.toByteArray();
Image qrImage = new Image(new ByteArrayInputStream(imageBytes));
qrCodeImageView.setImage(qrImage);
}
private void onPaymentAccountsComboBoxSelected() {
@ -614,16 +630,19 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
gridPane.setVgap(5);
ColumnConstraints columnConstraints1 = new ColumnConstraints();
columnConstraints1.setHalignment(HPos.RIGHT);
columnConstraints1.setHgrow(Priority.SOMETIMES);
columnConstraints1.setHgrow(Priority.NEVER);
columnConstraints1.setMinWidth(200);
ColumnConstraints columnConstraints2 = new ColumnConstraints();
columnConstraints2.setHgrow(Priority.ALWAYS);
gridPane.getColumnConstraints().addAll(columnConstraints1, columnConstraints2);
ColumnConstraints columnConstraints3 = new ColumnConstraints();
columnConstraints3.setHgrow(Priority.NEVER);
gridPane.getColumnConstraints().addAll(columnConstraints1, columnConstraints2, columnConstraints3);
scrollPane.setContent(gridPane);
}
private void addPaymentGroup() {
addTitledGroupBg(gridPane, gridRow, 2, "Select payment account");
TitledGroupBg titledGroupBg = addTitledGroupBg(gridPane, gridRow, 2, "Select payment account");
GridPane.setColumnSpan(titledGroupBg, 3);
paymentAccountsComboBox = addLabelComboBox(gridPane, gridRow, "Payment account:", Layout.FIRST_ROW_DISTANCE).second;
paymentAccountsComboBox.setPromptText("Select payment account");
@ -651,7 +670,8 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
}
private void addAmountPriceGroup() {
addTitledGroupBg(gridPane, ++gridRow, 2, "Set amount and price", Layout.GROUP_DISTANCE);
TitledGroupBg titledGroupBg = addTitledGroupBg(gridPane, ++gridRow, 2, "Set amount and price", Layout.GROUP_DISTANCE);
GridPane.setColumnSpan(titledGroupBg, 3);
imageView = new ImageView();
imageView.setPickOnBounds(true);
@ -688,6 +708,7 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
private void addFundingGroup() {
// don't increase gridRow as we removed button when this gets visible
payFundsPane = addTitledGroupBg(gridPane, gridRow, 3, BSResources.get("createOffer.fundsBox.title"), Layout.GROUP_DISTANCE);
GridPane.setColumnSpan(payFundsPane, 3);
payFundsPane.setVisible(false);
totalToPayLabel = new Label(BSResources.get("createOffer.fundsBox.totalsNeeded"));
@ -701,8 +722,8 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
GridPane.setMargin(totalToPayBox, new Insets(Layout.FIRST_ROW_AND_GROUP_DISTANCE, 0, 0, 0));
GridPane.setRowIndex(totalToPayBox, gridRow);
gridPane.getChildren().add(totalToPayBox);
totalToPayTextField = new TextField();
totalToPayTextField.setEditable(false);
totalToPayTextField = new TextFieldWithCopyIcon();
totalToPayTextField.setCopyWithoutCurrencyPostFix(true);
totalToPayTextField.setFocusTraversable(false);
totalToPayTextField.setVisible(false);
GridPane.setRowIndex(totalToPayTextField, gridRow);
@ -710,6 +731,16 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
GridPane.setMargin(totalToPayTextField, new Insets(Layout.FIRST_ROW_AND_GROUP_DISTANCE, 0, 0, 0));
gridPane.getChildren().add(totalToPayTextField);
qrCodeImageView = new ImageView();
qrCodeImageView.setVisible(false);
qrCodeImageView.setStyle("-fx-cursor: hand;");
qrCodeImageView.setOnMouseClicked(e -> new QRCodeWindow(getBitcoinURI()).show());
GridPane.setRowIndex(qrCodeImageView, gridRow);
GridPane.setColumnIndex(qrCodeImageView, 2);
GridPane.setRowSpan(qrCodeImageView, 3);
GridPane.setMargin(qrCodeImageView, new Insets(Layout.FIRST_ROW_AND_GROUP_DISTANCE, 0, 0, 0));
gridPane.getChildren().add(qrCodeImageView);
Tuple2<Label, AddressTextField> addressTuple = addLabelAddressTextField(gridPane, ++gridRow, BSResources.get("createOffer.fundsBox.address"));
addressLabel = addressTuple.first;
addressLabel.setVisible(false);
@ -749,6 +780,12 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
cancelButton2.setId("cancel-button");
}
@NotNull
private String getBitcoinURI() {
return model.getAddressAsString() != null ? BitcoinURI.convertToBitcoinURI(model.getAddressAsString(), model.totalToPayAsCoin.get(),
model.getPaymentLabel(), null) : "";
}
private void addAmountPriceFields() {
// amountBox
Tuple3<HBox, InputTextField, Label> amountValueCurrencyBoxTuple = FormBuilder.getValueCurrencyBox(BSResources.get("createOffer.amount.prompt"));
@ -794,6 +831,7 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
GridPane.setRowIndex(hBox, gridRow);
GridPane.setColumnIndex(hBox, 1);
GridPane.setMargin(hBox, new Insets(Layout.FIRST_ROW_AND_GROUP_DISTANCE, 10, 0, 0));
GridPane.setColumnSpan(hBox, 2);
gridPane.getChildren().add(hBox);
}

View File

@ -39,6 +39,7 @@ import io.bitsquare.gui.main.offer.OfferView;
import io.bitsquare.gui.main.overlays.notifications.Notification;
import io.bitsquare.gui.main.overlays.popups.Popup;
import io.bitsquare.gui.main.overlays.windows.OfferDetailsWindow;
import io.bitsquare.gui.main.overlays.windows.QRCodeWindow;
import io.bitsquare.gui.main.portfolio.PortfolioView;
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesView;
import io.bitsquare.gui.util.BSFormatter;
@ -51,17 +52,23 @@ import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ChangeListener;
import javafx.geometry.*;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.scene.text.Font;
import javafx.stage.Window;
import javafx.util.StringConverter;
import net.glxn.qrgen.QRCode;
import net.glxn.qrgen.image.ImageType;
import org.bitcoinj.core.Coin;
import org.bitcoinj.uri.BitcoinURI;
import org.controlsfx.control.PopOver;
import org.fxmisc.easybind.EasyBind;
import org.fxmisc.easybind.Subscription;
import org.jetbrains.annotations.NotNull;
import javax.inject.Inject;
import java.io.ByteArrayInputStream;
import java.util.concurrent.TimeUnit;
import static io.bitsquare.gui.util.FormBuilder.*;
@ -106,6 +113,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
private boolean offerDetailsWindowDisplayed;
private Notification walletFundedNotification;
private Subscription isWalletFundedSubscription;
private ImageView qrCodeImageView;
///////////////////////////////////////////////////////////////////////////////////////////
@ -463,6 +471,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
totalToPayTextField.setVisible(true);
addressLabel.setVisible(true);
addressTextField.setVisible(true);
qrCodeImageView.setVisible(true);
balanceLabel.setVisible(true);
balanceTextField.setVisible(true);
@ -491,6 +500,15 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
}
});
}
final byte[] imageBytes = QRCode
.from(getBitcoinURI())
.withSize(98, 98) // code has 41 elements 8 px is border with 98 we get double scale and min. border
.to(ImageType.PNG)
.stream()
.toByteArray();
Image qrImage = new Image(new ByteArrayInputStream(imageBytes));
qrCodeImageView.setImage(qrImage);
}
@ -529,16 +547,20 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
gridPane.setVgap(5);
ColumnConstraints columnConstraints1 = new ColumnConstraints();
columnConstraints1.setHalignment(HPos.RIGHT);
columnConstraints1.setHgrow(Priority.SOMETIMES);
columnConstraints1.setHgrow(Priority.NEVER);
columnConstraints1.setMinWidth(200);
ColumnConstraints columnConstraints2 = new ColumnConstraints();
columnConstraints2.setHgrow(Priority.ALWAYS);
gridPane.getColumnConstraints().addAll(columnConstraints1, columnConstraints2);
ColumnConstraints columnConstraints3 = new ColumnConstraints();
columnConstraints3.setHgrow(Priority.NEVER);
gridPane.getColumnConstraints().addAll(columnConstraints1, columnConstraints2, columnConstraints3);
scrollPane.setContent(gridPane);
}
private void addPaymentGroup() {
addTitledGroupBg(gridPane, gridRow, 2, "Payment info");
TitledGroupBg titledGroupBg = addTitledGroupBg(gridPane, gridRow, 2, "Payment info");
GridPane.setColumnSpan(titledGroupBg, 3);
Tuple2<Label, ComboBox> tuple = addLabelComboBox(gridPane, gridRow, "Payment account:", Layout.FIRST_ROW_DISTANCE);
paymentAccountsLabel = tuple.first;
paymentAccountsLabel.setVisible(false);
@ -566,7 +588,8 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
}
private void addAmountPriceGroup() {
addTitledGroupBg(gridPane, ++gridRow, 2, "Set amount and price", Layout.GROUP_DISTANCE);
TitledGroupBg titledGroupBg = addTitledGroupBg(gridPane, ++gridRow, 2, "Set amount and price", Layout.GROUP_DISTANCE);
GridPane.setColumnSpan(titledGroupBg, 3);
imageView = new ImageView();
imageView.setPickOnBounds(true);
@ -618,6 +641,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
private void addFundingGroup() {
// don't increase gridRow as we removed button when this gets visible
payFundsPane = addTitledGroupBg(gridPane, gridRow, 3, BSResources.get("takeOffer.fundsBox.title"), Layout.GROUP_DISTANCE);
GridPane.setColumnSpan(payFundsPane, 3);
payFundsPane.setVisible(false);
totalToPayLabel = new Label(BSResources.get("takeOffer.fundsBox.totalsNeeded"));
@ -641,6 +665,16 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
GridPane.setMargin(totalToPayTextField, new Insets(Layout.FIRST_ROW_AND_GROUP_DISTANCE, 0, 0, 0));
gridPane.getChildren().add(totalToPayTextField);
qrCodeImageView = new ImageView();
qrCodeImageView.setVisible(false);
qrCodeImageView.setStyle("-fx-cursor: hand;");
qrCodeImageView.setOnMouseClicked(e -> new QRCodeWindow(getBitcoinURI()).show());
GridPane.setRowIndex(qrCodeImageView, gridRow);
GridPane.setColumnIndex(qrCodeImageView, 2);
GridPane.setRowSpan(qrCodeImageView, 3);
GridPane.setMargin(qrCodeImageView, new Insets(Layout.FIRST_ROW_AND_GROUP_DISTANCE, 0, 0, 0));
gridPane.getChildren().add(qrCodeImageView);
Tuple2<Label, AddressTextField> addressTuple = addLabelAddressTextField(gridPane, ++gridRow, BSResources.get("takeOffer.fundsBox.address"));
addressLabel = addressTuple.first;
addressLabel.setVisible(false);
@ -683,6 +717,12 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
cancelButton2.setId("cancel-button");
}
@NotNull
private String getBitcoinURI() {
return model.getAddressAsString() != null ? BitcoinURI.convertToBitcoinURI(model.getAddressAsString(), model.totalToPayAsCoin.get(),
model.getPaymentLabel(), null) : "";
}
private void addAmountPriceFields() {
// amountBox
Tuple3<HBox, InputTextField, Label> amountValueCurrencyBoxTuple = getAmountCurrencyBox(BSResources.get("takeOffer.amount.prompt"));
@ -728,6 +768,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
GridPane.setRowIndex(hBox, gridRow);
GridPane.setColumnIndex(hBox, 1);
GridPane.setMargin(hBox, new Insets(Layout.FIRST_ROW_AND_GROUP_DISTANCE, 10, 0, 0));
GridPane.setColumnSpan(hBox, 2);
gridPane.getChildren().add(hBox);
}

View File

@ -0,0 +1,52 @@
package io.bitsquare.gui.main.overlays.windows;
import io.bitsquare.gui.main.overlays.Overlay;
import javafx.geometry.HPos;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import net.glxn.qrgen.QRCode;
import net.glxn.qrgen.image.ImageType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
public class QRCodeWindow extends Overlay<QRCodeWindow> {
private static final Logger log = LoggerFactory.getLogger(QRCodeWindow.class);
private final ImageView qrCodeImageView;
public QRCodeWindow(String bitcoinURI) {
final byte[] imageBytes = QRCode
.from(bitcoinURI)
.withSize(250, 250)
.to(ImageType.PNG)
.stream()
.toByteArray();
Image qrImage = new Image(new ByteArrayInputStream(imageBytes));
qrCodeImageView = new ImageView(qrImage);
type = Type.Information;
width = 400;
headLine("QR-Code");
message("Please use that QR-Code for funding your Bitsquare wallet from your external wallet.");
}
@Override
public void show() {
createGridPane();
addHeadLine();
addSeparator();
addMessage();
GridPane.setRowIndex(qrCodeImageView, ++rowIndex);
GridPane.setColumnSpan(qrCodeImageView, 2);
GridPane.setHalignment(qrCodeImageView, HPos.CENTER);
gridPane.getChildren().add(qrCodeImageView);
addCloseButton();
applyStyles();
display();
}
}