Mercurial > libervia-desktop-kivy
comparison src/cagou/core/cagou_main.py @ 38:9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
- a couple of methods have been added to handle visible and hidden widgets
- a new getOrClone method allow to recreate a widget if it already has a parent (can happen even if the widget is not shown, e.g. in a carousel)
- handler now display hidden widgets of the same class as the displayed one when swiping. For instance, if a chat widget is displayed, and header input is used to show an other one, it's now possible to go back to the former by swiping. QuickWidget.onDelete method can be used to handle if a widget must be really deleted (return True) or just hidden (any other value).
- handler use a subclass of Carousel for this new feature, with some adjustement so event can be passed to children without too much delay (and frustration). This may need to be adjusted again in the future.
- handler.cagou_widget now give the main displayed widget in the handler
- handler.changeWidget must be used when widget need to be changed (it's better to use host.switchWidget which will call it itself)
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 28 Aug 2016 15:27:48 +0200 |
parents | 02acbb297a61 |
children | a1ec6cb57a1b |
comparison
equal
deleted
inserted
replaced
37:6cf08d0ee460 | 38:9f45098289cc |
---|---|
22 import logging_setter | 22 import logging_setter |
23 logging_setter.set_logging() | 23 logging_setter.set_logging() |
24 from constants import Const as C | 24 from constants import Const as C |
25 from sat.core import log as logging | 25 from sat.core import log as logging |
26 log = logging.getLogger(__name__) | 26 log = logging.getLogger(__name__) |
27 from sat.core import exceptions | |
27 from sat_frontends.quick_frontend.quick_app import QuickApp | 28 from sat_frontends.quick_frontend.quick_app import QuickApp |
28 from sat_frontends.quick_frontend import quick_widgets | 29 from sat_frontends.quick_frontend import quick_widgets |
29 from sat_frontends.bridge.DBus import DBusBridgeFrontend | 30 from sat_frontends.bridge.DBus import DBusBridgeFrontend |
30 import kivy | 31 import kivy |
31 kivy.require('1.9.1') | 32 kivy.require('1.9.1') |
41 from kivy.uix.label import Label | 42 from kivy.uix.label import Label |
42 from kivy.uix.boxlayout import BoxLayout | 43 from kivy.uix.boxlayout import BoxLayout |
43 from kivy.uix.screenmanager import ScreenManager, Screen, FallOutTransition, RiseInTransition | 44 from kivy.uix.screenmanager import ScreenManager, Screen, FallOutTransition, RiseInTransition |
44 from kivy.uix.dropdown import DropDown | 45 from kivy.uix.dropdown import DropDown |
45 from cagou_widget import CagouWidget | 46 from cagou_widget import CagouWidget |
47 from . import widgets_handler | |
46 from .common import IconButton | 48 from .common import IconButton |
47 from importlib import import_module | 49 from importlib import import_module |
48 import os.path | 50 import os.path |
49 import glob | 51 import glob |
50 import cagou.plugins | 52 import cagou.plugins |
203 self.app.host = self | 205 self.app.host = self |
204 self.media_dir = self.app.media_dir = self.bridge.getConfig("", "media_dir") | 206 self.media_dir = self.app.media_dir = self.bridge.getConfig("", "media_dir") |
205 self.app.default_avatar = os.path.join(self.media_dir, "misc/default_avatar.png") | 207 self.app.default_avatar = os.path.join(self.media_dir, "misc/default_avatar.png") |
206 self._plg_wids = [] # widget plugins | 208 self._plg_wids = [] # widget plugins |
207 self._import_plugins() | 209 self._import_plugins() |
210 self._visible_widgets = {} # visible widgets by classes | |
211 | |
212 @property | |
213 def visible_widgets(self): | |
214 for w_list in self._visible_widgets.itervalues(): | |
215 for w in w_list: | |
216 yield w | |
208 | 217 |
209 def run(self): | 218 def run(self): |
210 self.app.run() | 219 self.app.run() |
211 | 220 |
212 def _defaultFactory(self, plugin_info, target, profiles): | 221 def _defaultFactory(self, plugin_info, target, profiles): |
304 continue | 313 continue |
305 yield plugin_data | 314 yield plugin_data |
306 | 315 |
307 ## widgets handling | 316 ## widgets handling |
308 | 317 |
318 def getParentHandler(self, widget): | |
319 """Return handler holding this widget | |
320 | |
321 @return (WidgetsHandler): handler | |
322 """ | |
323 w_handler = widget.parent | |
324 while w_handler and not(isinstance(w_handler, widgets_handler.WidgetsHandler)): | |
325 w_handler = w_handler.parent | |
326 return w_handler | |
327 | |
309 def switchWidget(self, old, new): | 328 def switchWidget(self, old, new): |
310 """Replace old widget by new one | 329 """Replace old widget by new one |
311 | 330 |
312 old(CagouWidget): CagouWidget instance or a child | 331 old(CagouWidget): CagouWidget instance or a child |
313 new(CagouWidget): new widget instance | 332 new(CagouWidget): new widget instance |
320 if isinstance(w, CagouWidget): | 339 if isinstance(w, CagouWidget): |
321 to_change = w | 340 to_change = w |
322 break | 341 break |
323 | 342 |
324 if to_change is None: | 343 if to_change is None: |
325 log.error(u"no CagouWidget found when trying to switch widget") | 344 raise exceptions.InternalError(u"no CagouWidget found when trying to switch widget") |
326 else: | 345 handler = self.getParentHandler(to_change) |
327 parent = to_change.parent | 346 handler.changeWidget(new) |
328 idx = parent.children.index(to_change) | 347 |
329 parent.remove_widget(to_change) | 348 def addVisibleWidget(self, widget): |
330 if isinstance(to_change, quick_widgets.QuickWidget): | 349 """declare a widget visible |
331 self.widgets.deleteWidget(to_change) | 350 |
332 parent.add_widget(new, index=idx) | 351 for internal use only! |
352 """ | |
353 assert isinstance(widget, quick_widgets.QuickWidget) | |
354 log.info(u"addVisibleWidget: {}".format(', '.join([unicode(t) for t in widget.targets]))) | |
355 self._visible_widgets.setdefault(widget.__class__, []).append(widget) | |
356 | |
357 def removeVisibleWidget(self, widget): | |
358 """declare a widget not visible anymore | |
359 | |
360 for internal use only! | |
361 """ | |
362 log.info(u"removeVisibleWidget: {}".format(', '.join([unicode(t) for t in widget.targets]))) | |
363 self._visible_widgets[widget.__class__].remove(widget) | |
364 log.info("remove: " + unicode(widget.targets)) | |
365 self.widgets.deleteWidget(widget) | |
366 | |
367 def getVisibleList(self, cls): | |
368 """get list of visible widgets for a given class | |
369 | |
370 @param cls(QuickWidget class): type of widgets to get | |
371 @return (list[QuickWidget class]): visible widgets of this class | |
372 """ | |
373 try: | |
374 return self._visible_widgets[cls] | |
375 except KeyError: | |
376 return [] | |
377 | |
378 def getOrClone(self, widget): | |
379 """Get a QuickWidget if it has not parent set else clone it""" | |
380 if widget.parent is None: | |
381 return widget | |
382 targets = list(widget.targets) | |
383 w = self.widgets.getOrCreateWidget(widget.__class__, targets[0], on_new_widget=None, on_existing_widget=C.WIDGET_RECREATE, profiles=widget.profiles) | |
384 for t in targets[1:]: | |
385 w.addTarget(t) | |
386 return w | |
333 | 387 |
334 ## misc ## | 388 ## misc ## |
335 | 389 |
336 def plugging_profiles(self): | 390 def plugging_profiles(self): |
337 self.app.root.changeWidget(WidgetsHandler()) | 391 self.app.root.changeWidget(WidgetsHandler()) |