diff --git a/pom.xml b/pom.xml
index 55f47feacd..13f73c0244 100644
--- a/pom.xml
+++ b/pom.xml
@@ -240,6 +240,12 @@
+
+ net.glxn
+ qrgen
+ 1.3
+
+
UTF-8
diff --git a/src/main/java/io/bitsquare/BitSquare.java b/src/main/java/io/bitsquare/BitSquare.java
index 6badf0c95e..67823ed10e 100644
--- a/src/main/java/io/bitsquare/BitSquare.java
+++ b/src/main/java/io/bitsquare/BitSquare.java
@@ -35,7 +35,7 @@ public class BitSquare extends Application
public static boolean fillFormsWithDummyData = true;
- private static String APP_NAME = "bitsquare";
+ private static String APP_NAME = "Bitsquare";
private static Stage primaryStage;
private WalletFacade walletFacade;
private MessageFacade messageFacade;
diff --git a/src/main/java/io/bitsquare/gui/bitsquare.css b/src/main/java/io/bitsquare/gui/bitsquare.css
index 136a5647fa..7ddb32ce5b 100644
--- a/src/main/java/io/bitsquare/gui/bitsquare.css
+++ b/src/main/java/io/bitsquare/gui/bitsquare.css
@@ -32,6 +32,7 @@
-fx-fill: red;
}
+
/* main nav */
#nav-button {
-fx-cursor: hand;
@@ -78,14 +79,19 @@
-fx-background-color: transparent;
}
+#qr-code-icon {
+ -fx-fill: #0096c9;
+ -fx-cursor: hand;
+}
+
#copy-icon {
- -fx-fill: black;
- -fx-cursor: hand;
+ -fx-fill: #0096c9;
+ -fx-cursor: hand;
}
#copy-icon .hover{
- -fx-fill: #0096c9;
- -fx-cursor: hand;
+ -fx-fill: #0096c9;
+ -fx-cursor: hand;
}
.copy-icon {
@@ -97,6 +103,22 @@
-fx-fill: black;
}
+/* Same stlye like non editable textfield. But textfield spans a whole column in a grid, so we use generally textfield */
+#label-with-background {
+ -fx-background-color: #FAFAFA;
+ -fx-border-radius: 4;
+ -fx-padding: 4 4 4 4;
+}
+
+#address-label {
+ -fx-cursor: hand;
+ -fx-text-fill: #0096c9;
+ -fx-underline: true;
+ -fx-background-color: #FAFAFA;
+ -fx-border-radius: 4;
+ -fx-padding: 4 4 4 4;
+}
+
#funds-confidence {
-fx-progress-color: dimgrey;
}
diff --git a/src/main/java/io/bitsquare/gui/components/btc/AddressTextField.java b/src/main/java/io/bitsquare/gui/components/btc/AddressTextField.java
index 238f997837..39806bd121 100644
--- a/src/main/java/io/bitsquare/gui/components/btc/AddressTextField.java
+++ b/src/main/java/io/bitsquare/gui/components/btc/AddressTextField.java
@@ -1,18 +1,36 @@
package io.bitsquare.gui.components.btc;
+import com.google.bitcoin.uri.BitcoinURI;
import de.jensd.fx.fontawesome.AwesomeDude;
import de.jensd.fx.fontawesome.AwesomeIcon;
+import io.bitsquare.BitSquare;
+import io.bitsquare.gui.components.Popups;
+import java.awt.Desktop;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.net.URI;
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.input.Clipboard;
import javafx.scene.input.ClipboardContent;
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.controlsfx.control.PopOver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class AddressTextField extends AnchorPane
{
+ private static final Logger log = LoggerFactory.getLogger(AddressTextField.class);
+
private final Label copyIcon;
- private final TextField addressTextField;
+ private final Label addressLabel;
+ private final Label qrCode;
private String address;
///////////////////////////////////////////////////////////////////////////////////////////
@@ -21,12 +39,15 @@ public class AddressTextField extends AnchorPane
public AddressTextField()
{
- addressTextField = new TextField();
- addressTextField.setFocusTraversable(false);
- addressTextField.setEditable(false);
+ addressLabel = new Label();
+ addressLabel.setFocusTraversable(false);
+ addressLabel.setId("address-label");
copyIcon = new Label();
copyIcon.setLayoutY(3);
+ copyIcon.setId("copy-icon");
+ Tooltip.install(copyIcon, new Tooltip("Copy address to clipboard"));
+ AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY);
copyIcon.setOnMouseClicked(e -> {
if (address != null && address.length() > 0)
{
@@ -37,30 +58,72 @@ public class AddressTextField extends AnchorPane
}
});
- Tooltip copyIconTooltip = new Tooltip("Copy address to clipboard");
- Tooltip.install(copyIcon, copyIconTooltip);
+ qrCode = new Label();
+ qrCode.setId("qr-code-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 != null && address.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);
- AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY);
- copyIcon.setId("copy-icon");
+ Pane pane = new Pane(view);
+ pane.setPrefSize(320, 240);
+ view.relocate(10, 10);
- AnchorPane.setRightAnchor(copyIcon, 5.0);
- AnchorPane.setRightAnchor(addressTextField, 35.0);
- AnchorPane.setLeftAnchor(addressTextField, 0.0);
+ PopOver popOver = new PopOver(pane);
+ popOver.setDetachedTitle("Scan QR code for this address");
+ popOver.setDetached(true);
- getChildren().addAll(addressTextField, copyIcon);
+ 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);
+ }
+ });
+
+ AnchorPane.setRightAnchor(qrCode, 5.0);
+ AnchorPane.setRightAnchor(copyIcon, 30.0);
+ AnchorPane.setRightAnchor(addressLabel, 55.0);
+ AnchorPane.setLeftAnchor(addressLabel, 0.0);
+
+ getChildren().addAll(addressLabel, copyIcon, qrCode);
+
+ addressLabel.setOnMouseClicked(mouseEvent -> {
+ try
+ {
+ if (address != null)
+ Desktop.getDesktop().browse(URI.create(getBitcoinURI()));
+ } catch (IOException e)
+ {
+ log.warn(e.getMessage());
+ Popups.openWarningPopup("Opening wallet app failed", "Perhaps you don't have one installed?");
+ }
+ });
}
+ private String getBitcoinURI()
+ {
+ return BitcoinURI.convertToBitcoinURI(address, null, BitSquare.getAppName(), null);
+ }
///////////////////////////////////////////////////////////////////////////////////////////
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
-
public void setAddress(String address)
{
this.address = address;
- addressTextField.setText(address);
+ addressLabel.setText(address);
}
}
diff --git a/src/main/java/io/bitsquare/gui/components/btc/BalanceTextField.java b/src/main/java/io/bitsquare/gui/components/btc/BalanceTextField.java
index 878b6a575f..71530aef22 100644
--- a/src/main/java/io/bitsquare/gui/components/btc/BalanceTextField.java
+++ b/src/main/java/io/bitsquare/gui/components/btc/BalanceTextField.java
@@ -49,7 +49,7 @@ public class BalanceTextField extends AnchorPane
Tooltip.install(progressIndicator, progressIndicatorTooltip);
AnchorPane.setRightAnchor(progressIndicator, 0.0);
- AnchorPane.setRightAnchor(balanceTextField, 35.0);
+ AnchorPane.setRightAnchor(balanceTextField, 55.0);
AnchorPane.setLeftAnchor(balanceTextField, 0.0);
getChildren().addAll(balanceTextField, progressIndicator);
diff --git a/src/main/java/io/bitsquare/gui/trade/createoffer/CreateOfferController.java b/src/main/java/io/bitsquare/gui/trade/createoffer/CreateOfferController.java
index ce4b096866..be877d842d 100644
--- a/src/main/java/io/bitsquare/gui/trade/createoffer/CreateOfferController.java
+++ b/src/main/java/io/bitsquare/gui/trade/createoffer/CreateOfferController.java
@@ -105,7 +105,7 @@ public class CreateOfferController extends CachedViewController
setupBindings();
setupValidation();
-
+
//TODO just for dev testing
if (BitSquare.fillFormsWithDummyData)
{
@@ -171,7 +171,7 @@ public class CreateOfferController extends CachedViewController
if (amountTextField.getIsValid() && minAmountTextField.getIsValid() && volumeTextField.getIsValid() && amountTextField.getIsValid())
{
viewModel.isPlaceOfferButtonDisabled.set(true);
-
+
tradeManager.requestPlaceOffer(offerId,
direction,
BitSquareFormatter.parseToDouble(viewModel.price.get()),