comparison src/cagou/core/cagou_main.py @ 33:c21d1be2e54c

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.
author Goffi <goffi@goffi.org>
date Sun, 21 Aug 2016 21:41:52 +0200
parents fdaf914e2729
children 02acbb297a61
comparison
equal deleted inserted replaced
32:fdaf914e2729 33:c21d1be2e54c
37 from profile_manager import ProfileManager 37 from profile_manager import ProfileManager
38 from widgets_handler import WidgetsHandler 38 from widgets_handler import WidgetsHandler
39 from kivy.clock import Clock 39 from kivy.clock import Clock
40 from kivy.uix.label import Label 40 from kivy.uix.label import Label
41 from kivy.uix.boxlayout import BoxLayout 41 from kivy.uix.boxlayout import BoxLayout
42 from kivy.uix.screenmanager import ScreenManager, Screen 42 from kivy.uix.screenmanager import ScreenManager, Screen, FallOutTransition, RiseInTransition
43 from kivy.uix.dropdown import DropDown 43 from kivy.uix.dropdown import DropDown
44 from cagou_widget import CagouWidget 44 from cagou_widget import CagouWidget
45 from .common import IconButton 45 from .common import IconButton
46 from importlib import import_module 46 from importlib import import_module
47 import os.path 47 import os.path
48 import glob 48 import glob
49 import cagou.plugins 49 import cagou.plugins
50 import cagou.kv 50 import cagou.kv
51 51
52 52
53 class NotifIcon(IconButton): 53 class NotifsIcon(IconButton):
54 54 notifs = properties.ListProperty()
55 def __init__(self, callback, callback_args):
56 self._callback = callback
57 self._callback_args = callback_args
58 super(NotifIcon, self).__init__()
59 55
60 def on_release(self): 56 def on_release(self):
61 self.parent.remove_widget(self) 57 callback, args, kwargs = self.notifs.pop(0)
62 self._callback(*self._callback_args) 58 callback(*args, **kwargs)
59
60 def addNotif(self, callback, *args, **kwargs):
61 self.notifs.append((callback, args, kwargs))
63 62
64 63
65 class Note(Label): 64 class Note(Label):
66 title = properties.StringProperty() 65 title = properties.StringProperty()
67 message = properties.StringProperty() 66 message = properties.StringProperty()
88 87
89 88
90 class RootHeadWidget(BoxLayout): 89 class RootHeadWidget(BoxLayout):
91 """Notifications widget""" 90 """Notifications widget"""
92 manager = properties.ObjectProperty() 91 manager = properties.ObjectProperty()
92 notifs_icon = properties.ObjectProperty()
93 notes = properties.ListProperty() 93 notes = properties.ListProperty()
94 94
95 def __init__(self): 95 def __init__(self):
96 super(RootHeadWidget, self).__init__() 96 super(RootHeadWidget, self).__init__()
97 self.notes_last = None 97 self.notes_last = None
98 self.notes_event = None 98 self.notes_event = None
99 self.notes_drop = NotesDrop(self.notes) # auto_with=False, width=100) 99 self.notes_drop = NotesDrop(self.notes)
100 100
101 def addNotif(self, callback, *args): 101 def addNotif(self, callback, *args, **kwargs):
102 icon = NotifIcon(callback, args) 102 self.notifs_icon.addNotif(callback, *args, **kwargs)
103 self.add_widget(icon)
104 103
105 def addNote(self, title, message, level): 104 def addNote(self, title, message, level):
106 note = Note(title=title, message=message, level=level) 105 note = Note(title=title, message=message, level=level)
107 self.notes.append(note) 106 self.notes.append(note)
108 if len(self.notes) > 10: 107 if len(self.notes) > 10:
109 del self.notes[:-10] 108 del self.notes[:-10]
110 if self.notes_event is None: 109 if self.notes_event is None:
111 self.notes_event = Clock.schedule_interval(self._displayNextNote, 5) 110 self.notes_event = Clock.schedule_interval(self._displayNextNote, 5)
112 self._displayNextNote() 111 self._displayNextNote()
112
113 def addNotifUI(self, ui):
114 self.notifs_icon.addNotif(ui.show, force=True)
113 115
114 def _displayNextNote(self, dummy=None): 116 def _displayNextNote(self, dummy=None):
115 screen = Screen() 117 screen = Screen()
116 try: 118 try:
117 idx = self.notes.index(self.notes_last) + 1 119 idx = self.notes.index(self.notes_last) + 1
135 self._head_widget = RootHeadWidget() 137 self._head_widget = RootHeadWidget()
136 self.add_widget(self._head_widget) 138 self.add_widget(self._head_widget)
137 139
138 # body 140 # body
139 self._manager = ScreenManager() 141 self._manager = ScreenManager()
142 # main widgets
140 main_screen = Screen(name='main') 143 main_screen = Screen(name='main')
141 main_screen.add_widget(main_widget) 144 main_screen.add_widget(main_widget)
142 self._manager.add_widget(main_screen) 145 self._manager.add_widget(main_screen)
146 # backend XMLUI (popups, forms, etc)
147 xmlui_screen = Screen(name='xmlui')
148 self._manager.add_widget(xmlui_screen)
143 self.add_widget(self._manager) 149 self.add_widget(self._manager)
144 self.change_widget(main_widget) 150
145 151 def changeWidget(self, widget, screen_name="main"):
146 def change_widget(self, main_widget, screen="main"):
147 """change main widget""" 152 """change main widget"""
148 main_screen = self._manager.get_screen(screen) 153 screen = self._manager.get_screen(screen_name)
149 main_screen.clear_widgets() 154 screen.clear_widgets()
150 main_screen.add_widget(main_widget) 155 screen.add_widget(widget)
156
157 def show(self, screen="main"):
158 if self._manager.current == screen:
159 return
160 if screen == "main":
161 self._manager.transition = FallOutTransition()
162 else:
163 self._manager.transition = RiseInTransition()
164 self._manager.current = screen
151 165
152 def newAction(self, handler, action_data, id_, security_limit, profile): 166 def newAction(self, handler, action_data, id_, security_limit, profile):
153 """Add a notification for an action""" 167 """Add a notification for an action"""
154 self._head_widget.addNotif(handler, action_data, id_, security_limit, profile) 168 self._head_widget.addNotif(handler, action_data, id_, security_limit, profile)
155 169
156 def addNote(self, title, message, level): 170 def addNote(self, title, message, level):
157 self._head_widget.addNote(title, message, level) 171 self._head_widget.addNote(title, message, level)
172
173 def addNotifUI(self, ui):
174 self._head_widget.addNotifUI(ui)
158 175
159 176
160 class CagouApp(App): 177 class CagouApp(App):
161 """Kivy App for Cagou""" 178 """Kivy App for Cagou"""
162 179
312 parent.add_widget(new, index=idx) 329 parent.add_widget(new, index=idx)
313 330
314 ## misc ## 331 ## misc ##
315 332
316 def plugging_profiles(self): 333 def plugging_profiles(self):
317 self.app.root.change_widget(WidgetsHandler()) 334 self.app.root.changeWidget(WidgetsHandler())
318 335
319 def setPresenceStatus(self, show='', status=None, profile=C.PROF_KEY_NONE): 336 def setPresenceStatus(self, show='', status=None, profile=C.PROF_KEY_NONE):
320 log.info(u"Profile presence status set to {show}/{status}".format(show=show, status=status)) 337 log.info(u"Profile presence status set to {show}/{status}".format(show=show, status=status))
321 338
322 def addNote(self, title, message, level): 339 def addNote(self, title, message, level):
323 """add a note (message which disappear) to root widget's header""" 340 """add a note (message which disappear) to root widget's header"""
324 self.app.root.addNote(title, message, level) 341 self.app.root.addNote(title, message, level)
325 342
326 ## signals handling ## 343 def addNotifUI(self, ui):
327 344 """add a notification with a XMLUI attached
328 def actionNewHandler(self, action_data, id_, security_limit, profile): 345
329 handler = super(Cagou, self).actionNewHandler 346 @param ui(xmlui.XMLUIPanel): XMLUI instance to show when notification is selected
330 # FIXME: temporarily deactivated 347 """
331 # if 'xmlui' in action_data: 348 self.app.root.addNotifUI(ui)
332 # self.app.root.newAction(handler, action_data, id_, security_limit, profile) 349
333 # else: 350 def showUI(self, ui):
334 # handler(action_data, id_, security_limit, profile) 351 self.app.root.changeWidget(ui, "xmlui")
335 handler(action_data, id_, security_limit, profile) 352 self.app.root.show("xmlui")
353
354 def closeUI(self):
355 self.app.root.show()