From e3b2992934f0573ef296ce53e0267d29431270d9 Mon Sep 17 00:00:00 2001 From: Dominique <5765435+dpad85@users.noreply.github.com> Date: Mon, 14 Jan 2019 16:53:52 +0100 Subject: [PATCH 01/10] Readibility improvements in GUI (#801) * Improved amounts readability (fixes #542) and added the Bits unit denomination in the documentation * Improved channel panel UI layout * Added a confirmation dialog when closing a channel, with a short summary of the channel to be closed The balance bar has been shrunk in size so that it should not be mistaken as a separator element between channels. The channel's balance, capacity and peer node id are now more visible. Also added the short channel id to the channel's pane. fixes #690 * Added node's aggregated balance in the status bar fixes #775 --- README.md | 2 +- .../scala/fr/acinq/eclair/CoinUtils.scala | 41 +++++-- .../scala/fr/acinq/eclair/CoinUtilsSpec.scala | 8 ++ .../main/resources/gui/commons/globals.css | 22 +++- .../main/resources/gui/main/channelPane.fxml | 104 ++++++++++-------- .../src/main/resources/gui/main/main.css | 18 ++- .../src/main/resources/gui/main/main.fxml | 79 ++++++------- .../scala/fr/acinq/eclair/gui/FxApp.scala | 7 +- .../fr/acinq/eclair/gui/GUIUpdater.scala | 90 +++++++-------- .../controllers/ChannelPaneController.scala | 92 ++++++++++++++-- .../gui/controllers/MainController.scala | 33 +++--- .../fr/acinq/eclair/gui/utils/Constants.scala | 7 +- 12 files changed, 311 insertions(+), 192 deletions(-) diff --git a/README.md b/README.md index b5e278619..9cb5efe2d 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ name | description eclair.bitcoind.rpcpassword | Bitcoin Core RPC password | bar eclair.bitcoind.zmqblock | Bitcoin Core ZMQ block address | "tcp://127.0.0.1:29000" eclair.bitcoind.zmqtx | Bitcoin Core ZMQ tx address | "tcp://127.0.0.1:29000" - eclair.gui.unit | Unit in which amounts are displayed (possible values: msat, sat, mbtc, btc) | btc + eclair.gui.unit | Unit in which amounts are displayed (possible values: msat, sat, bits, mbtc, btc) | btc Quotes are not required unless the value contains special characters. Full syntax guide [here](https://github.com/lightbend/config/blob/master/HOCON.md). diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/CoinUtils.scala b/eclair-core/src/main/scala/fr/acinq/eclair/CoinUtils.scala index e6fbe9656..cd649a0c5 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/CoinUtils.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/CoinUtils.scala @@ -16,7 +16,7 @@ package fr.acinq.eclair -import java.text.DecimalFormat +import java.text.{DecimalFormat, NumberFormat} import fr.acinq.bitcoin.{Btc, BtcAmount, MilliBtc, MilliSatoshi, Satoshi} import grizzled.slf4j.Logging @@ -93,19 +93,44 @@ case object BtcUnit extends CoinUnit { object CoinUtils extends Logging { - val COIN_PATTERN = "###,###,###,##0.###########" - var COIN_FORMAT = new DecimalFormat(COIN_PATTERN) + // msat pattern, no decimals allowed + val MILLI_SAT_PATTERN = "#,###,###,###,###,###,##0" - def setCoinPattern(pattern: String) = { + // sat pattern decimals are optional + val SAT_PATTERN = "#,###,###,###,###,##0.###" + + // bits pattern always shows 2 decimals (msat optional) + val BITS_PATTERN = "##,###,###,###,##0.00###" + + // milli btc pattern always shows 5 decimals (msat optional) + val MILLI_BTC_PATTERN = "##,###,###,##0.00000###" + + // btc pattern always shows 8 decimals (msat optional). This is the default pattern. + val BTC_PATTERN = "##,###,##0.00000000###" + + var COIN_FORMAT: NumberFormat = new DecimalFormat(BTC_PATTERN) + + def setCoinPattern(pattern: String): Unit = { COIN_FORMAT = new DecimalFormat(pattern) } + def getPatternFromUnit(unit: CoinUnit): String = { + unit match { + case MSatUnit => MILLI_SAT_PATTERN + case SatUnit => SAT_PATTERN + case BitUnit => BITS_PATTERN + case MBtcUnit => MILLI_BTC_PATTERN + case BtcUnit => BTC_PATTERN + case _ => throw new IllegalArgumentException("unhandled unit") + } + } + /** * Converts a string amount denominated in a bitcoin unit to a Millisatoshi amount. The amount might be truncated if * it has too many decimals because MilliSatoshi only accepts Long amount. * * @param amount numeric String, can be decimal. - * @param unit bitcoin unit, can be milliSatoshi, Satoshi, milliBTC, BTC. + * @param unit bitcoin unit, can be milliSatoshi, Satoshi, Bits, milliBTC, BTC. * @return amount as a MilliSatoshi object. * @throws NumberFormatException if the amount parameter is not numeric. * @throws IllegalArgumentException if the unit is not equals to milliSatoshi, Satoshi or milliBTC. @@ -132,7 +157,7 @@ object CoinUtils extends Logging { fr.acinq.bitcoin.millisatoshi2satoshi(CoinUtils.convertStringAmountToMsat(amount, unit)) /** - * Only BtcUnit, MBtcUnit, SatUnit and MSatUnit codes or label are supported. + * Only BtcUnit, MBtcUnit, BitUnit, SatUnit and MSatUnit codes or label are supported. * @param unit * @return */ @@ -199,13 +224,13 @@ object CoinUtils extends Logging { } /** - * Converts the amount to the user preferred unit and returns the Long value. + * Converts the amount to the user preferred unit and returns the BigDecimal value. * This method is useful to feed numeric text input without formatting. * * Returns -1 if the given amount can not be converted. * * @param amount BtcAmount - * @return Long value of the BtcAmount + * @return BigDecimal value of the BtcAmount */ def rawAmountInUnit(amount: BtcAmount, unit: CoinUnit): BigDecimal = Try(convertAmountToGUIUnit(amount, unit) match { case a: BtcAmountGUILossless => BigDecimal(a.amount_msat) / a.unit.factorToMsat diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/CoinUtilsSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/CoinUtilsSpec.scala index 68ce42634..2ee8cf559 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/CoinUtilsSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/CoinUtilsSpec.scala @@ -27,6 +27,8 @@ class CoinUtilsSpec extends FunSuite { assert(am_btc == MilliSatoshi(100000000000L)) val am_mbtc: MilliSatoshi = CoinUtils.convertStringAmountToMsat("1", MBtcUnit.code) assert(am_mbtc == MilliSatoshi(100000000L)) + val am_bits: MilliSatoshi = CoinUtils.convertStringAmountToMsat("1", BitUnit.code) + assert(am_bits == MilliSatoshi(100000)) val am_sat: MilliSatoshi = CoinUtils.convertStringAmountToMsat("1", SatUnit.code) assert(am_sat == MilliSatoshi(1000)) val am_msat: MilliSatoshi = CoinUtils.convertStringAmountToMsat("1", MSatUnit.code) @@ -42,6 +44,8 @@ class CoinUtilsSpec extends FunSuite { assert(am_mbtc_dec_nozero == MilliSatoshi(25000000L)) val am_mbtc_dec: MilliSatoshi = CoinUtils.convertStringAmountToMsat("1.23456789", MBtcUnit.code) assert(am_mbtc_dec == MilliSatoshi(123456789L)) + val am_bits_dec: MilliSatoshi = CoinUtils.convertStringAmountToMsat("1.23456789", BitUnit.code) + assert(am_bits_dec == MilliSatoshi(123456)) val am_sat_dec: MilliSatoshi = CoinUtils.convertStringAmountToMsat("1.23456789", SatUnit.code) assert(am_sat_dec == MilliSatoshi(1234)) val am_msat_dec: MilliSatoshi = CoinUtils.convertStringAmountToMsat("1.234", MSatUnit.code) @@ -80,19 +84,23 @@ class CoinUtilsSpec extends FunSuite { assert(CoinUtils.rawAmountInUnit(MilliSatoshi(123), SatUnit) == BigDecimal(0.123)) assert(CoinUtils.rawAmountInUnit(MilliSatoshi(123), MSatUnit) == BigDecimal(123)) assert(CoinUtils.rawAmountInUnit(MilliSatoshi(12345678), BtcUnit) == BigDecimal(0.00012345678)) + assert(CoinUtils.rawAmountInUnit(MilliSatoshi(1234567), BitUnit) == BigDecimal(12.34567)) assert(CoinUtils.rawAmountInUnit(Satoshi(123), BtcUnit) == BigDecimal(0.00000123)) assert(CoinUtils.rawAmountInUnit(Satoshi(123), MBtcUnit) == BigDecimal(0.00123)) + assert(CoinUtils.rawAmountInUnit(Satoshi(123), BitUnit) == BigDecimal(1.23)) assert(CoinUtils.rawAmountInUnit(Satoshi(123), SatUnit) == BigDecimal(123)) assert(CoinUtils.rawAmountInUnit(Satoshi(123), MSatUnit) == BigDecimal(123000)) assert(CoinUtils.rawAmountInUnit(MilliBtc(123.456), BtcUnit) == BigDecimal(0.123456)) assert(CoinUtils.rawAmountInUnit(MilliBtc(123.456), MBtcUnit) == BigDecimal(123.456)) + assert(CoinUtils.rawAmountInUnit(MilliBtc(123.45678), BitUnit) == BigDecimal(123456.78)) assert(CoinUtils.rawAmountInUnit(MilliBtc(123.456789), SatUnit) == BigDecimal(12345678.9)) assert(CoinUtils.rawAmountInUnit(MilliBtc(123.45678987), MSatUnit) == BigDecimal(12345678987L)) assert(CoinUtils.rawAmountInUnit(Btc(123.456), BtcUnit) == BigDecimal(123.456)) assert(CoinUtils.rawAmountInUnit(Btc(123.45678987654), MBtcUnit) == BigDecimal(123456.78987654)) + assert(CoinUtils.rawAmountInUnit(Btc(123.456789876), BitUnit) == BigDecimal(123456789.876)) assert(CoinUtils.rawAmountInUnit(Btc(1.22233333444), SatUnit) == BigDecimal(122233333.444)) assert(CoinUtils.rawAmountInUnit(Btc(0.00011111222), MSatUnit) == BigDecimal(11111222L)) } diff --git a/eclair-node-gui/src/main/resources/gui/commons/globals.css b/eclair-node-gui/src/main/resources/gui/commons/globals.css index 2888370b2..986df8da9 100644 --- a/eclair-node-gui/src/main/resources/gui/commons/globals.css +++ b/eclair-node-gui/src/main/resources/gui/commons/globals.css @@ -15,10 +15,26 @@ -fx-font-weight: bold; } +.text-xs { + -fx-font-size: 10px; +} + .text-sm { -fx-font-size: 12px; } +.text-md { + -fx-font-size: 14px; +} + +.text-lg { + -fx-font-size: 16px; +} + +.text-xl { + -fx-font-size: 18px; +} + .text-error { -fx-text-fill: rgb(216,31,74); -fx-font-size: 11px; @@ -115,15 +131,13 @@ /* ---------- Progress Bar ---------- */ .bar { - -fx-background-color: rgb(63,179,234); + -fx-background-color: rgb(114,193,229); -fx-background-insets: 0; - -fx-background-radius: 0; } .track { - -fx-background-color: rgb(206,230,255); + -fx-background-color: rgb(211,227,234); -fx-background-insets: 0; - -fx-background-radius: 0; } /* ---------- Forms ----------- */ diff --git a/eclair-node-gui/src/main/resources/gui/main/channelPane.fxml b/eclair-node-gui/src/main/resources/gui/main/channelPane.fxml index b25056177..ce1f7acf2 100644 --- a/eclair-node-gui/src/main/resources/gui/main/channelPane.fxml +++ b/eclair-node-gui/src/main/resources/gui/main/channelPane.fxml @@ -1,8 +1,17 @@ - - + + + + + + + + + + + - + - - + + - + - - - - + + + + + + - - - - - - + + + + + - - - -