def on_touch_down(self, touch): if not super(FrescoThumbnail, self).on_touch_down(touch): return Animation.stop_all(self, "pos") if touch.is_double_tap: self.show_popup() return True
def toggle(self): Animation.stop_all(self, 'x') Animation.stop_all(self.shadow, 'color') if self._open: if self.side == 'left': target_x = -1 * self.width else: target_x = Window.width sh_anim = Animation(duration=self.anim_length_open, t=self.animation_t_open, color=[0, 0, 0, 0]) sh_anim.start(self.shadow) self._get_main_animation(duration=self.anim_length_close, t=self.animation_t_close, x=target_x).start(self) self._open = False else: if self.side == 'left': target_x = 0 else: target_x = Window.width - self.width Animation(duration=self.anim_length_open, t=self.animation_t_open, color=[0, 0, 0, 0.5]).start(self.shadow) self._get_main_animation(duration=self.anim_length_open, t=self.animation_t_open, x=target_x).start(self) self._open = True
def toggle_widget_tree(self, *args): new_x = 0 if self.widget_tree.x > self.widget_tree.width* -0.5: new_x = - self.widget_tree.width Animation.stop_all(self.widget_tree, 'x') anim = Animation(x=new_x, t='out_expo', d=0.5) anim.start(self.widget_tree)
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_mouse - d elif touch.button == 'scrolldown': syd = self._scroll_y_mouse + d self._scroll_y_mouse = scroll_y = min(max(syd, 0), 1) Animation.stop_all(self, 'scroll_y') Animation(scroll_y=scroll_y, d=.3, t='out_quart').start(self) Clock.unschedule(self._update_animation) 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 toggle_timeline(self, *largs): if self.timeline_target == 1.0: self.timeline_target = 0.0 else: self.timeline_target = 1.0 Animation.stop_all(self, 'timeline_pos') timeline_anim = Animation(timeline_pos=self.timeline_target, t='out_quad', d=0.4) timeline_anim.start(self)
def on_press(self): img = self.ids['main_img'] label = self.ids['main_label'] Animation.stop_all(img) anim = Animation(color=self.color) anim_label = Animation(opacity=1,duration=0.05) anim.start(img) anim_label.start(label) anim.on_complete = self.launch_expo
def animate_remove_shrink(self): if self.parent is None: raise ValueError('tried to remove TouchPosition but it has no parent') self.throbbing = False Animation.stop_all(self) anim = Animation(radius=0, duration=0.25, t='out_quad') anim.bind(on_complete=self.remove_from_parent) anim.start(self)
def update_from_scroll(self, *largs): '''Force the reposition of the content, according to current value of :attr:`scroll_x` and :attr:`scroll_y`. This method is automatically called when one of the :attr:`scroll_x`, :attr:`scroll_y`, :attr:`pos` or :attr:`size` properties change, or if the size of the content changes. ''' if not self._viewport: return vp = self._viewport # update from size_hint if vp.size_hint_x is not None: w = vp.size_hint_x * self.width if vp.size_hint_min_x is not None: w = max(w, vp.size_hint_min_x) if vp.size_hint_max_x is not None: w = min(w, vp.size_hint_max_x) vp.width = w if vp.size_hint_y is not None: h = vp.size_hint_y * self.height if vp.size_hint_min_y is not None: h = max(h, vp.size_hint_min_y) if vp.size_hint_max_y is not None: h = min(h, vp.size_hint_max_y) vp.height = h if vp.width > self.width: sw = vp.width - self.width x = self.x - self.scroll_x * sw else: x = self.x if vp.height > self.height: sh = vp.height - self.height y = self.y - self.scroll_y * sh else: y = self.top - vp.height # from 1.8.0, we now use a matrix by default, instead of moving the # widget position behind. We set it here, but it will be a no-op most # of the time. vp.pos = 0, 0 self.g_translate.xy = x, y # New in 1.2.0, show bar when scrolling happens and (changed in 1.9.0) # fade to bar_inactive_color when no scroll is happening. ev = self._bind_inactive_bar_color_ev if ev is None: ev = self._bind_inactive_bar_color_ev = Clock.create_trigger( self._bind_inactive_bar_color, .5) self.funbind('bar_inactive_color', self._change_bar_color) Animation.stop_all(self, '_bar_color') self.fbind('bar_color', self._change_bar_color) self._bar_color = self.bar_color ev()
def scroll_to(self, widget, padding=10, animate=True): '''Scrolls the viewport to ensure that the given widget is visible, optionally with padding and animation. If animate is True (the default), then the default animation parameters will be used. Otherwise, it should be a dict containing arguments to pass to :class:`~kivy.animation.Animation` constructor. .. versionadded:: 1.9.1 ''' if not self.parent: return # if _viewport is layout and has pending operation, reschedule if hasattr(self._viewport, 'do_layout'): if self._viewport._trigger_layout.is_triggered: Clock.schedule_once( lambda *dt: self.scroll_to(widget, padding, animate)) return if isinstance(padding, (int, float)): padding = (padding, padding) pos = self.parent.to_widget(*widget.to_window(*widget.pos)) cor = self.parent.to_widget(*widget.to_window(widget.right, widget.top)) dx = dy = 0 if pos[1] < self.y: dy = self.y - pos[1] + dp(padding[1]) elif cor[1] > self.top: dy = self.top - cor[1] - dp(padding[1]) if pos[0] < self.x: dx = self.x - pos[0] + dp(padding[0]) elif cor[0] > self.right: dx = self.right - cor[0] - dp(padding[0]) dsx, dsy = self.convert_distance_to_scroll(dx, dy) sxp = min(1, max(0, self.scroll_x - dsx)) syp = min(1, max(0, self.scroll_y - dsy)) if animate: if animate is True: animate = {'d': 0.2, 't': 'out_quad'} Animation.stop_all(self, 'scroll_x', 'scroll_y') Animation(scroll_x=sxp, scroll_y=syp, **animate).start(self) else: self.scroll_x = sxp self.scroll_y = syp
def scroll_to(self, widget, padding=10, animate=True): '''Scrolls the viewport to ensure that the given widget is visible, optionally with padding and animation. If animate is True (the default), then the default animation parameters will be used. Otherwise, it should be a dict containing arguments to pass to :class:`~kivy.animation.Animation` constructor. .. versionadded:: 1.9.1 ''' if not self.parent: return # if _viewport is layout and has pending operation, reschedule if hasattr(self._viewport, 'do_layout'): if self._viewport._trigger_layout.is_triggered: Clock.schedule_once( lambda *dt: self.scroll_to(widget, padding, animate)) return if isinstance(padding, (int, float)): padding = (padding, padding) pos = self.parent.to_widget(*widget.to_window(*widget.pos)) cor = self.parent.to_widget( *widget.to_window(widget.right, widget.top)) dx = dy = 0 if pos[1] < self.y: dy = self.y - pos[1] + dp(padding[1]) elif cor[1] > self.top: dy = self.top - cor[1] - dp(padding[1]) if pos[0] < self.x: dx = self.x - pos[0] + dp(padding[0]) elif cor[0] > self.right: dx = self.right - cor[0] - dp(padding[0]) dsx, dsy = self.convert_distance_to_scroll(dx, dy) sxp = min(1, max(0, self.scroll_x - dsx)) syp = min(1, max(0, self.scroll_y - dsy)) if animate: if animate is True: animate = {'d': 0.2, 't': 'out_quad'} Animation.stop_all(self, 'scroll_x', 'scroll_y') Animation(scroll_x=sxp, scroll_y=syp, **animate).start(self) else: self.scroll_x = sxp self.scroll_y = syp
def update_from_scroll(self, *largs): '''Force the reposition of the content, according to current value of :data:`scroll_x` and :data:`scroll_y`. This method is automatically called when one of the :data:`scroll_x`, :data:`scroll_y`, :data:`pos` or :data:`size` properties change, or if the size of the content changes. ''' if not self._viewport: return vp = self._viewport vpheight = vp.height vpwidth = vp.width # update from size_hint if vp.size_hint_x is not None: vpwidth = vp.size_hint_x * self.width if vp.size_hint_y is not None: vpheight = vp.size_hint_y * self.height if vpwidth > self.width: sw = vpwidth - self.width x = self.x - self.scroll_x * sw else: x = self.x if vpheight > self.height: sh = vpheight - self.height y = self.y - self.scroll_y * sh else: y = self.top - vpheight logger.info(str([x,y, vp.width,vp.height])) vp.updateVP(x,y,vpwidth, vpheight) vp.height=vpheight vp.width=vpwidth #vp.vppos = x, y # that must be magic .. vp.pos = x, y # new in 1.2.0, show bar when scrolling happen # and slowly remove them when no scroll is happening. self.bar_alpha = 1. Animation.stop_all(self, 'bar_alpha') Clock.unschedule(self._start_decrease_alpha) Clock.schedule_once(self._start_decrease_alpha, .5)
def play(self): self._initalize_circ() self._initialize_cross() anim = Animation( angle_start_l=self.angle_start_l, angle_end_l=315, angle_start_r=self.angle_start_r, angle_end_r=45, # t='in_quad', d=0.2, ) anim.bind(on_complete=self._intermediate) anim.stop_all(self) anim.start(self)
def show_float_button(self): if self._float_anim_playing: self._float_anim_playing = True return self._float_button_status = "open" Animation.stop_all(self._floating_button) width = Window.width anim = Animation( right=width - self.float_button_padding_x, d=self.duration, t=self.transition, ) anim.bind(on_complete=self._allow_float_anim) anim.start(self._floating_button)
def center_on(self, val, animate=True): Animation.stop_all(self) center_index = self.index_of(val) half_length = self.line_length / 2. / self.scale index_0 = center_index - half_length index_1 = center_index + half_length if animate: anim = Animation(index_0=index_0, index_1=index_1, duration=self.center_duration) anim.on_complete = lambda *args: self._centered() anim.start(self) else: self.index_0 = index_0 self.index_1 = index_1 self._centered()
def window_state(self, value): print(value, self._window_state) VALID_VALUES = ('VISIBLE', 'HIDDEN', 'INVERT') if value not in VALID_VALUES: raise ValueError if value == 'INVERT': self._window_state = 'VISIBLE' if self._window_state == 'HIDDEN' else 'HIDDEN' else: self._window_state = value Animation.stop_all(Window) Animation(top=0 if self._window_state == 'VISIBLE' else -Window.height, d=.5, t='out_expo').start(Window)
def update_from_scroll(self, *largs): '''Force the reposition of the content, according to current value of :attr:`scroll_x` and :attr:`scroll_y`. This method is automatically called when one of the :attr:`scroll_x`, :attr:`scroll_y`, :attr:`pos` or :attr:`size` properties change, or if the size of the content changes. ''' if not self._viewport: return vp = self._viewport # update from size_hint if vp.size_hint_x is not None: vp.width = vp.size_hint_x * self.width if vp.size_hint_y is not None: vp.height = vp.size_hint_y * self.height if vp.width > self.width: sw = vp.width - self.width x = self.x - self.scroll_x * sw else: x = self.x if vp.height > self.height: sh = vp.height - self.height y = self.y - self.scroll_y * sh else: y = self.top - vp.height # from 1.8.0, we now use a matrix by default, instead of moving the # widget position behind. We set it here, but it will be a no-op most of # the time. vp.pos = 0, 0 self.g_translate.xy = x, y # New in 1.2.0, show bar when scrolling happens and (changed in 1.9.0) # fade to bar_inactive_color when no scroll is happening. ev = self._bind_inactive_bar_color_ev if ev is None: ev = self._bind_inactive_bar_color_ev = Clock.create_trigger( self._bind_inactive_bar_color, .5) self.funbind('bar_inactive_color', self._change_bar_color) Animation.stop_all(self, '_bar_color') self.fbind('bar_color', self._change_bar_color) self._bar_color = self.bar_color ev()
def scroll_to(self, widget, padding=10, animate=True): """Sacado directamente del código fuente de kivy 1.9.1-dev: Scrolls the viewport to ensure that the given widget is visible, optionally with padding and animation. If animate is True (the default), then the default animation parameters will be used. Otherwise, it should be a dict containing arguments to pass to :class:`~kivy.animation.Animation` constructor. .. versionadded:: 1.9.1 """ if not self.parent: return if isinstance(padding, (int, float)): padding = (padding, padding) pos = self.parent.to_widget(*widget.to_window(*widget.pos)) cor = self.parent.to_widget(*widget.to_window(widget.right, widget.top)) dx = dy = 0 if pos[1] < self.y: dy = self.y - pos[1] + dp(padding[1]) elif cor[1] > self.top: dy = self.top - cor[1] - dp(padding[1]) if pos[0] < self.x: dx = self.x - pos[0] + dp(padding[0]) elif cor[0] > self.right: dx = self.right - cor[0] - dp(padding[0]) dsx, dsy = self.convert_distance_to_scroll(dx, dy) sxp = min(1, max(0, self.scroll_x - dsx)) syp = min(1, max(0, self.scroll_y - dsy)) if animate: if animate is True: animate = {'d': 0.2, 't': 'out_quad'} Animation.stop_all(self, 'scroll_x', 'scroll_y') Animation(scroll_x=sxp, scroll_y=syp, **animate).start(self) else: self.scroll_x = sxp self.scroll_y = syp
def checks(self,dir,len): if self.parent.dispMaze[int(self.y)][int(self.x)] is not None: self.parent.parent.deaths += 1 self.parent.veil.shade=0 anim = Animation(shade=1, duration=.1) anim.start(self.parent.veil) self.x = 0 self.y = self.parent.mazeDim Animation(x=self.x+1, duration=self.speed).start(self) elif self.x == 0: Animation.stop_all(self) Animation(x=self.x+1, duration=self.speed).start(self) elif self.x == self.parent.mazeDim*2: self.parent.parent.level += 1 Animation.stop_all(self) self.parent.start() else: self.move(dir,len)
class BoardUI(Widget): ball = ObjectProperty(None) def __init__(self): Widget.__init__(self) self.anim = Animation(x=550, duration=3., t='in_elastic') self.anim.start(self.ball) def on_touch_down(self, touch): print("Touch widget at ({0}, {1})".format(touch.px, touch.py)) self.anim.stop_all(self.ball) self.anim = Animation(x=touch.px, y=touch.py, duration=2.,t='in_out_cubic') self.anim.start(self.ball) def update(self, dt): print self.ball.x def draw(self, **kwargs): pass
def update_from_scroll(self, *largs): '''Force the reposition of the content, according to current value of :data:`scroll_x` and :data:`scroll_y`. This method is automatically called when one of the :data:`scroll_x`, :data:`scroll_y`, :data:`pos` or :data:`size` properties change, or if the size of the content changes. ''' if not self._viewport: return vp = self._viewport if self.do_scroll_x: self.scroll_x = min(1, max(0, self.scroll_x)) self._scroll_x_mouse = self.scroll_x if self.do_scroll_y: self.scroll_y = min(1, max(0, self.scroll_y)) self._scroll_y_mouse = self.scroll_y # update from size_hint if vp.size_hint_x is not None: vp.width = vp.size_hint_x * self.width if vp.size_hint_y is not None: vp.height = vp.size_hint_y * self.height if vp.width > self.width: sw = vp.width - self.width x = self.x - self.scroll_x * sw else: x = self.x if vp.height > self.height: sh = vp.height - self.height y = self.y - self.scroll_y * sh else: y = self.top - vp.height vp.pos = x, y # new in 1.2.0, show bar when scrolling happen # and slowly remove them when no scroll is happening. self.bar_alpha = 1. Animation.stop_all(self, 'bar_alpha') Clock.unschedule(self._start_decrease_alpha) Clock.schedule_once(self._start_decrease_alpha, .5)
def on_touch_down(self, touch): if not self.collide_point(*touch.pos): touch.ud[self._get_uid('svavoid')] = True return if self._touch: return super(ScrollView, self).on_touch_down(touch) # 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) if d != 0: d = self.scroll_distance / float(d) if touch.button == 'scrollup': syd = self._scroll_y_mouse - d elif touch.button == 'scrolldown': syd = self._scroll_y_mouse + d self._scroll_y_mouse = scroll_y = min(max(syd, 0), 1) Animation.stop_all(self, 'scroll_y') Animation(scroll_y=scroll_y, d=.3, t='out_quart').start(self) Clock.unschedule(self._update_animation) 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, 'user_stopped': False, 'same': 0, 'moves': FixedList(self.scroll_moves)} Clock.schedule_interval(self._update_delta, 0) Clock.schedule_once(self._change_touch_mode, self.scroll_timeout / 1000.) return True
def screensaver(dt=None, stop=False): Animation.stop_all(scatter_imageButtons) if not stop: anim = Animation(opacity=.5, d=5) anim.start(scatter_imageButtons) else: scatter_imageButtons.opacity = 1 for child in app.root_images.children: if child.isParent and child.__class__.__name__ == 'ImageItem': if hasattr(child, 'body') and child.body != None: if stop == False: forces = [-5, 5, 0] rx = choice(forces) ry = choice(forces) child.body.reset_forces() child.body.apply_force((rx, ry), r=(0, 0)) else: child.body.reset_forces()
def update_from_scroll(self, *largs): '''Force the reposition of the content, according to current value of :attr:`scroll_x` and :attr:`scroll_y`. This method is automatically called when one of the :attr:`scroll_x`, :attr:`scroll_y`, :attr:`pos` or :attr:`size` properties change, or if the size of the content changes. ''' if not self._viewport: return vp = self._viewport # update from size_hint if vp.size_hint_x is not None: vp.width = vp.size_hint_x * self.width if vp.size_hint_y is not None: vp.height = vp.size_hint_y * self.height if vp.width > self.width: sw = vp.width - self.width x = self.x - self.scroll_x * sw else: x = self.x if vp.height > self.height: sh = vp.height - self.height y = self.y - self.scroll_y * sh else: y = self.top - vp.height # from 1.8.0, we now use a matrix by default, instead of moving the # widget position behind. We set it here, but it will be a no-op most of # the time. vp.pos = 0, 0 self.g_translate.xy = x, y # new in 1.2.0, show bar when scrolling happen # and slowly remove them when no scroll is happening. if self.scrollbar_animate is True: self.bar_alpha = 1. Animation.stop_all(self, 'bar_alpha') Clock.unschedule(self._start_decrease_alpha) Clock.schedule_once(self._start_decrease_alpha, .5)
def __init__(self, **kw): super().__init__(**kw) for child in self.widget.children: if isinstance(child, OverdrawLabel): child.dismiss() self.widget.overdrawer = self self.widget.add_widget(self) Animation.stop_all(self) Animation(opacity=1, d=.2).start(self) if Config.get('animations', True): anim = ( Animation(angle=self.__MAX_TILT, d=.3, t='in_out_expo') + Animation(angle=0, d=1, t='out_elastic') + Animation(d=2) + Animation(angle=self.__MAX_TILT * -1, d=.3, t='in_out_expo') + Animation(angle=0, d=1, t='out_elastic') + Animation(d=2)) anim.repeat = True anim.start(self)
def my_on_btn_more(self, *largs): if self.flip_front == True: new_rotation = 45 else: new_rotation = 0 anim = Animation(d=.3, rotation=new_rotation, t='out_quad') Animation.stop_all(self.btn_more_cross, 'rotation') anim.start(self.btn_more_cross) # self.img_square.scale = 0.4 print 'btn more', self.projection, self.flip_front if self.projection and self.flip_front == True: print 'launching message' send_message(self.projection) send_message(',add') elif self.projection and self.flip_front == False: send_message(self.projection) send_message(',remove') self.flip()
def on_edit_mode(self, instance, value): self.do_translation = (self.edit_mode, self.edit_mode) self.scale = 1 self.do_translation = value if (value): # Edit Mode activado transitionName = "in_out_quad" anim = Animation(scale=1.05, duration=.5, t=transitionName) anim += Animation(scale=.95, duration=.5, t=transitionName) anim.repeat = True anim.start(self) else: # Edit Mode desactivado self.updateInstanceOnDB() transitionName = "in_out_sine" Animation.stop_all(self) anim = Animation(scale=1.1, duration=.25, t=transitionName) anim += Animation(scale=.9, duration=.25, t=transitionName) anim += Animation(scale=1, duration=.125, t=transitionName) anim.start(self)
def update_from_scroll(self, *largs): """Force the reposition of the content, according to current value of :data:`scroll_x` and :data:`scroll_y`. This method is automatically called when one of the :data:`scroll_x`, :data:`scroll_y`, :data:`pos` or :data:`size` properties change, or if the size of the content changes. """ if not self._viewport: return vp = self._viewport if self.do_scroll_x: self.scroll_x = min(1, max(0, self.scroll_x)) if self.do_scroll_y: self.scroll_y = min(1, max(0, self.scroll_y)) # update from size_hint if vp.size_hint_x is not None: vp.width = vp.size_hint_x * self.width if vp.size_hint_y is not None: vp.height = vp.size_hint_y * self.height if vp.width > self.width: sw = vp.width - self.width x = self.x - self.scroll_x * sw else: x = self.x if vp.height > self.height: sh = vp.height - self.height y = self.y - self.scroll_y * sh else: y = self.top - vp.height vp.pos = x, y # new in 1.2.0, show bar when scrolling happen # and slowly remove them when no scroll is happening. self.bar_alpha = 1.0 Animation.stop_all(self, "bar_alpha") Clock.unschedule(self._start_decrease_alpha) Clock.schedule_once(self._start_decrease_alpha, 0.5)
def update_from_scroll(self, *largs): '''Force the reposition of the content, according to current value of :attr:`scroll_x` and :attr:`scroll_y`. This method is automatically called when one of the :attr:`scroll_x`, :attr:`scroll_y`, :attr:`pos` or :attr:`size` properties change, or if the size of the content changes. ''' if not self._viewport: return vp = self._viewport # update from size_hint if vp.size_hint_x is not None: vp.width = vp.size_hint_x * self.width if vp.size_hint_y is not None: vp.height = vp.size_hint_y * self.height if vp.width > self.width: sw = vp.width - self.width x = self.x - self.scroll_x * sw else: x = self.x if vp.height > self.height: sh = vp.height - self.height y = self.y - self.scroll_y * sh else: y = self.top - vp.height # from 1.8.0, we now use a matrix by default, instead of moving the # widget position behind. We set it here, but it will be a no-op most of # the time. vp.pos = 0, 0 self.g_translate.xy = x, y # new in 1.2.0, show bar when scrolling happen # and slowly remove them when no scroll is happening. self.bar_alpha = 1. Animation.stop_all(self, 'bar_alpha') Clock.unschedule(self._start_decrease_alpha) Clock.schedule_once(self._start_decrease_alpha, .5)
def on_rate_structure_selected(self, instance, value): try: logging.info('CostSavings: Rate structure selection changed to {0}.'.format(value['name'])) except KeyError: logging.info('CostSavings: Rate structure selection reset.') self.rate_structure_desc.text = '' self.has_selection = False else: Animation.stop_all(self.preview_box, 'opacity') self.preview_box.opacity = 0 def _generate_preview(): self.generate_schedule_charts() self.generate_flat_demand_rate_table() self.generate_misc_table() Clock.schedule_once(partial(fade_in_animation, self.preview_box), 0) self.has_selection = True thread_preview = threading.Thread(target=_generate_preview) thread_preview.start()
def _set_toolbar_pos(self, instance, vbar): y = vbar[0] * self.height if not self._last_y: self._last_y = y return else: diff = self._last_y - y self._last_y = y # Sometimes scrollview jumps suddenly if diff > 50: return # handle floating button scrolled_y = (1 - vbar[1] - vbar[0]) * self.height if ( scrolled_y > self.float_button_show_distance and self._float_button_status == "close" ): self.show_float_button() elif ( scrolled_y < self.float_button_show_distance and self._float_button_status == "open" ): self.hide_float_button() if self._anim_playing: Animation.stop_all(self._toolbar) self._anim_playing = False self._toolbar.y += diff # hide if self._toolbar.y > self.height: self.hide_toolbar() # full size elif ( self._toolbar.top < self.height or round(vbar[0] + vbar[1], 2) == 1 ): self.show_toolbar()
def toggle(self): Animation.stop_all(self, "x") Animation.stop_all(self.shadow, "color") if self._open: if self.side == "left": target_x = -1 * self.width else: target_x = Window.width sh_anim = Animation( duration=self.anim_length_open, t=self.animation_t_open, color=[0, 0, 0, 0], ) sh_anim.start(self.shadow) self._get_main_animation( duration=self.anim_length_close, t=self.animation_t_close, x=target_x, is_closing=True, ).start(self) self._open = False else: if self.side == "left": target_x = 0 else: target_x = Window.width - self.width Animation( duration=self.anim_length_open, t=self.animation_t_open, color=[0, 0, 0, 0.5], ).start(self.shadow) self._get_main_animation( duration=self.anim_length_open, t=self.animation_t_open, x=target_x, is_closing=False, ).start(self) self._open = True
def clear_bubbles(self, bulk): def check_animation(): flag = False for anim in Animation._instances: if ( anim._widgets and anim._widgets.values() and anim._widgets.values()[0].get("widget", "").__class__ == CustomScatter().__class__ ): flag = True break return flag bulk = set(bulk) cols = set([]) for scatter in bulk: Animation.stop_all(scatter) scatter.cleared = True cols.add(scatter.col) set_color(scatter.children[0], get_color_from_hex("303030")) if cols: self.swift(columns=list(cols))
def keyInput(self, key): # if key.prop[0] == 'input': # if len(self.label_text.text) < 6: # if not self.alternative: # self.label_text.text += key.prop[4] # else: # self.label_text.text += key.prop[6] # self.resetNextInput() # self.dispatch('on_input', self.label_text.text) # elif key.prop[0] == 'back': # if len(self.label_text.text) > 0: # self.label_text.text = self.label_text.text[0:len(self.label_text.text) - 1] #moche mais fait le taf # self.resetNextInput() # self.dispatch('on_input', self.label_text.text) # self.enable_key() # elif key.prop[0] == 'clear': # self.clear_text() # elif key.prop[0] == 'change': # self.switch() # center_tmp = (key.center[0], key.center[1]) # key.size = (key.size[0] + 15, key.size[1] + 15) # key.wd = key.wd + 15 # key.hgt = key.hgt + 15 Animation.stop_all(key) anim = Animation(wd=key.wd_fix + 15, hgt=key.hgt_fix + 15, duration=0.07, t='in_quad') anim.start(key) # key.center = center_tmp parent = key.parent parent.remove_widget(key) parent.add_widget(key) key.background_color = [1, 1, 1, 1]
def on_collision_with_deflector(self, deflector, deflector_vector): self.parent.app.sound['deflection'].play() # flash up the deflector Animation.stop_all(deflector.point1, 'color') Animation.stop_all(deflector.point2, 'color') deflector.point1.color = (1, 1, 1, 1) deflector.point2.color = (1, 1, 1, 1) animation = Animation(color=(0, 0, 1, 1), duration=3, t='out_expo') animation.start(deflector.point1) animation.start(deflector.point2) # calculate deflection angle impact_angle = (radians(deflector_vector.angle(Vector(1, 0))) % pi) - (self.angle % pi) self.angle = (self.angle + 2*impact_angle) % (2*pi) destination = self.calc_destination(self.angle) speed = boundary(self.parent.app.config.getint('GamePlay', 'BulletSpeed'), 1, 10) self.animation = self.create_animation(speed, destination) # start the animation self.animation.start(self) self.animation.bind(on_complete=self.on_collision_with_edge)
def on_touch_down(self, touch): if not self.collide_point(*touch.pos): touch.ud[self._get_uid("svavoid")] = True return if self._touch: return super(ScrollView, self).on_touch_down(touch) # 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_mouse - d elif touch.button == "scrolldown": syd = self._scroll_y_mouse + d self._scroll_y_mouse = scroll_y = min(max(syd, 0), 1) Animation.stop_all(self, "scroll_y") Animation(scroll_y=scroll_y, d=0.3, t="out_quart").start(self) Clock.unschedule(self._update_animation) 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.0) return True
def stop_running_animations(self): for widget in self.animated_widgets: Animation.stop_all(widget) self.animated_widgets.clear()
def test_stop_all_2(self): self.a.start(self.w) self.sleep(.5) Animation.stop_all(self.w, 'x')
def on_target_pos(self, instance, value): print 'setting target', value print self.move_anim if self.move_anim != None: Animation.stop_all(self, 'pos') self.sprite_image.update_sprite_direction()
def up(self, value, time): self.translate = [0.0, value, 0.0] Animation.stop_all(self) Animation(translate=(0.0, 0.0, 0.0), duration=time).start(self)
def pitch(self, value, time): self.rotate = [value, 1.0, 0.0, 0.0] Animation.stop_all(self) Animation(rotate=[0.0, 1.0, 0.0, 0.0], duration=time).start(self)
# animaçoes em paralelo, duas animacoes ao mesmo tempo anim = Animation(pos=(80, 10)) anim &= Animation(size=(800, 800), duration=2.) anim.start(widget) # animacao em que se repete ao terminar anim = Animation(x=50) + Animation(size=(80, 80), duration=2.) anim.repeat = True anim.start(widget) Animation.cancel_all(widget, 'x') #cancelar todas animacoes # CARACTERISTICAS anim.start(widget) #inicia uma animacao anim.stop(widget) #para uma animacao anim.cancel(widget) #apara a animacaoe evento on_complete noa sera executado Animation.stop_all(widget, 'x') #para e afeta todas a s animacoes Animation.cancel_all(widget, 'y') #para e afeta todas a s animacoes stop_property(widget, 'x') #para e remove a propriedade da animacao do widget cancel_property(widget, 'y') #para e remove a propriedade da animacao do widget anim.duration = 2.0 # tempo duracao de animacao anim.transition = 'in_quad' # funcao de transicao, pode ser da propeia classe que vc criou anim.step = 1.0 / 30.0 # 30 FPS na animacao anim.have_properties_to_animate #retona true se widget tem uma animacao #EVENTOS anim.on_start #dispara quando a niamacaoe iniciada anim.on_complete #dispara quandoa animacao termina anim.on_progress #dispara euqnato a animcao seta sendo executada # OBJETO DE TRANSICAO DE COMO A ANIMACAO E FEITA
class TapTargetView(EventDispatcher): """ Rough try to mimic the working of Android's TapTargetView """ def __init__(self, widget, outer_radius=dp(400), outer_circle_color=[1, 0, 0], outer_circle_alpha=.96, target_radius=dp(70), target_circle_color=[1, 1, 1], title_text="", title_text_size=dp(25), title_text_color=[1, 1, 1, 1], title_text_bold=True, description_text="", description_text_size=dp(20), description_text_color=[.9, .9, .9, 1], description_text_bold=False, draw_shadow=False, cancelable=False, widget_position="left", title_position="auto", on_end=None, **kwargs): """ Attributes: =========== widget: widget to add TapTargetView upon outer_radius: (optional), Radius for outer circle, defaults to dp(400) outer_circle_color: (optional), Color for the outer circle, defaults to [1,0,0] outer_circle_alpha: (optional), Alpha value for outer circle, defaults to .96 target_radius: (optional), Radius for target circle, defaults to dp(80) target_circle_color:(optional), Color for target circle, defaults to [1,1,1] title_text: (optional), Title to be shown on the view, defaults to '' title_text_size: (optional), Text size for title, defaults to sp(30) title_text_color: (optional), Text color for title, defaults to [1,1,1,1] title_text_bold: (optional), Whether title should be bold. Defaults to `True` description_text: (optional), Description to be shown below the title(Keep it short). Defaults to '' description_text_size: (optional), Text size for description text, defaults to sp(10) description_text_color: (optional), Text color for description text, defaults to [.8,.8,.8,1] description_text_bold: (optional), Whether description should be bold. Defaults to False draw_shadow: (optional), Whether to show shadow, defaults to False cancelable: (optional), Whether clicking outside the outer circle dismisses the view, defaults to False widget_position: (optional), Sets the position of the widget on the outer_circle. Can be one of "left","right","top","bottom","left_top","right_top", "left_bottom","right_bottom", and "center". Defaults to "left" title_position: (optional), Sets the position of `title_text` on the outer circle. Only works if `widget_position` is set to "center". In all other cases, it calculates the `title_position` itself. Must be set to other than "auto" when `widget_position` is set to "center". Can be one of "left","right","top","bottom","left_top","right_top", "left_bottom", and "right_bottom". Defaults to "auto"(since `widget_position` defaults to "left") on_end: (optional), Function to be called when the animation ends by clicking the button. Defaults to None """ self.widget = widget self.outer_radius = outer_radius self.outer_circle_color = outer_circle_color self.outer_circle_alpha = outer_circle_alpha self.target_radius = target_radius self.target_circle_color = target_circle_color self.title_text_size = title_text_size self.title_text_color = title_text_color self.title_text_bold = title_text_bold self.description_text_size = description_text_size self.description_text_color = description_text_color self.description_text_bold = description_text_bold self.draw_shadow = draw_shadow self.cancelable = cancelable self.widget_position = widget_position self.title_position = title_position self.on_end = on_end self.ripple_max_dist = dp(70) #just to track if it's already been ended or not self._count = 0 self.title_text = CoreLabel( text=title_text, font_size=self.title_text_size, bold=self.title_text_bold, ) self.title_text.refresh() self.title_text = self.title_text.texture self.description_text = CoreLabel(text=description_text, font_size=self.description_text_size, bold=self.description_text_bold) self.description_text.refresh() self.description_text = self.description_text.texture super(TapTargetView, self).__init__(**kwargs) def _initialize(self): setattr(self.widget, "outer_radius", 0) setattr(self.widget, "target_radius", 0) setattr(self.widget, "target_ripple_radius", 0) setattr(self.widget, "target_ripple_alpha", 0) def draw_canvas(self): _pos = self.ttv_pos() self.widget.canvas.before.clear() with self.widget.canvas.before: #outer circle Color(*self.outer_circle_color, self.outer_circle_alpha) _rad1 = self.widget.outer_radius Ellipse(size=(_rad1, _rad1), pos=_pos[0]) #Title text Color(*self.title_text_color) Rectangle(size=self.title_text.size, texture=self.title_text, pos=_pos[1]) #Description text Color(*self.description_text_color) Rectangle(size=self.description_text.size, texture=self.description_text, pos=(_pos[1][0], _pos[1][1] - self.description_text.size[1] - 5)) #target circle Color(*self.target_circle_color) _rad2 = self.widget.target_radius Ellipse( size=(_rad2, _rad2), pos=(self.widget.x - (_rad2 / 2 - self.widget.size[0] / 2), self.widget.y - (_rad2 / 2 - self.widget.size[0] / 2))) #target ripple Color(*self.target_circle_color, self.widget.target_ripple_alpha) _rad3 = self.widget.target_ripple_radius Ellipse( size=(_rad3, _rad3), pos=(self.widget.x - (_rad3 / 2 - self.widget.size[0] / 2), self.widget.y - (_rad3 / 2 - self.widget.size[0] / 2))) def stop(self, *args): #it needs a better implementation self.anim_ripple.unbind(on_complete=self._repeat_ripple) self.description_text_color = [1, 1, 1, 0] self.title_text_color = [1, 1, 1, 0] anim = Animation( d=.15, t="in_cubic", **dict( zip(["outer_radius", "target_radius", "target_ripple_radius"], [0, 0, 0]))) anim.bind(on_complete=self._after_stop) anim.start(self.widget) self._count += 1 def _after_stop(self, *args): self.widget.canvas.before.clear() args[0].stop_all(self.widget) if self._count == 1 and self.on_end is not None: self.on_end() def start(self): self._initialize() self._animate_outer() def _animate_outer(self): anim = Animation(d=.3, t="out_cubic", **dict( zip(["outer_radius", "target_radius"], [self.outer_radius, self.target_radius]))) anim.cancel_all(self.widget) anim.bind(on_progress=lambda x, y, z: self.draw_canvas()) anim.bind(on_complete=self._animate_ripple) anim.start(self.widget) setattr(self.widget, "target_ripple_radius", self.target_radius) setattr(self.widget, "target_ripple_alpha", 1) def _animate_ripple(self, *args): self.anim_ripple = Animation(d=1, t="in_cubic", target_ripple_radius=self.target_radius + self.ripple_max_dist, target_ripple_alpha=0) self.anim_ripple.stop_all(self.widget) self.anim_ripple.bind(on_progress=lambda x, y, z: self.draw_canvas()) self.anim_ripple.bind(on_complete=self._repeat_ripple) self.anim_ripple.start(self.widget) def _repeat_ripple(self, *args): setattr(self.widget, "target_ripple_radius", self.target_radius) setattr(self.widget, "target_ripple_alpha", 1) self._animate_ripple() def on_target_click(self): pass def on_outer_click(self): pass def ttv_pos(self): """ Calculates the `pos` value for outer circle and text based on the position provided param returns: A tupple containing pos for the circle and text """ _rad1 = self.widget.outer_radius _center_x = self.widget.x - (_rad1 / 2 - self.widget.size[0] / 2) _center_y = self.widget.y - (_rad1 / 2 - self.widget.size[0] / 2) if self.widget_position == "left": circ_pos = (_center_x + _rad1 / 3, _center_y) title_pos = (_center_x + _rad1 / 1.4, _center_y + _rad1 / 1.4) elif self.widget_position == "right": circ_pos = (_center_x - _rad1 / 3, _center_y) title_pos = (_center_x - _rad1 / 10, _center_y + _rad1 / 1.4) elif self.widget_position == "top": circ_pos = (_center_x, _center_y - _rad1 / 3) title_pos = (_center_x + _rad1 / 4, _center_y + _rad1 / 4) elif self.widget_position == "bottom": circ_pos = (_center_x, _center_y + _rad1 / 3) title_pos = (_center_x + _rad1 / 4, _center_y + _rad1 / 1.2) #corner ones need to be at a little smaller distance #than edge ones that's why _rad1/4 elif self.widget_position == "left_top": circ_pos = (_center_x + _rad1 / 4, _center_y - _rad1 / 4) title_pos = (_center_x + _rad1 / 2, _center_y + _rad1 / 4) elif self.widget_position == "right_top": circ_pos = (_center_x - _rad1 / 4, _center_y - _rad1 / 4) title_pos = (_center_x - _rad1 / 10, _center_y + _rad1 / 4) elif self.widget_position == "left_bottom": circ_pos = (_center_x + _rad1 / 4, _center_y + _rad1 / 4) title_pos = (_center_x + _rad1 / 2, _center_y + _rad1 / 1.2) elif self.widget_position == "right_bottom": circ_pos = (_center_x - _rad1 / 4, _center_y + _rad1 / 4) title_pos = (_center_x, _center_y + _rad1 / 1.2) else: #center circ_pos = (_center_x, _center_y) if self.title_position == "auto": raise ValueError( "widget_position='center' requires title_position to be set." ) elif self.title_position == "left": title_pos = (_center_x + _rad1 / 10, _center_y + _rad1 / 2) elif self.title_position == "right": title_pos = (_center_x + _rad1 / 1.6, _center_y + _rad1 / 2) elif self.title_position == "top": title_pos = (_center_x + _rad1 / 2.5, _center_y + _rad1 / 1.3) elif self.title_position == "bottom": title_pos = (_center_x + _rad1 / 2.5, _center_y + _rad1 / 4) elif self.title_position == "left_top": title_pos = (_center_x + _rad1 / 8, _center_y + _rad1 / 1.4) elif self.title_position == "right_top": title_pos = (_center_x + _rad1 / 2, _center_y + _rad1 / 1.3) elif self.title_position == "left_bottom": title_pos = (_center_x + _rad1 / 8, _center_y + _rad1 / 4) elif self.title_position == "right_bottom": title_pos = (_center_x + _rad1 / 2, _center_y + _rad1 / 3.5) else: raise ValueError( "'{}' is not a valid value for title_position".format( self.title_position)) return circ_pos, title_pos
def stop_anims(self, sender, widget): """Stop all animations.""" Animation.stop_all(widget)
def _intermediate(self, wid, ins): anim = Animation(angle_start=-51, angle_end=-51, t="out_quad", d=0.15) anim &= self._tick_animation() anim.stop_all(self) anim.start(self)
def toggle(self): Animation.stop_all(self, 'x') anim = self.animation_for_toggling_state() self._open = not self._open anim.start(self)
def _show_bubble(self): self.alpha = 1 Animation.stop_all(self, 'alpha')
class MDTapTargetView(ThemableBehavior, EventDispatcher): """Rough try to mimic the working of Android's TapTargetView. :Events: :attr:`on_open` Called at the time of the start of the widget opening animation. :attr:`on_close` Called at the time of the start of the widget closed animation. """ widget = ObjectProperty() """ Widget to add ``TapTargetView`` upon. :attr:`widget` is an :class:`~kivy.properties.ObjectProperty` and defaults to `None`. """ outer_radius = NumericProperty(dp(200)) """ Radius for outer circle. .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/tap-target-view-widget-outer-radius.png :align: center :attr:`outer_radius` is an :class:`~kivy.properties.NumericProperty` and defaults to `dp(200)`. """ outer_circle_color = ListProperty() """ Color for the outer circle in ``rgb`` format. .. code-block:: python self.tap_target_view = MDTapTargetView( ... outer_circle_color=(1, 0, 0) ) .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/tap-target-view-widget-outer-circle-color.png :align: center :attr:`outer_circle_color` is an :class:`~kivy.properties.ListProperty` and defaults to ``theme_cls.primary_color``. """ outer_circle_alpha = NumericProperty(0.96) """ Alpha value for outer circle. :attr:`outer_circle_alpha` is an :class:`~kivy.properties.NumericProperty` and defaults to `0.96`. """ target_radius = NumericProperty(dp(45)) """ Radius for target circle. .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/tap-target-view-widget-target-radius.png :align: center :attr:`target_radius` is an :class:`~kivy.properties.NumericProperty` and defaults to `dp(45)`. """ target_circle_color = ListProperty([1, 1, 1]) """ Color for target circle in ``rgb`` format. .. code-block:: python self.tap_target_view = MDTapTargetView( ... target_circle_color=(1, 0, 0) ) .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/tap-target-view-widget-target-circle-color.png :align: center :attr:`target_circle_color` is an :class:`~kivy.properties.ListProperty` and defaults to `[1, 1, 1]`. """ title_text = StringProperty() """ Title to be shown on the view. :attr:`title_text` is an :class:`~kivy.properties.StringProperty` and defaults to `''`. """ title_text_size = NumericProperty(dp(25)) """ Text size for title. :attr:`title_text_size` is an :class:`~kivy.properties.NumericProperty` and defaults to `dp(25)`. """ title_text_color = ListProperty([1, 1, 1, 1]) """ Text color for title. :attr:`title_text_color` is an :class:`~kivy.properties.ListProperty` and defaults to `[1, 1, 1, 1]`. """ title_text_bold = BooleanProperty(True) """ Whether title should be bold. :attr:`title_text_bold` is an :class:`~kivy.properties.BooleanProperty` and defaults to `True`. """ description_text = StringProperty() """ Description to be shown below the title (keep it short). :attr:`description_text` is an :class:`~kivy.properties.StringProperty` and defaults to `''`. """ description_text_size = NumericProperty(dp(20)) """ Text size for description text. :attr:`description_text_size` is an :class:`~kivy.properties.NumericProperty` and defaults to `dp(20)`. """ description_text_color = ListProperty([0.9, 0.9, 0.9, 1]) """ Text size for description text. :attr:`description_text_color` is an :class:`~kivy.properties.ListProperty` and defaults to `[0.9, 0.9, 0.9, 1]`. """ description_text_bold = BooleanProperty(False) """ Whether description should be bold. :attr:`description_text_bold` is an :class:`~kivy.properties.BooleanProperty` and defaults to `False`. """ draw_shadow = BooleanProperty(False) """ Whether to show shadow. :attr:`draw_shadow` is an :class:`~kivy.properties.BooleanProperty` and defaults to `False`. """ cancelable = BooleanProperty(False) """ Whether clicking outside the outer circle dismisses the view. :attr:`cancelable` is an :class:`~kivy.properties.BooleanProperty` and defaults to `False`. """ widget_position = OptionProperty( "left", options=[ "left", "right", "top", "bottom", "left_top", "right_top", "left_bottom", "right_bottom", "center", ], ) """ Sets the position of the widget on the :attr:`~outer_circle`. Available options are `'left`', `'right`', `'top`', `'bottom`', `'left_top`', `'right_top`', `'left_bottom`', `'right_bottom`', `'center`'. :attr:`widget_position` is an :class:`~kivy.properties.OptionProperty` and defaults to `'left'`. """ title_position = OptionProperty( "auto", options=[ "auto", "left", "right", "top", "bottom", "left_top", "right_top", "left_bottom", "right_bottom", ], ) """ Sets the position of :attr`~title_text` on the outer circle. Only works if :attr`~widget_position` is set to `'center'`. In all other cases, it calculates the :attr`~title_position` itself. Must be set to other than `'auto`' when :attr`~widget_position` is set to `'center`'. Available options are `'auto'`, `'left`', `'right`', `'top`', `'bottom`', `'left_top`', `'right_top`', `'left_bottom`', `'right_bottom`', `'center`'. :attr:`title_position` is an :class:`~kivy.properties.OptionProperty` and defaults to `'auto'`. """ stop_on_outer_touch = BooleanProperty(False) """ Whether clicking on outer circle stops the animation. :attr:`stop_on_outer_touch` is an :class:`~kivy.properties.BooleanProperty` and defaults to `False`. """ stop_on_target_touch = BooleanProperty(True) """ Whether clicking on target circle should stop the animation. :attr:`stop_on_target_touch` is an :class:`~kivy.properties.BooleanProperty` and defaults to `True`. """ state = OptionProperty("close", options=["close", "open"]) """ State of :class:`~MDTapTargetView`. :attr:`state` is an :class:`~kivy.properties.OptionProperty` and defaults to `'close'`. """ _outer_radius = NumericProperty(0) _target_radius = NumericProperty(0) def __init__(self, **kwargs): self.ripple_max_dist = dp(90) self.on_outer_radius(self, self.outer_radius) self.on_target_radius(self, self.target_radius) self.core_title_text = Label(markup=True, size_hint=(None, None), bold=self.title_text_bold) self.core_title_text.bind( texture_size=self.core_title_text.setter("size")) self.core_description_text = Label(markup=True, size_hint=(None, None)) self.core_description_text.bind( texture_size=self.core_description_text.setter("size")) super().__init__(**kwargs) self.register_event_type("on_outer_touch") self.register_event_type("on_target_touch") self.register_event_type("on_outside_click") self.register_event_type("on_open") self.register_event_type("on_close") if not self.outer_circle_color: self.outer_circle_color = self.theme_cls.primary_color[:-1] def _initialize(self): setattr(self.widget, "_outer_radius", 0) setattr(self.widget, "_target_radius", 0) setattr(self.widget, "target_ripple_radius", 0) setattr(self.widget, "target_ripple_alpha", 0) # Bind some function on widget event when this function is called # instead of when the class itself is initialized to prevent all # widgets of all instances to get bind at once and start messing up. self.widget.bind(on_touch_down=self._some_func) def _draw_canvas(self): _pos = self._ttv_pos() self.widget.canvas.before.clear() with self.widget.canvas.before: # Outer circle. Color( *self.outer_circle_color, self.outer_circle_alpha, group="ttv_group", ) _rad1 = self.widget._outer_radius Ellipse(size=(_rad1, _rad1), pos=_pos[0], group="ttv_group") # Title text. Color(*self.title_text_color, group="ttv_group") Rectangle( size=self.core_title_text.texture.size, texture=self.core_title_text.texture, pos=_pos[1], group="ttv_group", ) # Description text. Color(*self.description_text_color, group="ttv_group") Rectangle( size=self.core_description_text.texture.size, texture=self.core_description_text.texture, pos=( _pos[1][0], _pos[1][1] - self.core_description_text.size[1] - 5, ), group="ttv_group", ) # Target circle. Color(*self.target_circle_color, group="ttv_group") _rad2 = self.widget._target_radius Ellipse( size=(_rad2, _rad2), pos=( self.widget.x - (_rad2 / 2 - self.widget.size[0] / 2), self.widget.y - (_rad2 / 2 - self.widget.size[0] / 2), ), group="ttv_group", ) # Target ripple. Color( *self.target_circle_color, self.widget.target_ripple_alpha, group="ttv_group", ) _rad3 = self.widget.target_ripple_radius Ellipse( size=(_rad3, _rad3), pos=( self.widget.x - (_rad3 / 2 - self.widget.size[0] / 2), self.widget.y - (_rad3 / 2 - self.widget.size[0] / 2), ), group="ttv_group", ) def stop(self, *args): """Starts widget close animation.""" # It needs a better implementation. self.anim_ripple.unbind(on_complete=self._repeat_ripple) self.core_title_text.opacity = 0 self.core_description_text.opacity = 0 anim = Animation( d=0.15, t="in_cubic", **dict( zip( [ "_outer_radius", "_target_radius", "target_ripple_radius" ], [0, 0, 0], )), ) anim.bind(on_complete=self._after_stop) anim.start(self.widget) def _after_stop(self, *args): self.widget.canvas.before.remove_group("ttv_group") args[0].stop_all(self.widget) elev = getattr(self.widget, "elevation", None) if elev: self._fix_elev() self.dispatch("on_close") # Don't forget to unbind the function or it'll mess # up with other next bindings. self.widget.unbind(on_touch_down=self._some_func) self.state = "close" def _fix_elev(self): with self.widget.canvas.before: Color(a=self.widget._soft_shadow_a) Rectangle( texture=self.widget._soft_shadow_texture, size=self.widget._soft_shadow_size, pos=self.widget._soft_shadow_pos, ) Color(a=self.widget._hard_shadow_a) Rectangle( texture=self.widget._hard_shadow_texture, size=self.widget._hard_shadow_size, pos=self.widget._hard_shadow_pos, ) Color(a=1) def start(self, *args): """Starts widget opening animation.""" self._initialize() self._animate_outer() self.state = "open" self.core_title_text.opacity = 1 self.core_description_text.opacity = 1 self.dispatch("on_open") def _animate_outer(self): anim = Animation( d=0.2, t="out_cubic", **dict( zip( ["_outer_radius", "_target_radius"], [self._outer_radius, self._target_radius], )), ) anim.cancel_all(self.widget) anim.bind(on_progress=lambda x, y, z: self._draw_canvas()) anim.bind(on_complete=self._animate_ripple) anim.start(self.widget) setattr(self.widget, "target_ripple_radius", self._target_radius) setattr(self.widget, "target_ripple_alpha", 1) def _animate_ripple(self, *args): self.anim_ripple = Animation( d=1, t="in_cubic", target_ripple_radius=self._target_radius + self.ripple_max_dist, target_ripple_alpha=0, ) self.anim_ripple.stop_all(self.widget) self.anim_ripple.bind(on_progress=lambda x, y, z: self._draw_canvas()) self.anim_ripple.bind(on_complete=self._repeat_ripple) self.anim_ripple.start(self.widget) def _repeat_ripple(self, *args): setattr(self.widget, "target_ripple_radius", self._target_radius) setattr(self.widget, "target_ripple_alpha", 1) self._animate_ripple() def on_open(self, *args): """Called at the time of the start of the widget opening animation.""" def on_close(self, *args): """Called at the time of the start of the widget closed animation.""" def on_draw_shadow(self, instance, value): Logger.warning( "The shadow adding method will be implemented in future versions") def on_description_text(self, instance, value): self.core_description_text.text = value def on_description_text_size(self, instance, value): self.core_description_text.font_size = value def on_description_text_bold(self, instance, value): self.core_description_text.bold = value def on_title_text(self, instance, value): self.core_title_text.text = value def on_title_text_size(self, instance, value): self.core_title_text.font_size = value def on_title_text_bold(self, instance, value): self.core_title_text.bold = value def on_outer_radius(self, instance, value): self._outer_radius = self.outer_radius * 2 def on_target_radius(self, instance, value): self._target_radius = self.target_radius * 2 def on_target_touch(self): if self.stop_on_target_touch: self.stop() def on_outer_touch(self): if self.stop_on_outer_touch: self.stop() def on_outside_click(self): if self.cancelable: self.stop() def _some_func(self, wid, touch): """ This function decides which one to dispatch based on the touch position. """ if self._check_pos_target(touch.pos): self.dispatch("on_target_touch") elif self._check_pos_outer(touch.pos): self.dispatch("on_outer_touch") else: self.dispatch("on_outside_click") def _check_pos_outer(self, pos): """ Checks if a given `pos` coordinate is within the :attr:`~outer_radius`. """ cx = self.circ_pos[0] + self._outer_radius / 2 cy = self.circ_pos[1] + self._outer_radius / 2 r = self._outer_radius / 2 h, k = pos lhs = (cx - h)**2 + (cy - k)**2 rhs = r**2 if lhs <= rhs: return True return False def _check_pos_target(self, pos): """ Checks if a given `pos` coordinate is within the :attr:`~target_radius`. """ cx = self.widget.pos[0] + self.widget.width / 2 cy = self.widget.pos[1] + self.widget.height / 2 r = self._target_radius / 2 h, k = pos lhs = (cx - h)**2 + (cy - k)**2 rhs = r**2 if lhs <= rhs: return True return False def _ttv_pos(self): """ Calculates the `pos` value for outer circle and text based on the position provided. :returns: A tuple containing pos for the circle and text. """ _rad1 = self.widget._outer_radius _center_x = self.widget.x - (_rad1 / 2 - self.widget.size[0] / 2) _center_y = self.widget.y - (_rad1 / 2 - self.widget.size[0] / 2) if self.widget_position == "left": circ_pos = (_center_x + _rad1 / 3, _center_y) title_pos = (_center_x + _rad1 / 1.4, _center_y + _rad1 / 1.4) elif self.widget_position == "right": circ_pos = (_center_x - _rad1 / 3, _center_y) title_pos = (_center_x - _rad1 / 10, _center_y + _rad1 / 1.4) elif self.widget_position == "top": circ_pos = (_center_x, _center_y - _rad1 / 3) title_pos = (_center_x + _rad1 / 4, _center_y + _rad1 / 4) elif self.widget_position == "bottom": circ_pos = (_center_x, _center_y + _rad1 / 3) title_pos = (_center_x + _rad1 / 4, _center_y + _rad1 / 1.2) # Corner ones need to be at a little smaller distance # than edge ones that's why _rad1/4. elif self.widget_position == "left_top": circ_pos = (_center_x + _rad1 / 4, _center_y - _rad1 / 4) title_pos = (_center_x + _rad1 / 2, _center_y + _rad1 / 4) elif self.widget_position == "right_top": circ_pos = (_center_x - _rad1 / 4, _center_y - _rad1 / 4) title_pos = (_center_x - _rad1 / 10, _center_y + _rad1 / 4) elif self.widget_position == "left_bottom": circ_pos = (_center_x + _rad1 / 4, _center_y + _rad1 / 4) title_pos = (_center_x + _rad1 / 2, _center_y + _rad1 / 1.2) elif self.widget_position == "right_bottom": circ_pos = (_center_x - _rad1 / 4, _center_y + _rad1 / 4) title_pos = (_center_x, _center_y + _rad1 / 1.2) else: # Center. circ_pos = (_center_x, _center_y) if self.title_position == "auto": raise ValueError( "widget_position='center' requires title_position to be set." ) elif self.title_position == "left": title_pos = (_center_x + _rad1 / 10, _center_y + _rad1 / 2) elif self.title_position == "right": title_pos = (_center_x + _rad1 / 1.6, _center_y + _rad1 / 2) elif self.title_position == "top": title_pos = (_center_x + _rad1 / 2.5, _center_y + _rad1 / 1.3) elif self.title_position == "bottom": title_pos = (_center_x + _rad1 / 2.5, _center_y + _rad1 / 4) elif self.title_position == "left_top": title_pos = (_center_x + _rad1 / 8, _center_y + _rad1 / 1.4) elif self.title_position == "right_top": title_pos = (_center_x + _rad1 / 2, _center_y + _rad1 / 1.3) elif self.title_position == "left_bottom": title_pos = (_center_x + _rad1 / 8, _center_y + _rad1 / 4) elif self.title_position == "right_bottom": title_pos = (_center_x + _rad1 / 2, _center_y + _rad1 / 3.5) else: raise ValueError(f"'{self.title_position}'" f"is not a valid value for title_position") self.circ_pos = circ_pos return circ_pos, title_pos
def on_touch_down(self, touch): if not super(MapThumbnail, self).on_touch_down(touch): return Animation.stop_all(self, 'pos') self.controled = True return True
def on_target_pos(self, instance, value): if self.move_anim != None: Animation.stop_all(self, 'pos')
def twist(self): Animation.stop_all(self) (Animation(rotate=25, t="out_quad", d=0.05) + Animation(rotate=0, t="out_elastic", d=0.5)).start(self)
def on_touch_down(self, touch): if not self.collide_point(*touch.pos): touch.ud[self._get_uid('svavoid')] = True return if self._touch: return super(ScrollView, self).on_touch_down(touch) # support scrolling ! if self._viewport and 'button' in touch.profile and \ touch.button.startswith('scroll'): btn = touch.button # 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) syd = None if d != 0: d = self.scroll_distance / float(d) if btn == 'scrollup': syd = self._scroll_y_mouse - d elif btn == 'scrolldown': syd = self._scroll_y_mouse + d if syd is not None: if not self.do_scroll_y: return self._scroll_y_mouse = scroll_y = min(max(syd, 0), 1) Animation.stop_all(self, 'scroll_y') Animation(scroll_y=scroll_y, d=.3, t='out_quart').start(self) Clock.unschedule(self._update_animation) return True if vp.width > self.width and self.do_scroll_x: # let's say we want to move over 40 pixels each scroll d = (vp.width - self.width) sxd = None if d != 0: d = self.scroll_distance / float(d) if btn == 'scrollright': sxd = self._scroll_x_mouse - d elif btn == 'scrollleft': sxd = self._scroll_x_mouse + d if sxd is not None: if not self.do_scroll_y: return self._scroll_x_mouse = scroll_x = min(max(sxd, 0), 1) Animation.stop_all(self, 'scroll_x') Animation(scroll_x=scroll_x, d=.3, t='out_quart').start( self) Clock.unschedule(self._update_animation) 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, 'user_stopped': False, 'same': 0, 'moves': FixedList(self.scroll_moves)} Clock.schedule_interval(self._update_delta, 0) Clock.schedule_once(self._change_touch_mode, self.scroll_timeout / 1000.) return True
def shrink(self): Animation.stop_all(self) Animation(scale_x=0.95, scale_y=0.95, t="out_quad", d=0.1).start(self)
def on_leave(self): Animation.stop_all(self.content, 'opacity') self.content.opacity = 0
def test_stop_all(self): self.a.start(self.w) self.sleep(0.5) Animation.stop_all(self.w)