Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add info icon for rounding of fiat values #1628

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion src/main/java/bisq/desktop/components/InfoInputTextField.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ public class InfoInputTextField extends AnchorPane {
private final Label infoIcon;
@Getter
private final Label warningIcon;
@Getter
private final Label privacyIcon;

private Label currentIcon;
private PopOver popover;
private boolean hidePopover;
Expand All @@ -63,21 +66,28 @@ public InfoInputTextField() {
warningIcon.setLayoutY(3);
warningIcon.getStyleClass().addAll("icon", "warning");

privacyIcon = getIcon(AwesomeIcon.EYE_CLOSE);
privacyIcon.setLayoutY(3);
privacyIcon.getStyleClass().addAll("icon", "info");

AnchorPane.setLeftAnchor(infoIcon, 7.0);
AnchorPane.setLeftAnchor(warningIcon, 7.0);
AnchorPane.setLeftAnchor(privacyIcon, 7.0);
AnchorPane.setRightAnchor(inputTextField, 0.0);
AnchorPane.setLeftAnchor(inputTextField, 0.0);

hideIcons();

getChildren().addAll(inputTextField, infoIcon, warningIcon);
getChildren().addAll(inputTextField, infoIcon, warningIcon, privacyIcon);
}

private void hideIcons() {
infoIcon.setManaged(false);
infoIcon.setVisible(false);
warningIcon.setManaged(false);
warningIcon.setVisible(false);
privacyIcon.setManaged(false);
privacyIcon.setVisible(false);
}

///////////////////////////////////////////////////////////////////////////////////////////
Expand All @@ -98,13 +108,22 @@ public void setContentForWarningPopOver(Node node) {
setActionHandlers(node);
}

public void setContentForPrivacyPopOver(Node node) {
currentIcon = privacyIcon;

hideIcons();
setActionHandlers(node);
}

public void setIconsRightAligned() {
AnchorPane.clearConstraints(infoIcon);
AnchorPane.clearConstraints(warningIcon);
AnchorPane.clearConstraints(privacyIcon);
AnchorPane.clearConstraints(inputTextField);

AnchorPane.setRightAnchor(infoIcon, 7.0);
AnchorPane.setRightAnchor(warningIcon, 7.0);
AnchorPane.setRightAnchor(privacyIcon, 7.0);
AnchorPane.setLeftAnchor(inputTextField, 0.0);
AnchorPane.setRightAnchor(inputTextField, 0.0);
}
Expand Down
99 changes: 75 additions & 24 deletions src/main/java/bisq/desktop/components/InfoTextField.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

import bisq.common.UserThread;

import de.jensd.fx.fontawesome.AwesomeDude;
import de.jensd.fx.fontawesome.AwesomeIcon;

import org.controlsfx.control.PopOver;
Expand All @@ -37,71 +36,123 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import lombok.Getter;

import static bisq.desktop.util.FormBuilder.getIcon;

public class InfoTextField extends AnchorPane {
public static final Logger log = LoggerFactory.getLogger(InfoTextField.class);

@Getter
protected final TextField textField;

private final StringProperty text = new SimpleStringProperty();
protected final Label infoIcon;
protected final TextField textField;
protected final Label privacyIcon;
private Label currentIcon;
private Boolean hidePopover;
private PopOver infoPopover;
private PopOver popover;
private PopOver.ArrowLocation arrowLocation;

public InfoTextField() {

arrowLocation = PopOver.ArrowLocation.RIGHT_TOP;;
textField = new TextField();
textField.setEditable(false);
textField.textProperty().bind(text);
textField.setFocusTraversable(false);

infoIcon = new Label();
infoIcon = getIcon(AwesomeIcon.INFO_SIGN);
infoIcon.setLayoutY(3);
infoIcon.getStyleClass().addAll("icon", "info");
AwesomeDude.setIcon(infoIcon, AwesomeIcon.INFO_SIGN);

privacyIcon = getIcon(AwesomeIcon.EYE_CLOSE);
privacyIcon.setLayoutY(3);
privacyIcon.getStyleClass().addAll("icon", "info");

AnchorPane.setRightAnchor(infoIcon, 7.0);
AnchorPane.setRightAnchor(privacyIcon, 7.0);
AnchorPane.setRightAnchor(textField, 0.0);
AnchorPane.setLeftAnchor(textField, 0.0);

getChildren().addAll(textField, infoIcon);
hideIcons();

getChildren().addAll(textField, infoIcon, privacyIcon);
}



///////////////////////////////////////////////////////////////////////////////////////////
// Public
///////////////////////////////////////////////////////////////////////////////////////////

public void setContentForInfoPopOver(Node node) {

currentIcon = infoIcon;

hideIcons();
}

public void setContentForPrivacyPopOver(Node node) {
currentIcon = privacyIcon;

hideIcons();
setActionHandlers(node);
}

public void setIconsLeftAligned() {
arrowLocation = PopOver.ArrowLocation.LEFT_TOP;;

AnchorPane.clearConstraints(infoIcon);
AnchorPane.clearConstraints(privacyIcon);

AnchorPane.setLeftAnchor(infoIcon, 7.0);
AnchorPane.setLeftAnchor(privacyIcon, 7.0);
}

///////////////////////////////////////////////////////////////////////////////////////////
// Private
///////////////////////////////////////////////////////////////////////////////////////////
private void hideIcons() {
infoIcon.setManaged(false);
infoIcon.setVisible(false);
privacyIcon.setManaged(false);
privacyIcon.setVisible(false);
}

private void setActionHandlers(Node node) {

currentIcon.setManaged(true);
currentIcon.setVisible(true);

// As we don't use binding here we need to recreate it on mouse over to reflect the current state
infoIcon.setOnMouseEntered(e -> {
currentIcon.setOnMouseEntered(e -> {
hidePopover = false;
showInfoPopOver(node);
showPopOver(node);
});
infoIcon.setOnMouseExited(e -> {
if (infoPopover != null)
infoPopover.hide();
currentIcon.setOnMouseExited(e -> {
if (popover != null)
popover.hide();
hidePopover = true;
UserThread.runAfter(() -> {
if (hidePopover) {
infoPopover.hide();
popover.hide();
hidePopover = false;
}
}, 250, TimeUnit.MILLISECONDS);
});
}


///////////////////////////////////////////////////////////////////////////////////////////
// Private
///////////////////////////////////////////////////////////////////////////////////////////

private void showInfoPopOver(Node node) {
private void showPopOver(Node node) {
node.getStyleClass().add("default-text");

infoPopover = new PopOver(node);
if (infoIcon.getScene() != null) {
infoPopover.setDetachable(false);
infoPopover.setArrowLocation(PopOver.ArrowLocation.RIGHT_TOP);
infoPopover.setArrowIndent(5);
popover = new PopOver(node);
if (currentIcon.getScene() != null) {
popover.setDetachable(false);
popover.setArrowLocation(arrowLocation);
popover.setArrowIndent(5);

infoPopover.show(infoIcon, -17);
popover.show(currentIcon, -17);
}
}

Expand Down
19 changes: 15 additions & 4 deletions src/main/java/bisq/desktop/main/offer/MutableOfferView.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import bisq.desktop.util.Layout;
import bisq.desktop.util.Transitions;

import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.offer.Offer;
Expand Down Expand Up @@ -158,7 +159,8 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel> extends
private ChangeListener<Boolean> amountFocusedListener, minAmountFocusedListener, volumeFocusedListener,
buyerSecurityDepositFocusedListener, priceFocusedListener, placeOfferCompletedListener,
priceAsPercentageFocusedListener;
private ChangeListener<String> tradeCurrencyCodeListener, errorMessageListener, marketPriceMarginListener;
private ChangeListener<String> tradeCurrencyCodeListener, errorMessageListener,
marketPriceMarginListener, volumeListener;
private ChangeListener<Number> marketPriceAvailableListener;
private EventHandler<ActionEvent> currencyComboBoxSelectionHandler, paymentAccountsComboBoxSelectionHandler;
private OfferView.CloseHandler closeHandler;
Expand All @@ -167,7 +169,7 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel> extends
private final List<Node> editOfferElements = new ArrayList<>();
private boolean clearXchangeWarningDisplayed, isActivated;
private ChangeListener<Boolean> getShowWalletFundedNotificationListener;
private InfoInputTextField marketBasedPriceInfoInputTextField;
private InfoInputTextField marketBasedPriceInfoInputTextField, volumeInfoInputTextField;
protected TitledGroupBg amountTitledGroupBg;

///////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -718,6 +720,12 @@ private void createListeners() {
}
};

volumeListener = (observable, oldValue, newValue) -> {
if (!newValue.equals("") && CurrencyUtil.isFiatCurrency(model.tradeCurrencyCode.get())) {
volumeInfoInputTextField.setContentForPrivacyPopOver(createPopoverLabel(Res.get("offerbook.info.roundedFiatVolume")));
}
};

marketPriceMarginListener = (observable, oldValue, newValue) -> {
if (marketBasedPriceInfoInputTextField != null) {
String tooltip;
Expand Down Expand Up @@ -776,6 +784,7 @@ private void addListeners() {
model.tradeCurrencyCode.addListener(tradeCurrencyCodeListener);
model.marketPriceAvailableProperty.addListener(marketPriceAvailableListener);
model.marketPriceMargin.addListener(marketPriceMarginListener);
model.volume.addListener(volumeListener);

// focus out
amountTextField.focusedProperty().addListener(amountFocusedListener);
Expand Down Expand Up @@ -803,6 +812,7 @@ private void removeListeners() {
model.tradeCurrencyCode.removeListener(tradeCurrencyCodeListener);
model.marketPriceAvailableProperty.removeListener(marketPriceAvailableListener);
model.marketPriceMargin.removeListener(marketPriceMarginListener);
model.volume.removeListener(volumeListener);

// focus out
amountTextField.focusedProperty().removeListener(amountFocusedListener);
Expand Down Expand Up @@ -1180,9 +1190,10 @@ private void addAmountPriceFields() {
resultLabel.setPadding(new Insets(14, 2, 0, 2));

// volume
Tuple3<HBox, InputTextField, Label> volumeValueCurrencyBoxTuple = getEditableValueCurrencyBox(Res.get("createOffer.volume.prompt"));
Tuple3<HBox, InfoInputTextField, Label> volumeValueCurrencyBoxTuple = getEditableValueCurrencyBoxWithInfo(Res.get("createOffer.volume.prompt"));
HBox volumeValueCurrencyBox = volumeValueCurrencyBoxTuple.first;
volumeTextField = volumeValueCurrencyBoxTuple.second;
volumeInfoInputTextField = volumeValueCurrencyBoxTuple.second;
volumeTextField = volumeInfoInputTextField.getInputTextField();
editOfferElements.add(volumeTextField);
volumeCurrencyLabel = volumeValueCurrencyBoxTuple.third;
editOfferElements.add(volumeCurrencyLabel);
Expand Down
25 changes: 21 additions & 4 deletions src/main/java/bisq/desktop/main/offer/takeoffer/TakeOfferView.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import bisq.desktop.components.BalanceTextField;
import bisq.desktop.components.BusyAnimation;
import bisq.desktop.components.FundsTextField;
import bisq.desktop.components.InfoTextField;
import bisq.desktop.components.InputTextField;
import bisq.desktop.components.TitledGroupBg;
import bisq.desktop.main.MainView;
Expand All @@ -49,6 +50,7 @@
import bisq.desktop.util.GUIUtil;
import bisq.desktop.util.Layout;

import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferPayload;
Expand Down Expand Up @@ -111,6 +113,7 @@
import static bisq.desktop.util.FormBuilder.addLabelFundsTextfield;
import static bisq.desktop.util.FormBuilder.getAmountCurrencyBox;
import static bisq.desktop.util.FormBuilder.getNonEditableValueCurrencyBox;
import static bisq.desktop.util.FormBuilder.getNonEditableValueCurrencyBoxWithInfo;
import static javafx.beans.binding.Bindings.createStringBinding;

@FxmlView
Expand Down Expand Up @@ -152,6 +155,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
private boolean offerDetailsWindowDisplayed, clearXchangeWarningDisplayed;
private SimpleBooleanProperty errorPopupDisplayed;
private ChangeListener<Boolean> getShowWalletFundedNotificationListener;
private InfoTextField volumeInfoTextField;

///////////////////////////////////////////////////////////////////////////////////////////
// Constructor, lifecycle
Expand Down Expand Up @@ -324,6 +328,9 @@ public void initWithData(Offer offer) {
addressTextField.setPaymentLabel(model.getPaymentLabel());
addressTextField.setAddress(model.dataModel.getAddressEntry().getAddressString());

if (CurrencyUtil.isFiatCurrency(offer.getCurrencyCode()))
volumeInfoTextField.setContentForPrivacyPopOver(createPopoverLabel(Res.get("offerbook.info.roundedFiatVolume")));

if (offer.getPrice() == null)
new Popup<>().warning(Res.get("takeOffer.noPriceFeedAvailable"))
.onClose(this::close)
Expand Down Expand Up @@ -496,7 +503,7 @@ private void close() {

private void addBindings() {
amountTextField.textProperty().bindBidirectional(model.amount);
volumeTextField.textProperty().bindBidirectional(model.volume);
volumeInfoTextField.textProperty().bindBidirectional(model.volume);
totalToPayTextField.textProperty().bind(model.totalToPay);
addressTextField.amountAsCoinProperty().bind(model.dataModel.getMissingCoin());
amountTextField.validationResultProperty().bind(model.amountValidationResult);
Expand All @@ -515,7 +522,7 @@ private void addBindings() {

private void removeBindings() {
amountTextField.textProperty().unbindBidirectional(model.amount);
volumeTextField.textProperty().unbindBidirectional(model.volume);
volumeInfoTextField.textProperty().unbindBidirectional(model.volume);
totalToPayTextField.textProperty().unbind();
addressTextField.amountAsCoinProperty().unbind();
amountTextField.validationResultProperty().unbind();
Expand Down Expand Up @@ -941,9 +948,11 @@ private void addAmountPriceFields() {
resultLabel.setPadding(new Insets(14, 2, 0, 2));

// volume
Tuple3<HBox, TextField, Label> volumeValueCurrencyBoxTuple = getNonEditableValueCurrencyBox();
Tuple3<HBox, InfoTextField, Label> volumeValueCurrencyBoxTuple = getNonEditableValueCurrencyBoxWithInfo();
HBox volumeValueCurrencyBox = volumeValueCurrencyBoxTuple.first;
volumeTextField = volumeValueCurrencyBoxTuple.second;

volumeInfoTextField = volumeValueCurrencyBoxTuple.second;
volumeTextField = volumeInfoTextField.getTextField();
volumeCurrencyLabel = volumeValueCurrencyBoxTuple.third;
Tuple2<Label, VBox> volumeInputBoxTuple = getTradeInputBox(volumeValueCurrencyBox, model.volumeDescriptionLabel.get());
volumeDescriptionLabel = volumeInputBoxTuple.first;
Expand Down Expand Up @@ -1069,6 +1078,14 @@ private GridPane createInfoPopover() {
return infoGridPane;
}

private Label createPopoverLabel(String text) {
final Label label = new Label(text);
label.setPrefWidth(300);
label.setWrapText(true);
label.setPadding(new Insets(10));
return label;
}

private void addPayInfoEntry(GridPane infoGridPane, int row, String labelText, String value) {
Label label = new AutoTooltipLabel(labelText);
TextField textField = new TextField(value);
Expand Down
Loading