Browse Source

kivy tx dialog: abstract away ActionDropdown, mv into its own file

master
SomberNight 5 years ago
parent
commit
b8ec85d615
No known key found for this signature in database
GPG Key ID: B33B5F232C6271E9
  1. 70
      electrum/gui/kivy/uix/actiondropdown.py
  2. 66
      electrum/gui/kivy/uix/dialogs/tx_dialog.py

70
electrum/gui/kivy/uix/actiondropdown.py

@ -0,0 +1,70 @@
from typing import NamedTuple, Callable, Sequence
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from electrum.gui.kivy.i18n import _
class ActionButtonOption(NamedTuple):
text: str
func: Callable[['Button'], None]
enabled: bool = True
class ActionDropdown(Button):
"""A button that offers a list of actions and can expand into a dropdown.
If the list of available actions:
- is empty, the button will be hidden,
- consists of a single option, the button will correspond to that,
- consists of multiple options, the button opens a dropdown which has one sub-button for each.
"""
def __init__(self, **kwargs):
Button.__init__(
self,
text='',
disabled=True,
opacity=0,
**kwargs,
)
self.dropdown_text = _('Options')
self._on_release = None
def update(self, *, options: Sequence[ActionButtonOption] = ()):
num_options = sum(map(lambda o: bool(o.enabled), options))
# if no options available, hide button
if num_options == 0:
self.disabled = True
self.opacity = 0
return
self.disabled = False
self.opacity = 1
if num_options == 1:
# only one option, button will correspond to that
for option in options:
if option.enabled:
self.text = option.text
self._on_release = option.func
else:
# multiple options. button opens dropdown which has one sub-button for each
dropdown = DropDown()
self.text = self.dropdown_text
self._on_release = dropdown.open
for option in options:
if option.enabled:
btn = Button(
text=option.text,
size_hint_y=None,
height=self.height,
halign='center',
valign='center',
)
btn.bind(on_release=option.func)
dropdown.add_widget(btn)
def on_release(self):
if self._on_release:
self._on_release(self)

66
electrum/gui/kivy/uix/dialogs/tx_dialog.py

@ -12,15 +12,16 @@ from kivy.uix.label import Label
from kivy.uix.dropdown import DropDown from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button from kivy.uix.button import Button
from .question import Question
from electrum.gui.kivy.i18n import _
from electrum.util import InvalidPassword from electrum.util import InvalidPassword
from electrum.address_synchronizer import TX_HEIGHT_LOCAL from electrum.address_synchronizer import TX_HEIGHT_LOCAL
from electrum.wallet import CannotBumpFee, CannotDoubleSpendTx from electrum.wallet import CannotBumpFee, CannotDoubleSpendTx
from electrum.transaction import Transaction, PartialTransaction from electrum.transaction import Transaction, PartialTransaction
from electrum.network import NetworkException from electrum.network import NetworkException
from ...util import address_colors
from electrum.gui.kivy.i18n import _
from electrum.gui.kivy.util import address_colors
from ..actiondropdown import ActionDropdown, ActionButtonOption
from .question import Question
if TYPE_CHECKING: if TYPE_CHECKING:
from ...main_window import ElectrumWindow from ...main_window import ElectrumWindow
@ -94,14 +95,10 @@ Builder.load_string('''
BoxLayout: BoxLayout:
size_hint: 1, None size_hint: 1, None
height: '48dp' height: '48dp'
Button: ActionDropdown:
id: action_button id: action_dropdown
size_hint: 0.5, None size_hint: 0.5, None
height: '48dp' height: '48dp'
text: ''
disabled: True
opacity: 0
on_release: root.on_action_button_clicked()
IconButton: IconButton:
size_hint: 0.5, None size_hint: 0.5, None
height: '48dp' height: '48dp'
@ -120,12 +117,6 @@ 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):
@ -133,7 +124,6 @@ class TxDialog(Factory.Popup):
self.app = app # type: ElectrumWindow self.app = app # type: ElectrumWindow
self.wallet = self.app.wallet self.wallet = self.app.wallet
self.tx = tx # type: Transaction self.tx = tx # type: Transaction
self._action_button_fn = lambda btn: None
# If the wallet can populate the inputs with more info, do it now. # If the wallet can populate the inputs with more info, do it now.
# As a result, e.g. we might learn an imported address tx is segwit, # As a result, e.g. we might learn an imported address tx is segwit,
@ -193,10 +183,10 @@ class TxDialog(Factory.Popup):
dict_entry['color'], dict_entry['background_color'] = address_colors(self.wallet, dict_entry['address']) dict_entry['color'], dict_entry['background_color'] = address_colors(self.wallet, dict_entry['address'])
self.can_remove_tx = tx_details.can_remove self.can_remove_tx = tx_details.can_remove
self.update_action_button() self.update_action_dropdown()
def update_action_button(self): def update_action_dropdown(self):
action_button = self.ids.action_button action_dropdown = self.ids.action_dropdown # type: ActionDropdown
# note: button texts need to be short; there is only horizontal space for ~13 chars # note: button texts need to be short; there is only horizontal space for ~13 chars
options = ( options = (
ActionButtonOption(text=_('Sign'), func=lambda btn: self.do_sign(), enabled=self.can_sign), ActionButtonOption(text=_('Sign'), func=lambda btn: self.do_sign(), enabled=self.can_sign),
@ -205,41 +195,7 @@ class TxDialog(Factory.Popup):
ActionButtonOption(text=_('Cancel') + '\n(double-spend)', func=lambda btn: self.do_dscancel(), enabled=self.can_dscancel), ActionButtonOption(text=_('Cancel') + '\n(double-spend)', func=lambda btn: self.do_dscancel(), enabled=self.can_dscancel),
ActionButtonOption(text=_('Remove'), func=lambda btn: self.remove_local_tx(), enabled=self.can_remove_tx), ActionButtonOption(text=_('Remove'), func=lambda btn: self.remove_local_tx(), enabled=self.can_remove_tx),
) )
num_options = sum(map(lambda o: bool(o.enabled), options)) action_dropdown.update(options=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='48dp',
halign='center',
valign='center',
)
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 _add_info_to_tx_from_wallet_and_network(self, tx: PartialTransaction) -> bool: def _add_info_to_tx_from_wallet_and_network(self, tx: PartialTransaction) -> bool:
"""Returns whether successful.""" """Returns whether successful."""

Loading…
Cancel
Save