def on_start(self): # on ios we have to change the status bar color right when we are up. if platform == 'ios': from pyobjus import autoclass, objc_str ObjcClass = autoclass('ObjcClassINSD') o_instance = ObjcClass.alloc().init() o_instance.lightStatusBar() print('App started') from modules.core.android_utils import RemoveTutorialScreen RemoveTutorialScreen() from modules.core.android_utils import Toast Toast('logging in...', True) from utilities.notification import stopNotificationService, getLastNotificationMessage stopNotificationService() # make sure that if we started from a notification we act accordingly. keys = getLastNotificationMessage() if keys: from kivy.clock import Clock def switchscreens(*largs): from api.streams.posts import Manager as PostsManager if not PostsManager.logged_in: Clock.schedule_once(switchscreens, 0.125) return if len(keys) == 1: s = self.root.manager.get_screen('favs') s.fake_click_for_item = keys[0] self.root.manager.current = 'favs' Clock.schedule_once(switchscreens, 0.125)
def send_osc_go_on_signal(*args): osc_address = osc_go_address #send the gate on signal (ie the rising edge of the gate signal) send_osc_message(osc_address, [1.0]) #queue up the gate off signal (ie the falling edge) Clock.schedule_once(send_osc_go_off_signal, _osc_go_delay)
def move_leftright(self, right): r = range(3, -1, -1) if right else range(4) grid = self.grid moved = False for iy in range(4): # get all the cube for the current line cubes = [] for ix in r: cube = grid[ix][iy] if cube: cubes.append(cube) # combine them self.combine(cubes) # update the grid for ix in r: cube = cubes.pop(0) if cubes else None if grid[ix][iy] != cube: moved = True grid[ix][iy] = cube if not cube: continue pos = self.index_to_pos(ix, iy) if cube.pos != pos: cube.move_to(pos) if not self.check_end() and moved: Clock.schedule_once(self.spawn_number, tempo)
def __init__(self, **kwargs): super(LayoutFunctioning, self).__init__(**kwargs) # Enable send_btn after some seconds self.cb_disablesend = lambda dt: self.disablesend(False) Clock.schedule_once(self.cb_disablesend, self.send_disabled_t) # When previously saw finish screen if self.master_kanji.cur_framenum == -1: self.master_kanji.nextkanji() self.reinitscreen(0) else: self.reinitscreen(self.master_kanji.dbcurrent("nextKanji")) # First time opening app show explanation story if self.master_kanji.cur_framenum == 0: print("First time app") self.master_kanji.story_show = True # Link button to website print("!!! DEBUG UTF-8 !!!") #print(self.master_kanji.cur_framekanji) print(type(self.master_kanji.cur_framekanji)) self.ww_link = "http://kanji.koohii.com/study/kanji/{}".format(self.master_kanji.cur_framekanji) # "TODO") # Keyboard height #Clock.schedule_once(lambda dt: self.storykeybheight()) print("Keyboard binding") Window.bind(on_keyboard=self.storykeybheight) print("--- INIT LayoutFunctioning COMPLETED ---\n")
def move_topdown(self, top, from_keyboard=False): r = range(self.dim - 1, -1, -1) if top else range(self.dim) grid = self.grid moved = False for ix in range(self.dim): # get all the cube for the current line cubes = [] for iy in r: cube = grid[ix][iy] if cube: cubes.append(cube) # combine them self.combine(cubes) # update the grid for iy in r: cube = cubes.pop(0) if cubes else None if grid[ix][iy] != cube: moved = True grid[ix][iy] = cube if not cube: continue pos = self.index_to_pos(ix, iy) if cube.pos != pos: cube.move_to(pos) if from_keyboard: return moved elif not self.check_end() and moved: Clock.schedule_once(self.spawn_number, .20)
def on_touch_down(self, touch): if self._touch: return super(ScrollView, self).on_touch_down(touch) if not self.collide_point(*touch.pos): return # support scrolling ! if self._viewport and 'button' in touch.profile and \ touch.button.startswith('scroll'): # distance available to move, if no distance, do nothing vp = self._viewport if vp.height > self.height: # let's say we want to move over 40 pixels each scroll d = (vp.height - self.height) d = self.scroll_distance / float(d) if touch.button == 'scrollup': syd = self.scroll_y - d elif touch.button == 'scrolldown': syd = self.scroll_y + d self.scroll_y = min(max(syd, 0), 1) return True self._touch = touch uid = self._get_uid() touch.grab(self) touch.ud[uid] = { 'mode': 'unknown', 'sx': self.scroll_x, 'sy': self.scroll_y, 'dt': None, 'time': touch.time_start} Clock.schedule_once(self._change_touch_mode, self.scroll_timeout/1000.) return True
def _setup_default_tab(self): if self._default_tab in self.tab_list: return content = self._default_tab.content _tabs = self._tab_strip cls = self.default_tab_cls if not issubclass(cls, TabbedPanelHeader): raise TabbedPanelException('`default_tab_class` should be\ subclassed from `TabbedPanelHeader`') # no need to instanciate if class is TabbedPanelHeader if cls != TabbedPanelHeader: self._current_tab = self._original_tab = self._default_tab = cls() default_tab = self.default_tab if self._original_tab == self.default_tab: default_tab.text = self.default_tab_text default_tab.height = self.tab_height default_tab.group = '__tab%r__' % _tabs.uid default_tab.state = 'down' default_tab.width = self.tab_width if self.tab_width else 100 default_tab.content = content tl = self.tab_list if default_tab not in tl: _tabs.add_widget(default_tab, len(tl)) if default_tab.content: self.clear_widgets() self.add_widget(self.default_tab.content) else: Clock.schedule_once(self._load_default_tab_content) self._current_tab = default_tab
def on_enter(self): anim = Animation( opacity=1.0, duration=2.0) # anim &= Animation(size=[self.menu_text.size[0]+4, self.menu_text[1]+4], duration=.2) anim.start(self.story_text1) Clock.schedule_once(self.show_text2, 2.0)
def __init__(self, **kwargs): self.slides = [] super(Slides, self).__init__(**kwargs) Window.bind(on_keyboard=self.on_keyboard) Clock.schedule_interval(self.increase_time, 1 / 30.0) Clock.schedule_once(self.init, 0) self.add_widget(SlidesForeground(slides=self))
def _sign_tx(self, tx, password, on_success, on_failure): try: self.wallet.sign_transaction(tx, password) except InvalidPassword: Clock.schedule_once(lambda dt: on_failure(_("Invalid PIN"))) return Clock.schedule_once(lambda dt: on_success(tx))
def __init__(self, **kwargs): self.register_event_type('on_subprocess_done') super(KivyConsole, self).__init__(**kwargs) # initialisations self.txtinput_command_line_refocus = False self.txtinput_run_command_refocus = False self.win = None self.scheduled = False self.command_history = [] self.command_history_pos = 0 self.command_status = 'closed' if sys.version_info >= (3, 0): self.cur_dir = os.getcwd() else: self.cur_dir = os.getcwdu() self.stdout = std_in_out(self, 'stdout') self.stdin = std_in_out(self, 'stdin') # self.stderror = stderror(self) # delayed initialisation Clock.schedule_once(self._initialize) self_change_txtcache = self._change_txtcache _trig = Clock.create_trigger(self_change_txtcache) self.bind(textcache=_trig) self._hostname = 'unknown' try: if hasattr(os, 'uname'): self._hostname = os.uname()[1] else: self._hostname = os.environ.get('COMPUTERNAME', 'unknown') except Exception: pass self._username = os.environ.get('USER', '') if not self._username: self._username = os.environ.get('USERNAME', 'unknown')
def test_schedule_once_draw_before(self): from kivy.clock import Clock Clock.schedule_once(callback, -1) Clock.tick_draw() self.assertEqual(counter, 1) Clock.tick() self.assertEqual(counter, 1)
def test_unschedule_after_tick(self): from kivy.clock import Clock Clock.schedule_once(callback, 5.) Clock.tick() Clock.unschedule(callback) Clock.tick() self.assertEqual(counter, 0)
def next(self,*largs): Clock.unschedule(self.next) if(self.screenManager.current == 'page1'): next = 'page2' page = self.page2 else: next = 'page1' page = self.page1 self.index += 1 if self.index == len(self.photos): self.index = 0 page.source = self.photos[self.index] page.background.scale = 1.0 self.screenManager.transition = self.transitions[random.randint(0, len(self.transitions) -1)] self.screenManager.current = next anim = Animation( scale=page.background.scale*1.3, duration=15.0 ) Clock.schedule_once(self.next, 10) anim.start(page.background)
def _on_click(self, sid): if sid == 'msgbox': XMessage(text='It could be your Ad', title='XMessage demo') elif sid == 'error': XError(text='Don`t panic! Its just the XError demo.') elif sid == 'confirm': XConfirmation(text='Do you see a confirmation?', on_dismiss=self._callback) elif sid == 'progress': self._o_popup = XProgress(title='PopupProgress demo', text='Processing...', max=200) Clock.schedule_once(self._progress_test, .1) elif sid == 'input': XTextInput(title='Edit text', text='I\'m a text', on_dismiss=self._callback) elif sid == 'notes': XNotes(title='Edit notes', on_dismiss=self._callback_notes, lines=['Text', 'Too many text...', 'Yet another row.']) elif sid == 'slider': self._o_popup = XSlider( min=.4, max=.9, value=.5, size_hint=(.6, .5), title_template='Slider test, Value: %0.2f', buttons=['Horizontal', 'Vertical', 'Close'], on_change=self._slider_value, on_dismiss=self._slider_click) elif sid == 'login': XAuthorization( on_dismiss=self._callback, login='******', required_fields={'login': '******', 'password': '******'}, password='******')
def build(self): self.load_data() root = Widget(size=(1080,1920), size_hint=(None, None)) self.movie_screen = MovieScreen(app=self) root.add_widget(self.movie_screen) self.thank_you_screen = ThankYouScreen(app=self) root.add_widget(self.thank_you_screen) self.info_screen = InfoScreen(app=self) root.add_widget(self.info_screen) self.layout = root viewport = Viewport(size=(1080,1920)) Clock.schedule_once(viewport.fit_to_window) viewport.add_widget(Image(source='images/mainbg.png', pos=(0,0), size=(1080,1920))) viewport.add_widget(root) self.logo = LogoImage(source='images/logo.png', y=1620, size=(1080,300), bgcolor=[.1,.1,.1]) viewport.add_widget(self.logo) self.active_screen = self.info_screen Clock.schedule_once(self.start) Clock.schedule_interval(self.print_fps, 2.0) return viewport
def stay(self,instance): # Disable the users buttons for btn in self.player_btns.children: btn.disabled = True #Begin dealer draw Clock.schedule_once(self.parent.parent.begin_dealer)
def __init__(self,*args,**kwargs): super(CajaUnoUno,self).__init__(*args,**kwargs) self.frecuencias = ['125','250','500','1000','1500','2000','3000','4000','6000','8000'] self.atenuacion_h_prima = ['0','0','0','0','0','0','0','0','0','0'] self.atenuacion_h = ['0','0','0','0','0','0','0','0','0','0'] Clock.schedule_once(self.on_carga, 1)
def __init__(self,*args,**kwargs): super(Protegete,self).__init__(*args,**kwargs) self.frecuencias_prt = ['63','125','250','500','1000','1500','2000','3000','4000','6000','8000'] self.interpolado_protectores = ['0','0','0','0','0','0','0','0','0','0','0'] self.atenuacion_protegido = ['0','0','0','0','0','0','0','0','0','0','0'] Clock.schedule_once(self.in_carga, 1)
def on_touch_down(self, touch): """Either make a new tower, or display menu for an existing one """ tower_coord = (touch.x // self.cell_width // TOWER_SIZE * TOWER_SIZE, touch.y // self.cell_height // TOWER_SIZE * TOWER_SIZE) matrix_coord = tower_coord[0] + 1, tower_coord[1] + 1 if self.matrix[matrix_coord] < 0: # On tower? for tower in self.towers: # Yes, relay the touch to it if tower.coord == tower_coord: tower.on_touch_down(touch) break else: # Not on tower pass else: # On free space – make tower side = int(touch.x > self.window_width / 2) if self.funds[side] >= 0: size = (self.cell_width * TOWER_SIZE, self.cell_height * TOWER_SIZE) tower = Tower( pos=( touch.x // size[0] * size[0], touch.y // size[1] * size[1]), size=size, side=side ) tower.coord = tower_coord if self.add_tower(tower): tower.on_touch_down(touch) else: # Tower would block; display message to that effect label = Label( text='Blocking!', pos=(-50, -50), size=(100, 100), font_size=self.cell_width * 2, color=(1, 1, 1, 1), ) self.add_widget(label) with label.canvas.before: PushMatrix() Translate(touch.pos[0], touch.pos[1], 0) Rotate(90 if side else 270, 0, 0, 1) with label.canvas.after: PopMatrix() # Animate and fade out the message anim = Animation(font_size=TOWER_PIXEL_SIZE * 2, color=(1, 1, 1, 0), duration=1, t='in_quad') anim.start(label) def tick_blocking_anim(dt): label.canvas.ask_update() Clock.schedule_once(tick_blocking_anim) tick_blocking_anim(0) def end_blocking_anim(dt): self.remove_widget(label) Clock.unschedule(tick_blocking_anim) Clock.schedule_once(end_blocking_anim, 1)
def __init__(self, direction, hp, **kwargs): """Initialize a Critter `direction`: direction in radians that the critter is facing initially `hp`: Health of the Critter """ Widget.__init__(self, **kwargs) # Max health self.hp = hp # Direction we're facing currently self.direction = direction # Speed in tiles per second self.speed = CRITTER_SPEED # Damage done (accessed through .damage) self._damage = 0 # Are we dead yet? self.dead = False # x-component of velocity self.xdir = int(numpy.sign(round(numpy.cos(direction)))) # y-component of velocity self.ydir = int(numpy.sign(round(numpy.sin(direction)))) # Initial velocity self.initial_dir = self.xdir, self.ydir self.draw() Clock.schedule_once(self.go) Clock.schedule_once(self.tick)
def draw_shot(self, dt=0): """Draw the cannon and shot (in a layer above the level markings) """ if not self.parent: return self.canvas.after.clear() with self.canvas.after: # Shot if self.target: # Fade out the shot dirung 1/4 the time beteen shots self.shot_opacity -= dt * self.interval * 4 # Draw shot & schedule next draw if self.shot_opacity > 0: Color(1, 0, 0, self.shot_opacity) Line(points=itertools.chain(self.center, self.target.pos)) Clock.schedule_once(self.draw_shot) # Set cannon direction self.direction = numpy.arctan2( self.target.pos[1] - self.center[1], self.target.pos[0] - self.center[0], ) # Draw the cannon (if at least lv. 1) Color(0, 0, 0) if self.level: center = self.center direction = self.direction cell_size = self.parent.cell_size LineWidth(self.level) Line(points=itertools.chain(self.center, ( float(center[0] + numpy.cos(direction) * cell_size), float(center[1] + numpy.sin(direction) * cell_size), ))) LineWidth(1)
def activate_screen_outputs(self, screen): if self._out_actv: return self._out_actv = True Clock.schedule_once( lambda dt: self._activate_screen_outputs(screen), .1)
def test_y(self, y): if y[0] < self.y_min or y[1] > self.y_max or abs(y[0] - self.y_min) > 10 or abs(y[1] - self.y_max) > 10 \ or self.y_tick == 0: self.update_points = False self.graph_kill() Clock.schedule_once(partial(self.graph_build, self.graph_type), 1)
def activate_screen_transactionid(self, screen): if self._trans_actv: return self._trans_actv = True Clock.schedule_once( lambda dt: self._activate_screen_transactionid(screen), .1)
def on_volts(self, mapBin, instance): value = instance.text.strip() if value == '' or value == "." or value == "-": value = 0 instance.text = str(value) try: value = float(value) if self.scaling_map: self.scaling_map.setVolts(mapBin, value) self.dispatch('on_map_updated') self.regen_plot() except ScalingMapException as e: warn = CenteredBubble() warn.add_widget(WarnLabel(text=str(e))) warn.auto_dismiss_timeout(WARN_DISMISS_TIMEOUT) warn.background_color = (1, 0, 0, 1.0) warn.size = (dp(200), dp(50)) warn.size_hint = (None,None) self.get_root_window().add_widget(warn) warn.center_on(instance) original_value = self.scaling_map.getVolts(mapBin) self.set_volts_cell(instance, original_value) Clock.schedule_once(lambda dt: self._refocus(instance)) except Exception as e: alertPopup('Scaling Map', str(e)) original_value = self.scaling_map.getVolts(mapBin) self.set_volts_cell(instance, original_value)
def on_focus(self, instance, value, *largs): win = self._win if not win: self._win = win = self.get_root_window() if not win: # we got argument, it could be the previous schedule # cancel focus. if len(largs): Logger.warning('Textinput: ' 'Cannot focus the element, unable to get root window') return else: Clock.schedule_once(partial(self.on_focus, self, value), 0) return if value: keyboard = win.request_keyboard(self._keyboard_released, self) self._keyboard = keyboard keyboard.bind( on_key_down=self._keyboard_on_key_down, on_key_up=self._keyboard_on_key_up) Clock.schedule_interval(self._do_blink_cursor, 1 / 2.) else: keyboard = self._keyboard keyboard.unbind( on_key_down=self._keyboard_on_key_down, on_key_up=self._keyboard_on_key_up) keyboard.release() self.cancel_selection() Clock.unschedule(self._do_blink_cursor) self._win = None
def on_activate(self): # do activate routine here slide = None if not self._loaded: self._loaded = True CarouselHeader = Factory.CarouselHeader ch = CarouselHeader() ch.slide = 0 # idx slide = Factory.ScreenAddress() slide.tab = ch self.add_widget(slide) self.add_widget(ch) app = App.get_running_app() if not slide: slide = self.carousel_content.carousel.slides[0] # add a tab for each wallet self.wallet_name = app.wallet.get_account_names()[0] labels = app.wallet.labels addresses = app.wallet.addresses() _labels = {} for address in addresses: _labels[labels.get(address, address)] = address slide.labels = _labels Clock.schedule_once(lambda dt: self._setup_slide(slide))
def reinitscreen(self, nxt_cur): # No answer given yet if nxt_cur == 0: print("Reinit: no answer") self.next_kanji = False self.answered = 0 self.master_kanji.story_show = False # Correct answer elif nxt_cur == 1: print("Reinit: correct") self.next_kanji = True self.answered = 1 self.master_kanji.story_show = True Clock.unschedule(self.cb_disablesend) self.disablesend(False) # Wrong answer else: print("Reinit: wrong") self.next_kanji = False self.answered = 1 self.master_kanji.story_show = True # Answers bold in self.story #self.master_kanji.story_bold() # sKanji buttons (Clock.schedule to call this function after .kv initialisation) Clock.schedule_once(lambda dt: self.changeSKanji())
def upgrade_tick(self, dt): """Called each frame when upgrading (or cancelling upgrade) """ if not self.parent: return # Upgrade “progress units” are € # Figure out amount of upgrade amount = self.upgrading_direction * dt * self.build_speed # Clamp to wha is needed for the tower amount = clamp(amount, -self.upgrade_spent, self.upgrade_cost - self.upgrade_spent) # Ask player to pay the corresponding amount (this might lower the # amount, or even make it negative!) amount = self.parent.pay(self.side, amount) self.upgrade_spent += amount if (self.upgrading_direction > 0 and self.upgrade_cost == self.upgrade_spent): self.upgrade() self.upgrading_direction = 0 #self.touch_uid = None elif self.upgrade_spent < 0 or (self.upgrade_spent == 0 and self.upgrading_direction < 0): self.parent.pay(self.side, -self.upgrade_spent) self.upgrading_direction = 0 if self.level == 0: self.parent.remove_tower(self) else: Clock.schedule_once(self.upgrade_tick) self.draw()
def change_color(self, color, timer): Clock.schedule_once(partial(change_color_main, self, color), timer)
def update_config(self, save_to_file=True): super().update_config(save_to_file=save_to_file) self.katrain.update_calculated_ranks() Clock.schedule_once(self.katrain.controls.update_players, 0)
def __init__(self, katrain): super().__init__() self.katrain = katrain self.popup = None Clock.schedule_once(self.build_and_set_properties, 0)
def show_error(message): chat_app.info_page.update_info(message) chat_app.screen_manager.current = 'Info' Clock.schedule_once(sys.exit, 10)
def __init__(self, **kwargs): super().__init__(**kwargs) Clock.schedule_once(lambda dt: self.setup(), 0)
def sh_cb(self, cmd, data=None): #Logger.info("%s %s" % (cmd, str(data))) if cmd == "connected": Logger.info("connected") self.popup.title = "Getting values from SkyBean" self.popup.set_progress(0) self.block_set = True # self.set_status("Connected (%s)" % data) self.get_value("volume") self.get_value("auto_power_off") self.get_value("active_profile") self.get_value("silent_start") self.get_value("fluid_audio") self.get_value("lift_1") self.get_value("lift_2") self.get_value("lift_3") self.get_value("lift_4") self.get_value("lift_5") self.get_value("sink_1") self.get_value("sink_2") self.get_value("sink_3") self.get_value("sink_4") self.get_value("sink_5") self.get_value("index_lift") self.get_value("index_sink") for i in range(41): self.get_value("freq_%d" % i) self.get_value("pause_%d" % i) self.get_value("length_%d" % i) self.get_value("END") self.values_to_get = len(self.to_get) if cmd == "all_done": self.block_set = False self.popup.dismiss() if cmd == "get_value": p = 1 - (len(self.to_get) / self.values_to_get) self.popup.set_progress(p * 100) value_name, value_data = data Logger.info("get_value %s = %s" % (value_name, str(value_data))) self.update_gui(value_name, value_data) if cmd == "set_value": Logger.info("set_value") if cmd == "idle": if self.set_next_value(): return if self.get_next_value(): return if cmd == "disconnected": Logger.info("disconnected") Clock.schedule_once(self.popup.open) self.popup.title = "Please connect SkyBean" self.popup.set_progress(0)
def get_color_2(self, timer): Clock.schedule_once(partial(get_color_main, self), timer) return colors
def __init__(self, **kwargs): super(NavigationDrawerButton, self).__init__(**kwargs) self.lbl_icon = LeftIcon(font_style='Icon', theme_text_color='Custom', text_color=(0, 0, 0, 0.54)) Clock.schedule_once(self.initialization_instructions)
def __init__(self, **kwargs): super(Dash, self).__init__(**kwargs) Clock.schedule_once(self.delay, 1)
def move_left(self, times, timer, animation="in_out_cubic"): Clock.schedule_once(partial(move_left_main, self, times, animation), timer)
def _listen_screen_touch(self, instance, event): if self.go_home_schedule: self.go_home_schedule.cancel() self.go_home_schedule = Clock.schedule_once(self._show_gohome_modal, 180)
def on_enter(self): Clock.schedule_once(self.on_dismiss, SPLASH_TIME)
def _pay_error(self): self.count_down_schedule.cancel() self.order_state_schedule.cancel() self._show_warning('Payment canceled.') Clock.schedule_once(self._go_home, 2)
def _delay_init(self, time): if self._init_qrcode(): self.count_down_schedule = Clock.schedule_once(self._count_down, 1) self.order_state_schedule = Clock.schedule_interval( self._listen_order_state, 5)
def on_current_language(self, *args): # Language is switched AFTER this event fires, so we have to reschedule to next frame. Clock.schedule_once(lambda dt: self._update_language(), 1)
def _init_qrcode(self): Clock.schedule_once(self._get_qrcode, 1) return True
def on_amount_or_message(self): self.save_request() Clock.schedule_once(lambda dt: self.update_qr())
def call_test(self, func): a = TestApp() p = partial(func, a) Clock.schedule_once(p, 0.0001) a.run()
def on_touch_down(self, touch): self.jumping = True self.bird_image.source = "images/flappynormal.png" self.velocity_y = self.jump_height / (self.jump_time * 60.0) Clock.unschedule(self.stop_jumping) Clock.schedule_once(self.switch_to_normal, self.jump_time / 5.0)
def on_enter(self): # FIXME: use a proper event don't use animation time of screen Clock.schedule_once(lambda dt: self.dispatch('on_activate'), .25) pass
def show_error(self, msg): app = App.get_running_app() Clock.schedule_once(lambda dt: app.show_error(msg))
def func(f=v): Clock.schedule_once(lambda dt: f(obj), 0.15)
def __init__(self, **kwargs): super(BaseButton, self).__init__(**kwargs) Clock.schedule_once(self._finish_init)
def switch_to_normal(self, dt): self.bird_image.source = "images/flappyup.png" Clock.schedule_once(self.stop_jumping, self.jump_time * (4.0 / 5.0))
def delayed_func(*args, **kwargs): def callback_func(dt): func(*args, **kwargs) Clock.schedule_once(callback_func, 0)
def close_message_soon(self, message_popup, when): Clock.schedule_once(lambda dt: message_popup.dismiss(), when)
def on_stop(*l): if duration: Clock.schedule_once(self.hide, duration + .5)
def show_error(self, msg): Clock.schedule_once(lambda dt: app.show_error(msg))
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 copy_to_clipboard(self): Clipboard.copy(self.data) msg = _('Text copied to clipboard.') Clock.schedule_once(lambda dt: self.app.show_info(msg))