def on_release(self): rc = self.ripple_color anim = Animation( ripple_color=[rc[0], rc[1], rc[2], 0.], t=self.ripple_func_out, duration=self.ripple_duration_out) anim.bind(on_complete=self.anim_completed) anim.start(self)
def fade_out(self, duration): if duration == 0: self._a = 0. return anim = Animation(_a=0., duration=duration, t='out_quad') anim.bind(on_complete=lambda *x: self.dispatch('on_invisible')) anim.start(self)
class MDCheckbox(ThemableBehavior, CircularRippleBehavior, ToggleButtonBehavior, Label): active = BooleanProperty(False) _checkbox_icon = StringProperty( u"{}".format(md_icons['md-check-box-outline-blank'])) _radio_icon = StringProperty(u"{}".format(md_icons['md-radio-button-off'])) _icon_active = StringProperty(u"{}".format(md_icons['md-check-box'])) def __init__(self, **kwargs): super(MDCheckbox, self).__init__(**kwargs) self.register_event_type('on_active') self.check_anim_out = Animation(font_size=0, duration=.1, t='out_quad') self.check_anim_in = Animation(font_size=sp(24), duration=.1, t='out_quad') self.check_anim_out.bind( on_complete=lambda *x: self.check_anim_in.start(self)) def on_state(self, *args): if self.state == 'down': self.check_anim_in.cancel(self) self.check_anim_out.start(self) self._radio_icon = u"{}".format(md_icons['md-radio-button-on']) self._checkbox_icon = u"{}".format(md_icons['md-check-box']) self.active = True else: self.check_anim_in.cancel(self) self.check_anim_out.start(self) self._radio_icon = u"{}".format(md_icons['md-radio-button-off']) self._checkbox_icon = u"{}".format( md_icons['md-check-box-outline-blank']) self.active = False def on_active(self, instance, value): self.state = 'down' if value else 'normal'
def reanimate(self, w, val): self.rotate_z = 0 anim = Animation(rotate_z=360, duration=3) anim.bind(on_complete=self.reanimate) anim.start(self)
def login(self): animation = Animation(x=self.login_area.x - self.login_area.width, duration=0.8) animation.start(self.login_area) self.pan_screen= Image(source= "mylogo1.jpg", keep_ratio= False, allow_stretch= True, color= (1, 1, 1, 0.1)) self.add_widget(self.pan_screen) animation.bind(on_complete=self.check_login)
def prepare_next(self,dt): self.generateGameQuestion(self.level) self.y=self.parent.height/2-self.height/1.5 self.x=-self.width-10 anim=Animation(x=10,d=self.levelSpeed/4,t="in_out_back") anim.bind(on_complete=self.prepareQuestionPanel) anim.start(self)
def update(self, widget=None, event=None): self.image_hero.angle = 0 self.image_baddy.angle = 0 try: self.current_gem.remove_widget(self.current_gem.children[-1]) self.scatter_hero.remove_widget(self.current_gem) except: pass anim1 = Animation(scale=self.baddy_size_ratio) anim2 = Animation(y= self.baddy_position[1]) anim3 = Animation(x= self.baddy_position[0]) anim4 = Animation(x = X_BLOCK) anim1.start(self.scatter_baddy) anim2.start(self.scatter_baddy) if self.time_limit < 0: anim3.start(self.scatter_baddy) anim4.start(self.scatter_hero) self.image_baddy.set_score(self.baddy_points) self.image_score.set_score(self.level_score) if self.scatter_baddy.scale > self.baddy_size_ratio: self.hero_celebrate() else: self.baddy_celebrate() if self.level_score < 0: self.image_score.flash(10) anim4.bind(on_complete = self.decide_next_stage)
def __init__(self, cows, difficulty, e_sound, s_sound): super(UFO, self).__init__() self.size = [UFO_WIDTH, UFO_HEIGHT] self.pos = [Window.center[0], Window.height] # self.engine_sound = SoundLoader.load('sound/ufo_engine.ogg') # self.shot_sound = SoundLoader.load('sound/ufo_shot.ogg') self.engine_sound = e_sound self.shot_sound = s_sound self.engine_sound.volume = 0.5 self.engine_sound.loop = True self.source = 'img/cows/ufo_03.png' self.cows = cows # self.victim = None self.difficulty = difficulty self.think_time = 3.5 - difficulty self.__all_engines_start() # self.__move_to_start_position() self.__chose_victim() anim = Animation(x=self.x, y=TOP_BORDER, d=0.5) _f = Clock.schedule_interval anim.bind(on_complete=lambda *args: _f(self.__move, FPS)) anim.start(self)
def open(self, *largs, **kwargs): '''Show the view window from the :attr:`attach_to` widget. If set, it will attach to the nearest window. If the widget is not attached to any window, the view will attach to the global :class:`~kivy.core.window.Window`. When the view is opened, it will be faded in with an animation. If you don't want the animation, use:: view.open(animation=False) ''' if self._window is not None: Logger.warning('ModalView: you can only open once.') return # search window self._window = self._search_window() if not self._window: Logger.warning('ModalView: cannot open view, no window found.') return self._window.add_widget(self) self._window.bind( on_resize=self._align_center, on_keyboard=self._handle_keyboard) self.center = self._window.center self.fbind('center', self._align_center) self.fbind('size', self._align_center) if kwargs.get('animation', True): a = Animation(_anim_alpha=1., d=self._anim_duration) a.bind(on_complete=lambda *x: self.dispatch('on_open')) a.start(self) else: self._anim_alpha = 1. self.dispatch('on_open')
def fader(self): self.img=Image(source="fader.jpg",allow_stretch=True) self.add_widget(self.img) self.img.opacity=0 anim=Animation(opacity=1,d=.5,t="out_sine") anim.bind(on_complete=self.fade_level) anim.start(self.img)
def _anim_back(self, *args): _angle_back_anim = Animation(_angle_start=self._angle_end - 8, duration=.6, t='in_out_cubic') _angle_back_anim.bind(on_complete=self._start_loop) _angle_back_anim.start(self)
class CalendarApp(App): # rightnow dateobject for alarms and such rightnow = ObjectProperty(dt.datetime.now()) memos = ObjectProperty(JsonStore('memos.json')) def __init__(self, **kwargs): Logger.info('Building App') super(CalendarApp, self).__init__(**kwargs) # Clock.schedule_interval(self.update_time, 1) self.popup = AlertPopup() self.anim_dismiss_popup = Animation(opacity=0, duration=1.5) self.anim_dismiss_popup.bind(on_complete=self.popup.dismiss) # update self.rightnow to a new datetime object every 1sec def update_time(self, *args): self.rightnow = dt.datetime.now() def build(self): main = Main() return main def alert(self, text): self.popup.label.text = text self.popup.open() self.popup.opacity = 1 self.anim_dismiss_popup.start(self.popup) def on_pause(self, *args): return True
def on_touch_down(self, touch, *args): if self.collide_point(*touch.pos): if not hasattr(self, '_sound') or self.state == 'down' and not self.loop: return if self.loop and self.state == 'down': if self.fadeout: a = Animation(volume=0, d=self.fadeout) a.bind(on_complete=lambda *x: self._sound.stop()) a.start(self._sound) else: self._sound.stop() elif self.fadein: self._sound.volume = 0 a = Animation(volume=self.volume, d=self.fadein) a.start(self._sound) self._sound.play() if self.fadeout: a = Animation(d=self._sound.length - self.fadeout) + Animation(volume=0, d=self.fadeout) a.start(self._sound) else: self._sound.play() else: return super(PlayButton, self).on_touch_down(touch, *args)
def add_explosion(self, line): line += self.currently_exploding self.currently_exploding += 1 explosion = InstructionGroup() color = Color(1, 1, .5, .8) explosion.add(color) explosion.add(Rectangle( pos=self.coord_to_pos(0, line), size=( self.tile_size()[0] * self.cols, self.tile_size()[1] ) )) self.canvas.add(explosion) def remove(self): self.canvas.remove(explosion) self.currently_exploding -= 1 anim = Animation( a=0, duration=.125 ) anim.bind(on_complete=lambda *args: remove(self)) anim.start(color)
def reset_cutter(self): self.cutter_event.cancel() ph = {'right': 1.0} anim = Animation(pos_hint=ph, duration=config.cutter_downtime) anim.bind(on_complete=lambda i, j: self.start_clock()) anim.start(self.cutter)
def on_activated(self, instance, activated): if not activated: self.grect.size = 0, 0 if self.at_bottom: anim = Animation(top=0, t='out_quad', d=.3) else: anim = Animation(y=self.height, t='out_quad', d=.3) anim.bind(on_complete=self.animation_close) anim.start(self.layout) self.widget = None self.widget_info = False else: self.win.add_widget(self) Logger.info('Inspector: inspector activated') if self.at_bottom: Animation(top=60, t='out_quad', d=.3).start(self.layout) else: Animation(y=self.height - 60, t='out_quad', d=.3).start( self.layout) ev = self._update_widget_tree_ev if ev is None: ev = self._update_widget_tree_ev = Clock.schedule_interval( self.update_widget_tree, 1) else: ev() self.update_widget_tree()
def outAnim(self, obj, *args): # Animation.cancel_all(self) anim = Animation(x=obj.pos[0]-100, t='in_back', duration=.3) anim &=Animation(opacity=0.0, t='in_back', duration=.3) anim.bind(on_complete=self.newTimeTrigger) anim.start(obj)
def doAnimation(self): if not self.mutexAnimation: anim = Animation(pos=(self.x + 10, self.y + 10), duration=.05) + \ Animation(pos=(self.x, self.y), duration=.05) anim.bind(on_start=self.on_start_animation) anim.bind(on_complete=self.on_complete_animation) anim.start(self)
def doSlide(self, pos): if not self.mutexAnimation: self.old_pos = self.pos[:] anim = Animation(pos=pos, duration=0.1) anim.bind(on_start=self.on_start_slide) anim.bind(on_complete=self.on_complete_slide) anim.start(self)
def _deal_with_collision(self, obj): Clock.unschedule(self._move) x, y = obj.center anim = Animation(x=x, y=y, size=(0, 0), d=0.4) anim.bind(on_start=lambda *args: self.parent.collect_coin(self)) anim.start(self)
def move(self, direction): """ Move up, down, left or right. :param direction: The direction to move in. :type direction: str :rtype: bool """ Logger.debug('TileMovement: move({})'.format(direction)) self.direction = direction new_x, new_y = self.get_tile_in_direction(self.direction) # move the destination tile to keep coherence if self.destination_tile == self.current_tile: self.destination_tile.x = new_x self.destination_tile.y = new_y self.current_tile.x = new_x self.current_tile.y = new_y coordinates = self.tile_map.get_tile_position(self.current_tile.x, self.current_tile.y) Logger.debug('TileMovement: Moving to {} at {}'.format(self.current_tile, coordinates)) # mark moving variable in case anyone is watching it self.moving = True animation = Animation(pos=coordinates, duration=0.5) animation.bind(on_complete=lambda *args: self.on_animation_complete()) animation.start(self)
def updateCharactor(self, *args): def setNextAnimation(): if self.mapInstance.charaWidget != None: self.chara.step(1, self.mapInstance) if isinstance(self.mapInstance.GetBlock(self.chara.cpos), EndBlock): return elif not self.mapInstance.IsInRange(): def okpush(inst): sys.exit() def restartpush(inst): self.chara = None self.mapInstance.charaWidget = None self.mapInstance.redraw() self.popup.dismiss() layout = BoxLayout(orientation='vertical') layout.add_widget(Button(text="end", multiline=False, on_press=okpush)) layout.add_widget(Button(text="restart", multiline=False, on_press=restartpush)) self.popup = Popup(title='warnnig', content=layout, size_hint=(None, None), size=(300, 200)) self.popup.open() return else: Clock.schedule_once(self.updateCharactor) anim = Animation(pos=self.mapInstance.GetRectPos([ self.chara.cpos[0] + self.chara.vec[0], self.chara.cpos[1] + self.chara.vec[1] ]), t='out_bounce') anim.bind(on_complete=lambda *args: setNextAnimation()) anim.start(self.chara)
def on_new_item(self, instance, text): text = text.lstrip() if text: #Mimic `ListAdapter.create_view` listview = self.list_view.proxy_ref data = (9e9, text, u"", 0, u"") index = len(self.list_items) item_args = self._args_converter(index, data) item_args.update({'index': index})#, 'listview': listview}) new_item = listview.cached_views[index] = self._item(**item_args) #new_item.bind(on_release=listview.handle_selection) listview.container.add_widget(new_item) def _on_start(a, w): instance.text = '' instance.focus = False def _on_complete(a, w): cursor = w.root_directory.cursor() cursor.execute(""" INSERT INTO [notebook](ix, what, page) VALUES((SELECT MAX(ROWID) FROM [notebook])+1, ?, ?); SELECT MAX(ROWID) FROM [notebook]; """, (text, w.page)) ix = cursor.fetchall()[0][0] new_item.ix = ix self.list_items.append((ix, text, u"", 0, u"")) _anim = Animation(y=0, t='out_expo', d=0.3) _anim.bind(on_start=_on_start, on_complete=_on_complete) instance._anim = ref(_anim) _anim.start(self.proxy_ref)
def destroy_blocks(self, ball): for i, block in enumerate(self.blocks): if block.collide_widget(ball): y_overlap = ( ball.top - block.y if ball.velocity[1] > 0 else block.top - ball.y) / block.size_hint_y x_overlap = ( ball.right - block.x if ball.velocity[0] > 0 else block.right - ball.x) / block.size_hint_x if x_overlap < y_overlap: ball.velocity[0] *= -1 else: ball.velocity[1] *= -1 if self.anim_block_remove: a = Animation(scale=.1, color=[1, 0, 0, 0], t='out_quad', duration=.5) a.bind(on_complete=lambda a, w: self.remove_widget(w)) a.start(block) else: self.remove_widget(block) if self.particles: explode = ParticleSystem('particle.pex') explode.emitter_x = ball.x explode.emitter_y = ball.y self.add_widget(explode) explode.start(duration=.2) Clock.schedule_once(lambda *a: self.remove_widget(explode), 1) del self.blocks[i] return True
def _transition_outof_intro(self, *args): # Fade out self.fader = ScreenFader(size=Window.size) Window.add_widget(self.fader) anim = Animation(alpha = 1.0, d=0.6) anim.bind(on_complete=self.begin_game) anim.start(self.fader)
def show(self, callback=None): self.opacity = 0.0 self.arrange_displays() anim = Animation(opacity=1.0) if callback: anim.bind(on_complete=callback) anim.start(self)
def hide(self, callback=None): anim_top = Animation(y=self.top_screen.top, t='out_quad', d=1.0) anim_bottom = Animation(top=-self.bottom_screen.y, t='out_quad', d=1.0) if callback: anim_top.bind(on_complete=callback) anim_top.start(self.top_screen) anim_bottom.start(self.bottom_screen)
def open(self, *largs): '''Show the view window from the :attr:`attach_to` widget. If set, it will attach to the nearest window. If the widget is not attached to any window, the view will attach to the global :class:`~kivy.core.window.Window`. ''' if self._window is not None: Logger.warning('ModalView: you can only open once.') return self # search window self._window = self._search_window() if not self._window: Logger.warning('ModalView: cannot open view, no window found.') return self self.shadow.fade_in(duration=.2, add_to=self._window) self._window.add_widget(self) self._window.bind( on_resize=self._align_center, on_keyboard=self._handle_keyboard) self.center = self._window.center self.bind(size=self._update_center) a = Animation(_anim_alpha=1., d=self._anim_duration) a.bind(on_complete=lambda *x: self.dispatch('on_open')) a.start(self) return self
def windowFade(self,anim,button): self.screen = Image(size=Window.size,color=(0,0,0,0)) self.screen.button = button self.parent.parent.parent.parent.add_widget(self.screen,0) animation = Animation(color=(0,0,0,1),duration=0.5,t="linear") animation.bind(on_complete=self.infoView) animation.start(self.screen)
def scroll_wall(self, next_index): def animation_complete(animation, widget): self.screen_manager.set_moving_flag(False) computed_positions = self.current_layout_manager.computed_positions # the layout height ist the last "position" computed_positions = computed_positions + [self.ids.layout.height] scrollview = self.ids.sv scroll_dist = self.compute_vertical_scroll_distance(scrollview, computed_positions, next_index) # do the animation self.screen_manager.set_moving_flag(True) animation = Animation(scroll_y=scroll_dist, duration=.15) animation.bind(on_complete=animation_complete) animation.start(scrollview) #scrollview._update_effect_y_bounds() previous_selected_widget = self.current_adapter.views[self.screen_manager.current_active_post_index] animation = Animation(background_color=previous_selected_widget.default_background_color, duration=.5) animation.start(previous_selected_widget) next_selected_widget = self.current_adapter.views[next_index] animation = Animation(background_color=[0, 0, .5, .7], duration=self.anim_move_duration) animation.start(next_selected_widget) self.screen_manager.current_active_post_index = next_index
class TransitionBase(EventDispatcher): '''TransitionBase is used to animate 2 screens within the :class:`ScreenManager`. This class acts as a base for other implementations like the :class:`SlideTransition` and :class:`SwapTransition`. :Events: `on_progress`: Transition object, progression float Fired during the animation of the transition. `on_complete`: Transition object Fired when the transition is finished. ''' screen_out = ObjectProperty() '''Property that contains the screen to hide. Automatically set by the :class:`ScreenManager`. :class:`screen_out` is an :class:`~kivy.properties.ObjectProperty` and defaults to None. ''' screen_in = ObjectProperty() '''Property that contains the screen to show. Automatically set by the :class:`ScreenManager`. :class:`screen_in` is an :class:`~kivy.properties.ObjectProperty` and defaults to None. ''' duration = NumericProperty(.4) '''Duration in seconds of the transition. :class:`duration` is a :class:`~kivy.properties.NumericProperty` and defaults to .4 (= 400ms). .. versionchanged:: 1.8.0 Default duration has been changed from 700ms to 400ms. ''' manager = ObjectProperty() ''':class:`ScreenManager` object, set when the screen is added to a manager. :attr:`manager` is an :class:`~kivy.properties.ObjectProperty` and defaults to None, read-only. ''' is_active = BooleanProperty(False) '''Indicate whether the transition is currently active or not. :attr:`is_active` is a :class:`~kivy.properties.BooleanProperty` and defaults to False, read-only. ''' # privates _anim = ObjectProperty(allownone=True) __events__ = ('on_progress', 'on_complete') def start(self, manager): '''(internal) Starts the transition. This is automatically called by the :class:`ScreenManager`. ''' if self.is_active: raise ScreenManagerException('start() is called twice!') self.manager = manager self._anim = Animation(d=self.duration, s=0) self._anim.bind(on_progress=self._on_progress, on_complete=self._on_complete) self.add_screen(self.screen_in) self.screen_in.transition_progress = 0. self.screen_in.transition_state = 'in' self.screen_out.transition_progress = 0. self.screen_out.transition_state = 'out' self.screen_in.dispatch('on_pre_enter') self.screen_out.dispatch('on_pre_leave') self.is_active = True self._anim.start(self) self.dispatch('on_progress', 0) def stop(self): '''(internal) Stops the transition. This is automatically called by the :class:`ScreenManager`. ''' if self._anim: self._anim.cancel(self) self.dispatch('on_complete') self._anim = None self.is_active = False def add_screen(self, screen): '''(internal) Used to add a screen to the :class:`ScreenManager`. ''' self.manager.real_add_widget(screen) def remove_screen(self, screen): '''(internal) Used to remove a screen from the :class:`ScreenManager`. ''' self.manager.real_remove_widget(screen) def on_complete(self): self.remove_screen(self.screen_out) def on_progress(self, progression): pass def _on_progress(self, *l): progress = l[-1] self.screen_in.transition_progress = progress self.screen_out.transition_progress = 1. - progress self.dispatch('on_progress', progress) def _on_complete(self, *l): self.is_active = False self.dispatch('on_complete') self.screen_in.dispatch('on_enter') self.screen_out.dispatch('on_leave') self._anim = None
def _open_brick(self, _=None): a = Animation(y=self.parent.height * atariGridPos["y"], duration=brickFallTime, t=brickFallTransition) a.bind(on_complete=self.open_brick) a.bind(on_progress=self.update_canvas) a.start(self.openingBrick)
def die(self): anim = Animation(top=0, duration=.3, t='out_quad') anim.bind(on_complete=lambda *args: manager._play_next(self)) anim.bind(on_complete=lambda *args: Window.remove_widget(self)) anim.start(self)
def blink(self): # Animation that changes the blink size and opacity anim = Animation(outer_opacity=0, blink_size=50) # when yhe animation completes, reset the animation, then repeat anim.bind(on_complete=self.reset) anim.start(self)
def go_right(self, instance, value): animation = Animation(right=self.parent.width) animation.bind(on_complete=self.go_left) animation.start(self)
def go_left(self, instance, value): animation = Animation(x=0) animation.bind(on_complete=self.go_right) animation.start(self)
class MDSpinner(ThemableBehavior, Widget): """:class:`MDSpinner` is an implementation of the circular progress indicator in Google's Material Design. It can be used either as an indeterminate indicator that loops while the user waits for something to happen, or as a determinate indicator. Set :attr:`determinate` to **True** to activate determinate mode, and :attr:`determinate_time` to set the duration of the animation. """ determinate = BooleanProperty(False) """:attr:`determinate` is a :class:`~kivy.properties.BooleanProperty` and defaults to False """ determinate_time = NumericProperty(2) """:attr:`determinate_time` is a :class:`~kivy.properties.NumericProperty` and defaults to 2 """ active = BooleanProperty(True) """Use :attr:`active` to start or stop the spinner. :attr:`active` is a :class:`~kivy.properties.BooleanProperty` and defaults to True """ color = ListProperty([]) """:attr:`color` is a :class:`~kivy.properties.ListProperty` and defaults to 'self.theme_cls.primary_color' """ _alpha = NumericProperty(0) _rotation_angle = NumericProperty(360) _angle_start = NumericProperty(0) _angle_end = NumericProperty(8) def __init__(self, **kwargs): super().__init__(**kwargs) self.color = self.theme_cls.primary_color self._alpha_anim_in = Animation(_alpha=1, duration=.8, t='out_quad') self._alpha_anim_out = Animation(_alpha=0, duration=.3, t='out_quad') self._alpha_anim_out.bind(on_complete=self._reset) self.theme_cls.bind(primary_color=self._update_color) if self.determinate: self._start_determinate() else: self._start_loop() def _update_color(self, *args): self.color = self.theme_cls.primary_color def _start_determinate(self, *args): self._alpha_anim_in.start(self) _rot_anim = Animation(_rotation_angle=0, duration=self.determinate_time * .7, t='out_quad') _rot_anim.start(self) _angle_start_anim = Animation(_angle_end=360, duration=self.determinate_time, t='in_out_quad') _angle_start_anim.bind( on_complete=lambda *x: self._alpha_anim_out.start(self)) _angle_start_anim.start(self) def _start_loop(self, *args): if self._alpha == 0: _rot_anim = Animation(_rotation_angle=0, duration=2, t='linear') _rot_anim.start(self) self._alpha = 1 self._alpha_anim_in.start(self) _angle_start_anim = Animation(_angle_end=self._angle_end + 270, duration=.6, t='in_out_cubic') _angle_start_anim.bind(on_complete=self._anim_back) _angle_start_anim.start(self) def _anim_back(self, *args): _angle_back_anim = Animation(_angle_start=self._angle_end - 8, duration=.6, t='in_out_cubic') _angle_back_anim.bind(on_complete=self._start_loop) _angle_back_anim.start(self) def on__rotation_angle(self, *args): if self._rotation_angle == 0: self._rotation_angle = 360 if not self.determinate: _rot_anim = Animation(_rotation_angle=0, duration=2) _rot_anim.start(self) def _reset(self, *args): Animation.cancel_all(self, '_angle_start', '_rotation_angle', '_angle_end', '_alpha') self._angle_start = 0 self._angle_end = 8 self._rotation_angle = 360 self._alpha = 0 self.active = False def on_active(self, *args): if not self.active: self._reset() else: if self.determinate: self._start_determinate() else: self._start_loop()
def hide_anim_spinner(self): spinner = self.ids.body_spinner anim = Animation(y=Window.height, d=0.8, t="out_elastic") anim.bind(on_complete=self.set_spinner) anim.start(spinner)
def set_selected_screen(self): anim = Animation(x=0, y=0, d=0.1) anim.bind(on_complete=self.set_default_screens_position) anim.start(self.selected_screen)
class MDSpinner(ThemableBehavior, Widget): """:class:`MDSpinner` is an implementation of the circular progress indicator in `Google's Material Design`. It can be used either as an indeterminate indicator that loops while the user waits for something to happen, or as a determinate indicator. Set :attr:`determinate` to **True** to activate determinate mode, and :attr:`determinate_time` to set the duration of the animation. """ determinate = BooleanProperty(False) """ Determinate value. :attr:`determinate` is a :class:`~kivy.properties.BooleanProperty` and defaults to `False`. """ determinate_time = NumericProperty(2) """ Determinate time value. :attr:`determinate_time` is a :class:`~kivy.properties.NumericProperty` and defaults to `2`. """ active = BooleanProperty(True) """Use :attr:`active` to start or stop the spinner. :attr:`active` is a :class:`~kivy.properties.BooleanProperty` and defaults to `True`. """ color = ListProperty([0, 0, 0, 0]) """ Spinner color. :attr:`color` is a :class:`~kivy.properties.ListProperty` and defaults to ``self.theme_cls.primary_color``. """ palette = ListProperty() """ A set of colors. Changes with each completed spinner cycle. :attr:`palette` is a :class:`~kivy.properties.ListProperty` and defaults to `[]`. """ _alpha = NumericProperty(0) _rotation_angle = NumericProperty(360) _angle_start = NumericProperty(0) _angle_end = NumericProperty(0) _palette = [] def __init__(self, **kwargs): super().__init__(**kwargs) self.color = self.theme_cls.primary_color self._alpha_anim_in = Animation(_alpha=1, duration=0.8, t="out_quad") self._alpha_anim_out = Animation(_alpha=0, duration=0.3, t="out_quad") self._alpha_anim_out.bind(on_complete=self._reset) self.theme_cls.bind(primary_color=self._update_color) if self.determinate: self._start_determinate() else: self._start_loop() def _update_color(self, *args): self.color = self.theme_cls.primary_color def _start_determinate(self, *args): self._alpha_anim_in.start(self) _rot_anim = Animation( _rotation_angle=0, duration=self.determinate_time * 0.7, t="out_quad", ) _rot_anim.start(self) _angle_start_anim = Animation(_angle_end=360, duration=self.determinate_time, t="in_out_quad") _angle_start_anim.bind( on_complete=lambda *x: self._alpha_anim_out.start(self)) _angle_start_anim.start(self) def _start_loop(self, *args): if self._alpha == 0: _rot_anim = Animation(_rotation_angle=0, duration=2, t="linear") _rot_anim.start(self) self._alpha = 1 self._alpha_anim_in.start(self) _angle_start_anim = Animation(_angle_end=self._angle_end + 270, duration=0.6, t="in_out_cubic") _angle_start_anim.bind(on_complete=self._anim_back) _angle_start_anim.start(self) def _anim_back(self, *args): _angle_back_anim = Animation(_angle_start=self._angle_end - 8, duration=0.6, t="in_out_cubic") _angle_back_anim.bind(on_complete=self._start_loop) _angle_back_anim.start(self) def on__rotation_angle(self, *args): if self._rotation_angle == 0: self._rotation_angle = 360 if not self.determinate: _rot_anim = Animation(_rotation_angle=0, duration=2) _rot_anim.start(self) elif self._rotation_angle == 360: if self._palette: try: Animation(color=next(self._palette), duration=2).start(self) except StopIteration: self._palette = iter(self.palette) Animation(color=next(self._palette), duration=2).start(self) def _reset(self, *args): Animation.cancel_all( self, "_angle_start", "_rotation_angle", "_angle_end", "_alpha", "color", ) self._angle_start = 0 self._angle_end = 0 self._rotation_angle = 360 self._alpha = 0 self.active = False def on_palette(self, instance, value): self._palette = iter(value) def on_active(self, *args): if not self.active: self._reset() else: if self.determinate: self._start_determinate() else: self._start_loop()
def close_card(self): anim = Animation(x=0, t=self.closing_transition, d=self.opening_time) anim.bind(on_complete=self._reset_open_progress) anim.start(self.children[0]) self.state = "closed"
class Focus(MDApp): title = "Focus" icon = 'icon.ico' use_kivy_settings = False color_theme = 'dark' bg_color = ListProperty([29 / 255, 29 / 255, 29 / 255, 1]) tile_color = ListProperty([40 / 255, 40 / 255, 40 / 255, 1]) raised_button_color = ListProperty([52 / 255, 52 / 255, 52 / 255, 1]) text_color = ListProperty([1, 1, 1, 1]) title_text_color = ListProperty([1, 1, 1, 1]) accent_color = ListProperty([0.5, 0.7, 0.5, 1]) app_font = StringProperty( resource_path(os.path.join('data', 'fonts', 'Code2000', 'CODE2000.ttf'))) cursor_width = NumericProperty(3) home_icon = StringProperty('home') home_icon_tooltip = StringProperty('Back') add_icon = StringProperty('plus-circle-outline') add_icon_tooltip = StringProperty('Create new') search_icon = StringProperty('magnify') search_icon_tooltip = StringProperty('Search') def open_settings(self, *largs): self.mainmenu.ids.settings_button.trigger_action() def build(self): self.themes = { 'dark': self.color_theme_dark, 'light': self.color_theme_light, 'rgb': self.color_theme_rgb, 'custom': None } self.transitions = { 'slide': SlideTransition, 'wipe': WipeTransition, 'fade': FadeTransition, 'fall out': FallOutTransition, 'none': NoTransition } if getattr(sys, 'frozen', False): from app.screens import mainmenu, wikipedia, notebook, translation, youtube, todo, books, settings, about else: from screens import mainmenu, wikipedia, notebook, translation, youtube, todo, books, settings, about self.user_settings = settings.SettingsBackend().show_settings() self.root = ScreenManager() self.mainmenu = mainmenu.MainMenu() self.wikipedia = wikipedia.Wikipedia() self.notebook = notebook.Notebook() self.translation = translation.Translation() self.youtube = youtube.Youtube() self.todo = todo.ToDo() self.books = books.Books() self.settings = settings.Settings() self.about = about.About() self.screens = { 'mainmenu': self.mainmenu, 'wikipedia': self.wikipedia, 'notebook': self.notebook, 'translation': self.translation, 'youtube': self.youtube, 'todo': self.todo, 'books': self.books, 'settings': self.settings, 'about': self.about } self.themes['custom'] = self.settings.color_theme_custom self.root.switch_to(self.mainmenu) try: self.root.transition = self.transitions.get( self.user_settings.get('page_transition'))() except BaseException: self.root.transition = SlideTransition() self.themes.get(self.user_settings.get('theme'))() Window.show() return self.root def switch_screen(self, screen_name, direction='left'): self.root.transition.direction = direction self.root.switch_to(self.screens.get(screen_name)) def color_theme_dark(self): self.color_theme = 'dark' try: Animation.cancel_all(self) except BaseException: pass self.bg_color = [29 / 255, 29 / 255, 29 / 255, 1] self.tile_color = [40 / 255, 40 / 255, 40 / 255, 1] self.raised_button_color = [52 / 255, 52 / 255, 52 / 255, 1] self.text_color = [1, 1, 1, 1] self.title_text_color = [1, 1, 1, 1] self.accent_color = [0.5, 0.7, 0.5, 1] def color_theme_light(self): self.color_theme = 'light' try: Animation.cancel_all(self) except BaseException: pass self.bg_color = [0.989, 0.989, 0.989, 1.0] self.tile_color = [0.94, 0.94, 0.94, 1.0] self.raised_button_color = [0.823, 0.823, 0.823, 1.0] self.text_color = [0.0, 0.0, 0.0, 1.0] self.title_text_color = [0.0, 0.0, 0.0, 1.0] self.accent_color = [0.212, 0.099, 1.0, 1.0] def color_theme_rgb(self): self.color_theme = 'rgb' def update_bg_anim(self): self.bg_color_animation = Animation( bg_color=utils.get_random_color(), duration=4.) self.bg_color_animation.bind( on_complete=lambda idk, a=self: update_bg_anim(a)) self.bg_color_animation.start(self) update_bg_anim(self) def update_tile_anim(self): self.tile_color_animation = Animation( tile_color=utils.get_random_color(), duration=4.) self.tile_color_animation.bind( on_complete=lambda idk, a=self: update_tile_anim(a)) self.tile_color_animation.start(self) update_tile_anim(self) def update_raised_button_anim(self): self.raised_button_color_animation = Animation( raised_button_color=utils.get_random_color(), duration=4.) self.raised_button_color_animation.bind( on_complete=lambda idk, a=self: update_raised_button_anim(a)) self.raised_button_color_animation.start(self) update_raised_button_anim(self) def update_text_anim(self): self.text_color_animation = Animation( text_color=utils.get_random_color(), duration=4.) self.text_color_animation.bind( on_complete=lambda idk, a=self: update_text_anim(a)) self.text_color_animation.start(self) update_text_anim(self) def update_title_text_anim(self): self.title_text_color_animation = Animation( title_text_color=utils.get_random_color(), duration=4.) self.title_text_color_animation.bind( on_complete=lambda idk, a=self: update_title_text_anim(a)) self.title_text_color_animation.start(self) update_title_text_anim(self) def update_accent_anim(self): self.accent_color_animation = Animation( accent_color=utils.get_random_color(), duration=4.) self.accent_color_animation.bind( on_complete=lambda idk, a=self: update_accent_anim(a)) self.accent_color_animation.start(self) update_accent_anim(self) def color_theme_custom(self, user_settings): self.color_theme = 'custom' try: Animation.cancel_all(self) except BaseException: pass self.bg_color = user_settings.get('bg_color') if len( user_settings.get('bg_color')) == 4 else [ 29 / 255, 29 / 255, 29 / 255, 1 ] self.tile_color = user_settings.get('tile_color') if len( user_settings.get('tile_color')) == 4 else [ 40 / 255, 40 / 255, 40 / 255, 1 ] self.raised_button_color = user_settings.get( 'raised_button_color') if len( user_settings.get('raised_button_color')) == 4 else [ 52 / 255, 52 / 255, 52 / 255, 1 ] self.text_color = user_settings.get('text_color') if len( user_settings.get('text_color')) == 4 else [1, 1, 1, 1] self.title_text_color = user_settings.get('title_text_color') if len( user_settings.get('title_text_color')) == 4 else [1, 1, 1, 1] self.accent_color = user_settings.get('accent_color') if len( user_settings.get('accent_color')) == 4 else [0.5, 0.7, 0.5, 1] def transition_changed(self, user_settings): try: self.root.transition = self.transitions.get( user_settings.get('page_transition'))() except BaseException: self.root.transition = SlideTransition()
class Placeholder(HotSpotImage): def __init__(self, data, factor, target, **kwargs): super(Placeholder, self).__init__(allow_stretch=True, keep_ratio=False, **kwargs) self.source = None self.holder = None self.data = data self.factor = factor self.target = target self.staticplaceholdertexture = kwargs.get( 'placeholder_texture', staticplaceholdertexture.texture) self.texture = self.staticplaceholdertexture self._capturing = False self._anim = None self._cntx = None self._cntx_rect = None self.newtexture = None self._gesture_target = kwargs.get('gesture_target', None) self._gesture_anim_max_height = kwargs.get( 'gesture_anim_height', self.staticplaceholdertexture.height * 0.6) self._vote_widget = None self._vote_scale = 0 def dispose_widget(self): # make sure we are not marked as capturing, no matter where we are self._capturing = False # if we have a holder - dispose of the actual texture and switch to holder texture if self.holder: if self._anim: self.anim_on_complete(1) self.texture = self.staticplaceholdertexture self.holder = None self.newtexture = None self.clear_hotspots() self.canvas.ask_update() return True return False def anim_on_progress(self, *l): if not self._anim or not self._cntx: Logger.info('Placeholder: animation without ctx') return progress = l[-1] #Logger.info('ANIMATION %s -- %s' % (str(self), progress)) self._cntx_rect.pos = self.to_window(self.x, self.y) self._cntx['t'] = progress # callback to update the fadein texture position, jist before we render def _cntx_callback(self, *largs): self._cntx_rect.pos = self.to_window(self.x, self.y) def anim_on_complete(self, *l): #Logger.info('ANIMATION %s -- complete' % (str(self))) if self._anim: self._anim.cancel(self) self._anim = None if self._cntx: self.canvas.remove(self._cntx) # updating the texture actually triggers screen update # so do it after you removed the animation context if self.newtexture: self.texture = self.newtexture self.newtexture = None self._cntx = None self._cntx_rect = None # hotspots should have been cleared, if they are not, don't mess it up self.attach_hotspots(self.target, self._hotspots, clear=False) def assign(self, widget, scrollview_container=None): if self._anim: Logger.info('Placeholder: assign with animation') return # first update our size to the new texture size. self.size = self.newtexture.size self.texture_size = self.newtexture.size self._hotspots = widget.get_hotspots() visual_bbox = None if scrollview_container: visual_bbox = StableScrollView.BBox( *scrollview_container._get_pure_viewbox()) if not visual_bbox or not self.collide_widget(visual_bbox): self.anim_on_complete(1.0) else: self._cntx = RenderContext(use_parent_projection=True) self._cntx.shader.fs = FADE_TRANSITION_FS with self._cntx: # here, we are binding a custom texture at index 1 # this will be used as texture1 in shader. BindTexture(texture=self.newtexture, index=1) # create a rectangle with texture (will be at index 0) pos = self.to_window(self.x, self.y) self._cntx_rect = Rectangle(size=self.size, pos=pos, texture=self.holder, tex_coords=self.holder.tex_coords) # callback to update position #Callback(self._cntx_callback) # set the texture1 to use texture index 1 self._cntx['t'] = 0.0 self._cntx['tex_in'] = 1 self._cntx['tex_out'] = 0 self.canvas.add(self._cntx) # set the animation in progress self._anim = Animation(duration=0.250, s=0) self._anim.bind(on_progress=self.anim_on_progress, on_complete=self.anim_on_complete) self._anim.start(self) def _capture_widget(self, instance, largs): widget, = largs scrollview_container = widget.scrollview_container def update_tex(tex): if not self.holder: self.holder = self.texture #else: # Logger.info('Placeholder: update_text when we already have one %s' % self.data) self.newtexture = tex # mark end of capturing process self._capturing = False # start animation and stuff self.assign(widget, scrollview_container) # we actually should wait another frame to make sure the frame is rendered def capture_add_texture(dt): screenshot_texture(widget, update_tex) widget.dispose() Clock.schedule_once(capture_add_texture, 0.025) def _update_data(self, data): # update data, if we already have data - only update the fields we already have data_updated = False if isinstance(data, dict): if self.data: for k in set(data.keys()).intersection(self.data.keys()): if self.data[k] != data[k]: data_updated = True self.data[k] = data[k] else: data_updated = True self.data = data return data_updated def update_widget(self, data=None, ignore_old_data=False, **kwargs): # if we already have a texture or we are already capturing if (self.holder or self._capturing) and (not data or self.data == data): return False if ignore_old_data: self.data = data data_updated = True else: data_updated = self._update_data(data) # if we already have a texture and nothing was changed, skip it. if self.holder and not data_updated: return False # mark us as already capturing, # so we shouldn't schedule another call while we are waiting to capture. self._capturing = True # create the item item = self.factor(self.data) if not item: # Logger.info('Placeholder: update_widget - we didnt get an item') # we failed creating the item, let's reschedule retries = kwargs.get('retries', 0) if retries < 3: from functools import partial Clock.schedule_once( partial(self.update_widget, retries=retries + 1), 0.250) return True # schedule capture callback item.size_hint_x = None item.width = self.width item.scrollview_container = kwargs.get('scrollview_container', None) # if there is no callback just initiate the call now if not item.set_load_callback(self._capture_widget, item): self._capture_widget(item, [item]) return True def update_texture(self, newtexture): if not self.holder: self.holder = self.texture self.texture = newtexture def update_widget_data(self, data, retries=0, ignore_old_data=False): # if we don't have a texture, just update the data if not self.holder: if self.data and not ignore_old_data: for k in set(data.keys()).intersection(self.data.keys()): self.data[k] = data[k] else: self.data = data else: # update texture return self.update_widget(data=data, ignore_old_data=ignore_old_data) def pass_touch_to_spot(self, spot): if spot and spot[3][2] * spot[3][3] < 100 * 100: return True return False def check_touch_gesture(self, touch): return True def on_touch_down(self, touch): if not self._gesture_target: return super(Placeholder, self).on_touch_down(touch) # close on double tap if touch.is_double_tap: touch.grab(self) touch.grab_current = self try: self.parent.parent.parent.parent.parent.dispatch('on_close') except: self.parent.parent.parent.parent.parent.parent.dispatch( 'on_close') return True if self.disabled or not self.collide_point(*touch.pos): return False #Logger.info('<<<DOWN>>>: %s -- pos=%s osx=%s sx=%s' % (self.data['content'], touch.pos, touch.osx, touch.sx)) spot = self.find_hotspot_touch(touch) if spot and self.pass_touch_to_spot(spot): return super(Placeholder, self).on_touch_down(touch) if not self.check_touch_gesture(touch): return False cx, cy = self.to_window(*self.center) #print 'pos %s -- %s %s' % (self.center, cx, cy) window = self.get_parent_window() if cy < 0 or cy > window.height: return False touch.grab(self) touch.grab_current = self touch.dx = touch.dy = 0 #touch.x, touch.y = cx, cy #touch.sx, touch.sy = float(touch.x)/window.width, float(touch.y)/window.height touch.ox, touch.oy = touch.px, touch.py = touch.pos touch.osx, touch.osy = touch.psx, touch.psy = touch.sx, touch.sy #Logger.info('<<<DOWN>>>: -- pos=%s osx=%s sx=%s' % (touch.pos, touch.osy, touch.sy)) if hasattr(touch, 'scroll') and touch.scroll: self._vote_scale = 0.001 else: self._vote_scale = 0 return True def on_touch_move(self, touch): if touch.grab_current is not self: return False swipe_range = 0.35 swipe_dx = touch.osx - touch.sx swipe_range_y = 0.35 swipe_dy = touch.osy - touch.sy touch_distance = max(abs(swipe_dx), abs(swipe_dy)) #Logger.info('<<<MOVE>>>: %s %s %s %s' % (str(touch.pos), touch_distance, touch.dx, touch.dy)) scale = min(1, max(.001, abs(swipe_dx) / abs(swipe_range))) scale_y = min(1, max(.001, abs(swipe_dy) / swipe_range_y)) sign = float(swipe_dx) / swipe_range self._vote_scale = scale if sign >= 0 else -scale if not self._vote_widget and abs(scale) > 0.1: cx, cy = self.to_window(*self.center) global global_vote_widget self._vote_widget = global_vote_widget pos = (cx - self._vote_widget.width / 2, cy - self._vote_widget.height / 2) self._vote_widget.clear(pos=pos) if self._gesture_target: self._gesture_target.add_gesture_animation(self._vote_widget) v = self._vote_widget if v: #Logger.info('<<<MOVE>>>: osx=%s sx=%s r=%s dx=%s' % (touch.osx, touch.sx, swipe_range, swipe_dx)) rescale = 1 + _scale_to_theme_dpi(2 * 1.33) * scale if v.height * 3 > self._gesture_anim_max_height and rescale * v.height > self._gesture_anim_max_height: rescale = float(self._gesture_anim_max_height) / float( v.height) if scale_y < 0.0: pass elif scale_y > 0.35: scale = .001 elif scale_y >= 0.0: scale *= 1. ##-scale_y self._vote_scale = scale if sign >= 0 else -scale #Logger.info('<<<MOVE>>>: %s %s osy=%s sy=%s r=%s dy=%s' % (scale, scale_y, touch.osy, touch.sy, swipe_range_y, swipe_dy)) ancore = v.center #print 'anim: pos %s sign %s scaling %s ancore %s' % (v.pos, sign, scale, ancore) v.apply_transform(rescale=rescale, anchor=ancore) v.setscale(scale, sign) return True def on_touch_up(self, touch): if touch.grab_current is not self: return False touch.ungrab(self) touch.grab_current = None swipe_dx = touch.osx - touch.sx swipe_dy = touch.osy - touch.sy touch_distance = max(abs(swipe_dx), abs(swipe_dy)) #Logger.info('<<< UP >>>: %s %s %s %s %s' % (self._vote_scale, str(touch.pos), touch_distance, touch.dx, touch.dy)) if self._vote_widget: def remove_vote_widget(*largs): if self._gesture_target: self._gesture_target.remove_gesture_animation( self._vote_widget) self._vote_widget = None if abs(self._vote_scale) < 0.001 and touch_distance < 0.001: remove_vote_widget() self.call_on_release(touch) elif self._vote_scale < -0.80: self._vote_widget.setscale(1., self._vote_scale) self.target.item_gesture_right(self, touch) Clock.schedule_once(remove_vote_widget, 0.500) elif self._vote_scale > 0.80: self._vote_widget.setscale(1., self._vote_scale) self.target.item_gesture_left(self, touch) Clock.schedule_once(remove_vote_widget, 0.500) else: remove_vote_widget() self._vote_scale = 0 else: if abs(self._vote_scale) < 0.0001: super(Placeholder, self).on_touch_down(touch) super(Placeholder, self).on_touch_up(touch) self._vote_scale = 0 return True
class NavigationController( BoxLayout ) : ''' Custom layout you can use to manage navigation in your app. This is inspired by iOS navigation system, but much easier... You should put a NavigationController as root widget for your app, internally uses a stack to manage navigation ( accessible by using the 'stack' property ). You can pop\push views by using 'pop' and 'push' methods. ''' root_widget = ObjectProperty( None ) ''' The current widget is stored here. ''' stack = ListProperty( [] ) ''' Stack used to navigate between various screens\widgets. ''' background_color = ListProperty( [ .93, .93, .93, 1 ] ) ''' Solid background color. ''' animation_duracy = NumericProperty( 0 )#.25 ) ''' Push & pop animation duracy, default 0.25 seconds. ''' push_mode = OptionProperty( 'right', options=['left','right'] ) ''' Left or right, will push/pop views from/to the given direction. ''' disable_widget = BooleanProperty( False ) ''' If true, root widget will be disabled during animations. This will hide animations! ''' #Navigation bar title = StringProperty( 'Navigation control!' ) ''' Navigation bar title. ''' nav_height = NumericProperty( dp(56) ) ''' Navigation bar height. ''' nav_color = ListProperty( [ .1, .11, .11, 1] ) ''' Navigation bar color. ''' shadow_alpha = NumericProperty( .065 ) ''' Alpha channel for navigation bar shadow. ''' font_name = StringProperty( None ) ''' Navigation bar font name. ''' font_size = NumericProperty( dp(22) ) ''' Navigation bar font size. ''' text_color = ListProperty( [1,1,1,1] ) ''' Navigation bar text color. ''' floating_panel = ObjectProperty( None ) ''' FloatingLayout you can use for any pourpose. ''' floating_action = ObjectProperty( None ) ''' FloatingAction managed by the controller. Press 'Menu' key to fire the on-press event. ''' splash_image = StringProperty( alphapng ) ''' Image used as splash screen. ''' #Private stuffs... _push_cache = ListProperty( [] ) _actionprev = ObjectProperty( None ) _actiontext = ObjectProperty( None ) _content = ObjectProperty( None ) _width = NumericProperty( float(Config.get('graphics','width')) ) def __init__( self, **kargs ) : super( NavigationController, self ).__init__( **kargs ) self._keyboard_show = False self._keyboard_just_show = False self._has_root = False self._last_args = {'title':'', 'animation':None} self._animation = None self._bind_keyboard() self.push( Form( shared_navigation_controller=self ) ) def pop( self, *args ) : ''' Use this to go back to the last view. Will eventually throw EmptyNavigationStack. ''' if self._animation is None : if len( self.stack ) > 1 : if len( self.stack ) > 2 : try : self.root_widget.on_pop( self ) except : pass self._save_temp_view( 0, self.root_widget ) self._run_pop_animation() else : raise DidPopLastViewException() else : raise EmptyNavigationStack() def push( self, view, **kargs ) : ''' Will append the last view to the list and show the new one. Keyword arguments : title Navigation bar title, default ''. ''' if self._animation is None : if not 'title' in kargs.keys() : kargs['title'] = '' self._last_kargs = kargs x = -1 if self.push_mode == 'left' else 1 self._save_temp_view( x, view ) self._run_push_animation() #================================================================================ # Private stuff of various use... #================================================================================ def _bind_keyboard(self) : EventLoop.window.bind( on_keyboard=self._on_keyboard_show ) EventLoop.window.bind( on_key_down=self._on_keyboard_down ) def _on_keyboard_show( self, *args ) : self._keyboard_show = True def _on_keyboard_down( self, window, key, *args ) : if key == 319 : # Menu if self.floating_action : self.floating_action.on_press() return True if key == 27 : # Escape if self._keyboard_show : self._keyboard_show = False EventLoop.window.release_all_keyboards() else : self.pop() return True return False def _run_push_animation( self ) : try : self._temp_view.disabled = self.disable_widget if self._has_root : self._animation = Animation( x=0, duration=self.animation_duracy ) self._animation.bind( on_complete=self._push_temp_view ) self._animation.start( self._temp_view ) else : self._push_temp_view() except : pass #Exception as e : print(e) def _run_pop_animation( self ) : try : self._temp_view.disabled = self.disable_widget x = self._temp_view.width * ( -1 if self.push_mode == 'left' else 1 ) self._animation = Animation( x=x, duration=self.animation_duracy ) self._animation.bind( on_complete=self._pop_temp_view ) self._animation.start( self._temp_view ) except : pass #Exception as e : print(e) def _push_temp_view( self, *args ) : self._temp_view.disabled = False if self._has_root : self.content.remove_widget( self.root_widget ) self.stack.append( [ self.root_widget, self._last_kargs ] ) self.root_widget = self._temp_view self._clear_temp_view() self.content.add_widget( self.root_widget ) self._has_root = True self._update_nav() self._animation = None try : self.root_widget.on_push( self ) except : pass def _pop_temp_view( self, *args ) : self._temp_view.disabled = False self.content.remove_widget( self.root_widget ) self.root_widget, self._last_kargs = self.stack.pop() if len(self.stack) > 1 : self._last_kargs = self.stack[-1][1] self.content.add_widget( self.root_widget ) self._update_nav() self._animation = None def _clear_temp_view( self, *args ) : try : self.floating_panel.remove_widget( self._temp_view ) except : pass self._temp_view = None def _save_temp_view( self, p, view ) : self._temp_view = view try : self._temp_view.pos = [ self._width*p, 0 ] self.floating_panel.add_widget( self._temp_view ) except : pass def _update_nav( self ) : self.title = self._last_kargs['title'] has_previous = len( self.stack ) > 2 self.actionprev.text = ' < ' if has_previous else '' self.actionprev.disabled = not has_previous
def animate_bullet_x(self, instance): # important to author animation = Animation(pos=instance.pos) animation += Animation(pos=instance.button.pos, duration=1, t="in_circ") animation.bind(on_complete=self.animate_bullet_x_complete) animation.start(instance)
def _switch_picker(self, *a, **kw): noanim = "noanim" in kw if noanim: noanim = kw["noanim"] try: container = self.ids.picker_container except (AttributeError, NameError): Clock.schedule_once(lambda *a: self._switch_picker(noanim=noanim)) if self.picker == "hours": picker = self._h_picker prevpicker = self._m_picker elif self.picker == "minutes": picker = self._m_picker prevpicker = self._h_picker if len(self._bound) > 0: prevpicker.unbind(selected=self.on_selected) self.unbind(**self._bound) picker.bind(selected=self.on_selected) self._bound = { "selector_color": picker.setter("selector_color"), "color": picker.setter("color"), "selector_alpha": picker.setter("selector_alpha"), } self.bind(**self._bound) if len(container._bound) > 0: container.unbind(**container._bound) container._bound = { "size": picker.setter("size"), "pos": picker.setter("pos"), } container.bind(**container._bound) picker.pos = container.pos picker.size = container.size picker.selector_color = self.selector_color picker.color = self.color picker.selector_alpha = self.selector_alpha if noanim: if prevpicker in container.children: container.remove_widget(prevpicker) if picker.parent: picker.parent.remove_widget(picker) container.add_widget(picker) else: self.is_animating() if prevpicker in container.children: anim = Animation(scale=1.5, d=0.5, t="in_back") & Animation( opacity=0, d=0.5, t="in_cubic") anim.start(prevpicker) Clock.schedule_once( lambda *y: container.remove_widget(prevpicker), 0.5) # .31) picker.scale = 1.5 picker.opacity = 0 if picker.parent: picker.parent.remove_widget(picker) container.add_widget(picker) anim = Animation(scale=1, d=0.5, t="out_back") & Animation( opacity=1, d=0.5, t="out_cubic") anim.bind(on_complete=self.is_not_animating) Clock.schedule_once(lambda *y: anim.start(picker), 0.3)
def fade_out(self, interval): Animation(opacity=0, duration=0.4).start(self.label_toast) anim_body = Animation(opacity=0, duration=0.4) anim_body.bind(on_complete=lambda *x: self.dismiss()) anim_body.start(self)
def animate_bullet(self, instance): animation = Animation(pos=instance.pos) animation += Animation(pos=instance.button.pos, duration=float(self.get_conf_delay()/10), t="in_circ") animation.bind(on_complete=self.animate_bullet_complete) animation.start(instance)
class Controller(object): def __init__(self, widget): super(Controller, self).__init__() self.view = widget self.settings = kivy.app.App.get_running_app().settings kivy.app.App.get_running_app().main_widget = widget self.last_background_url = None # Race condition prevention self.anim = None # Race condition prevention # this effectively calls on_next_frame, when the view is ready Clock.schedule_once(self.on_next_frame, 0) def on_next_frame(self, dt): """Called once, when the view is ready.""" background_path = self.settings.get('last_custom_background') Logger.info( 'MainWidget: Settings background to: {}'.format(background_path)) self.set_background_path(background_path, use_transition=False) def _background_fetch_failure(self, request, result): """Callback called when a background image fetch failed.""" Logger.error('Background: Fetching the background image failed') def _background_fetch_error(self, request, error): """Callback called when a background image fetch raised an internal error.""" Logger.info( 'Background: Fetching the background image raised an error: {}'. format(error)) def _background_fetch_success(self, url, request, result): """Callback called when a background image fetch succeeded.""" Logger.info( 'Background: Fetching the background image succeeded! {}'.format( url)) # Check if the image data is correct and can actually be loaded try: im = CoreImage(io.BytesIO(result), ext=url.split('.')[-1]) except Exception as ex: Logger.error( 'Background: The image downloaded could not be correctly loaded: {}' .format(repr(ex))) im = None if im: filecache.save_file(url, result) # If a new request has been made in the meantime, don't change the background! if url == self.last_background_url: self.set_background_path(filecache.map_file(url)) def _pop_background(self, animation, widget): """Switch the background images so that a new image can be shown in the background, in the future. """ self.view.ids.background.source = self.view.ids.background_new.source self.view.ids.background_new.opacity = 0 self.anim = None def set_background_path(self, path, use_transition=True): """Set the background to a file on disk pointed by the path.""" self.settings.set('last_custom_background', path) if path is None: path = get_resources_path('images/back.png') if self.view.ids.background.source == path and self.anim is None: Logger.info( 'Background: The requested background is already used. Not doing anything.' ) return Logger.info('Background: setting background to: {}'.format(path)) if not os.path.isfile(path): Logger.info( 'Background: Trying to set the background to an nonexistent file: {}' .format(path)) return self.view.ids.background_new.opacity = 0 if use_transition: self.view.ids.background_new.source = path self.anim = Animation(opacity=1, transition='linear', duration=2) self.anim.bind(on_complete=self._pop_background) Animation.cancel_all(self.view.ids.background_new) self.anim.start(self.view.ids.background_new) else: self.view.ids.background.source = path def set_background(self, url): """Set the background to a file pointed by the url. The file will be fetched if it is not already cached. If url is None, the default background will be used. """ self.last_background_url = url if url is None: Logger.info('Background: No background set') self.set_background_path(None) return background_path = filecache.map_file(url) if os.path.isfile(background_path): Logger.info( 'Background: Background already fetched. Reusing cached data.') self.set_background_path(background_path) else: Logger.info('Background: Fetching url: {}'.format(url)) self.url_request = UrlRequest( url, on_success=partial(self._background_fetch_success, url), on_error=self._background_fetch_error, decode=False, timeout=30)
def animate_heart_bullet_x(self, animation, instance): # important to author animation = Animation(pos=instance.pos) index = (instance.button.index + 1) % 12 animation += Animation(pos=self.buttons[index].bullet.pos, duration=5, t="out_circ") animation.bind(on_complete=self.animate_heart_bullet_x_complete) animation.start(instance)
class AmazonScene(Screen): #beat_1, triangle, and triangle are of type ObjectProperty, which means they are of any object type, therefore they can be assigned to any object of any kind later in the code #in these cases, in the kivy code, beat_1, triangle, and toggle are assigned to be different labels in the kivy. See the kivy for more instructions triangle = ObjectProperty(None) toggle = ObjectProperty(None) tree = ObjectProperty(None) grid = ObjectProperty(None) angle = NumericProperty(0) pathSize = 0 fileName = "" #constructor for AmazonScene. the song that will play in the background is loaded here def __init__(self, name, **kwargs): self.name = name super(Screen, self).__init__() print("super") def doNothing(self, *args): pass #the following access the width and height of the current screen using the width and height properties of the Window object. These methods are used in the Kivy and below in other Python methods for positioning def getWindowWidth(self): return Window.width def getWindowHeight(self): return Window.height #plays the song def playSound(self, *args): self.audioFile.play() def start(self, *args): # if(self.name == "deforestation"): # t = threading.Timer(0, self.playSound) # t.start() self.animation = Animation(x=self.getWindowWidth(), y=0, duration=3.0, t="out_circ") self.animation &= Animation(size=(0, 0)) #self.animation += Animation(x=self.getWindowWidth(), y=0, duration=0.0) #self.animation += Animation(size=(10, self.getWindowHeight()), duration=0.0) self.animation.start(self.tree) self.animation.bind(on_complete=self.toDeforestation) print("anim") def toDeforestation(self, *args): sm.current = "deforestation" sm.on_enter = DeforestationScene.startSoundThread() print("started anim and song") #stop the song, the animation, set all the strings in the guitar tab graphic to black (implemented later in the Kivy), set all the tab text to empty strings, and home the carriage motor def stopSong(self): if (self.audioFile.state == 'play'): self.audioFile.stop() def quitUI(self): quit()
def __init__(self, **kwargs): super(Number, self).__init__(**kwargs) anim = Animation(scale=1., d=.15, t='out_quad') anim.bind(on_complete=self.clean_canvas) anim.start(self)
def intersecProg(self, layout, inQueue, outQueue, inter1, *largs): path = ((0, 0), (1, 0), (1, 1), (0, 1)) c = Window.center c = [c[0] - 20, c[1] - 20] roadAlign = 40 pathAnim = [ (c[0] - roadAlign, c[1] + roadAlign), (c[0] - roadAlign, c[1] - roadAlign), (c[0] + roadAlign, c[1] - roadAlign), (c[0] + roadAlign, c[1] + roadAlign), ] inQueueAnim = [ (c[0] - roadAlign, c[1] + roadAlign * 11), (c[0] - roadAlign * 11, c[1] - roadAlign), (c[0] + roadAlign, c[1] - roadAlign * 11), (c[0] + roadAlign * 11, c[1] + roadAlign), ] outQueueAnim = [ (c[0] + roadAlign, c[1] + roadAlign * 11), (c[0] - roadAlign * 11, c[1] + roadAlign), (c[0] - roadAlign, c[1] - roadAlign * 11), (c[0] + roadAlign * 11, c[1] - roadAlign), ] nbrCars = sum([len(way) for way in inQueue]) def moveCar(car, futurePos, ttDur): oldPos = car[3].pos[:] angle = car[3].angle movex, movey = futurePos[0] - oldPos[0], futurePos[1] - oldPos[1] if movex < 0: correctAngle = 270 if angle == 0: correctAngle = -90 elif movex > 0: correctAngle = 90 elif movey < 0: correctAngle = 0 if angle == 270: correctAngle = 360 else: correctAngle = 180 def forwardAnim(futurePos, dur, *largs): doNextMoveR.pop() anim = Animation(pos=futurePos, duration=ttDur - dur * 1.3) doNextMoveF.append(False) anim.start(largs[1]) anim.bind(on_complete=partial(popNextMoveF)) dur = 0.15 if correctAngle == angle: dur = 0 doNextMoveR.append(False) rotat = Animation(angle=correctAngle, duration=dur) rotat.start(car[3]) rotat.bind(on_complete=partial(forwardAnim, futurePos, dur)) def popNextMoveF(anim, widget): doNextMoveF.pop() if len(doNextMoveF) + len(doNextMoveR) == 0: # move by 1 every car for pathIndex in range(0, len(path)): x, y = path[pathIndex] newInterCase = {} if inter1[x][y] != {0: []}: for time, car in inter1[x][y].items(): carDestination = (car[1] + car[2] + 1) % 4 if path[carDestination] == path[(pathIndex + 1) % 4] and time == 0: outQueue[carDestination].append( car ) # move car to outqueue if reach destination moveCar(car, outQueueAnim[carDestination], 1) elif time != 0: newInterCase.update( {time - 1: car}) # move by 1 on timeline in case inter1[x][y] = newInterCase # change the state of the case if 0 in inter1[x][y]: moveCar(newInterCase[0], pathAnim[pathIndex], 1) newInQueue = [] for wayQueue in inQueue: # remove or reduce timer for cars in inqueue itemToKeep = [] for i in range(0, len(wayQueue)): item = wayQueue[i] if item[1] != 0: if item[1] != -1: item[1] -= 1 itemToKeep.append(item) newInQueue.append(itemToKeep[:]) inQueue = newInQueue[:] # take care of queue (add paths for cars) for way in range(0, 4): for carIndex in range(0, len(inQueue[way])): if inQueue[way][carIndex][1] == -1: car = inQueue[way][carIndex][0] doNotPath = True markdown = 0 while doNotPath: # search for path doNotPath = False markdown += 1 for i in range(way, way + car[2] + 1): pos = i % 4 x, y = path[pos] doNotPath = doNotPath or (markdown + i - way) in inter1[x][y] for i in range(way, way + car[2] + 1): # Add whole path at end timeline pos = i % 4 x, y = path[pos] inter1[x][y].update({markdown + i - way: car}) inQueue[way][carIndex][ 1] = markdown - 1 # Add when car exit inQueue layout.add_widget(car[3]) anim = Animation(pos=inQueueAnim[car[1]], duration=0) anim &= Animation(angle=90 * car[1], duration=0) doNextMoveF.append(False) oldPos = car[3].pos[:] anim.start(car[3]) anim.bind(on_complete=partial(popNextMoveF)) '''print "This move:"
class TransitionBase(EventDispatcher): '''Transition class is used to animate 2 screens within the :class:`ScreenManager`. This class act as a base for others implementation, like :class:`SlideTransition`, :class:`SwapTransition`. :Events: `on_progress`: Transition object, progression float Fired during the animation of the transition `on_complete`: Transition object Fired when the transition is fininshed. ''' screen_out = ObjectProperty() '''Property that contain the screen to hide. Automatically set by the :class:`ScreenManager`. :class:`screen_out` is a :class:`~kivy.properties.ObjectProperty`, default to None. ''' screen_in = ObjectProperty() '''Property that contain the screen to show. Automatically set by the :class:`ScreenManager`. :class:`screen_in` is a :class:`~kivy.properties.ObjectProperty`, default to None. ''' duration = NumericProperty(.7) '''Duration in seconds of the transition. :class:`duration` is a :class:`~kivy.properties.NumericProperty`, default to .7 (= 700ms) ''' manager = ObjectProperty() '''Screen manager object, set when the screen is added within a manager. :data:`manager` is a :class:`~kivy.properties.ObjectProperty`, default to None, read-only. ''' is_active = BooleanProperty(False) '''Indicate if the transition is currently active :data:`is_active` is a :class:`~kivy.properties.BooleanProperty`, default to False, read-only. ''' # privates _anim = ObjectProperty(allownone=True) def __init__(self, **kw): self.register_event_type('on_progress') self.register_event_type('on_complete') super(TransitionBase, self).__init__(**kw) def start(self, manager): '''(internal) Start the transition. This is automatically called by the :class:`ScreenManager`. ''' if self.is_active: raise ScreenManagerException('start() is called twice!') self.manager = manager self._anim = Animation(d=self.duration, s=0) self._anim.bind(on_progress=self._on_progress, on_complete=self._on_complete) self.add_screen(self.screen_in) self.screen_in.transition_progress = 0. self.screen_in.transition_mode = 'in' self.screen_out.transition_progress = 0. self.screen_out.transition_mode = 'out' self.is_active = True self._anim.start(self) self.dispatch('on_progress', 0) def stop(self): '''(internal) Stop the transition. This is automatically called by the :class:`ScreenManager`. ''' if self._anim: self._anim.cancel(self) self.dispatch('on_complete') self._anim = None self.is_active = False def add_screen(self, screen): '''(internal) Used to add a screen into the :class:`ScreenManager` ''' self.manager.real_add_widget(screen) def remove_screen(self, screen): '''(internal) Used to remove a screen into the :class:`ScreenManager` ''' self.manager.real_remove_widget(screen) def on_complete(self): self.remove_screen(self.screen_out) def on_progress(self, progression): pass def _on_progress(self, *l): progress = l[-1] self.screen_in.transition_progress = progress self.screen_out.transition_progress = 1. - progress self.dispatch('on_progress', progress) def _on_complete(self, *l): self.is_active = False self.dispatch('on_complete') self._anim = None
def on_focus(self, *args): disabled_hint_text_color = self.theme_cls.disabled_hint_text_color Animation.cancel_all(self, "_line_width", "_hint_y", "_hint_lbl_font_size") self._set_text_len_error() if self.focus: if not self._get_has_error(): def on_progress(*args): self._line_blank_space_right_point = ( self._hint_lbl.width + dp(5)) animation = Animation( _line_blank_space_left_point=self._hint_lbl.x - dp(5), _current_hint_text_color=self.line_color_focus, _fill_color=self.fill_color[:-1] + [self.fill_color[-1] - 0.1], duration=0.2, t="out_quad", ) animation.bind(on_progress=on_progress) animation.start(self) self.has_had_text = True Animation.cancel_all(self, "_line_width", "_hint_y", "_hint_lbl_font_size") if not self.text: self._anim_lbl_font_size(dp(14), sp(12)) Animation( _line_width=self.width, duration=(0.2 if self.line_anim else 0), t="out_quad", ).start(self) if self._get_has_error(): self._anim_current_error_color(self.error_color) if self.helper_text_mode == "on_error" and ( self.error or self._text_len_error): self._anim_current_error_color(self.error_color) elif (self.helper_text_mode == "on_error" and not self.error and not self._text_len_error): self._anim_current_error_color((0, 0, 0, 0)) elif self.helper_text_mode in ("persistent", "on_focus"): self._anim_current_error_color(disabled_hint_text_color) else: self._anim_current_right_lbl_color(disabled_hint_text_color) Animation( duration=0.2, _current_hint_text_color=self.line_color_focus).start(self) if self.helper_text_mode == "on_error": self._anim_current_error_color((0, 0, 0, 0)) if self.helper_text_mode in ("persistent", "on_focus"): self._anim_current_error_color(disabled_hint_text_color) else: Animation( _fill_color=self.fill_color[:-1] + [self.fill_color[-1] + 0.1], duration=0.2, t="out_quad", ).start(self) if not self.text: self._anim_lbl_font_size(dp(38), sp(16)) Animation( _line_blank_space_right_point=0, _line_blank_space_left_point=0, duration=0.2, t="out_quad", ).start(self) if self._get_has_error(): self._anim_get_has_error_color(self.error_color) if self.helper_text_mode == "on_error" and ( self.error or self._text_len_error): self._anim_current_error_color(self.error_color) elif (self.helper_text_mode == "on_error" and not self.error and not self._text_len_error): self._anim_current_error_color((0, 0, 0, 0)) elif self.helper_text_mode == "persistent": self._anim_current_error_color(disabled_hint_text_color) elif self.helper_text_mode == "on_focus": self._anim_current_error_color((0, 0, 0, 0)) else: Animation(duration=0.2, color=(1, 1, 1, 1)).start(self._hint_lbl) self._anim_get_has_error_color() if self.helper_text_mode == "on_error": self._anim_current_error_color((0, 0, 0, 0)) elif self.helper_text_mode == "persistent": self._anim_current_error_color(disabled_hint_text_color) elif self.helper_text_mode == "on_focus": self._anim_current_error_color((0, 0, 0, 0)) Animation( _line_width=0, duration=(0.2 if self.line_anim else 0), t="out_quad", ).start(self)
def forwardAnim(futurePos, dur, *largs): doNextMoveR.pop() anim = Animation(pos=futurePos, duration=ttDur - dur * 1.3) doNextMoveF.append(False) anim.start(largs[1]) anim.bind(on_complete=partial(popNextMoveF))
def show_text_input(self, input): ani = Animation(x=0, duration=0.05) ani.bind(on_complete=self.on_complete) self.__float_input__.input = input ani.start(self.__float_input__)
def animate_game_event(self, widget=None, anim_duration=0.2): """ Process a single event from self.animation_queue Read the event and perform the correct actions on widgets (such as update text of log window, create and launch animation, maybe make some sound). The event is removed from self.map.game_events. After the actions required are performed, the method calls itself again, either recursively, or, in case of animations, via Animation's on_complete argument. The recursion is broken when event queue is empty. :return: """ if widget and widget.parent and widget.height == 0: # If the widget was given zero size, this means it should be removed # This entire affair is kinda inefficient and should be rebuilt later widget.parent.remove_widget(widget) if not self.animation_queue == []: event = self.animation_queue.pop(0) if event.event_type == 'moved': final = self.get_screen_pos(event.actor.location, center=True) if final[0] < event.actor.widget.pos[0] and event.actor.widget.direction == 'right'\ or final[0] > event.actor.widget.pos[0] and event.actor.widget.direction == 'left': event.actor.widget.flip() a = Animation(center=final, duration=anim_duration) a.bind(on_start=lambda x, y: self.remember_anim(), on_complete=lambda x, y: self.animate_game_event(widget=y)) a.start(event.actor.widget) elif event.event_type == 'attacked': current = self.get_screen_pos(event.actor.location, center=True) target = self.get_screen_pos(event.location, center=True) if target[0] > current[0] and event.actor.widget.direction == 'left' or\ target[0] < current[0] and event.actor.widget.direction == 'right': event.actor.widget.flip() a = Animation(center_x=current[0]+int((target[0]-current[0])/2), center_y=current[1]+int((target[1]-current[1])/2), duration=anim_duration/2) a += Animation(center_x=current[0], center_y=current[1], duration=anim_duration/2) a.bind(on_start=lambda x, y: self.remember_anim(), on_complete=lambda x, y: self.animate_game_event(widget=y)) a.start(event.actor.widget) self.parent.boombox['attacked'].seek(0) self.parent.boombox['attacked'].play() elif event.event_type == 'was_destroyed': if not event.actor.widget: # If actor is None, that means it was destroyed right after spawning, not getting a # widget. Similar case is covered under 'dropped', see there for example. The check is # different here, because in 'dropped' item is taken from map, where it's None by the time # this method runs. Here, on the other hand, Item object exists (in GameEvent), but has # no widget (and is not placed on map, but that's irrelevant). self.animate_game_event() return a = Animation(size=(0, 0), duration=anim_duration) a.bind(on_start=lambda x, y: self.remember_anim(), on_complete=lambda x, y: self.animate_game_event(widget=y)) a.start(event.actor.widget) elif event.event_type == 'picked_up': # It's assumed that newly added item will be the last in player inventory self.layer_widgets['items'].remove_widget(self.map.actors[0].inventory[-1].widget) self.animate_game_event() elif event.event_type == 'dropped': item = self.map.get_item(location=event.location, layer='items') if not item: # Item could've been destroyed right after being drop, ie it didn't get a widget. Skip. # It's rather likely if someone was killed by landmine, dropped an item and had this item # destroyed in the same explosion self.animate_game_event() return if not item.widget: self.tile_factory.create_widget(item) item.widget.center = self.get_screen_pos(event.location, center=True) self.layer_widgets['items'].add_widget(item.widget) self.animate_game_event() elif event.event_type == 'actor_spawned': if not event.actor.widget: self.tile_factory.create_widget(event.actor) event.actor.widget.center = self.get_screen_pos(event.location, center=True) self.layer_widgets['actors'].add_widget(event.actor.widget) self.animate_game_event() elif event.event_type == 'construction_spawned': if not event.actor.widget: self.tile_factory.create_widget(event.actor) event.actor.widget.center = self.get_screen_pos(event.location, center=True) self.layer_widgets['constructions'].add_widget(event.actor.widget) self.animate_game_event() elif event.event_type == 'exploded': loc = self.get_screen_pos(event.location) loc = (loc[0]+16, loc[1]+16) self.overlay_widget = Image(source='Explosion.png', size=(0, 0), size_hint=(None, None), pos=loc) a = Animation(size=(96, 96), pos=(loc[0]-32, loc[1]-32), duration=0.3) a += Animation(size=(0, 0), pos=loc, duration=0.3) a.bind(on_start=lambda x, y: self.remember_anim(), on_complete=lambda x, y: self.animate_game_event(widget=y)) self.add_widget(self.overlay_widget) self.parent.boombox['exploded'].seek(0) self.parent.boombox['exploded'].play() a.start(self.overlay_widget) elif event.event_type == 'rocket_shot': self.overlay_widget = RelativeLayout(center=self.get_screen_pos(event.actor.location, center=True), size=(64,64), size_hint=(None, None)) i = Image(source='Rocket.png', size=(32, 32), size_hint=(None, None)) self.overlay_widget.add_widget(i) self.overlay_widget.canvas.before.add(Translate(x=16, y=16)) a = degrees(atan2(event.actor.location[1]-event.location[1], event.actor.location[0]-event.location[0])) # if abs(a) >= 90: # self.overlay_widget.center_y += 64 self.overlay_widget.canvas.before.add(Rotate(angle=a+90, axis=(0, 0, 1), origin=i.center)) a = Animation(center=self.get_screen_pos(event.location, center=True), duration=anim_duration) a += Animation(size=(0, 0), duration=0) a.bind(on_start=lambda x, y: self.remember_anim(), on_complete=lambda x, y: self.animate_game_event(widget=y)) self.add_widget(self.overlay_widget) a.start(self.overlay_widget) elif event.event_type == 'shot': self.overlay_widget = Image(source='Shot.png', size=(32, 32), size_hint=(None, None), pos=self.get_screen_pos(event.actor.location)) a = Animation(pos=self.get_screen_pos(event.location), duration=anim_duration) a += Animation(size=(0, 0), duration=0) a.bind(on_start=lambda x, y: self.remember_anim(), on_complete=lambda x, y: self.animate_game_event(widget=y)) self.add_widget(self.overlay_widget) self.parent.boombox['shot'].seek(0) self.parent.boombox['shot'].play() a.start(self.overlay_widget) elif event.event_type in self.non_animated: self.parent.process_nonmap_event(event) self.animate_game_event() else: # Reactivating keyboard after finishing animation self.animating = False # Might as well be time to redraw the Dijkstra widget if DISPLAY_DIJKSTRA_MAP: if self.dijkstra_widget: self.remove_widget(self.dijkstra_widget) # else: # self.map.dijkstras['PC'].rebuild_self() self.dijkstra_widget = DijkstraWidget(parent=self) self.add_widget(self.dijkstra_widget)
def anim_resize_open_item(self, *args): self.content.name_item = self.title anim = Animation(height=self.content.height + dp(70), d=.2, t='in_cubic') anim.bind(on_complete=self.add_content) anim.start(self)
def display_title(self, *args): a = Animation(title_y_decal=0, d=.4, t='out_quad') a.bind(on_complete=self.display_carousel) a.start(self.root.ids.container)