Mercurial > libervia-desktop-kivy
comparison cagou/core/cagou_main.py @ 250:ff1efdeff53f
core: notifs can now have a custom icon and be clickable:
- new host.doAction method, to open a specific widget/target (chat only for now)
- when adding a notif, symbol can now be specified
- an action can be linked to a notification
- notifs design improvments
- plugins contact list and chat use the new doAction/notif action
- if None is given as old widget in SwitchWidget, the new getWidgetToSwitch method is used to select one to switch.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 26 Jan 2019 20:24:48 +0100 |
parents | 5d69e4cab925 |
children | 4601793b0dee |
comparison
equal
deleted
inserted
replaced
249:5d69e4cab925 | 250:ff1efdeff53f |
---|---|
52 from kivy.uix.boxlayout import BoxLayout | 52 from kivy.uix.boxlayout import BoxLayout |
53 from kivy.uix.floatlayout import FloatLayout | 53 from kivy.uix.floatlayout import FloatLayout |
54 from kivy.uix.screenmanager import (ScreenManager, Screen, | 54 from kivy.uix.screenmanager import (ScreenManager, Screen, |
55 FallOutTransition, RiseInTransition) | 55 FallOutTransition, RiseInTransition) |
56 from kivy.uix.dropdown import DropDown | 56 from kivy.uix.dropdown import DropDown |
57 from kivy.uix.behaviors import ButtonBehavior | |
57 from kivy.core.window import Window | 58 from kivy.core.window import Window |
58 from kivy.animation import Animation | 59 from kivy.animation import Animation |
59 from kivy.metrics import dp | 60 from kivy.metrics import dp |
60 from cagou_widget import CagouWidget | 61 from cagou_widget import CagouWidget |
61 from . import widgets_handler | 62 from . import widgets_handler |
102 class Note(Label): | 103 class Note(Label): |
103 title = properties.StringProperty() | 104 title = properties.StringProperty() |
104 message = properties.StringProperty() | 105 message = properties.StringProperty() |
105 level = properties.OptionProperty(C.XMLUI_DATA_LVL_DEFAULT, | 106 level = properties.OptionProperty(C.XMLUI_DATA_LVL_DEFAULT, |
106 options=list(C.XMLUI_DATA_LVLS)) | 107 options=list(C.XMLUI_DATA_LVLS)) |
107 | 108 symbol = properties.StringProperty() |
108 | 109 action = properties.ObjectProperty() |
109 class NoteDrop(BoxLayout): | 110 |
111 | |
112 class NoteDrop(ButtonBehavior, BoxLayout): | |
110 title = properties.StringProperty() | 113 title = properties.StringProperty() |
111 message = properties.StringProperty() | 114 message = properties.StringProperty() |
112 level = properties.OptionProperty(C.XMLUI_DATA_LVL_DEFAULT, | 115 level = properties.OptionProperty(C.XMLUI_DATA_LVL_DEFAULT, |
113 options=list(C.XMLUI_DATA_LVLS)) | 116 options=list(C.XMLUI_DATA_LVLS)) |
117 symbol = properties.StringProperty() | |
118 action = properties.ObjectProperty() | |
119 | |
120 def on_press(self): | |
121 if self.action is not None: | |
122 self.parent.parent.select(self.action) | |
114 | 123 |
115 | 124 |
116 class NotesDrop(DropDown): | 125 class NotesDrop(DropDown): |
117 clear_btn = properties.ObjectProperty() | 126 clear_btn = properties.ObjectProperty() |
118 | 127 |
121 self.notes = notes | 130 self.notes = notes |
122 | 131 |
123 def open(self, widget): | 132 def open(self, widget): |
124 self.clear_widgets() | 133 self.clear_widgets() |
125 for n in self.notes: | 134 for n in self.notes: |
126 self.add_widget(NoteDrop(title=n.title, message=n.message, level=n.level)) | 135 kwargs = { |
136 u'title': n.title, | |
137 u'message': n.message, | |
138 u'level': n.level | |
139 } | |
140 if n.symbol is not None: | |
141 kwargs[u'symbol'] = n.symbol | |
142 if n.action is not None: | |
143 kwargs[u'action'] = n.action | |
144 self.add_widget(NoteDrop(title=n.title, message=n.message, level=n.level, | |
145 symbol=n.symbol, action=n.action)) | |
127 self.add_widget(self.clear_btn) | 146 self.add_widget(self.clear_btn) |
128 super(NotesDrop, self).open(widget) | 147 super(NotesDrop, self).open(widget) |
148 | |
149 def on_select(self, action_kwargs): | |
150 app = App.get_running_app() | |
151 app.host.doAction(**action_kwargs) | |
129 | 152 |
130 | 153 |
131 class RootHeadWidget(BoxLayout): | 154 class RootHeadWidget(BoxLayout): |
132 """Notifications widget""" | 155 """Notifications widget""" |
133 manager = properties.ObjectProperty() | 156 manager = properties.ObjectProperty() |
147 when notification is pressed, callback is called | 170 when notification is pressed, callback is called |
148 @param *args, **kwargs: arguments of callback | 171 @param *args, **kwargs: arguments of callback |
149 """ | 172 """ |
150 self.notifs_icon.addNotif(callback, *args, **kwargs) | 173 self.notifs_icon.addNotif(callback, *args, **kwargs) |
151 | 174 |
152 def addNote(self, title, message, level): | 175 def addNote(self, title, message, level, symbol, action): |
153 note = Note(title=title, message=message, level=level) | 176 kwargs = { |
177 u'title': title, | |
178 u'message': message, | |
179 u'level': level | |
180 } | |
181 if symbol is not None: | |
182 kwargs[u'symbol'] = symbol | |
183 if action is not None: | |
184 kwargs[u'action'] = action | |
185 note = Note(**kwargs) | |
154 self.notes.append(note) | 186 self.notes.append(note) |
155 if self.notes_event is None: | 187 if self.notes_event is None: |
156 self.notes_event = Clock.schedule_interval(self._displayNextNote, 5) | 188 self.notes_event = Clock.schedule_interval(self._displayNextNote, 5) |
157 self._displayNextNote() | 189 self._displayNextNote() |
158 | 190 |
235 | 267 |
236 def newAction(self, handler, action_data, id_, security_limit, profile): | 268 def newAction(self, handler, action_data, id_, security_limit, profile): |
237 """Add a notification for an action""" | 269 """Add a notification for an action""" |
238 self.head_widget.addNotif(handler, action_data, id_, security_limit, profile) | 270 self.head_widget.addNotif(handler, action_data, id_, security_limit, profile) |
239 | 271 |
240 def addNote(self, title, message, level): | 272 def addNote(self, title, message, level, symbol, action): |
241 self.head_widget.addNote(title, message, level) | 273 self.head_widget.addNote(title, message, level, symbol, action) |
242 | 274 |
243 def addNotifUI(self, ui): | 275 def addNotifUI(self, ui): |
244 self.head_widget.addNotifUI(ui) | 276 self.head_widget.addNotifUI(ui) |
245 | 277 |
246 def addNotifWidget(self, widget): | 278 def addNotifWidget(self, widget): |
660 self.addNote(u"", _(u"room {} has been joined").format(widget.target)) | 692 self.addNote(u"", _(u"room {} has been joined").format(widget.target)) |
661 | 693 |
662 def switchWidget(self, old, new): | 694 def switchWidget(self, old, new): |
663 """Replace old widget by new one | 695 """Replace old widget by new one |
664 | 696 |
665 old(CagouWidget): CagouWidget instance or a child | 697 old(CagouWidgetn None): CagouWidget instance or a child |
698 None to select automatically widget to switch | |
666 new(CagouWidget): new widget instance | 699 new(CagouWidget): new widget instance |
667 """ | 700 """ |
701 if old is None: | |
702 old = self.getWidgetToSwitch() | |
668 to_change = None | 703 to_change = None |
669 if isinstance(old, CagouWidget): | 704 if isinstance(old, CagouWidget): |
670 to_change = old | 705 to_change = old |
671 else: | 706 else: |
672 for w in old.walk_reverse(): | 707 for w in old.walk_reverse(): |
728 profiles=widget.profiles) | 763 profiles=widget.profiles) |
729 for t in targets[1:]: | 764 for t in targets[1:]: |
730 w.addTarget(t) | 765 w.addTarget(t) |
731 return w | 766 return w |
732 | 767 |
768 def getWidgetToSwitch(self): | |
769 """Choose best candidate when we need to switch widget and old is not specified | |
770 | |
771 @return (CagouWidget): widget to switch | |
772 """ | |
773 if self.selected_widget is not None: | |
774 return self.selected_widget | |
775 # no widget is selected we check if we have any default widget | |
776 default_cls = self.default_wid['main'] | |
777 for w in self.visible_widgets: | |
778 if isinstance(w, default_cls): | |
779 return w | |
780 | |
781 # no default widget found, we return the first widget | |
782 return next(iter(self.visible_widgets)) | |
783 | |
784 def doAction(self, action, target, profiles): | |
785 """Launch an action handler by a plugin | |
786 | |
787 @param action(unicode): action to do, can be: | |
788 - chat: open a chat widget | |
789 @param target(unicode): target of the action | |
790 @param profiles(list[unicode]): profiles to use | |
791 """ | |
792 try: | |
793 # FIXME: Q&D way to get chat plugin, should be replaced by a clean method | |
794 # in host | |
795 plg_infos = [p for p in self.getPluggedWidgets() | |
796 if action in p['import_name']][0] | |
797 except IndexError: | |
798 log.warning(u"No plugin widget found to do {action}".format(action=action)) | |
799 else: | |
800 factory = plg_infos['factory'] | |
801 self.switchWidget(None, | |
802 factory(plg_infos, target=target, profiles=profiles)) | |
803 | |
733 ## menus ## | 804 ## menus ## |
734 | 805 |
735 def _menusGetCb(self, backend_menus): | 806 def _menusGetCb(self, backend_menus): |
736 main_menu = self.app.root.root_menus | 807 main_menu = self.app.root.root_menus |
737 self.menus.addMenus(backend_menus) | 808 self.menus.addMenus(backend_menus) |
764 | 835 |
765 def errback(self, failure_, title=_('error'), | 836 def errback(self, failure_, title=_('error'), |
766 message=_(u'error while processing: {msg}')): | 837 message=_(u'error while processing: {msg}')): |
767 self.addNote(title, message.format(msg=failure_), level=C.XMLUI_DATA_LVL_WARNING) | 838 self.addNote(title, message.format(msg=failure_), level=C.XMLUI_DATA_LVL_WARNING) |
768 | 839 |
769 def addNote(self, title, message, level=C.XMLUI_DATA_LVL_INFO): | 840 def addNote(self, title, message, level=C.XMLUI_DATA_LVL_INFO, symbol=None, |
841 action=None): | |
770 """add a note (message which disappear) to root widget's header""" | 842 """add a note (message which disappear) to root widget's header""" |
771 self.app.root.addNote(title, message, level) | 843 self.app.root.addNote(title, message, level, symbol, action) |
772 | 844 |
773 def addNotifUI(self, ui): | 845 def addNotifUI(self, ui): |
774 """add a notification with a XMLUI attached | 846 """add a notification with a XMLUI attached |
775 | 847 |
776 @param ui(xmlui.XMLUIPanel): XMLUI instance to show when notification is selected | 848 @param ui(xmlui.XMLUIPanel): XMLUI instance to show when notification is selected |