electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

__init__.py (6089B)


      1 from typing import TYPE_CHECKING, Sequence
      2 
      3 from kivy.app import App
      4 from kivy.clock import Clock
      5 from kivy.factory import Factory
      6 from kivy.properties import NumericProperty, StringProperty, BooleanProperty
      7 from kivy.core.window import Window
      8 from kivy.uix.recycleview import RecycleView
      9 from kivy.uix.boxlayout import BoxLayout
     10 
     11 from electrum.gui.kivy.i18n import _
     12 
     13 if TYPE_CHECKING:
     14     from ...main_window import ElectrumWindow
     15     from electrum.transaction import TxOutput
     16 
     17 
     18 class AnimatedPopup(Factory.Popup):
     19     ''' An Animated Popup that animates in and out.
     20     '''
     21 
     22     anim_duration = NumericProperty(.36)
     23     '''Duration of animation to be used
     24     '''
     25 
     26     __events__ = ['on_activate', 'on_deactivate']
     27 
     28 
     29     def on_activate(self):
     30         '''Base function to be overridden on inherited classes.
     31         Called when the popup is done animating.
     32         '''
     33         pass
     34 
     35     def on_deactivate(self):
     36         '''Base function to be overridden on inherited classes.
     37         Called when the popup is done animating.
     38         '''
     39         pass
     40 
     41     def open(self):
     42         '''Do the initialization of incoming animation here.
     43         Override to set your custom animation.
     44         '''
     45         def on_complete(*l):
     46             self.dispatch('on_activate')
     47 
     48         self.opacity = 0
     49         super(AnimatedPopup, self).open()
     50         anim = Factory.Animation(opacity=1, d=self.anim_duration)
     51         anim.bind(on_complete=on_complete)
     52         anim.start(self)
     53 
     54     def dismiss(self):
     55         '''Do the initialization of incoming animation here.
     56         Override to set your custom animation.
     57         '''
     58         def on_complete(*l):
     59             super(AnimatedPopup, self).dismiss()
     60             self.dispatch('on_deactivate')
     61 
     62         anim = Factory.Animation(opacity=0, d=.25)
     63         anim.bind(on_complete=on_complete)
     64         anim.start(self)
     65 
     66 class EventsDialog(Factory.Popup):
     67     ''' Abstract Popup that provides the following events
     68     .. events::
     69         `on_release`
     70         `on_press`
     71     '''
     72 
     73     __events__ = ('on_release', 'on_press')
     74 
     75     def __init__(self, **kwargs):
     76         super(EventsDialog, self).__init__(**kwargs)
     77 
     78     def on_release(self, instance):
     79         pass
     80 
     81     def on_press(self, instance):
     82         pass
     83 
     84 
     85 class SelectionDialog(EventsDialog):
     86 
     87     def add_widget(self, widget, index=0):
     88         if self.content:
     89             self.content.add_widget(widget, index)
     90             return
     91         super(SelectionDialog, self).add_widget(widget)
     92 
     93 
     94 class InfoBubble(Factory.Bubble):
     95     '''Bubble to be used to display short Help Information'''
     96 
     97     message = StringProperty(_('Nothing set !'))
     98     '''Message to be displayed; defaults to "nothing set"'''
     99 
    100     icon = StringProperty('')
    101     ''' Icon to be displayed along with the message defaults to ''
    102 
    103     :attr:`icon` is a  `StringProperty` defaults to `''`
    104     '''
    105 
    106     fs = BooleanProperty(False)
    107     ''' Show Bubble in half screen mode
    108 
    109     :attr:`fs` is a `BooleanProperty` defaults to `False`
    110     '''
    111 
    112     modal = BooleanProperty(False)
    113     ''' Allow bubble to be hidden on touch.
    114 
    115     :attr:`modal` is a `BooleanProperty` defauult to `False`.
    116     '''
    117 
    118     exit = BooleanProperty(False)
    119     '''Indicates whether to exit app after bubble is closed.
    120 
    121     :attr:`exit` is a `BooleanProperty` defaults to False.
    122     '''
    123 
    124     dim_background = BooleanProperty(False)
    125     ''' Indicates Whether to draw a background on the windows behind the bubble.
    126 
    127     :attr:`dim` is a `BooleanProperty` defaults to `False`.
    128     '''
    129 
    130     def on_touch_down(self, touch):
    131         if self.modal:
    132             return True
    133         self.hide()
    134         if self.collide_point(*touch.pos):
    135             return True
    136 
    137     def show(self, pos, duration, width=None, modal=False, exit=False):
    138         '''Animate the bubble into position'''
    139         self.modal, self.exit = modal, exit
    140         if width:
    141             self.width = width
    142         if self.modal:
    143             from kivy.uix.modalview import ModalView
    144             self._modal_view = m = ModalView(background_color=[.5, .5, .5, .2])
    145             Window.add_widget(m)
    146             m.add_widget(self)
    147         else:
    148             Window.add_widget(self)
    149 
    150         # wait for the bubble to adjust its size according to text then animate
    151         Clock.schedule_once(lambda dt: self._show(pos, duration))
    152 
    153     def _show(self, pos, duration):
    154 
    155         def on_stop(*l):
    156             if duration:
    157                 Clock.schedule_once(self.hide, duration + .5)
    158 
    159         self.opacity = 0
    160         arrow_pos = self.arrow_pos
    161         if arrow_pos[0] in ('l', 'r'):
    162             pos = pos[0], pos[1] - (self.height/2)
    163         else:
    164             pos = pos[0] - (self.width/2), pos[1]
    165 
    166         self.limit_to = Window
    167 
    168         anim = Factory.Animation(opacity=1, pos=pos, d=.32)
    169         anim.bind(on_complete=on_stop)
    170         anim.cancel_all(self)
    171         anim.start(self)
    172 
    173 
    174     def hide(self, now=False):
    175         ''' Auto fade out the Bubble
    176         '''
    177         def on_stop(*l):
    178             if self.modal:
    179                 m = self._modal_view
    180                 m.remove_widget(self)
    181                 Window.remove_widget(m)
    182             Window.remove_widget(self)
    183             if self.exit:
    184                 App.get_running_app().stop()
    185                 import sys
    186                 sys.exit()
    187             else:
    188                 App.get_running_app().is_exit = False
    189 
    190         if now:
    191             return on_stop()
    192 
    193         anim = Factory.Animation(opacity=0, d=.25)
    194         anim.bind(on_complete=on_stop)
    195         anim.cancel_all(self)
    196         anim.start(self)
    197 
    198 
    199 
    200 class OutputItem(BoxLayout):
    201     pass
    202 
    203 class OutputList(RecycleView):
    204 
    205     def __init__(self, **kwargs):
    206         super(OutputList, self).__init__(**kwargs)
    207         self.app = App.get_running_app()  # type: ElectrumWindow
    208 
    209     def update(self, outputs: Sequence['TxOutput']):
    210         res = []
    211         for o in outputs:
    212             value = self.app.format_amount_and_units(o.value)
    213             res.append({'address': o.get_ui_address_str(), 'value': value})
    214         self.data = res
    215 
    216 
    217 class TopLabel(Factory.Label):
    218     pass
    219 
    220 
    221 class RefLabel(TopLabel):
    222     pass