def __init__(self, **kwargs): super(Dialog, self).__init__(**kwargs) self.elevation = 12 self.shadow = Shadow(opacity=0.5) self.bind(_action_buttons=self._update_action_buttons, auto_dismiss=lambda *x: setattr( self.shadow, 'on_release', self.shadow.dismiss if self.auto_dismiss else None))
def __init__(self, **kwargs): self.register_event_type('on_closed') self.register_event_type('on_opening') self.register_event_type('on_opened') self.register_event_type('on_closing') self.animation_open = Animation(duration=self.animation_length, t="out_sine") self.animation_dismiss = Animation(duration=self.animation_length, t="out_sine") self.shadow = Shadow(width=0, opacity=0.8, size_hint_x=None, on_release=lambda x: self.dismiss()) super(SlidingPanel, self).__init__(**kwargs) self.orientation = "vertical" self.size_hint = (None, None) self.status = "closed" self.timer = None self.shadow.fade_out(0) self.bind(height=self.shadow.setter('height')) helpers.bind_to_rotation(self._device_rotated)
class SlidingPanel(RelativeLayout): """An empty panel that slides from a side""" side = StringProperty("left") """Side from which the menu will slide from Valid values are "left" and "right" """ animation_length = NumericProperty(0.3) """How long will the animation last""" def __init__(self, **kwargs): self.register_event_type('on_closed') self.register_event_type('on_opening') self.register_event_type('on_opened') self.register_event_type('on_closing') self.animation_open = Animation(duration=self.animation_length, t="out_sine") self.animation_dismiss = Animation(duration=self.animation_length, t="out_sine") self.shadow = Shadow(width=0, opacity=0.8, size_hint_x=None, on_release=lambda x: self.dismiss()) super(SlidingPanel, self).__init__(**kwargs) self.orientation = "vertical" self.size_hint = (None, None) self.status = "closed" self.timer = None self.shadow.fade_out(0) self.bind(height=self.shadow.setter('height')) helpers.bind_to_rotation(self._device_rotated) def on_touch_down(self, touch): # Prevents touch events from propagating to anything below the widget. super(SlidingPanel, self).on_touch_down(touch) if self.collide_point(*touch.pos): return True def open(self): if self.status != "closed": return self.update_animations() self.shadow.fade_in(self.animation_length, add_to=self) self.animation_open.start(self) self.dispatch('on_opening') self.status = "opening" self.timer = ThreadedTimer( self.animation_length + 0.1, self._fix_status).start() def dismiss(self): if self.status != "open": return self.update_animations() self.shadow.fade_out(self.animation_length) self.animation_dismiss.start(self) self.dispatch('on_closing') self.status = "closing" self.timer = ThreadedTimer( self.animation_length + 0.1, self._fix_status).start() def update_animations(self): if self.side == "left": self.shadow.x = self.width if self.status == "closed": self.animation_open.animated_properties['x'] = self.x +\ self.width elif self.status == "open": self.animation_dismiss.animated_properties['x'] = self.x -\ self.width elif self.side == "right": self.shadow.x = 0 - self.shadow.width if self.status == "closed": self.animation_open.animated_properties['x'] = \ self.parent.width - self.width elif self.status == "open": self.animation_dismiss.animated_properties['x'] = \ self.parent.x + self.width self.animation_dismiss.animated_properties['y'] = float(self.y) def _device_rotated(self, orientation): self.update_animations() def toggle(self): if self.status == "open": self.dismiss() elif self.status == "closed": self.open() def _fix_status(self): if self.status == "opening": self.status = "open" elif self.status == "closing": self.status = "closed" else: return self.timer = None def on_side(self, instance, value): if value == "left": self.shadow.x = self.width value.unbind(width=self.setter('x')) elif value == "right": self.shadow.x = self.shadow.width - self.width else: raise ValueError( "Valid values for side are \"left\" and \"right\"") def on_parent(self, instance, value): value.bind(height=self.setter('height')) value.bind(x=self._set_x) value.bind(y=self._set_y) value.bind(width=self.shadow.setter('width')) if self.side == "left": self.x = value.x - self.width elif self.side == "right": value.bind(width=self.setter('x')) def _set_x(self, instance, value): if self.side == "left": self.x = value - self.width elif self.side == "right": self.x = instance.width def _set_y(self, instance, value): self.y = value def on_closed(self): pass def on_opening(self): pass def on_opened(self): pass def on_closing(self): pass
def __init__(self, **kwargs): super(Dialog, self).__init__(**kwargs) self.shadow = Shadow(opacity=0.4) self.bind(_action_buttons=self._update_action_buttons, auto_dismiss=lambda *x: setattr(self.shadow, 'on_release', self.shadow.dismiss if self.auto_dismiss else None))
class Dialog(ThemeBehaviour, ElevationBehaviour, ModalView): title = StringProperty('') content = ObjectProperty(None) _container = ObjectProperty() _action_buttons = ListProperty([]) _action_area = ObjectProperty() def __init__(self, **kwargs): super(Dialog, self).__init__(**kwargs) self.shadow = Shadow(opacity=0.4) self.bind(_action_buttons=self._update_action_buttons, auto_dismiss=lambda *x: setattr(self.shadow, 'on_release', self.shadow.dismiss if self.auto_dismiss else None)) def add_action_button(self, text, action=None): """Add an :class:`FlatButton` to the right of the action area. :param icon: Unicode character for the icon :type icon: str or None :param action: Function set to trigger when on_release fires :type action: function or None """ button = FlatButton(text=text, size_hint=(None, None), height=dp(36)) if action: button.bind(on_release=action) button.text_color = self._theme_cls.primary_color button.background_color = self._theme_cls.dialog_background_color self._action_buttons.append(button) def add_widget(self, widget): if self._container: if self.content: raise PopupException( 'Popup can have only one widget as content') self.content = widget else: super(Dialog, self).add_widget(widget) 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 dismiss(self, *largs, **kwargs): '''Close the view if it is open. If you really want to close the view, whatever the on_dismiss event returns, you can use the *force* argument: :: view = ModalView(...) view.dismiss(force=True) When the view is dismissed, it will be faded out before being removed from the parent. If you don't want animation, use:: view.dismiss(animation=False) ''' if self._window is None: return self if self.dispatch('on_dismiss') is True: if kwargs.get('force', False) is not True: return self self.shadow.fade_out(duration=.2) if kwargs.get('animation', True): Animation(_anim_alpha=0., d=self._anim_duration).start(self) else: self._anim_alpha = 0 self._real_remove_widget() return self def on_content(self, instance, value): if self._container: self._container.clear_widgets() self._container.add_widget(value) def on__container(self, instance, value): if value is None or self.content is None: return self._container.clear_widgets() self._container.add_widget(self.content) def on_touch_down(self, touch): if self.disabled and self.collide_point(*touch.pos): return True return super(Dialog, self).on_touch_down(touch) def _update_action_buttons(self, *args): self._action_area.clear_widgets() for btn in self._action_buttons: btn._label.texture_update() btn.width = btn._label.texture_size[0] + dp(16) self._action_area.add_widget(btn)
class Dialog(ThemeBehaviour, ElevationBehaviour, ModalView): title = StringProperty('') content = ObjectProperty(None) _container = ObjectProperty() _action_buttons = ListProperty([]) _action_area = ObjectProperty() def __init__(self, **kwargs): super(Dialog, self).__init__(**kwargs) self.elevation = 12 self.shadow = Shadow(opacity=0.5) self.bind(_action_buttons=self._update_action_buttons, auto_dismiss=lambda *x: setattr( self.shadow, 'on_release', self.shadow.dismiss if self.auto_dismiss else None)) def add_action_button(self, text, action=None): """Add an :class:`FlatButton` to the right of the action area. :param icon: Unicode character for the icon :type icon: str or None :param action: Function set to trigger when on_release fires :type action: function or None """ button = FlatButton(text=text, size_hint=(None, None), height=dp(36)) if action: button.bind(on_release=action) button.text_color = self._theme_cls.primary_color button.background_color = self._theme_cls.dialog_background_color self._action_buttons.append(button) def add_widget(self, widget): if self._container: if self.content: raise PopupException( 'Popup can have only one widget as content') self.content = widget else: super(Dialog, self).add_widget(widget) 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 dismiss(self, *largs, **kwargs): '''Close the view if it is open. If you really want to close the view, whatever the on_dismiss event returns, you can use the *force* argument: :: view = ModalView(...) view.dismiss(force=True) When the view is dismissed, it will be faded out before being removed from the parent. If you don't want animation, use:: view.dismiss(animation=False) ''' if self._window is None: return self if self.dispatch('on_dismiss') is True: if kwargs.get('force', False) is not True: return self self.shadow.fade_out(duration=.2) if kwargs.get('animation', True): Animation(_anim_alpha=0., d=self._anim_duration).start(self) else: self._anim_alpha = 0 self._real_remove_widget() return self def on_content(self, instance, value): if self._container: self._container.clear_widgets() self._container.add_widget(value) def on__container(self, instance, value): if value is None or self.content is None: return self._container.clear_widgets() self._container.add_widget(self.content) def on_touch_down(self, touch): if self.disabled and self.collide_point(*touch.pos): return True return super(Dialog, self).on_touch_down(touch) def _update_action_buttons(self, *args): self._action_area.clear_widgets() for btn in self._action_buttons: btn._label.texture_update() btn.width = btn._label.texture_size[0] + dp(16) self._action_area.add_widget(btn)