Mercurial > libervia-desktop-kivy
comparison cagou/core/menu.py @ 404:f7476818f9fb
core (common): JidSelector + behaviors various improvments:
- renamed *Behaviour => *Behavior to be consistent with Kivy + moved to new
"core.behaviors" modules
- use a dedicated property in ContactItem for notification counter (which is now named
"badge")
- in JidSelector, well-known strings now create use a dedicated layout, add separator
(except if new `add_separators` property is set to False), and are added to attribute of
the same name
- a new `item_class` property is now used to indicate the class to instanciate for items
(by default it's a ContactItem)
- FilterBahavior.do_filter now expect the parent layout instead of directly the children,
this is to allow a FilterBahavior to manage several children layout at once (used with
JidSelector)
- core.utils has been removed, as the behavior there has been moved to core.behaviors
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 12 Feb 2020 20:02:58 +0100 |
parents | 71f51198478c |
children | 5761b5f03c0c |
comparison
equal
deleted
inserted
replaced
403:b0af45a92055 | 404:f7476818f9fb |
---|---|
24 from cagou.core.common import JidToggle | 24 from cagou.core.common import JidToggle |
25 from kivy.uix.boxlayout import BoxLayout | 25 from kivy.uix.boxlayout import BoxLayout |
26 from kivy.uix.label import Label | 26 from kivy.uix.label import Label |
27 from kivy.uix.button import Button | 27 from kivy.uix.button import Button |
28 from kivy.uix.popup import Popup | 28 from kivy.uix.popup import Popup |
29 from cagou.core.utils import FilterBehavior | 29 from .behaviors import FilterBehavior |
30 from kivy import properties | 30 from kivy import properties |
31 from kivy_garden import modernmenu | |
32 from kivy.core.window import Window | 31 from kivy.core.window import Window |
33 from kivy.animation import Animation | 32 from kivy.animation import Animation |
34 from kivy.metrics import dp | 33 from kivy.metrics import dp |
35 from kivy.clock import Clock | |
36 from cagou import G | 34 from cagou import G |
37 from functools import partial | 35 from functools import partial |
38 import webbrowser | 36 import webbrowser |
39 | 37 |
40 log = logging.getLogger(__name__) | 38 log = logging.getLogger(__name__) |
293 jids = [c.jid for c in self.layout.children if c.state == 'down'] | 291 jids = [c.jid for c in self.layout.children if c.state == 'down'] |
294 self.callback(jids) | 292 self.callback(jids) |
295 | 293 |
296 def do_filter_input(self, filter_input, text): | 294 def do_filter_input(self, filter_input, text): |
297 self.layout.spacing = 0 if text else dp(5) | 295 self.layout.spacing = 0 if text else dp(5) |
298 self.do_filter(self.layout.children, | 296 self.do_filter(self.layout, |
299 text, | 297 text, |
300 lambda c: c.jid, | 298 lambda c: c.jid, |
301 width_cb=lambda c: c.width, | 299 width_cb=lambda c: c.width, |
302 height_cb=lambda c: dp(70)) | 300 height_cb=lambda c: dp(70)) |
303 | |
304 | |
305 class TouchMenu(modernmenu.ModernMenu): | |
306 pass | |
307 | |
308 | |
309 class TouchMenuItemBehaviour(object): | |
310 """Class to use on every item where a menu may appear | |
311 | |
312 main_wid attribute must be set to the class inheriting from TouchMenuBehaviour | |
313 do_item_action is the method called on simple click | |
314 getMenuChoices must return a list of menus for long press | |
315 menus there are dict as expected by ModernMenu | |
316 (translated text, index and callback) | |
317 """ | |
318 main_wid = properties.ObjectProperty() | |
319 click_timeout = properties.NumericProperty(0.4) | |
320 | |
321 def on_touch_down(self, touch): | |
322 if not self.collide_point(*touch.pos): | |
323 return | |
324 t = partial(self.open_menu, touch) | |
325 touch.ud['menu_timeout'] = t | |
326 Clock.schedule_once(t, self.click_timeout) | |
327 return super(TouchMenuItemBehaviour, self).on_touch_down(touch) | |
328 | |
329 def do_item_action(self, touch): | |
330 pass | |
331 | |
332 def on_touch_up(self, touch): | |
333 if touch.ud.get('menu_timeout'): | |
334 Clock.unschedule(touch.ud['menu_timeout']) | |
335 if self.collide_point(*touch.pos) and self.main_wid.menu is None: | |
336 self.do_item_action(touch) | |
337 return super(TouchMenuItemBehaviour, self).on_touch_up(touch) | |
338 | |
339 def open_menu(self, touch, dt): | |
340 self.main_wid.open_menu(self, touch) | |
341 del touch.ud['menu_timeout'] | |
342 | |
343 def getMenuChoices(self): | |
344 """return choice adapted to selected item | |
345 | |
346 @return (list[dict]): choices ad expected by ModernMenu | |
347 """ | |
348 return [] | |
349 | |
350 | |
351 class TouchMenuBehaviour(object): | |
352 """Class to handle a menu appearing on long press on items | |
353 | |
354 classes using this behaviour need to have a float_layout property | |
355 pointing the main FloatLayout. | |
356 """ | |
357 float_layout = properties.ObjectProperty() | |
358 | |
359 def __init__(self, *args, **kwargs): | |
360 super(TouchMenuBehaviour, self).__init__(*args, **kwargs) | |
361 self.menu = None | |
362 self.menu_item = None | |
363 | |
364 ## menu methods ## | |
365 | |
366 def clean_fl_children(self, layout, children): | |
367 """insure that self.menu and self.menu_item are None when menu is dimissed""" | |
368 if self.menu is not None and self.menu not in children: | |
369 self.menu = self.menu_item = None | |
370 | |
371 def clear_menu(self): | |
372 """remove menu if there is one""" | |
373 if self.menu is not None: | |
374 self.menu.dismiss() | |
375 self.menu = None | |
376 self.menu_item = None | |
377 | |
378 def open_menu(self, item, touch): | |
379 """open menu for item | |
380 | |
381 @param item(PathWidget): item when the menu has been requested | |
382 @param touch(kivy.input.MotionEvent): touch data | |
383 """ | |
384 if self.menu_item == item: | |
385 return | |
386 self.clear_menu() | |
387 pos = self.to_widget(*touch.pos) | |
388 choices = item.getMenuChoices() | |
389 if not choices: | |
390 return | |
391 self.menu = TouchMenu(choices=choices, | |
392 center=pos, | |
393 size_hint=(None, None)) | |
394 self.float_layout.add_widget(self.menu) | |
395 self.menu.start_display(touch) | |
396 self.menu_item = item | |
397 | |
398 def on_float_layout(self, wid, float_layout): | |
399 float_layout.bind(children=self.clean_fl_children) |