electrum-bitcoinprivate/gui/kivy/uix/menus.py

96 lines
2.7 KiB
Python

from functools import partial
from kivy.animation import Animation
from kivy.core.window import Window
from kivy.clock import Clock
from kivy.uix.bubble import Bubble, BubbleButton
from kivy.properties import ListProperty
from kivy.uix.widget import Widget
from electrum_bitcoinprivate_gui.kivy.i18n import _
class ContextMenuItem(Widget):
'''abstract class
'''
class ContextButton(ContextMenuItem, BubbleButton):
pass
class ContextMenu(Bubble):
buttons = ListProperty([_('ok'), _('cancel')])
'''List of Buttons to be displayed at the bottom'''
__events__ = ('on_press', 'on_release')
def __init__(self, **kwargs):
self._old_buttons = self.buttons
super(ContextMenu, self).__init__(**kwargs)
self.on_buttons(self, self.buttons)
def on_touch_down(self, touch):
if not self.collide_point(*touch.pos):
self.hide()
return
return super(ContextMenu, self).on_touch_down(touch)
def on_buttons(self, _menu, value):
if 'menu_content' not in self.ids.keys():
return
if value == self._old_buttons:
return
blayout = self.ids.menu_content
blayout.clear_widgets()
for btn in value:
ib = ContextButton(text=btn)
ib.bind(on_press=partial(self.dispatch, 'on_press'))
ib.bind(on_release=partial(self.dispatch, 'on_release'))
blayout.add_widget(ib)
self._old_buttons = value
def on_press(self, instance):
pass
def on_release(self, instance):
pass
def show(self, pos, duration=0):
Window.add_widget(self)
# wait for the bubble to adjust it's size according to text then animate
Clock.schedule_once(lambda dt: self._show(pos, duration))
def _show(self, pos, duration):
def on_stop(*l):
if duration:
Clock.schedule_once(self.hide, duration + .5)
self.opacity = 0
arrow_pos = self.arrow_pos
if arrow_pos[0] in ('l', 'r'):
pos = pos[0], pos[1] - (self.height/2)
else:
pos = pos[0] - (self.width/2), pos[1]
self.limit_to = Window
anim = Animation(opacity=1, pos=pos, d=.32)
anim.bind(on_complete=on_stop)
anim.cancel_all(self)
anim.start(self)
def hide(self, *dt):
def on_stop(*l):
Window.remove_widget(self)
anim = Animation(opacity=0, d=.25)
anim.bind(on_complete=on_stop)
anim.cancel_all(self)
anim.start(self)
def add_widget(self, widget, index=0):
if not isinstance(widget, ContextMenuItem):
super(ContextMenu, self).add_widget(widget, index)
return
menu_content.add_widget(widget, index)