mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-03-15 20:30:17 +01:00
Move to GridPane wallet, dynamic sizing (#3492)
This commit is contained in:
parent
3cdc0d19c7
commit
e315fb0563
6 changed files with 106 additions and 68 deletions
|
@ -34,7 +34,6 @@ object BundleGUI extends WalletGUI with BitcoinSAppJFX3 {
|
||||||
|
|
||||||
val DEFAULT_WIDTH = 1400.0
|
val DEFAULT_WIDTH = 1400.0
|
||||||
val DEFAULT_HEIGHT = 800.0
|
val DEFAULT_HEIGHT = 800.0
|
||||||
val DEFAULT_MAXIMIZED = false
|
|
||||||
val NOT_SET = Double.MinValue
|
val NOT_SET = Double.MinValue
|
||||||
val MINIMUM_WIDTH = 800.0
|
val MINIMUM_WIDTH = 800.0
|
||||||
val MINIMUM_HEIGHT = 500.0
|
val MINIMUM_HEIGHT = 500.0
|
||||||
|
|
|
@ -25,6 +25,11 @@
|
||||||
-fx-text-fill: red;
|
-fx-text-fill: red;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Non-editable TextField to look like Label */
|
||||||
|
.no-text-input-readonly-style .text-input:readonly {
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
.titulo {
|
.titulo {
|
||||||
-fx-font-weight: bold;
|
-fx-font-weight: bold;
|
||||||
-fx-font-size: 18px;
|
-fx-font-size: 18px;
|
||||||
|
|
|
@ -35,54 +35,9 @@ abstract class WalletGUI extends Logging {
|
||||||
model.updateTorAddress()
|
model.updateTorAddress()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val satsProperty = StringProperty(" sats")
|
|
||||||
|
|
||||||
private lazy val confirmedText = new Label() {
|
|
||||||
text <== StringProperty(
|
|
||||||
"Confirmed balance:\t\t") + GlobalData.currentConfirmedBalance + satsProperty
|
|
||||||
}
|
|
||||||
|
|
||||||
private lazy val unconfirmedText = new Label() {
|
|
||||||
text <== StringProperty(
|
|
||||||
"Unconfirmed balance:\t") + GlobalData.currentUnconfirmedBalance + satsProperty
|
|
||||||
}
|
|
||||||
|
|
||||||
private lazy val reservedText = new Label() {
|
|
||||||
text <== StringProperty(
|
|
||||||
"Reserved balance:\t\t") + GlobalData.currentReservedBalance + satsProperty
|
|
||||||
}
|
|
||||||
|
|
||||||
private lazy val totalBalanceText = new Label() {
|
|
||||||
text <== StringProperty(
|
|
||||||
"Total balance:\t\t\t") + GlobalData.currentTotalBalance + satsProperty
|
|
||||||
}
|
|
||||||
|
|
||||||
private lazy val pnlText = new Label() {
|
|
||||||
text <== StringProperty(
|
|
||||||
"Profit and Loss:\t\t\t") + GlobalData.currentPNL + satsProperty
|
|
||||||
}
|
|
||||||
|
|
||||||
private lazy val rateOfReturnText = new Label() {
|
|
||||||
text <== StringProperty("Rate of Return:\t\t\t") + GlobalData.rateOfReturn
|
|
||||||
}
|
|
||||||
|
|
||||||
private[gui] lazy val dlcPane = new DLCPane(glassPane)(system.dispatcher)
|
private[gui] lazy val dlcPane = new DLCPane(glassPane)(system.dispatcher)
|
||||||
private[gui] lazy val model = new WalletGUIModel(dlcPane.model)
|
private[gui] lazy val model = new WalletGUIModel(dlcPane.model)
|
||||||
|
|
||||||
private lazy val balanceBox = new VBox {
|
|
||||||
spacing = 10
|
|
||||||
children = Vector(confirmedText,
|
|
||||||
unconfirmedText,
|
|
||||||
reservedText,
|
|
||||||
new Separator(),
|
|
||||||
totalBalanceText)
|
|
||||||
}
|
|
||||||
|
|
||||||
private lazy val walletAccountingBox = new VBox {
|
|
||||||
spacing = 10
|
|
||||||
children = Vector(pnlText, rateOfReturnText)
|
|
||||||
}
|
|
||||||
|
|
||||||
private lazy val getNewAddressButton = new Button {
|
private lazy val getNewAddressButton = new Button {
|
||||||
text = "Get New Address"
|
text = "Get New Address"
|
||||||
onAction = _ => model.onGetNewAddress()
|
onAction = _ => model.onGetNewAddress()
|
||||||
|
@ -93,15 +48,92 @@ abstract class WalletGUI extends Logging {
|
||||||
onAction = _ => model.onSend()
|
onAction = _ => model.onSend()
|
||||||
}
|
}
|
||||||
|
|
||||||
private lazy val spacer = new Region { vgrow = Priority.Always }
|
private lazy val buttonBox = new HBox {
|
||||||
|
spacing = 10
|
||||||
|
getNewAddressButton.prefWidth <== width / 2
|
||||||
|
sendButton.prefWidth <== width / 2
|
||||||
|
getNewAddressButton.minWidth = 120
|
||||||
|
sendButton.minWidth = 120
|
||||||
|
getNewAddressButton.maxWidth = 240
|
||||||
|
sendButton.maxWidth = 240
|
||||||
|
children = Vector(getNewAddressButton, sendButton)
|
||||||
|
}
|
||||||
|
|
||||||
private var nextRow: Int = 0
|
private var nextRow: Int = _
|
||||||
|
|
||||||
|
private def getTextField(stringProperty: StringProperty): TextField =
|
||||||
|
new TextField() {
|
||||||
|
text <== stringProperty
|
||||||
|
editable = false
|
||||||
|
alignment = Pos.CenterRight
|
||||||
|
}
|
||||||
|
private def getSatsLabel(): Label = new Label("sats")
|
||||||
|
|
||||||
|
private lazy val walletGrid = new GridPane() {
|
||||||
|
minWidth = 490 // Matches button widths, this sets minWidth of sidebar
|
||||||
|
styleClass += "no-text-input-readonly-style"
|
||||||
|
nextRow = 0
|
||||||
|
add(new Label("Confirmed Balance"), 0, nextRow)
|
||||||
|
add(getTextField(GlobalData.currentConfirmedBalance), 1, nextRow)
|
||||||
|
add(getSatsLabel(), 2, nextRow)
|
||||||
|
nextRow += 1
|
||||||
|
|
||||||
|
add(new Label("Unconfirmed Balance"), 0, nextRow)
|
||||||
|
add(getTextField(GlobalData.currentUnconfirmedBalance), 1, nextRow)
|
||||||
|
add(getSatsLabel(), 2, nextRow)
|
||||||
|
nextRow += 1
|
||||||
|
|
||||||
|
add(new Label("Reserve Balance"), 0, nextRow)
|
||||||
|
add(getTextField(GlobalData.currentReservedBalance), 1, nextRow)
|
||||||
|
add(getSatsLabel(), 2, nextRow)
|
||||||
|
nextRow += 1
|
||||||
|
|
||||||
|
add(new Separator(), 1, nextRow)
|
||||||
|
nextRow += 1
|
||||||
|
|
||||||
|
add(new Label("Total Balance"), 0, nextRow)
|
||||||
|
add(getTextField(GlobalData.currentTotalBalance), 1, nextRow)
|
||||||
|
add(getSatsLabel(), 2, nextRow)
|
||||||
|
|
||||||
|
nextRow = 0 // 2nd column
|
||||||
|
add(new Label("Profit and Loss"), 4, nextRow)
|
||||||
|
add(getTextField(GlobalData.currentPNL), 5, nextRow)
|
||||||
|
add(getSatsLabel(), 6, nextRow)
|
||||||
|
nextRow += 1
|
||||||
|
|
||||||
|
add(new Label("Rate of Return"), 4, nextRow)
|
||||||
|
add(getTextField(GlobalData.rateOfReturn), 5, nextRow)
|
||||||
|
add(new Label("%"), 6, nextRow)
|
||||||
|
nextRow += 1
|
||||||
|
|
||||||
|
// Force spacer column width
|
||||||
|
columnConstraints = Seq(
|
||||||
|
new ColumnConstraints(),
|
||||||
|
new ColumnConstraints() {
|
||||||
|
prefWidth = 110
|
||||||
|
},
|
||||||
|
new ColumnConstraints(),
|
||||||
|
new ColumnConstraints() { // spacer column
|
||||||
|
prefWidth = 30
|
||||||
|
},
|
||||||
|
new ColumnConstraints(),
|
||||||
|
new ColumnConstraints() {
|
||||||
|
prefWidth = 90
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private lazy val wallet = new VBox {
|
||||||
|
padding = Insets(10)
|
||||||
|
spacing = 10
|
||||||
|
children = Vector(walletGrid, buttonBox)
|
||||||
|
}
|
||||||
|
|
||||||
private lazy val stateDetails = new GridPane {
|
private lazy val stateDetails = new GridPane {
|
||||||
visible <== GlobalData.torAddress.isNotEmpty
|
visible <== GlobalData.torAddress.isNotEmpty
|
||||||
hgap = 5
|
hgap = 5
|
||||||
vgap = 5
|
vgap = 5
|
||||||
prefWidth = 300 // to match buttons
|
prefWidth = 490 // to match wallet
|
||||||
columnConstraints = Seq(new ColumnConstraints { hgrow = Priority.Always },
|
columnConstraints = Seq(new ColumnConstraints { hgrow = Priority.Always },
|
||||||
new ColumnConstraints { hgrow = Priority.Always })
|
new ColumnConstraints { hgrow = Priority.Always })
|
||||||
|
|
||||||
|
@ -115,7 +147,7 @@ abstract class WalletGUI extends Logging {
|
||||||
GUIUtil.getCopyToClipboardButton(GlobalData.torAddress)
|
GUIUtil.getCopyToClipboardButton(GlobalData.torAddress)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
nextRow = 0
|
||||||
add(new Label("Tor Address"), 0, nextRow)
|
add(new Label("Tor Address"), 0, nextRow)
|
||||||
add(hbox, 1, nextRow)
|
add(hbox, 1, nextRow)
|
||||||
nextRow += 1
|
nextRow += 1
|
||||||
|
@ -127,14 +159,9 @@ abstract class WalletGUI extends Logging {
|
||||||
|
|
||||||
getNewAddressButton.prefWidth <== width
|
getNewAddressButton.prefWidth <== width
|
||||||
sendButton.prefWidth <== width
|
sendButton.prefWidth <== width
|
||||||
getNewAddressButton.maxWidth = 300
|
getNewAddressButton.maxWidth = 240
|
||||||
sendButton.maxWidth = 300
|
sendButton.maxWidth = 240
|
||||||
children = Vector(balanceBox,
|
children = Vector(wallet, GUIUtil.getVSpacer(), stateDetails)
|
||||||
walletAccountingBox,
|
|
||||||
getNewAddressButton,
|
|
||||||
sendButton,
|
|
||||||
spacer,
|
|
||||||
stateDetails)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy val bottomStack: HBox = new HBox {
|
lazy val bottomStack: HBox = new HBox {
|
||||||
|
|
|
@ -169,11 +169,11 @@ class WalletGUIModel(dlcModel: DLCPaneModel)(implicit system: ActorSystem)
|
||||||
false
|
false
|
||||||
case Success(commandReturn) =>
|
case Success(commandReturn) =>
|
||||||
val json = ujson.read(commandReturn).obj
|
val json = ujson.read(commandReturn).obj
|
||||||
val pnl = json(PicklerKeys.pnl).num.toLong.toString
|
val pnl = json(PicklerKeys.pnl).num.toLong
|
||||||
val rateOfReturn = json(PicklerKeys.rateOfReturn).num
|
val rateOfReturn = json(PicklerKeys.rateOfReturn).num
|
||||||
val rorPrettyPrint = RateOfReturnUtil.prettyPrint(rateOfReturn)
|
val rorPercentage = RateOfReturnUtil.toPercentage(rateOfReturn)
|
||||||
GlobalData.currentPNL.value = pnl
|
GlobalData.currentPNL.value = GUIUtil.numberFormatter.format(pnl)
|
||||||
GlobalData.rateOfReturn.value = rorPrettyPrint
|
GlobalData.rateOfReturn.value = rorPercentage
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ class DLCPane(glassPane: VBox)(implicit ec: ExecutionContext) {
|
||||||
private val resultArea = new BorderPane() {
|
private val resultArea = new BorderPane() {
|
||||||
padding = Insets(top = 10, right = 0, bottom = 10, left = 0)
|
padding = Insets(top = 10, right = 0, bottom = 10, left = 0)
|
||||||
center = resultTextArea
|
center = resultTextArea
|
||||||
|
hgrow = Priority.Always
|
||||||
}
|
}
|
||||||
|
|
||||||
val model = new DLCPaneModel(this)
|
val model = new DLCPaneModel(this)
|
||||||
|
@ -99,9 +100,12 @@ class DLCPane(glassPane: VBox)(implicit ec: ExecutionContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private val buttonSpacer = new HBox {
|
private val buttonSpacer = new HBox {
|
||||||
spacing = 100
|
|
||||||
alignment = Pos.Center
|
alignment = Pos.Center
|
||||||
children = Vector(initButtonBar, acceptButtonBar, execButtonBar)
|
children = Vector(initButtonBar,
|
||||||
|
GUIUtil.getHSpacer(),
|
||||||
|
acceptButtonBar,
|
||||||
|
GUIUtil.getHSpacer(),
|
||||||
|
execButtonBar)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val textAreaHBox = new HBox {
|
private val textAreaHBox = new HBox {
|
||||||
|
@ -141,9 +145,7 @@ class DLCPane(glassPane: VBox)(implicit ec: ExecutionContext) {
|
||||||
center = textAreasAndTableViewVBox
|
center = textAreasAndTableViewVBox
|
||||||
}
|
}
|
||||||
|
|
||||||
resultArea.prefWidth <== borderPane.width
|
|
||||||
resultArea.prefHeight <== (borderPane.height * 2) / 3
|
resultArea.prefHeight <== (borderPane.height * 2) / 3
|
||||||
|
|
||||||
tableView.prefHeight <== borderPane.height / 3
|
tableView.prefHeight <== borderPane.height / 3
|
||||||
|
|
||||||
private val taskRunner = new TaskRunner(buttonSpacer, glassPane)
|
private val taskRunner = new TaskRunner(buttonSpacer, glassPane)
|
||||||
|
|
|
@ -4,7 +4,12 @@ object RateOfReturnUtil {
|
||||||
|
|
||||||
/** @see https://alvinalexander.com/scala/how-to-format-numbers-commas-international-currency-in-scala/ */
|
/** @see https://alvinalexander.com/scala/how-to-format-numbers-commas-international-currency-in-scala/ */
|
||||||
def prettyPrint(ror: BigDecimal): String = {
|
def prettyPrint(ror: BigDecimal): String = {
|
||||||
val percent = ror * 100
|
toPercentage(ror, 2) + "%"
|
||||||
f"${percent}%1.2f" + "%"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Convert to default two decimal percentage representation without % label */
|
||||||
|
def toPercentage(ror: BigDecimal, decimals: Int = 2): String = {
|
||||||
|
s"%1.${decimals}f".format(ror * 100)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue