__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