annotate cagou/core/menu.py @ 400:71f51198478c

android: handle runtime permissions: - some mandatory permissions are requested on Cagou start, Cagou won't start at all and display a warning message if they are not granted (we request 5 times before showing the warning) - transfer plugin can now use "android_permissions" in plugin_info, to indicate what is necessary. The permissions will then be requested, and the plugin widget won't be shown if they are not granted (and a warning not will then be displayed)
author Goffi <goffi@goffi.org>
date Sun, 09 Feb 2020 23:47:29 +0100
parents 1da3c379205b
children f7476818f9fb
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
379
1da3c379205b fixed shebangs
Goffi <goffi@goffi.org>
parents: 378
diff changeset
1 #!/usr/bin/env python3
1da3c379205b fixed shebangs
Goffi <goffi@goffi.org>
parents: 378
diff changeset
2
51
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
3
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # Cagou: desktop/mobile frontend for Salut à Toi XMPP client
378
4d660b252487 dates update
Goffi <goffi@goffi.org>
parents: 376
diff changeset
5 # Copyright (C) 2016-2020 Jérôme Poisson (goffi@goffi.org)
51
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
6
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # This program is free software: you can redistribute it and/or modify
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # it under the terms of the GNU Affero General Public License as published by
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # the Free Software Foundation, either version 3 of the License, or
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
10 # (at your option) any later version.
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
11
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # This program is distributed in the hope that it will be useful,
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
15 # GNU Affero General Public License for more details.
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
16
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # You should have received a copy of the GNU Affero General Public License
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
19
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
20
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
21 from sat.core.i18n import _
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
22 from sat.core import log as logging
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
23 from cagou.core.constants import Const as C
197
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
24 from cagou.core.common import JidToggle
85
c2a7234d13d2 menu: use of garden's contextmenu for menus
Goffi <goffi@goffi.org>
parents: 53
diff changeset
25 from kivy.uix.boxlayout import BoxLayout
51
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
26 from kivy.uix.label import Label
376
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
27 from kivy.uix.button import Button
51
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
28 from kivy.uix.popup import Popup
197
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
29 from cagou.core.utils import FilterBehavior
51
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
30 from kivy import properties
373
5d994be1161b core: removed root menus (i.e. global menu on top of window):
Goffi <goffi@goffi.org>
parents: 365
diff changeset
31 from kivy_garden import modernmenu
168
397f2fb67aab core (menu): animate transfer menu opening/closing + close it on [ESC]/back
Goffi <goffi@goffi.org>
parents: 126
diff changeset
32 from kivy.core.window import Window
397f2fb67aab core (menu): animate transfer menu opening/closing + close it on [ESC]/back
Goffi <goffi@goffi.org>
parents: 126
diff changeset
33 from kivy.animation import Animation
197
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
34 from kivy.metrics import dp
222
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
35 from kivy.clock import Clock
51
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
36 from cagou import G
222
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
37 from functools import partial
51
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
38 import webbrowser
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
39
302
f55b60659ec1 core (about): improved "about" popup:
Goffi <goffi@goffi.org>
parents: 282
diff changeset
40 log = logging.getLogger(__name__)
f55b60659ec1 core (about): improved "about" popup:
Goffi <goffi@goffi.org>
parents: 282
diff changeset
41
312
772c170b47a9 Python3 port:
Goffi <goffi@goffi.org>
parents: 302
diff changeset
42 ABOUT_TITLE = _("About {}".format(C.APP_NAME))
772c170b47a9 Python3 port:
Goffi <goffi@goffi.org>
parents: 302
diff changeset
43 ABOUT_CONTENT = _("""[b]Cagou (Salut à Toi)[/b]
302
f55b60659ec1 core (about): improved "about" popup:
Goffi <goffi@goffi.org>
parents: 282
diff changeset
44
f55b60659ec1 core (about): improved "about" popup:
Goffi <goffi@goffi.org>
parents: 282
diff changeset
45 [u]cagou version[/u]:
f55b60659ec1 core (about): improved "about" popup:
Goffi <goffi@goffi.org>
parents: 282
diff changeset
46 {version}
f55b60659ec1 core (about): improved "about" popup:
Goffi <goffi@goffi.org>
parents: 282
diff changeset
47
f55b60659ec1 core (about): improved "about" popup:
Goffi <goffi@goffi.org>
parents: 282
diff changeset
48 [u]backend version[/u]:
f55b60659ec1 core (about): improved "about" popup:
Goffi <goffi@goffi.org>
parents: 282
diff changeset
49 {backend_version}
51
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
50
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
51 Cagou is a libre communication tool based on libre standard XMPP.
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
52
302
f55b60659ec1 core (about): improved "about" popup:
Goffi <goffi@goffi.org>
parents: 282
diff changeset
53 Cagou is part of the "Salut à Toi" project (desktop/mobile frontend)
51
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
54 more informations at [color=5500ff][ref=website]salut-a-toi.org[/ref][/color]
246
15e47bbb192c about: show full version of SàT
Goffi <goffi@goffi.org>
parents: 222
diff changeset
55 """)
51
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
56
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
57
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 class AboutContent(Label):
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
59
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
60 def on_ref_press(self, value):
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
61 if value == "website":
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
62 webbrowser.open("https://salut-a-toi.org")
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
63
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
64
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
65 class AboutPopup(Popup):
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
66
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
67 def on_touch_down(self, touch):
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
68 if self.collide_point(*touch.pos):
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
69 self.dismiss()
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
70 return super(AboutPopup, self).on_touch_down(touch)
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
71
3f8599d9a766 core: menus first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
72
97
5d2289127bb7 menu (upload): better menu using dedicated widget:
Goffi <goffi@goffi.org>
parents: 88
diff changeset
73 class TransferItem(BoxLayout):
5d2289127bb7 menu (upload): better menu using dedicated widget:
Goffi <goffi@goffi.org>
parents: 88
diff changeset
74 plug_info = properties.DictProperty()
5d2289127bb7 menu (upload): better menu using dedicated widget:
Goffi <goffi@goffi.org>
parents: 88
diff changeset
75
5d2289127bb7 menu (upload): better menu using dedicated widget:
Goffi <goffi@goffi.org>
parents: 88
diff changeset
76 def on_touch_up(self, touch):
5d2289127bb7 menu (upload): better menu using dedicated widget:
Goffi <goffi@goffi.org>
parents: 88
diff changeset
77 if not self.collide_point(*touch.pos):
5d2289127bb7 menu (upload): better menu using dedicated widget:
Goffi <goffi@goffi.org>
parents: 88
diff changeset
78 return super(TransferItem, self).on_touch_up(touch)
5d2289127bb7 menu (upload): better menu using dedicated widget:
Goffi <goffi@goffi.org>
parents: 88
diff changeset
79 else:
5d2289127bb7 menu (upload): better menu using dedicated widget:
Goffi <goffi@goffi.org>
parents: 88
diff changeset
80 transfer_menu = self.parent
5d2289127bb7 menu (upload): better menu using dedicated widget:
Goffi <goffi@goffi.org>
parents: 88
diff changeset
81 while not isinstance(transfer_menu, TransferMenu):
5d2289127bb7 menu (upload): better menu using dedicated widget:
Goffi <goffi@goffi.org>
parents: 88
diff changeset
82 transfer_menu = transfer_menu.parent
5d2289127bb7 menu (upload): better menu using dedicated widget:
Goffi <goffi@goffi.org>
parents: 88
diff changeset
83 transfer_menu.do_callback(self.plug_info)
5d2289127bb7 menu (upload): better menu using dedicated widget:
Goffi <goffi@goffi.org>
parents: 88
diff changeset
84 return True
5d2289127bb7 menu (upload): better menu using dedicated widget:
Goffi <goffi@goffi.org>
parents: 88
diff changeset
85
5d2289127bb7 menu (upload): better menu using dedicated widget:
Goffi <goffi@goffi.org>
parents: 88
diff changeset
86
197
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
87 class SideMenu(BoxLayout):
216
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
88 size_hint_close = (0, 1)
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
89 size_hint_open = (0.4, 1)
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
90 size_close = (100, 100)
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
91 size_open = (0, 0)
197
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
92 bg_color = properties.ListProperty([0, 0, 0, 1])
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
93 # callback will be called with arguments relevant to menu
86
c711be670ecd core, chat: upload plugin system:
Goffi <goffi@goffi.org>
parents: 85
diff changeset
94 callback = properties.ObjectProperty()
197
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
95 # call do_callback even when menu is cancelled
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
96 callback_on_close = properties.BooleanProperty(False)
86
c711be670ecd core, chat: upload plugin system:
Goffi <goffi@goffi.org>
parents: 85
diff changeset
97 # cancel callback need to remove the widget for UI
c711be670ecd core, chat: upload plugin system:
Goffi <goffi@goffi.org>
parents: 85
diff changeset
98 # will be called with the widget to remove as argument
c711be670ecd core, chat: upload plugin system:
Goffi <goffi@goffi.org>
parents: 85
diff changeset
99 cancel_cb = properties.ObjectProperty()
c711be670ecd core, chat: upload plugin system:
Goffi <goffi@goffi.org>
parents: 85
diff changeset
100
c711be670ecd core, chat: upload plugin system:
Goffi <goffi@goffi.org>
parents: 85
diff changeset
101 def __init__(self, **kwargs):
197
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
102 super(SideMenu, self).__init__(**kwargs)
86
c711be670ecd core, chat: upload plugin system:
Goffi <goffi@goffi.org>
parents: 85
diff changeset
103 if self.cancel_cb is None:
197
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
104 self.cancel_cb = self.onMenuCancelled
86
c711be670ecd core, chat: upload plugin system:
Goffi <goffi@goffi.org>
parents: 85
diff changeset
105
216
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
106 def _set_anim_kw(self, kw, size_hint, size):
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
107 """Set animation keywords
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
108
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
109 for each value of size_hint it is used if not None,
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
110 else size is used.
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
111 If one value of size is bigger than the respective one of Window
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
112 the one of Window is used
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
113 """
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
114 size_hint_x, size_hint_y = size_hint
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
115 width, height = size
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
116 if size_hint_x is not None:
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
117 kw['size_hint_x'] = size_hint_x
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
118 elif width is not None:
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
119 kw['width'] = min(width, Window.width)
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
120
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
121 if size_hint_y is not None:
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
122 kw['size_hint_y'] = size_hint_y
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
123 elif height is not None:
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
124 kw['height'] = min(height, Window.height)
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
125
86
c711be670ecd core, chat: upload plugin system:
Goffi <goffi@goffi.org>
parents: 85
diff changeset
126 def show(self, caller_wid=None):
168
397f2fb67aab core (menu): animate transfer menu opening/closing + close it on [ESC]/back
Goffi <goffi@goffi.org>
parents: 126
diff changeset
127 Window.bind(on_keyboard=self.key_input)
97
5d2289127bb7 menu (upload): better menu using dedicated widget:
Goffi <goffi@goffi.org>
parents: 88
diff changeset
128 G.host.app.root.add_widget(self)
216
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
129 kw = {'d': 0.3, 't': 'out_back'}
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
130 self._set_anim_kw(kw, self.size_hint_open, self.size_open)
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
131 Animation(**kw).start(self)
168
397f2fb67aab core (menu): animate transfer menu opening/closing + close it on [ESC]/back
Goffi <goffi@goffi.org>
parents: 126
diff changeset
132
397f2fb67aab core (menu): animate transfer menu opening/closing + close it on [ESC]/back
Goffi <goffi@goffi.org>
parents: 126
diff changeset
133 def hide(self):
397f2fb67aab core (menu): animate transfer menu opening/closing + close it on [ESC]/back
Goffi <goffi@goffi.org>
parents: 126
diff changeset
134 Window.unbind(on_keyboard=self.key_input)
216
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
135 kw = {'d': 0.2}
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
136 self._set_anim_kw(kw, self.size_hint_close, self.size_close)
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
137 anim = Animation(**kw)
168
397f2fb67aab core (menu): animate transfer menu opening/closing + close it on [ESC]/back
Goffi <goffi@goffi.org>
parents: 126
diff changeset
138 anim.bind(on_complete=lambda anim, menu: self.parent.remove_widget(self))
397f2fb67aab core (menu): animate transfer menu opening/closing + close it on [ESC]/back
Goffi <goffi@goffi.org>
parents: 126
diff changeset
139 anim.start(self)
197
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
140 if self.callback_on_close:
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
141 self.do_callback()
97
5d2289127bb7 menu (upload): better menu using dedicated widget:
Goffi <goffi@goffi.org>
parents: 88
diff changeset
142
5d2289127bb7 menu (upload): better menu using dedicated widget:
Goffi <goffi@goffi.org>
parents: 88
diff changeset
143 def on_touch_down(self, touch):
5d2289127bb7 menu (upload): better menu using dedicated widget:
Goffi <goffi@goffi.org>
parents: 88
diff changeset
144 # we remove the menu if we click outside
5d2289127bb7 menu (upload): better menu using dedicated widget:
Goffi <goffi@goffi.org>
parents: 88
diff changeset
145 # else we want to handle the event, but not
5d2289127bb7 menu (upload): better menu using dedicated widget:
Goffi <goffi@goffi.org>
parents: 88
diff changeset
146 # transmit it to parents
5d2289127bb7 menu (upload): better menu using dedicated widget:
Goffi <goffi@goffi.org>
parents: 88
diff changeset
147 if not self.collide_point(*touch.pos):
168
397f2fb67aab core (menu): animate transfer menu opening/closing + close it on [ESC]/back
Goffi <goffi@goffi.org>
parents: 126
diff changeset
148 self.hide()
86
c711be670ecd core, chat: upload plugin system:
Goffi <goffi@goffi.org>
parents: 85
diff changeset
149 else:
197
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
150 return super(SideMenu, self).on_touch_down(touch)
97
5d2289127bb7 menu (upload): better menu using dedicated widget:
Goffi <goffi@goffi.org>
parents: 88
diff changeset
151 return True
86
c711be670ecd core, chat: upload plugin system:
Goffi <goffi@goffi.org>
parents: 85
diff changeset
152
168
397f2fb67aab core (menu): animate transfer menu opening/closing + close it on [ESC]/back
Goffi <goffi@goffi.org>
parents: 126
diff changeset
153 def key_input(self, window, key, scancode, codepoint, modifier):
397f2fb67aab core (menu): animate transfer menu opening/closing + close it on [ESC]/back
Goffi <goffi@goffi.org>
parents: 126
diff changeset
154 if key == 27:
397f2fb67aab core (menu): animate transfer menu opening/closing + close it on [ESC]/back
Goffi <goffi@goffi.org>
parents: 126
diff changeset
155 self.hide()
397f2fb67aab core (menu): animate transfer menu opening/closing + close it on [ESC]/back
Goffi <goffi@goffi.org>
parents: 126
diff changeset
156 return True
397f2fb67aab core (menu): animate transfer menu opening/closing + close it on [ESC]/back
Goffi <goffi@goffi.org>
parents: 126
diff changeset
157
197
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
158 def onMenuCancelled(self, wid, cleaning_cb=None):
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
159 self._closeUI(wid)
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
160 if cleaning_cb is not None:
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
161 cleaning_cb()
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
162
86
c711be670ecd core, chat: upload plugin system:
Goffi <goffi@goffi.org>
parents: 85
diff changeset
163 def _closeUI(self, wid):
c711be670ecd core, chat: upload plugin system:
Goffi <goffi@goffi.org>
parents: 85
diff changeset
164 G.host.closeUI()
c711be670ecd core, chat: upload plugin system:
Goffi <goffi@goffi.org>
parents: 85
diff changeset
165
197
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
166 def do_callback(self, *args, **kwargs):
312
772c170b47a9 Python3 port:
Goffi <goffi@goffi.org>
parents: 302
diff changeset
167 log.warning("callback not implemented")
197
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
168
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
169
376
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
170 class ExtraMenuItem(Button):
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
171 pass
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
172
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
173
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
174 class ExtraSideMenu(SideMenu):
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
175 """Menu with general app actions like showing the about widget"""
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
176
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
177 def __init__(self, **kwargs):
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
178 super().__init__(**kwargs)
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
179 G.local_platform.on_extra_menu_init(self)
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
180
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
181 def addItem(self, label, callback):
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
182 self.add_widget(
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
183 ExtraMenuItem(
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
184 text=label,
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
185 on_press=partial(self.onItemPress, callback=callback),
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
186 ),
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
187 # we want the new item above "About" and last empty Widget
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
188 index=2)
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
189
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
190 def onItemPress(self, *args, callback):
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
191 self.hide()
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
192 callback()
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
193
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
194 def onAbout(self):
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
195 self.hide()
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
196 about = AboutPopup()
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
197 about.title = ABOUT_TITLE
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
198 about.content = AboutContent(
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
199 text=ABOUT_CONTENT.format(
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
200 backend_version = G.host.backend_version,
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
201 version=G.host.version),
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
202 markup=True)
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
203 about.open()
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
204
9ef01266e3fe core: new extra menu:
Goffi <goffi@goffi.org>
parents: 373
diff changeset
205
197
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
206 class TransferMenu(SideMenu):
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
207 """transfer menu which handle display and callbacks"""
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
208 # callback will be called with path to file to transfer
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
209 # profiles if set will be sent to transfer widget, may be used to get specific files
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
210 profiles = properties.ObjectProperty()
312
772c170b47a9 Python3 port:
Goffi <goffi@goffi.org>
parents: 302
diff changeset
211 transfer_txt = _("Beware! The file will be sent to your server and stay unencrypted "
772c170b47a9 Python3 port:
Goffi <goffi@goffi.org>
parents: 302
diff changeset
212 "there\nServer admin(s) can see the file, and they choose how, "
772c170b47a9 Python3 port:
Goffi <goffi@goffi.org>
parents: 302
diff changeset
213 "when and if it will be deleted")
772c170b47a9 Python3 port:
Goffi <goffi@goffi.org>
parents: 302
diff changeset
214 send_txt = _("The file will be sent unencrypted directly to your contact "
772c170b47a9 Python3 port:
Goffi <goffi@goffi.org>
parents: 302
diff changeset
215 "(without transiting by the server), except in some cases")
197
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
216 items_layout = properties.ObjectProperty()
216
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
217 size_hint_close = (1, 0)
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
218 size_hint_open = (1, 0.5)
197
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
219
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
220 def __init__(self, **kwargs):
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
221 super(TransferMenu, self).__init__(**kwargs)
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
222 if self.profiles is None:
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
223 self.profiles = iter(G.host.profiles)
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
224 for plug_info in G.host.getPluggedWidgets(type_=C.PLUG_TYPE_TRANSFER):
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
225 item = TransferItem(
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
226 plug_info = plug_info
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
227 )
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
228 self.items_layout.add_widget(item)
86
c711be670ecd core, chat: upload plugin system:
Goffi <goffi@goffi.org>
parents: 85
diff changeset
229
400
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
230 def _onTransferCb(self, file_path, external, wid_cont, cleaning_cb=None):
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
231 if not external:
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
232 wid = wid_cont[0]
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
233 self._closeUI(wid)
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
234 self.callback(
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
235 file_path,
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
236 transfer_type = (C.TRANSFER_UPLOAD
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
237 if self.ids['upload_btn'].state == "down" else C.TRANSFER_SEND),
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
238 cleaning_cb=cleaning_cb,
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
239 )
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
240
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
241 def _check_plugin_permissions_cb(self, plug_info):
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
242 external = plug_info.get('external', False)
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
243 wid_cont = []
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
244 wid_cont.append(plug_info['factory'](
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
245 plug_info,
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
246 partial(self._onTransferCb, external=external, wid_cont=wid_cont),
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
247 self.cancel_cb,
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
248 self.profiles))
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
249 if not external:
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
250 G.host.showExtraUI(wid_cont[0])
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
251
86
c711be670ecd core, chat: upload plugin system:
Goffi <goffi@goffi.org>
parents: 85
diff changeset
252 def do_callback(self, plug_info):
97
5d2289127bb7 menu (upload): better menu using dedicated widget:
Goffi <goffi@goffi.org>
parents: 88
diff changeset
253 self.parent.remove_widget(self)
86
c711be670ecd core, chat: upload plugin system:
Goffi <goffi@goffi.org>
parents: 85
diff changeset
254 if self.callback is None:
312
772c170b47a9 Python3 port:
Goffi <goffi@goffi.org>
parents: 302
diff changeset
255 log.warning("TransferMenu callback is not set")
86
c711be670ecd core, chat: upload plugin system:
Goffi <goffi@goffi.org>
parents: 85
diff changeset
256 else:
400
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
257 G.local_platform.check_plugin_permissions(
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
258 plug_info,
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
259 callback=partial(self._check_plugin_permissions_cb, plug_info),
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
260 errback=lambda: G.host.addNote(
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
261 _("permission refused"),
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
262 _("this transfer menu can't be used if you refuse the requested "
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
263 "permission"),
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
264 C.XMLUI_DATA_LVL_WARNING)
71f51198478c android: handle runtime permissions:
Goffi <goffi@goffi.org>
parents: 379
diff changeset
265 )
197
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
266
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
267
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
268 class EntitiesSelectorMenu(SideMenu, FilterBehavior):
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
269 """allow to select entities from roster"""
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
270 profiles = properties.ObjectProperty()
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
271 layout = properties.ObjectProperty()
312
772c170b47a9 Python3 port:
Goffi <goffi@goffi.org>
parents: 302
diff changeset
272 instructions = properties.StringProperty(_("Please select entities"))
197
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
273 filter_input = properties.ObjectProperty()
216
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
274 size_hint_close = (None, 1)
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
275 size_hint_open = (None, 1)
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
276 size_open = (dp(250), 100)
e42e0c45d384 core (menu): allow to specify size in SideMenu:
Goffi <goffi@goffi.org>
parents: 197
diff changeset
277 size_close = (0, 100)
197
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
278
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
279 def __init__(self, **kwargs):
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
280 super(EntitiesSelectorMenu, self).__init__(**kwargs)
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
281 self.filter_input.bind(text=self.do_filter_input)
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
282 if self.profiles is None:
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
283 self.profiles = iter(G.host.profiles)
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
284 for profile in self.profiles:
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
285 for jid_, jid_data in G.host.contact_lists[profile].all_iter:
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
286 jid_wid = JidToggle(
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
287 jid=jid_,
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
288 profile=profile)
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
289 self.layout.add_widget(jid_wid)
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
290
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
291 def do_callback(self):
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
292 if self.callback is not None:
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
293 jids = [c.jid for c in self.layout.children if c.state == 'down']
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
294 self.callback(jids)
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
295
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
296 def do_filter_input(self, filter_input, text):
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
297 self.layout.spacing = 0 if text else dp(5)
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
298 self.do_filter(self.layout.children,
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
299 text,
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
300 lambda c: c.jid,
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
301 width_cb=lambda c: c.width,
c7d15ef4bfa8 core (menu): new EntitiesSelectorMenu:
Goffi <goffi@goffi.org>
parents: 184
diff changeset
302 height_cb=lambda c: dp(70))
222
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
303
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
304
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
305 class TouchMenu(modernmenu.ModernMenu):
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
306 pass
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
307
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
308
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
309 class TouchMenuItemBehaviour(object):
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
310 """Class to use on every item where a menu may appear
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
311
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
312 main_wid attribute must be set to the class inheriting from TouchMenuBehaviour
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
313 do_item_action is the method called on simple click
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
314 getMenuChoices must return a list of menus for long press
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
315 menus there are dict as expected by ModernMenu
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
316 (translated text, index and callback)
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
317 """
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
318 main_wid = properties.ObjectProperty()
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
319 click_timeout = properties.NumericProperty(0.4)
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
320
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
321 def on_touch_down(self, touch):
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
322 if not self.collide_point(*touch.pos):
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
323 return
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
324 t = partial(self.open_menu, touch)
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
325 touch.ud['menu_timeout'] = t
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
326 Clock.schedule_once(t, self.click_timeout)
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
327 return super(TouchMenuItemBehaviour, self).on_touch_down(touch)
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
328
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
329 def do_item_action(self, touch):
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
330 pass
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
331
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
332 def on_touch_up(self, touch):
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
333 if touch.ud.get('menu_timeout'):
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
334 Clock.unschedule(touch.ud['menu_timeout'])
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
335 if self.collide_point(*touch.pos) and self.main_wid.menu is None:
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
336 self.do_item_action(touch)
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
337 return super(TouchMenuItemBehaviour, self).on_touch_up(touch)
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
338
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
339 def open_menu(self, touch, dt):
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
340 self.main_wid.open_menu(self, touch)
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
341 del touch.ud['menu_timeout']
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
342
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
343 def getMenuChoices(self):
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
344 """return choice adapted to selected item
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
345
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
346 @return (list[dict]): choices ad expected by ModernMenu
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
347 """
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
348 return []
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
349
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
350
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
351 class TouchMenuBehaviour(object):
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
352 """Class to handle a menu appearing on long press on items
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
353
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
354 classes using this behaviour need to have a float_layout property
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
355 pointing the main FloatLayout.
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
356 """
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
357 float_layout = properties.ObjectProperty()
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
358
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
359 def __init__(self, *args, **kwargs):
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
360 super(TouchMenuBehaviour, self).__init__(*args, **kwargs)
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
361 self.menu = None
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
362 self.menu_item = None
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
363
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
364 ## menu methods ##
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
365
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
366 def clean_fl_children(self, layout, children):
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
367 """insure that self.menu and self.menu_item are None when menu is dimissed"""
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
368 if self.menu is not None and self.menu not in children:
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
369 self.menu = self.menu_item = None
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
370
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
371 def clear_menu(self):
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
372 """remove menu if there is one"""
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
373 if self.menu is not None:
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
374 self.menu.dismiss()
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
375 self.menu = None
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
376 self.menu_item = None
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
377
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
378 def open_menu(self, item, touch):
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
379 """open menu for item
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
380
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
381 @param item(PathWidget): item when the menu has been requested
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
382 @param touch(kivy.input.MotionEvent): touch data
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
383 """
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
384 if self.menu_item == item:
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
385 return
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
386 self.clear_menu()
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
387 pos = self.to_widget(*touch.pos)
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
388 choices = item.getMenuChoices()
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
389 if not choices:
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
390 return
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
391 self.menu = TouchMenu(choices=choices,
365
9c6fe392d623 core (widgets_handler): use a StencilView + BoxLayout instead of ScrollView as wrapper:
Goffi <goffi@goffi.org>
parents: 327
diff changeset
392 center=pos,
9c6fe392d623 core (widgets_handler): use a StencilView + BoxLayout instead of ScrollView as wrapper:
Goffi <goffi@goffi.org>
parents: 327
diff changeset
393 size_hint=(None, None))
222
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
394 self.float_layout.add_widget(self.menu)
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
395 self.menu.start_display(touch)
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
396 self.menu_item = item
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
397
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
398 def on_float_layout(self, wid, float_layout):
a676cb07c1cb core (menu): TouchMenuBehaviour:
Goffi <goffi@goffi.org>
parents: 216
diff changeset
399 float_layout.bind(children=self.clean_fl_children)