kivy tx dialog: "action button" can have multiple options -> dropdown
This commit is contained in:
@@ -1,14 +1,21 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
from typing import NamedTuple, Callable
|
||||||
|
|
||||||
from kivy.app import App
|
from kivy.app import App
|
||||||
from kivy.factory import Factory
|
from kivy.factory import Factory
|
||||||
from kivy.properties import ObjectProperty
|
from kivy.properties import ObjectProperty
|
||||||
from kivy.lang import Builder
|
from kivy.lang import Builder
|
||||||
from kivy.clock import Clock
|
from kivy.clock import Clock
|
||||||
from kivy.uix.label import Label
|
from kivy.uix.label import Label
|
||||||
|
from kivy.uix.dropdown import DropDown
|
||||||
|
from kivy.uix.button import Button
|
||||||
|
|
||||||
|
from .question import Question
|
||||||
from electrum.gui.kivy.i18n import _
|
from electrum.gui.kivy.i18n import _
|
||||||
from datetime import datetime
|
|
||||||
from electrum.util import InvalidPassword
|
from electrum.util import InvalidPassword
|
||||||
|
|
||||||
|
|
||||||
Builder.load_string('''
|
Builder.load_string('''
|
||||||
|
|
||||||
<TxDialog>
|
<TxDialog>
|
||||||
@@ -73,15 +80,13 @@ Builder.load_string('''
|
|||||||
size_hint: 1, None
|
size_hint: 1, None
|
||||||
height: '48dp'
|
height: '48dp'
|
||||||
Button:
|
Button:
|
||||||
|
id: action_button
|
||||||
size_hint: 0.5, None
|
size_hint: 0.5, None
|
||||||
height: '48dp'
|
height: '48dp'
|
||||||
text: _('Sign') if root.can_sign else _('Broadcast') if root.can_broadcast else _('Bump fee') if root.can_rbf else ''
|
text: ''
|
||||||
disabled: not(root.can_sign or root.can_broadcast or root.can_rbf)
|
disabled: True
|
||||||
opacity: 0 if self.disabled else 1
|
opacity: 0
|
||||||
on_release:
|
on_release: root.on_action_button_clicked()
|
||||||
if root.can_sign: root.do_sign()
|
|
||||||
if root.can_broadcast: root.do_broadcast()
|
|
||||||
if root.can_rbf: root.do_rbf()
|
|
||||||
IconButton:
|
IconButton:
|
||||||
size_hint: 0.5, None
|
size_hint: 0.5, None
|
||||||
height: '48dp'
|
height: '48dp'
|
||||||
@@ -95,6 +100,12 @@ Builder.load_string('''
|
|||||||
''')
|
''')
|
||||||
|
|
||||||
|
|
||||||
|
class ActionButtonOption(NamedTuple):
|
||||||
|
text: str
|
||||||
|
func: Callable
|
||||||
|
enabled: bool
|
||||||
|
|
||||||
|
|
||||||
class TxDialog(Factory.Popup):
|
class TxDialog(Factory.Popup):
|
||||||
|
|
||||||
def __init__(self, app, tx):
|
def __init__(self, app, tx):
|
||||||
@@ -102,6 +113,7 @@ class TxDialog(Factory.Popup):
|
|||||||
self.app = app
|
self.app = app
|
||||||
self.wallet = self.app.wallet
|
self.wallet = self.app.wallet
|
||||||
self.tx = tx
|
self.tx = tx
|
||||||
|
self._action_button_fn = lambda btn: None
|
||||||
|
|
||||||
def on_open(self):
|
def on_open(self):
|
||||||
self.update()
|
self.update()
|
||||||
@@ -131,6 +143,44 @@ class TxDialog(Factory.Popup):
|
|||||||
self.fee_str = format_amount(fee) if fee is not None else _('unknown')
|
self.fee_str = format_amount(fee) if fee is not None else _('unknown')
|
||||||
self.can_sign = self.wallet.can_sign(self.tx)
|
self.can_sign = self.wallet.can_sign(self.tx)
|
||||||
self.ids.output_list.update(self.tx.get_outputs_for_UI())
|
self.ids.output_list.update(self.tx.get_outputs_for_UI())
|
||||||
|
self.update_action_button()
|
||||||
|
|
||||||
|
def update_action_button(self):
|
||||||
|
action_button = self.ids.action_button
|
||||||
|
options = (
|
||||||
|
ActionButtonOption(text=_('Sign'), func=lambda btn: self.do_sign(), enabled=self.can_sign),
|
||||||
|
ActionButtonOption(text=_('Broadcast'), func=lambda btn: self.do_broadcast(), enabled=self.can_broadcast),
|
||||||
|
ActionButtonOption(text=_('Bump fee'), func=lambda btn: self.do_rbf(), enabled=self.can_rbf),
|
||||||
|
)
|
||||||
|
num_options = sum(map(lambda o: bool(o.enabled), options))
|
||||||
|
# if no options available, hide button
|
||||||
|
if num_options == 0:
|
||||||
|
action_button.disabled = True
|
||||||
|
action_button.opacity = 0
|
||||||
|
return
|
||||||
|
action_button.disabled = False
|
||||||
|
action_button.opacity = 1
|
||||||
|
|
||||||
|
if num_options == 1:
|
||||||
|
# only one option, button will correspond to that
|
||||||
|
for option in options:
|
||||||
|
if option.enabled:
|
||||||
|
action_button.text = option.text
|
||||||
|
self._action_button_fn = option.func
|
||||||
|
else:
|
||||||
|
# multiple options. button opens dropdown which has one sub-button for each
|
||||||
|
dropdown = DropDown()
|
||||||
|
action_button.text = _('Options')
|
||||||
|
self._action_button_fn = dropdown.open
|
||||||
|
for option in options:
|
||||||
|
if option.enabled:
|
||||||
|
btn = Button(text=option.text, size_hint_y=None, height=48)
|
||||||
|
btn.bind(on_release=option.func)
|
||||||
|
dropdown.add_widget(btn)
|
||||||
|
|
||||||
|
def on_action_button_clicked(self):
|
||||||
|
action_button = self.ids.action_button
|
||||||
|
self._action_button_fn(action_button)
|
||||||
|
|
||||||
def do_rbf(self):
|
def do_rbf(self):
|
||||||
from .bump_fee_dialog import BumpFeeDialog
|
from .bump_fee_dialog import BumpFeeDialog
|
||||||
|
|||||||
Reference in New Issue
Block a user