Browse Source

qml: consolidate fee slider ui in various places to a single FeePicker control

master
Sander van Grieken 2 years ago
parent
commit
c0b892720e
No known key found for this signature in database
GPG Key ID: 9BCF8209EA402EBA
  1. 149
      electrum/gui/qml/components/ConfirmTxDialog.qml
  2. 154
      electrum/gui/qml/components/CpfpBumpFeeDialog.qml
  3. 78
      electrum/gui/qml/components/RbfBumpFeeDialog.qml
  4. 69
      electrum/gui/qml/components/RbfCancelDialog.qml
  5. 111
      electrum/gui/qml/components/controls/FeePicker.qml
  6. 21
      electrum/gui/qml/qetxfinalizer.py

149
electrum/gui/qml/components/ConfirmTxDialog.qml

@ -30,7 +30,7 @@ ElDialog {
function updateAmountText() {
btcValue.text = Config.formatSats(finalizer.effectiveAmount, false)
fiatValue.text = Daemon.fx.enabled
? '(' + Daemon.fx.fiatValue(finalizer.effectiveAmount, false) + ' ' + Daemon.fx.fiatCurrency + ')'
? Daemon.fx.fiatValue(finalizer.effectiveAmount, false)
: ''
}
@ -57,119 +57,82 @@ ElDialog {
Label {
id: amountLabel
Layout.fillWidth: true
Layout.minimumWidth: implicitWidth
Layout.columnSpan: 2
text: qsTr('Amount to send')
color: Material.accentColor
}
RowLayout {
Layout.fillWidth: true
Label {
id: btcValue
font.bold: true
font.family: FixedFont
}
Label {
text: Config.baseUnit
color: Material.accentColor
}
Label {
id: fiatValue
Layout.fillWidth: true
font.pixelSize: constants.fontSizeMedium
}
Component.onCompleted: updateAmountText()
Connections {
target: finalizer
function onEffectiveAmountChanged() {
updateAmountText()
TextHighlightPane {
Layout.columnSpan: 2
Layout.fillWidth: true
GridLayout {
columns: 2
Label {
id: btcValue
Layout.alignment: Qt.AlignRight
font.pixelSize: constants.fontSizeXLarge
font.family: FixedFont
font.bold: true
}
}
}
Label {
text: qsTr('Mining fee')
color: Material.accentColor
}
FormattedAmount {
amount: finalizer.fee
}
Label {
visible: !finalizer.extraFee.isEmpty
text: qsTr('Extra fee')
color: Material.accentColor
}
FormattedAmount {
visible: !finalizer.extraFee.isEmpty
amount: finalizer.extraFee
}
Label {
text: qsTr('Fee rate')
color: Material.accentColor
}
Label {
Layout.fillWidth: true
text: Config.baseUnit
color: Material.accentColor
font.pixelSize: constants.fontSizeXLarge
}
RowLayout {
Label {
id: feeRate
text: finalizer.feeRate
font.family: FixedFont
}
Label {
id: fiatValue
Layout.alignment: Qt.AlignRight
visible: Daemon.fx.enabled
font.pixelSize: constants.fontSizeMedium
color: constants.mutedForeground
}
Label {
text: UI_UNIT_NAME.FEERATE_SAT_PER_VB
color: Material.accentColor
Label {
Layout.fillWidth: true
visible: Daemon.fx.enabled
text: Daemon.fx.fiatCurrency
font.pixelSize: constants.fontSizeMedium
color: constants.mutedForeground
}
Component.onCompleted: updateAmountText()
Connections {
target: finalizer
function onEffectiveAmountChanged() {
updateAmountText()
}
}
}
}
Label {
text: qsTr('Target')
Layout.columnSpan: 2
text: qsTr('Fee')
color: Material.accentColor
}
Label {
id: targetdesc
text: finalizer.target
}
RowLayout {
TextHighlightPane {
Layout.columnSpan: 2
Layout.fillWidth: true
height: feepicker.height
Slider {
id: feeslider
Layout.fillWidth: true
leftPadding: constants.paddingMedium
snapMode: Slider.SnapOnRelease
stepSize: 1
from: 0
to: finalizer.sliderSteps
FeePicker {
id: feepicker
width: parent.width
finalizer: dialog.finalizer
onValueChanged: {
if (activeFocus)
finalizer.sliderPos = value
}
Component.onCompleted: {
value = finalizer.sliderPos
Label {
visible: !finalizer.extraFee.isEmpty
text: qsTr('Extra fee')
color: Material.accentColor
}
Connections {
target: finalizer
function onSliderPosChanged() {
feeslider.value = finalizer.sliderPos
}
}
}
FeeMethodComboBox {
id: target
feeslider: finalizer
FormattedAmount {
visible: !finalizer.extraFee.isEmpty
amount: finalizer.extraFee
}
}
}

154
electrum/gui/qml/components/CpfpBumpFeeDialog.qml

@ -56,113 +56,91 @@ ElDialog {
}
Label {
Layout.preferredWidth: 1
Layout.fillWidth: true
text: qsTr('Total size')
Layout.columnSpan: 2
Layout.topMargin: constants.paddingSmall
text: qsTr('Child tx fee')
color: Material.accentColor
}
Label {
Layout.preferredWidth: 1
TextHighlightPane {
Layout.columnSpan: 2
Layout.fillWidth: true
text: cpfpfeebumper.totalSize + ' ' + UI_UNIT_NAME.TXSIZE_VBYTES
}
Label {
text: qsTr('Input amount')
color: Material.accentColor
}
FormattedAmount {
amount: cpfpfeebumper.inputAmount
height: feepicker.height
FeePicker {
id: feepicker
width: parent.width
finalizer: dialog.cpfpfeebumper
targetLabel: qsTr('Target total')
feeLabel: qsTr('Fee for child')
feeRateLabel: qsTr('Fee rate for child')
}
}
Label {
text: qsTr('Output amount')
Layout.columnSpan: 2
Layout.topMargin: constants.paddingSmall
text: qsTr('Total')
color: Material.accentColor
visible: cpfpfeebumper.valid
}
FormattedAmount {
amount: cpfpfeebumper.outputAmount
valid: cpfpfeebumper.valid
}
RowLayout {
TextHighlightPane {
Layout.columnSpan: 2
Slider {
id: feeslider
leftPadding: constants.paddingMedium
snapMode: Slider.SnapOnRelease
stepSize: 1
from: 0
to: cpfpfeebumper.sliderSteps
onValueChanged: {
if (activeFocus)
cpfpfeebumper.sliderPos = value
}
Component.onCompleted: {
value = cpfpfeebumper.sliderPos
}
Connections {
target: cpfpfeebumper
function onSliderPosChanged() {
feeslider.value = cpfpfeebumper.sliderPos
}
}
}
FeeMethodComboBox {
id: feemethod
feeslider: cpfpfeebumper
}
}
Label {
visible: feemethod.currentValue
text: qsTr('Target')
color: Material.accentColor
}
Layout.fillWidth: true
visible: cpfpfeebumper.valid
Label {
visible: feemethod.currentValue
text: cpfpfeebumper.target
}
GridLayout {
width: parent.width
columns: 2
Label {
text: qsTr('Fee for child')
color: Material.accentColor
}
Label {
Layout.preferredWidth: 1
Layout.fillWidth: true
text: qsTr('Total size')
color: Material.accentColor
}
FormattedAmount {
amount: cpfpfeebumper.feeForChild
valid: cpfpfeebumper.valid
}
Label {
Layout.preferredWidth: 2
Layout.fillWidth: true
text: cpfpfeebumper.totalSize + ' ' + UI_UNIT_NAME.TXSIZE_VBYTES
}
Label {
text: qsTr('Total fee')
color: Material.accentColor
}
Label {
Layout.preferredWidth: 1
Layout.fillWidth: true
text: qsTr('Total fee')
color: Material.accentColor
}
FormattedAmount {
amount: cpfpfeebumper.totalFee
valid: cpfpfeebumper.valid
}
FormattedAmount {
Layout.preferredWidth: 2
Layout.fillWidth: true
amount: cpfpfeebumper.totalFee
}
Label {
text: qsTr('Total fee rate')
color: Material.accentColor
}
Label {
Layout.preferredWidth: 1
Layout.fillWidth: true
text: qsTr('Total fee rate')
color: Material.accentColor
}
RowLayout {
Label {
text: cpfpfeebumper.valid ? cpfpfeebumper.totalFeeRate : ''
font.family: FixedFont
}
RowLayout {
Layout.preferredWidth: 2
Layout.fillWidth: true
Label {
text: cpfpfeebumper.valid ? cpfpfeebumper.totalFeeRate : ''
font.family: FixedFont
}
Label {
visible: cpfpfeebumper.valid
text: UI_UNIT_NAME.FEERATE_SAT_PER_VB
color: Material.accentColor
Label {
visible: cpfpfeebumper.valid
text: UI_UNIT_NAME.FEERATE_SAT_PER_VB
color: Material.accentColor
}
}
}
}

78
electrum/gui/qml/components/RbfBumpFeeDialog.qml

@ -49,17 +49,12 @@ ElDialog {
}
Label {
Layout.preferredWidth: 1
Layout.fillWidth: true
text: qsTr('Method')
color: Material.accentColor
}
RowLayout {
Layout.preferredWidth: 1
Layout.fillWidth: true
Layout.minimumWidth: bumpMethodComboBox.implicitWidth
ElComboBox {
id: bumpMethodComboBox
@ -79,15 +74,11 @@ ElDialog {
}
Label {
Layout.preferredWidth: 1
Layout.fillWidth: true
text: qsTr('Old fee')
color: Material.accentColor
}
FormattedAmount {
Layout.preferredWidth: 1
Layout.fillWidth: true
amount: rbffeebumper.oldfee
}
@ -110,71 +101,22 @@ ElDialog {
}
Label {
Layout.columnSpan: 2
Layout.topMargin: constants.paddingSmall
text: qsTr('New fee')
color: Material.accentColor
}
FormattedAmount {
amount: rbffeebumper.fee
valid: rbffeebumper.valid
}
Label {
text: qsTr('New fee rate')
color: Material.accentColor
}
RowLayout {
Label {
id: feeRate
text: rbffeebumper.valid ? rbffeebumper.feeRate : ''
font.family: FixedFont
}
Label {
visible: rbffeebumper.valid
text: UI_UNIT_NAME.FEERATE_SAT_PER_VB
color: Material.accentColor
}
}
Label {
text: qsTr('Target')
color: Material.accentColor
}
Label {
id: targetdesc
text: rbffeebumper.target
}
RowLayout {
TextHighlightPane {
Layout.columnSpan: 2
Slider {
id: feeslider
leftPadding: constants.paddingMedium
snapMode: Slider.SnapOnRelease
stepSize: 1
from: 0
to: rbffeebumper.sliderSteps
onValueChanged: {
if (activeFocus)
rbffeebumper.sliderPos = value
}
Component.onCompleted: {
value = rbffeebumper.sliderPos
}
Connections {
target: rbffeebumper
function onSliderPosChanged() {
feeslider.value = rbffeebumper.sliderPos
}
}
}
Layout.fillWidth: true
height: feepicker.height
FeePicker {
id: feepicker
width: parent.width
finalizer: dialog.rbffeebumper
FeeMethodComboBox {
id: target
feeslider: rbffeebumper
}
}

69
electrum/gui/qml/components/RbfCancelDialog.qml

@ -73,71 +73,22 @@ ElDialog {
}
Label {
Layout.columnSpan: 2
Layout.topMargin: constants.paddingSmall
text: qsTr('New fee')
color: Material.accentColor
}
FormattedAmount {
amount: txcanceller.fee
valid: txcanceller.valid
}
Label {
text: qsTr('New fee rate')
color: Material.accentColor
}
RowLayout {
Label {
id: feeRate
text: txcanceller.valid ? txcanceller.feeRate : ''
font.family: FixedFont
}
Label {
visible: txcanceller.valid
text: UI_UNIT_NAME.FEERATE_SAT_PER_VB
color: Material.accentColor
}
}
Label {
text: qsTr('Target')
color: Material.accentColor
}
Label {
id: targetdesc
text: txcanceller.target
}
RowLayout {
TextHighlightPane {
Layout.columnSpan: 2
Slider {
id: feeslider
leftPadding: constants.paddingMedium
snapMode: Slider.SnapOnRelease
stepSize: 1
from: 0
to: txcanceller.sliderSteps
onValueChanged: {
if (activeFocus)
txcanceller.sliderPos = value
}
Component.onCompleted: {
value = txcanceller.sliderPos
}
Connections {
target: txcanceller
function onSliderPosChanged() {
feeslider.value = txcanceller.sliderPos
}
}
}
Layout.fillWidth: true
height: feepicker.height
FeePicker {
id: feepicker
width: parent.width
finalizer: dialog.txcanceller
FeeMethodComboBox {
id: target
feeslider: txcanceller
}
}

111
electrum/gui/qml/components/controls/FeePicker.qml

@ -0,0 +1,111 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Controls.Material
import org.electrum 1.0
Item {
id: root
required property QtObject finalizer
default property alias additionalItems: rootLayout.children
property string targetLabel: qsTr('Target')
property string feeLabel: qsTr('Mining fee')
property string feeRateLabel: qsTr('Fee rate')
implicitHeight: rootLayout.height
GridLayout {
id: rootLayout
width: parent.width
columns: 2
Label {
Layout.fillWidth: true
Layout.preferredWidth: 1
text: feeLabel
color: Material.accentColor
}
FormattedAmount {
Layout.fillWidth: true
Layout.preferredWidth: 2
amount: finalizer.fee
valid: finalizer.valid
}
Label {
Layout.fillWidth: true
Layout.preferredWidth: 1
text: feeRateLabel
color: Material.accentColor
}
RowLayout {
Layout.fillWidth: true
Layout.preferredWidth: 2
Label {
id: feeRate
text: finalizer.valid ? finalizer.feeRate : ''
font.family: FixedFont
}
Label {
text: finalizer.valid ? UI_UNIT_NAME.FEERATE_SAT_PER_VBYTE : ''
color: Material.accentColor
}
}
Label {
Layout.fillWidth: true
Layout.preferredWidth: 1
text: targetLabel
color: Material.accentColor
}
Label {
Layout.fillWidth: true
Layout.preferredWidth: 2
id: targetdesc
text: finalizer.target
}
RowLayout {
Layout.columnSpan: 2
Layout.fillWidth: true
Slider {
id: feeslider
Layout.fillWidth: true
leftPadding: constants.paddingMedium
snapMode: Slider.SnapOnRelease
stepSize: 1
from: 0
to: finalizer.sliderSteps
onValueChanged: {
if (activeFocus)
finalizer.sliderPos = value
}
Component.onCompleted: {
value = finalizer.sliderPos
}
Connections {
target: finalizer
function onSliderPosChanged() {
feeslider.value = finalizer.sliderPos
}
}
}
FeeMethodComboBox {
id: target
feeslider: finalizer
}
}
}
}

21
electrum/gui/qml/qetxfinalizer.py

@ -7,7 +7,7 @@ from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject
from electrum.logging import get_logger
from electrum.i18n import _
from electrum.transaction import PartialTxOutput, PartialTransaction, Transaction, TxOutpoint
from electrum.util import NotEnoughFunds, profiler
from electrum.util import NotEnoughFunds, profiler, quantize_feerate
from electrum.wallet import CannotBumpFee, CannotDoubleSpendTx, CannotCPFP, BumpFeeStrategy
from electrum.plugin import run_hook
@ -719,7 +719,6 @@ class QETxCpfpFeeBumper(TxFeeSlider, TxMonMixin):
self._input_amount = QEAmount()
self._output_amount = QEAmount()
self._fee_for_child = QEAmount()
self._total_fee = QEAmount()
self._total_fee_rate = 0
self._total_size = 0
@ -754,17 +753,6 @@ class QETxCpfpFeeBumper(TxFeeSlider, TxMonMixin):
self._total_fee_rate = totalfeerate
self.totalFeeRateChanged.emit()
feeForChildChanged = pyqtSignal()
@pyqtProperty(QEAmount, notify=feeForChildChanged)
def feeForChild(self):
return self._fee_for_child
@feeForChild.setter
def feeForChild(self, feeforchild):
if self._fee_for_child != feeforchild:
self._fee_for_child.copyFrom(feeforchild)
self.feeForChildChanged.emit()
inputAmountChanged = pyqtSignal()
@pyqtProperty(QEAmount, notify=inputAmountChanged)
def inputAmount(self):
@ -850,12 +838,12 @@ class QETxCpfpFeeBumper(TxFeeSlider, TxMonMixin):
comb_fee = fee + self._parent_fee
comb_feerate = comb_fee / self._total_size
self._fee_for_child.satsInt = fee
self._fee.satsInt = fee
self._output_amount.satsInt = self._max_fee - fee
self.outputAmountChanged.emit()
self._total_fee.satsInt = fee + self._parent_fee
self._total_fee_rate = f'{comb_feerate:.1f}'
self._total_fee_rate = str(quantize_feerate(comb_feerate))
try:
self._new_tx = self._wallet.wallet.cpfp(self._parent_tx, fee)
@ -864,6 +852,9 @@ class QETxCpfpFeeBumper(TxFeeSlider, TxMonMixin):
self.warning = str(e)
return
child_feerate = fee / self._new_tx.estimated_size()
self.feeRate = str(quantize_feerate(child_feerate))
self.update_inputs_from_tx(self._new_tx)
self.update_outputs_from_tx(self._new_tx)

Loading…
Cancel
Save