# HG changeset patch # User Goffi # Date 1471808512 -7200 # Node ID c21d1be2e54c01d418a08c07f9b6911162975216 # Parent fdaf914e2729f6f9d1765c3ef3ad0cef06256d98 core: XMLUI notifications coming from backend are handled: when a notification from backend is coming, it's added to a notification icon (on the right for important notifications which need user action, while left icon is used for notes). If user click on the notification icon, the XMLUI replace the main widget with a rise animation. When action is finished, ui is closed with a fall out animation. diff -r fdaf914e2729 -r c21d1be2e54c src/cagou/core/cagou_main.py --- a/src/cagou/core/cagou_main.py Sun Aug 21 17:49:14 2016 +0200 +++ b/src/cagou/core/cagou_main.py Sun Aug 21 21:41:52 2016 +0200 @@ -39,7 +39,7 @@ from kivy.clock import Clock from kivy.uix.label import Label from kivy.uix.boxlayout import BoxLayout -from kivy.uix.screenmanager import ScreenManager, Screen +from kivy.uix.screenmanager import ScreenManager, Screen, FallOutTransition, RiseInTransition from kivy.uix.dropdown import DropDown from cagou_widget import CagouWidget from .common import IconButton @@ -50,16 +50,15 @@ import cagou.kv -class NotifIcon(IconButton): - - def __init__(self, callback, callback_args): - self._callback = callback - self._callback_args = callback_args - super(NotifIcon, self).__init__() +class NotifsIcon(IconButton): + notifs = properties.ListProperty() def on_release(self): - self.parent.remove_widget(self) - self._callback(*self._callback_args) + callback, args, kwargs = self.notifs.pop(0) + callback(*args, **kwargs) + + def addNotif(self, callback, *args, **kwargs): + self.notifs.append((callback, args, kwargs)) class Note(Label): @@ -90,17 +89,17 @@ class RootHeadWidget(BoxLayout): """Notifications widget""" manager = properties.ObjectProperty() + notifs_icon = properties.ObjectProperty() notes = properties.ListProperty() def __init__(self): super(RootHeadWidget, self).__init__() self.notes_last = None self.notes_event = None - self.notes_drop = NotesDrop(self.notes) # auto_with=False, width=100) + self.notes_drop = NotesDrop(self.notes) - def addNotif(self, callback, *args): - icon = NotifIcon(callback, args) - self.add_widget(icon) + def addNotif(self, callback, *args, **kwargs): + self.notifs_icon.addNotif(callback, *args, **kwargs) def addNote(self, title, message, level): note = Note(title=title, message=message, level=level) @@ -111,6 +110,9 @@ self.notes_event = Clock.schedule_interval(self._displayNextNote, 5) self._displayNextNote() + def addNotifUI(self, ui): + self.notifs_icon.addNotif(ui.show, force=True) + def _displayNextNote(self, dummy=None): screen = Screen() try: @@ -137,17 +139,29 @@ # body self._manager = ScreenManager() + # main widgets main_screen = Screen(name='main') main_screen.add_widget(main_widget) self._manager.add_widget(main_screen) + # backend XMLUI (popups, forms, etc) + xmlui_screen = Screen(name='xmlui') + self._manager.add_widget(xmlui_screen) self.add_widget(self._manager) - self.change_widget(main_widget) - def change_widget(self, main_widget, screen="main"): + def changeWidget(self, widget, screen_name="main"): """change main widget""" - main_screen = self._manager.get_screen(screen) - main_screen.clear_widgets() - main_screen.add_widget(main_widget) + screen = self._manager.get_screen(screen_name) + screen.clear_widgets() + screen.add_widget(widget) + + def show(self, screen="main"): + if self._manager.current == screen: + return + if screen == "main": + self._manager.transition = FallOutTransition() + else: + self._manager.transition = RiseInTransition() + self._manager.current = screen def newAction(self, handler, action_data, id_, security_limit, profile): """Add a notification for an action""" @@ -156,6 +170,9 @@ def addNote(self, title, message, level): self._head_widget.addNote(title, message, level) + def addNotifUI(self, ui): + self._head_widget.addNotifUI(ui) + class CagouApp(App): """Kivy App for Cagou""" @@ -314,7 +331,7 @@ ## misc ## def plugging_profiles(self): - self.app.root.change_widget(WidgetsHandler()) + self.app.root.changeWidget(WidgetsHandler()) def setPresenceStatus(self, show='', status=None, profile=C.PROF_KEY_NONE): log.info(u"Profile presence status set to {show}/{status}".format(show=show, status=status)) @@ -323,13 +340,16 @@ """add a note (message which disappear) to root widget's header""" self.app.root.addNote(title, message, level) - ## signals handling ## + def addNotifUI(self, ui): + """add a notification with a XMLUI attached + + @param ui(xmlui.XMLUIPanel): XMLUI instance to show when notification is selected + """ + self.app.root.addNotifUI(ui) - def actionNewHandler(self, action_data, id_, security_limit, profile): - handler = super(Cagou, self).actionNewHandler - # FIXME: temporarily deactivated - # if 'xmlui' in action_data: - # self.app.root.newAction(handler, action_data, id_, security_limit, profile) - # else: - # handler(action_data, id_, security_limit, profile) - handler(action_data, id_, security_limit, profile) + def showUI(self, ui): + self.app.root.changeWidget(ui, "xmlui") + self.app.root.show("xmlui") + + def closeUI(self): + self.app.root.show() diff -r fdaf914e2729 -r c21d1be2e54c src/cagou/core/xmlui.py --- a/src/cagou/core/xmlui.py Sun Aug 21 17:49:14 2016 +0200 +++ b/src/cagou/core/xmlui.py Sun Aug 21 21:41:52 2016 +0200 @@ -114,7 +114,7 @@ if self.close_cb is not None: self.close_cb(self) else: - log.error(u"No close method defined") + G.host.closeUI() def constructUI(self, parsed_dom): xmlui.XMLUIPanel.constructUI(self, parsed_dom) @@ -131,6 +131,12 @@ self.add_widget(cancel_btn) self.add_widget(Widget()) # to have elements on the top + def show(self, *args, **kwargs): + if not self.user_action and not kwargs.get("force", False): + G.host.addNotifUI(self) + else: + G.host.showUI(self) + class XMLUIDialog(xmlui.XMLUIDialog): dialog_factory = WidgetFactory() diff -r fdaf914e2729 -r c21d1be2e54c src/cagou/kv/root_widget.kv --- a/src/cagou/kv/root_widget.kv Sun Aug 21 17:49:14 2016 +0200 +++ b/src/cagou/kv/root_widget.kv Sun Aug 21 21:41:52 2016 +0200 @@ -49,6 +49,7 @@ : manager: manager + notifs_icon: notifs_icon size_hint: 1, None height: 35 IconButton: @@ -58,3 +59,9 @@ on_release: root.notes_drop.open(self) if root.notes else None ScreenManager: id: manager + NotifsIcon: + id: notifs_icon + source: app.expand("{media}/icons/muchoslava/png/cagou_profil_bleu_32.png") if self.notifs else app.expand("{media}/misc/black.png") + size_hint: None, 1 + width: self.texture_size[0] +