mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-06-23 06:14:11 -04:00
major update to look and feel of desktop ui (#1733)
This commit is contained in:
parent
c239f9aac0
commit
aa1eb70d9a
141 changed files with 2395 additions and 995 deletions
|
@ -51,6 +51,7 @@ import org.bitcoinj.utils.MonetaryFormat;
|
|||
import java.math.BigInteger;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
|
||||
public class VolumeUtil {
|
||||
|
@ -187,4 +188,35 @@ public class VolumeUtil {
|
|||
private static MonetaryFormat getMonetaryFormat(String currencyCode) {
|
||||
return CurrencyUtil.isVolumeRoundedToNearestUnit(currencyCode) ? VOLUME_FORMAT_UNIT : VOLUME_FORMAT_PRECISE;
|
||||
}
|
||||
|
||||
public static Volume sum(Collection<Volume> volumes) {
|
||||
if (volumes == null || volumes.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
Volume sum = null;
|
||||
for (Volume volume : volumes) {
|
||||
if (sum == null) {
|
||||
sum = volume;
|
||||
} else {
|
||||
if (!sum.getCurrencyCode().equals(volume.getCurrencyCode())) {
|
||||
throw new IllegalArgumentException("Cannot sum volumes with different currencies");
|
||||
}
|
||||
sum = add(sum, volume);
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
public static Volume add(Volume volume1, Volume volume2) {
|
||||
if (volume1 == null) return volume2;
|
||||
if (volume2 == null) return volume1;
|
||||
if (!volume1.getCurrencyCode().equals(volume2.getCurrencyCode())) {
|
||||
throw new IllegalArgumentException("Cannot add volumes with different currencies");
|
||||
}
|
||||
if (volume1.getMonetary() instanceof CryptoMoney) {
|
||||
return new Volume(((CryptoMoney) volume1.getMonetary()).add((CryptoMoney) volume2.getMonetary()));
|
||||
} else {
|
||||
return new Volume(((TraditionalMoney) volume1.getMonetary()).add((TraditionalMoney) volume2.getMonetary()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -315,9 +315,6 @@ market.tabs.spreadCurrency=Offers by Currency
|
|||
market.tabs.spreadPayment=Offers by Payment Method
|
||||
market.tabs.trades=Trades
|
||||
|
||||
# OfferBookView
|
||||
market.offerBook.filterPrompt=Filter
|
||||
|
||||
# OfferBookChartView
|
||||
market.offerBook.sellOffersHeaderLabel=Sell {0} to
|
||||
market.offerBook.buyOffersHeaderLabel=Buy {0} from
|
||||
|
@ -410,8 +407,10 @@ shared.notSigned.noNeedAlts=Cryptocurrency accounts do not feature signing or ag
|
|||
|
||||
offerbook.nrOffers=No. of offers: {0}
|
||||
offerbook.volume={0} (min - max)
|
||||
offerbook.volumeTotal={0} {1}
|
||||
offerbook.deposit=Deposit XMR (%)
|
||||
offerbook.deposit.help=Deposit paid by each trader to guarantee the trade. Will be returned when the trade is completed.
|
||||
offerbook.XMRTotal=XMR ({0})
|
||||
|
||||
offerbook.createNewOffer=Create offer to {0} {1}
|
||||
offerbook.createOfferDisabled.tooltip=You can only create one offer at a time
|
||||
|
@ -1162,8 +1161,6 @@ support.tab.refund.support=Refund
|
|||
support.tab.arbitration.support=Arbitration
|
||||
support.tab.legacyArbitration.support=Legacy Arbitration
|
||||
support.tab.ArbitratorsSupportTickets={0}'s tickets
|
||||
support.filter=Search disputes
|
||||
support.filter.prompt=Enter trade ID, date, onion address or account data
|
||||
support.tab.SignedOffers=Signed Offers
|
||||
support.prompt.signedOffer.penalty.msg=This will charge the maker a penalty fee and return the remaining trade funds to their wallet. Are you sure you want to send?\n\n\
|
||||
Offer ID: {0}\n\
|
||||
|
@ -1337,6 +1334,7 @@ setting.preferences.displayOptions=Display options
|
|||
setting.preferences.showOwnOffers=Show my own offers in offer book
|
||||
setting.preferences.useAnimations=Use animations
|
||||
setting.preferences.useDarkMode=Use dark mode
|
||||
setting.preferences.useLightMode=Use light mode
|
||||
setting.preferences.sortWithNumOffers=Sort market lists with no. of offers/trades
|
||||
setting.preferences.onlyShowPaymentMethodsFromAccount=Hide non-supported payment methods
|
||||
setting.preferences.denyApiTaker=Deny takers using the API
|
||||
|
@ -2012,6 +2010,7 @@ offerDetailsWindow.confirm.takerCrypto=Confirm: Take offer to {0} {1}
|
|||
offerDetailsWindow.creationDate=Creation date
|
||||
offerDetailsWindow.makersOnion=Maker's onion address
|
||||
offerDetailsWindow.challenge=Offer passphrase
|
||||
offerDetailsWindow.challenge.copy=Copy passphrase to share with your peer
|
||||
|
||||
qRCodeWindow.headline=QR Code
|
||||
qRCodeWindow.msg=Please use this QR code for funding your Haveno wallet from your external wallet.
|
||||
|
|
|
@ -315,7 +315,6 @@ market.tabs.spreadPayment=Nabídky podle způsobů platby
|
|||
market.tabs.trades=Obchody
|
||||
|
||||
# OfferBookView
|
||||
market.offerBook.filterPrompt=Filtr
|
||||
|
||||
# OfferBookChartView
|
||||
market.offerBook.sellOffersHeaderLabel=Prodat {0} kupujícímu
|
||||
|
@ -1125,8 +1124,6 @@ support.tab.refund.support=Vrácení peněz
|
|||
support.tab.arbitration.support=Arbitráž
|
||||
support.tab.legacyArbitration.support=Starší arbitráž
|
||||
support.tab.ArbitratorsSupportTickets=Úkoly pro {0}
|
||||
support.filter=Hledat spory
|
||||
support.filter.prompt=Zadejte ID obchodu, datum, onion adresu nebo údaje o účtu
|
||||
support.tab.SignedOffers=Podepsané nabídky
|
||||
support.prompt.signedOffer.penalty.msg=Tím se tvůrci účtuje sankční poplatek a zbývající prostředky z obchodu se vrátí do jeho peněženky. Jste si jisti, že chcete odeslat?\n\n\
|
||||
ID nabídky: {0}\n\
|
||||
|
@ -1300,6 +1297,7 @@ setting.preferences.displayOptions=Zobrazit možnosti
|
|||
setting.preferences.showOwnOffers=Zobrazit mé vlastní nabídky v seznamu nabídek
|
||||
setting.preferences.useAnimations=Použít animace
|
||||
setting.preferences.useDarkMode=Použít tmavý režim
|
||||
setting.preferences.useLightMode=Použijte světlý režim
|
||||
setting.preferences.sortWithNumOffers=Seřadit seznamy trhů s počtem nabídek/obchodů
|
||||
setting.preferences.onlyShowPaymentMethodsFromAccount=Skrýt nepodporované způsoby platby
|
||||
setting.preferences.denyApiTaker=Odmítat příjemce, kteří používají API
|
||||
|
@ -1975,6 +1973,7 @@ offerDetailsWindow.confirm.takerCrypto=Potvrďte: Přijmout nabídku {0} {1}
|
|||
offerDetailsWindow.creationDate=Datum vzniku
|
||||
offerDetailsWindow.makersOnion=Onion adresa tvůrce
|
||||
offerDetailsWindow.challenge=Passphrase nabídky
|
||||
offerDetailsWindow.challenge.copy=Zkopírujte přístupovou frázi pro sdílení s protějškem
|
||||
|
||||
qRCodeWindow.headline=QR Kód
|
||||
qRCodeWindow.msg=Použijte tento QR kód k financování vaší peněženky Haveno z vaší externí peněženky.
|
||||
|
|
|
@ -927,8 +927,6 @@ support.tab.mediation.support=Mediation
|
|||
support.tab.arbitration.support=Vermittlung
|
||||
support.tab.legacyArbitration.support=Legacy-Vermittlung
|
||||
support.tab.ArbitratorsSupportTickets={0} Tickets
|
||||
support.filter=Konflikte durchsuchen
|
||||
support.filter.prompt=Tragen sie Handel ID, Datum, Onion Adresse oder Kontodaten
|
||||
|
||||
support.sigCheck.button=Signatur überprüfen
|
||||
support.sigCheck.popup.info=Fügen Sie die Zusammenfassungsnachricht des Schiedsverfahrens ein. Mit diesem Tool kann jeder Benutzer überprüfen, ob die Unterschrift des Schiedsrichters mit der Zusammenfassungsnachricht übereinstimmt.
|
||||
|
@ -1035,6 +1033,7 @@ setting.preferences.displayOptions=Darstellungsoptionen
|
|||
setting.preferences.showOwnOffers=Eigenen Angebote im Angebotsbuch zeigen
|
||||
setting.preferences.useAnimations=Animationen abspielen
|
||||
setting.preferences.useDarkMode=Nacht-Modus benutzen
|
||||
setting.preferences.useLightMode=Leichtmodus verwenden
|
||||
setting.preferences.sortWithNumOffers=Marktlisten nach Anzahl der Angebote/Trades sortieren
|
||||
setting.preferences.onlyShowPaymentMethodsFromAccount=Nicht unterstützte Zahlungsmethoden ausblenden
|
||||
setting.preferences.denyApiTaker=Taker die das API nutzen vermeiden
|
||||
|
@ -1477,6 +1476,7 @@ offerDetailsWindow.confirm.taker=Bestätigen: Angebot annehmen monero zu {0}
|
|||
offerDetailsWindow.creationDate=Erstellungsdatum
|
||||
offerDetailsWindow.makersOnion=Onion-Adresse des Erstellers
|
||||
offerDetailsWindow.challenge=Angebots-Passphrase
|
||||
offerDetailsWindow.challenge.copy=Passphrase kopieren, um sie mit Ihrem Handelspartner zu teilen
|
||||
|
||||
qRCodeWindow.headline=QR Code
|
||||
qRCodeWindow.msg=Bitte nutzen Sie diesen QR Code um Ihr Haveno Wallet von Ihrem externen Wallet aufzuladen.
|
||||
|
|
|
@ -928,8 +928,6 @@ support.tab.mediation.support=Mediación
|
|||
support.tab.arbitration.support=Arbitraje
|
||||
support.tab.legacyArbitration.support=Legado de arbitraje
|
||||
support.tab.ArbitratorsSupportTickets=Tickets de {0}
|
||||
support.filter=Buscar disputas
|
||||
support.filter.prompt=Introduzca ID de transacción, fecha, dirección onion o datos de cuenta.
|
||||
|
||||
support.sigCheck.button=Comprobar firma
|
||||
support.sigCheck.popup.info=Pegue el mensaje resumido del proceso de arbitraje. Con esta herramienta, cualquier usuario puede verificar si la firma del árbitro coincide con el mensaje resumido.
|
||||
|
@ -1036,6 +1034,7 @@ setting.preferences.displayOptions=Mostrar opciones
|
|||
setting.preferences.showOwnOffers=Mostrar mis propias ofertas en el libro de ofertas
|
||||
setting.preferences.useAnimations=Usar animaciones
|
||||
setting.preferences.useDarkMode=Usar modo oscuro
|
||||
setting.preferences.useLightMode=Usar modo claro
|
||||
setting.preferences.sortWithNumOffers=Ordenar listas de mercado por número de ofertas/intercambios
|
||||
setting.preferences.onlyShowPaymentMethodsFromAccount=Ocultar métodos de pago no soportados
|
||||
setting.preferences.denyApiTaker=Denegar tomadores usando la misma API
|
||||
|
@ -1478,6 +1477,7 @@ offerDetailsWindow.confirm.taker=Confirmar: Tomar oferta {0} monero
|
|||
offerDetailsWindow.creationDate=Fecha de creación
|
||||
offerDetailsWindow.makersOnion=Dirección onion del creador
|
||||
offerDetailsWindow.challenge=Frase de contraseña de la oferta
|
||||
offerDetailsWindow.challenge.copy=Copiar frase de contraseña para compartir con tu contraparte
|
||||
|
||||
qRCodeWindow.headline=Código QR
|
||||
qRCodeWindow.msg=Por favor, utilice este código QR para fondear su billetera Haveno desde su billetera externa.
|
||||
|
|
|
@ -218,7 +218,7 @@ shared.delayedPayoutTxId=Delayed payout transaction ID
|
|||
shared.delayedPayoutTxReceiverAddress=Delayed payout transaction sent to
|
||||
shared.unconfirmedTransactionsLimitReached=You have too many unconfirmed transactions at the moment. Please try again later.
|
||||
shared.numItemsLabel=Number of entries: {0}
|
||||
shared.filter=Filter
|
||||
shared.filter=فیلتر
|
||||
shared.enabled=Enabled
|
||||
|
||||
|
||||
|
@ -926,8 +926,6 @@ support.tab.mediation.support=Mediation
|
|||
support.tab.arbitration.support=Arbitration
|
||||
support.tab.legacyArbitration.support=Legacy Arbitration
|
||||
support.tab.ArbitratorsSupportTickets={0}'s tickets
|
||||
support.filter=Search disputes
|
||||
support.filter.prompt=Enter trade ID, date, onion address or account data
|
||||
|
||||
support.sigCheck.button=Check signature
|
||||
support.sigCheck.popup.header=Verify dispute result signature
|
||||
|
@ -1031,7 +1029,8 @@ setting.preferences.addCrypto=افزودن آلتکوین
|
|||
setting.preferences.displayOptions=نمایش گزینهها
|
||||
setting.preferences.showOwnOffers=نمایش پیشنهادهای من در دفتر پیشنهاد
|
||||
setting.preferences.useAnimations=استفاده از انیمیشنها
|
||||
setting.preferences.useDarkMode=Use dark mode
|
||||
setting.preferences.useDarkMode=حالت تاریک را استفاده کنید
|
||||
setting.preferences.useLightMode=حالت روشن را استفاده کنید
|
||||
setting.preferences.sortWithNumOffers=مرتب سازی لیستها با تعداد معاملات/پیشنهادها
|
||||
setting.preferences.onlyShowPaymentMethodsFromAccount=Hide non-supported payment methods
|
||||
setting.preferences.denyApiTaker=Deny takers using the API
|
||||
|
@ -1473,6 +1472,7 @@ offerDetailsWindow.confirm.taker=تأیید: پیشنهاد را به {0} بپذ
|
|||
offerDetailsWindow.creationDate=تاریخ ایجاد
|
||||
offerDetailsWindow.makersOnion=آدرس Onion سفارش گذار
|
||||
offerDetailsWindow.challenge=Passphrase de l'offre
|
||||
offerDetailsWindow.challenge.copy=عبارت عبور را برای به اشتراکگذاری با همتا کپی کنید
|
||||
|
||||
qRCodeWindow.headline=QR Code
|
||||
qRCodeWindow.msg=Please use this QR code for funding your Haveno wallet from your external wallet.
|
||||
|
|
|
@ -929,8 +929,6 @@ support.tab.mediation.support=Médiation
|
|||
support.tab.arbitration.support=Arbitrage
|
||||
support.tab.legacyArbitration.support=Conclusion d'arbitrage
|
||||
support.tab.ArbitratorsSupportTickets=Tickets de {0}
|
||||
support.filter=Chercher les litiges
|
||||
support.filter.prompt=Saisissez l'ID du trade, la date, l'adresse "onion" ou les données du compte.
|
||||
|
||||
support.sigCheck.button=Vérifier la signature
|
||||
support.sigCheck.popup.info=Collez le message récapitulatif du processus d'arbitrage. Avec cet outil, n'importe quel utilisateur peut vérifier si la signature de l'arbitre correspond au message récapitulatif.
|
||||
|
@ -1037,6 +1035,7 @@ setting.preferences.displayOptions=Afficher les options
|
|||
setting.preferences.showOwnOffers=Montrer mes ordres dans le livre des ordres
|
||||
setting.preferences.useAnimations=Utiliser des animations
|
||||
setting.preferences.useDarkMode=Utiliser le mode sombre
|
||||
setting.preferences.useLightMode=Utiliser le mode clair
|
||||
setting.preferences.sortWithNumOffers=Trier les listes de marché avec le nombre d'ordres/de transactions
|
||||
setting.preferences.onlyShowPaymentMethodsFromAccount=Masquer les méthodes de paiement non supportées
|
||||
setting.preferences.denyApiTaker=Refuser les preneurs utilisant l'API
|
||||
|
@ -1479,6 +1478,7 @@ offerDetailsWindow.confirm.taker=Confirmer: Acceptez l''ordre de {0} monero
|
|||
offerDetailsWindow.creationDate=Date de création
|
||||
offerDetailsWindow.makersOnion=Adresse onion du maker
|
||||
offerDetailsWindow.challenge=Phrase secrète de l'offre
|
||||
offerDetailsWindow.challenge.copy=Copier la phrase secrète à partager avec votre pair
|
||||
|
||||
qRCodeWindow.headline=QR Code
|
||||
qRCodeWindow.msg=Veuillez utiliser le code QR pour recharger du portefeuille externe au portefeuille Haveno.
|
||||
|
|
|
@ -218,7 +218,7 @@ shared.delayedPayoutTxId=Delayed payout transaction ID
|
|||
shared.delayedPayoutTxReceiverAddress=Delayed payout transaction sent to
|
||||
shared.unconfirmedTransactionsLimitReached=Al momento, hai troppe transazioni non confermate. Per favore riprova più tardi.
|
||||
shared.numItemsLabel=Number of entries: {0}
|
||||
shared.filter=Filter
|
||||
shared.filter=Filtro
|
||||
shared.enabled=Enabled
|
||||
|
||||
|
||||
|
@ -927,8 +927,6 @@ support.tab.mediation.support=Mediazione
|
|||
support.tab.arbitration.support=Arbitrato
|
||||
support.tab.legacyArbitration.support=Arbitrato Legacy
|
||||
support.tab.ArbitratorsSupportTickets=I ticket di {0}
|
||||
support.filter=Search disputes
|
||||
support.filter.prompt=Inserisci ID commerciale, data, indirizzo onion o dati dell'account
|
||||
|
||||
support.sigCheck.button=Check signature
|
||||
support.sigCheck.popup.header=Verify dispute result signature
|
||||
|
@ -1034,6 +1032,7 @@ setting.preferences.displayOptions=Mostra opzioni
|
|||
setting.preferences.showOwnOffers=Mostra le mie offerte nel libro delle offerte
|
||||
setting.preferences.useAnimations=Usa animazioni
|
||||
setting.preferences.useDarkMode=Usa modalità notte
|
||||
setting.preferences.useLightMode=Usa la modalità chiara
|
||||
setting.preferences.sortWithNumOffers=Ordina le liste di mercato con n. di offerte/scambi
|
||||
setting.preferences.onlyShowPaymentMethodsFromAccount=Hide non-supported payment methods
|
||||
setting.preferences.denyApiTaker=Deny takers using the API
|
||||
|
@ -1476,6 +1475,7 @@ offerDetailsWindow.confirm.taker=Conferma: Accetta l'offerta a {0} monero
|
|||
offerDetailsWindow.creationDate=Data di creazione
|
||||
offerDetailsWindow.makersOnion=Indirizzo .onion del maker
|
||||
offerDetailsWindow.challenge=Passphrase dell'offerta
|
||||
offerDetailsWindow.challenge.copy=Copia la frase segreta da condividere con il tuo interlocutore
|
||||
|
||||
qRCodeWindow.headline=QR Code
|
||||
qRCodeWindow.msg=Please use this QR code for funding your Haveno wallet from your external wallet.
|
||||
|
|
|
@ -927,8 +927,6 @@ support.tab.mediation.support=調停
|
|||
support.tab.arbitration.support=仲裁
|
||||
support.tab.legacyArbitration.support=レガシー仲裁
|
||||
support.tab.ArbitratorsSupportTickets={0} のチケット
|
||||
support.filter=係争を検索
|
||||
support.filter.prompt=トレードID、日付、onionアドレスまたはアカウントデータを入力してください
|
||||
|
||||
support.sigCheck.button=Check signature
|
||||
support.sigCheck.popup.info=仲裁プロセスの要約メッセージを貼り付けてください。このツールを使用すると、どんなユーザーでも仲裁者の署名が要約メッセージと一致するかどうかを確認できます。
|
||||
|
@ -1035,6 +1033,7 @@ setting.preferences.displayOptions=表示設定
|
|||
setting.preferences.showOwnOffers=オファーブックに自分のオファーを表示
|
||||
setting.preferences.useAnimations=アニメーションを使用
|
||||
setting.preferences.useDarkMode=ダークモードを利用
|
||||
setting.preferences.useLightMode=ライトモードを使用する
|
||||
setting.preferences.sortWithNumOffers=市場リストをオファー/トレードの数で並び替える
|
||||
setting.preferences.onlyShowPaymentMethodsFromAccount=サポートされていない支払い方法を非表示にする
|
||||
setting.preferences.denyApiTaker=APIを使用するテイカーを拒否する
|
||||
|
@ -1477,6 +1476,7 @@ offerDetailsWindow.confirm.taker=承認: ビットコインを{0}オファーを
|
|||
offerDetailsWindow.creationDate=作成日
|
||||
offerDetailsWindow.makersOnion=メイカーのonionアドレス
|
||||
offerDetailsWindow.challenge=オファーパスフレーズ
|
||||
offerDetailsWindow.challenge.copy=ピアと共有するためにパスフレーズをコピーする
|
||||
|
||||
qRCodeWindow.headline=QRコード
|
||||
qRCodeWindow.msg=外部ウォレットからHavenoウォレットへ送金するのに、このQRコードを利用して下さい。
|
||||
|
|
|
@ -221,7 +221,7 @@ shared.delayedPayoutTxId=Delayed payout transaction ID
|
|||
shared.delayedPayoutTxReceiverAddress=Delayed payout transaction sent to
|
||||
shared.unconfirmedTransactionsLimitReached=No momento, você possui muitas transações não-confirmadas. Tente novamente mais tarde.
|
||||
shared.numItemsLabel=Number of entries: {0}
|
||||
shared.filter=Filter
|
||||
shared.filter=Filtro
|
||||
shared.enabled=Enabled
|
||||
|
||||
|
||||
|
@ -929,8 +929,6 @@ support.tab.mediation.support=Mediação
|
|||
support.tab.arbitration.support=Arbitragem
|
||||
support.tab.legacyArbitration.support=Arbitração antiga
|
||||
support.tab.ArbitratorsSupportTickets=Tickets de {0}
|
||||
support.filter=Search disputes
|
||||
support.filter.prompt=Insira ID da negociação. data. endereço onion ou dados da conta
|
||||
|
||||
support.sigCheck.button=Check signature
|
||||
support.sigCheck.popup.header=Verify dispute result signature
|
||||
|
@ -1036,6 +1034,7 @@ setting.preferences.displayOptions=Opções de exibição
|
|||
setting.preferences.showOwnOffers=Exibir minhas ofertas no livro de ofertas
|
||||
setting.preferences.useAnimations=Usar animações
|
||||
setting.preferences.useDarkMode=Usar modo escuro
|
||||
setting.preferences.useLightMode=Usar modo claro
|
||||
setting.preferences.sortWithNumOffers=Ordenar pelo nº de ofertas/negociações
|
||||
setting.preferences.onlyShowPaymentMethodsFromAccount=Hide non-supported payment methods
|
||||
setting.preferences.denyApiTaker=Deny takers using the API
|
||||
|
@ -1480,6 +1479,7 @@ offerDetailsWindow.confirm.taker=Confirmar: Aceitar oferta de {0} monero
|
|||
offerDetailsWindow.creationDate=Criada em
|
||||
offerDetailsWindow.makersOnion=Endereço onion do ofertante
|
||||
offerDetailsWindow.challenge=Passphrase da oferta
|
||||
offerDetailsWindow.challenge.copy=Copiar frase secreta para compartilhar com seu par
|
||||
|
||||
qRCodeWindow.headline=QR Code
|
||||
qRCodeWindow.msg=Please use this QR code for funding your Haveno wallet from your external wallet.
|
||||
|
|
|
@ -218,7 +218,7 @@ shared.delayedPayoutTxId=Delayed payout transaction ID
|
|||
shared.delayedPayoutTxReceiverAddress=Delayed payout transaction sent to
|
||||
shared.unconfirmedTransactionsLimitReached=You have too many unconfirmed transactions at the moment. Please try again later.
|
||||
shared.numItemsLabel=Number of entries: {0}
|
||||
shared.filter=Filter
|
||||
shared.filter=Filtro
|
||||
shared.enabled=Enabled
|
||||
|
||||
|
||||
|
@ -926,8 +926,6 @@ support.tab.mediation.support=Mediação
|
|||
support.tab.arbitration.support=Arbitragem
|
||||
support.tab.legacyArbitration.support=Arbitragem Antiga
|
||||
support.tab.ArbitratorsSupportTickets=Bilhetes de {0}
|
||||
support.filter=Search disputes
|
||||
support.filter.prompt=Insira o ID do negócio, data, endereço onion ou dados da conta
|
||||
|
||||
support.sigCheck.button=Check signature
|
||||
support.sigCheck.popup.header=Verify dispute result signature
|
||||
|
@ -1033,6 +1031,7 @@ setting.preferences.displayOptions=Mostrar opções
|
|||
setting.preferences.showOwnOffers=Mostrar as minhas próprias ofertas no livro de ofertas
|
||||
setting.preferences.useAnimations=Usar animações
|
||||
setting.preferences.useDarkMode=Usar o modo escuro
|
||||
setting.preferences.useLightMode=Usar modo claro
|
||||
setting.preferences.sortWithNumOffers=Ordenar listas de mercado por nº de ofertas/negociações:
|
||||
setting.preferences.onlyShowPaymentMethodsFromAccount=Hide non-supported payment methods
|
||||
setting.preferences.denyApiTaker=Deny takers using the API
|
||||
|
@ -1473,6 +1472,7 @@ offerDetailsWindow.confirm.taker=Confirmar: Aceitar oferta de {0} monero
|
|||
offerDetailsWindow.creationDate=Data de criação
|
||||
offerDetailsWindow.makersOnion=Endereço onion do ofertante
|
||||
offerDetailsWindow.challenge=Passphrase da oferta
|
||||
offerDetailsWindow.challenge.copy=Copiar frase secreta para compartilhar com seu parceiro
|
||||
|
||||
qRCodeWindow.headline=QR Code
|
||||
qRCodeWindow.msg=Please use this QR code for funding your Haveno wallet from your external wallet.
|
||||
|
|
|
@ -218,7 +218,7 @@ shared.delayedPayoutTxId=Delayed payout transaction ID
|
|||
shared.delayedPayoutTxReceiverAddress=Delayed payout transaction sent to
|
||||
shared.unconfirmedTransactionsLimitReached=You have too many unconfirmed transactions at the moment. Please try again later.
|
||||
shared.numItemsLabel=Number of entries: {0}
|
||||
shared.filter=Filter
|
||||
shared.filter=Фильтр
|
||||
shared.enabled=Enabled
|
||||
|
||||
|
||||
|
@ -926,8 +926,6 @@ support.tab.mediation.support=Mediation
|
|||
support.tab.arbitration.support=Arbitration
|
||||
support.tab.legacyArbitration.support=Legacy Arbitration
|
||||
support.tab.ArbitratorsSupportTickets={0}'s tickets
|
||||
support.filter=Search disputes
|
||||
support.filter.prompt=Введите идентификатор сделки, дату, onion-адрес или данные учётной записи
|
||||
|
||||
support.sigCheck.button=Check signature
|
||||
support.sigCheck.popup.header=Verify dispute result signature
|
||||
|
@ -1031,7 +1029,8 @@ setting.preferences.addCrypto=Добавить альткойн
|
|||
setting.preferences.displayOptions=Параметры отображения
|
||||
setting.preferences.showOwnOffers=Показать мои предложения в списке предложений
|
||||
setting.preferences.useAnimations=Использовать анимацию
|
||||
setting.preferences.useDarkMode=Use dark mode
|
||||
setting.preferences.useDarkMode=Использовать тёмный режим
|
||||
setting.preferences.useLightMode=Использовать светлый режим
|
||||
setting.preferences.sortWithNumOffers=Сортировать списки по кол-ву предложений/сделок
|
||||
setting.preferences.onlyShowPaymentMethodsFromAccount=Hide non-supported payment methods
|
||||
setting.preferences.denyApiTaker=Deny takers using the API
|
||||
|
@ -1474,6 +1473,7 @@ offerDetailsWindow.confirm.taker=Подтвердите: принять пред
|
|||
offerDetailsWindow.creationDate=Дата создания
|
||||
offerDetailsWindow.makersOnion=Onion-адрес мейкера
|
||||
offerDetailsWindow.challenge=Пароль предложения
|
||||
offerDetailsWindow.challenge.copy=Скопируйте кодовую фразу, чтобы поделиться с партнёром
|
||||
|
||||
qRCodeWindow.headline=QR Code
|
||||
qRCodeWindow.msg=Please use this QR code for funding your Haveno wallet from your external wallet.
|
||||
|
|
|
@ -218,7 +218,7 @@ shared.delayedPayoutTxId=Delayed payout transaction ID
|
|||
shared.delayedPayoutTxReceiverAddress=Delayed payout transaction sent to
|
||||
shared.unconfirmedTransactionsLimitReached=You have too many unconfirmed transactions at the moment. Please try again later.
|
||||
shared.numItemsLabel=Number of entries: {0}
|
||||
shared.filter=Filter
|
||||
shared.filter=ตัวกรอง
|
||||
shared.enabled=Enabled
|
||||
|
||||
|
||||
|
@ -926,8 +926,6 @@ support.tab.mediation.support=Mediation
|
|||
support.tab.arbitration.support=Arbitration
|
||||
support.tab.legacyArbitration.support=Legacy Arbitration
|
||||
support.tab.ArbitratorsSupportTickets={0}'s tickets
|
||||
support.filter=Search disputes
|
||||
support.filter.prompt=Enter trade ID, date, onion address or account data
|
||||
|
||||
support.sigCheck.button=Check signature
|
||||
support.sigCheck.popup.header=Verify dispute result signature
|
||||
|
@ -1031,7 +1029,8 @@ setting.preferences.addCrypto=เพิ่ม crypto
|
|||
setting.preferences.displayOptions=แสดงตัวเลือกเพิ่มเติม
|
||||
setting.preferences.showOwnOffers=แสดงข้อเสนอของฉันเองในสมุดข้อเสนอ
|
||||
setting.preferences.useAnimations=ใช้ภาพเคลื่อนไหว
|
||||
setting.preferences.useDarkMode=Use dark mode
|
||||
setting.preferences.useDarkMode=ใช้โหมดมืด
|
||||
setting.preferences.useLightMode=ใช้โหมดสว่าง
|
||||
setting.preferences.sortWithNumOffers=จัดเรียงรายการโดยเลขของข้อเสนอ / การซื้อขาย
|
||||
setting.preferences.onlyShowPaymentMethodsFromAccount=Hide non-supported payment methods
|
||||
setting.preferences.denyApiTaker=Deny takers using the API
|
||||
|
@ -1474,6 +1473,7 @@ offerDetailsWindow.confirm.taker=ยืนยัน: รับข้อเสน
|
|||
offerDetailsWindow.creationDate=วันที่สร้าง
|
||||
offerDetailsWindow.makersOnion=ที่อยู่ onion ของผู้สร้าง
|
||||
offerDetailsWindow.challenge=รหัสผ่านสำหรับข้อเสนอ
|
||||
offerDetailsWindow.challenge.copy=คัดลอกวลีรหัสเพื่อแชร์กับเพื่อนของคุณ
|
||||
|
||||
qRCodeWindow.headline=QR Code
|
||||
qRCodeWindow.msg=Please use this QR code for funding your Haveno wallet from your external wallet.
|
||||
|
|
|
@ -231,7 +231,7 @@ shared.delayedPayoutTxId=Gecikmiş ödeme işlem kimliği
|
|||
shared.delayedPayoutTxReceiverAddress=Gecikmiş ödeme işlemi gönderildi
|
||||
shared.unconfirmedTransactionsLimitReached=Şu anda çok fazla onaylanmamış işleminiz var. Lütfen daha sonra tekrar deneyin.
|
||||
shared.numItemsLabel=Girdi sayısı: {0}
|
||||
shared.filter=Filtrele
|
||||
shared.filter=Filtre
|
||||
shared.enabled=Etkin
|
||||
shared.pending=Beklemede
|
||||
shared.me=Ben
|
||||
|
@ -1120,8 +1120,6 @@ support.tab.refund.support=Geri Ödeme
|
|||
support.tab.arbitration.support=Arbitraj
|
||||
support.tab.legacyArbitration.support=Eski Arbitraj
|
||||
support.tab.ArbitratorsSupportTickets={0}'nin biletleri
|
||||
support.filter=Uyuşmazlıkları ara
|
||||
support.filter.prompt=İşlem ID'si, tarih, onion adresi veya hesap verilerini girin
|
||||
support.tab.SignedOffers=İmzalı Teklifler
|
||||
support.prompt.signedOffer.penalty.msg=Bu, üreticiden bir ceza ücreti alacak ve kalan işlem fonlarını cüzdanına iade edecektir. Göndermek istediğinizden emin misiniz?\n\n\
|
||||
Teklif ID'si: {0}\n\
|
||||
|
@ -1295,6 +1293,7 @@ setting.preferences.displayOptions=Görüntüleme seçenekleri
|
|||
setting.preferences.showOwnOffers=Teklif defterinde kendi tekliflerini göster
|
||||
setting.preferences.useAnimations=Animasyonları kullan
|
||||
setting.preferences.useDarkMode=Karanlık modu kullan
|
||||
setting.preferences.useLightMode=Aydınlık modu kullan
|
||||
setting.preferences.sortWithNumOffers=Piyasaları teklif sayısına göre sırala
|
||||
setting.preferences.onlyShowPaymentMethodsFromAccount=Olmayan ödeme yöntemlerini gizle
|
||||
setting.preferences.denyApiTaker=API kullanan alıcıları reddet
|
||||
|
@ -1970,6 +1969,7 @@ offerDetailsWindow.confirm.takerCrypto=Onayla: {0} {1} teklifi al
|
|||
offerDetailsWindow.creationDate=Oluşturma tarihi
|
||||
offerDetailsWindow.makersOnion=Yapıcı'nın onion adresi
|
||||
offerDetailsWindow.challenge=Teklif şifresi
|
||||
offerDetailsWindow.challenge.copy=Parolanızı eşinizle paylaşmak için kopyalayın
|
||||
|
||||
qRCodeWindow.headline=QR Kodu
|
||||
qRCodeWindow.msg=Harici cüzdanınızdan Haveno cüzdanınızı finanse etmek için bu QR kodunu kullanın.
|
||||
|
|
|
@ -218,7 +218,7 @@ shared.delayedPayoutTxId=Delayed payout transaction ID
|
|||
shared.delayedPayoutTxReceiverAddress=Delayed payout transaction sent to
|
||||
shared.unconfirmedTransactionsLimitReached=You have too many unconfirmed transactions at the moment. Please try again later.
|
||||
shared.numItemsLabel=Number of entries: {0}
|
||||
shared.filter=Filter
|
||||
shared.filter=Bộ lọc
|
||||
shared.enabled=Enabled
|
||||
|
||||
|
||||
|
@ -928,8 +928,6 @@ support.tab.mediation.support=Mediation
|
|||
support.tab.arbitration.support=Arbitration
|
||||
support.tab.legacyArbitration.support=Legacy Arbitration
|
||||
support.tab.ArbitratorsSupportTickets={0}'s tickets
|
||||
support.filter=Search disputes
|
||||
support.filter.prompt=Nhập ID giao dịch, ngày tháng, địa chỉ onion hoặc dữ liệu tài khoản
|
||||
|
||||
support.sigCheck.button=Check signature
|
||||
support.sigCheck.popup.header=Verify dispute result signature
|
||||
|
@ -1033,7 +1031,8 @@ setting.preferences.addCrypto=Bổ sung crypto
|
|||
setting.preferences.displayOptions=Hiển thị các phương án
|
||||
setting.preferences.showOwnOffers=Hiển thị Báo giá của tôi trong danh mục Báo giá
|
||||
setting.preferences.useAnimations=Sử dụng hoạt ảnh
|
||||
setting.preferences.useDarkMode=Use dark mode
|
||||
setting.preferences.useDarkMode=Sử dụng chế độ tối
|
||||
setting.preferences.useLightMode=Sử dụng chế độ sáng
|
||||
setting.preferences.sortWithNumOffers=Sắp xếp danh sách thị trường với số chào giá/giao dịch
|
||||
setting.preferences.onlyShowPaymentMethodsFromAccount=Hide non-supported payment methods
|
||||
setting.preferences.denyApiTaker=Deny takers using the API
|
||||
|
@ -1476,6 +1475,7 @@ offerDetailsWindow.confirm.taker=Xác nhận: Nhận chào giáo cho {0} monero
|
|||
offerDetailsWindow.creationDate=Ngày tạo
|
||||
offerDetailsWindow.makersOnion=Địa chỉ onion của người tạo
|
||||
offerDetailsWindow.challenge=Mã bảo vệ giao dịch
|
||||
offerDetailsWindow.challenge.copy=Sao chép cụm mật khẩu để chia sẻ với đối tác của bạn
|
||||
|
||||
qRCodeWindow.headline=QR Code
|
||||
qRCodeWindow.msg=Please use this QR code for funding your Haveno wallet from your external wallet.
|
||||
|
|
|
@ -927,8 +927,6 @@ support.tab.mediation.support=调解
|
|||
support.tab.arbitration.support=仲裁
|
||||
support.tab.legacyArbitration.support=历史仲裁
|
||||
support.tab.ArbitratorsSupportTickets={0} 的工单
|
||||
support.filter=查找纠纷
|
||||
support.filter.prompt=输入 交易 ID、日期、洋葱地址或账户信息
|
||||
|
||||
support.sigCheck.button=Check signature
|
||||
support.sigCheck.popup.info=请粘贴仲裁过程的摘要信息。使用这个工具,任何用户都可以检查仲裁者的签名是否与摘要信息相符。
|
||||
|
@ -1035,6 +1033,7 @@ setting.preferences.displayOptions=显示选项
|
|||
setting.preferences.showOwnOffers=在报价列表中显示我的报价
|
||||
setting.preferences.useAnimations=使用动画
|
||||
setting.preferences.useDarkMode=使用夜间模式
|
||||
setting.preferences.useLightMode=使用浅色模式
|
||||
setting.preferences.sortWithNumOffers=使用“报价ID/交易ID”筛选列表
|
||||
setting.preferences.onlyShowPaymentMethodsFromAccount=Hide non-supported payment methods
|
||||
setting.preferences.denyApiTaker=Deny takers using the API
|
||||
|
@ -1478,6 +1477,7 @@ offerDetailsWindow.confirm.taker=确定:下单买入 {0} 比特币
|
|||
offerDetailsWindow.creationDate=创建时间
|
||||
offerDetailsWindow.makersOnion=卖家的匿名地址
|
||||
offerDetailsWindow.challenge=提供密码
|
||||
offerDetailsWindow.challenge.copy=复制助记词以与您的交易对手共享
|
||||
|
||||
qRCodeWindow.headline=二维码
|
||||
qRCodeWindow.msg=请使用二维码从外部钱包充值至 Haveno 钱包
|
||||
|
|
|
@ -218,7 +218,7 @@ shared.delayedPayoutTxId=延遲支付交易 ID
|
|||
shared.delayedPayoutTxReceiverAddress=延遲交易交易已發送至
|
||||
shared.unconfirmedTransactionsLimitReached=你現在有過多的未確認交易。請稍後嘗試
|
||||
shared.numItemsLabel=Number of entries: {0}
|
||||
shared.filter=Filter
|
||||
shared.filter=篩選
|
||||
shared.enabled=啟用
|
||||
|
||||
|
||||
|
@ -927,8 +927,6 @@ support.tab.mediation.support=調解
|
|||
support.tab.arbitration.support=仲裁
|
||||
support.tab.legacyArbitration.support=歷史仲裁
|
||||
support.tab.ArbitratorsSupportTickets={0} 的工單
|
||||
support.filter=查找糾紛
|
||||
support.filter.prompt=輸入 交易 ID、日期、洋葱地址或賬户信息
|
||||
|
||||
support.sigCheck.button=Check signature
|
||||
support.sigCheck.popup.info=請貼上仲裁程序的摘要訊息。利用這個工具,任何使用者都可以檢查仲裁者的簽名是否與摘要訊息相符。
|
||||
|
@ -1035,6 +1033,7 @@ setting.preferences.displayOptions=顯示選項
|
|||
setting.preferences.showOwnOffers=在報價列表中顯示我的報價
|
||||
setting.preferences.useAnimations=使用動畫
|
||||
setting.preferences.useDarkMode=使用夜間模式
|
||||
setting.preferences.useLightMode=使用淺色模式
|
||||
setting.preferences.sortWithNumOffers=使用“報價ID/交易ID”篩選列表
|
||||
setting.preferences.onlyShowPaymentMethodsFromAccount=Hide non-supported payment methods
|
||||
setting.preferences.denyApiTaker=Deny takers using the API
|
||||
|
@ -1478,6 +1477,7 @@ offerDetailsWindow.confirm.taker=確定:下單買入 {0} 比特幣
|
|||
offerDetailsWindow.creationDate=創建時間
|
||||
offerDetailsWindow.makersOnion=賣家的匿名地址
|
||||
offerDetailsWindow.challenge=提供密碼
|
||||
offerDetailsWindow.challenge.copy=複製密語以與對方分享
|
||||
|
||||
qRCodeWindow.headline=二維碼
|
||||
qRCodeWindow.msg=請使用二維碼從外部錢包充值至 Haveno 錢包
|
||||
|
|
|
@ -62,6 +62,8 @@
|
|||
-demo-bar-fill: -bs-sell;
|
||||
-fx-background-color: -demo-bar-fill;
|
||||
-fx-background-insets: 0;
|
||||
-fx-background-radius: 2px;
|
||||
-fx-border-radius: 2px;
|
||||
}
|
||||
|
||||
.candlestick-bar.close-above-open {
|
||||
|
@ -80,6 +82,8 @@
|
|||
-fx-padding: 5;
|
||||
-fx-background-color: -bs-volume-transparent;
|
||||
-fx-background-insets: 0;
|
||||
-fx-background-radius: 2px;
|
||||
-fx-border-radius: 2px;
|
||||
}
|
||||
|
||||
.chart-alternative-row-fill {
|
||||
|
|
|
@ -74,6 +74,7 @@ import javafx.scene.Scene;
|
|||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Screen;
|
||||
import javafx.stage.Stage;
|
||||
|
@ -223,6 +224,9 @@ public class HavenoApp extends Application implements UncaughtExceptionHandler {
|
|||
CssTheme.loadSceneStyles(scene, preferences.getCssTheme(), config.useDevModeHeader);
|
||||
});
|
||||
CssTheme.loadSceneStyles(scene, preferences.getCssTheme(), config.useDevModeHeader);
|
||||
|
||||
// set initial background color
|
||||
scene.setFill(CssTheme.isDarkTheme() ? Color.BLACK : Color.WHITE);
|
||||
|
||||
return scene;
|
||||
}
|
||||
|
|
|
@ -216,7 +216,10 @@ public class HavenoAppMain extends HavenoExecutable {
|
|||
|
||||
// Set the dialog content
|
||||
VBox vbox = new VBox(10);
|
||||
vbox.getChildren().addAll(new ImageView(ImageUtil.getImageByPath("logo_splash.png")), passwordField, errorMessageField, versionField);
|
||||
ImageView logoImageView = new ImageView(ImageUtil.getImageByPath("logo_splash_light.png"));
|
||||
logoImageView.setFitWidth(342);
|
||||
logoImageView.setPreserveRatio(true);
|
||||
vbox.getChildren().addAll(logoImageView, passwordField, errorMessageField, versionField);
|
||||
vbox.setAlignment(Pos.TOP_CENTER);
|
||||
getDialogPane().setContent(vbox);
|
||||
|
||||
|
|
|
@ -20,14 +20,17 @@ package haveno.desktop.components;
|
|||
import com.jfoenix.controls.JFXTextField;
|
||||
import de.jensd.fx.fontawesome.AwesomeDude;
|
||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
import haveno.common.UserThread;
|
||||
import haveno.common.util.Utilities;
|
||||
import haveno.core.locale.Res;
|
||||
import haveno.desktop.main.overlays.popups.Popup;
|
||||
import haveno.desktop.util.GUIUtil;
|
||||
import haveno.desktop.util.Layout;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
|
@ -55,6 +58,7 @@ public class AddressTextField extends AnchorPane {
|
|||
textField.setId("address-text-field");
|
||||
textField.setEditable(false);
|
||||
textField.setLabelFloat(true);
|
||||
textField.getStyleClass().add("label-float");
|
||||
textField.setPromptText(label);
|
||||
|
||||
textField.textProperty().bind(address);
|
||||
|
@ -70,28 +74,32 @@ public class AddressTextField extends AnchorPane {
|
|||
|
||||
textField.focusTraversableProperty().set(focusTraversableProperty().get());
|
||||
Label extWalletIcon = new Label();
|
||||
extWalletIcon.setLayoutY(3);
|
||||
extWalletIcon.setLayoutY(Layout.FLOATING_ICON_Y);
|
||||
extWalletIcon.getStyleClass().addAll("icon", "highlight");
|
||||
extWalletIcon.setTooltip(new Tooltip(tooltipText));
|
||||
AwesomeDude.setIcon(extWalletIcon, AwesomeIcon.SIGNIN);
|
||||
extWalletIcon.setOnMouseClicked(e -> openWallet());
|
||||
|
||||
Label copyIcon = new Label();
|
||||
copyIcon.setLayoutY(3);
|
||||
copyIcon.getStyleClass().addAll("icon", "highlight");
|
||||
Tooltip.install(copyIcon, new Tooltip(Res.get("addressTextField.copyToClipboard")));
|
||||
AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY);
|
||||
copyIcon.setOnMouseClicked(e -> {
|
||||
Label copyLabel = new Label();
|
||||
copyLabel.setLayoutY(Layout.FLOATING_ICON_Y);
|
||||
copyLabel.getStyleClass().addAll("icon", "highlight");
|
||||
Tooltip.install(copyLabel, new Tooltip(Res.get("addressTextField.copyToClipboard")));
|
||||
copyLabel.setGraphic(GUIUtil.getCopyIcon());
|
||||
copyLabel.setOnMouseClicked(e -> {
|
||||
if (address.get() != null && address.get().length() > 0)
|
||||
Utilities.copyToClipboard(address.get());
|
||||
Tooltip tp = new Tooltip(Res.get("shared.copiedToClipboard"));
|
||||
Node node = (Node) e.getSource();
|
||||
UserThread.runAfter(() -> tp.hide(), 1);
|
||||
tp.show(node, e.getScreenX() + Layout.PADDING, e.getScreenY() + Layout.PADDING);
|
||||
});
|
||||
|
||||
AnchorPane.setRightAnchor(copyIcon, 30.0);
|
||||
AnchorPane.setRightAnchor(copyLabel, 30.0);
|
||||
AnchorPane.setRightAnchor(extWalletIcon, 5.0);
|
||||
AnchorPane.setRightAnchor(textField, 55.0);
|
||||
AnchorPane.setLeftAnchor(textField, 0.0);
|
||||
|
||||
getChildren().addAll(textField, copyIcon, extWalletIcon);
|
||||
getChildren().addAll(textField, copyLabel, extWalletIcon);
|
||||
}
|
||||
|
||||
private void openWallet() {
|
||||
|
|
|
@ -31,15 +31,15 @@ public class AutoTooltipButton extends JFXButton {
|
|||
}
|
||||
|
||||
public AutoTooltipButton(String text) {
|
||||
super(text.toUpperCase());
|
||||
super(text);
|
||||
}
|
||||
|
||||
public AutoTooltipButton(String text, Node graphic) {
|
||||
super(text.toUpperCase(), graphic);
|
||||
super(text, graphic);
|
||||
}
|
||||
|
||||
public void updateText(String text) {
|
||||
setText(text.toUpperCase());
|
||||
setText(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -24,6 +24,7 @@ import javafx.collections.FXCollections;
|
|||
import javafx.collections.ObservableList;
|
||||
import javafx.event.Event;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.control.ListView;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -44,6 +45,7 @@ public class AutocompleteComboBox<T> extends JFXComboBox<T> {
|
|||
private List<? extends T> extendedList;
|
||||
private List<T> matchingList;
|
||||
private JFXComboBoxListViewSkin<T> comboBoxListViewSkin;
|
||||
private boolean selectAllShortcut = false;
|
||||
|
||||
public AutocompleteComboBox() {
|
||||
this(FXCollections.observableArrayList());
|
||||
|
@ -153,6 +155,27 @@ public class AutocompleteComboBox<T> extends JFXComboBox<T> {
|
|||
|
||||
private void reactToQueryChanges() {
|
||||
getEditor().addEventHandler(KeyEvent.KEY_RELEASED, (KeyEvent event) -> {
|
||||
|
||||
// ignore ctrl and command keys
|
||||
if (event.getCode() == KeyCode.CONTROL || event.getCode() == KeyCode.COMMAND || event.getCode() == KeyCode.META) {
|
||||
event.consume();
|
||||
return;
|
||||
}
|
||||
|
||||
// handle select all
|
||||
boolean isSelectAll = event.getCode() == KeyCode.A && (event.isControlDown() || event.isMetaDown());
|
||||
if (isSelectAll) {
|
||||
getEditor().selectAll();
|
||||
selectAllShortcut = true;
|
||||
event.consume();
|
||||
return;
|
||||
}
|
||||
if (event.getCode() == KeyCode.A && selectAllShortcut) { // 'A' can be received after ctrl/cmd
|
||||
selectAllShortcut = false;
|
||||
event.consume();
|
||||
return;
|
||||
}
|
||||
|
||||
UserThread.execute(() -> {
|
||||
String query = getEditor().getText();
|
||||
var exactMatch = list.stream().anyMatch(item -> asString(item).equalsIgnoreCase(query));
|
||||
|
@ -180,6 +203,10 @@ public class AutocompleteComboBox<T> extends JFXComboBox<T> {
|
|||
if (matchingListSize() > 0) {
|
||||
comboBoxListViewSkin.getPopupContent().autosize();
|
||||
show();
|
||||
if (comboBoxListViewSkin.getPopupContent() instanceof ListView<?> listView) {
|
||||
listView.applyCss();
|
||||
listView.layout();
|
||||
}
|
||||
} else {
|
||||
hide();
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ public class BalanceTextField extends AnchorPane {
|
|||
public BalanceTextField(String label) {
|
||||
textField = new HavenoTextField();
|
||||
textField.setLabelFloat(true);
|
||||
textField.getStyleClass().add("label-float");
|
||||
textField.setPromptText(label);
|
||||
textField.setFocusTraversable(false);
|
||||
textField.setEditable(false);
|
||||
|
|
|
@ -23,6 +23,7 @@ import de.jensd.fx.fontawesome.AwesomeIcon;
|
|||
import haveno.common.util.Utilities;
|
||||
import haveno.core.locale.Res;
|
||||
import haveno.core.user.Preferences;
|
||||
import haveno.desktop.util.GUIUtil;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.Tooltip;
|
||||
|
@ -38,19 +39,19 @@ public class ExplorerAddressTextField extends AnchorPane {
|
|||
|
||||
@Getter
|
||||
private final TextField textField;
|
||||
private final Label copyIcon, missingAddressWarningIcon;
|
||||
private final Label copyLabel, missingAddressWarningIcon;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public ExplorerAddressTextField() {
|
||||
copyIcon = new Label();
|
||||
copyIcon.setLayoutY(3);
|
||||
copyIcon.getStyleClass().addAll("icon", "highlight");
|
||||
copyIcon.setTooltip(new Tooltip(Res.get("explorerAddressTextField.copyToClipboard")));
|
||||
AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY);
|
||||
AnchorPane.setRightAnchor(copyIcon, 30.0);
|
||||
copyLabel = new Label();
|
||||
copyLabel.setLayoutY(3);
|
||||
copyLabel.getStyleClass().addAll("icon", "highlight");
|
||||
copyLabel.setTooltip(new Tooltip(Res.get("explorerAddressTextField.copyToClipboard")));
|
||||
copyLabel.setGraphic(GUIUtil.getCopyIcon());
|
||||
AnchorPane.setRightAnchor(copyLabel, 30.0);
|
||||
|
||||
Tooltip tooltip = new Tooltip(Res.get("explorerAddressTextField.blockExplorerIcon.tooltip"));
|
||||
|
||||
|
@ -71,27 +72,27 @@ public class ExplorerAddressTextField extends AnchorPane {
|
|||
AnchorPane.setRightAnchor(textField, 80.0);
|
||||
AnchorPane.setLeftAnchor(textField, 0.0);
|
||||
textField.focusTraversableProperty().set(focusTraversableProperty().get());
|
||||
getChildren().addAll(textField, missingAddressWarningIcon, copyIcon);
|
||||
getChildren().addAll(textField, missingAddressWarningIcon, copyLabel);
|
||||
}
|
||||
|
||||
public void setup(@Nullable String address) {
|
||||
if (address == null) {
|
||||
textField.setText(Res.get("shared.na"));
|
||||
textField.setId("address-text-field-error");
|
||||
copyIcon.setVisible(false);
|
||||
copyIcon.setManaged(false);
|
||||
copyLabel.setVisible(false);
|
||||
copyLabel.setManaged(false);
|
||||
missingAddressWarningIcon.setVisible(true);
|
||||
missingAddressWarningIcon.setManaged(true);
|
||||
return;
|
||||
}
|
||||
|
||||
textField.setText(address);
|
||||
copyIcon.setOnMouseClicked(e -> Utilities.copyToClipboard(address));
|
||||
copyLabel.setOnMouseClicked(e -> Utilities.copyToClipboard(address));
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
textField.setOnMouseClicked(null);
|
||||
copyIcon.setOnMouseClicked(null);
|
||||
copyLabel.setOnMouseClicked(null);
|
||||
textField.setText("");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,9 +17,10 @@
|
|||
|
||||
package haveno.desktop.components;
|
||||
|
||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
import haveno.common.util.Utilities;
|
||||
import haveno.core.locale.Res;
|
||||
import haveno.desktop.util.GUIUtil;
|
||||
import haveno.desktop.util.Layout;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
|
@ -29,8 +30,6 @@ import javafx.scene.layout.AnchorPane;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static haveno.desktop.util.FormBuilder.getIcon;
|
||||
|
||||
public class FundsTextField extends InfoTextField {
|
||||
public static final Logger log = LoggerFactory.getLogger(FundsTextField.class);
|
||||
|
||||
|
@ -46,11 +45,12 @@ public class FundsTextField extends InfoTextField {
|
|||
textField.textProperty().unbind();
|
||||
textField.textProperty().bind(Bindings.concat(textProperty())); // TODO: removed `, " ", fundsStructure` for haveno to fix "Funds needed: .123 XMR (null)" bug
|
||||
|
||||
Label copyIcon = getIcon(AwesomeIcon.COPY);
|
||||
copyIcon.setLayoutY(5);
|
||||
copyIcon.getStyleClass().addAll("icon", "highlight");
|
||||
Tooltip.install(copyIcon, new Tooltip(Res.get("shared.copyToClipboard")));
|
||||
copyIcon.setOnMouseClicked(e -> {
|
||||
Label copyLabel = new Label();
|
||||
copyLabel.setLayoutY(Layout.FLOATING_ICON_Y);
|
||||
copyLabel.getStyleClass().addAll("icon", "highlight");
|
||||
Tooltip.install(copyLabel, new Tooltip(Res.get("shared.copyToClipboard")));
|
||||
copyLabel.setGraphic(GUIUtil.getCopyIcon());
|
||||
copyLabel.setOnMouseClicked(e -> {
|
||||
String text = getText();
|
||||
if (text != null && text.length() > 0) {
|
||||
String copyText;
|
||||
|
@ -64,11 +64,11 @@ public class FundsTextField extends InfoTextField {
|
|||
}
|
||||
});
|
||||
|
||||
AnchorPane.setRightAnchor(copyIcon, 30.0);
|
||||
AnchorPane.setRightAnchor(copyLabel, 30.0);
|
||||
AnchorPane.setRightAnchor(infoIcon, 62.0);
|
||||
AnchorPane.setRightAnchor(textField, 55.0);
|
||||
|
||||
getChildren().add(copyIcon);
|
||||
getChildren().add(copyLabel);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
package haveno.desktop.components;
|
||||
|
||||
import com.jfoenix.controls.JFXTextField;
|
||||
import haveno.desktop.util.GUIUtil;
|
||||
import javafx.scene.control.Skin;
|
||||
|
||||
public class HavenoTextField extends JFXTextField {
|
||||
|
||||
public HavenoTextField(String value) {
|
||||
super(value);
|
||||
GUIUtil.applyFilledStyle(this);
|
||||
}
|
||||
|
||||
public HavenoTextField() {
|
||||
super();
|
||||
this(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -21,6 +21,7 @@ import com.jfoenix.controls.JFXTextField;
|
|||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIcon;
|
||||
import haveno.desktop.components.controlsfx.control.PopOver;
|
||||
import haveno.desktop.util.Layout;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.scene.Node;
|
||||
|
@ -51,13 +52,14 @@ public class InfoTextField extends AnchorPane {
|
|||
arrowLocation = PopOver.ArrowLocation.RIGHT_TOP;
|
||||
textField = new HavenoTextField();
|
||||
textField.setLabelFloat(true);
|
||||
textField.getStyleClass().add("label-float");
|
||||
textField.setEditable(false);
|
||||
textField.textProperty().bind(text);
|
||||
textField.setFocusTraversable(false);
|
||||
textField.setId("info-field");
|
||||
|
||||
infoIcon = getIcon(AwesomeIcon.INFO_SIGN);
|
||||
infoIcon.setLayoutY(5);
|
||||
infoIcon.setLayoutY(Layout.FLOATING_ICON_Y - 2);
|
||||
infoIcon.getStyleClass().addAll("icon", "info");
|
||||
|
||||
AnchorPane.setRightAnchor(infoIcon, 7.0);
|
||||
|
|
|
@ -20,6 +20,7 @@ package haveno.desktop.components;
|
|||
|
||||
import com.jfoenix.controls.JFXTextField;
|
||||
import haveno.core.util.validation.InputValidator;
|
||||
import haveno.desktop.util.GUIUtil;
|
||||
import haveno.desktop.util.validation.JFXInputValidator;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
|
@ -67,6 +68,7 @@ public class InputTextField extends JFXTextField {
|
|||
|
||||
public InputTextField() {
|
||||
super();
|
||||
GUIUtil.applyFilledStyle(this);
|
||||
|
||||
getValidators().add(jfxValidationWrapper);
|
||||
|
||||
|
|
|
@ -124,7 +124,8 @@ public class PeerInfoIcon extends Group {
|
|||
numTradesPane.relocate(scaleFactor * 18, scaleFactor * 14);
|
||||
numTradesPane.setMouseTransparent(true);
|
||||
ImageView numTradesCircle = new ImageView();
|
||||
numTradesCircle.setId("image-green_circle");
|
||||
numTradesCircle.setId("image-green_circle_solid");
|
||||
|
||||
numTradesLabel = new AutoTooltipLabel();
|
||||
numTradesLabel.relocate(scaleFactor * 5, scaleFactor * 1);
|
||||
numTradesLabel.setId("ident-num-label");
|
||||
|
@ -134,7 +135,7 @@ public class PeerInfoIcon extends Group {
|
|||
tagPane.relocate(Math.round(scaleFactor * 18), scaleFactor * -2);
|
||||
tagPane.setMouseTransparent(true);
|
||||
ImageView tagCircle = new ImageView();
|
||||
tagCircle.setId("image-blue_circle");
|
||||
tagCircle.setId("image-blue_circle_solid");
|
||||
tagLabel = new AutoTooltipLabel();
|
||||
tagLabel.relocate(Math.round(scaleFactor * 5), scaleFactor * 1);
|
||||
tagLabel.setId("ident-num-label");
|
||||
|
|
|
@ -18,12 +18,15 @@
|
|||
package haveno.desktop.components;
|
||||
|
||||
import com.jfoenix.controls.JFXTextField;
|
||||
import de.jensd.fx.fontawesome.AwesomeDude;
|
||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
|
||||
import haveno.common.UserThread;
|
||||
import haveno.common.util.Utilities;
|
||||
import haveno.core.locale.Res;
|
||||
import haveno.desktop.util.GUIUtil;
|
||||
import haveno.desktop.util.Layout;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.Tooltip;
|
||||
|
@ -45,12 +48,13 @@ public class TextFieldWithCopyIcon extends AnchorPane {
|
|||
}
|
||||
|
||||
public TextFieldWithCopyIcon(String customStyleClass) {
|
||||
Label copyIcon = new Label();
|
||||
copyIcon.setLayoutY(3);
|
||||
copyIcon.getStyleClass().addAll("icon", "highlight");
|
||||
copyIcon.setTooltip(new Tooltip(Res.get("shared.copyToClipboard")));
|
||||
AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY);
|
||||
copyIcon.setOnMouseClicked(e -> {
|
||||
Label copyLabel = new Label();
|
||||
copyLabel.setLayoutY(Layout.FLOATING_ICON_Y);
|
||||
copyLabel.getStyleClass().addAll("icon", "highlight");
|
||||
if (customStyleClass != null) copyLabel.getStyleClass().add(customStyleClass + "-icon");
|
||||
copyLabel.setTooltip(new Tooltip(Res.get("shared.copyToClipboard")));
|
||||
copyLabel.setGraphic(GUIUtil.getCopyIcon());
|
||||
copyLabel.setOnMouseClicked(e -> {
|
||||
String text = getText();
|
||||
if (text != null && text.length() > 0) {
|
||||
String copyText;
|
||||
|
@ -70,17 +74,25 @@ public class TextFieldWithCopyIcon extends AnchorPane {
|
|||
copyText = text;
|
||||
}
|
||||
Utilities.copyToClipboard(copyText);
|
||||
Tooltip tp = new Tooltip(Res.get("shared.copiedToClipboard"));
|
||||
Node node = (Node) e.getSource();
|
||||
UserThread.runAfter(() -> tp.hide(), 1);
|
||||
tp.show(node, e.getScreenX() + Layout.PADDING, e.getScreenY() + Layout.PADDING);
|
||||
}
|
||||
});
|
||||
textField = new JFXTextField();
|
||||
textField.setEditable(false);
|
||||
if (customStyleClass != null) textField.getStyleClass().add(customStyleClass);
|
||||
textField.textProperty().bindBidirectional(text);
|
||||
AnchorPane.setRightAnchor(copyIcon, 5.0);
|
||||
AnchorPane.setRightAnchor(copyLabel, 5.0);
|
||||
AnchorPane.setRightAnchor(textField, 30.0);
|
||||
AnchorPane.setLeftAnchor(textField, 0.0);
|
||||
AnchorPane.setTopAnchor(copyLabel, 0.0);
|
||||
AnchorPane.setBottomAnchor(copyLabel, 0.0);
|
||||
AnchorPane.setTopAnchor(textField, 0.0);
|
||||
AnchorPane.setBottomAnchor(textField, 0.0);
|
||||
textField.focusTraversableProperty().set(focusTraversableProperty().get());
|
||||
getChildren().addAll(textField, copyIcon);
|
||||
getChildren().addAll(textField, copyLabel);
|
||||
}
|
||||
|
||||
public void setPromptText(String value) {
|
||||
|
|
|
@ -21,6 +21,7 @@ import com.jfoenix.controls.JFXTextField;
|
|||
import de.jensd.fx.fontawesome.AwesomeDude;
|
||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
import haveno.common.UserThread;
|
||||
import haveno.desktop.util.Layout;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
|
@ -53,10 +54,10 @@ public class TextFieldWithIcon extends AnchorPane {
|
|||
|
||||
iconLabel = new Label();
|
||||
iconLabel.setLayoutX(0);
|
||||
iconLabel.setLayoutY(3);
|
||||
iconLabel.setLayoutY(Layout.FLOATING_ICON_Y);
|
||||
|
||||
dummyTextField.widthProperty().addListener((observable, oldValue, newValue) -> {
|
||||
iconLabel.setLayoutX(dummyTextField.widthProperty().get() + 20);
|
||||
iconLabel.setLayoutX(dummyTextField.widthProperty().get() + 20 + Layout.FLOATING_ICON_Y);
|
||||
});
|
||||
|
||||
getChildren().addAll(textField, dummyTextField, iconLabel);
|
||||
|
|
|
@ -29,7 +29,10 @@ import haveno.core.user.Preferences;
|
|||
import haveno.core.xmr.wallet.XmrWalletService;
|
||||
import haveno.desktop.components.indicator.TxConfidenceIndicator;
|
||||
import haveno.desktop.util.GUIUtil;
|
||||
import haveno.desktop.util.Layout;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.scene.Cursor;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.Tooltip;
|
||||
|
@ -51,7 +54,7 @@ public class TxIdTextField extends AnchorPane {
|
|||
private final TextField textField;
|
||||
private final Tooltip progressIndicatorTooltip;
|
||||
private final TxConfidenceIndicator txConfidenceIndicator;
|
||||
private final Label copyIcon, blockExplorerIcon, missingTxWarningIcon;
|
||||
private final Label copyLabel, blockExplorerIcon, missingTxWarningIcon;
|
||||
|
||||
private MoneroWalletListener walletListener;
|
||||
private ChangeListener<Number> tradeListener;
|
||||
|
@ -70,16 +73,17 @@ public class TxIdTextField extends AnchorPane {
|
|||
txConfidenceIndicator.setProgress(0);
|
||||
txConfidenceIndicator.setVisible(false);
|
||||
AnchorPane.setRightAnchor(txConfidenceIndicator, 0.0);
|
||||
AnchorPane.setTopAnchor(txConfidenceIndicator, 3.0);
|
||||
AnchorPane.setTopAnchor(txConfidenceIndicator, Layout.FLOATING_ICON_Y);
|
||||
progressIndicatorTooltip = new Tooltip("-");
|
||||
txConfidenceIndicator.setTooltip(progressIndicatorTooltip);
|
||||
|
||||
copyIcon = new Label();
|
||||
copyIcon.setLayoutY(3);
|
||||
copyIcon.getStyleClass().addAll("icon", "highlight");
|
||||
copyIcon.setTooltip(new Tooltip(Res.get("txIdTextField.copyIcon.tooltip")));
|
||||
AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY);
|
||||
AnchorPane.setRightAnchor(copyIcon, 30.0);
|
||||
copyLabel = new Label();
|
||||
copyLabel.setLayoutY(Layout.FLOATING_ICON_Y);
|
||||
copyLabel.getStyleClass().addAll("icon", "highlight");
|
||||
copyLabel.setTooltip(new Tooltip(Res.get("txIdTextField.copyIcon.tooltip")));
|
||||
copyLabel.setGraphic(GUIUtil.getCopyIcon());
|
||||
copyLabel.setCursor(Cursor.HAND);
|
||||
AnchorPane.setRightAnchor(copyLabel, 30.0);
|
||||
|
||||
Tooltip tooltip = new Tooltip(Res.get("txIdTextField.blockExplorerIcon.tooltip"));
|
||||
|
||||
|
@ -89,7 +93,7 @@ public class TxIdTextField extends AnchorPane {
|
|||
AwesomeDude.setIcon(blockExplorerIcon, AwesomeIcon.EXTERNAL_LINK);
|
||||
blockExplorerIcon.setMinWidth(20);
|
||||
AnchorPane.setRightAnchor(blockExplorerIcon, 52.0);
|
||||
AnchorPane.setTopAnchor(blockExplorerIcon, 4.0);
|
||||
AnchorPane.setTopAnchor(blockExplorerIcon, Layout.FLOATING_ICON_Y);
|
||||
|
||||
missingTxWarningIcon = new Label();
|
||||
missingTxWarningIcon.getStyleClass().addAll("icon", "error-icon");
|
||||
|
@ -97,7 +101,7 @@ public class TxIdTextField extends AnchorPane {
|
|||
missingTxWarningIcon.setTooltip(new Tooltip(Res.get("txIdTextField.missingTx.warning.tooltip")));
|
||||
missingTxWarningIcon.setMinWidth(20);
|
||||
AnchorPane.setRightAnchor(missingTxWarningIcon, 52.0);
|
||||
AnchorPane.setTopAnchor(missingTxWarningIcon, 4.0);
|
||||
AnchorPane.setTopAnchor(missingTxWarningIcon, Layout.FLOATING_ICON_Y);
|
||||
missingTxWarningIcon.setVisible(false);
|
||||
missingTxWarningIcon.setManaged(false);
|
||||
|
||||
|
@ -108,7 +112,7 @@ public class TxIdTextField extends AnchorPane {
|
|||
AnchorPane.setRightAnchor(textField, 80.0);
|
||||
AnchorPane.setLeftAnchor(textField, 0.0);
|
||||
textField.focusTraversableProperty().set(focusTraversableProperty().get());
|
||||
getChildren().addAll(textField, missingTxWarningIcon, blockExplorerIcon, copyIcon, txConfidenceIndicator);
|
||||
getChildren().addAll(textField, missingTxWarningIcon, blockExplorerIcon, copyLabel, txConfidenceIndicator);
|
||||
}
|
||||
|
||||
public void setup(@Nullable String txId) {
|
||||
|
@ -131,8 +135,8 @@ public class TxIdTextField extends AnchorPane {
|
|||
textField.setId("address-text-field-error");
|
||||
blockExplorerIcon.setVisible(false);
|
||||
blockExplorerIcon.setManaged(false);
|
||||
copyIcon.setVisible(false);
|
||||
copyIcon.setManaged(false);
|
||||
copyLabel.setVisible(false);
|
||||
copyLabel.setManaged(false);
|
||||
txConfidenceIndicator.setVisible(false);
|
||||
missingTxWarningIcon.setVisible(true);
|
||||
missingTxWarningIcon.setManaged(true);
|
||||
|
@ -158,7 +162,13 @@ public class TxIdTextField extends AnchorPane {
|
|||
textField.setText(txId);
|
||||
textField.setOnMouseClicked(mouseEvent -> openBlockExplorer(txId));
|
||||
blockExplorerIcon.setOnMouseClicked(mouseEvent -> openBlockExplorer(txId));
|
||||
copyIcon.setOnMouseClicked(e -> Utilities.copyToClipboard(txId));
|
||||
copyLabel.setOnMouseClicked(e -> {
|
||||
Utilities.copyToClipboard(txId);
|
||||
Tooltip tp = new Tooltip(Res.get("shared.copiedToClipboard"));
|
||||
Node node = (Node) e.getSource();
|
||||
UserThread.runAfter(() -> tp.hide(), 1);
|
||||
tp.show(node, e.getScreenX() + Layout.PADDING, e.getScreenY() + Layout.PADDING);
|
||||
});
|
||||
txConfidenceIndicator.setVisible(true);
|
||||
|
||||
// update off main thread
|
||||
|
@ -177,7 +187,7 @@ public class TxIdTextField extends AnchorPane {
|
|||
trade = null;
|
||||
textField.setOnMouseClicked(null);
|
||||
blockExplorerIcon.setOnMouseClicked(null);
|
||||
copyIcon.setOnMouseClicked(null);
|
||||
copyLabel.setOnMouseClicked(null);
|
||||
textField.setText("");
|
||||
}
|
||||
|
||||
|
|
|
@ -494,7 +494,7 @@ public class PopOver extends PopupControl {
|
|||
* @since 1.0
|
||||
*/
|
||||
public final void hide(Duration fadeOutDuration) {
|
||||
log.info("hide:" + fadeOutDuration.toString());
|
||||
log.debug("hide:" + fadeOutDuration.toString());
|
||||
//We must remove EventFilter in order to prevent memory leak.
|
||||
if (ownerWindow != null) {
|
||||
ownerWindow.removeEventFilter(WindowEvent.WINDOW_CLOSE_REQUEST,
|
||||
|
|
|
@ -17,13 +17,10 @@
|
|||
|
||||
package haveno.desktop.components.list;
|
||||
|
||||
import haveno.core.locale.Res;
|
||||
import haveno.desktop.components.AutoTooltipLabel;
|
||||
import haveno.desktop.components.InputTextField;
|
||||
import haveno.desktop.util.filtering.FilterableListItem;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.collections.transformation.FilteredList;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.layout.HBox;
|
||||
|
||||
|
@ -37,13 +34,10 @@ public class FilterBox extends HBox {
|
|||
super();
|
||||
setSpacing(5.0);
|
||||
|
||||
AutoTooltipLabel label = new AutoTooltipLabel(Res.get("shared.filter"));
|
||||
HBox.setMargin(label, new Insets(5.0, 0, 0, 10.0));
|
||||
|
||||
textField = new InputTextField();
|
||||
textField.setMinWidth(500);
|
||||
|
||||
getChildren().addAll(label, textField);
|
||||
getChildren().addAll(textField);
|
||||
}
|
||||
|
||||
public void initialize(FilteredList<? extends FilterableListItem> filteredList,
|
||||
|
@ -67,4 +61,8 @@ public class FilterBox extends HBox {
|
|||
private void applyFilteredListPredicate(String filterString) {
|
||||
filteredList.setPredicate(item -> item.match(filterString));
|
||||
}
|
||||
|
||||
public void setPromptText(String promptText) {
|
||||
textField.setPromptText(promptText);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import haveno.desktop.components.AutocompleteComboBox;
|
|||
import haveno.desktop.components.InputTextField;
|
||||
import haveno.desktop.main.overlays.popups.Popup;
|
||||
import haveno.desktop.util.FormBuilder;
|
||||
import haveno.desktop.util.GUIUtil;
|
||||
import haveno.desktop.util.Layout;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.CheckBox;
|
||||
|
@ -202,6 +203,8 @@ public class AssetsForm extends PaymentMethodForm {
|
|||
CurrencyUtil.getActiveSortedCryptoCurrencies(filterManager));
|
||||
currencyComboBox.setVisibleRowCount(Math.min(currencyComboBox.getItems().size(), 10));
|
||||
|
||||
currencyComboBox.setCellFactory(GUIUtil.getTradeCurrencyCellFactoryNameAndCode());
|
||||
|
||||
currencyComboBox.setConverter(new StringConverter<>() {
|
||||
@Override
|
||||
public String toString(TradeCurrency tradeCurrency) {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,16 +1,3 @@
|
|||
/* splash screen */
|
||||
/*noinspection CssUnknownTarget*/
|
||||
#image-splash-logo {
|
||||
-fx-image: url("../../images/logo_splash.png");
|
||||
}
|
||||
|
||||
/* splash screen testnet */
|
||||
/*noinspection CssUnknownTarget*/
|
||||
#image-splash-testnet-logo {
|
||||
-fx-image: url("../../images/logo_splash_testnet.png");
|
||||
}
|
||||
|
||||
/* shared*/
|
||||
#image-info {
|
||||
-fx-image: url("../../images/info.png");
|
||||
}
|
||||
|
@ -23,16 +10,29 @@
|
|||
-fx-image: url("../../images/alert_round.png");
|
||||
}
|
||||
|
||||
#image-red_circle_solid {
|
||||
-fx-image: url("../../images/red_circle_solid.png");
|
||||
}
|
||||
|
||||
|
||||
#image-green_circle {
|
||||
-fx-image: url("../../images/green_circle.png");
|
||||
}
|
||||
|
||||
#image-green_circle_solid {
|
||||
-fx-image: url("../../images/green_circle_solid.png");
|
||||
}
|
||||
|
||||
#image-yellow_circle {
|
||||
-fx-image: url("../../images/yellow_circle.png");
|
||||
}
|
||||
|
||||
#image-blue_circle {
|
||||
-fx-image: url("../../images/blue_circle.png");
|
||||
#image-yellow_circle_solid {
|
||||
-fx-image: url("../../images/yellow_circle_solid.png");
|
||||
}
|
||||
|
||||
#image-blue_circle_solid {
|
||||
-fx-image: url("../../images/blue_circle_solid.png");
|
||||
}
|
||||
|
||||
#image-remove {
|
||||
|
@ -300,3 +300,59 @@
|
|||
#image-new-trade-protocol-screenshot {
|
||||
-fx-image: url("../../images/new_trade_protocol_screenshot.png");
|
||||
}
|
||||
|
||||
#image-support {
|
||||
-fx-image: url("../../images/support.png");
|
||||
}
|
||||
|
||||
#image-account {
|
||||
-fx-image: url("../../images/account.png");
|
||||
}
|
||||
|
||||
#image-settings {
|
||||
-fx-image: url("../../images/settings.png");
|
||||
}
|
||||
|
||||
#image-btc-logo {
|
||||
-fx-image: url("../../images/btc_logo.png");
|
||||
}
|
||||
|
||||
#image-bch-logo {
|
||||
-fx-image: url("../../images/bch_logo.png");
|
||||
}
|
||||
|
||||
#image-dai-erc20-logo {
|
||||
-fx-image: url("../../images/dai-erc20_logo.png");
|
||||
}
|
||||
|
||||
#image-eth-logo {
|
||||
-fx-image: url("../../images/eth_logo.png");
|
||||
}
|
||||
|
||||
#image-ltc-logo {
|
||||
-fx-image: url("../../images/ltc_logo.png");
|
||||
}
|
||||
|
||||
#image-usdc-erc20-logo {
|
||||
-fx-image: url("../../images/usdc-erc20_logo.png");
|
||||
}
|
||||
|
||||
#image-usdt-erc20-logo {
|
||||
-fx-image: url("../../images/usdt-erc20_logo.png");
|
||||
}
|
||||
|
||||
#image-usdt-trc20-logo {
|
||||
-fx-image: url("../../images/usdt-trc20_logo.png");
|
||||
}
|
||||
|
||||
#image-xmr-logo {
|
||||
-fx-image: url("../../images/xmr_logo.png");
|
||||
}
|
||||
|
||||
#image-dark-mode-toggle {
|
||||
-fx-image: url("../../images/dark_mode_toggle.png");
|
||||
}
|
||||
|
||||
#image-light-mode-toggle {
|
||||
-fx-image: url("../../images/light_mode_toggle.png");
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import haveno.core.locale.GlobalSettings;
|
|||
import haveno.core.locale.LanguageUtil;
|
||||
import haveno.core.locale.Res;
|
||||
import haveno.core.provider.price.MarketPrice;
|
||||
import haveno.core.user.Preferences;
|
||||
import haveno.desktop.Navigation;
|
||||
import haveno.desktop.common.view.CachingViewLoader;
|
||||
import haveno.desktop.common.view.FxmlView;
|
||||
|
@ -73,6 +74,7 @@ import javafx.geometry.Insets;
|
|||
import javafx.geometry.NodeOrientation;
|
||||
import javafx.geometry.Orientation;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Cursor;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Label;
|
||||
|
@ -92,6 +94,7 @@ import static javafx.scene.layout.AnchorPane.setRightAnchor;
|
|||
import static javafx.scene.layout.AnchorPane.setTopAnchor;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.StackPane;
|
||||
|
@ -125,17 +128,19 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
|||
private Label xmrSplashInfo;
|
||||
private Popup p2PNetworkWarnMsgPopup, xmrNetworkWarnMsgPopup;
|
||||
private final TorNetworkSettingsWindow torNetworkSettingsWindow;
|
||||
private final Preferences preferences;
|
||||
private static final int networkIconSize = 20;
|
||||
|
||||
public static StackPane getRootContainer() {
|
||||
return MainView.rootContainer;
|
||||
}
|
||||
|
||||
public static void blurLight() {
|
||||
transitions.blur(MainView.rootContainer, Transitions.DEFAULT_DURATION, -0.6, false, 5);
|
||||
transitions.blur(MainView.rootContainer, Transitions.DEFAULT_DURATION, -0.6, false, 15);
|
||||
}
|
||||
|
||||
public static void blurUltraLight() {
|
||||
transitions.blur(MainView.rootContainer, Transitions.DEFAULT_DURATION, -0.6, false, 2);
|
||||
transitions.blur(MainView.rootContainer, Transitions.DEFAULT_DURATION, -0.6, false, 15);
|
||||
}
|
||||
|
||||
public static void darken() {
|
||||
|
@ -151,12 +156,14 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
|||
CachingViewLoader viewLoader,
|
||||
Navigation navigation,
|
||||
Transitions transitions,
|
||||
TorNetworkSettingsWindow torNetworkSettingsWindow) {
|
||||
TorNetworkSettingsWindow torNetworkSettingsWindow,
|
||||
Preferences preferences) {
|
||||
super(model);
|
||||
this.viewLoader = viewLoader;
|
||||
this.navigation = navigation;
|
||||
MainView.transitions = transitions;
|
||||
this.torNetworkSettingsWindow = torNetworkSettingsWindow;
|
||||
this.preferences = preferences;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -165,15 +172,15 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
|||
if (LanguageUtil.isDefaultLanguageRTL())
|
||||
MainView.rootContainer.setNodeOrientation(NodeOrientation.RIGHT_TO_LEFT);
|
||||
|
||||
ToggleButton marketButton = new NavButton(MarketView.class, Res.get("mainView.menu.market").toUpperCase());
|
||||
ToggleButton buyButton = new NavButton(BuyOfferView.class, Res.get("mainView.menu.buyXmr").toUpperCase());
|
||||
ToggleButton sellButton = new NavButton(SellOfferView.class, Res.get("mainView.menu.sellXmr").toUpperCase());
|
||||
ToggleButton portfolioButton = new NavButton(PortfolioView.class, Res.get("mainView.menu.portfolio").toUpperCase());
|
||||
ToggleButton fundsButton = new NavButton(FundsView.class, Res.get("mainView.menu.funds").toUpperCase());
|
||||
ToggleButton marketButton = new NavButton(MarketView.class, Res.get("mainView.menu.market"));
|
||||
ToggleButton buyButton = new NavButton(BuyOfferView.class, Res.get("mainView.menu.buyXmr"));
|
||||
ToggleButton sellButton = new NavButton(SellOfferView.class, Res.get("mainView.menu.sellXmr"));
|
||||
ToggleButton portfolioButton = new NavButton(PortfolioView.class, Res.get("mainView.menu.portfolio"));
|
||||
ToggleButton fundsButton = new NavButton(FundsView.class, Res.get("mainView.menu.funds"));
|
||||
|
||||
ToggleButton supportButton = new NavButton(SupportView.class, Res.get("mainView.menu.support"));
|
||||
ToggleButton accountButton = new NavButton(AccountView.class, Res.get("mainView.menu.account"));
|
||||
ToggleButton settingsButton = new NavButton(SettingsView.class, Res.get("mainView.menu.settings"));
|
||||
ToggleButton supportButton = new SecondaryNavButton(SupportView.class, Res.get("mainView.menu.support"), "image-support");
|
||||
ToggleButton accountButton = new SecondaryNavButton(AccountView.class, Res.get("mainView.menu.account"), "image-account");
|
||||
ToggleButton settingsButton = new SecondaryNavButton(SettingsView.class, Res.get("mainView.menu.settings"), "image-settings");
|
||||
|
||||
JFXBadge portfolioButtonWithBadge = new JFXBadge(portfolioButton);
|
||||
JFXBadge supportButtonWithBadge = new JFXBadge(supportButton);
|
||||
|
@ -298,47 +305,56 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
|||
}
|
||||
});
|
||||
|
||||
HBox primaryNav = new HBox(marketButton, getNavigationSeparator(), buyButton, getNavigationSeparator(),
|
||||
sellButton, getNavigationSeparator(), portfolioButtonWithBadge, getNavigationSeparator(), fundsButton);
|
||||
HBox primaryNav = new HBox(getLogoPane(), marketButton, getNavigationSpacer(), buyButton, getNavigationSpacer(),
|
||||
sellButton, getNavigationSpacer(), portfolioButtonWithBadge, getNavigationSpacer(), fundsButton);
|
||||
|
||||
primaryNav.setAlignment(Pos.CENTER_LEFT);
|
||||
primaryNav.getStyleClass().add("nav-primary");
|
||||
HBox.setHgrow(primaryNav, Priority.SOMETIMES);
|
||||
|
||||
HBox secondaryNav = new HBox(supportButtonWithBadge, getNavigationSpacer(), accountButton,
|
||||
getNavigationSpacer(), settingsButtonWithBadge, getNavigationSpacer());
|
||||
secondaryNav.getStyleClass().add("nav-secondary");
|
||||
HBox.setHgrow(secondaryNav, Priority.SOMETIMES);
|
||||
|
||||
secondaryNav.setAlignment(Pos.CENTER);
|
||||
|
||||
HBox priceAndBalance = new HBox(marketPriceBox.second, getNavigationSeparator(), availableBalanceBox.second,
|
||||
getNavigationSeparator(), pendingBalanceBox.second, getNavigationSeparator(), reservedBalanceBox.second);
|
||||
priceAndBalance.setMaxHeight(41);
|
||||
|
||||
priceAndBalance.setAlignment(Pos.CENTER);
|
||||
priceAndBalance.setSpacing(9);
|
||||
priceAndBalance.setSpacing(12);
|
||||
priceAndBalance.getStyleClass().add("nav-price-balance");
|
||||
|
||||
HBox navPane = new HBox(primaryNav, secondaryNav, getNavigationSpacer(),
|
||||
priceAndBalance) {{
|
||||
setLeftAnchor(this, 0d);
|
||||
setRightAnchor(this, 0d);
|
||||
setTopAnchor(this, 0d);
|
||||
HBox navPane = new HBox(primaryNav, priceAndBalance) {{
|
||||
setLeftAnchor(this, 25d);
|
||||
setRightAnchor(this, 25d);
|
||||
setTopAnchor(this, 20d);
|
||||
setPadding(new Insets(0, 0, 0, 0));
|
||||
getStyleClass().add("top-navigation");
|
||||
}};
|
||||
navPane.setAlignment(Pos.CENTER);
|
||||
|
||||
HBox secondaryNav = new HBox(supportButtonWithBadge, accountButton, settingsButtonWithBadge);
|
||||
secondaryNav.getStyleClass().add("nav-secondary");
|
||||
secondaryNav.setAlignment(Pos.CENTER_RIGHT);
|
||||
secondaryNav.setPickOnBounds(false);
|
||||
HBox.setHgrow(secondaryNav, Priority.ALWAYS);
|
||||
AnchorPane.setLeftAnchor(secondaryNav, 0.0);
|
||||
AnchorPane.setRightAnchor(secondaryNav, 0.0);
|
||||
AnchorPane.setTopAnchor(secondaryNav, 0.0);
|
||||
|
||||
AnchorPane secondaryNavContainer = new AnchorPane() {{
|
||||
setId("nav-secondary-container");
|
||||
setLeftAnchor(this, 0d);
|
||||
setRightAnchor(this, 0d);
|
||||
setTopAnchor(this, 94d);
|
||||
}};
|
||||
secondaryNavContainer.setPickOnBounds(false);
|
||||
secondaryNavContainer.getChildren().add(secondaryNav);
|
||||
|
||||
AnchorPane contentContainer = new AnchorPane() {{
|
||||
getStyleClass().add("content-pane");
|
||||
setLeftAnchor(this, 0d);
|
||||
setRightAnchor(this, 0d);
|
||||
setTopAnchor(this, 57d);
|
||||
setTopAnchor(this, 95d);
|
||||
setBottomAnchor(this, 0d);
|
||||
}};
|
||||
|
||||
AnchorPane applicationContainer = new AnchorPane(navPane, contentContainer) {{
|
||||
AnchorPane applicationContainer = new AnchorPane(navPane, contentContainer, secondaryNavContainer) {{
|
||||
setId("application-container");
|
||||
}};
|
||||
|
||||
|
@ -398,15 +414,32 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
|||
private Separator getNavigationSeparator() {
|
||||
final Separator separator = new Separator(Orientation.VERTICAL);
|
||||
HBox.setHgrow(separator, Priority.ALWAYS);
|
||||
separator.setMaxHeight(22);
|
||||
separator.setMaxWidth(Double.MAX_VALUE);
|
||||
separator.getStyleClass().add("nav-separator");
|
||||
return separator;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Pane getLogoPane() {
|
||||
ImageView logo = new ImageView();
|
||||
logo.setId("image-logo-landscape");
|
||||
logo.setPreserveRatio(true);
|
||||
logo.setFitHeight(40);
|
||||
logo.setSmooth(true);
|
||||
logo.setCache(true);
|
||||
|
||||
final Pane pane = new Pane();
|
||||
HBox.setHgrow(pane, Priority.ALWAYS);
|
||||
pane.getStyleClass().add("nav-logo");
|
||||
pane.getChildren().add(logo);
|
||||
return pane;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Region getNavigationSpacer() {
|
||||
final Region spacer = new Region();
|
||||
HBox.setHgrow(spacer, Priority.ALWAYS);
|
||||
spacer.getStyleClass().add("nav-spacer");
|
||||
return spacer;
|
||||
}
|
||||
|
||||
|
@ -447,7 +480,6 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
|||
priceComboBox.setVisibleRowCount(12);
|
||||
priceComboBox.setFocusTraversable(false);
|
||||
priceComboBox.setId("price-feed-combo");
|
||||
priceComboBox.setPadding(new Insets(0, -4, -4, 0));
|
||||
priceComboBox.setCellFactory(p -> getPriceFeedComboBoxListCell());
|
||||
ListCell<PriceFeedComboBoxItem> buttonCell = getPriceFeedComboBoxListCell();
|
||||
buttonCell.setId("price-feed-combo");
|
||||
|
@ -458,7 +490,6 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
|||
updateMarketPriceLabel(marketPriceLabel);
|
||||
|
||||
marketPriceLabel.getStyleClass().add("nav-balance-label");
|
||||
marketPriceLabel.setPadding(new Insets(-2, 0, 4, 9));
|
||||
|
||||
marketPriceBox.getChildren().addAll(priceComboBox, marketPriceLabel);
|
||||
|
||||
|
@ -509,7 +540,10 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
|||
vBox.setId("splash");
|
||||
|
||||
ImageView logo = new ImageView();
|
||||
logo.setId(Config.baseCurrencyNetwork() == BaseCurrencyNetwork.XMR_MAINNET ? "image-splash-logo" : "image-splash-testnet-logo");
|
||||
logo.setId(Config.baseCurrencyNetwork() == BaseCurrencyNetwork.XMR_MAINNET ? "image-logo-splash" : "image-logo-splash-testnet");
|
||||
logo.setFitWidth(400);
|
||||
logo.setPreserveRatio(true);
|
||||
logo.setSmooth(true);
|
||||
|
||||
// createBitcoinInfoBox
|
||||
xmrSplashInfo = new AutoTooltipLabel();
|
||||
|
@ -552,7 +586,7 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
|||
// create P2PNetworkBox
|
||||
splashP2PNetworkLabel = new AutoTooltipLabel();
|
||||
splashP2PNetworkLabel.setWrapText(true);
|
||||
splashP2PNetworkLabel.setMaxWidth(500);
|
||||
splashP2PNetworkLabel.setMaxWidth(700);
|
||||
splashP2PNetworkLabel.setTextAlignment(TextAlignment.CENTER);
|
||||
splashP2PNetworkLabel.getStyleClass().add("sub-info");
|
||||
splashP2PNetworkLabel.textProperty().bind(model.getP2PNetworkInfo());
|
||||
|
@ -587,9 +621,11 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
|||
|
||||
ImageView splashP2PNetworkIcon = new ImageView();
|
||||
splashP2PNetworkIcon.setId("image-connection-tor");
|
||||
splashP2PNetworkIcon.setFitWidth(networkIconSize);
|
||||
splashP2PNetworkIcon.setFitHeight(networkIconSize);
|
||||
splashP2PNetworkIcon.setVisible(false);
|
||||
splashP2PNetworkIcon.setManaged(false);
|
||||
HBox.setMargin(splashP2PNetworkIcon, new Insets(0, 0, 5, 0));
|
||||
HBox.setMargin(splashP2PNetworkIcon, new Insets(0, 0, 0, 0));
|
||||
splashP2PNetworkIcon.setOnMouseClicked(e -> {
|
||||
torNetworkSettingsWindow.show();
|
||||
});
|
||||
|
@ -603,6 +639,8 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
|||
splashP2PNetworkIcon.setId(newValue);
|
||||
splashP2PNetworkIcon.setVisible(true);
|
||||
splashP2PNetworkIcon.setManaged(true);
|
||||
splashP2PNetworkIcon.setFitWidth(networkIconSize);
|
||||
splashP2PNetworkIcon.setFitHeight(networkIconSize);
|
||||
|
||||
// if we can connect in 10 sec. we know that tor is working
|
||||
showTorNetworkSettingsTimer.stop();
|
||||
|
@ -725,15 +763,39 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
|||
setRightAnchor(versionBox, 10d);
|
||||
setBottomAnchor(versionBox, 7d);
|
||||
|
||||
// Dark mode toggle
|
||||
ImageView useDarkModeIcon = new ImageView();
|
||||
useDarkModeIcon.setId(preferences.getCssTheme() == 1 ? "image-dark-mode-toggle" : "image-light-mode-toggle");
|
||||
useDarkModeIcon.setFitHeight(networkIconSize);
|
||||
useDarkModeIcon.setPreserveRatio(true);
|
||||
useDarkModeIcon.setPickOnBounds(true);
|
||||
useDarkModeIcon.setCursor(Cursor.HAND);
|
||||
setRightAnchor(useDarkModeIcon, 8d);
|
||||
setBottomAnchor(useDarkModeIcon, 6d);
|
||||
Tooltip modeToolTip = new Tooltip();
|
||||
Tooltip.install(useDarkModeIcon, modeToolTip);
|
||||
useDarkModeIcon.setOnMouseEntered(e -> modeToolTip.setText(Res.get(preferences.getCssTheme() == 1 ? "setting.preferences.useLightMode" : "setting.preferences.useDarkMode")));
|
||||
useDarkModeIcon.setOnMouseClicked(e -> {
|
||||
preferences.setCssTheme(preferences.getCssTheme() != 1);
|
||||
});
|
||||
preferences.getCssThemeProperty().addListener((observable, oldValue, newValue) -> {
|
||||
useDarkModeIcon.setId(preferences.getCssTheme() == 1 ? "image-dark-mode-toggle" : "image-light-mode-toggle");
|
||||
});
|
||||
|
||||
// P2P Network
|
||||
Label p2PNetworkLabel = new AutoTooltipLabel();
|
||||
p2PNetworkLabel.setId("footer-pane");
|
||||
p2PNetworkLabel.textProperty().bind(model.getP2PNetworkInfo());
|
||||
|
||||
double networkIconRightAnchor = 54d;
|
||||
ImageView p2PNetworkIcon = new ImageView();
|
||||
setRightAnchor(p2PNetworkIcon, 10d);
|
||||
setBottomAnchor(p2PNetworkIcon, 5d);
|
||||
setRightAnchor(p2PNetworkIcon, networkIconRightAnchor);
|
||||
setBottomAnchor(p2PNetworkIcon, 6d);
|
||||
p2PNetworkIcon.setPickOnBounds(true);
|
||||
p2PNetworkIcon.setCursor(Cursor.HAND);
|
||||
p2PNetworkIcon.setOpacity(0.4);
|
||||
p2PNetworkIcon.setFitWidth(networkIconSize);
|
||||
p2PNetworkIcon.setFitHeight(networkIconSize);
|
||||
p2PNetworkIcon.idProperty().bind(model.getP2PNetworkIconId());
|
||||
p2PNetworkLabel.idProperty().bind(model.getP2pNetworkLabelId());
|
||||
model.getP2pNetworkWarnMsg().addListener((ov, oldValue, newValue) -> {
|
||||
|
@ -749,8 +811,12 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
|||
});
|
||||
|
||||
ImageView p2PNetworkStatusIcon = new ImageView();
|
||||
setRightAnchor(p2PNetworkStatusIcon, 30d);
|
||||
setBottomAnchor(p2PNetworkStatusIcon, 7d);
|
||||
p2PNetworkStatusIcon.setPickOnBounds(true);
|
||||
p2PNetworkStatusIcon.setCursor(Cursor.HAND);
|
||||
p2PNetworkStatusIcon.setFitWidth(networkIconSize);
|
||||
p2PNetworkStatusIcon.setFitHeight(networkIconSize);
|
||||
setRightAnchor(p2PNetworkStatusIcon, networkIconRightAnchor + 22);
|
||||
setBottomAnchor(p2PNetworkStatusIcon, 6d);
|
||||
Tooltip p2pNetworkStatusToolTip = new Tooltip();
|
||||
Tooltip.install(p2PNetworkStatusIcon, p2pNetworkStatusToolTip);
|
||||
p2PNetworkStatusIcon.setOnMouseEntered(e -> p2pNetworkStatusToolTip.setText(model.getP2pConnectionSummary()));
|
||||
|
@ -791,10 +857,10 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
|||
VBox vBox = new VBox();
|
||||
vBox.setAlignment(Pos.CENTER_RIGHT);
|
||||
vBox.getChildren().addAll(p2PNetworkLabel, p2pNetworkProgressBar);
|
||||
setRightAnchor(vBox, 53d);
|
||||
setRightAnchor(vBox, networkIconRightAnchor + 45);
|
||||
setBottomAnchor(vBox, 5d);
|
||||
|
||||
return new AnchorPane(separator, xmrInfoLabel, versionBox, vBox, p2PNetworkStatusIcon, p2PNetworkIcon) {{
|
||||
return new AnchorPane(separator, xmrInfoLabel, versionBox, vBox, p2PNetworkStatusIcon, p2PNetworkIcon, useDarkModeIcon) {{
|
||||
setId("footer-pane");
|
||||
setMinHeight(30);
|
||||
setMaxHeight(30);
|
||||
|
@ -825,6 +891,9 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
|||
|
||||
this.setToggleGroup(navButtons);
|
||||
this.getStyleClass().add("nav-button");
|
||||
this.setMinWidth(Region.USE_PREF_SIZE); // prevent squashing content
|
||||
this.setPrefWidth(Region.USE_COMPUTED_SIZE);
|
||||
|
||||
// Japanese fonts are dense, increase top nav button text size
|
||||
if (model.getPreferences() != null && "ja".equals(model.getPreferences().getUserLanguage())) {
|
||||
this.getStyleClass().add("nav-button-japanese");
|
||||
|
@ -836,4 +905,29 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
private class SecondaryNavButton extends NavButton {
|
||||
|
||||
SecondaryNavButton(Class<? extends View> viewClass, String title, String iconId) {
|
||||
super(viewClass, title);
|
||||
this.getStyleClass().setAll("nav-secondary-button");
|
||||
|
||||
// Japanese fonts are dense, increase top nav button text size
|
||||
if (model.getPreferences() != null && "ja".equals(model.getPreferences().getUserLanguage())) {
|
||||
this.getStyleClass().setAll("nav-secondary-button-japanese");
|
||||
}
|
||||
|
||||
// add icon
|
||||
ImageView imageView = new ImageView();
|
||||
imageView.setId(iconId);
|
||||
imageView.setFitWidth(15);
|
||||
imageView.setPreserveRatio(true);
|
||||
setGraphicTextGap(10);
|
||||
setGraphic(imageView);
|
||||
|
||||
// show cursor hand on any hover
|
||||
this.setPickOnBounds(true);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,12 +86,12 @@ public class AccountView extends ActivatableView<TabPane, Void> {
|
|||
|
||||
root.setTabClosingPolicy(TabPane.TabClosingPolicy.ALL_TABS);
|
||||
|
||||
traditionalAccountsTab.setText(Res.get("account.menu.paymentAccount").toUpperCase());
|
||||
cryptoAccountsTab.setText(Res.get("account.menu.altCoinsAccountView").toUpperCase());
|
||||
passwordTab.setText(Res.get("account.menu.password").toUpperCase());
|
||||
seedWordsTab.setText(Res.get("account.menu.seedWords").toUpperCase());
|
||||
//walletInfoTab.setText(Res.get("account.menu.walletInfo").toUpperCase());
|
||||
backupTab.setText(Res.get("account.menu.backup").toUpperCase());
|
||||
traditionalAccountsTab.setText(Res.get("account.menu.paymentAccount"));
|
||||
cryptoAccountsTab.setText(Res.get("account.menu.altCoinsAccountView"));
|
||||
passwordTab.setText(Res.get("account.menu.password"));
|
||||
seedWordsTab.setText(Res.get("account.menu.seedWords"));
|
||||
//walletInfoTab.setText(Res.get("account.menu.walletInfo"));
|
||||
backupTab.setText(Res.get("account.menu.backup"));
|
||||
|
||||
navigationListener = (viewPath, data) -> {
|
||||
if (viewPath.size() == 3 && viewPath.indexOf(AccountView.class) == 1) {
|
||||
|
|
|
@ -216,7 +216,7 @@ public class CryptoAccountsView extends PaymentAccountsView<GridPane, CryptoAcco
|
|||
}
|
||||
removeAccountRows();
|
||||
addAccountButton.setDisable(false);
|
||||
accountTitledGroupBg = addTitledGroupBg(root, ++gridRow, 2, Res.get("shared.selectedAccount"), Layout.GROUP_DISTANCE);
|
||||
accountTitledGroupBg = addTitledGroupBg(root, ++gridRow, 2, "", Layout.GROUP_DISTANCE);
|
||||
paymentMethodForm = getPaymentMethodForm(current);
|
||||
paymentMethodForm.addFormForEditAccount();
|
||||
gridRow = paymentMethodForm.getGridRow();
|
||||
|
|
|
@ -26,6 +26,7 @@ import haveno.desktop.components.AutoTooltipButton;
|
|||
import haveno.desktop.components.AutoTooltipLabel;
|
||||
import haveno.desktop.components.AutoTooltipTableColumn;
|
||||
import haveno.desktop.main.overlays.Overlay;
|
||||
import haveno.desktop.util.GUIUtil;
|
||||
import haveno.desktop.util.ImageUtil;
|
||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||
import javafx.collections.FXCollections;
|
||||
|
@ -73,6 +74,7 @@ public class ManageMarketAlertsWindow extends Overlay<ManageMarketAlertsWindow>
|
|||
|
||||
private void addContent() {
|
||||
TableView<MarketAlertFilter> tableView = new TableView<>();
|
||||
GUIUtil.applyTableStyle(tableView);
|
||||
GridPane.setRowIndex(tableView, ++rowIndex);
|
||||
GridPane.setColumnSpan(tableView, 2);
|
||||
GridPane.setMargin(tableView, new Insets(10, 0, 0, 0));
|
||||
|
|
|
@ -535,7 +535,7 @@ public class TraditionalAccountsView extends PaymentAccountsView<GridPane, Tradi
|
|||
}
|
||||
removeAccountRows();
|
||||
addAccountButton.setDisable(false);
|
||||
accountTitledGroupBg = addTitledGroupBg(root, ++gridRow, 2, Res.get("shared.selectedAccount"), Layout.GROUP_DISTANCE);
|
||||
accountTitledGroupBg = addTitledGroupBg(root, ++gridRow, 2, "", Layout.GROUP_DISTANCE);
|
||||
paymentMethodForm = getPaymentMethodForm(current);
|
||||
if (paymentMethodForm != null) {
|
||||
paymentMethodForm.addFormForEditAccount();
|
||||
|
|
|
@ -55,9 +55,9 @@ public class FundsView extends ActivatableView<TabPane, Void> {
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
depositTab.setText(Res.get("funds.tab.deposit").toUpperCase());
|
||||
withdrawalTab.setText(Res.get("funds.tab.withdrawal").toUpperCase());
|
||||
transactionsTab.setText(Res.get("funds.tab.transactions").toUpperCase());
|
||||
depositTab.setText(Res.get("funds.tab.deposit"));
|
||||
withdrawalTab.setText(Res.get("funds.tab.withdrawal"));
|
||||
transactionsTab.setText(Res.get("funds.tab.transactions"));
|
||||
|
||||
navigationListener = (viewPath, data) -> {
|
||||
if (viewPath.size() == 3 && viewPath.indexOf(FundsView.class) == 1)
|
||||
|
|
|
@ -40,6 +40,7 @@ import com.google.inject.name.Named;
|
|||
import haveno.common.ThreadUtils;
|
||||
import haveno.common.UserThread;
|
||||
import haveno.common.app.DevEnv;
|
||||
import haveno.common.util.Tuple2;
|
||||
import haveno.common.util.Tuple3;
|
||||
import haveno.core.locale.Res;
|
||||
import haveno.core.trade.HavenoUtils;
|
||||
|
@ -89,10 +90,9 @@ import javafx.scene.image.Image;
|
|||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.util.Callback;
|
||||
import monero.common.MoneroUtils;
|
||||
import monero.wallet.model.MoneroTxConfig;
|
||||
import monero.wallet.model.MoneroWalletListener;
|
||||
import net.glxn.qrgen.QRCode;
|
||||
import net.glxn.qrgen.image.ImageType;
|
||||
|
@ -111,6 +111,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
|
|||
@FXML
|
||||
TableColumn<DepositListItem, DepositListItem> addressColumn, balanceColumn, confirmationsColumn, usageColumn;
|
||||
private ImageView qrCodeImageView;
|
||||
private StackPane qrCodePane;
|
||||
private AddressTextField addressTextField;
|
||||
private Button generateNewAddressButton;
|
||||
private TitledGroupBg titledGroupBg;
|
||||
|
@ -144,6 +145,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
GUIUtil.applyTableStyle(tableView);
|
||||
|
||||
paymentLabelString = Res.get("funds.deposit.fundHavenoWallet");
|
||||
addressColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.address")));
|
||||
|
@ -154,6 +156,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
|
|||
// set loading placeholder
|
||||
Label placeholderLabel = new Label("Loading...");
|
||||
tableView.setPlaceholder(placeholderLabel);
|
||||
tableView.getStyleClass().add("non-interactive-table");
|
||||
|
||||
ThreadUtils.execute(() -> {
|
||||
|
||||
|
@ -190,19 +193,19 @@ public class DepositView extends ActivatableView<VBox, Void> {
|
|||
titledGroupBg = addTitledGroupBg(gridPane, gridRow, 4, Res.get("funds.deposit.fundWallet"));
|
||||
titledGroupBg.getStyleClass().add("last");
|
||||
|
||||
qrCodeImageView = new ImageView();
|
||||
qrCodeImageView.setFitHeight(150);
|
||||
qrCodeImageView.setFitWidth(150);
|
||||
qrCodeImageView.getStyleClass().add("qr-code");
|
||||
Tooltip.install(qrCodeImageView, new Tooltip(Res.get("shared.openLargeQRWindow")));
|
||||
qrCodeImageView.setOnMouseClicked(e -> UserThread.runAfter(
|
||||
Tuple2<StackPane, ImageView> qrCodeTuple = GUIUtil.getSmallXmrQrCodePane();
|
||||
qrCodePane = qrCodeTuple.first;
|
||||
qrCodeImageView = qrCodeTuple.second;
|
||||
|
||||
Tooltip.install(qrCodePane, new Tooltip(Res.get("shared.openLargeQRWindow")));
|
||||
qrCodePane.setOnMouseClicked(e -> UserThread.runAfter(
|
||||
() -> new QRCodeWindow(getPaymentUri()).show(),
|
||||
200, TimeUnit.MILLISECONDS));
|
||||
GridPane.setRowIndex(qrCodeImageView, gridRow);
|
||||
GridPane.setRowSpan(qrCodeImageView, 4);
|
||||
GridPane.setColumnIndex(qrCodeImageView, 1);
|
||||
GridPane.setMargin(qrCodeImageView, new Insets(Layout.FIRST_ROW_DISTANCE, 0, 0, 10));
|
||||
gridPane.getChildren().add(qrCodeImageView);
|
||||
GridPane.setRowIndex(qrCodePane, gridRow);
|
||||
GridPane.setRowSpan(qrCodePane, 4);
|
||||
GridPane.setColumnIndex(qrCodePane, 1);
|
||||
GridPane.setMargin(qrCodePane, new Insets(Layout.FIRST_ROW_DISTANCE, 0, 0, 10));
|
||||
gridPane.getChildren().add(qrCodePane);
|
||||
|
||||
addressTextField = addAddressTextField(gridPane, ++gridRow, Res.get("shared.address"), Layout.FIRST_ROW_DISTANCE);
|
||||
addressTextField.setPaymentLabel(paymentLabelString);
|
||||
|
@ -213,8 +216,8 @@ public class DepositView extends ActivatableView<VBox, Void> {
|
|||
|
||||
titledGroupBg.setVisible(false);
|
||||
titledGroupBg.setManaged(false);
|
||||
qrCodeImageView.setVisible(false);
|
||||
qrCodeImageView.setManaged(false);
|
||||
qrCodePane.setVisible(false);
|
||||
qrCodePane.setManaged(false);
|
||||
addressTextField.setVisible(false);
|
||||
addressTextField.setManaged(false);
|
||||
amountTextField.setManaged(false);
|
||||
|
@ -310,8 +313,8 @@ public class DepositView extends ActivatableView<VBox, Void> {
|
|||
private void fillForm(String address) {
|
||||
titledGroupBg.setVisible(true);
|
||||
titledGroupBg.setManaged(true);
|
||||
qrCodeImageView.setVisible(true);
|
||||
qrCodeImageView.setManaged(true);
|
||||
qrCodePane.setVisible(true);
|
||||
qrCodePane.setManaged(true);
|
||||
addressTextField.setVisible(true);
|
||||
addressTextField.setManaged(true);
|
||||
amountTextField.setManaged(true);
|
||||
|
@ -366,10 +369,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
|
|||
|
||||
@NotNull
|
||||
private String getPaymentUri() {
|
||||
return MoneroUtils.getPaymentUri(new MoneroTxConfig()
|
||||
.setAddress(addressTextField.getAddress())
|
||||
.setAmount(HavenoUtils.coinToAtomicUnits(getAmount()))
|
||||
.setNote(paymentLabelString));
|
||||
return GUIUtil.getMoneroURI(addressTextField.getAddress(), HavenoUtils.coinToAtomicUnits(getAmount()), paymentLabelString);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -377,7 +377,6 @@ public class DepositView extends ActivatableView<VBox, Void> {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void setUsageColumnCellFactory() {
|
||||
usageColumn.getStyleClass().add("last-column");
|
||||
usageColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
|
||||
usageColumn.setCellFactory(new Callback<>() {
|
||||
|
||||
|
@ -390,7 +389,9 @@ public class DepositView extends ActivatableView<VBox, Void> {
|
|||
public void updateItem(final DepositListItem item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (item != null && !empty) {
|
||||
setGraphic(new AutoTooltipLabel(item.getUsage()));
|
||||
Label usageLabel = new AutoTooltipLabel(item.getUsage());
|
||||
usageLabel.getStyleClass().add("highlight-text");
|
||||
setGraphic(usageLabel);
|
||||
} else {
|
||||
setGraphic(null);
|
||||
}
|
||||
|
@ -401,7 +402,6 @@ public class DepositView extends ActivatableView<VBox, Void> {
|
|||
}
|
||||
|
||||
private void setAddressColumnCellFactory() {
|
||||
addressColumn.getStyleClass().add("first-column");
|
||||
addressColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
|
||||
|
||||
addressColumn.setCellFactory(
|
||||
|
@ -434,6 +434,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
|
|||
|
||||
private void setBalanceColumnCellFactory() {
|
||||
balanceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
|
||||
balanceColumn.getStyleClass().add("highlight-text");
|
||||
balanceColumn.setCellFactory(new Callback<>() {
|
||||
|
||||
@Override
|
||||
|
|
|
@ -122,6 +122,7 @@ public class LockedView extends ActivatableView<VBox, Void> {
|
|||
addressColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.address")));
|
||||
balanceColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.balanceWithCur", Res.getBaseCurrencyCode())));
|
||||
|
||||
GUIUtil.applyTableStyle(tableView);
|
||||
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
||||
tableView.setPlaceholder(new AutoTooltipLabel(Res.get("funds.locked.noFunds")));
|
||||
|
||||
|
@ -250,7 +251,6 @@ public class LockedView extends ActivatableView<VBox, Void> {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void setDateColumnCellFactory() {
|
||||
dateColumn.getStyleClass().add("first-column");
|
||||
dateColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
|
||||
dateColumn.setCellFactory(new Callback<>() {
|
||||
|
||||
|
@ -342,7 +342,6 @@ public class LockedView extends ActivatableView<VBox, Void> {
|
|||
}
|
||||
|
||||
private void setBalanceColumnCellFactory() {
|
||||
balanceColumn.getStyleClass().add("last-column");
|
||||
balanceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
|
||||
balanceColumn.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
|
|
@ -122,6 +122,7 @@ public class ReservedView extends ActivatableView<VBox, Void> {
|
|||
addressColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.address")));
|
||||
balanceColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.balanceWithCur", Res.getBaseCurrencyCode())));
|
||||
|
||||
GUIUtil.applyTableStyle(tableView);
|
||||
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
||||
tableView.setPlaceholder(new AutoTooltipLabel(Res.get("funds.reserved.noFunds")));
|
||||
|
||||
|
@ -249,7 +250,6 @@ public class ReservedView extends ActivatableView<VBox, Void> {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void setDateColumnCellFactory() {
|
||||
dateColumn.getStyleClass().add("first-column");
|
||||
dateColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
|
||||
dateColumn.setCellFactory(new Callback<>() {
|
||||
|
||||
|
@ -313,7 +313,6 @@ public class ReservedView extends ActivatableView<VBox, Void> {
|
|||
}
|
||||
|
||||
private void setAddressColumnCellFactory() {
|
||||
addressColumn.getStyleClass().add("last-column");
|
||||
addressColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
|
||||
|
||||
addressColumn.setCellFactory(
|
||||
|
@ -341,7 +340,6 @@ public class ReservedView extends ActivatableView<VBox, Void> {
|
|||
}
|
||||
|
||||
private void setBalanceColumnCellFactory() {
|
||||
balanceColumn.getStyleClass().add("last-column");
|
||||
balanceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
|
||||
balanceColumn.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
|
|
@ -32,14 +32,14 @@
|
|||
</padding>
|
||||
<TableView fx:id="tableView" VBox.vgrow="ALWAYS">
|
||||
<columns>
|
||||
<TableColumn fx:id="dateColumn" minWidth="180" maxWidth="180"/>
|
||||
<TableColumn fx:id="detailsColumn" minWidth="220" maxWidth="220"/>
|
||||
<TableColumn fx:id="addressColumn" minWidth="260"/>
|
||||
<TableColumn fx:id="dateColumn" minWidth="100" maxWidth="180"/>
|
||||
<TableColumn fx:id="detailsColumn" minWidth="180" maxWidth="220"/>
|
||||
<TableColumn fx:id="addressColumn" minWidth="250"/>
|
||||
<TableColumn fx:id="transactionColumn" minWidth="180"/>
|
||||
<TableColumn fx:id="amountColumn" minWidth="110" maxWidth="110"/>
|
||||
<TableColumn fx:id="txFeeColumn" minWidth="110" maxWidth="110"/>
|
||||
<TableColumn fx:id="confidenceColumn" minWidth="60" maxWidth="130"/>
|
||||
<TableColumn fx:id="memoColumn" minWidth="40"/>
|
||||
<TableColumn fx:id="confidenceColumn" minWidth="70" maxWidth="130"/>
|
||||
<TableColumn fx:id="memoColumn" minWidth="40" maxWidth="250"/>
|
||||
<TableColumn fx:id="revertTxColumn" sortable="false" minWidth="110" maxWidth="110" visible="false"/>
|
||||
</columns>
|
||||
</TableView>
|
||||
|
|
|
@ -127,6 +127,8 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
GUIUtil.applyTableStyle(tableView);
|
||||
|
||||
dateColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.dateTime")));
|
||||
detailsColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.details")));
|
||||
addressColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.address")));
|
||||
|
@ -139,6 +141,7 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
|||
|
||||
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY_FLEX_LAST_COLUMN);
|
||||
tableView.setPlaceholder(new AutoTooltipLabel(Res.get("funds.tx.noTxAvailable")));
|
||||
tableView.getStyleClass().add("non-interactive-table");
|
||||
|
||||
setDateColumnCellFactory();
|
||||
setDetailsColumnCellFactory();
|
||||
|
@ -169,11 +172,6 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
|||
keyEventEventHandler = event -> {
|
||||
// Not intended to be public to users as the feature is not well tested
|
||||
if (Utilities.isAltOrCtrlPressed(KeyCode.R, event)) {
|
||||
if (revertTxColumn.isVisible()) {
|
||||
confidenceColumn.getStyleClass().remove("last-column");
|
||||
} else {
|
||||
confidenceColumn.getStyleClass().add("last-column");
|
||||
}
|
||||
revertTxColumn.setVisible(!revertTxColumn.isVisible());
|
||||
}
|
||||
};
|
||||
|
@ -265,7 +263,6 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void setDateColumnCellFactory() {
|
||||
dateColumn.getStyleClass().add("first-column");
|
||||
dateColumn.setCellValueFactory((addressListItem) ->
|
||||
new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
|
||||
dateColumn.setMaxWidth(200);
|
||||
|
@ -400,6 +397,7 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
|||
private void setAmountColumnCellFactory() {
|
||||
amountColumn.setCellValueFactory((addressListItem) ->
|
||||
new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
|
||||
amountColumn.getStyleClass().add("highlight-text");
|
||||
amountColumn.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
||||
|
@ -427,6 +425,7 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
|||
private void setTxFeeColumnCellFactory() {
|
||||
txFeeColumn.setCellValueFactory((addressListItem) ->
|
||||
new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
|
||||
txFeeColumn.getStyleClass().add("highlight-text");
|
||||
txFeeColumn.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
||||
|
@ -453,6 +452,7 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
|||
private void setMemoColumnCellFactory() {
|
||||
memoColumn.setCellValueFactory((addressListItem) ->
|
||||
new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
|
||||
memoColumn.getStyleClass().add("highlight-text");
|
||||
memoColumn.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
||||
|
@ -477,7 +477,6 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
|||
}
|
||||
|
||||
private void setConfidenceColumnCellFactory() {
|
||||
confidenceColumn.getStyleClass().add("last-column");
|
||||
confidenceColumn.setCellValueFactory((addressListItem) ->
|
||||
new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
|
||||
confidenceColumn.setCellFactory(
|
||||
|
@ -504,7 +503,6 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
|||
}
|
||||
|
||||
private void setRevertTxColumnCellFactory() {
|
||||
revertTxColumn.getStyleClass().add("last-column");
|
||||
revertTxColumn.setCellValueFactory((addressListItem) ->
|
||||
new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
|
||||
revertTxColumn.setCellFactory(
|
||||
|
|
|
@ -144,7 +144,7 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||
|
||||
amountLabel = feeTuple3.first;
|
||||
amountTextField = feeTuple3.second;
|
||||
amountTextField.setMinWidth(180);
|
||||
amountTextField.setMinWidth(200);
|
||||
HyperlinkWithIcon sendMaxLink = feeTuple3.third;
|
||||
|
||||
withdrawMemoTextField = addTopLabelInputTextField(gridPane, ++rowIndex,
|
||||
|
|
|
@ -88,10 +88,10 @@ public class MarketView extends ActivatableView<TabPane, Void> {
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
offerBookTab.setText(Res.get("market.tabs.offerBook").toUpperCase());
|
||||
spreadTab.setText(Res.get("market.tabs.spreadCurrency").toUpperCase());
|
||||
spreadTabPaymentMethod.setText(Res.get("market.tabs.spreadPayment").toUpperCase());
|
||||
tradesTab.setText(Res.get("market.tabs.trades").toUpperCase());
|
||||
offerBookTab.setText(Res.get("market.tabs.offerBook"));
|
||||
spreadTab.setText(Res.get("market.tabs.spreadCurrency"));
|
||||
spreadTabPaymentMethod.setText(Res.get("market.tabs.spreadPayment"));
|
||||
tradesTab.setText(Res.get("market.tabs.trades"));
|
||||
|
||||
navigationListener = (viewPath, data) -> {
|
||||
if (viewPath.size() == 3 && viewPath.indexOf(MarketView.class) == 1)
|
||||
|
|
|
@ -26,6 +26,7 @@ import haveno.common.util.Tuple3;
|
|||
import haveno.common.util.Tuple4;
|
||||
import haveno.core.locale.CurrencyUtil;
|
||||
import haveno.core.locale.Res;
|
||||
import haveno.core.monetary.Volume;
|
||||
import haveno.core.offer.Offer;
|
||||
import haveno.core.offer.OfferDirection;
|
||||
import haveno.core.util.FormattingUtils;
|
||||
|
@ -65,13 +66,13 @@ import javafx.scene.chart.NumberAxis;
|
|||
import javafx.scene.chart.XYChart;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.ContentDisplay;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.SingleSelectionModel;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.control.TableCell;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
|
@ -95,7 +96,10 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
|||
private AnchorPane chartPane;
|
||||
private AutocompleteComboBox<CurrencyListItem> currencyComboBox;
|
||||
private Subscription tradeCurrencySubscriber;
|
||||
private final StringProperty volumeColumnLabel = new SimpleStringProperty();
|
||||
private final StringProperty volumeSellColumnLabel = new SimpleStringProperty();
|
||||
private final StringProperty volumeBuyColumnLabel = new SimpleStringProperty();
|
||||
private final StringProperty amountSellColumnLabel = new SimpleStringProperty();
|
||||
private final StringProperty amountBuyColumnLabel = new SimpleStringProperty();
|
||||
private final StringProperty priceColumnLabel = new SimpleStringProperty();
|
||||
private AutoTooltipButton sellButton;
|
||||
private AutoTooltipButton buyButton;
|
||||
|
@ -106,10 +110,11 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
|||
private ListChangeListener<OfferBookListItem> changeListener;
|
||||
private ListChangeListener<CurrencyListItem> currencyListItemsListener;
|
||||
private final double dataLimitFactor = 3;
|
||||
private final double initialOfferTableViewHeight = 121;
|
||||
private final double initialOfferTableViewHeight = 78; // decrease as MainView's content-pane's top anchor increases
|
||||
private final double offerTableExtraMarginBottom = 0;
|
||||
private final Function<Double, Double> offerTableViewHeight = (screenSize) -> {
|
||||
// initial visible row count=5, header height=30
|
||||
double pixelsPerOfferTableRow = (initialOfferTableViewHeight - 30) / 5.0;
|
||||
double pixelsPerOfferTableRow = (initialOfferTableViewHeight - offerTableExtraMarginBottom) / 5.0;
|
||||
int extraRows = screenSize <= INITIAL_WINDOW_HEIGHT ? 0 : (int) ((screenSize - INITIAL_WINDOW_HEIGHT) / pixelsPerOfferTableRow);
|
||||
return extraRows == 0 ? initialOfferTableViewHeight : Math.ceil(initialOfferTableViewHeight + ((extraRows + 1) * pixelsPerOfferTableRow));
|
||||
};
|
||||
|
@ -136,6 +141,7 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
|||
this.currencyComboBox = currencyComboBoxTuple.third;
|
||||
this.currencyComboBox.setCellFactory(GUIUtil.getCurrencyListItemCellFactory(Res.get("shared.oneOffer"),
|
||||
Res.get("shared.multipleOffers"), model.preferences));
|
||||
this.currencyComboBox.getStyleClass().add("input-with-border");
|
||||
|
||||
createChart();
|
||||
|
||||
|
@ -200,7 +206,6 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
|||
tradeCurrencySubscriber = EasyBind.subscribe(model.selectedTradeCurrencyProperty,
|
||||
tradeCurrency -> {
|
||||
String code = tradeCurrency.getCode();
|
||||
volumeColumnLabel.set(Res.get("offerbook.volume", code));
|
||||
xAxis.setTickLabelFormatter(new StringConverter<>() {
|
||||
final int cryptoPrecision = 3;
|
||||
final DecimalFormat df = new DecimalFormat(",###");
|
||||
|
@ -230,15 +235,21 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
|||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
String viewBaseCurrencyCode = CurrencyUtil.isCryptoCurrency(code) ? code : Res.getBaseCurrencyCode();
|
||||
String viewPriceCurrencyCode = CurrencyUtil.isCryptoCurrency(code) ? Res.getBaseCurrencyCode() : code;
|
||||
|
||||
String viewBaseCurrencyCode = model.isCrypto() ? code : Res.getBaseCurrencyCode();
|
||||
String viewPriceCurrencyCode = model.isCrypto() ? Res.getBaseCurrencyCode() : code;
|
||||
|
||||
sellHeaderLabel.setText(Res.get("market.offerBook.sellOffersHeaderLabel", viewBaseCurrencyCode));
|
||||
sellButton.updateText(Res.get("shared.sellCurrency", viewBaseCurrencyCode, viewPriceCurrencyCode));
|
||||
sellButton.updateText(Res.get("shared.sellCurrency", viewBaseCurrencyCode));
|
||||
sellButton.setGraphic(GUIUtil.getCurrencyIconWithBorder(viewBaseCurrencyCode));
|
||||
sellButton.setOnAction(e -> model.goToOfferView(model.isCrypto() ? OfferDirection.SELL : OfferDirection.BUY));
|
||||
sellButton.setId("sell-button-big");
|
||||
|
||||
buyHeaderLabel.setText(Res.get("market.offerBook.buyOffersHeaderLabel", viewBaseCurrencyCode));
|
||||
buyButton.updateText(Res.get("shared.buyCurrency", viewBaseCurrencyCode, viewPriceCurrencyCode));
|
||||
buyButton.updateText(Res.get( "shared.buyCurrency", viewBaseCurrencyCode));
|
||||
buyButton.setGraphic(GUIUtil.getCurrencyIconWithBorder(viewBaseCurrencyCode));
|
||||
buyButton.setOnAction(e -> model.goToOfferView(model.isCrypto() ? OfferDirection.BUY : OfferDirection.SELL));
|
||||
buyButton.setId("buy-button-big");
|
||||
|
||||
priceColumnLabel.set(Res.get("shared.priceWithCur", viewPriceCurrencyCode));
|
||||
|
||||
|
@ -288,8 +299,8 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
|||
currencyComboBox.getSelectionModel().select(model.getSelectedCurrencyListItem().get());
|
||||
};
|
||||
|
||||
buyTableRowSelectionListener = (observable, oldValue, newValue) -> model.goToOfferView(OfferDirection.BUY);
|
||||
sellTableRowSelectionListener = (observable, oldValue, newValue) -> model.goToOfferView(OfferDirection.SELL);
|
||||
buyTableRowSelectionListener = (observable, oldValue, newValue) -> model.goToOfferView(OfferDirection.BUY);
|
||||
|
||||
havenoWindowVerticalSizeListener = (observable, oldValue, newValue) -> layout();
|
||||
}
|
||||
|
@ -345,12 +356,27 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
|||
}
|
||||
|
||||
private synchronized void updateChartData() {
|
||||
seriesBuy.getData().clear();
|
||||
|
||||
// update volume headers
|
||||
Volume volumeSell = model.getTotalVolume(model.isCrypto() ? OfferDirection.BUY : OfferDirection.SELL);
|
||||
Volume volumeBuy = model.getTotalVolume(model.isCrypto() ? OfferDirection.SELL : OfferDirection.BUY);
|
||||
String formattedVolumeSell = volumeSell == null ? null : VolumeUtil.formatVolume(volumeSell);
|
||||
String formattedVolumeBuy = volumeBuy == null ? null : VolumeUtil.formatVolume(volumeBuy);
|
||||
if (model.getSellData().isEmpty()) formattedVolumeSell = "0.0";
|
||||
if (model.getBuyData().isEmpty()) formattedVolumeBuy = "0.0";
|
||||
volumeSellColumnLabel.set(Res.get("offerbook.volumeTotal", model.getCurrencyCode(), formattedVolumeSell == null ? "" : "(" + formattedVolumeSell + ")"));
|
||||
volumeBuyColumnLabel.set(Res.get("offerbook.volumeTotal", model.getCurrencyCode(), formattedVolumeBuy == null ? "" : "(" + formattedVolumeBuy + ")"));
|
||||
|
||||
// update amount headers
|
||||
amountSellColumnLabel.set(Res.get("offerbook.XMRTotal", "" + model.getTotalAmount(model.isCrypto() ? OfferDirection.BUY : OfferDirection.SELL)));
|
||||
amountBuyColumnLabel.set(Res.get("offerbook.XMRTotal", "" + model.getTotalAmount(model.isCrypto() ? OfferDirection.SELL : OfferDirection.BUY)));
|
||||
|
||||
seriesSell.getData().clear();
|
||||
seriesBuy.getData().clear();
|
||||
areaChart.getData().clear();
|
||||
|
||||
seriesBuy.getData().addAll(filterOutliersBuy(model.getBuyData()));
|
||||
seriesSell.getData().addAll(filterOutliersSell(model.getSellData()));
|
||||
seriesBuy.getData().addAll(filterOutliersBuy(model.getBuyData()));
|
||||
|
||||
areaChart.getData().addAll(List.of(seriesBuy, seriesSell));
|
||||
}
|
||||
|
@ -426,10 +452,11 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
|||
|
||||
private Tuple4<TableView<OfferListItem>, VBox, Button, Label> getOfferTable(OfferDirection direction) {
|
||||
TableView<OfferListItem> tableView = new TableView<>();
|
||||
GUIUtil.applyTableStyle(tableView, false);
|
||||
tableView.setMinHeight(initialOfferTableViewHeight);
|
||||
tableView.setPrefHeight(initialOfferTableViewHeight);
|
||||
tableView.setMinWidth(480);
|
||||
tableView.getStyleClass().add("offer-table");
|
||||
tableView.getStyleClass().addAll("offer-table", "non-interactive-table");
|
||||
|
||||
// price
|
||||
TableColumn<OfferListItem, OfferListItem> priceColumn = new TableColumn<>();
|
||||
|
@ -484,12 +511,14 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
|||
}
|
||||
});
|
||||
|
||||
boolean isSellTable = model.isSellOffer(direction);
|
||||
|
||||
// volume
|
||||
TableColumn<OfferListItem, OfferListItem> volumeColumn = new TableColumn<>();
|
||||
volumeColumn.setMinWidth(115);
|
||||
volumeColumn.setSortable(false);
|
||||
volumeColumn.textProperty().bind(volumeColumnLabel);
|
||||
volumeColumn.getStyleClass().addAll("number-column", "first-column");
|
||||
volumeColumn.textProperty().bind(isSellTable ? volumeSellColumnLabel : volumeBuyColumnLabel);
|
||||
volumeColumn.getStyleClass().addAll("number-column");
|
||||
volumeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
|
||||
volumeColumn.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
@ -546,7 +575,8 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
|||
});
|
||||
|
||||
// amount
|
||||
TableColumn<OfferListItem, OfferListItem> amountColumn = new AutoTooltipTableColumn<>(Res.get("shared.XMRMinMax"));
|
||||
TableColumn<OfferListItem, OfferListItem> amountColumn = new TableColumn<>();
|
||||
amountColumn.textProperty().bind(isSellTable ? amountSellColumnLabel : amountBuyColumnLabel);
|
||||
amountColumn.setMinWidth(115);
|
||||
amountColumn.setSortable(false);
|
||||
amountColumn.getStyleClass().add("number-column");
|
||||
|
@ -570,10 +600,8 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
|||
}
|
||||
});
|
||||
|
||||
boolean isSellOffer = model.isSellOffer(direction);
|
||||
|
||||
// trader avatar
|
||||
TableColumn<OfferListItem, OfferListItem> avatarColumn = new AutoTooltipTableColumn<>(isSellOffer ?
|
||||
TableColumn<OfferListItem, OfferListItem> avatarColumn = new AutoTooltipTableColumn<>(isSellTable ?
|
||||
Res.get("shared.sellerUpperCase") : Res.get("shared.buyerUpperCase")) {
|
||||
{
|
||||
setMinWidth(80);
|
||||
|
@ -582,7 +610,7 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
|||
}
|
||||
};
|
||||
|
||||
avatarColumn.getStyleClass().addAll("last-column", "avatar-column");
|
||||
avatarColumn.getStyleClass().addAll("avatar-column");
|
||||
avatarColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
|
||||
avatarColumn.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
@ -629,20 +657,16 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
|||
tableView.setPlaceholder(placeholder);
|
||||
|
||||
HBox titleButtonBox = new HBox();
|
||||
titleButtonBox.getStyleClass().add("offer-table-top");
|
||||
titleButtonBox.setAlignment(Pos.CENTER);
|
||||
|
||||
Label titleLabel = new AutoTooltipLabel();
|
||||
titleLabel.getStyleClass().add("table-title");
|
||||
|
||||
AutoTooltipButton button = new AutoTooltipButton();
|
||||
ImageView iconView = new ImageView();
|
||||
iconView.setId(isSellOffer ? "image-buy-white" : "image-sell-white");
|
||||
button.setGraphic(iconView);
|
||||
button.setContentDisplay(ContentDisplay.RIGHT);
|
||||
button.setGraphicTextGap(10);
|
||||
button.updateText(isSellOffer ? Res.get("market.offerBook.buy") : Res.get("market.offerBook.sell"));
|
||||
button.setMinHeight(32);
|
||||
button.setId(isSellOffer ? "buy-button-big" : "sell-button-big");
|
||||
button.setOnAction(e -> model.goToOfferView(direction));
|
||||
|
||||
Region spacer = new Region();
|
||||
|
||||
|
@ -653,9 +677,9 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
|||
VBox vBox = new VBox();
|
||||
VBox.setVgrow(tableView, Priority.ALWAYS);
|
||||
vBox.setPadding(new Insets(0, 0, 0, 0));
|
||||
vBox.setSpacing(10);
|
||||
vBox.setSpacing(0);
|
||||
vBox.setFillWidth(true);
|
||||
vBox.setMinHeight(190);
|
||||
//vBox.setMinHeight(190);
|
||||
vBox.getChildren().addAll(titleButtonBox, tableView);
|
||||
|
||||
return new Tuple4<>(tableView, vBox, button, titleLabel);
|
||||
|
|
|
@ -26,6 +26,7 @@ import haveno.core.locale.CurrencyUtil;
|
|||
import haveno.core.locale.GlobalSettings;
|
||||
import haveno.core.locale.TradeCurrency;
|
||||
import haveno.core.monetary.Price;
|
||||
import haveno.core.monetary.Volume;
|
||||
import haveno.core.offer.Offer;
|
||||
import haveno.core.offer.OfferDirection;
|
||||
import haveno.core.offer.OpenOfferManager;
|
||||
|
@ -58,6 +59,7 @@ import javafx.collections.ListChangeListener;
|
|||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.chart.XYChart;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
@ -212,10 +214,42 @@ class OfferBookChartViewModel extends ActivatableViewModel {
|
|||
}
|
||||
|
||||
public boolean isSellOffer(OfferDirection direction) {
|
||||
// for cryptocurrency, buy direction is to buy XMR, so we need sell offers
|
||||
// for traditional currency, buy direction is to sell XMR, so we need buy offers
|
||||
boolean isCryptoCurrency = CurrencyUtil.isCryptoCurrency(getCurrencyCode());
|
||||
return isCryptoCurrency ? direction == OfferDirection.BUY : direction == OfferDirection.SELL;
|
||||
return direction == OfferDirection.SELL;
|
||||
}
|
||||
|
||||
public double getTotalAmount(OfferDirection direction) {
|
||||
synchronized (offerBookListItems) {
|
||||
List<Offer> offerList = offerBookListItems.stream()
|
||||
.map(OfferBookListItem::getOffer)
|
||||
.filter(e -> e.getCurrencyCode().equals(selectedTradeCurrencyProperty.get().getCode())
|
||||
&& e.getDirection().equals(direction))
|
||||
.collect(Collectors.toList());
|
||||
BigInteger sum = BigInteger.ZERO;
|
||||
for (Offer offer : offerList) sum = sum.add(offer.getAmount());
|
||||
return HavenoUtils.atomicUnitsToXmr(sum);
|
||||
}
|
||||
}
|
||||
|
||||
public Volume getTotalVolume(OfferDirection direction) {
|
||||
synchronized (offerBookListItems) {
|
||||
List<Volume> volumes = offerBookListItems.stream()
|
||||
.map(OfferBookListItem::getOffer)
|
||||
.filter(e -> e.getCurrencyCode().equals(selectedTradeCurrencyProperty.get().getCode())
|
||||
&& e.getDirection().equals(direction))
|
||||
.map(Offer::getVolume)
|
||||
.collect(Collectors.toList());
|
||||
try {
|
||||
return VolumeUtil.sum(volumes);
|
||||
} catch (Exception e) {
|
||||
// log.error("Cannot compute total volume because prices are unavailable, currency={}, direction={}",
|
||||
// selectedTradeCurrencyProperty.get().getCode(), direction);
|
||||
return null; // expected before prices are available
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isCrypto() {
|
||||
return CurrencyUtil.isCryptoCurrency(getCurrencyCode());
|
||||
}
|
||||
|
||||
public boolean isMyOffer(Offer offer) {
|
||||
|
|
|
@ -65,6 +65,8 @@ public class SpreadView extends ActivatableViewAndModel<GridPane, SpreadViewMode
|
|||
@Override
|
||||
public void initialize() {
|
||||
tableView = new TableView<>();
|
||||
GUIUtil.applyTableStyle(tableView);
|
||||
tableView.getStyleClass().add("non-interactive-table");
|
||||
|
||||
int gridRow = 0;
|
||||
GridPane.setRowIndex(tableView, gridRow);
|
||||
|
@ -144,7 +146,7 @@ public class SpreadView extends ActivatableViewAndModel<GridPane, SpreadViewMode
|
|||
setMinWidth(160);
|
||||
}
|
||||
};
|
||||
column.getStyleClass().addAll("number-column", "first-column");
|
||||
column.getStyleClass().addAll("number-column");
|
||||
column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
|
||||
column.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
@ -259,7 +261,7 @@ public class SpreadView extends ActivatableViewAndModel<GridPane, SpreadViewMode
|
|||
setMinWidth(140);
|
||||
}
|
||||
};
|
||||
column.getStyleClass().add("number-column");
|
||||
column.getStyleClass().addAll("number-column", "highlight-text");
|
||||
column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
|
||||
column.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
@ -289,7 +291,7 @@ public class SpreadView extends ActivatableViewAndModel<GridPane, SpreadViewMode
|
|||
setMinWidth(110);
|
||||
}
|
||||
};
|
||||
column.getStyleClass().addAll("number-column", "last-column");
|
||||
column.getStyleClass().addAll("number-column", "highlight-text");
|
||||
column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
|
||||
column.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
|
|
@ -686,6 +686,7 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
|||
currencyComboBox = currencyComboBoxTuple.third;
|
||||
currencyComboBox.setCellFactory(GUIUtil.getCurrencyListItemCellFactory(Res.get("shared.trade"),
|
||||
Res.get("shared.trades"), model.preferences));
|
||||
currencyComboBox.getStyleClass().add("input-with-border");
|
||||
|
||||
Pane spacer = new Pane();
|
||||
HBox.setHgrow(spacer, Priority.ALWAYS);
|
||||
|
@ -730,7 +731,9 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
|||
|
||||
private void createTable() {
|
||||
tableView = new TableView<>();
|
||||
GUIUtil.applyTableStyle(tableView);
|
||||
VBox.setVgrow(tableView, Priority.ALWAYS);
|
||||
tableView.getStyleClass().add("non-interactive-table");
|
||||
|
||||
// date
|
||||
TableColumn<TradeStatistics3ListItem, TradeStatistics3ListItem> dateColumn = new AutoTooltipTableColumn<>(Res.get("shared.dateTime")) {
|
||||
|
@ -739,7 +742,7 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
|||
setMaxWidth(240);
|
||||
}
|
||||
};
|
||||
dateColumn.getStyleClass().addAll("number-column", "first-column");
|
||||
dateColumn.getStyleClass().addAll("number-column");
|
||||
dateColumn.setCellValueFactory((tradeStatistics) -> new ReadOnlyObjectWrapper<>(tradeStatistics.getValue()));
|
||||
dateColumn.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
@ -865,7 +868,7 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
|||
|
||||
// paymentMethod
|
||||
TableColumn<TradeStatistics3ListItem, TradeStatistics3ListItem> paymentMethodColumn = new AutoTooltipTableColumn<>(Res.get("shared.paymentMethod"));
|
||||
paymentMethodColumn.getStyleClass().add("number-column");
|
||||
paymentMethodColumn.getStyleClass().addAll("number-column");
|
||||
paymentMethodColumn.setCellValueFactory((tradeStatistics) -> new ReadOnlyObjectWrapper<>(tradeStatistics.getValue()));
|
||||
paymentMethodColumn.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
|
|
@ -85,6 +85,7 @@ import javafx.scene.layout.AnchorPane;
|
|||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.util.StringConverter;
|
||||
|
@ -149,7 +150,8 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
|
|||
private ComboBox<PaymentAccount> paymentAccountsComboBox;
|
||||
private ComboBox<TradeCurrency> currencyComboBox;
|
||||
private ImageView qrCodeImageView;
|
||||
private VBox currencySelection, fixedPriceBox, percentagePriceBox, currencyTextFieldBox, triggerPriceVBox;
|
||||
private StackPane qrCodePane;
|
||||
private VBox paymentAccountsSelection, currencySelection, fixedPriceBox, percentagePriceBox, currencyTextFieldBox, triggerPriceVBox;
|
||||
private HBox fundingHBox, firstRowHBox, secondRowHBox, placeOfferBox, amountValueCurrencyBox,
|
||||
priceAsPercentageValueCurrencyBox, volumeValueCurrencyBox, priceValueCurrencyBox,
|
||||
minAmountValueCurrencyBox, securityDepositAndFeeBox, triggerPriceHBox;
|
||||
|
@ -308,7 +310,7 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
|
|||
if (!result) {
|
||||
new Popup().headLine(Res.get("popup.warning.noTradingAccountSetup.headline"))
|
||||
.instruction(Res.get("popup.warning.noTradingAccountSetup.msg"))
|
||||
.actionButtonTextWithGoTo("navigation.account")
|
||||
.actionButtonTextWithGoTo("mainView.menu.account")
|
||||
.onAction(() -> {
|
||||
navigation.setReturnPath(navigation.getCurrentPath());
|
||||
navigation.navigateTo(MainView.class, AccountView.class, TraditionalAccountsView.class);
|
||||
|
@ -425,7 +427,8 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
|
|||
totalToPayTextField.setContentForInfoPopOver(createInfoPopover());
|
||||
});
|
||||
|
||||
paymentAccountsComboBox.setDisable(true);
|
||||
paymentAccountsSelection.setDisable(true);
|
||||
currencySelection.setDisable(true);
|
||||
|
||||
editOfferElements.forEach(node -> {
|
||||
node.setMouseTransparent(true);
|
||||
|
@ -449,8 +452,8 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
|
|||
private void updateOfferElementsStyle() {
|
||||
GridPane.setColumnSpan(firstRowHBox, 2);
|
||||
|
||||
String activeInputStyle = "input-with-border";
|
||||
String readOnlyInputStyle = "input-with-border-readonly";
|
||||
String activeInputStyle = "offer-input";
|
||||
String readOnlyInputStyle = "offer-input-readonly";
|
||||
amountValueCurrencyBox.getStyleClass().remove(activeInputStyle);
|
||||
amountValueCurrencyBox.getStyleClass().add(readOnlyInputStyle);
|
||||
priceAsPercentageValueCurrencyBox.getStyleClass().remove(activeInputStyle);
|
||||
|
@ -709,7 +712,11 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
|
|||
};
|
||||
extraInfoFocusedListener = (observable, oldValue, newValue) -> {
|
||||
model.onFocusOutExtraInfoTextArea(oldValue, newValue);
|
||||
extraInfoTextArea.setText(model.extraInfo.get());
|
||||
|
||||
// avoid setting text area to empty text because blinking caret does not appear
|
||||
if (model.extraInfo.get() != null && !model.extraInfo.get().isEmpty()) {
|
||||
extraInfoTextArea.setText(model.extraInfo.get());
|
||||
}
|
||||
};
|
||||
|
||||
errorMessageListener = (o, oldValue, newValue) -> {
|
||||
|
@ -749,7 +756,7 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
|
|||
UserThread.runAfter(() -> new Popup().headLine(Res.get("createOffer.success.headline"))
|
||||
.feedback(Res.get("createOffer.success.info"))
|
||||
.dontShowAgainId(key)
|
||||
.actionButtonTextWithGoTo("navigation.portfolio.myOpenOffers")
|
||||
.actionButtonTextWithGoTo("portfolio.tab.openOffers")
|
||||
.onAction(this::closeAndGoToOpenOffers)
|
||||
.onClose(this::closeAndGoToOpenOffers)
|
||||
.show(),
|
||||
|
@ -973,7 +980,7 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
|
|||
private void addGridPane() {
|
||||
gridPane = new GridPane();
|
||||
gridPane.getStyleClass().add("content-pane");
|
||||
gridPane.setPadding(new Insets(25, 25, -1, 25));
|
||||
gridPane.setPadding(new Insets(25, 25, 25, 25));
|
||||
gridPane.setHgap(5);
|
||||
gridPane.setVgap(5);
|
||||
GUIUtil.setDefaultTwoColumnConstraintsForGridPane(gridPane);
|
||||
|
@ -995,8 +1002,9 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
|
|||
final Tuple3<VBox, Label, ComboBox<TradeCurrency>> currencyBoxTuple = addTopLabelComboBox(
|
||||
Res.get("shared.currency"), Res.get("list.currency.select"));
|
||||
|
||||
paymentAccountsSelection = tradingAccountBoxTuple.first;
|
||||
currencySelection = currencyBoxTuple.first;
|
||||
paymentGroupBox.getChildren().addAll(tradingAccountBoxTuple.first, currencySelection);
|
||||
paymentGroupBox.getChildren().addAll(paymentAccountsSelection, currencySelection);
|
||||
|
||||
GridPane.setRowIndex(paymentGroupBox, gridRow);
|
||||
GridPane.setColumnSpan(paymentGroupBox, 2);
|
||||
|
@ -1007,11 +1015,13 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
|
|||
paymentAccountsComboBox = tradingAccountBoxTuple.third;
|
||||
paymentAccountsComboBox.setMinWidth(tradingAccountBoxTuple.first.getMinWidth());
|
||||
paymentAccountsComboBox.setPrefWidth(tradingAccountBoxTuple.first.getMinWidth());
|
||||
editOfferElements.add(tradingAccountBoxTuple.first);
|
||||
paymentAccountsComboBox.getStyleClass().add("input-with-border");
|
||||
editOfferElements.add(paymentAccountsSelection);
|
||||
|
||||
// we display either currencyComboBox (multi currency account) or currencyTextField (single)
|
||||
currencyComboBox = currencyBoxTuple.third;
|
||||
currencyComboBox.setMaxWidth(tradingAccountBoxTuple.first.getMinWidth() / 2);
|
||||
currencyComboBox.getStyleClass().add("input-with-border");
|
||||
editOfferElements.add(currencySelection);
|
||||
currencyComboBox.setConverter(new StringConverter<>() {
|
||||
@Override
|
||||
|
@ -1094,6 +1104,7 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
|
|||
GridPane.setColumnSpan(extraInfoTitledGroupBg, 3);
|
||||
|
||||
extraInfoTextArea = new InputTextArea();
|
||||
extraInfoTextArea.setText("");
|
||||
extraInfoTextArea.setPromptText(Res.get("payment.shared.extraInfo.prompt.offer"));
|
||||
extraInfoTextArea.getStyleClass().add("text-area");
|
||||
extraInfoTextArea.setWrapText(true);
|
||||
|
@ -1179,8 +1190,8 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
|
|||
totalToPayTextField.setManaged(false);
|
||||
addressTextField.setVisible(false);
|
||||
addressTextField.setManaged(false);
|
||||
qrCodeImageView.setVisible(false);
|
||||
qrCodeImageView.setManaged(false);
|
||||
qrCodePane.setVisible(false);
|
||||
qrCodePane.setManaged(false);
|
||||
balanceTextField.setVisible(false);
|
||||
balanceTextField.setManaged(false);
|
||||
cancelButton2.setVisible(false);
|
||||
|
@ -1196,8 +1207,8 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
|
|||
totalToPayTextField.setManaged(true);
|
||||
addressTextField.setVisible(true);
|
||||
addressTextField.setManaged(true);
|
||||
qrCodeImageView.setVisible(true);
|
||||
qrCodeImageView.setManaged(true);
|
||||
qrCodePane.setVisible(true);
|
||||
qrCodePane.setManaged(true);
|
||||
balanceTextField.setVisible(true);
|
||||
balanceTextField.setManaged(true);
|
||||
cancelButton2.setVisible(true);
|
||||
|
@ -1239,21 +1250,23 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
|
|||
totalToPayTextField.setVisible(false);
|
||||
GridPane.setMargin(totalToPayTextField, new Insets(60 + heightAdjustment, 10, 0, 0));
|
||||
|
||||
qrCodeImageView = new ImageView();
|
||||
qrCodeImageView.setVisible(false);
|
||||
qrCodeImageView.setFitHeight(150);
|
||||
qrCodeImageView.setFitWidth(150);
|
||||
qrCodeImageView.getStyleClass().add("qr-code");
|
||||
Tooltip.install(qrCodeImageView, new Tooltip(Res.get("shared.openLargeQRWindow")));
|
||||
qrCodeImageView.setOnMouseClicked(e -> UserThread.runAfter(
|
||||
Tuple2<StackPane, ImageView> qrCodeTuple = GUIUtil.getSmallXmrQrCodePane();
|
||||
qrCodePane = qrCodeTuple.first;
|
||||
qrCodeImageView = qrCodeTuple.second;
|
||||
|
||||
Tooltip.install(qrCodePane, new Tooltip(Res.get("shared.openLargeQRWindow")));
|
||||
qrCodePane.setOnMouseClicked(e -> UserThread.runAfter(
|
||||
() -> new QRCodeWindow(getMoneroURI()).show(),
|
||||
200, TimeUnit.MILLISECONDS));
|
||||
GridPane.setRowIndex(qrCodeImageView, gridRow);
|
||||
GridPane.setColumnIndex(qrCodeImageView, 1);
|
||||
GridPane.setRowSpan(qrCodeImageView, 3);
|
||||
GridPane.setValignment(qrCodeImageView, VPos.BOTTOM);
|
||||
GridPane.setMargin(qrCodeImageView, new Insets(Layout.FIRST_ROW_DISTANCE - 9, 0, 0, 10));
|
||||
gridPane.getChildren().add(qrCodeImageView);
|
||||
GridPane.setRowIndex(qrCodePane, gridRow);
|
||||
GridPane.setColumnIndex(qrCodePane, 1);
|
||||
GridPane.setRowSpan(qrCodePane, 3);
|
||||
GridPane.setValignment(qrCodePane, VPos.BOTTOM);
|
||||
GridPane.setMargin(qrCodePane, new Insets(Layout.FIRST_ROW_DISTANCE - 9, 0, 0, 10));
|
||||
gridPane.getChildren().add(qrCodePane);
|
||||
|
||||
qrCodePane.setVisible(false);
|
||||
qrCodePane.setManaged(false);
|
||||
|
||||
addressTextField = addAddressTextField(gridPane, ++gridRow,
|
||||
Res.get("shared.tradeWalletAddress"));
|
||||
|
|
|
@ -504,7 +504,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
|||
|
||||
extraInfoStringListener = (ov, oldValue, newValue) -> {
|
||||
if (newValue != null) {
|
||||
extraInfo.set(newValue);
|
||||
extraInfo.set(newValue.trim());
|
||||
UserThread.execute(() -> onExtraInfoTextAreaChanged());
|
||||
}
|
||||
};
|
||||
|
@ -727,7 +727,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
|||
new Popup().warning(Res.get("shared.notEnoughFunds",
|
||||
HavenoUtils.formatXmr(dataModel.totalToPayAsProperty().get(), true),
|
||||
HavenoUtils.formatXmr(dataModel.getTotalBalance(), true)))
|
||||
.actionButtonTextWithGoTo("navigation.funds.depositFunds")
|
||||
.actionButtonTextWithGoTo("funds.tab.deposit")
|
||||
.onAction(() -> navigation.navigateTo(MainView.class, FundsView.class, DepositView.class))
|
||||
.show();
|
||||
}
|
||||
|
@ -1056,7 +1056,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
|||
FormattingUtils.formatToPercentWithSymbol(preferences.getMaxPriceDistanceInPercent())))
|
||||
.actionButtonText(Res.get("createOffer.changePrice"))
|
||||
.onAction(popup::hide)
|
||||
.closeButtonTextWithGoTo("navigation.settings.preferences")
|
||||
.closeButtonTextWithGoTo("settings.tab.preferences")
|
||||
.onClose(() -> navigation.navigateTo(MainView.class, SettingsView.class, PreferencesView.class))
|
||||
.show();
|
||||
}
|
||||
|
|
|
@ -220,14 +220,14 @@ public abstract class OfferView extends ActivatableView<TabPane, Void> {
|
|||
labelTab.setClosable(false);
|
||||
Label offerLabel = new Label(getOfferLabel()); // use overlay for label for custom formatting
|
||||
offerLabel.getStyleClass().add("titled-group-bg-label");
|
||||
offerLabel.setStyle("-fx-font-size: 1.4em;");
|
||||
offerLabel.setStyle("-fx-font-size: 1.3em;");
|
||||
labelTab.setGraphic(offerLabel);
|
||||
|
||||
fiatOfferBookTab = new Tab(Res.get("shared.fiat").toUpperCase());
|
||||
fiatOfferBookTab = new Tab(Res.get("shared.fiat"));
|
||||
fiatOfferBookTab.setClosable(false);
|
||||
cryptoOfferBookTab = new Tab(Res.get("shared.crypto").toUpperCase());
|
||||
cryptoOfferBookTab = new Tab(Res.get("shared.crypto"));
|
||||
cryptoOfferBookTab.setClosable(false);
|
||||
otherOfferBookTab = new Tab(Res.get("shared.other").toUpperCase());
|
||||
otherOfferBookTab = new Tab(Res.get("shared.other"));
|
||||
otherOfferBookTab.setClosable(false);
|
||||
tabPane.getTabs().addAll(labelTab, fiatOfferBookTab, cryptoOfferBookTab, otherOfferBookTab);
|
||||
}
|
||||
|
|
|
@ -91,7 +91,6 @@ import javafx.scene.layout.GridPane;
|
|||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.text.TextAlignment;
|
||||
import javafx.util.Callback;
|
||||
|
@ -179,29 +178,29 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
|
|||
currencyComboBoxContainer = currencyBoxTuple.first;
|
||||
currencyComboBox = currencyBoxTuple.third;
|
||||
currencyComboBox.setPrefWidth(250);
|
||||
currencyComboBox.getStyleClass().add("input-with-border");
|
||||
|
||||
Tuple3<VBox, Label, AutocompleteComboBox<PaymentMethod>> paymentBoxTuple = FormBuilder.addTopLabelAutocompleteComboBox(
|
||||
Res.get("offerbook.filterByPaymentMethod"));
|
||||
paymentMethodComboBox = paymentBoxTuple.third;
|
||||
paymentMethodComboBox.setCellFactory(GUIUtil.getPaymentMethodCellFactory());
|
||||
paymentMethodComboBox.setPrefWidth(250);
|
||||
|
||||
matchingOffersToggleButton = AwesomeDude.createIconToggleButton(AwesomeIcon.USER, null, "1.5em", null);
|
||||
matchingOffersToggleButton.getStyleClass().add("toggle-button-no-slider");
|
||||
matchingOffersToggleButton.setPrefHeight(27);
|
||||
Tooltip matchingOffersTooltip = new Tooltip(Res.get("offerbook.matchingOffers"));
|
||||
Tooltip.install(matchingOffersToggleButton, matchingOffersTooltip);
|
||||
paymentMethodComboBox.getStyleClass().add("input-with-border");
|
||||
|
||||
noDepositOffersToggleButton = new ToggleButton(Res.get("offerbook.filterNoDeposit"));
|
||||
noDepositOffersToggleButton.getStyleClass().add("toggle-button-no-slider");
|
||||
noDepositOffersToggleButton.setPrefHeight(27);
|
||||
Tooltip noDepositOffersTooltip = new Tooltip(Res.get("offerbook.noDepositOffers"));
|
||||
Tooltip.install(noDepositOffersToggleButton, noDepositOffersTooltip);
|
||||
|
||||
matchingOffersToggleButton = AwesomeDude.createIconToggleButton(AwesomeIcon.USER, null, "1.5em", null);
|
||||
matchingOffersToggleButton.getStyleClass().add("toggle-button-no-slider");
|
||||
Tooltip matchingOffersTooltip = new Tooltip(Res.get("offerbook.matchingOffers"));
|
||||
Tooltip.install(matchingOffersToggleButton, matchingOffersTooltip);
|
||||
|
||||
createOfferButton = new AutoTooltipButton("");
|
||||
createOfferButton.setMinHeight(40);
|
||||
createOfferButton.setGraphicTextGap(10);
|
||||
createOfferButton.setStyle("-fx-padding: 0 15 0 15;");
|
||||
createOfferButton.setStyle("-fx-padding: 7 25 7 25;");
|
||||
disabledCreateOfferButtonTooltip = new Label("");
|
||||
disabledCreateOfferButtonTooltip.setMinSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
|
||||
disabledCreateOfferButtonTooltip.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
|
||||
|
@ -211,15 +210,17 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
|
|||
disabledCreateOfferButtonTooltip.setManaged(false);
|
||||
disabledCreateOfferButtonTooltip.setVisible(false);
|
||||
|
||||
var createOfferButtonStack = new StackPane(createOfferButton, disabledCreateOfferButtonTooltip);
|
||||
var createOfferVBox = new VBox(createOfferButton, disabledCreateOfferButtonTooltip);
|
||||
createOfferVBox.setAlignment(Pos.BOTTOM_RIGHT);
|
||||
|
||||
Tuple3<VBox, Label, AutoTooltipTextField> autoToolTipTextField = addTopLabelAutoToolTipTextField("");
|
||||
VBox filterBox = autoToolTipTextField.first;
|
||||
filterInputField = autoToolTipTextField.third;
|
||||
filterInputField.setPromptText(Res.get("market.offerBook.filterPrompt"));
|
||||
filterInputField.setPromptText(Res.get("shared.filter"));
|
||||
filterInputField.getStyleClass().add("input-with-border");
|
||||
|
||||
offerToolsBox.getChildren().addAll(currencyBoxTuple.first, paymentBoxTuple.first,
|
||||
filterBox, matchingOffersToggleButton, noDepositOffersToggleButton, getSpacer(), createOfferButtonStack);
|
||||
filterBox, noDepositOffersToggleButton, matchingOffersToggleButton, getSpacer(), createOfferVBox);
|
||||
|
||||
GridPane.setHgrow(offerToolsBox, Priority.ALWAYS);
|
||||
GridPane.setRowIndex(offerToolsBox, gridRow);
|
||||
|
@ -228,6 +229,7 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
|
|||
root.getChildren().add(offerToolsBox);
|
||||
|
||||
tableView = new TableView<>();
|
||||
GUIUtil.applyTableStyle(tableView);
|
||||
|
||||
GridPane.setRowIndex(tableView, ++gridRow);
|
||||
GridPane.setColumnIndex(tableView, 0);
|
||||
|
@ -405,14 +407,12 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
|
|||
if (showAll) {
|
||||
volumeColumn.setTitleWithHelpText(Res.get("shared.amountMinMax"), Res.get("shared.amountHelp"));
|
||||
priceColumn.setTitle(Res.get("shared.price"));
|
||||
priceColumn.getStyleClass().remove("first-column");
|
||||
|
||||
if (!tableView.getColumns().contains(marketColumn))
|
||||
tableView.getColumns().add(0, marketColumn);
|
||||
} else {
|
||||
volumeColumn.setTitleWithHelpText(Res.get("offerbook.volume", code), Res.get("shared.amountHelp"));
|
||||
priceColumn.setTitle(CurrencyUtil.getPriceWithCurrencyCode(code));
|
||||
priceColumn.getStyleClass().add("first-column");
|
||||
|
||||
tableView.getColumns().remove(marketColumn);
|
||||
}
|
||||
|
@ -585,9 +585,8 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
|
|||
|
||||
public void setDirection(OfferDirection direction) {
|
||||
model.initWithDirection(direction);
|
||||
ImageView iconView = new ImageView();
|
||||
createOfferButton.setGraphic(iconView);
|
||||
iconView.setId(direction == OfferDirection.SELL ? "image-sell-white" : "image-buy-white");
|
||||
createOfferButton.setGraphic(GUIUtil.getCurrencyIconWithBorder(Res.getBaseCurrencyCode()));
|
||||
createOfferButton.setContentDisplay(ContentDisplay.RIGHT);
|
||||
createOfferButton.setId(direction == OfferDirection.SELL ? "sell-button-big" : "buy-button-big");
|
||||
avatarColumn.setTitle(direction == OfferDirection.SELL ? Res.get("shared.buyerUpperCase") : Res.get("shared.sellerUpperCase"));
|
||||
if (direction == OfferDirection.SELL) {
|
||||
|
@ -750,8 +749,8 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
|
|||
() -> {
|
||||
log.debug(Res.get("offerbook.removeOffer.success"));
|
||||
if (DontShowAgainLookup.showAgain(key))
|
||||
new Popup().instruction(Res.get("offerbook.withdrawFundsHint", Res.get("navigation.funds.availableForWithdrawal")))
|
||||
.actionButtonTextWithGoTo("navigation.funds.availableForWithdrawal")
|
||||
new Popup().instruction(Res.get("offerbook.withdrawFundsHint", Res.get("funds.tab.withdrawal")))
|
||||
.actionButtonTextWithGoTo("funds.tab.withdrawal")
|
||||
.onAction(() -> navigation.navigateTo(MainView.class, FundsView.class, WithdrawalView.class))
|
||||
.dontShowAgainId(key)
|
||||
.show();
|
||||
|
@ -769,7 +768,7 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
|
|||
|
||||
new Popup().headLine(headline)
|
||||
.instruction(Res.get("offerbook.warning.noMatchingAccount.msg"))
|
||||
.actionButtonTextWithGoTo("navigation.account")
|
||||
.actionButtonTextWithGoTo("mainView.menu.account")
|
||||
.onAction(() -> {
|
||||
navigation.setReturnPath(navigation.getCurrentPath());
|
||||
navigation.navigateTo(MainView.class, AccountView.class, accountViewClass);
|
||||
|
@ -812,7 +811,7 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
|
|||
setMinWidth(40);
|
||||
}
|
||||
};
|
||||
column.getStyleClass().addAll("number-column", "first-column");
|
||||
column.getStyleClass().addAll("number-column");
|
||||
column.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
|
||||
column.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
@ -1065,7 +1064,6 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
|
|||
setSortable(false);
|
||||
}
|
||||
};
|
||||
column.getStyleClass().addAll("last-column", "avatar-column");
|
||||
column.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
|
||||
column.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
@ -1116,7 +1114,12 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
|
|||
// https://github.com/bisq-network/bisq/issues/4986
|
||||
if (tableRow != null) {
|
||||
canTakeOfferResult = model.offerFilterService.canTakeOffer(offer, false);
|
||||
tableRow.setOpacity(canTakeOfferResult.isValid() || myOffer ? 1 : 0.4);
|
||||
if (canTakeOfferResult.isValid() || myOffer) {
|
||||
tableRow.getStyleClass().remove("row-faded");
|
||||
} else {
|
||||
if (!tableRow.getStyleClass().contains("row-faded")) tableRow.getStyleClass().add("row-faded");
|
||||
hbox.getStyleClass().add("cell-faded");
|
||||
}
|
||||
|
||||
if (myOffer) {
|
||||
button.setDefaultButton(false);
|
||||
|
@ -1149,12 +1152,16 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
|
|||
} else {
|
||||
boolean isSellOffer = OfferViewUtil.isShownAsSellOffer(offer);
|
||||
boolean isPrivateOffer = offer.isPrivateOffer();
|
||||
iconView.setId(isPrivateOffer ? "image-lock2x" : isSellOffer ? "image-buy-white" : "image-sell-white");
|
||||
iconView.setFitHeight(16);
|
||||
iconView.setFitWidth(16);
|
||||
if (isPrivateOffer) {
|
||||
button.setGraphic(GUIUtil.getLockLabel());
|
||||
} else {
|
||||
iconView.setId(isSellOffer ? "image-buy-white" : "image-sell-white");
|
||||
iconView.setFitHeight(16);
|
||||
iconView.setFitWidth(16);
|
||||
}
|
||||
button.setId(isSellOffer ? "buy-button" : "sell-button");
|
||||
button.setStyle("-fx-text-fill: white");
|
||||
title = Res.get("offerbook.takeOffer");
|
||||
title = Res.get(isSellOffer ? "mainView.menu.buyXmr" : "mainView.menu.sellXmr");
|
||||
button.setTooltip(new Tooltip(Res.get("offerbook.takeOfferButton.tooltip", model.getDirectionLabelTooltip(offer))));
|
||||
button.setOnAction(e -> onTakeOffer(offer));
|
||||
button2.setManaged(false);
|
||||
|
@ -1179,8 +1186,8 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
|
|||
button.setOnAction(null);
|
||||
button2.setOnAction(null);
|
||||
if (tableRow != null) {
|
||||
tableRow.setOpacity(1);
|
||||
tableRow.setOnMousePressed(null);
|
||||
tableRow.getStyleClass().remove("row-faded");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1236,7 +1243,7 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
|
|||
setSortable(true);
|
||||
}
|
||||
};
|
||||
column.getStyleClass().addAll("last-column", "avatar-column");
|
||||
column.getStyleClass().addAll("avatar-column");
|
||||
column.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
|
||||
column.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
@ -1280,8 +1287,8 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
|
|||
|
||||
private void updateCreateOfferButton() {
|
||||
createOfferButton.setText(Res.get("offerbook.createNewOffer",
|
||||
model.getDirection() == OfferDirection.BUY ? Res.get("shared.buy") : Res.get("shared.sell"),
|
||||
getTradeCurrencyCode()).toUpperCase());
|
||||
model.getDirection() == OfferDirection.BUY ? Res.get("shared.buy").toUpperCase() : Res.get("shared.sell").toUpperCase(),
|
||||
getTradeCurrencyCode()));
|
||||
}
|
||||
|
||||
abstract String getTradeCurrencyCode();
|
||||
|
|
|
@ -40,7 +40,6 @@ import javafx.beans.property.ReadOnlyObjectWrapper;
|
|||
import javafx.collections.transformation.FilteredList;
|
||||
import javafx.collections.transformation.SortedList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.ContextMenu;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.MenuItem;
|
||||
|
@ -98,10 +97,6 @@ public class SignedOfferView extends ActivatableViewAndModel<VBox, SignedOffersV
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
Label label = new AutoTooltipLabel(Res.get("support.filter"));
|
||||
HBox.setMargin(label, new Insets(5, 0, 0, 0));
|
||||
HBox.setHgrow(label, Priority.NEVER);
|
||||
|
||||
filterTextField = new InputTextField();
|
||||
Tooltip tooltip = new Tooltip();
|
||||
tooltip.setShowDelay(Duration.millis(100));
|
||||
|
@ -120,6 +115,7 @@ public class SignedOfferView extends ActivatableViewAndModel<VBox, SignedOffersV
|
|||
sortedList.comparatorProperty().bind(tableView.comparatorProperty());
|
||||
tableView.setItems(sortedList);
|
||||
filterBox.initialize(filteredList, tableView);
|
||||
filterBox.setPromptText(Res.get("shared.filter"));
|
||||
filterBox.activate();
|
||||
|
||||
contextMenu = new ContextMenu();
|
||||
|
|
|
@ -108,6 +108,7 @@ import javafx.scene.layout.AnchorPane;
|
|||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.text.Text;
|
||||
import net.glxn.qrgen.QRCode;
|
||||
|
@ -127,13 +128,13 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
private GridPane gridPane;
|
||||
private TitledGroupBg noFundingRequiredTitledGroupBg;
|
||||
private Label noFundingRequiredLabel;
|
||||
private int lastGridRowNoFundingRequired;
|
||||
private int gridRowNoFundingRequired;
|
||||
private TitledGroupBg payFundsTitledGroupBg;
|
||||
private TitledGroupBg advancedOptionsGroup;
|
||||
private VBox priceAsPercentageInputBox, amountRangeBox;
|
||||
private HBox fundingHBox, amountValueCurrencyBox, priceValueCurrencyBox, volumeValueCurrencyBox,
|
||||
priceAsPercentageValueCurrencyBox, minAmountValueCurrencyBox, advancedOptionsBox,
|
||||
takeOfferBox, buttonBox, firstRowHBox;
|
||||
takeOfferBox, nextButtonBox, firstRowHBox;
|
||||
private ComboBox<PaymentAccount> paymentAccountsComboBox;
|
||||
private TextArea extraInfoTextArea;
|
||||
private Label amountDescriptionLabel,
|
||||
|
@ -142,7 +143,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
volumeCurrencyLabel, priceDescriptionLabel, volumeDescriptionLabel,
|
||||
waitingForFundsLabel, offerAvailabilityLabel, priceAsPercentageDescription,
|
||||
tradeFeeDescriptionLabel, resultLabel, tradeFeeInXmrLabel, xLabel,
|
||||
fakeXLabel;
|
||||
fakeXLabel, extraInfoLabel;
|
||||
private InputTextField amountTextField;
|
||||
private TextField paymentMethodTextField, currencyTextField, priceTextField, priceAsPercentageTextField,
|
||||
volumeTextField, amountRangeTextField;
|
||||
|
@ -153,6 +154,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
private Button nextButton, cancelButton1, cancelButton2;
|
||||
private AutoTooltipButton takeOfferButton, fundFromSavingsWalletButton;
|
||||
private ImageView qrCodeImageView;
|
||||
private StackPane qrCodePane;
|
||||
private BusyAnimation waitingForFundsBusyAnimation, offerAvailabilityBusyAnimation;
|
||||
private Notification walletFundedNotification;
|
||||
private OfferView.CloseHandler closeHandler;
|
||||
|
@ -200,7 +202,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
|
||||
createListeners();
|
||||
|
||||
addButtons();
|
||||
addNextButtons();
|
||||
addOfferAvailabilityLabel();
|
||||
addFundingGroup();
|
||||
|
||||
|
@ -339,8 +341,10 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
if (model.isRange()) {
|
||||
amountRangeTextField.setText(model.getAmountRange());
|
||||
amountRangeBox.setVisible(true);
|
||||
amountRangeBox.setManaged(true);
|
||||
} else {
|
||||
amountTextField.setDisable(true);
|
||||
amountTextField.setManaged(true);
|
||||
}
|
||||
|
||||
priceTextField.setText(model.getPrice());
|
||||
|
@ -361,20 +365,26 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
if (offer.hasBuyerAsTakerWithoutDeposit() && offer.getCombinedExtraInfo() != null && !offer.getCombinedExtraInfo().isEmpty()) {
|
||||
|
||||
// attach extra info text area
|
||||
extraInfoTextArea = addCompactTopLabelTextArea(gridPane, ++lastGridRowNoFundingRequired, Res.get("payment.shared.extraInfo.noDeposit"), "").second;
|
||||
extraInfoTextArea.setText(offer.getCombinedExtraInfo());
|
||||
extraInfoTextArea.getStyleClass().add("text-area");
|
||||
//updateOfferElementsStyle();
|
||||
Tuple2<Label, TextArea> extraInfoTuple = addCompactTopLabelTextArea(gridPane, ++gridRowNoFundingRequired, Res.get("payment.shared.extraInfo.noDeposit"), "");
|
||||
extraInfoLabel = extraInfoTuple.first;
|
||||
extraInfoLabel.setVisible(false);
|
||||
extraInfoLabel.setManaged(false);
|
||||
extraInfoTextArea = extraInfoTuple.second;
|
||||
extraInfoTextArea.setVisible(false);
|
||||
extraInfoTextArea.setManaged(false);
|
||||
extraInfoTextArea.setText(offer.getCombinedExtraInfo().trim());
|
||||
extraInfoTextArea.getStyleClass().addAll("text-area", "flat-text-area-with-border");
|
||||
extraInfoTextArea.setWrapText(true);
|
||||
extraInfoTextArea.setPrefHeight(75);
|
||||
extraInfoTextArea.setMinHeight(75);
|
||||
extraInfoTextArea.setMaxHeight(150);
|
||||
extraInfoTextArea.setMaxHeight(300);
|
||||
extraInfoTextArea.setEditable(false);
|
||||
GridPane.setRowIndex(extraInfoTextArea, lastGridRowNoFundingRequired);
|
||||
GUIUtil.adjustHeightAutomatically(extraInfoTextArea);
|
||||
GridPane.setRowIndex(extraInfoTextArea, gridRowNoFundingRequired);
|
||||
GridPane.setColumnSpan(extraInfoTextArea, GridPane.REMAINING);
|
||||
GridPane.setColumnIndex(extraInfoTextArea, 0);
|
||||
|
||||
// move up take offer buttons
|
||||
GridPane.setRowIndex(takeOfferBox, lastGridRowNoFundingRequired + 1);
|
||||
GridPane.setRowIndex(takeOfferBox, gridRowNoFundingRequired + 1);
|
||||
GridPane.setMargin(takeOfferBox, new Insets(15, 0, 0, 0));
|
||||
}
|
||||
}
|
||||
|
@ -490,19 +500,33 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
}
|
||||
|
||||
cancelButton2.setVisible(true);
|
||||
cancelButton2.setManaged(true);
|
||||
|
||||
// temporarily disabled due to high CPU usage (per issue #4649)
|
||||
//waitingForFundsBusyAnimation.play();
|
||||
|
||||
if (model.getOffer().hasBuyerAsTakerWithoutDeposit()) {
|
||||
noFundingRequiredTitledGroupBg.setVisible(true);
|
||||
noFundingRequiredTitledGroupBg.setManaged(true);
|
||||
noFundingRequiredLabel.setVisible(true);
|
||||
noFundingRequiredLabel.setManaged(true);
|
||||
if (model.getOffer().getCombinedExtraInfo() != null && !model.getOffer().getCombinedExtraInfo().isEmpty()) {
|
||||
extraInfoLabel.setVisible(true);
|
||||
extraInfoLabel.setManaged(true);
|
||||
extraInfoTextArea.setVisible(true);
|
||||
extraInfoTextArea.setManaged(true);
|
||||
}
|
||||
} else {
|
||||
payFundsTitledGroupBg.setVisible(true);
|
||||
payFundsTitledGroupBg.setManaged(true);
|
||||
totalToPayTextField.setVisible(true);
|
||||
totalToPayTextField.setManaged(true);
|
||||
addressTextField.setVisible(true);
|
||||
qrCodeImageView.setVisible(true);
|
||||
addressTextField.setManaged(true);
|
||||
qrCodePane.setVisible(true);
|
||||
qrCodePane.setManaged(true);
|
||||
balanceTextField.setVisible(true);
|
||||
balanceTextField.setManaged(true);
|
||||
}
|
||||
|
||||
totalToPayTextField.setFundsStructure(Res.get("takeOffer.fundsBox.fundsStructure",
|
||||
|
@ -536,8 +560,8 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
private void updateOfferElementsStyle() {
|
||||
GridPane.setColumnSpan(firstRowHBox, 1);
|
||||
|
||||
final String activeInputStyle = "input-with-border";
|
||||
final String readOnlyInputStyle = "input-with-border-readonly";
|
||||
final String activeInputStyle = "offer-input";
|
||||
final String readOnlyInputStyle = "offer-input-readonly";
|
||||
amountValueCurrencyBox.getStyleClass().remove(activeInputStyle);
|
||||
amountValueCurrencyBox.getStyleClass().add(readOnlyInputStyle);
|
||||
priceAsPercentageValueCurrencyBox.getStyleClass().remove(activeInputStyle);
|
||||
|
@ -631,7 +655,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
|
||||
UserThread.runAfter(() -> new Popup().warning(newValue + "\n\n" +
|
||||
Res.get("takeOffer.alreadyPaidInFunds"))
|
||||
.actionButtonTextWithGoTo("navigation.funds.availableForWithdrawal")
|
||||
.actionButtonTextWithGoTo("funds.tab.withdrawal")
|
||||
.onAction(() -> {
|
||||
errorPopupDisplayed.set(true);
|
||||
model.resetOfferWarning();
|
||||
|
@ -663,6 +687,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
if (isOfferAvailable) {
|
||||
offerAvailabilityBusyAnimation.stop();
|
||||
offerAvailabilityBusyAnimation.setVisible(false);
|
||||
offerAvailabilityBusyAnimation.setManaged(false);
|
||||
if (!model.isRange() && !model.showPayFundsScreenDisplayed.get())
|
||||
showNextStepAfterAmountIsSet();
|
||||
}
|
||||
|
@ -693,7 +718,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
if (DontShowAgainLookup.showAgain(key)) {
|
||||
UserThread.runAfter(() -> new Popup().headLine(Res.get("takeOffer.success.headline"))
|
||||
.feedback(Res.get("takeOffer.success.info"))
|
||||
.actionButtonTextWithGoTo("navigation.portfolio.pending")
|
||||
.actionButtonTextWithGoTo("portfolio.tab.pendingTrades")
|
||||
.dontShowAgainId(key)
|
||||
.onAction(() -> {
|
||||
UserThread.runAfter(
|
||||
|
@ -755,7 +780,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
private void addGridPane() {
|
||||
gridPane = new GridPane();
|
||||
gridPane.getStyleClass().add("content-pane");
|
||||
gridPane.setPadding(new Insets(15, 15, -1, 15));
|
||||
gridPane.setPadding(new Insets(25, 25, 25, 25));
|
||||
gridPane.setHgap(5);
|
||||
gridPane.setVgap(5);
|
||||
GUIUtil.setDefaultTwoColumnConstraintsForGridPane(gridPane);
|
||||
|
@ -837,11 +862,11 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
advancedOptionsBox.getChildren().addAll(tradeFeeFieldsBox);
|
||||
}
|
||||
|
||||
private void addButtons() {
|
||||
private void addNextButtons() {
|
||||
Tuple3<Button, Button, HBox> tuple = add2ButtonsWithBox(gridPane, ++gridRow,
|
||||
Res.get("shared.nextStep"), Res.get("shared.cancel"), 15, true);
|
||||
|
||||
buttonBox = tuple.third;
|
||||
nextButtonBox = tuple.third;
|
||||
|
||||
nextButton = tuple.first;
|
||||
nextButton.setMaxWidth(200);
|
||||
|
@ -870,7 +895,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
offerAvailabilityBusyAnimation = new BusyAnimation(false);
|
||||
offerAvailabilityLabel = new AutoTooltipLabel(Res.get("takeOffer.fundsBox.isOfferAvailable"));
|
||||
HBox.setMargin(offerAvailabilityLabel, new Insets(6, 0, 0, 0));
|
||||
buttonBox.getChildren().addAll(offerAvailabilityBusyAnimation, offerAvailabilityLabel);
|
||||
nextButtonBox.getChildren().addAll(offerAvailabilityBusyAnimation, offerAvailabilityLabel);
|
||||
}
|
||||
|
||||
private void addFundingGroup() {
|
||||
|
@ -881,16 +906,18 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
noFundingRequiredTitledGroupBg.getStyleClass().add("last");
|
||||
GridPane.setColumnSpan(noFundingRequiredTitledGroupBg, 2);
|
||||
noFundingRequiredTitledGroupBg.setVisible(false);
|
||||
noFundingRequiredTitledGroupBg.setManaged(false);
|
||||
|
||||
// no funding required description
|
||||
noFundingRequiredLabel = new AutoTooltipLabel(Res.get("takeOffer.fundsBox.noFundingRequiredDescription"));
|
||||
noFundingRequiredLabel.setVisible(false);
|
||||
noFundingRequiredLabel.setManaged(false);
|
||||
//GridPane.setRowSpan(noFundingRequiredLabel, 1);
|
||||
GridPane.setRowIndex(noFundingRequiredLabel, gridRow);
|
||||
noFundingRequiredLabel.setPadding(new Insets(Layout.COMPACT_FIRST_ROW_AND_GROUP_DISTANCE, 0, 0, 0));
|
||||
GridPane.setHalignment(noFundingRequiredLabel, HPos.LEFT);
|
||||
gridPane.getChildren().add(noFundingRequiredLabel);
|
||||
lastGridRowNoFundingRequired = gridRow;
|
||||
gridRowNoFundingRequired = gridRow;
|
||||
|
||||
// funding title
|
||||
payFundsTitledGroupBg = addTitledGroupBg(gridPane, gridRow, 3,
|
||||
|
@ -898,32 +925,38 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
payFundsTitledGroupBg.getStyleClass().add("last");
|
||||
GridPane.setColumnSpan(payFundsTitledGroupBg, 2);
|
||||
payFundsTitledGroupBg.setVisible(false);
|
||||
payFundsTitledGroupBg.setManaged(false);
|
||||
|
||||
totalToPayTextField = addFundsTextfield(gridPane, gridRow,
|
||||
Res.get("shared.totalsNeeded"), Layout.COMPACT_FIRST_ROW_AND_GROUP_DISTANCE);
|
||||
totalToPayTextField.setVisible(false);
|
||||
totalToPayTextField.setManaged(false);
|
||||
|
||||
qrCodeImageView = new ImageView();
|
||||
qrCodeImageView.setVisible(false);
|
||||
qrCodeImageView.setFitHeight(150);
|
||||
qrCodeImageView.setFitWidth(150);
|
||||
qrCodeImageView.getStyleClass().add("qr-code");
|
||||
Tooltip.install(qrCodeImageView, new Tooltip(Res.get("shared.openLargeQRWindow")));
|
||||
qrCodeImageView.setOnMouseClicked(e -> UserThread.runAfter(
|
||||
Tuple2<StackPane, ImageView> qrCodeTuple = GUIUtil.getSmallXmrQrCodePane();
|
||||
qrCodePane = qrCodeTuple.first;
|
||||
qrCodeImageView = qrCodeTuple.second;
|
||||
|
||||
Tooltip.install(qrCodePane, new Tooltip(Res.get("shared.openLargeQRWindow")));
|
||||
qrCodePane.setOnMouseClicked(e -> UserThread.runAfter(
|
||||
() -> new QRCodeWindow(getMoneroURI()).show(),
|
||||
200, TimeUnit.MILLISECONDS));
|
||||
GridPane.setRowIndex(qrCodeImageView, gridRow);
|
||||
GridPane.setColumnIndex(qrCodeImageView, 1);
|
||||
GridPane.setRowSpan(qrCodeImageView, 3);
|
||||
GridPane.setValignment(qrCodeImageView, VPos.BOTTOM);
|
||||
GridPane.setMargin(qrCodeImageView, new Insets(Layout.FIRST_ROW_DISTANCE - 9, 0, 0, 10));
|
||||
gridPane.getChildren().add(qrCodeImageView);
|
||||
GridPane.setRowIndex(qrCodePane, gridRow);
|
||||
GridPane.setColumnIndex(qrCodePane, 1);
|
||||
GridPane.setRowSpan(qrCodePane, 3);
|
||||
GridPane.setValignment(qrCodePane, VPos.BOTTOM);
|
||||
GridPane.setMargin(qrCodePane, new Insets(Layout.FIRST_ROW_DISTANCE - 9, 0, 0, 10));
|
||||
gridPane.getChildren().add(qrCodePane);
|
||||
|
||||
qrCodePane.setVisible(false);
|
||||
qrCodePane.setManaged(false);
|
||||
|
||||
addressTextField = addAddressTextField(gridPane, ++gridRow, Res.get("shared.tradeWalletAddress"));
|
||||
addressTextField.setVisible(false);
|
||||
addressTextField.setManaged(false);
|
||||
|
||||
balanceTextField = addBalanceTextField(gridPane, ++gridRow, Res.get("shared.tradeWalletBalance"));
|
||||
balanceTextField.setVisible(false);
|
||||
balanceTextField.setManaged(false);
|
||||
|
||||
fundingHBox = new HBox();
|
||||
fundingHBox.setVisible(false);
|
||||
|
@ -1000,6 +1033,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
});
|
||||
cancelButton2.setDefaultButton(false);
|
||||
cancelButton2.setVisible(false);
|
||||
cancelButton2.setManaged(false);
|
||||
}
|
||||
|
||||
private void openWallet() {
|
||||
|
@ -1100,6 +1134,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
fakeXLabel = new Label();
|
||||
fakeXIcon = getIconForLabel(MaterialDesignIcon.CLOSE, "2em", fakeXLabel);
|
||||
fakeXLabel.setVisible(false); // we just use it to get the same layout as the upper row
|
||||
fakeXIcon.setManaged(false);
|
||||
fakeXLabel.getStyleClass().add("opaque-icon-character");
|
||||
|
||||
HBox hBox = new HBox();
|
||||
|
@ -1147,7 +1182,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
UserThread.runAfter(() -> {
|
||||
new GenericMessageWindow()
|
||||
.preamble(Res.get("payment.tradingRestrictions"))
|
||||
.instruction(offer.getCombinedExtraInfo())
|
||||
.instruction(offer.getCombinedExtraInfo().trim())
|
||||
.actionButtonText(Res.get("shared.iConfirm"))
|
||||
.closeButtonText(Res.get("shared.close"))
|
||||
.width(Layout.INITIAL_WINDOW_WIDTH)
|
||||
|
|
|
@ -256,7 +256,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
|||
new Popup().warning(Res.get("shared.notEnoughFunds",
|
||||
HavenoUtils.formatXmr(dataModel.getTotalToPay().get(), true),
|
||||
HavenoUtils.formatXmr(dataModel.getTotalAvailableBalance(), true)))
|
||||
.actionButtonTextWithGoTo("navigation.funds.depositFunds")
|
||||
.actionButtonTextWithGoTo("funds.tab.deposit")
|
||||
.onAction(() -> navigation.navigateTo(MainView.class, FundsView.class, DepositView.class))
|
||||
.show();
|
||||
return false;
|
||||
|
|
|
@ -19,6 +19,8 @@ package haveno.desktop.main.overlays;
|
|||
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIcon;
|
||||
import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIconView;
|
||||
import haveno.common.Timer;
|
||||
import haveno.common.UserThread;
|
||||
import haveno.common.config.Config;
|
||||
|
@ -42,8 +44,6 @@ import javafx.animation.Interpolator;
|
|||
import javafx.animation.KeyFrame;
|
||||
import javafx.animation.KeyValue;
|
||||
import javafx.animation.Timeline;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
|
@ -52,6 +52,7 @@ import javafx.geometry.HPos;
|
|||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.NodeOrientation;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Cursor;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.PerspectiveCamera;
|
||||
import javafx.scene.Scene;
|
||||
|
@ -122,7 +123,7 @@ public abstract class Overlay<T extends Overlay<T>> {
|
|||
Notification(AnimationType.SlideFromRightTop, ChangeBackgroundType.BlurLight),
|
||||
|
||||
BackgroundInfo(AnimationType.SlideDownFromCenterTop, ChangeBackgroundType.BlurUltraLight),
|
||||
Feedback(AnimationType.SlideDownFromCenterTop, ChangeBackgroundType.Darken),
|
||||
Feedback(AnimationType.SlideDownFromCenterTop, ChangeBackgroundType.BlurLight),
|
||||
|
||||
Information(AnimationType.FadeInAtCenter, ChangeBackgroundType.BlurLight),
|
||||
Instruction(AnimationType.ScaleFromCenter, ChangeBackgroundType.BlurLight),
|
||||
|
@ -141,6 +142,9 @@ public abstract class Overlay<T extends Overlay<T>> {
|
|||
}
|
||||
}
|
||||
|
||||
private static int numCenterOverlays = 0;
|
||||
private static int numBlurEffects = 0;
|
||||
|
||||
protected final static double DEFAULT_WIDTH = 668;
|
||||
protected Stage stage;
|
||||
protected GridPane gridPane;
|
||||
|
@ -168,7 +172,7 @@ public abstract class Overlay<T extends Overlay<T>> {
|
|||
protected boolean showScrollPane = false;
|
||||
|
||||
protected TextArea messageTextArea;
|
||||
protected Label headlineIcon, copyIcon, headLineLabel;
|
||||
protected Label headlineIcon, copyLabel, headLineLabel;
|
||||
protected String headLine, message, closeButtonText, actionButtonText,
|
||||
secondaryActionButtonText, dontShowAgainId, dontShowAgainText,
|
||||
truncatedMessage;
|
||||
|
@ -249,6 +253,7 @@ public abstract class Overlay<T extends Overlay<T>> {
|
|||
|
||||
protected void animateHide() {
|
||||
animateHide(() -> {
|
||||
if (isCentered()) numCenterOverlays--;
|
||||
removeEffectFromBackground();
|
||||
|
||||
if (stage != null)
|
||||
|
@ -541,6 +546,14 @@ public abstract class Overlay<T extends Overlay<T>> {
|
|||
|
||||
layout();
|
||||
|
||||
// add dropshadow if light mode or multiple centered overlays
|
||||
if (isCentered()) {
|
||||
numCenterOverlays++;
|
||||
}
|
||||
if (!CssTheme.isDarkTheme() || numCenterOverlays > 1) {
|
||||
getRootContainer().getStyleClass().add("popup-dropshadow");
|
||||
}
|
||||
|
||||
addEffectToBackground();
|
||||
|
||||
// On Linux the owner stage does not move the child stage as it does on Mac
|
||||
|
@ -739,6 +752,8 @@ public abstract class Overlay<T extends Overlay<T>> {
|
|||
}
|
||||
|
||||
protected void addEffectToBackground() {
|
||||
numBlurEffects++;
|
||||
if (numBlurEffects > 1) return;
|
||||
if (type.changeBackgroundType == ChangeBackgroundType.BlurUltraLight)
|
||||
MainView.blurUltraLight();
|
||||
else if (type.changeBackgroundType == ChangeBackgroundType.BlurLight)
|
||||
|
@ -758,12 +773,14 @@ public abstract class Overlay<T extends Overlay<T>> {
|
|||
|
||||
|
||||
if (headLineLabel != null) {
|
||||
if (copyIcon != null) {
|
||||
copyIcon.getStyleClass().add("popup-icon-information");
|
||||
copyIcon.setManaged(true);
|
||||
copyIcon.setVisible(true);
|
||||
FormBuilder.getIconForLabel(AwesomeIcon.COPY, copyIcon, "1.1em");
|
||||
copyIcon.addEventHandler(MOUSE_CLICKED, mouseEvent -> {
|
||||
if (copyLabel != null) {
|
||||
copyLabel.getStyleClass().add("popup-icon-information");
|
||||
copyLabel.setManaged(true);
|
||||
copyLabel.setVisible(true);
|
||||
MaterialDesignIconView copyIcon = new MaterialDesignIconView(MaterialDesignIcon.CONTENT_COPY, "1.2em");
|
||||
copyLabel.setGraphic(copyIcon);
|
||||
copyLabel.setCursor(Cursor.HAND);
|
||||
copyLabel.addEventHandler(MOUSE_CLICKED, mouseEvent -> {
|
||||
if (message != null) {
|
||||
Utilities.copyToClipboard(getClipboardText());
|
||||
Tooltip tp = new Tooltip(Res.get("shared.copiedToClipboard"));
|
||||
|
@ -808,6 +825,8 @@ public abstract class Overlay<T extends Overlay<T>> {
|
|||
}
|
||||
|
||||
protected void removeEffectFromBackground() {
|
||||
numBlurEffects--;
|
||||
if (numBlurEffects > 0) return;
|
||||
MainView.removeEffect();
|
||||
}
|
||||
|
||||
|
@ -828,15 +847,15 @@ public abstract class Overlay<T extends Overlay<T>> {
|
|||
headLineLabel.setStyle(headlineStyle);
|
||||
|
||||
if (message != null) {
|
||||
copyIcon = new Label();
|
||||
copyIcon.setManaged(false);
|
||||
copyIcon.setVisible(false);
|
||||
copyIcon.setPadding(new Insets(3));
|
||||
copyIcon.setTooltip(new Tooltip(Res.get("shared.copyToClipboard")));
|
||||
copyLabel = new Label();
|
||||
copyLabel.setManaged(false);
|
||||
copyLabel.setVisible(false);
|
||||
copyLabel.setPadding(new Insets(3));
|
||||
copyLabel.setTooltip(new Tooltip(Res.get("shared.copyToClipboard")));
|
||||
final Pane spacer = new Pane();
|
||||
HBox.setHgrow(spacer, Priority.ALWAYS);
|
||||
spacer.setMinSize(Layout.PADDING, 1);
|
||||
hBox.getChildren().addAll(headlineIcon, headLineLabel, spacer, copyIcon);
|
||||
hBox.getChildren().addAll(headlineIcon, headLineLabel, spacer, copyLabel);
|
||||
} else {
|
||||
hBox.getChildren().addAll(headlineIcon, headLineLabel);
|
||||
}
|
||||
|
@ -852,23 +871,8 @@ public abstract class Overlay<T extends Overlay<T>> {
|
|||
if (message != null) {
|
||||
messageTextArea = new TextArea(truncatedMessage);
|
||||
messageTextArea.setEditable(false);
|
||||
messageTextArea.getStyleClass().add("text-area-no-border");
|
||||
messageTextArea.sceneProperty().addListener((o, oldScene, newScene) -> {
|
||||
if (newScene != null) {
|
||||
// avoid javafx css warning
|
||||
CssTheme.loadSceneStyles(newScene, CssTheme.CSS_THEME_LIGHT, false);
|
||||
messageTextArea.applyCss();
|
||||
var text = messageTextArea.lookup(".text");
|
||||
|
||||
messageTextArea.prefHeightProperty().bind(Bindings.createDoubleBinding(() -> {
|
||||
return messageTextArea.getFont().getSize() + text.getBoundsInLocal().getHeight();
|
||||
}, text.boundsInLocalProperty()));
|
||||
|
||||
text.boundsInLocalProperty().addListener((observableBoundsAfter, boundsBefore, boundsAfter) -> {
|
||||
Platform.runLater(() -> messageTextArea.requestLayout());
|
||||
});
|
||||
}
|
||||
});
|
||||
messageTextArea.getStyleClass().add("text-area-popup");
|
||||
GUIUtil.adjustHeightAutomatically(messageTextArea);
|
||||
messageTextArea.setWrapText(true);
|
||||
|
||||
Region messageRegion;
|
||||
|
@ -1093,4 +1097,10 @@ public abstract class Overlay<T extends Overlay<T>> {
|
|||
", message='" + message + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
private boolean isCentered() {
|
||||
if (type.animationType == AnimationType.SlideDownFromCenterTop) return false;
|
||||
if (type.animationType == AnimationType.SlideFromRightTop) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ public class PasswordPopup extends Overlay<PasswordPopup> {
|
|||
|
||||
@Override
|
||||
public void show() {
|
||||
actionButtonText("CONFIRM");
|
||||
actionButtonText("Confirm");
|
||||
createGridPane();
|
||||
addHeadLine();
|
||||
addContent();
|
||||
|
|
|
@ -42,6 +42,7 @@ public class Notification extends Overlay<Notification> {
|
|||
private boolean hasBeenDisplayed;
|
||||
private boolean autoClose;
|
||||
private Timer autoCloseTimer;
|
||||
private static final int BORDER_PADDING = 10;
|
||||
|
||||
public Notification() {
|
||||
width = 413; // 320 visible bg because of insets
|
||||
|
@ -205,8 +206,8 @@ public class Notification extends Overlay<Notification> {
|
|||
Window window = owner.getScene().getWindow();
|
||||
double titleBarHeight = window.getHeight() - owner.getScene().getHeight();
|
||||
double shadowInset = 44;
|
||||
stage.setX(Math.round(window.getX() + window.getWidth() + shadowInset - stage.getWidth()));
|
||||
stage.setY(Math.round(window.getY() + titleBarHeight - shadowInset));
|
||||
stage.setX(Math.round(window.getX() + window.getWidth() + shadowInset - stage.getWidth() - BORDER_PADDING));
|
||||
stage.setY(Math.round(window.getY() + titleBarHeight - shadowInset + BORDER_PADDING));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -216,7 +216,7 @@ public class NotificationCenter {
|
|||
if (DontShowAgainLookup.showAgain(key)) {
|
||||
Notification notification = new Notification().tradeHeadLine(trade.getShortId()).message(message);
|
||||
if (navigation.getCurrentPath() != null && !navigation.getCurrentPath().contains(PendingTradesView.class)) {
|
||||
notification.actionButtonTextWithGoTo("navigation.portfolio.pending")
|
||||
notification.actionButtonTextWithGoTo("portfolio.tab.pendingTrades")
|
||||
.onAction(() -> {
|
||||
DontShowAgainLookup.dontShowAgain(key, true);
|
||||
navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class);
|
||||
|
@ -318,7 +318,7 @@ public class NotificationCenter {
|
|||
private void goToSupport(Trade trade, String message, Class<? extends DisputeView> viewClass) {
|
||||
Notification notification = new Notification().disputeHeadLine(trade.getShortId()).message(message);
|
||||
if (navigation.getCurrentPath() != null && !navigation.getCurrentPath().contains(viewClass)) {
|
||||
notification.actionButtonTextWithGoTo("navigation.support")
|
||||
notification.actionButtonTextWithGoTo("mainView.menu.support")
|
||||
.onAction(() -> navigation.navigateTo(MainView.class, SupportView.class, viewClass))
|
||||
.show();
|
||||
} else {
|
||||
|
|
|
@ -46,6 +46,7 @@ import static haveno.desktop.util.FormBuilder.addConfirmationLabelTextField;
|
|||
import static haveno.desktop.util.FormBuilder.addConfirmationLabelTextFieldWithCopyIcon;
|
||||
import static haveno.desktop.util.FormBuilder.addLabelExplorerAddressTextField;
|
||||
import static haveno.desktop.util.FormBuilder.addLabelTxIdTextField;
|
||||
import static haveno.desktop.util.FormBuilder.addSeparator;
|
||||
import static haveno.desktop.util.FormBuilder.addTitledGroupBg;
|
||||
import haveno.desktop.util.Layout;
|
||||
import haveno.network.p2p.NodeAddress;
|
||||
|
@ -137,15 +138,20 @@ public class ContractWindow extends Overlay<ContractWindow> {
|
|||
addTitledGroupBg(gridPane, ++rowIndex, rows, Res.get("contractWindow.title"));
|
||||
addConfirmationLabelTextField(gridPane, rowIndex, Res.get("shared.offerId"), offer.getId(),
|
||||
Layout.TWICE_FIRST_ROW_DISTANCE);
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane, ++rowIndex, Res.get("contractWindow.dates"),
|
||||
DisplayUtils.formatDateTime(offer.getDate()) + " / " + DisplayUtils.formatDateTime(dispute.getTradeDate()));
|
||||
String currencyCode = offer.getCurrencyCode();
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane, ++rowIndex, Res.get("shared.offerType"),
|
||||
DisplayUtils.getDirectionBothSides(offer.getDirection(), offer.isPrivateOffer()));
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane, ++rowIndex, Res.get("shared.tradePrice"),
|
||||
FormattingUtils.formatPrice(contract.getPrice()));
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane, ++rowIndex, Res.get("shared.tradeAmount"),
|
||||
HavenoUtils.formatXmr(contract.getTradeAmount(), true));
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane,
|
||||
++rowIndex,
|
||||
VolumeUtil.formatVolumeLabel(currencyCode, ":"),
|
||||
|
@ -157,16 +163,20 @@ public class ContractWindow extends Overlay<ContractWindow> {
|
|||
Res.getWithColAndCap("shared.seller") +
|
||||
" " +
|
||||
HavenoUtils.formatXmr(offer.getOfferPayload().getSellerSecurityDepositForTradeAmount(contract.getTradeAmount()), true);
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane, ++rowIndex, Res.get("shared.securityDeposit"), securityDeposit);
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane,
|
||||
++rowIndex,
|
||||
Res.get("contractWindow.xmrAddresses"),
|
||||
contract.getBuyerPayoutAddressString() + " / " + contract.getSellerPayoutAddressString());
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane,
|
||||
++rowIndex,
|
||||
Res.get("contractWindow.onions"),
|
||||
contract.getBuyerNodeAddress().getFullAddress() + " / " + contract.getSellerNodeAddress().getFullAddress());
|
||||
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane,
|
||||
++rowIndex,
|
||||
Res.get("contractWindow.accountAge"),
|
||||
|
@ -176,16 +186,19 @@ public class ContractWindow extends Overlay<ContractWindow> {
|
|||
DisputeManager<? extends DisputeList<Dispute>> disputeManager = getDisputeManager(dispute);
|
||||
String nrOfDisputesAsBuyer = disputeManager != null ? disputeManager.getNrOfDisputes(true, contract) : "";
|
||||
String nrOfDisputesAsSeller = disputeManager != null ? disputeManager.getNrOfDisputes(false, contract) : "";
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane,
|
||||
++rowIndex,
|
||||
Res.get("contractWindow.numDisputes"),
|
||||
nrOfDisputesAsBuyer + " / " + nrOfDisputesAsSeller);
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane,
|
||||
++rowIndex,
|
||||
Res.get("shared.paymentDetails", Res.get("shared.buyer")),
|
||||
dispute.getBuyerPaymentAccountPayload() != null
|
||||
? dispute.getBuyerPaymentAccountPayload().getPaymentDetails()
|
||||
: "NA");
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane,
|
||||
++rowIndex,
|
||||
Res.get("shared.paymentDetails", Res.get("shared.seller")),
|
||||
|
@ -219,6 +232,7 @@ public class ContractWindow extends Overlay<ContractWindow> {
|
|||
NodeAddress agentNodeAddress = disputeManager.getAgentNodeAddress(dispute);
|
||||
if (agentNodeAddress != null) {
|
||||
String value = agentMatrixUserName + " (" + agentNodeAddress.getFullAddress() + ")";
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane, ++rowIndex, title, value);
|
||||
}
|
||||
}
|
||||
|
@ -232,40 +246,53 @@ public class ContractWindow extends Overlay<ContractWindow> {
|
|||
countries = CountryUtil.getCodesString(acceptedCountryCodes);
|
||||
tooltip = new Tooltip(CountryUtil.getNamesByCodesString(acceptedCountryCodes));
|
||||
}
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane, ++rowIndex, Res.get("shared.acceptedTakerCountries"), countries)
|
||||
.second.setTooltip(tooltip);
|
||||
}
|
||||
|
||||
if (showAcceptedBanks) {
|
||||
if (offer.getPaymentMethod().equals(PaymentMethod.SAME_BANK)) {
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane, ++rowIndex, Res.get("shared.bankName"), acceptedBanks.get(0));
|
||||
} else if (offer.getPaymentMethod().equals(PaymentMethod.SPECIFIC_BANKS)) {
|
||||
String value = Joiner.on(", ").join(acceptedBanks);
|
||||
Tooltip tooltip = new Tooltip(Res.get("shared.acceptedBanks") + value);
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane, ++rowIndex, Res.get("shared.acceptedBanks"), value)
|
||||
.second.setTooltip(tooltip);
|
||||
}
|
||||
}
|
||||
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addLabelTxIdTextField(gridPane, ++rowIndex, Res.get("shared.makerDepositTransactionId"), contract.getMakerDepositTxHash());
|
||||
if (contract.getTakerDepositTxHash() != null)
|
||||
if (contract.getTakerDepositTxHash() != null) {
|
||||
addLabelTxIdTextField(gridPane, ++rowIndex, Res.get("shared.takerDepositTransactionId"), contract.getTakerDepositTxHash());
|
||||
}
|
||||
|
||||
if (dispute.getDelayedPayoutTxId() != null)
|
||||
if (dispute.getDelayedPayoutTxId() != null) {
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addLabelTxIdTextField(gridPane, ++rowIndex, Res.get("shared.delayedPayoutTxId"), dispute.getDelayedPayoutTxId());
|
||||
}
|
||||
|
||||
if (dispute.getDonationAddressOfDelayedPayoutTx() != null) {
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addLabelExplorerAddressTextField(gridPane, ++rowIndex, Res.get("shared.delayedPayoutTxReceiverAddress"),
|
||||
dispute.getDonationAddressOfDelayedPayoutTx());
|
||||
}
|
||||
|
||||
if (dispute.getPayoutTxSerialized() != null)
|
||||
if (dispute.getPayoutTxSerialized() != null) {
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addLabelTxIdTextField(gridPane, ++rowIndex, Res.get("shared.payoutTxId"), dispute.getPayoutTxId());
|
||||
}
|
||||
|
||||
if (dispute.getContractHash() != null)
|
||||
if (dispute.getContractHash() != null) {
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, Res.get("contractWindow.contractHash"),
|
||||
Utils.HEX.encode(dispute.getContractHash())).second.setMouseTransparent(false);
|
||||
}
|
||||
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
Button viewContractButton = addConfirmationLabelButton(gridPane, ++rowIndex, Res.get("shared.contractAsJson"),
|
||||
Res.get("shared.viewContractAsJson"), 0).second;
|
||||
viewContractButton.setDefaultButton(false);
|
||||
|
|
|
@ -188,7 +188,7 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
|
|||
protected void createGridPane() {
|
||||
super.createGridPane();
|
||||
gridPane.setPadding(new Insets(35, 40, 30, 40));
|
||||
gridPane.getStyleClass().add("grid-pane");
|
||||
gridPane.getStyleClass().addAll("grid-pane", "popup-with-input");
|
||||
gridPane.getColumnConstraints().get(0).setHalignment(HPos.LEFT);
|
||||
gridPane.setPrefWidth(width);
|
||||
}
|
||||
|
@ -413,11 +413,13 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
|
|||
private void addPayoutAmountTextFields() {
|
||||
buyerPayoutAmountInputTextField = new InputTextField();
|
||||
buyerPayoutAmountInputTextField.setLabelFloat(true);
|
||||
buyerPayoutAmountInputTextField.getStyleClass().add("label-float");
|
||||
buyerPayoutAmountInputTextField.setEditable(false);
|
||||
buyerPayoutAmountInputTextField.setPromptText(Res.get("disputeSummaryWindow.payoutAmount.buyer"));
|
||||
|
||||
sellerPayoutAmountInputTextField = new InputTextField();
|
||||
sellerPayoutAmountInputTextField.setLabelFloat(true);
|
||||
sellerPayoutAmountInputTextField.getStyleClass().add("label-float");
|
||||
sellerPayoutAmountInputTextField.setPromptText(Res.get("disputeSummaryWindow.payoutAmount.seller"));
|
||||
sellerPayoutAmountInputTextField.setEditable(false);
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package haveno.desktop.main.overlays.windows;
|
||||
|
||||
import haveno.desktop.main.overlays.Overlay;
|
||||
import haveno.desktop.util.GUIUtil;
|
||||
import haveno.desktop.util.Layout;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextArea;
|
||||
|
@ -28,6 +29,7 @@ import static haveno.desktop.util.FormBuilder.addTextArea;
|
|||
|
||||
public class GenericMessageWindow extends Overlay<GenericMessageWindow> {
|
||||
private String preamble;
|
||||
private static final double MAX_TEXT_AREA_HEIGHT = 250;
|
||||
|
||||
public GenericMessageWindow() {
|
||||
super();
|
||||
|
@ -54,20 +56,11 @@ public class GenericMessageWindow extends Overlay<GenericMessageWindow> {
|
|||
}
|
||||
checkNotNull(message, "message must not be null");
|
||||
TextArea textArea = addTextArea(gridPane, ++rowIndex, "", 10);
|
||||
textArea.getStyleClass().add("flat-text-area-with-border");
|
||||
textArea.setText(message);
|
||||
textArea.setEditable(false);
|
||||
textArea.setWrapText(true);
|
||||
// sizes the textArea to fit within its parent container
|
||||
double verticalSizePercentage = ensureRange(countLines(message) / 20.0, 0.2, 0.7);
|
||||
textArea.setPrefSize(Layout.INITIAL_WINDOW_WIDTH, Layout.INITIAL_WINDOW_HEIGHT * verticalSizePercentage);
|
||||
}
|
||||
|
||||
private static int countLines(String str) {
|
||||
String[] lines = str.split("\r\n|\r|\n");
|
||||
return lines.length;
|
||||
}
|
||||
|
||||
private static double ensureRange(double value, double min, double max) {
|
||||
return Math.min(Math.max(value, min), max);
|
||||
textArea.setPrefWidth(Layout.INITIAL_WINDOW_WIDTH);
|
||||
GUIUtil.adjustHeightAutomatically(textArea, MAX_TEXT_AREA_HEIGHT);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,10 +20,16 @@ package haveno.desktop.main.overlays.windows;
|
|||
import com.google.common.base.Joiner;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.name.Named;
|
||||
import com.jfoenix.controls.JFXButton;
|
||||
import com.jfoenix.controls.JFXTextField;
|
||||
|
||||
import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIcon;
|
||||
import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIconView;
|
||||
import haveno.common.UserThread;
|
||||
import haveno.common.crypto.KeyRing;
|
||||
import haveno.common.util.Tuple2;
|
||||
import haveno.common.util.Tuple4;
|
||||
import haveno.common.util.Utilities;
|
||||
import haveno.core.locale.CountryUtil;
|
||||
import haveno.core.locale.Res;
|
||||
import haveno.core.monetary.Price;
|
||||
|
@ -45,30 +51,37 @@ import haveno.desktop.components.BusyAnimation;
|
|||
import haveno.desktop.main.overlays.Overlay;
|
||||
import haveno.desktop.main.overlays.editor.PasswordPopup;
|
||||
import haveno.desktop.main.overlays.popups.Popup;
|
||||
import haveno.desktop.util.CssTheme;
|
||||
import haveno.desktop.util.DisplayUtils;
|
||||
import static haveno.desktop.util.FormBuilder.addButtonAfterGroup;
|
||||
import static haveno.desktop.util.FormBuilder.addButtonBusyAnimationLabelAfterGroup;
|
||||
import static haveno.desktop.util.FormBuilder.addConfirmationLabelLabel;
|
||||
import static haveno.desktop.util.FormBuilder.addConfirmationLabelTextArea;
|
||||
import static haveno.desktop.util.FormBuilder.addConfirmationLabelTextFieldWithCopyIcon;
|
||||
import static haveno.desktop.util.FormBuilder.addLabel;
|
||||
import static haveno.desktop.util.FormBuilder.addSeparator;
|
||||
import static haveno.desktop.util.FormBuilder.addTitledGroupBg;
|
||||
import haveno.desktop.util.GUIUtil;
|
||||
import haveno.desktop.util.Layout;
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.geometry.HPos;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.geometry.VPos;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ContentDisplay;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.paint.Color;
|
||||
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
import org.fxmisc.easybind.Subscription;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -115,7 +128,7 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
|||
this.tradePrice = tradePrice;
|
||||
|
||||
rowIndex = -1;
|
||||
width = 1118;
|
||||
width = Layout.DETAILS_WINDOW_WIDTH;
|
||||
createGridPane();
|
||||
addContent();
|
||||
display();
|
||||
|
@ -124,7 +137,7 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
|||
public void show(Offer offer) {
|
||||
this.offer = offer;
|
||||
rowIndex = -1;
|
||||
width = 1118;
|
||||
width = Layout.DETAILS_WINDOW_WIDTH;
|
||||
createGridPane();
|
||||
addContent();
|
||||
display();
|
||||
|
@ -194,7 +207,7 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
|||
rows++;
|
||||
}
|
||||
|
||||
addTitledGroupBg(gridPane, ++rowIndex, rows, Res.get(offer.isPrivateOffer() ? "shared.Offer" : "shared.Offer"));
|
||||
addTitledGroupBg(gridPane, ++rowIndex, rows, Res.get("shared.Offer"));
|
||||
|
||||
String counterCurrencyDirectionInfo = "";
|
||||
String xmrDirectionInfo = "";
|
||||
|
@ -218,17 +231,22 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
|||
addConfirmationLabelLabel(gridPane, rowIndex, offerTypeLabel,
|
||||
DisplayUtils.getDirectionBothSides(direction, offer.isPrivateOffer()), firstRowDistance);
|
||||
}
|
||||
|
||||
String amount = Res.get("shared.xmrAmount");
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
if (takeOfferHandlerOptional.isPresent()) {
|
||||
addConfirmationLabelLabel(gridPane, ++rowIndex, amount + xmrDirectionInfo,
|
||||
HavenoUtils.formatXmr(tradeAmount, true));
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelLabel(gridPane, ++rowIndex, VolumeUtil.formatVolumeLabel(currencyCode) + counterCurrencyDirectionInfo,
|
||||
VolumeUtil.formatVolumeWithCode(offer.getVolumeByAmount(tradeAmount)));
|
||||
} else {
|
||||
addConfirmationLabelLabel(gridPane, ++rowIndex, amount + xmrDirectionInfo,
|
||||
HavenoUtils.formatXmr(offer.getAmount(), true));
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("offerDetailsWindow.minXmrAmount"),
|
||||
HavenoUtils.formatXmr(offer.getMinAmount(), true));
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
String volume = VolumeUtil.formatVolumeWithCode(offer.getVolume());
|
||||
String minVolume = "";
|
||||
if (offer.getVolume() != null && offer.getMinVolume() != null &&
|
||||
|
@ -239,6 +257,7 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
|||
}
|
||||
|
||||
String priceLabel = Res.get("shared.price");
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
if (takeOfferHandlerOptional.isPresent()) {
|
||||
addConfirmationLabelLabel(gridPane, ++rowIndex, priceLabel, FormattingUtils.formatPrice(tradePrice));
|
||||
} else {
|
||||
|
@ -264,6 +283,7 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
|||
final PaymentAccount myPaymentAccount = user.getPaymentAccount(makerPaymentAccountId);
|
||||
String countryCode = offer.getCountryCode();
|
||||
boolean isMyOffer = offer.isMyOffer(keyRing);
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
if (isMyOffer && makerPaymentAccountId != null && myPaymentAccount != null) {
|
||||
addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("offerDetailsWindow.myTradingAccount"), myPaymentAccount.getAccountName());
|
||||
} else {
|
||||
|
@ -272,6 +292,7 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
|||
}
|
||||
|
||||
if (showXmrAutoConf) {
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
String isAutoConf = offer.isXmrAutoConf() ?
|
||||
Res.get("shared.yes") :
|
||||
Res.get("shared.no");
|
||||
|
@ -280,8 +301,10 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
|||
|
||||
if (showAcceptedBanks) {
|
||||
if (paymentMethod.equals(PaymentMethod.SAME_BANK)) {
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("offerDetailsWindow.bankId"), acceptedBanks.get(0));
|
||||
} else if (isSpecificBanks) {
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
String value = Joiner.on(", ").join(acceptedBanks);
|
||||
String acceptedBanksLabel = Res.get("shared.acceptedBanks");
|
||||
Tooltip tooltip = new Tooltip(acceptedBanksLabel + " " + value);
|
||||
|
@ -291,6 +314,7 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
|||
}
|
||||
}
|
||||
if (showAcceptedCountryCodes) {
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
String countries;
|
||||
Tooltip tooltip = null;
|
||||
if (CountryUtil.containsAllSepaEuroCountries(acceptedCountryCodes)) {
|
||||
|
@ -313,29 +337,16 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
|||
}
|
||||
|
||||
if (isF2F) {
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("payment.f2f.city"), offer.getF2FCity());
|
||||
}
|
||||
if (showOfferExtraInfo) {
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
TextArea textArea = addConfirmationLabelTextArea(gridPane, ++rowIndex, Res.get("payment.shared.extraInfo"), "", 0).second;
|
||||
textArea.setText(offer.getCombinedExtraInfo());
|
||||
textArea.setMaxHeight(200);
|
||||
textArea.sceneProperty().addListener((o, oldScene, newScene) -> {
|
||||
if (newScene != null) {
|
||||
// avoid javafx css warning
|
||||
CssTheme.loadSceneStyles(newScene, CssTheme.CSS_THEME_LIGHT, false);
|
||||
textArea.applyCss();
|
||||
var text = textArea.lookup(".text");
|
||||
|
||||
textArea.prefHeightProperty().bind(Bindings.createDoubleBinding(() -> {
|
||||
return textArea.getFont().getSize() + text.getBoundsInLocal().getHeight();
|
||||
}, text.boundsInLocalProperty()));
|
||||
|
||||
text.boundsInLocalProperty().addListener((observableBoundsAfter, boundsBefore, boundsAfter) -> {
|
||||
Platform.runLater(() -> textArea.requestLayout());
|
||||
});
|
||||
}
|
||||
});
|
||||
textArea.setText(offer.getCombinedExtraInfo().trim());
|
||||
textArea.setMaxHeight(Layout.DETAILS_WINDOW_EXTRA_INFO_MAX_HEIGHT);
|
||||
textArea.setEditable(false);
|
||||
GUIUtil.adjustHeightAutomatically(textArea, Layout.DETAILS_WINDOW_EXTRA_INFO_MAX_HEIGHT);
|
||||
}
|
||||
|
||||
// get amount reserved for the offer
|
||||
|
@ -355,13 +366,16 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
|||
if (offerChallenge != null)
|
||||
rows++;
|
||||
|
||||
addTitledGroupBg(gridPane, ++rowIndex, rows, Res.get("shared.details"), Layout.GROUP_DISTANCE);
|
||||
addTitledGroupBg(gridPane, ++rowIndex, rows, Res.get("shared.details"), Layout.COMPACT_GROUP_DISTANCE);
|
||||
addConfirmationLabelTextFieldWithCopyIcon(gridPane, rowIndex, Res.get("shared.offerId"), offer.getId(),
|
||||
Layout.TWICE_FIRST_ROW_AND_GROUP_DISTANCE);
|
||||
Layout.TWICE_FIRST_ROW_AND_COMPACT_GROUP_DISTANCE);
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, Res.get("offerDetailsWindow.makersOnion"),
|
||||
offer.getMakerNodeAddress().getFullAddress());
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("offerDetailsWindow.creationDate"),
|
||||
DisplayUtils.formatDateTime(offer.getDate()));
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
String value = Res.getWithColAndCap("shared.buyer") +
|
||||
" " +
|
||||
HavenoUtils.formatXmr(takeOfferHandlerOptional.isPresent() ? offer.getOfferPayload().getBuyerSecurityDepositForTradeAmount(tradeAmount) : offer.getOfferPayload().getMaxBuyerSecurityDeposit(), true) +
|
||||
|
@ -372,27 +386,75 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
|||
addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("shared.securityDeposit"), value);
|
||||
|
||||
if (reservedAmount != null) {
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("shared.reservedAmount"), HavenoUtils.formatXmr(reservedAmount, true));
|
||||
}
|
||||
|
||||
if (countryCode != null && !isF2F)
|
||||
if (countryCode != null && !isF2F) {
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("offerDetailsWindow.countryBank"),
|
||||
CountryUtil.getNameAndCode(countryCode));
|
||||
}
|
||||
|
||||
if (offerChallenge != null)
|
||||
addConfirmationLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, Res.get("offerDetailsWindow.challenge"), offerChallenge);
|
||||
if (offerChallenge != null) {
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
|
||||
// add label
|
||||
Label label = addLabel(gridPane, ++rowIndex, Res.get("offerDetailsWindow.challenge"), 0);
|
||||
label.getStyleClass().addAll("confirmation-label", "regular-text-color");
|
||||
GridPane.setHalignment(label, HPos.LEFT);
|
||||
GridPane.setValignment(label, VPos.TOP);
|
||||
|
||||
// add vbox with passphrase and copy button
|
||||
VBox vbox = new VBox(13);
|
||||
vbox.setAlignment(Pos.TOP_CENTER);
|
||||
VBox.setVgrow(vbox, Priority.ALWAYS);
|
||||
vbox.getStyleClass().addAll("passphrase-copy-box");
|
||||
|
||||
// add passphrase
|
||||
JFXTextField centerLabel = new JFXTextField(offerChallenge);
|
||||
centerLabel.getStyleClass().add("confirmation-value");
|
||||
centerLabel.setAlignment(Pos.CENTER);
|
||||
centerLabel.setFocusTraversable(false);
|
||||
|
||||
// add copy button
|
||||
Label copyLabel = new Label();
|
||||
copyLabel.getStyleClass().addAll("icon");
|
||||
copyLabel.setTooltip(new Tooltip(Res.get("shared.copyToClipboard")));
|
||||
MaterialDesignIconView copyIcon = new MaterialDesignIconView(MaterialDesignIcon.CONTENT_COPY, "1.2em");
|
||||
copyIcon.setFill(Color.WHITE);
|
||||
copyLabel.setGraphic(copyIcon);
|
||||
JFXButton copyButton = new JFXButton(Res.get("offerDetailsWindow.challenge.copy"), copyLabel);
|
||||
copyButton.setContentDisplay(ContentDisplay.LEFT);
|
||||
copyButton.setGraphicTextGap(8);
|
||||
copyButton.setOnMouseClicked(e -> {
|
||||
Utilities.copyToClipboard(offerChallenge);
|
||||
Tooltip tp = new Tooltip(Res.get("shared.copiedToClipboard"));
|
||||
Node node = (Node) e.getSource();
|
||||
UserThread.runAfter(() -> tp.hide(), 1);
|
||||
tp.show(node, e.getScreenX() + Layout.PADDING, e.getScreenY() + Layout.PADDING);
|
||||
});
|
||||
copyButton.setId("buy-button");
|
||||
copyButton.setFocusTraversable(false);
|
||||
vbox.getChildren().addAll(centerLabel, copyButton);
|
||||
|
||||
// add vbox to grid pane in next column
|
||||
GridPane.setRowIndex(vbox, rowIndex);
|
||||
GridPane.setColumnIndex(vbox, 1);
|
||||
gridPane.getChildren().add(vbox);
|
||||
}
|
||||
|
||||
if (placeOfferHandlerOptional.isPresent()) {
|
||||
addTitledGroupBg(gridPane, ++rowIndex, 1, Res.get("offerDetailsWindow.commitment"), Layout.GROUP_DISTANCE);
|
||||
addTitledGroupBg(gridPane, ++rowIndex, 1, Res.get("offerDetailsWindow.commitment"), Layout.COMPACT_GROUP_DISTANCE);
|
||||
final Tuple2<Label, Label> labelLabelTuple2 = addConfirmationLabelLabel(gridPane, rowIndex, Res.get("offerDetailsWindow.agree"), Res.get("createOffer.tac"),
|
||||
Layout.TWICE_FIRST_ROW_AND_GROUP_DISTANCE);
|
||||
Layout.TWICE_FIRST_ROW_AND_COMPACT_GROUP_DISTANCE);
|
||||
labelLabelTuple2.second.setWrapText(true);
|
||||
|
||||
addConfirmAndCancelButtons(true);
|
||||
} else if (takeOfferHandlerOptional.isPresent()) {
|
||||
addTitledGroupBg(gridPane, ++rowIndex, 1, Res.get("shared.contract"), Layout.GROUP_DISTANCE);
|
||||
addTitledGroupBg(gridPane, ++rowIndex, 1, Res.get("shared.contract"), Layout.COMPACT_GROUP_DISTANCE);
|
||||
final Tuple2<Label, Label> labelLabelTuple2 = addConfirmationLabelLabel(gridPane, rowIndex, Res.get("offerDetailsWindow.tac"), Res.get("takeOffer.tac"),
|
||||
Layout.TWICE_FIRST_ROW_AND_GROUP_DISTANCE);
|
||||
Layout.TWICE_FIRST_ROW_AND_COMPACT_GROUP_DISTANCE);
|
||||
labelLabelTuple2.second.setWrapText(true);
|
||||
|
||||
addConfirmAndCancelButtons(false);
|
||||
|
@ -418,9 +480,6 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
|||
Res.get("offerDetailsWindow.confirm.taker", Res.get("shared.buy")) :
|
||||
Res.get("offerDetailsWindow.confirm.taker", Res.get("shared.sell"));
|
||||
|
||||
ImageView iconView = new ImageView();
|
||||
iconView.setId(isBuyerRole ? "image-buy-white" : "image-sell-white");
|
||||
|
||||
Tuple4<Button, BusyAnimation, Label, HBox> placeOfferTuple = addButtonBusyAnimationLabelAfterGroup(gridPane,
|
||||
++rowIndex, 1,
|
||||
isPlaceOffer ? placeOfferButtonText : takeOfferButtonText);
|
||||
|
@ -428,11 +487,18 @@ public class OfferDetailsWindow extends Overlay<OfferDetailsWindow> {
|
|||
AutoTooltipButton confirmButton = (AutoTooltipButton) placeOfferTuple.first;
|
||||
confirmButton.setMinHeight(40);
|
||||
confirmButton.setPadding(new Insets(0, 20, 0, 20));
|
||||
confirmButton.setGraphic(iconView);
|
||||
confirmButton.setGraphicTextGap(10);
|
||||
confirmButton.setId(isBuyerRole ? "buy-button-big" : "sell-button-big");
|
||||
confirmButton.updateText(isPlaceOffer ? placeOfferButtonText : takeOfferButtonText);
|
||||
|
||||
if (offer.hasBuyerAsTakerWithoutDeposit()) {
|
||||
confirmButton.setGraphic(GUIUtil.getLockLabel());
|
||||
} else {
|
||||
ImageView iconView = new ImageView();
|
||||
iconView.setId(isBuyerRole ? "image-buy-white" : "image-sell-white");
|
||||
confirmButton.setGraphic(iconView);
|
||||
}
|
||||
|
||||
busyAnimation = placeOfferTuple.second;
|
||||
Label spinnerInfoLabel = placeOfferTuple.third;
|
||||
|
||||
|
|
|
@ -17,9 +17,12 @@
|
|||
|
||||
package haveno.desktop.main.overlays.windows;
|
||||
|
||||
import haveno.common.util.Tuple2;
|
||||
import haveno.common.util.Utilities;
|
||||
import haveno.core.locale.Res;
|
||||
import haveno.desktop.components.AutoTooltipLabel;
|
||||
import haveno.desktop.main.overlays.Overlay;
|
||||
import haveno.desktop.util.GUIUtil;
|
||||
import javafx.geometry.HPos;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Label;
|
||||
|
@ -27,31 +30,35 @@ import javafx.scene.image.Image;
|
|||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import net.glxn.qrgen.QRCode;
|
||||
import net.glxn.qrgen.image.ImageType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.net.URI;
|
||||
|
||||
public class QRCodeWindow extends Overlay<QRCodeWindow> {
|
||||
private static final Logger log = LoggerFactory.getLogger(QRCodeWindow.class);
|
||||
private final ImageView qrCodeImageView;
|
||||
private final StackPane qrCodePane;
|
||||
private final String moneroUri;
|
||||
|
||||
public QRCodeWindow(String bitcoinURI) {
|
||||
this.moneroUri = bitcoinURI;
|
||||
public QRCodeWindow(String moneroUri) {
|
||||
this.moneroUri = moneroUri;
|
||||
|
||||
Tuple2<StackPane, ImageView> qrCodeTuple = GUIUtil.getBigXmrQrCodePane();
|
||||
qrCodePane = qrCodeTuple.first;
|
||||
ImageView qrCodeImageView = qrCodeTuple.second;
|
||||
|
||||
final byte[] imageBytes = QRCode
|
||||
.from(bitcoinURI)
|
||||
.from(moneroUri)
|
||||
.withSize(300, 300)
|
||||
.to(ImageType.PNG)
|
||||
.stream()
|
||||
.toByteArray();
|
||||
Image qrImage = new Image(new ByteArrayInputStream(imageBytes));
|
||||
qrCodeImageView = new ImageView(qrImage);
|
||||
qrCodeImageView.setFitHeight(250);
|
||||
qrCodeImageView.setFitWidth(250);
|
||||
qrCodeImageView.getStyleClass().add("qr-code");
|
||||
qrCodeImageView.setImage(qrImage);
|
||||
|
||||
type = Type.Information;
|
||||
width = 468;
|
||||
|
@ -65,10 +72,11 @@ public class QRCodeWindow extends Overlay<QRCodeWindow> {
|
|||
addHeadLine();
|
||||
addMessage();
|
||||
|
||||
GridPane.setRowIndex(qrCodeImageView, ++rowIndex);
|
||||
GridPane.setColumnSpan(qrCodeImageView, 2);
|
||||
GridPane.setHalignment(qrCodeImageView, HPos.CENTER);
|
||||
gridPane.getChildren().add(qrCodeImageView);
|
||||
qrCodePane.setOnMouseClicked(event -> openWallet());
|
||||
GridPane.setRowIndex(qrCodePane, ++rowIndex);
|
||||
GridPane.setColumnSpan(qrCodePane, 2);
|
||||
GridPane.setHalignment(qrCodePane, HPos.CENTER);
|
||||
gridPane.getChildren().add(qrCodePane);
|
||||
|
||||
String request = moneroUri.replace("%20", " ").replace("?", "\n?").replace("&", "\n&");
|
||||
Label infoLabel = new AutoTooltipLabel(Res.get("qRCodeWindow.request", request));
|
||||
|
@ -91,4 +99,12 @@ public class QRCodeWindow extends Overlay<QRCodeWindow> {
|
|||
public String getClipboardText() {
|
||||
return moneroUri;
|
||||
}
|
||||
|
||||
private void openWallet() {
|
||||
try {
|
||||
Utilities.openURI(URI.create(moneroUri));
|
||||
} catch (Exception e) {
|
||||
log.warn(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ public class SignPaymentAccountsWindow extends Overlay<SignPaymentAccountsWindow
|
|||
// We want to have more space to read list entries... initial screen does not look so nice now, but
|
||||
// dynamically updating height of window is a bit tricky.... @christoph feel free to improve if you like...
|
||||
gridPane.setPrefHeight(600);
|
||||
|
||||
gridPane.getStyleClass().add("popup-with-input");
|
||||
gridPane.getColumnConstraints().get(1).setHgrow(Priority.NEVER);
|
||||
|
||||
headLine(Res.get("popup.accountSigning.selectAccounts.headline"));
|
||||
|
|
|
@ -67,6 +67,7 @@ public class SignSpecificWitnessWindow extends Overlay<SignSpecificWitnessWindow
|
|||
|
||||
gridPane.setPrefHeight(600);
|
||||
gridPane.getColumnConstraints().get(1).setHgrow(Priority.NEVER);
|
||||
gridPane.getStyleClass().add("popup-with-input");
|
||||
headLine(Res.get("popup.accountSigning.singleAccountSelect.headline"));
|
||||
type = Type.Attention;
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ public class SignUnsignedPubKeysWindow extends Overlay<SignUnsignedPubKeysWindow
|
|||
|
||||
gridPane.setPrefHeight(600);
|
||||
gridPane.getColumnConstraints().get(1).setHgrow(Priority.NEVER);
|
||||
gridPane.getStyleClass().add("popup-with-input");
|
||||
headLine(Res.get("popup.accountSigning.singleAccountSelect.headline"));
|
||||
type = Type.Attention;
|
||||
|
||||
|
|
|
@ -38,22 +38,21 @@ import haveno.core.xmr.wallet.BtcWalletService;
|
|||
import haveno.desktop.components.HavenoTextArea;
|
||||
import haveno.desktop.main.MainView;
|
||||
import haveno.desktop.main.overlays.Overlay;
|
||||
import haveno.desktop.util.CssTheme;
|
||||
import haveno.desktop.util.DisplayUtils;
|
||||
import haveno.desktop.util.GUIUtil;
|
||||
|
||||
import static haveno.desktop.util.DisplayUtils.getAccountWitnessDescription;
|
||||
import static haveno.desktop.util.FormBuilder.add2ButtonsWithBox;
|
||||
import static haveno.desktop.util.FormBuilder.addConfirmationLabelTextArea;
|
||||
import static haveno.desktop.util.FormBuilder.addConfirmationLabelTextField;
|
||||
import static haveno.desktop.util.FormBuilder.addLabelTxIdTextField;
|
||||
import static haveno.desktop.util.FormBuilder.addSeparator;
|
||||
import static haveno.desktop.util.FormBuilder.addTitledGroupBg;
|
||||
import haveno.desktop.util.Layout;
|
||||
import haveno.network.p2p.NodeAddress;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.TextArea;
|
||||
|
@ -107,7 +106,7 @@ public class TradeDetailsWindow extends Overlay<TradeDetailsWindow> {
|
|||
this.trade = trade;
|
||||
|
||||
rowIndex = -1;
|
||||
width = 918;
|
||||
width = Layout.DETAILS_WINDOW_WIDTH;
|
||||
createGridPane();
|
||||
addContent();
|
||||
display();
|
||||
|
@ -127,7 +126,6 @@ public class TradeDetailsWindow extends Overlay<TradeDetailsWindow> {
|
|||
@Override
|
||||
protected void createGridPane() {
|
||||
super.createGridPane();
|
||||
gridPane.setPadding(new Insets(35, 40, 30, 40));
|
||||
gridPane.getStyleClass().add("grid-pane");
|
||||
}
|
||||
|
||||
|
@ -135,7 +133,7 @@ public class TradeDetailsWindow extends Overlay<TradeDetailsWindow> {
|
|||
Offer offer = trade.getOffer();
|
||||
Contract contract = trade.getContract();
|
||||
|
||||
int rows = 5;
|
||||
int rows = 9;
|
||||
addTitledGroupBg(gridPane, ++rowIndex, rows, Res.get("tradeDetailsWindow.headline"));
|
||||
|
||||
boolean myOffer = tradeManager.isMyOffer(offer);
|
||||
|
@ -156,18 +154,22 @@ public class TradeDetailsWindow extends Overlay<TradeDetailsWindow> {
|
|||
xmrDirectionInfo = toSpend;
|
||||
}
|
||||
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane, ++rowIndex, Res.get("shared.xmrAmount") + xmrDirectionInfo,
|
||||
HavenoUtils.formatXmr(trade.getAmount(), true));
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane, ++rowIndex,
|
||||
VolumeUtil.formatVolumeLabel(offer.getCurrencyCode()) + counterCurrencyDirectionInfo,
|
||||
VolumeUtil.formatVolumeWithCode(trade.getVolume()));
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane, ++rowIndex, Res.get("shared.tradePrice"),
|
||||
FormattingUtils.formatPrice(trade.getPrice()));
|
||||
String paymentMethodText = Res.get(offer.getPaymentMethod().getId());
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane, ++rowIndex, Res.get("shared.paymentMethod"), paymentMethodText);
|
||||
|
||||
// second group
|
||||
rows = 7;
|
||||
rows = 5;
|
||||
|
||||
if (offer.getCombinedExtraInfo() != null && !offer.getCombinedExtraInfo().isEmpty())
|
||||
rows++;
|
||||
|
@ -200,9 +202,10 @@ public class TradeDetailsWindow extends Overlay<TradeDetailsWindow> {
|
|||
if (trade.getTradePeerNodeAddress() != null)
|
||||
rows++;
|
||||
|
||||
addTitledGroupBg(gridPane, ++rowIndex, rows, Res.get("shared.details"), Layout.GROUP_DISTANCE);
|
||||
addTitledGroupBg(gridPane, ++rowIndex, rows, Res.get("shared.details"), Layout.COMPACT_GROUP_DISTANCE);
|
||||
addConfirmationLabelTextField(gridPane, rowIndex, Res.get("shared.tradeId"),
|
||||
trade.getId(), Layout.TWICE_FIRST_ROW_AND_GROUP_DISTANCE);
|
||||
trade.getId(), Layout.TWICE_FIRST_ROW_AND_COMPACT_GROUP_DISTANCE);
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane, ++rowIndex, Res.get("tradeDetailsWindow.tradeDate"),
|
||||
DisplayUtils.formatDateTime(trade.getDate()));
|
||||
String securityDeposit = Res.getWithColAndCap("shared.buyer") +
|
||||
|
@ -212,40 +215,30 @@ public class TradeDetailsWindow extends Overlay<TradeDetailsWindow> {
|
|||
Res.getWithColAndCap("shared.seller") +
|
||||
" " +
|
||||
HavenoUtils.formatXmr(trade.getSellerSecurityDepositBeforeMiningFee(), true);
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane, ++rowIndex, Res.get("shared.securityDeposit"), securityDeposit);
|
||||
|
||||
NodeAddress arbitratorNodeAddress = trade.getArbitratorNodeAddress();
|
||||
if (arbitratorNodeAddress != null) {
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane, ++rowIndex,
|
||||
Res.get("tradeDetailsWindow.agentAddresses"),
|
||||
arbitratorNodeAddress.getFullAddress());
|
||||
}
|
||||
|
||||
if (trade.getTradePeerNodeAddress() != null)
|
||||
if (trade.getTradePeerNodeAddress() != null) {
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane, ++rowIndex, Res.get("tradeDetailsWindow.tradePeersOnion"),
|
||||
trade.getTradePeerNodeAddress().getFullAddress());
|
||||
}
|
||||
|
||||
if (offer.getCombinedExtraInfo() != null && !offer.getCombinedExtraInfo().isEmpty()) {
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
TextArea textArea = addConfirmationLabelTextArea(gridPane, ++rowIndex, Res.get("payment.shared.extraInfo.offer"), "", 0).second;
|
||||
textArea.setText(offer.getCombinedExtraInfo());
|
||||
textArea.setMaxHeight(200);
|
||||
textArea.sceneProperty().addListener((o, oldScene, newScene) -> {
|
||||
if (newScene != null) {
|
||||
// avoid javafx css warning
|
||||
CssTheme.loadSceneStyles(newScene, CssTheme.CSS_THEME_LIGHT, false);
|
||||
textArea.applyCss();
|
||||
var text = textArea.lookup(".text");
|
||||
|
||||
textArea.prefHeightProperty().bind(Bindings.createDoubleBinding(() -> {
|
||||
return textArea.getFont().getSize() + text.getBoundsInLocal().getHeight();
|
||||
}, text.boundsInLocalProperty()));
|
||||
|
||||
text.boundsInLocalProperty().addListener((observableBoundsAfter, boundsBefore, boundsAfter) -> {
|
||||
Platform.runLater(() -> textArea.requestLayout());
|
||||
});
|
||||
}
|
||||
});
|
||||
textArea.setText(offer.getCombinedExtraInfo().trim());
|
||||
textArea.setMaxHeight(Layout.DETAILS_WINDOW_EXTRA_INFO_MAX_HEIGHT);
|
||||
textArea.setEditable(false);
|
||||
GUIUtil.adjustHeightAutomatically(textArea, Layout.DETAILS_WINDOW_EXTRA_INFO_MAX_HEIGHT);
|
||||
}
|
||||
|
||||
if (contract != null) {
|
||||
|
@ -254,6 +247,7 @@ public class TradeDetailsWindow extends Overlay<TradeDetailsWindow> {
|
|||
if (buyerPaymentAccountPayload != null) {
|
||||
String paymentDetails = buyerPaymentAccountPayload.getPaymentDetails();
|
||||
String postFix = " / " + buyersAccountAge;
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane, ++rowIndex,
|
||||
Res.get("shared.paymentDetails", Res.get("shared.buyer")),
|
||||
paymentDetails + postFix).second.setTooltip(new Tooltip(paymentDetails + postFix));
|
||||
|
@ -261,21 +255,27 @@ public class TradeDetailsWindow extends Overlay<TradeDetailsWindow> {
|
|||
if (sellerPaymentAccountPayload != null) {
|
||||
String paymentDetails = sellerPaymentAccountPayload.getPaymentDetails();
|
||||
String postFix = " / " + sellersAccountAge;
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane, ++rowIndex,
|
||||
Res.get("shared.paymentDetails", Res.get("shared.seller")),
|
||||
paymentDetails + postFix).second.setTooltip(new Tooltip(paymentDetails + postFix));
|
||||
}
|
||||
if (buyerPaymentAccountPayload == null && sellerPaymentAccountPayload == null)
|
||||
if (buyerPaymentAccountPayload == null && sellerPaymentAccountPayload == null) {
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane, ++rowIndex, Res.get("shared.paymentMethod"),
|
||||
Res.get(contract.getPaymentMethodId()));
|
||||
}
|
||||
}
|
||||
|
||||
if (trade.getMaker().getDepositTxHash() != null)
|
||||
if (trade.getMaker().getDepositTxHash() != null) {
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addLabelTxIdTextField(gridPane, ++rowIndex, Res.get("shared.makerDepositTransactionId"),
|
||||
trade.getMaker().getDepositTxHash());
|
||||
if (trade.getTaker().getDepositTxHash() != null)
|
||||
}
|
||||
if (trade.getTaker().getDepositTxHash() != null) {
|
||||
addLabelTxIdTextField(gridPane, ++rowIndex, Res.get("shared.takerDepositTransactionId"),
|
||||
trade.getTaker().getDepositTxHash());
|
||||
}
|
||||
|
||||
|
||||
if (showDisputedTx) {
|
||||
|
@ -287,6 +287,7 @@ public class TradeDetailsWindow extends Overlay<TradeDetailsWindow> {
|
|||
}
|
||||
|
||||
if (trade.hasFailed()) {
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
textArea = addConfirmationLabelTextArea(gridPane, ++rowIndex, Res.get("shared.errorMessage"), "", 0).second;
|
||||
textArea.setText(trade.getErrorMessage());
|
||||
textArea.setEditable(false);
|
||||
|
@ -302,6 +303,7 @@ public class TradeDetailsWindow extends Overlay<TradeDetailsWindow> {
|
|||
textArea.scrollTopProperty().addListener(changeListener);
|
||||
textArea.setScrollTop(30);
|
||||
|
||||
addSeparator(gridPane, ++rowIndex);
|
||||
addConfirmationLabelTextField(gridPane, ++rowIndex, Res.get("tradeDetailsWindow.tradePhase"), trade.getPhase().name());
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ public class TradeFeedbackWindow extends Overlay<TradeFeedbackWindow> {
|
|||
@Override
|
||||
public void show() {
|
||||
headLine(Res.get("tradeFeedbackWindow.title"));
|
||||
message(Res.get("tradeFeedbackWindow.msg.part1"));
|
||||
//message(Res.get("tradeFeedbackWindow.msg.part1")); // TODO: this message part has padding which remaining message does not have
|
||||
hideCloseButton();
|
||||
actionButtonText(Res.get("shared.close"));
|
||||
|
||||
|
@ -51,6 +51,17 @@ public class TradeFeedbackWindow extends Overlay<TradeFeedbackWindow> {
|
|||
protected void addMessage() {
|
||||
super.addMessage();
|
||||
|
||||
AutoTooltipLabel messageLabel1 = new AutoTooltipLabel(Res.get("tradeFeedbackWindow.msg.part1"));
|
||||
messageLabel1.setMouseTransparent(true);
|
||||
messageLabel1.setWrapText(true);
|
||||
GridPane.setHalignment(messageLabel1, HPos.LEFT);
|
||||
GridPane.setHgrow(messageLabel1, Priority.ALWAYS);
|
||||
GridPane.setRowIndex(messageLabel1, ++rowIndex);
|
||||
GridPane.setColumnIndex(messageLabel1, 0);
|
||||
GridPane.setColumnSpan(messageLabel1, 2);
|
||||
gridPane.getChildren().add(messageLabel1);
|
||||
GridPane.setMargin(messageLabel1, new Insets(10, 0, 10, 0));
|
||||
|
||||
AutoTooltipLabel messageLabel2 = new AutoTooltipLabel(Res.get("tradeFeedbackWindow.msg.part2"));
|
||||
messageLabel2.setMouseTransparent(true);
|
||||
messageLabel2.setWrapText(true);
|
||||
|
|
|
@ -30,7 +30,6 @@ import static haveno.desktop.util.FormBuilder.addConfirmationLabelLabel;
|
|||
import static haveno.desktop.util.FormBuilder.addConfirmationLabelTextFieldWithCopyIcon;
|
||||
import static haveno.desktop.util.FormBuilder.addLabelTxIdTextField;
|
||||
import static haveno.desktop.util.FormBuilder.addMultilineLabel;
|
||||
import static haveno.desktop.util.FormBuilder.addTitledGroupBg;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
|
@ -50,21 +49,20 @@ public class TxDetailsWindow extends Overlay<TxDetailsWindow> {
|
|||
this.item = item;
|
||||
rowIndex = -1;
|
||||
width = 918;
|
||||
if (headLine == null)
|
||||
headLine = Res.get("txDetailsWindow.headline");
|
||||
createGridPane();
|
||||
gridPane.setHgap(15);
|
||||
addHeadLine();
|
||||
addContent();
|
||||
addButtons();
|
||||
addDontShowAgainCheckBox();
|
||||
applyStyles();
|
||||
display();
|
||||
}
|
||||
|
||||
protected void addContent() {
|
||||
int rows = 10;
|
||||
MoneroTxWallet tx = item.getTx();
|
||||
String memo = tx.getNote();
|
||||
if (memo != null && !"".equals(memo)) rows++;
|
||||
String txKey = null;
|
||||
boolean isOutgoing = tx.getOutgoingTransfer() != null;
|
||||
if (isOutgoing) {
|
||||
|
@ -74,18 +72,11 @@ public class TxDetailsWindow extends Overlay<TxDetailsWindow> {
|
|||
// TODO (monero-java): wallet.getTxKey() should return null if key does not exist instead of throwing exception
|
||||
}
|
||||
}
|
||||
if (txKey != null && !"".equals(txKey)) rows++;
|
||||
|
||||
// add title
|
||||
addTitledGroupBg(gridPane, ++rowIndex, rows, Res.get("txDetailsWindow.headline"));
|
||||
Region spacer = new Region();
|
||||
spacer.setMinHeight(15);
|
||||
gridPane.add(spacer, 0, ++rowIndex);
|
||||
|
||||
// add sent or received note
|
||||
String resKey = isOutgoing ? "txDetailsWindow.xmr.noteSent" : "txDetailsWindow.xmr.noteReceived";
|
||||
GridPane.setColumnSpan(addMultilineLabel(gridPane, ++rowIndex, Res.get(resKey), 0), 2);
|
||||
spacer = new Region();
|
||||
Region spacer = new Region();
|
||||
spacer.setMinHeight(15);
|
||||
gridPane.add(spacer, 0, ++rowIndex);
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ public class VerifyDisputeResultSignatureWindow extends Overlay<VerifyDisputeRes
|
|||
gridPane.setVgap(5);
|
||||
gridPane.setPadding(new Insets(64, 64, 64, 64));
|
||||
gridPane.setPrefWidth(width);
|
||||
gridPane.getStyleClass().add("popup-with-input");
|
||||
|
||||
ColumnConstraints columnConstraints1 = new ColumnConstraints();
|
||||
columnConstraints1.setHalignment(HPos.RIGHT);
|
||||
|
|
|
@ -80,9 +80,9 @@ public class PortfolioView extends ActivatableView<TabPane, Void> {
|
|||
root.setTabClosingPolicy(TabPane.TabClosingPolicy.ALL_TABS);
|
||||
failedTradesTab.setClosable(false);
|
||||
|
||||
openOffersTab.setText(Res.get("portfolio.tab.openOffers").toUpperCase());
|
||||
pendingTradesTab.setText(Res.get("portfolio.tab.pendingTrades").toUpperCase());
|
||||
closedTradesTab.setText(Res.get("portfolio.tab.history").toUpperCase());
|
||||
openOffersTab.setText(Res.get("portfolio.tab.openOffers"));
|
||||
pendingTradesTab.setText(Res.get("portfolio.tab.pendingTrades"));
|
||||
closedTradesTab.setText(Res.get("portfolio.tab.history"));
|
||||
|
||||
navigationListener = (viewPath, data) -> {
|
||||
if (viewPath.size() == 3 && viewPath.indexOf(PortfolioView.class) == 1)
|
||||
|
|
|
@ -156,6 +156,8 @@ public class ClosedTradesView extends ActivatableViewAndModel<VBox, ClosedTrades
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
GUIUtil.applyTableStyle(tableView);
|
||||
|
||||
widthListener = (observable, oldValue, newValue) -> onWidthChange((double) newValue);
|
||||
tradeFeeColumn.setGraphic(new AutoTooltipLabel(ColumnNames.TRADE_FEE.toString().replace(" BTC", "")));
|
||||
buyerSecurityDepositColumn.setGraphic(new AutoTooltipLabel(ColumnNames.BUYER_SEC.toString()));
|
||||
|
@ -252,6 +254,7 @@ public class ClosedTradesView extends ActivatableViewAndModel<VBox, ClosedTrades
|
|||
tableView.setItems(sortedList);
|
||||
|
||||
filterBox.initialize(filteredList, tableView); // here because filteredList is instantiated here
|
||||
filterBox.setPromptText(Res.get("shared.filter"));
|
||||
filterBox.activate();
|
||||
|
||||
numItems.setText(Res.get("shared.numItemsLabel", sortedList.size()));
|
||||
|
@ -326,7 +329,6 @@ public class ClosedTradesView extends ActivatableViewAndModel<VBox, ClosedTrades
|
|||
}
|
||||
|
||||
private void setTradeIdColumnCellFactory() {
|
||||
tradeIdColumn.getStyleClass().add("first-column");
|
||||
tradeIdColumn.setCellValueFactory((offerListItem) -> new ReadOnlyObjectWrapper<>(offerListItem.getValue()));
|
||||
tradeIdColumn.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
@ -463,7 +465,7 @@ public class ClosedTradesView extends ActivatableViewAndModel<VBox, ClosedTrades
|
|||
|
||||
@SuppressWarnings("UnusedReturnValue")
|
||||
private TableColumn<ClosedTradesListItem, ClosedTradesListItem> setAvatarColumnCellFactory() {
|
||||
avatarColumn.getStyleClass().addAll("last-column", "avatar-column");
|
||||
avatarColumn.getStyleClass().add("avatar-column");
|
||||
avatarColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue()));
|
||||
avatarColumn.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
@ -696,7 +698,7 @@ public class ClosedTradesView extends ActivatableViewAndModel<VBox, ClosedTrades
|
|||
if (!empty && newItem != null && !trade.isPayoutConfirmed()) {
|
||||
Label icon = FormBuilder.getIcon(AwesomeIcon.UNDO);
|
||||
JFXButton iconButton = new JFXButton("", icon);
|
||||
iconButton.setStyle("-fx-cursor: hand;");
|
||||
iconButton.setStyle("-fx-cursor: hand; -fx-padding: 0 10 0 10;");
|
||||
iconButton.getStyleClass().add("hidden-icon-button");
|
||||
iconButton.setTooltip(new Tooltip(Res.get("portfolio.failed.revertToPending")));
|
||||
iconButton.setOnAction(e -> onRevertTrade(trade));
|
||||
|
|
|
@ -115,6 +115,8 @@ public class FailedTradesView extends ActivatableViewAndModel<VBox, FailedTrades
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
GUIUtil.applyTableStyle(tableView);
|
||||
|
||||
priceColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.price")));
|
||||
amountColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.amountWithCur", Res.getBaseCurrencyCode())));
|
||||
volumeColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.amount")));
|
||||
|
@ -385,7 +387,6 @@ public class FailedTradesView extends ActivatableViewAndModel<VBox, FailedTrades
|
|||
}
|
||||
|
||||
private void setTradeIdColumnCellFactory() {
|
||||
tradeIdColumn.getStyleClass().add("first-column");
|
||||
tradeIdColumn.setCellValueFactory((offerListItem) -> new ReadOnlyObjectWrapper<>(offerListItem.getValue()));
|
||||
tradeIdColumn.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
@ -455,7 +456,6 @@ public class FailedTradesView extends ActivatableViewAndModel<VBox, FailedTrades
|
|||
}
|
||||
|
||||
private void setStateColumnCellFactory() {
|
||||
stateColumn.getStyleClass().add("last-column");
|
||||
stateColumn.setCellValueFactory((trade) -> new ReadOnlyObjectWrapper<>(trade.getValue()));
|
||||
stateColumn.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
<Insets bottom="15.0" left="15.0" right="15.0" top="15.0"/>
|
||||
</padding>
|
||||
<HBox fx:id="searchBox">
|
||||
<AutoTooltipLabel fx:id="filterLabel"/>
|
||||
<InputTextField fx:id="filterTextField" minWidth="500"/>
|
||||
<Pane fx:id="searchBoxSpacer"/>
|
||||
<AutoTooltipSlideToggleButton fx:id="selectToggleButton"/>
|
||||
|
|
|
@ -116,8 +116,6 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
@FXML
|
||||
HBox searchBox;
|
||||
@FXML
|
||||
AutoTooltipLabel filterLabel;
|
||||
@FXML
|
||||
InputTextField filterTextField;
|
||||
@FXML
|
||||
Pane searchBoxSpacer;
|
||||
|
@ -156,6 +154,8 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
GUIUtil.applyTableStyle(tableView);
|
||||
|
||||
widthListener = (observable, oldValue, newValue) -> onWidthChange((double) newValue);
|
||||
groupIdColumn.setGraphic(new AutoTooltipLabel(ColumnNames.GROUP_ID.toString()));
|
||||
paymentMethodColumn.setGraphic(new AutoTooltipLabel(ColumnNames.PAYMENT_METHOD.toString()));
|
||||
|
@ -231,8 +231,7 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
return row;
|
||||
});
|
||||
|
||||
filterLabel.setText(Res.get("shared.filter"));
|
||||
HBox.setMargin(filterLabel, new Insets(5, 0, 0, 10));
|
||||
filterTextField.setPromptText(Res.get("shared.filter"));
|
||||
filterTextFieldListener = (observable, oldValue, newValue) -> applyFilteredListPredicate(filterTextField.getText());
|
||||
searchBox.setSpacing(5);
|
||||
HBox.setHgrow(searchBoxSpacer, Priority.ALWAYS);
|
||||
|
@ -470,8 +469,8 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
|
||||
String key = "WithdrawFundsAfterRemoveOfferInfo";
|
||||
if (DontShowAgainLookup.showAgain(key)) {
|
||||
new Popup().instruction(Res.get("offerbook.withdrawFundsHint", Res.get("navigation.funds.availableForWithdrawal")))
|
||||
.actionButtonTextWithGoTo("navigation.funds.availableForWithdrawal")
|
||||
new Popup().instruction(Res.get("offerbook.withdrawFundsHint", Res.get("funds.tab.withdrawal")))
|
||||
.actionButtonTextWithGoTo("funds.tab.withdrawal")
|
||||
.onAction(() -> navigation.navigateTo(MainView.class, FundsView.class, WithdrawalView.class))
|
||||
.dontShowAgainId(key)
|
||||
.show();
|
||||
|
@ -527,7 +526,7 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
|
||||
private void setOfferIdColumnCellFactory() {
|
||||
offerIdColumn.setCellValueFactory((openOfferListItem) -> new ReadOnlyObjectWrapper<>(openOfferListItem.getValue()));
|
||||
offerIdColumn.getStyleClass().addAll("number-column", "first-column");
|
||||
offerIdColumn.getStyleClass().addAll("number-column");
|
||||
offerIdColumn.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
||||
|
@ -903,7 +902,7 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
}
|
||||
|
||||
private void setRemoveColumnCellFactory() {
|
||||
removeItemColumn.getStyleClass().addAll("last-column", "avatar-column");
|
||||
removeItemColumn.getStyleClass().addAll("avatar-column");
|
||||
removeItemColumn.setCellValueFactory((offerListItem) -> new ReadOnlyObjectWrapper<>(offerListItem.getValue()));
|
||||
removeItemColumn.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
|
|
@ -55,6 +55,7 @@ import haveno.desktop.main.shared.ChatView;
|
|||
import haveno.desktop.util.CssTheme;
|
||||
import haveno.desktop.util.DisplayUtils;
|
||||
import haveno.desktop.util.FormBuilder;
|
||||
import haveno.desktop.util.GUIUtil;
|
||||
import haveno.network.p2p.NodeAddress;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
|
@ -171,6 +172,8 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
GUIUtil.applyTableStyle(tableView);
|
||||
|
||||
priceColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.price")));
|
||||
amountColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.amountWithCur", Res.getBaseCurrencyCode())));
|
||||
volumeColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.amount")));
|
||||
|
@ -281,6 +284,7 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
|
|||
tableView.setMaxHeight(200);
|
||||
|
||||
filterBox.initialize(filteredList, tableView); // here because filteredList is instantiated here
|
||||
filterBox.setPromptText(Res.get("shared.filter"));
|
||||
filterBox.activate();
|
||||
|
||||
updateMoveTradeToFailedColumnState();
|
||||
|
@ -607,7 +611,6 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void setTradeIdColumnCellFactory() {
|
||||
tradeIdColumn.getStyleClass().add("first-column");
|
||||
tradeIdColumn.setCellValueFactory((pendingTradesListItem) -> new ReadOnlyObjectWrapper<>(pendingTradesListItem.getValue()));
|
||||
tradeIdColumn.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
@ -821,7 +824,7 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
|
|||
@SuppressWarnings("UnusedReturnValue")
|
||||
private TableColumn<PendingTradesListItem, PendingTradesListItem> setAvatarColumnCellFactory() {
|
||||
avatarColumn.setCellValueFactory((trade) -> new ReadOnlyObjectWrapper<>(trade.getValue()));
|
||||
avatarColumn.getStyleClass().addAll("last-column", "avatar-column");
|
||||
avatarColumn.getStyleClass().add("avatar-column");
|
||||
avatarColumn.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
||||
|
@ -860,7 +863,7 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
|
|||
@SuppressWarnings("UnusedReturnValue")
|
||||
private TableColumn<PendingTradesListItem, PendingTradesListItem> setChatColumnCellFactory() {
|
||||
chatColumn.setCellValueFactory((trade) -> new ReadOnlyObjectWrapper<>(trade.getValue()));
|
||||
chatColumn.getStyleClass().addAll("last-column", "avatar-column");
|
||||
chatColumn.getStyleClass().addAll("avatar-column");
|
||||
chatColumn.setSortable(false);
|
||||
chatColumn.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
|
|
@ -125,6 +125,7 @@ public abstract class TradeStepView extends AnchorPane {
|
|||
|
||||
gridPane.setHgap(Layout.GRID_GAP);
|
||||
gridPane.setVgap(Layout.GRID_GAP);
|
||||
gridPane.setPadding(new Insets(0, 0, 25, 0));
|
||||
ColumnConstraints columnConstraints1 = new ColumnConstraints();
|
||||
columnConstraints1.setHgrow(Priority.ALWAYS);
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ public class BuyerStep4View extends TradeStepView {
|
|||
if (!DevEnv.isDevMode()) {
|
||||
UserThread.runAfter(() -> new Popup().headLine(Res.get("portfolio.pending.step5_buyer.tradeCompleted.headline"))
|
||||
.feedback(Res.get("portfolio.pending.step5_buyer.tradeCompleted.msg"))
|
||||
.actionButtonTextWithGoTo("navigation.portfolio.closedTrades")
|
||||
.actionButtonTextWithGoTo("portfolio.tab.history")
|
||||
.onAction(() -> model.dataModel.navigation.navigateTo(MainView.class, PortfolioView.class, ClosedTradesView.class))
|
||||
.dontShowAgainId("tradeCompleteWithdrawCompletedInfo")
|
||||
.show(), 500, TimeUnit.MILLISECONDS);
|
||||
|
|
|
@ -56,9 +56,9 @@ public class SettingsView extends ActivatableView<TabPane, Void> {
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
preferencesTab.setText(Res.get("settings.tab.preferences").toUpperCase());
|
||||
networkTab.setText(Res.get("settings.tab.network").toUpperCase());
|
||||
aboutTab.setText(Res.get("settings.tab.about").toUpperCase());
|
||||
preferencesTab.setText(Res.get("settings.tab.preferences"));
|
||||
networkTab.setText(Res.get("settings.tab.network"));
|
||||
aboutTab.setText(Res.get("settings.tab.about"));
|
||||
|
||||
navigationListener = (viewPath, data) -> {
|
||||
if (viewPath.size() == 3 && viewPath.indexOf(SettingsView.class) == 1)
|
||||
|
|
|
@ -19,6 +19,7 @@ package haveno.desktop.main.settings.about;
|
|||
|
||||
import com.google.inject.Inject;
|
||||
import haveno.common.app.Version;
|
||||
import haveno.core.filter.FilterManager;
|
||||
import haveno.core.locale.Res;
|
||||
import haveno.desktop.common.view.ActivatableView;
|
||||
import haveno.desktop.common.view.FxmlView;
|
||||
|
@ -35,16 +36,18 @@ import javafx.scene.layout.GridPane;
|
|||
@FxmlView
|
||||
public class AboutView extends ActivatableView<GridPane, Void> {
|
||||
|
||||
private final FilterManager filterManager;
|
||||
private int gridRow = 0;
|
||||
|
||||
@Inject
|
||||
public AboutView() {
|
||||
public AboutView(FilterManager filterManager) {
|
||||
super();
|
||||
this.filterManager = filterManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
addTitledGroupBg(root, gridRow, 4, Res.get("setting.about.aboutHaveno"));
|
||||
addTitledGroupBg(root, gridRow, 5, Res.get("setting.about.aboutHaveno"));
|
||||
|
||||
Label label = addLabel(root, gridRow, Res.get("setting.about.about"), Layout.TWICE_FIRST_ROW_DISTANCE);
|
||||
label.setWrapText(true);
|
||||
|
@ -77,8 +80,11 @@ public class AboutView extends ActivatableView<GridPane, Void> {
|
|||
if (isXmr)
|
||||
addCompactTopLabelTextField(root, ++gridRow, Res.get("setting.about.feeEstimation.label"), "Monero node");
|
||||
|
||||
addTitledGroupBg(root, ++gridRow, 2, Res.get("setting.about.versionDetails"), Layout.GROUP_DISTANCE);
|
||||
String minVersion = filterManager.getDisableTradeBelowVersion() == null ? Res.get("shared.none") : filterManager.getDisableTradeBelowVersion();
|
||||
|
||||
addTitledGroupBg(root, ++gridRow, 3, Res.get("setting.about.versionDetails"), Layout.GROUP_DISTANCE);
|
||||
addCompactTopLabelTextField(root, gridRow, Res.get("setting.about.version"), Version.VERSION, Layout.TWICE_FIRST_ROW_AND_GROUP_DISTANCE);
|
||||
addCompactTopLabelTextField(root, ++gridRow, Res.get("filterWindow.disableTradeBelowVersion"), minVersion);
|
||||
addCompactTopLabelTextField(root, ++gridRow,
|
||||
Res.get("setting.about.subsystems.label"),
|
||||
Res.get("setting.about.subsystems.val",
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
<PropertyValueFactory property="address"/>
|
||||
</cellValueFactory>
|
||||
</TableColumn>
|
||||
<TableColumn fx:id="moneroConnectionConnectedColumn" minWidth="80" maxWidth="90">
|
||||
<TableColumn fx:id="moneroConnectionConnectedColumn" minWidth="80" maxWidth="110">
|
||||
<cellValueFactory>
|
||||
<PropertyValueFactory property="connected"/>
|
||||
</cellValueFactory>
|
||||
|
@ -108,6 +108,9 @@
|
|||
</HavenoTextField>
|
||||
|
||||
<VBox GridPane.rowIndex="6" GridPane.hgrow="ALWAYS" GridPane.vgrow="SOMETIMES">
|
||||
<GridPane.margin>
|
||||
<Insets top="0" right="0" bottom="10" left="0"/>
|
||||
</GridPane.margin>
|
||||
<AutoTooltipLabel fx:id="p2PPeersLabel" styleClass="small-text"/>
|
||||
<TableView fx:id="p2pPeersTableView">
|
||||
<columns>
|
||||
|
@ -159,10 +162,7 @@
|
|||
<HavenoTextField fx:id="chainHeightTextField" GridPane.rowIndex="9" editable="false"
|
||||
focusTraversable="false" labelFloat="true"/>
|
||||
|
||||
<HavenoTextField fx:id="minVersionForTrading" GridPane.rowIndex="10" editable="false"
|
||||
focusTraversable="false" labelFloat="true"/>
|
||||
|
||||
<AutoTooltipButton fx:id="openTorSettingsButton" GridPane.rowIndex="11" GridPane.columnIndex="0"/>
|
||||
<AutoTooltipButton fx:id="openTorSettingsButton" GridPane.rowIndex="10" GridPane.columnIndex="0"/>
|
||||
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="ALWAYS" minWidth="500"/>
|
||||
|
|
|
@ -75,7 +75,7 @@ public class NetworkSettingsView extends ActivatableView<GridPane, Void> {
|
|||
@FXML
|
||||
InputTextField xmrNodesInputTextField;
|
||||
@FXML
|
||||
TextField onionAddress, sentDataTextField, receivedDataTextField, chainHeightTextField, minVersionForTrading;
|
||||
TextField onionAddress, sentDataTextField, receivedDataTextField, chainHeightTextField;
|
||||
@FXML
|
||||
Label p2PPeersLabel, moneroConnectionsLabel;
|
||||
@FXML
|
||||
|
@ -149,6 +149,14 @@ public class NetworkSettingsView extends ActivatableView<GridPane, Void> {
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
GUIUtil.applyTableStyle(p2pPeersTableView);
|
||||
GUIUtil.applyTableStyle(moneroConnectionsTableView);
|
||||
|
||||
onionAddress.getStyleClass().add("label-float");
|
||||
sentDataTextField.getStyleClass().add("label-float");
|
||||
receivedDataTextField.getStyleClass().add("label-float");
|
||||
chainHeightTextField.getStyleClass().add("label-float");
|
||||
|
||||
btcHeader.setText(Res.get("settings.net.xmrHeader"));
|
||||
p2pHeader.setText(Res.get("settings.net.p2pHeader"));
|
||||
onionAddress.setPromptText(Res.get("settings.net.onionAddressLabel"));
|
||||
|
@ -160,7 +168,6 @@ public class NetworkSettingsView extends ActivatableView<GridPane, Void> {
|
|||
useTorForXmrOnRadio.setText(Res.get("settings.net.useTorForXmrOnRadio"));
|
||||
moneroNodesLabel.setText(Res.get("settings.net.moneroNodesLabel"));
|
||||
moneroConnectionAddressColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.address")));
|
||||
moneroConnectionAddressColumn.getStyleClass().add("first-column");
|
||||
moneroConnectionConnectedColumn.setGraphic(new AutoTooltipLabel(Res.get("settings.net.connection")));
|
||||
localhostXmrNodeInfoLabel.setText(Res.get("settings.net.localhostXmrNodeInfo"));
|
||||
useProvidedNodesRadio.setText(Res.get("settings.net.useProvidedNodesRadio"));
|
||||
|
@ -170,18 +177,15 @@ public class NetworkSettingsView extends ActivatableView<GridPane, Void> {
|
|||
rescanOutputsButton.updateText(Res.get("settings.net.rescanOutputsButton"));
|
||||
p2PPeersLabel.setText(Res.get("settings.net.p2PPeersLabel"));
|
||||
onionAddressColumn.setGraphic(new AutoTooltipLabel(Res.get("settings.net.onionAddressColumn")));
|
||||
onionAddressColumn.getStyleClass().add("first-column");
|
||||
creationDateColumn.setGraphic(new AutoTooltipLabel(Res.get("settings.net.creationDateColumn")));
|
||||
connectionTypeColumn.setGraphic(new AutoTooltipLabel(Res.get("settings.net.connectionTypeColumn")));
|
||||
sentDataTextField.setPromptText(Res.get("settings.net.sentDataLabel"));
|
||||
receivedDataTextField.setPromptText(Res.get("settings.net.receivedDataLabel"));
|
||||
chainHeightTextField.setPromptText(Res.get("settings.net.chainHeightLabel"));
|
||||
minVersionForTrading.setPromptText(Res.get("filterWindow.disableTradeBelowVersion"));
|
||||
roundTripTimeColumn.setGraphic(new AutoTooltipLabel(Res.get("settings.net.roundTripTimeColumn")));
|
||||
sentBytesColumn.setGraphic(new AutoTooltipLabel(Res.get("settings.net.sentBytesColumn")));
|
||||
receivedBytesColumn.setGraphic(new AutoTooltipLabel(Res.get("settings.net.receivedBytesColumn")));
|
||||
peerTypeColumn.setGraphic(new AutoTooltipLabel(Res.get("settings.net.peerTypeColumn")));
|
||||
peerTypeColumn.getStyleClass().add("last-column");
|
||||
openTorSettingsButton.updateText(Res.get("settings.net.openTorSettingsButton"));
|
||||
|
||||
// TODO: hiding button to rescan outputs until supported
|
||||
|
@ -504,10 +508,6 @@ public class NetworkSettingsView extends ActivatableView<GridPane, Void> {
|
|||
selectMoneroPeersToggle();
|
||||
onMoneroPeersToggleSelected(false);
|
||||
}
|
||||
|
||||
// set min version for trading
|
||||
String minVersion = filterManager.getDisableTradeBelowVersion();
|
||||
minVersionForTrading.textProperty().setValue(minVersion == null ? Res.get("shared.none") : minVersion);
|
||||
}
|
||||
|
||||
private boolean isPublicNodesDisabled() {
|
||||
|
|
|
@ -102,7 +102,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||
@FxmlView
|
||||
public class PreferencesView extends ActivatableViewAndModel<GridPane, PreferencesViewModel> {
|
||||
private final User user;
|
||||
private TextField btcExplorerTextField;
|
||||
private TextField xmrExplorerTextField;
|
||||
private ComboBox<String> userLanguageComboBox;
|
||||
private ComboBox<Country> userCountryComboBox;
|
||||
private ComboBox<TradeCurrency> preferredTradeCurrencyComboBox;
|
||||
|
@ -220,9 +220,9 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
|||
userCountryComboBox.setButtonCell(GUIUtil.getComboBoxButtonCell(Res.get("shared.country"), userCountryComboBox,
|
||||
false));
|
||||
|
||||
Tuple2<TextField, Button> btcExp = addTextFieldWithEditButton(root, ++gridRow, Res.get("setting.preferences.explorer"));
|
||||
btcExplorerTextField = btcExp.first;
|
||||
editCustomBtcExplorer = btcExp.second;
|
||||
Tuple2<TextField, Button> xmrExp = addTextFieldWithEditButton(root, ++gridRow, Res.get("setting.preferences.explorer"));
|
||||
xmrExplorerTextField = xmrExp.first;
|
||||
editCustomBtcExplorer = xmrExp.second;
|
||||
|
||||
// deviation
|
||||
deviationInputTextField = addInputTextField(root, ++gridRow,
|
||||
|
@ -688,7 +688,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
|||
}
|
||||
});
|
||||
|
||||
btcExplorerTextField.setText(preferences.getBlockChainExplorer().name);
|
||||
xmrExplorerTextField.setText(preferences.getBlockChainExplorer().name);
|
||||
|
||||
deviationInputTextField.setText(FormattingUtils.formatToPercentWithSymbol(preferences.getMaxPriceDistanceInPercent()));
|
||||
deviationInputTextField.textProperty().addListener(deviationListener);
|
||||
|
@ -779,7 +779,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
|||
.actionButtonText(Res.get("shared.save"))
|
||||
.onAction(() -> {
|
||||
preferences.setBlockChainExplorer(urlWindow.getEditedBlockChainExplorer());
|
||||
btcExplorerTextField.setText(preferences.getBlockChainExplorer().name);
|
||||
xmrExplorerTextField.setText(preferences.getBlockChainExplorer().name);
|
||||
})
|
||||
.closeButtonText(Res.get("shared.cancel"))
|
||||
.onClose(urlWindow::hide)
|
||||
|
|
|
@ -26,7 +26,7 @@ import haveno.desktop.main.overlays.notifications.Notification;
|
|||
import haveno.desktop.main.overlays.popups.Popup;
|
||||
import haveno.desktop.util.DisplayUtils;
|
||||
import haveno.desktop.util.GUIUtil;
|
||||
|
||||
import haveno.desktop.util.Layout;
|
||||
import haveno.core.locale.Res;
|
||||
import haveno.core.support.SupportManager;
|
||||
import haveno.core.support.SupportSession;
|
||||
|
@ -43,7 +43,8 @@ import com.google.common.io.ByteStreams;
|
|||
|
||||
import de.jensd.fx.fontawesome.AwesomeDude;
|
||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
|
||||
import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIcon;
|
||||
import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIconView;
|
||||
import javafx.stage.FileChooser;
|
||||
|
||||
import javafx.scene.Node;
|
||||
|
@ -204,6 +205,7 @@ public class ChatView extends AnchorPane {
|
|||
inputTextArea = new HavenoTextArea();
|
||||
inputTextArea.setPrefHeight(70);
|
||||
inputTextArea.setWrapText(true);
|
||||
inputTextArea.getStyleClass().add("input-with-border");
|
||||
|
||||
if (!supportSession.isDisputeAgent()) {
|
||||
inputTextArea.setPromptText(Res.get("support.input.prompt"));
|
||||
|
@ -271,7 +273,7 @@ public class ChatView extends AnchorPane {
|
|||
ImageView arrow = new ImageView();
|
||||
Label headerLabel = new AutoTooltipLabel();
|
||||
Label messageLabel = new AutoTooltipLabel();
|
||||
Label copyIcon = new Label();
|
||||
Label copyLabel = new Label();
|
||||
HBox attachmentsBox = new HBox();
|
||||
AnchorPane messageAnchorPane = new AnchorPane();
|
||||
Label statusIcon = new Label();
|
||||
|
@ -292,10 +294,10 @@ public class ChatView extends AnchorPane {
|
|||
statusIcon.getStyleClass().add("small-text");
|
||||
statusInfoLabel.getStyleClass().add("small-text");
|
||||
statusInfoLabel.setPadding(new Insets(3, 0, 0, 0));
|
||||
copyIcon.setTooltip(new Tooltip(Res.get("shared.copyToClipboard")));
|
||||
copyLabel.setTooltip(new Tooltip(Res.get("shared.copyToClipboard")));
|
||||
statusHBox.setSpacing(5);
|
||||
statusHBox.getChildren().addAll(statusIcon, statusInfoLabel);
|
||||
messageAnchorPane.getChildren().addAll(bg, arrow, headerLabel, messageLabel, copyIcon, attachmentsBox, statusHBox);
|
||||
messageAnchorPane.getChildren().addAll(bg, arrow, headerLabel, messageLabel, copyLabel, attachmentsBox, statusHBox);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -303,7 +305,13 @@ public class ChatView extends AnchorPane {
|
|||
UserThread.execute(() -> {
|
||||
super.updateItem(message, empty);
|
||||
if (message != null && !empty) {
|
||||
copyIcon.setOnMouseClicked(e -> Utilities.copyToClipboard(messageLabel.getText()));
|
||||
copyLabel.setOnMouseClicked(e -> {
|
||||
Utilities.copyToClipboard(messageLabel.getText());
|
||||
Tooltip tp = new Tooltip(Res.get("shared.copiedToClipboard"));
|
||||
Node node = (Node) e.getSource();
|
||||
UserThread.runAfter(() -> tp.hide(), 1);
|
||||
tp.show(node, e.getScreenX() + Layout.PADDING, e.getScreenY() + Layout.PADDING);
|
||||
});
|
||||
messageLabel.setOnMouseClicked(event -> {
|
||||
if (2 > event.getClickCount()) {
|
||||
return;
|
||||
|
@ -319,7 +327,7 @@ public class ChatView extends AnchorPane {
|
|||
AnchorPane.clearConstraints(headerLabel);
|
||||
AnchorPane.clearConstraints(arrow);
|
||||
AnchorPane.clearConstraints(messageLabel);
|
||||
AnchorPane.clearConstraints(copyIcon);
|
||||
AnchorPane.clearConstraints(copyLabel);
|
||||
AnchorPane.clearConstraints(statusHBox);
|
||||
AnchorPane.clearConstraints(attachmentsBox);
|
||||
|
||||
|
@ -328,7 +336,7 @@ public class ChatView extends AnchorPane {
|
|||
AnchorPane.setTopAnchor(headerLabel, 0d);
|
||||
AnchorPane.setBottomAnchor(arrow, bottomBorder + 5d);
|
||||
AnchorPane.setTopAnchor(messageLabel, 25d);
|
||||
AnchorPane.setTopAnchor(copyIcon, 25d);
|
||||
AnchorPane.setTopAnchor(copyLabel, 25d);
|
||||
AnchorPane.setBottomAnchor(attachmentsBox, bottomBorder + 10);
|
||||
|
||||
boolean senderIsTrader = message.isSenderIsTrader();
|
||||
|
@ -341,20 +349,20 @@ public class ChatView extends AnchorPane {
|
|||
headerLabel.getStyleClass().removeAll("message-header", "my-message-header", "success-text",
|
||||
"highlight-static");
|
||||
messageLabel.getStyleClass().removeAll("my-message", "message");
|
||||
copyIcon.getStyleClass().removeAll("my-message", "message");
|
||||
copyLabel.getStyleClass().removeAll("my-message", "message");
|
||||
|
||||
if (message.isSystemMessage()) {
|
||||
headerLabel.getStyleClass().addAll("message-header", "success-text");
|
||||
bg.setId("message-bubble-green");
|
||||
messageLabel.getStyleClass().add("my-message");
|
||||
copyIcon.getStyleClass().add("my-message");
|
||||
copyLabel.getStyleClass().add("my-message");
|
||||
message.addWeakMessageStateListener(() -> UserThread.execute(() -> updateMsgState(message)));
|
||||
updateMsgState(message);
|
||||
} else if (isMyMsg) {
|
||||
headerLabel.getStyleClass().add("my-message-header");
|
||||
bg.setId("message-bubble-blue");
|
||||
messageLabel.getStyleClass().add("my-message");
|
||||
copyIcon.getStyleClass().add("my-message");
|
||||
copyLabel.getStyleClass().add("my-message");
|
||||
if (supportSession.isClient())
|
||||
arrow.setId("bubble_arrow_blue_left");
|
||||
else
|
||||
|
@ -375,7 +383,7 @@ public class ChatView extends AnchorPane {
|
|||
headerLabel.getStyleClass().add("message-header");
|
||||
bg.setId("message-bubble-grey");
|
||||
messageLabel.getStyleClass().add("message");
|
||||
copyIcon.getStyleClass().add("message");
|
||||
copyLabel.getStyleClass().add("message");
|
||||
if (supportSession.isClient())
|
||||
arrow.setId("bubble_arrow_grey_right");
|
||||
else
|
||||
|
@ -389,7 +397,7 @@ public class ChatView extends AnchorPane {
|
|||
AnchorPane.setRightAnchor(bg, border);
|
||||
AnchorPane.setLeftAnchor(messageLabel, padding);
|
||||
AnchorPane.setRightAnchor(messageLabel, msgLabelPaddingRight);
|
||||
AnchorPane.setRightAnchor(copyIcon, padding);
|
||||
AnchorPane.setRightAnchor(copyLabel, padding);
|
||||
AnchorPane.setLeftAnchor(attachmentsBox, padding);
|
||||
AnchorPane.setRightAnchor(attachmentsBox, padding);
|
||||
AnchorPane.setLeftAnchor(statusHBox, padding);
|
||||
|
@ -400,7 +408,7 @@ public class ChatView extends AnchorPane {
|
|||
AnchorPane.setLeftAnchor(arrow, border);
|
||||
AnchorPane.setLeftAnchor(messageLabel, padding + arrowWidth);
|
||||
AnchorPane.setRightAnchor(messageLabel, msgLabelPaddingRight);
|
||||
AnchorPane.setRightAnchor(copyIcon, padding);
|
||||
AnchorPane.setRightAnchor(copyLabel, padding);
|
||||
AnchorPane.setLeftAnchor(attachmentsBox, padding + arrowWidth);
|
||||
AnchorPane.setRightAnchor(attachmentsBox, padding);
|
||||
AnchorPane.setRightAnchor(statusHBox, padding);
|
||||
|
@ -411,7 +419,7 @@ public class ChatView extends AnchorPane {
|
|||
AnchorPane.setRightAnchor(arrow, border);
|
||||
AnchorPane.setLeftAnchor(messageLabel, padding);
|
||||
AnchorPane.setRightAnchor(messageLabel, msgLabelPaddingRight + arrowWidth);
|
||||
AnchorPane.setRightAnchor(copyIcon, padding + arrowWidth);
|
||||
AnchorPane.setRightAnchor(copyLabel, padding + arrowWidth);
|
||||
AnchorPane.setLeftAnchor(attachmentsBox, padding);
|
||||
AnchorPane.setRightAnchor(attachmentsBox, padding + arrowWidth);
|
||||
AnchorPane.setLeftAnchor(statusHBox, padding);
|
||||
|
@ -454,8 +462,9 @@ public class ChatView extends AnchorPane {
|
|||
}
|
||||
|
||||
// Need to set it here otherwise style is not correct
|
||||
AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY, "16.0");
|
||||
copyIcon.getStyleClass().addAll("icon", "copy-icon-disputes");
|
||||
copyLabel.getStyleClass().addAll("icon", "copy-icon-disputes");
|
||||
MaterialDesignIconView copyIcon = new MaterialDesignIconView(MaterialDesignIcon.CONTENT_COPY, "16.0");
|
||||
copyLabel.setGraphic(copyIcon);
|
||||
|
||||
// TODO There are still some cell rendering issues on updates
|
||||
setGraphic(messageAnchorPane);
|
||||
|
@ -465,7 +474,7 @@ public class ChatView extends AnchorPane {
|
|||
|
||||
messageAnchorPane.prefWidthProperty().unbind();
|
||||
|
||||
copyIcon.setOnMouseClicked(null);
|
||||
copyLabel.setOnMouseClicked(null);
|
||||
messageLabel.setOnMouseClicked(null);
|
||||
setGraphic(null);
|
||||
}
|
||||
|
|
|
@ -139,9 +139,9 @@ public class SupportView extends ActivatableView<TabPane, Void> {
|
|||
// Has to be called before loadView
|
||||
updateAgentTabs();
|
||||
|
||||
tradersMediationDisputesTab.setText(Res.get("support.tab.mediation.support").toUpperCase());
|
||||
tradersRefundDisputesTab.setText(Res.get("support.tab.refund.support").toUpperCase());
|
||||
tradersArbitrationDisputesTab.setText(Res.get("support.tab.arbitration.support").toUpperCase());
|
||||
tradersMediationDisputesTab.setText(Res.get("support.tab.mediation.support"));
|
||||
tradersRefundDisputesTab.setText(Res.get("support.tab.refund.support"));
|
||||
tradersArbitrationDisputesTab.setText(Res.get("support.tab.arbitration.support"));
|
||||
|
||||
navigationListener = (viewPath, data) -> {
|
||||
if (viewPath.size() == 3 && viewPath.indexOf(SupportView.class) == 1)
|
||||
|
@ -221,16 +221,16 @@ public class SupportView extends ActivatableView<TabPane, Void> {
|
|||
|
||||
// We might get that method called before we have the map is filled in the arbitratorManager
|
||||
if (arbitratorTab != null) {
|
||||
arbitratorTab.setText(Res.get("support.tab.ArbitratorsSupportTickets", Res.get("shared.arbitrator")).toUpperCase());
|
||||
arbitratorTab.setText(Res.get("support.tab.ArbitratorsSupportTickets", Res.get("shared.arbitrator")));
|
||||
}
|
||||
if (signedOfferTab != null) {
|
||||
signedOfferTab.setText(Res.get("support.tab.SignedOffers").toUpperCase());
|
||||
signedOfferTab.setText(Res.get("support.tab.SignedOffers"));
|
||||
}
|
||||
if (mediatorTab != null) {
|
||||
mediatorTab.setText(Res.get("support.tab.ArbitratorsSupportTickets", Res.get("shared.mediator")).toUpperCase());
|
||||
mediatorTab.setText(Res.get("support.tab.ArbitratorsSupportTickets", Res.get("shared.mediator")));
|
||||
}
|
||||
if (refundAgentTab != null) {
|
||||
refundAgentTab.setText(Res.get("support.tab.ArbitratorsSupportTickets", Res.get("shared.refundAgentForSupportStaff")).toUpperCase());
|
||||
refundAgentTab.setText(Res.get("support.tab.ArbitratorsSupportTickets", Res.get("shared.refundAgentForSupportStaff")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -223,12 +223,8 @@ public abstract class DisputeView extends ActivatableView<VBox, Void> implements
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
Label label = new AutoTooltipLabel(Res.get("support.filter"));
|
||||
HBox.setMargin(label, new Insets(5, 0, 0, 0));
|
||||
HBox.setHgrow(label, Priority.NEVER);
|
||||
|
||||
filterTextField = new InputTextField();
|
||||
filterTextField.setPromptText(Res.get("support.filter.prompt"));
|
||||
filterTextField.setPromptText(Res.get("shared.filter"));
|
||||
Tooltip tooltip = new Tooltip();
|
||||
tooltip.setShowDelay(Duration.millis(100));
|
||||
tooltip.setShowDuration(Duration.seconds(10));
|
||||
|
@ -298,8 +294,7 @@ public abstract class DisputeView extends ActivatableView<VBox, Void> implements
|
|||
|
||||
HBox filterBox = new HBox();
|
||||
filterBox.setSpacing(5);
|
||||
filterBox.getChildren().addAll(label,
|
||||
filterTextField,
|
||||
filterBox.getChildren().addAll(filterTextField,
|
||||
alertIconLabel,
|
||||
spacer,
|
||||
reOpenButton,
|
||||
|
@ -311,6 +306,7 @@ public abstract class DisputeView extends ActivatableView<VBox, Void> implements
|
|||
VBox.setVgrow(filterBox, Priority.NEVER);
|
||||
|
||||
tableView = new TableView<>();
|
||||
GUIUtil.applyTableStyle(tableView);
|
||||
VBox.setVgrow(tableView, Priority.SOMETIMES);
|
||||
tableView.setMinHeight(150);
|
||||
|
||||
|
@ -957,7 +953,6 @@ public abstract class DisputeView extends ActivatableView<VBox, Void> implements
|
|||
{
|
||||
setMaxWidth(80);
|
||||
setMinWidth(65);
|
||||
getStyleClass().addAll("first-column", "avatar-column");
|
||||
setSortable(false);
|
||||
}
|
||||
};
|
||||
|
@ -1354,7 +1349,6 @@ public abstract class DisputeView extends ActivatableView<VBox, Void> implements
|
|||
setMinWidth(50);
|
||||
}
|
||||
};
|
||||
column.getStyleClass().add("last-column");
|
||||
column.setCellValueFactory((dispute) -> new ReadOnlyObjectWrapper<>(dispute.getValue()));
|
||||
column.setCellFactory(
|
||||
new Callback<>() {
|
||||
|
|
|
@ -208,7 +208,6 @@ public abstract class DisputeAgentView extends DisputeView implements MultipleHo
|
|||
protected void setupTable() {
|
||||
super.setupTable();
|
||||
|
||||
stateColumn.getStyleClass().remove("last-column");
|
||||
tableView.getColumns().add(getAlertColumn());
|
||||
}
|
||||
|
||||
|
@ -243,7 +242,6 @@ public abstract class DisputeAgentView extends DisputeView implements MultipleHo
|
|||
setMinWidth(50);
|
||||
}
|
||||
};
|
||||
column.getStyleClass().add("last-column");
|
||||
column.setCellValueFactory((dispute) -> new ReadOnlyObjectWrapper<>(dispute.getValue()));
|
||||
column.setCellFactory(
|
||||
c -> new TableCell<>() {
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
/* haveno main colors */
|
||||
-bs-color-primary: #0b65da;
|
||||
-bs-color-primary-dark: #0c59bd;
|
||||
-bs-text-color: #dadada;
|
||||
-bs-background-color: #29292a;
|
||||
-bs-background-gray: #2B2B2B;
|
||||
-bs-content-background-gray: #1F1F1F;
|
||||
-bs-text-color: white;
|
||||
-bs-background-color: black;
|
||||
-bs-background-gray: transparent;
|
||||
-bs-content-background-gray: black;
|
||||
|
||||
/* fifty shades of gray */
|
||||
-bs-color-gray-13: #bbb;
|
||||
|
@ -43,7 +43,19 @@
|
|||
-bs-color-gray-bbb: #5a5a5a;
|
||||
-bs-color-gray-aaa: #29292a;
|
||||
-bs-color-gray-fafa: #0a0a0a;
|
||||
-bs-color-gray-background: #1F1F1F;
|
||||
-bs-color-gray-background: black;
|
||||
-bs-color-background-popup: rgb(38, 38, 38);
|
||||
-bs-color-background-popup-blur: rgb(9, 9, 9);
|
||||
-bs-color-background-popup-input: rgb(9, 9, 9);
|
||||
-bs-color-background-form-field: rgb(26, 26, 26);
|
||||
-bs-color-background-form-field-readonly: rgb(18, 18, 18);
|
||||
-bs-color-border-form-field: rgb(65, 65, 65);
|
||||
-bs-color-background-pane: rgb(15, 15, 15);
|
||||
-bs-color-background-row-even: rgb(19, 19, 19);
|
||||
-bs-color-background-row-odd: rgb(9, 9, 9);
|
||||
-bs-color-table-cell-dim: -bs-color-gray-ccc;
|
||||
-bs-text-color-dim1: rgb(87, 87, 87);
|
||||
-bs-text-color-dim2: rgb(130, 130, 130);
|
||||
|
||||
/* lesser used colors */
|
||||
-bs-color-blue-5: #0a4576;
|
||||
|
@ -70,11 +82,15 @@
|
|||
-bs-rd-nav-border: #535353;
|
||||
-bs-rd-nav-primary-border: rgba(0, 0, 0, 0);
|
||||
-bs-rd-nav-border-color: rgba(255, 255, 255, 0.1);
|
||||
-bs-rd-nav-background: #141414;
|
||||
-bs-rd-nav-primary-background: rgba(255, 255, 255, 0.015);
|
||||
-bs-rd-nav-selected: #fff;
|
||||
-bs-rd-nav-deselected: rgba(255, 255, 255, 0.45);
|
||||
-bs-rd-nav-button-hover: rgba(255, 255, 255, 0.03);
|
||||
-bs-rd-nav-background: rgb(15, 15, 15);
|
||||
-bs-rd-nav-primary-background: rgb(15, 15, 15);
|
||||
-bs-rd-nav-selected: black;
|
||||
-bs-rd-nav-deselected: rgba(255, 255, 255, 1);
|
||||
-bs-rd-nav-secondary-selected: -fx-accent;
|
||||
-bs-rd-nav-secondary-deselected: -bs-rd-font-light;
|
||||
-bs-rd-nav-button-hover: derive(-bs-rd-nav-background, 10%);
|
||||
-bs-rd-nav-primary-button-hover: derive(-bs-rd-nav-primary-background, 10%);
|
||||
-bs-rd-nav-hover-text: black;
|
||||
|
||||
-bs-content-pane-bg-top: #212121;
|
||||
-bs-rd-tab-border: rgba(255, 255, 255, 0.00);
|
||||
|
@ -90,7 +106,7 @@
|
|||
-bs-footer-pane-text: #cfcecf;
|
||||
-bs-footer-pane-line: #29292a;
|
||||
|
||||
-bs-rd-font-balance: #bbbbbb;
|
||||
-bs-rd-font-balance: white;
|
||||
-bs-rd-font-dark-gray: #d4d4d4;
|
||||
-bs-rd-font-dark: #cccccc;
|
||||
-bs-rd-font-light: #b4b4b4;
|
||||
|
@ -99,28 +115,28 @@
|
|||
-bs-rd-font-confirmation-label: #504f52;
|
||||
-bs-rd-font-balance-label: #999999;
|
||||
|
||||
-bs-text-color-transparent-dark: rgba(29, 29, 33, 0.54);
|
||||
-bs-text-color-dropshadow: rgba(45, 45, 49, .75);
|
||||
-bs-text-color-dropshadow-light-mode: transparent;
|
||||
-bs-text-color-transparent: rgba(29, 29, 33, 0.2);
|
||||
-bs-color-gray-line: #504f52;
|
||||
|
||||
-bs-rd-separator: #1F1F1F;
|
||||
-bs-rd-separator-dark: #1F1F1F;
|
||||
-bs-rd-separator-dark: rgb(255, 255, 255, 0.1);
|
||||
-bs-rd-error-red: #d83431;
|
||||
-bs-rd-error-field: #521C1C;
|
||||
-bs-rd-message-bubble: #0086c6;
|
||||
-bs-rd-tooltip-truncated: #afaeb0;
|
||||
|
||||
-bs-toggle-selected: #25b135;
|
||||
/*-bs-toggle-selected: rgb(12, 89, 189);*/
|
||||
-bs-toggle-selected: rgb(12, 89, 190);
|
||||
-bs-warning: #db6300;
|
||||
-bs-buy: #006600;
|
||||
-bs-buy-focus: black;
|
||||
-bs-buy-hover: #237b2d;
|
||||
-bs-buy-transparent: rgba(46, 163, 60, 0.3);
|
||||
-bs-sell: #660000;
|
||||
-bs-sell-focus: #090202;
|
||||
-bs-sell-hover: #b42522;
|
||||
-bs-sell-transparent: rgba(216, 52, 49, 0.3);
|
||||
-bs-volume-transparent: rgba(37, 177, 54, 0.5);
|
||||
-bs-buy: rgb(80, 180, 90);
|
||||
-bs-buy-focus: derive(-bs-buy, -50%);
|
||||
-bs-buy-hover: derive(-bs-buy, -10%);
|
||||
-bs-sell: rgb(213, 63, 46);
|
||||
-bs-sell-focus: derive(-bs-sell, -50%);
|
||||
-bs-sell-hover: derive(-bs-sell, -10%);
|
||||
-bs-volume-transparent: -bs-buy;
|
||||
-bs-candle-stick-average-line: rgba(21, 188, 29, 0.8);
|
||||
-bs-candle-stick-loss: #ee6563;
|
||||
-bs-candle-stick-won: #15bc1d;
|
||||
|
@ -154,7 +170,7 @@
|
|||
/* Monero orange color code */
|
||||
-xmr-orange: #f26822;
|
||||
|
||||
-bs-support-chat-background: #cccccc;
|
||||
-bs-support-chat-background: rgb(125, 125, 125);
|
||||
}
|
||||
|
||||
/* table view */
|
||||
|
@ -164,7 +180,7 @@
|
|||
}
|
||||
|
||||
.table-view .column-header {
|
||||
-fx-background-color: derive(-bs-background-color,-50%);
|
||||
-fx-background-color: -bs-color-background-pane;
|
||||
-fx-border-width: 0;
|
||||
}
|
||||
|
||||
|
@ -173,21 +189,31 @@
|
|||
-fx-border-width: 0;
|
||||
}
|
||||
|
||||
/** These must be set to override default styles */
|
||||
.table-view .table-row-cell:even .table-cell {
|
||||
-fx-background-color: derive(-bs-background-color, -5%);
|
||||
-fx-border-color: derive(-bs-background-color, -5%);
|
||||
-fx-background-color: -bs-color-background-row-even;
|
||||
-fx-border-color: -bs-color-background-row-even;
|
||||
}
|
||||
|
||||
.table-view .table-row-cell:odd .table-cell {
|
||||
-fx-background-color: derive(-bs-background-color,-30%);
|
||||
-fx-border-color: derive(-bs-background-color,-30%);
|
||||
-fx-background-color: -bs-color-background-row-odd;
|
||||
-fx-border-color: -bs-color-background-row-odd;
|
||||
}
|
||||
|
||||
.table-view .table-row-cell:selected .table-cell {
|
||||
-fx-background: -fx-accent;
|
||||
-fx-background-color: -fx-selection-bar;
|
||||
-fx-border-color: -fx-selection-bar;
|
||||
}
|
||||
.table-view .table-row-cell:selected .table-cell,
|
||||
.table-view .table-row-cell:selected .table-cell .label,
|
||||
.table-view .table-row-cell:selected .table-cell .text {
|
||||
-fx-text-fill: -fx-dark-text-color;
|
||||
}
|
||||
.table-view .table-row-cell:selected .table-cell .hyperlink,
|
||||
.table-view .table-row-cell:selected .table-cell .hyperlink .text,
|
||||
.table-view .table-row-cell:selected .table-cell .hyperlink-with-icon,
|
||||
.table-view .table-row-cell:selected .table-cell .hyperlink-with-icon .text {
|
||||
-fx-fill: -fx-dark-text-color;
|
||||
}
|
||||
|
||||
.table-row-cell {
|
||||
-fx-border-color: -bs-background-color;
|
||||
|
@ -208,35 +234,49 @@
|
|||
-fx-background-color: -bs-tab-content-area;
|
||||
}
|
||||
|
||||
.jfx-tab-pane .viewport {
|
||||
-fx-background-color: -bs-viewport-background;
|
||||
|
||||
.jfx-tab-pane .headers-region .tab:selected .tab-container .tab-label {
|
||||
-fx-text-fill: white;
|
||||
}
|
||||
|
||||
.jfx-tab-pane .tab-header-background {
|
||||
-fx-background-color: derive(-bs-color-gray-background, -20%);
|
||||
.nav-secondary-button:selected .text {
|
||||
-fx-fill: white;
|
||||
}
|
||||
|
||||
.jfx-tab-pane .headers-region > .tab > .jfx-rippler {
|
||||
-jfx-rippler-fill: none;
|
||||
}
|
||||
|
||||
.jfx-tab-pane .viewport {
|
||||
-fx-background-color: -bs-viewport-background;
|
||||
}
|
||||
|
||||
/* text field */
|
||||
.jfx-text-field, .jfx-text-area,
|
||||
.jfx-combo-box, .jfx-combo-box > .list-cell {
|
||||
-fx-background-color: derive(-bs-background-color, 15%);
|
||||
-fx-prompt-text-fill: -bs-color-gray-6;
|
||||
-fx-text-fill: -bs-color-gray-12;
|
||||
}
|
||||
|
||||
.jfx-text-area:readonly, .jfx-text-field:readonly,
|
||||
.jfx-text-area:readonly,
|
||||
.jfx-text-field:readonly,
|
||||
.hyperlink-with-icon {
|
||||
-fx-background: -bs-background-color;
|
||||
-fx-background-color: -bs-background-color;
|
||||
-fx-background-color: -bs-color-background-form-field-readonly;
|
||||
-fx-prompt-text-fill: -bs-color-gray-2;
|
||||
-fx-text-fill: -bs-color-gray-3;
|
||||
}
|
||||
|
||||
.popover > .content .text-field {
|
||||
-fx-background-color: -bs-color-background-form-field !important;
|
||||
}
|
||||
|
||||
.jfx-combo-box > .text,
|
||||
.jfx-text-field-top-label, .jfx-text-area-top-label {
|
||||
-fx-text-fill: -bs-color-gray-11;
|
||||
}
|
||||
|
||||
.input-with-border {
|
||||
.offer-input {
|
||||
-fx-border-color: -bs-color-gray-2;
|
||||
-fx-border-width: 0 0 10 0;
|
||||
}
|
||||
|
@ -254,11 +294,6 @@
|
|||
-fx-text-fill: -fx-dark-text-color;
|
||||
}
|
||||
|
||||
.chart-pane, .chart-plot-background,
|
||||
#charts .chart-plot-background,
|
||||
#charts-dao .chart-plot-background {
|
||||
-fx-background-color: transparent;
|
||||
}
|
||||
.axis:top, .axis:right, .axis:bottom, .axis:left {
|
||||
-fx-border-color: transparent transparent transparent transparent;
|
||||
}
|
||||
|
@ -332,7 +367,7 @@
|
|||
}
|
||||
|
||||
.combo-box-popup > .list-view{
|
||||
-fx-background-color: -bs-background-color;
|
||||
-fx-background-color: -bs-color-background-pane;
|
||||
}
|
||||
|
||||
.jfx-combo-box > .arrow-button > .arrow {
|
||||
|
@ -352,7 +387,6 @@
|
|||
}
|
||||
|
||||
.list-view .list-cell:odd, .list-view .list-cell:even {
|
||||
-fx-background-color: -bs-background-color;
|
||||
-fx-border-width: 0;
|
||||
}
|
||||
|
||||
|
@ -371,18 +405,6 @@
|
|||
-fx-border-width: 0;
|
||||
}
|
||||
|
||||
.jfx-text-field {
|
||||
-fx-background-radius: 4;
|
||||
}
|
||||
|
||||
.jfx-text-field > .input-line {
|
||||
-fx-translate-x: 0;
|
||||
}
|
||||
|
||||
.jfx-text-field > .input-focused-line {
|
||||
-fx-translate-x: 0;
|
||||
}
|
||||
|
||||
.jfx-text-field-top-label {
|
||||
-fx-text-fill: -bs-color-gray-dim;
|
||||
}
|
||||
|
@ -394,14 +416,13 @@
|
|||
-fx-background-color: derive(-bs-background-color, 15%);
|
||||
}
|
||||
.jfx-combo-box:error,
|
||||
.jfx-text-field:error{
|
||||
.jfx-text-field:error {
|
||||
-fx-text-fill: -bs-rd-error-red;
|
||||
-fx-background-color: -bs-rd-error-field;
|
||||
}
|
||||
|
||||
.jfx-combo-box:error:focused,
|
||||
.jfx-text-field:error:focused{
|
||||
-fx-text-fill: -bs-rd-error-red;
|
||||
-fx-background-color: derive(-bs-rd-error-field, -5%);
|
||||
}
|
||||
|
||||
|
@ -417,11 +438,7 @@
|
|||
-jfx-disable-animation: true;
|
||||
}
|
||||
|
||||
.jfx-password-field {
|
||||
-fx-background-color: derive(-bs-background-color, -15%);
|
||||
}
|
||||
|
||||
.input-with-border {
|
||||
.offer-input {
|
||||
-fx-border-width: 0;
|
||||
-fx-border-color: -bs-background-color;
|
||||
}
|
||||
|
@ -448,11 +465,6 @@
|
|||
-jfx-disable-animation: true;
|
||||
}
|
||||
|
||||
.top-navigation {
|
||||
-fx-border-width: 0 0 0 0;
|
||||
-fx-padding: 0 7 0 0;
|
||||
}
|
||||
|
||||
.nav-price-balance {
|
||||
-fx-effect: null;
|
||||
}
|
||||
|
@ -462,37 +474,17 @@
|
|||
}
|
||||
|
||||
.nav-button:selected {
|
||||
-fx-background-color: derive(-bs-color-primary-dark, -10%);
|
||||
-fx-background-color: white;
|
||||
-fx-effect: null;
|
||||
}
|
||||
|
||||
.nav-button:hover {
|
||||
-fx-background-color: -bs-rd-nav-button-hover;
|
||||
}
|
||||
|
||||
.nav-primary .nav-button:selected {
|
||||
-fx-background-color: derive(-bs-color-primary-dark, -5%);
|
||||
-fx-background-color: derive(white, -5%);
|
||||
}
|
||||
.table-view {
|
||||
-fx-border-color: transparent;
|
||||
}
|
||||
|
||||
.table-view .table-cell {
|
||||
-fx-padding: 6 0 4 0;
|
||||
-fx-text-fill: -bs-text-color;
|
||||
}
|
||||
.table-view .table-cell.last-column {
|
||||
-fx-padding: 6 10 4 0;
|
||||
}
|
||||
|
||||
.table-view .table-cell.last-column.avatar-column {
|
||||
-fx-padding: 6 0 4 0;
|
||||
}
|
||||
|
||||
.table-view .table-cell.first-column {
|
||||
-fx-padding: 6 0 4 10;
|
||||
}
|
||||
|
||||
.jfx-tab-pane .headers-region .tab .tab-container .tab-label {
|
||||
-fx-cursor: hand;
|
||||
-jfx-disable-animation: true;
|
||||
|
@ -559,12 +551,95 @@
|
|||
}
|
||||
|
||||
.toggle-button-no-slider {
|
||||
-fx-focus-color: transparent;
|
||||
-fx-faint-focus-color: transparent;
|
||||
-fx-background-radius: 3;
|
||||
-fx-background-insets: 0, 1;
|
||||
-fx-background-color: -bs-color-background-form-field;
|
||||
}
|
||||
|
||||
.toggle-button-no-slider:selected {
|
||||
-fx-text-fill: white;
|
||||
-fx-background-color: -bs-color-gray-ccc;
|
||||
-fx-border-color: -bs-color-gray-ccc;
|
||||
-fx-border-width: 1px;
|
||||
}
|
||||
|
||||
.toggle-button-no-slider:hover {
|
||||
-fx-cursor: hand;
|
||||
-fx-background-color: -bs-color-gray-ddd;
|
||||
-fx-border-color: -bs-color-gray-ddd;
|
||||
}
|
||||
|
||||
.toggle-button-no-slider:selected:hover {
|
||||
-fx-cursor: hand;
|
||||
-fx-background-color: -bs-color-gray-3;
|
||||
-fx-border-color: -bs-color-gray-3;
|
||||
}
|
||||
|
||||
.toggle-button-no-slider:pressed, .toggle-button-no-slider:selected:hover:pressed {
|
||||
-fx-background-color: -bs-color-gray-bbb;
|
||||
}
|
||||
|
||||
#image-logo-splash {
|
||||
-fx-image: url("../../images/logo_splash_dark.png");
|
||||
}
|
||||
|
||||
#image-logo-splash-testnet {
|
||||
-fx-image: url("../../images/logo_splash_testnet_dark.png");
|
||||
}
|
||||
|
||||
#image-logo-landscape {
|
||||
-fx-image: url("../../images/logo_landscape_dark.png");
|
||||
}
|
||||
|
||||
.table-view .placeholder {
|
||||
-fx-background-color: -bs-color-background-pane;
|
||||
}
|
||||
|
||||
#charts .default-color0.chart-series-area-fill {
|
||||
-fx-fill: linear-gradient(to bottom,
|
||||
rgba(80, 181, 90, 0.45) 0%,
|
||||
rgba(80, 181, 90, 0.0) 100%
|
||||
);
|
||||
}
|
||||
|
||||
#charts .default-color1.chart-series-area-fill {
|
||||
-fx-fill: linear-gradient(to bottom,
|
||||
rgba(213, 63, 46, 0.45) 0%,
|
||||
rgba(213, 63, 46, 0.0) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.table-view .table-row-cell .label {
|
||||
-fx-text-fill: -bs-text-color;
|
||||
}
|
||||
|
||||
.table-view.non-interactive-table .table-cell,
|
||||
.table-view.non-interactive-table .table-cell .label,
|
||||
.table-view.non-interactive-table .label,
|
||||
.table-view.non-interactive-table .text,
|
||||
.table-view.non-interactive-table .hyperlink,
|
||||
.table-view.non-interactive-table .hyperlink-with-icon,
|
||||
.table-view.non-interactive-table .table-row-cell .hyperlink .text {
|
||||
-fx-text-fill: -bs-color-gray-dim;
|
||||
}
|
||||
|
||||
.table-view.non-interactive-table .hyperlink,
|
||||
.table-view.non-interactive-table .hyperlink-with-icon,
|
||||
.table-view.non-interactive-table .table-row-cell .hyperlink .text {
|
||||
-fx-fill: -bs-color-gray-dim;
|
||||
}
|
||||
|
||||
.table-view.non-interactive-table .table-cell.highlight-text,
|
||||
.table-view.non-interactive-table .table-cell.highlight-text .label,
|
||||
.table-view.non-interactive-table .table-cell.highlight-text .text,
|
||||
.table-view.non-interactive-table .table-cell.highlight-text .hyperlink,
|
||||
.table-view.non-interactive-table .table-cell.highlight-text .hyperlink .text {
|
||||
-fx-text-fill: -fx-dark-text-color;
|
||||
}
|
||||
|
||||
/* Match specificity to override. */
|
||||
.table-view.non-interactive-table .table-cell.highlight-text .zero-decimals {
|
||||
-fx-text-fill: -bs-color-gray-3;
|
||||
}
|
||||
|
||||
.regular-text-color {
|
||||
-fx-text-fill: -bs-text-color;
|
||||
}
|
||||
|
|
|
@ -41,12 +41,17 @@
|
|||
-bs-rd-green: #0b65da;
|
||||
-bs-rd-green-dark: #3EA34A;
|
||||
-bs-rd-nav-selected: #0b65da;
|
||||
-bs-rd-nav-deselected: rgba(255, 255, 255, 0.75);
|
||||
-bs-rd-nav-background: #0c59bd;
|
||||
-bs-rd-nav-deselected: rgba(255, 255, 255, 1);
|
||||
-bs-rd-nav-secondary-selected: -fx-accent;
|
||||
-bs-rd-nav-secondary-deselected: -bs-rd-font-light;
|
||||
-bs-rd-nav-background: #0b65da;
|
||||
-bs-rd-nav-primary-background: #0b65da;
|
||||
-bs-rd-nav-button-hover: derive(-bs-rd-nav-background, 10%);
|
||||
-bs-rd-nav-primary-button-hover: derive(-bs-rd-nav-primary-background, 10%);
|
||||
-bs-rd-nav-primary-border: #0B65DA;
|
||||
-bs-rd-nav-border: #535353;
|
||||
-bs-rd-nav-border-color: rgba(255, 255, 255, 0.31);
|
||||
-bs-rd-nav-hover-text: white;
|
||||
-bs-rd-tab-border: #e2e0e0;
|
||||
-bs-tab-content-area: #ffffff;
|
||||
-bs-color-gray-background: #f2f2f2;
|
||||
|
@ -58,32 +63,31 @@
|
|||
-bs-footer-pane-background: #dddddd;
|
||||
-bs-footer-pane-text: #4b4b4b;
|
||||
-bs-footer-pane-line: #bbb;
|
||||
-bs-rd-font-balance: #4f4f4f;
|
||||
-bs-rd-font-balance: white;
|
||||
-bs-rd-font-dark-gray: #3c3c3c;
|
||||
-bs-rd-font-dark: #4b4b4b;
|
||||
-bs-rd-font-light: #8d8d8d;
|
||||
-bs-rd-font-lighter: #a7a7a7;
|
||||
-bs-rd-font-confirmation-label: #504f52;
|
||||
-bs-rd-font-balance-label: #8e8e8e;
|
||||
-bs-text-color-transparent-dark: rgba(0, 0, 0, 0.54);
|
||||
-bs-rd-font-balance-label: #bbbbbb;
|
||||
-bs-text-color-dropshadow: rgba(0, 0, 0, 0.54);
|
||||
-bs-text-color-dropshadow-light-mode: rgba(0, 0, 0, 0.54);
|
||||
-bs-text-color-transparent: rgba(0, 0, 0, 0.2);
|
||||
-bs-color-gray-line: #979797;
|
||||
-bs-rd-separator: #dbdbdb;
|
||||
-bs-rd-separator-dark: #d5e0d6;
|
||||
-bs-rd-separator-dark: rgb(255, 255, 255, 0.1);
|
||||
-bs-rd-error-red: #dd0000;
|
||||
-bs-rd-message-bubble: #0086c6;
|
||||
-bs-toggle-selected: #7b7b7b;
|
||||
-bs-rd-tooltip-truncated: #0a0a0a;
|
||||
-bs-warning: #ff8a2b;
|
||||
-bs-buy: #3ea34a;
|
||||
-bs-buy: rgb(80, 180, 90);
|
||||
-bs-buy-focus: derive(-bs-buy, -50%);
|
||||
-bs-buy-hover: derive(-bs-buy, -10%);
|
||||
-bs-buy-transparent: rgba(62, 163, 74, 0.3);
|
||||
-bs-sell: #d73030;
|
||||
-bs-sell: rgb(213, 63, 46);
|
||||
-bs-sell-focus: derive(-bs-sell, -50%);
|
||||
-bs-sell-hover: derive(-bs-sell, -10%);
|
||||
-bs-sell-transparent: rgba(215, 48, 48, 0.3);
|
||||
-bs-volume-transparent: rgba(37, 177, 53, 0.3);
|
||||
-bs-volume-transparent: -bs-buy;
|
||||
-bs-candle-stick-average-line: -bs-rd-green;
|
||||
-bs-candle-stick-loss: #fe3001;
|
||||
-bs-candle-stick-won: #20b221;
|
||||
|
@ -104,6 +108,19 @@
|
|||
-bs-prompt-text: -fx-control-inner-background;
|
||||
-bs-soft-red: #aa4c3b;
|
||||
-bs-turquoise-light: #11eeee;
|
||||
-bs-color-border-form-field: -bs-background-gray;
|
||||
-bs-color-background-form-field-readonly: -bs-color-gray-1;
|
||||
-bs-color-background-pane: -bs-background-color;
|
||||
-bs-color-background-row-even: -bs-color-background-pane;
|
||||
-bs-color-background-row-odd: derive(-bs-color-background-pane, -6%);
|
||||
-bs-color-table-cell-dim: -bs-color-gray-ccc;
|
||||
-bs-color-background-popup: white;
|
||||
-bs-color-background-popup-blur: white;
|
||||
-bs-color-background-popup-input: -bs-color-gray-background;
|
||||
-bs-color-background-form-field: white;
|
||||
-bs-text-color-dim1: black;
|
||||
-bs-text-color-dim2: black;
|
||||
|
||||
|
||||
/* Monero orange color code */
|
||||
-xmr-orange: #f26822;
|
||||
|
@ -126,7 +143,33 @@
|
|||
-fx-background-color: -bs-color-gray-3;
|
||||
}
|
||||
|
||||
.toggle-button-no-slider {
|
||||
-fx-focus-color: transparent;
|
||||
-fx-faint-focus-color: transparent;
|
||||
#image-logo-splash {
|
||||
-fx-image: url("../../images/logo_splash_light.png");
|
||||
}
|
||||
|
||||
#image-logo-splash-testnet {
|
||||
-fx-image: url("../../images/logo_splash_testnet_light.png");
|
||||
}
|
||||
|
||||
#image-logo-landscape {
|
||||
-fx-image: url("../../images/logo_landscape_light.png");
|
||||
}
|
||||
|
||||
#charts .default-color0.chart-series-area-fill {
|
||||
-fx-fill: linear-gradient(to bottom,
|
||||
rgba(62, 163, 74, 0.45) 0%,
|
||||
rgba(62, 163, 74, 0.0) 100%
|
||||
);
|
||||
}
|
||||
|
||||
#charts .default-color1.chart-series-area-fill {
|
||||
-fx-fill: linear-gradient(to bottom,
|
||||
rgba(215, 48, 48, 0.45) 0%,
|
||||
rgba(215, 48, 48, 0.0) 100%
|
||||
);
|
||||
}
|
||||
|
||||
/* All inputs have border in light mode. */
|
||||
.jfx-combo-box, .jfx-text-field, .jfx-text-area, .jfx-password-field {
|
||||
-fx-border-color: -bs-color-border-form-field;
|
||||
}
|
||||
|
|
|
@ -58,6 +58,10 @@ public class CssTheme {
|
|||
scene.getStylesheets().add(cssThemeFolder + "theme-dev.css");
|
||||
}
|
||||
|
||||
public static int getCurrentTheme() {
|
||||
return currentCSSTheme;
|
||||
}
|
||||
|
||||
public static boolean isDarkTheme() {
|
||||
return currentCSSTheme == CSS_THEME_DARK;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
package haveno.desktop.util;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import haveno.core.locale.CurrencyUtil;
|
||||
import haveno.core.locale.TradeCurrency;
|
||||
import haveno.core.user.Preferences;
|
||||
import javafx.collections.FXCollections;
|
||||
|
@ -92,14 +94,13 @@ public class CurrencyList {
|
|||
}
|
||||
|
||||
private Comparator<CurrencyListItem> getComparator() {
|
||||
Comparator<CurrencyListItem> result;
|
||||
if (preferences.isSortMarketCurrenciesNumerically()) {
|
||||
Comparator<CurrencyListItem> byCount = Comparator.comparingInt(left -> left.numTrades);
|
||||
result = byCount.reversed();
|
||||
return Comparator
|
||||
.comparingInt((CurrencyListItem item) -> item.numTrades).reversed()
|
||||
.thenComparing(item -> CurrencyUtil.isCryptoCurrency(item.tradeCurrency.getCode()) ? item.tradeCurrency.getName() : item.tradeCurrency.getCode());
|
||||
} else {
|
||||
result = Comparator.comparing(item -> item.tradeCurrency);
|
||||
return Comparator.comparing(item -> CurrencyUtil.isCryptoCurrency(item.tradeCurrency.getCode()) ? item.tradeCurrency.getName() : item.tradeCurrency.getCode());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Map<TradeCurrency, Integer> countTrades(List<TradeCurrency> currencies) {
|
||||
|
|
|
@ -135,6 +135,24 @@ public class FormBuilder {
|
|||
return titledGroupBg;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Divider
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public static Region addSeparator(GridPane gridPane, int rowIndex) {
|
||||
Region separator = new Region();
|
||||
separator.getStyleClass().add("grid-pane-separator");
|
||||
separator.setPrefHeight(1);
|
||||
separator.setMinHeight(1);
|
||||
separator.setMaxHeight(1);
|
||||
GridPane.setRowIndex(separator, rowIndex);
|
||||
GridPane.setColumnIndex(separator, 0);
|
||||
GridPane.setColumnSpan(separator, 2);
|
||||
gridPane.getChildren().add(separator);
|
||||
separator.setPrefHeight(1);
|
||||
GridPane.setMargin(separator, new Insets(0, 0, 3, 0));
|
||||
return separator;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Label
|
||||
|
@ -361,7 +379,7 @@ public class FormBuilder {
|
|||
textField.setPrefWidth(Layout.INITIAL_WINDOW_WIDTH);
|
||||
|
||||
Button button = new AutoTooltipButton("...");
|
||||
button.setStyle("-fx-min-width: 26; -fx-pref-height: 26; -fx-padding: 0 0 10 0; -fx-background-color: -fx-background;");
|
||||
button.setStyle("-fx-min-width: 32; -fx-padding: 0 0 10 0; -fx-background-color: -fx-background;");
|
||||
button.managedProperty().bind(button.visibleProperty());
|
||||
|
||||
HBox hbox = new HBox(textField, button);
|
||||
|
@ -369,6 +387,7 @@ public class FormBuilder {
|
|||
hbox.setSpacing(8);
|
||||
|
||||
VBox vbox = getTopLabelVBox(0);
|
||||
vbox.setSpacing(2);
|
||||
vbox.getChildren().addAll(getTopLabel(title), hbox);
|
||||
|
||||
gridPane.getChildren().add(vbox);
|
||||
|
@ -490,6 +509,7 @@ public class FormBuilder {
|
|||
GridPane.setColumnIndex(textArea, 1);
|
||||
GridPane.setMargin(label, new Insets(top, 0, 0, 0));
|
||||
GridPane.setHalignment(label, HPos.LEFT);
|
||||
GridPane.setValignment(label, VPos.TOP);
|
||||
GridPane.setMargin(textArea, new Insets(top, 0, 0, 0));
|
||||
|
||||
return new Tuple2<>(label, textArea);
|
||||
|
@ -617,6 +637,7 @@ public class FormBuilder {
|
|||
JFXTextArea textArea = new HavenoTextArea();
|
||||
textArea.setPromptText(prompt);
|
||||
textArea.setLabelFloat(true);
|
||||
textArea.getStyleClass().add("label-float");
|
||||
textArea.setWrapText(true);
|
||||
|
||||
GridPane.setRowIndex(textArea, rowIndex);
|
||||
|
@ -805,9 +826,9 @@ public class FormBuilder {
|
|||
}
|
||||
|
||||
public static InputTextField addInputTextField(GridPane gridPane, int rowIndex, String title, double top) {
|
||||
|
||||
InputTextField inputTextField = new InputTextField();
|
||||
inputTextField.setLabelFloat(true);
|
||||
inputTextField.getStyleClass().add("label-float");
|
||||
inputTextField.setPromptText(title);
|
||||
GridPane.setRowIndex(inputTextField, rowIndex);
|
||||
GridPane.setColumnIndex(inputTextField, 0);
|
||||
|
@ -884,6 +905,8 @@ public class FormBuilder {
|
|||
|
||||
public static PasswordTextField addPasswordTextField(GridPane gridPane, int rowIndex, String title, double top) {
|
||||
PasswordTextField passwordField = new PasswordTextField();
|
||||
passwordField.getStyleClass().addAll("label-float");
|
||||
GUIUtil.applyFilledStyle(passwordField);
|
||||
passwordField.setPromptText(title);
|
||||
GridPane.setRowIndex(passwordField, rowIndex);
|
||||
GridPane.setColumnIndex(passwordField, 0);
|
||||
|
@ -1006,8 +1029,10 @@ public class FormBuilder {
|
|||
InputTextField inputTextField1 = new InputTextField();
|
||||
inputTextField1.setPromptText(title1);
|
||||
inputTextField1.setLabelFloat(true);
|
||||
inputTextField1.getStyleClass().add("label-float");
|
||||
InputTextField inputTextField2 = new InputTextField();
|
||||
inputTextField2.setLabelFloat(true);
|
||||
inputTextField2.getStyleClass().add("label-float");
|
||||
inputTextField2.setPromptText(title2);
|
||||
|
||||
HBox hBox = new HBox();
|
||||
|
@ -1228,6 +1253,7 @@ public class FormBuilder {
|
|||
|
||||
public static <T> ComboBox<T> addComboBox(GridPane gridPane, int rowIndex, int top) {
|
||||
final JFXComboBox<T> comboBox = new JFXComboBox<>();
|
||||
GUIUtil.applyFilledStyle(comboBox);
|
||||
|
||||
GridPane.setRowIndex(comboBox, rowIndex);
|
||||
GridPane.setMargin(comboBox, new Insets(top, 0, 0, 0));
|
||||
|
@ -1264,7 +1290,9 @@ public class FormBuilder {
|
|||
VBox vBox = getTopLabelVBox(top);
|
||||
|
||||
final JFXComboBox<T> comboBox = new JFXComboBox<>();
|
||||
GUIUtil.applyFilledStyle(comboBox);
|
||||
comboBox.setPromptText(prompt);
|
||||
comboBox.setPadding(new Insets(top, 0, 0, 12));
|
||||
|
||||
vBox.getChildren().addAll(label, comboBox);
|
||||
|
||||
|
@ -1389,7 +1417,9 @@ public class FormBuilder {
|
|||
|
||||
public static <T> ComboBox<T> addComboBox(GridPane gridPane, int rowIndex, String title, double top) {
|
||||
JFXComboBox<T> comboBox = new JFXComboBox<>();
|
||||
GUIUtil.applyFilledStyle(comboBox);
|
||||
comboBox.setLabelFloat(true);
|
||||
comboBox.getStyleClass().add("label-float");
|
||||
comboBox.setPromptText(title);
|
||||
comboBox.setMaxWidth(Double.MAX_VALUE);
|
||||
|
||||
|
@ -1399,6 +1429,7 @@ public class FormBuilder {
|
|||
|
||||
GridPane.setRowIndex(comboBox, rowIndex);
|
||||
GridPane.setColumnIndex(comboBox, 0);
|
||||
comboBox.setPadding(new Insets(0, 0, 0, 12));
|
||||
GridPane.setMargin(comboBox, new Insets(top + Layout.FLOATING_LABEL_DISTANCE, 0, 0, 0));
|
||||
gridPane.getChildren().add(comboBox);
|
||||
|
||||
|
@ -1407,7 +1438,9 @@ public class FormBuilder {
|
|||
|
||||
public static <T> AutocompleteComboBox<T> addAutocompleteComboBox(GridPane gridPane, int rowIndex, String title, double top) {
|
||||
var comboBox = new AutocompleteComboBox<T>();
|
||||
GUIUtil.applyFilledStyle(comboBox);
|
||||
comboBox.setLabelFloat(true);
|
||||
comboBox.getStyleClass().add("label-float");
|
||||
comboBox.setPromptText(title);
|
||||
comboBox.setMaxWidth(Double.MAX_VALUE);
|
||||
|
||||
|
@ -1469,6 +1502,7 @@ public class FormBuilder {
|
|||
AutocompleteComboBox<T> comboBox = new AutocompleteComboBox<>();
|
||||
comboBox.setPromptText(titleCombobox);
|
||||
comboBox.setLabelFloat(true);
|
||||
comboBox.getStyleClass().add("label-float");
|
||||
topLabelVBox2.getChildren().addAll(topLabel2, comboBox);
|
||||
|
||||
hBox.getChildren().addAll(topLabelVBox1, topLabelVBox2);
|
||||
|
@ -1498,7 +1532,9 @@ public class FormBuilder {
|
|||
hBox.setSpacing(10);
|
||||
|
||||
ComboBox<T> comboBox1 = new JFXComboBox<>();
|
||||
GUIUtil.applyFilledStyle(comboBox1);
|
||||
ComboBox<R> comboBox2 = new JFXComboBox<>();
|
||||
GUIUtil.applyFilledStyle(comboBox2);
|
||||
hBox.getChildren().addAll(comboBox1, comboBox2);
|
||||
|
||||
final Tuple2<Label, VBox> topLabelWithVBox = addTopLabelWithVBox(gridPane, rowIndex, title, hBox, top);
|
||||
|
@ -1526,8 +1562,10 @@ public class FormBuilder {
|
|||
hBox.setSpacing(10);
|
||||
|
||||
JFXComboBox<T> comboBox = new JFXComboBox<>();
|
||||
GUIUtil.applyFilledStyle(comboBox);
|
||||
comboBox.setPromptText(titleCombobox);
|
||||
comboBox.setLabelFloat(true);
|
||||
comboBox.getStyleClass().add("label-float");
|
||||
|
||||
TextField textField = new HavenoTextField();
|
||||
|
||||
|
@ -1570,6 +1608,7 @@ public class FormBuilder {
|
|||
button.setDefaultButton(true);
|
||||
|
||||
ComboBox<T> comboBox = new JFXComboBox<>();
|
||||
GUIUtil.applyFilledStyle(comboBox);
|
||||
|
||||
hBox.getChildren().addAll(comboBox, button);
|
||||
|
||||
|
@ -1604,6 +1643,7 @@ public class FormBuilder {
|
|||
hBox.setSpacing(10);
|
||||
|
||||
ComboBox<T> comboBox = new JFXComboBox<>();
|
||||
GUIUtil.applyFilledStyle(comboBox);
|
||||
TextField textField = new TextField(textFieldText);
|
||||
textField.setEditable(false);
|
||||
textField.setMouseTransparent(true);
|
||||
|
@ -1797,6 +1837,7 @@ public class FormBuilder {
|
|||
|
||||
return new Tuple2<>(label, textFieldWithCopyIcon);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Label + AddressTextField
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -2181,11 +2222,13 @@ public class FormBuilder {
|
|||
|
||||
Label label = new AutoTooltipLabel(Res.getBaseCurrencyCode());
|
||||
label.getStyleClass().add("input-label");
|
||||
HBox.setMargin(label, new Insets(0, 8, 0, 0));
|
||||
|
||||
HBox box = new HBox();
|
||||
HBox.setHgrow(input, Priority.ALWAYS);
|
||||
input.setMaxWidth(Double.MAX_VALUE);
|
||||
box.getStyleClass().add("input-with-border");
|
||||
box.setAlignment(Pos.CENTER_LEFT);
|
||||
box.getStyleClass().add("offer-input");
|
||||
box.getChildren().addAll(input, label);
|
||||
return new Tuple3<>(box, input, label);
|
||||
}
|
||||
|
@ -2197,11 +2240,13 @@ public class FormBuilder {
|
|||
|
||||
Label label = new AutoTooltipLabel(Res.getBaseCurrencyCode());
|
||||
label.getStyleClass().add("input-label");
|
||||
HBox.setMargin(label, new Insets(0, 8, 0, 0));
|
||||
|
||||
HBox box = new HBox();
|
||||
HBox.setHgrow(infoInputTextField, Priority.ALWAYS);
|
||||
infoInputTextField.setMaxWidth(Double.MAX_VALUE);
|
||||
box.getStyleClass().add("input-with-border");
|
||||
box.setAlignment(Pos.CENTER_LEFT);
|
||||
box.getStyleClass().add("offer-input");
|
||||
box.getChildren().addAll(infoInputTextField, label);
|
||||
return new Tuple3<>(box, infoInputTextField, label);
|
||||
}
|
||||
|
@ -2444,6 +2489,7 @@ public class FormBuilder {
|
|||
if (groupStyle != null) titledGroupBg.getStyleClass().add(groupStyle);
|
||||
|
||||
TableView<T> tableView = new TableView<>();
|
||||
GUIUtil.applyTableStyle(tableView);
|
||||
GridPane.setRowIndex(tableView, rowIndex);
|
||||
GridPane.setMargin(tableView, new Insets(top + 30, -10, 5, -10));
|
||||
gridPane.getChildren().add(tableView);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue