2 changed files with 81 additions and 55 deletions
@ -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) |
||||
Loading…
Reference in new issue