Show valuation in BTC balance tooltips

When hovering over the available, reserved, and locked BTC balances
in the main view, show the market price valuation based on your
preferred currency.

Fixes https://github.com/bisq-network/bisq/issues/1770
This commit is contained in:
Devin Bileck 2019-02-27 16:59:32 -08:00
parent a9ee15d9f6
commit 1d55d06fce
No known key found for this signature in database
GPG key ID: 38750B26EA8B8C93
3 changed files with 84 additions and 3 deletions

View file

@ -40,6 +40,7 @@ import bisq.desktop.main.settings.SettingsView;
import bisq.desktop.util.Transitions; import bisq.desktop.util.Transitions;
import bisq.core.exceptions.BisqException; import bisq.core.exceptions.BisqException;
import bisq.core.locale.GlobalSettings;
import bisq.core.locale.Res; import bisq.core.locale.Res;
import bisq.core.util.BSFormatter; import bisq.core.util.BSFormatter;
@ -80,11 +81,17 @@ import javafx.geometry.Insets;
import javafx.geometry.Orientation; import javafx.geometry.Orientation;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.beans.binding.ObjectBinding;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
import lombok.Setter; import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -186,6 +193,11 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
JFXBadge daoButtonWithBadge = new JFXBadge(daoButton); JFXBadge daoButtonWithBadge = new JFXBadge(daoButton);
daoButtonWithBadge.getStyleClass().add("new"); daoButtonWithBadge.getStyleClass().add("new");
Locale locale = GlobalSettings.getLocale();
DecimalFormat currencyFormat = (DecimalFormat) NumberFormat.getNumberInstance(locale);
currencyFormat.setMinimumFractionDigits(2);
currencyFormat.setMaximumFractionDigits(2);
root.sceneProperty().addListener((observable, oldValue, newValue) -> { root.sceneProperty().addListener((observable, oldValue, newValue) -> {
if (newValue != null) { if (newValue != null) {
newValue.addEventHandler(KeyEvent.KEY_RELEASED, keyEvent -> { newValue.addEventHandler(KeyEvent.KEY_RELEASED, keyEvent -> {
@ -231,15 +243,75 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
Tuple2<Label, VBox> availableBalanceBox = getBalanceBox(Res.get("mainView.balance.available")); Tuple2<Label, VBox> availableBalanceBox = getBalanceBox(Res.get("mainView.balance.available"));
availableBalanceBox.first.textProperty().bind(model.getAvailableBalance()); availableBalanceBox.first.textProperty().bind(model.getAvailableBalance());
availableBalanceBox.first.setPrefWidth(100); availableBalanceBox.first.setPrefWidth(100);
availableBalanceBox.first.setTooltip(new Tooltip(Res.get("mainView.balance.available"))); availableBalanceBox.first.tooltipProperty().bind(new ObjectBinding<>() {
{
bind(model.getAvailableBalance());
bind(model.getMarketPrice());
}
@Override
protected Tooltip computeValue() {
String tooltipText = Res.get("mainView.balance.available");
try {
double availableBalance = Double.parseDouble(
model.getAvailableBalance().getValue().replace("BTC", ""));
double marketPrice = Double.parseDouble(model.getMarketPrice().getValue());
tooltipText += "\n" + currencyFormat.format(availableBalance * marketPrice) +
" " + model.getPreferences().getPreferredTradeCurrency().getCode();
} catch (NullPointerException | NumberFormatException e) {
// Either the balance or market price is not available yet
}
return new Tooltip(tooltipText);
}
});
Tuple2<Label, VBox> reservedBalanceBox = getBalanceBox(Res.get("mainView.balance.reserved.short")); Tuple2<Label, VBox> reservedBalanceBox = getBalanceBox(Res.get("mainView.balance.reserved.short"));
reservedBalanceBox.first.textProperty().bind(model.getReservedBalance()); reservedBalanceBox.first.textProperty().bind(model.getReservedBalance());
reservedBalanceBox.first.setTooltip(new Tooltip(Res.get("mainView.balance.reserved"))); reservedBalanceBox.first.tooltipProperty().bind(new ObjectBinding<>() {
{
bind(model.getReservedBalance());
bind(model.getMarketPrice());
}
@Override
protected Tooltip computeValue() {
String tooltipText = Res.get("mainView.balance.reserved");
try {
double reservedBalance = Double.parseDouble(
model.getReservedBalance().getValue().replace("BTC", ""));
double marketPrice = Double.parseDouble(model.getMarketPrice().getValue());
tooltipText += "\n" + currencyFormat.format(reservedBalance * marketPrice) +
" " + model.getPreferences().getPreferredTradeCurrency().getCode();
} catch (NullPointerException | NumberFormatException e) {
// Either the balance or market price is not available yet
}
return new Tooltip(tooltipText);
}
});
Tuple2<Label, VBox> lockedBalanceBox = getBalanceBox(Res.get("mainView.balance.locked.short")); Tuple2<Label, VBox> lockedBalanceBox = getBalanceBox(Res.get("mainView.balance.locked.short"));
lockedBalanceBox.first.textProperty().bind(model.getLockedBalance()); lockedBalanceBox.first.textProperty().bind(model.getLockedBalance());
lockedBalanceBox.first.setTooltip(new Tooltip(Res.get("mainView.balance.locked"))); lockedBalanceBox.first.tooltipProperty().bind(new ObjectBinding<>() {
{
bind(model.getLockedBalance());
bind(model.getMarketPrice());
}
@Override
protected Tooltip computeValue() {
String tooltipText = Res.get("mainView.balance.locked");
try {
double lockedBalance = Double.parseDouble(
model.getLockedBalance().getValue().replace("BTC", ""));
double marketPrice = Double.parseDouble(model.getMarketPrice().getValue());
tooltipText += "\n" + currencyFormat.format(lockedBalance * marketPrice) +
" " + model.getPreferences().getPreferredTradeCurrency().getCode();
} catch (NullPointerException | NumberFormatException e) {
// Either the balance or market price is not available yet
}
return new Tooltip(tooltipText);
}
});
HBox primaryNav = new HBox(marketButton, getNavigationSeparator(), buyButton, getNavigationSeparator(), HBox primaryNav = new HBox(marketButton, getNavigationSeparator(), buyButton, getNavigationSeparator(),
sellButton, getNavigationSeparator(), portfolioButtonWithBadge, getNavigationSeparator(), fundsButton); sellButton, getNavigationSeparator(), portfolioButtonWithBadge, getNavigationSeparator(), fundsButton);

View file

@ -97,6 +97,7 @@ public class MainViewModel implements ViewModel, BisqSetup.BisqSetupCompleteList
private final DaoPresentation daoPresentation; private final DaoPresentation daoPresentation;
private final P2PService p2PService; private final P2PService p2PService;
private final TradeManager tradeManager; private final TradeManager tradeManager;
@Getter
private final Preferences preferences; private final Preferences preferences;
private final PrivateNotificationManager privateNotificationManager; private final PrivateNotificationManager privateNotificationManager;
private final WalletPasswordWindow walletPasswordWindow; private final WalletPasswordWindow walletPasswordWindow;
@ -591,6 +592,10 @@ public class MainViewModel implements ViewModel, BisqSetup.BisqSetupCompleteList
return marketPricePresentation.getMarketPriceUpdated(); return marketPricePresentation.getMarketPriceUpdated();
} }
StringProperty getMarketPrice() {
return marketPricePresentation.getMarketPrice();
}
public ObservableList<PriceFeedComboBoxItem> getPriceFeedComboBoxItems() { public ObservableList<PriceFeedComboBoxItem> getPriceFeedComboBoxItems() {
return marketPricePresentation.getPriceFeedComboBoxItems(); return marketPricePresentation.getPriceFeedComboBoxItems();
} }

View file

@ -237,4 +237,8 @@ public class MarketPricePresentation {
public IntegerProperty getMarketPriceUpdated() { public IntegerProperty getMarketPriceUpdated() {
return marketPriceUpdated; return marketPriceUpdated;
} }
public StringProperty getMarketPrice() {
return marketPrice;
}
} }