Mercurial > libervia-desktop-kivy
annotate cagou/core/widgets_handler.py @ 448:20a807443c3f
chat: resize attachments (images only for now):
if attachments to send contain oversized image, a checkbox will be shown (activated by
default) to reduce automatically the size.
The background color now cover the whole attachments to send widget.
If not already specified, media type is guessed from filename when adding an attachment.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 22 Mar 2020 14:10:59 +0100 |
parents | 84ff5c917064 |
children | 3c9ba4a694ef |
rev | line source |
---|---|
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
1 #!/usr/bin/env python3 |
13 | 2 |
3 # Cagou: desktop/mobile frontend for Salut à Toi XMPP client | |
378 | 4 # Copyright (C) 2016-2020 Jérôme Poisson (goffi@goffi.org) |
13 | 5 |
6 # This program is free software: you can redistribute it and/or modify | |
7 # it under the terms of the GNU Affero General Public License as published by | |
8 # the Free Software Foundation, either version 3 of the License, or | |
9 # (at your option) any later version. | |
10 | |
11 # This program is distributed in the hope that it will be useful, | |
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 # GNU Affero General Public License for more details. | |
15 | |
16 # You should have received a copy of the GNU Affero General Public License | |
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 | |
19 | |
20 from sat.core import log as logging | |
154 | 21 from sat.core import exceptions |
34
02acbb297a61
handler, widget: deleteWidget is now properly called when a QuickWidget is deleted
Goffi <goffi@goffi.org>
parents:
16
diff
changeset
|
22 from sat_frontends.quick_frontend import quick_widgets |
154 | 23 from kivy.graphics import Color, Ellipse |
24 from kivy.uix.layout import Layout | |
13 | 25 from kivy.uix.boxlayout import BoxLayout |
155
a0e486074d91
widget handler: block carousel swiping when there is only one slide
Goffi <goffi@goffi.org>
parents:
154
diff
changeset
|
26 from kivy.uix.stencilview import StencilView |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
27 from kivy.uix.carousel import Carousel |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
28 from kivy.uix.screenmanager import ScreenManager, Screen |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
29 from kivy.metrics import dp |
13 | 30 from kivy import properties |
16
ba14b596b90e
host can now be get as a global value:
Goffi <goffi@goffi.org>
parents:
15
diff
changeset
|
31 from cagou import G |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
32 from .constants import Const as C |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
33 from . import cagou_widget |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
34 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
35 log = logging.getLogger(__name__) |
13 | 36 |
163
ef09dce878c7
widgets handler: removed constants which are not used anymore
Goffi <goffi@goffi.org>
parents:
160
diff
changeset
|
37 |
269
a5dfc789eeaf
widgets_handler: increased remove limit and min height/width:
Goffi <goffi@goffi.org>
parents:
263
diff
changeset
|
38 REMOVE_WID_LIMIT = dp(50) |
a5dfc789eeaf
widgets_handler: increased remove limit and min height/width:
Goffi <goffi@goffi.org>
parents:
263
diff
changeset
|
39 MIN_WIDTH = MIN_HEIGHT = dp(70) |
13 | 40 |
41 | |
365
9c6fe392d623
core (widgets_handler): use a StencilView + BoxLayout instead of ScrollView as wrapper:
Goffi <goffi@goffi.org>
parents:
362
diff
changeset
|
42 class BoxStencil(BoxLayout, StencilView): |
9c6fe392d623
core (widgets_handler): use a StencilView + BoxLayout instead of ScrollView as wrapper:
Goffi <goffi@goffi.org>
parents:
362
diff
changeset
|
43 pass |
9c6fe392d623
core (widgets_handler): use a StencilView + BoxLayout instead of ScrollView as wrapper:
Goffi <goffi@goffi.org>
parents:
362
diff
changeset
|
44 |
9c6fe392d623
core (widgets_handler): use a StencilView + BoxLayout instead of ScrollView as wrapper:
Goffi <goffi@goffi.org>
parents:
362
diff
changeset
|
45 |
154 | 46 class WHWrapper(BoxLayout): |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
47 main_container = properties.ObjectProperty(None) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
48 screen_manager = properties.ObjectProperty(None, allownone=True) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
49 carousel = properties.ObjectProperty(None, allownone=True) |
154 | 50 split_size = properties.NumericProperty(dp(1)) |
51 split_margin = properties.NumericProperty(dp(2)) | |
52 split_color = properties.ListProperty([0.8, 0.8, 0.8, 1]) | |
177
9835cafbd909
widgets handler: use dark secondary color for split
Goffi <goffi@goffi.org>
parents:
171
diff
changeset
|
53 split_color_move = C.COLOR_SEC_DARK |
154 | 54 split_color_del = properties.ListProperty([0.8, 0.0, 0.0, 1]) |
55 # sp stands for "split point" | |
56 sp_size = properties.NumericProperty(dp(1)) | |
57 sp_space = properties.NumericProperty(dp(4)) | |
58 sp_zone = properties.NumericProperty(dp(30)) | |
59 _split = properties.OptionProperty('None', options=['None', 'left', 'top']) | |
60 _split_del = properties.BooleanProperty(False) | |
61 | |
62 def __init__(self, **kwargs): | |
63 idx = kwargs.pop('_wid_idx') | |
64 self._wid_idx = idx | |
65 super(WHWrapper, self).__init__(**kwargs) | |
66 self._left_wids = set() | |
67 self._top_wids = set() | |
68 self._right_wids = set() | |
69 self._bottom_wids = set() | |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
70 self._clear_attributes() |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
71 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
72 def _clear_attributes(self): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
73 self._former_slide = None |
154 | 74 |
75 def __repr__(self): | |
76 return "WHWrapper_{idx}".format(idx=self._wid_idx) | |
77 | |
78 def _main_wid(self, wid_list): | |
79 """return main widget of a side list | |
80 | |
263
fe540a6dc14d
widgets handler: call host._removeVisibleWidget when a widget is deleted (using split)
Goffi <goffi@goffi.org>
parents:
260
diff
changeset
|
81 main widget is either the widget currently splitted |
154 | 82 or any widget if none is split |
83 @return (WHWrapper, None): main widget or None | |
84 if there is not widget | |
85 """ | |
86 if not wid_list: | |
87 return None | |
88 for wid in wid_list: | |
89 if wid._split != 'None': | |
90 return wid | |
91 return next(iter(wid_list)) | |
92 | |
355
8b6621cc142c
core (widgets handler): clear widgets when WHWrapper is detached:
Goffi <goffi@goffi.org>
parents:
353
diff
changeset
|
93 def on_parent(self, __, new_parent): |
8b6621cc142c
core (widgets handler): clear widgets when WHWrapper is detached:
Goffi <goffi@goffi.org>
parents:
353
diff
changeset
|
94 if new_parent is None: |
8b6621cc142c
core (widgets handler): clear widgets when WHWrapper is detached:
Goffi <goffi@goffi.org>
parents:
353
diff
changeset
|
95 # we detach all children so CagouWidget.whwrapper won't link to this one |
8b6621cc142c
core (widgets handler): clear widgets when WHWrapper is detached:
Goffi <goffi@goffi.org>
parents:
353
diff
changeset
|
96 # anymore |
8b6621cc142c
core (widgets handler): clear widgets when WHWrapper is detached:
Goffi <goffi@goffi.org>
parents:
353
diff
changeset
|
97 self.clear_widgets() |
8b6621cc142c
core (widgets handler): clear widgets when WHWrapper is detached:
Goffi <goffi@goffi.org>
parents:
353
diff
changeset
|
98 |
154 | 99 @property |
100 def _left_wid(self): | |
101 return self._main_wid(self._left_wids) | |
102 | |
103 @property | |
104 def _top_wid(self): | |
105 return self._main_wid(self._top_wids) | |
106 | |
107 @property | |
108 def _right_wid(self): | |
109 return self._main_wid(self._right_wids) | |
110 | |
111 @property | |
112 def _bottom_wid(self): | |
113 return self._main_wid(self._bottom_wids) | |
13 | 114 |
154 | 115 @property |
116 def current_slide(self): | |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
117 if (self.carousel is not None |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
118 and (self.screen_manager is None or self.screen_manager.current == '')): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
119 return self.carousel.current_slide |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
120 elif self.screen_manager is not None: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
121 # we should have exactly one children in current_screen, else there is a bug |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
122 return self.screen_manager.current_screen.children[0] |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
123 else: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
124 try: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
125 return self.main_container.children[0] |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
126 except IndexError: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
127 log.error("No child found, this should not happen") |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
128 return None |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
129 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
130 @property |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
131 def carousel_active(self): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
132 """Return True if Carousel is used and active""" |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
133 if self.carousel is None: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
134 return False |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
135 if self.screen_manager is not None and self.screen_manager.current != '': |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
136 return False |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
137 return True |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
138 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
139 @property |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
140 def former_screen_wid(self): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
141 """Return widget currently active for former screen""" |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
142 if self.screen_manager is None: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
143 raise exceptions.InternalError( |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
144 "former_screen_wid can only be used if ScreenManager is used") |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
145 if self._former_screen_name is None: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
146 return None |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
147 return self.getScreenWidget(self._former_screen_name) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
148 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
149 def getScreenWidget(self, screen_name): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
150 """Return screen main widget, handling carousel if necessary""" |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
151 if self.carousel is not None and screen_name == '': |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
152 return self.carousel.current_slide |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
153 try: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
154 return self.screen_manager.get_screen(screen_name).children[0] |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
155 except IndexError: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
156 return None |
154 | 157 |
158 def _draw_ellipse(self): | |
159 """draw split ellipse""" | |
160 color = self.split_color_del if self._split_del else self.split_color_move | |
161 try: | |
162 self.canvas.after.remove(self.ellipse) | |
163 except AttributeError: | |
164 pass | |
165 if self._split == "top": | |
166 with self.canvas.after: | |
167 Color(*color) | |
168 self.ellipse = Ellipse(angle_start=90, angle_end=270, | |
169 pos=(self.x + self.width/2 - self.sp_zone/2, | |
170 self.y + self.height - self.sp_zone/2), | |
171 size=(self.sp_zone, self.sp_zone)) | |
172 elif self._split == "left": | |
173 with self.canvas.after: | |
174 Color(*color) | |
175 self.ellipse = Ellipse(angle_end=180, | |
176 pos=(self.x + -self.sp_zone/2, | |
177 self.y + self.height/2 - self.sp_zone/2), | |
178 size = (self.sp_zone, self.sp_zone)) | |
179 else: | |
180 raise exceptions.InternalError('unexpected split value') | |
13 | 181 |
154 | 182 def on_touch_down(self, touch): |
183 """activate split if touch is on a split zone""" | |
184 if not self.collide_point(*touch.pos): | |
185 return | |
186 log.debug("WIDGET IDX: {} (left: {}, top: {}, right: {}, bottom: {}), pos: {}, size: {}".format( | |
187 self._wid_idx, | |
188 'None' if not self._left_wids else [w._wid_idx for w in self._left_wids], | |
189 'None' if not self._top_wids else [w._wid_idx for w in self._top_wids], | |
190 'None' if not self._right_wids else [w._wid_idx for w in self._right_wids], | |
191 'None' if not self._bottom_wids else [w._wid_idx for w in self._bottom_wids], | |
192 self.pos, | |
193 self.size, | |
194 )) | |
195 touch_rx, touch_ry = self.to_widget(*touch.pos, relative=True) | |
196 if (touch_ry <= self.height and | |
197 touch_ry >= self.height - self.split_size - self.split_margin or | |
198 touch_ry <= self.height and | |
199 touch_ry >= self.height - self.sp_zone and | |
300
efd3fbc85aaf
core (widgets_handler): use explicit floor division to avoid warnings.
Goffi <goffi@goffi.org>
parents:
282
diff
changeset
|
200 touch_rx >= self.width//2 - self.sp_zone//2 and |
efd3fbc85aaf
core (widgets_handler): use explicit floor division to avoid warnings.
Goffi <goffi@goffi.org>
parents:
282
diff
changeset
|
201 touch_rx <= self.width//2 + self.sp_zone//2): |
154 | 202 # split area is touched, we activate top split mode |
203 self._split = "top" | |
204 self._draw_ellipse() | |
205 elif (touch_rx >= 0 and | |
206 touch_rx <= self.split_size + self.split_margin or | |
207 touch_rx >= 0 and | |
208 touch_rx <= self.sp_zone and | |
300
efd3fbc85aaf
core (widgets_handler): use explicit floor division to avoid warnings.
Goffi <goffi@goffi.org>
parents:
282
diff
changeset
|
209 touch_ry >= self.height//2 - self.sp_zone//2 and |
efd3fbc85aaf
core (widgets_handler): use explicit floor division to avoid warnings.
Goffi <goffi@goffi.org>
parents:
282
diff
changeset
|
210 touch_ry <= self.height//2 + self.sp_zone//2): |
154 | 211 # split area is touched, we activate left split mode |
212 self._split = "left" | |
213 touch.ud['ori_width'] = self.width | |
214 self._draw_ellipse() | |
13 | 215 else: |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
216 if self.carousel_active and len(self.carousel.slides) <= 1: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
217 # we don't want swipe of carousel if there is only one slide |
155
a0e486074d91
widget handler: block carousel swiping when there is only one slide
Goffi <goffi@goffi.org>
parents:
154
diff
changeset
|
218 return StencilView.on_touch_down(self.carousel, touch) |
a0e486074d91
widget handler: block carousel swiping when there is only one slide
Goffi <goffi@goffi.org>
parents:
154
diff
changeset
|
219 else: |
a0e486074d91
widget handler: block carousel swiping when there is only one slide
Goffi <goffi@goffi.org>
parents:
154
diff
changeset
|
220 return super(WHWrapper, self).on_touch_down(touch) |
13 | 221 |
222 def on_touch_move(self, touch): | |
154 | 223 """handle size change and widget creation on split""" |
224 if self._split == 'None': | |
225 return super(WHWrapper, self).on_touch_move(touch) | |
226 | |
227 elif self._split == 'top': | |
228 new_height = touch.y - self.y | |
229 | |
230 if new_height < MIN_HEIGHT: | |
231 return | |
232 | |
233 # we must not pass the top widget/border | |
234 if self._top_wids: | |
235 top = next(iter(self._top_wids)) | |
236 y_limit = top.y + top.height | |
237 | |
238 if top.height <= REMOVE_WID_LIMIT: | |
239 # we are in remove zone, we add visual hint for that | |
160
916af9c1cb9b
widget handler: don't set split delete mode if there is not top/left widget
Goffi <goffi@goffi.org>
parents:
155
diff
changeset
|
240 if not self._split_del and self._top_wids: |
154 | 241 self._split_del = True |
242 self._draw_ellipse() | |
243 else: | |
244 if self._split_del: | |
245 self._split_del = False | |
246 self._draw_ellipse() | |
247 else: | |
248 y_limit = self.y + self.height | |
249 | |
250 if touch.y >= y_limit: | |
251 return | |
252 | |
253 # all right, we can change size | |
254 self.height = new_height | |
255 self.ellipse.pos = (self.ellipse.pos[0], touch.y - self.sp_zone/2) | |
256 | |
257 if not self._top_wids: | |
258 # we are the last widget on the top | |
259 # so we create a new widget | |
260 new_wid = self.parent.add_widget() | |
261 self._top_wids.add(new_wid) | |
262 new_wid._bottom_wids.add(self) | |
263 for w in self._right_wids: | |
264 new_wid._right_wids.add(w) | |
265 w._left_wids.add(new_wid) | |
266 for w in self._left_wids: | |
267 new_wid._left_wids.add(w) | |
268 w._right_wids.add(new_wid) | |
13 | 269 |
154 | 270 elif self._split == 'left': |
271 ori_width = touch.ud['ori_width'] | |
272 new_x = touch.x | |
273 new_width = ori_width - (touch.x - touch.ox) | |
274 | |
275 if new_width < MIN_WIDTH: | |
276 return | |
277 | |
278 # we must not pass the left widget/border | |
279 if self._left_wids: | |
280 left = next(iter(self._left_wids)) | |
281 x_limit = left.x | |
282 | |
283 if left.width <= REMOVE_WID_LIMIT: | |
284 # we are in remove zone, we add visual hint for that | |
160
916af9c1cb9b
widget handler: don't set split delete mode if there is not top/left widget
Goffi <goffi@goffi.org>
parents:
155
diff
changeset
|
285 if not self._split_del and self._left_wids: |
154 | 286 self._split_del = True |
287 self._draw_ellipse() | |
288 else: | |
289 if self._split_del: | |
290 self._split_del = False | |
291 self._draw_ellipse() | |
292 else: | |
293 x_limit = self.x | |
294 | |
295 if new_x <= x_limit: | |
296 return | |
297 | |
298 # all right, we can change position/size | |
299 self.x = new_x | |
300 self.width = new_width | |
301 self.ellipse.pos = (touch.x - self.sp_zone/2, self.ellipse.pos[1]) | |
302 | |
303 if not self._left_wids: | |
304 # we are the last widget on the left | |
305 # so we create a new widget | |
306 new_wid = self.parent.add_widget() | |
307 self._left_wids.add(new_wid) | |
308 new_wid._right_wids.add(self) | |
309 for w in self._top_wids: | |
310 new_wid._top_wids.add(w) | |
311 w._bottom_wids.add(new_wid) | |
312 for w in self._bottom_wids: | |
313 new_wid._bottom_wids.add(w) | |
314 w._top_wids.add(new_wid) | |
315 | |
316 else: | |
317 raise Exception.InternalError('invalid _split value') | |
13 | 318 |
319 def on_touch_up(self, touch): | |
154 | 320 if self._split == 'None': |
321 return super(WHWrapper, self).on_touch_up(touch) | |
322 if self._split == 'top': | |
323 # we remove all top widgets in delete zone, | |
324 # and update there side widgets list | |
325 for top in self._top_wids.copy(): | |
326 if top.height <= REMOVE_WID_LIMIT: | |
263
fe540a6dc14d
widgets handler: call host._removeVisibleWidget when a widget is deleted (using split)
Goffi <goffi@goffi.org>
parents:
260
diff
changeset
|
327 G.host._removeVisibleWidget(top.current_slide) |
154 | 328 for w in top._top_wids: |
329 w._bottom_wids.remove(top) | |
330 w._bottom_wids.update(top._bottom_wids) | |
331 for w in top._bottom_wids: | |
332 w._top_wids.remove(top) | |
333 w._top_wids.update(top._top_wids) | |
334 for w in top._left_wids: | |
335 w._right_wids.remove(top) | |
336 for w in top._right_wids: | |
337 w._left_wids.remove(top) | |
338 self.parent.remove_widget(top) | |
339 elif self._split == 'left': | |
340 # we remove all left widgets in delete zone, | |
341 # and update there side widgets list | |
342 for left in self._left_wids.copy(): | |
343 if left.width <= REMOVE_WID_LIMIT: | |
263
fe540a6dc14d
widgets handler: call host._removeVisibleWidget when a widget is deleted (using split)
Goffi <goffi@goffi.org>
parents:
260
diff
changeset
|
344 G.host._removeVisibleWidget(left.current_slide) |
154 | 345 for w in left._left_wids: |
346 w._right_wids.remove(left) | |
347 w._right_wids.update(left._right_wids) | |
348 for w in left._right_wids: | |
349 w._left_wids.remove(left) | |
350 w._left_wids.update(left._left_wids) | |
351 for w in left._top_wids: | |
352 w._bottom_wids.remove(left) | |
353 for w in left._bottom_wids: | |
354 w._top_wids.remove(left) | |
355 self.parent.remove_widget(left) | |
356 self._split = 'None' | |
357 self.canvas.after.remove(self.ellipse) | |
358 del self.ellipse | |
13 | 359 |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
360 def clear_widgets(self): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
361 current_slide = self.current_slide |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
362 if current_slide is not None: |
355
8b6621cc142c
core (widgets handler): clear widgets when WHWrapper is detached:
Goffi <goffi@goffi.org>
parents:
353
diff
changeset
|
363 G.host._removeVisibleWidget(current_slide, ignore_missing=True) |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
364 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
365 super().clear_widgets() |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
366 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
367 self.screen_manager = None |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
368 self.carousel = None |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
369 self._clear_attributes() |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
370 |
154 | 371 def set_widget(self, wid, index=0): |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
372 assert len(self.children) == 0 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
373 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
374 if wid.collection_carousel or wid.global_screen_manager: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
375 self.main_container = self |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
376 else: |
365
9c6fe392d623
core (widgets_handler): use a StencilView + BoxLayout instead of ScrollView as wrapper:
Goffi <goffi@goffi.org>
parents:
362
diff
changeset
|
377 self.main_container = BoxStencil() |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
378 self.add_widget(self.main_container) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
379 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
380 if self.carousel is not None: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
381 return self.carousel.add_widget(wid, index) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
382 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
383 if wid.global_screen_manager: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
384 if self.screen_manager is None: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
385 self.screen_manager = ScreenManager() |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
386 self.main_container.add_widget(self.screen_manager) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
387 parent = Screen() |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
388 self.screen_manager.add_widget(parent) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
389 self._former_screen_name = '' |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
390 self.screen_manager.bind(current=self.onScreenChange) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
391 wid.screenManagerInit(self.screen_manager) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
392 else: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
393 parent = self.main_container |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
394 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
395 if wid.collection_carousel: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
396 # a Carousel is requested, and this is the first widget that we add |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
397 # so we need to create the carousel |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
398 self.carousel = Carousel( |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
399 direction = "right", |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
400 ignore_perpendicular_swipes = True, |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
401 loop = True, |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
402 ) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
403 self._slides_update_lock = 0 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
404 self.carousel.bind(current_slide=self.onSlideChange) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
405 parent.add_widget(self.carousel) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
406 self.carousel.add_widget(wid, index) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
407 else: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
408 # no Carousel requested, we add the widget as a direct child |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
409 parent.add_widget(wid) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
410 G.host._addVisibleWidget(wid) |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
411 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
412 def changeWidget(self, new_widget): |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
413 """Change currently displayed widget |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
414 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
415 slides widgets will be updated |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
416 """ |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
417 if (self.carousel is not None |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
418 and self.carousel.current_slide.__class__ == new_widget.__class__): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
419 # we have the same class, we reuse carousel and screen manager setting |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
420 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
421 if self.carousel.current_slide != new_widget: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
422 # slides update need to be blocked to avoid the update in onSlideChange |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
423 # which would mess the removal of current widgets |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
424 self._slides_update_lock += 1 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
425 new_wid = None |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
426 for w in self.carousel.slides[:]: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
427 if w.widget_hash == new_widget.widget_hash: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
428 new_wid = w |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
429 continue |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
430 self.carousel.remove_widget(w) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
431 if isinstance(w, quick_widgets.QuickWidget): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
432 G.host.widgets.deleteWidget(w) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
433 if new_wid is None: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
434 new_wid = G.host.getOrClone(new_widget) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
435 self.carousel.add_widget(new_wid) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
436 self._updateHiddenSlides() |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
437 self._slides_update_lock -= 1 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
438 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
439 if self.screen_manager is not None: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
440 self.screen_manager.clear_widgets([ |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
441 s for s in self.screen_manager.screens if s.name != '']) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
442 new_wid.screenManagerInit(self.screen_manager) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
443 else: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
444 # else, we restart fresh |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
445 self.clear_widgets() |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
446 self.set_widget(G.host.getOrClone(new_widget)) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
447 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
448 def onScreenChange(self, screen_manager, new_screen): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
449 try: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
450 new_screen_wid = self.current_slide |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
451 except IndexError: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
452 new_screen_wid = None |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
453 log.warning("Switching to a screen without children") |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
454 if new_screen == '' and self.carousel is not None: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
455 # carousel may have been changed in the background, so we update slides |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
456 self._updateHiddenSlides() |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
457 former_screen_wid = self.former_screen_wid |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
458 if isinstance(former_screen_wid, cagou_widget.CagouWidget): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
459 G.host._removeVisibleWidget(former_screen_wid) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
460 if isinstance(new_screen_wid, cagou_widget.CagouWidget): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
461 G.host._addVisibleWidget(new_screen_wid) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
462 self._former_screen_name = new_screen |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
463 G.host.selected_widget = new_screen_wid |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
464 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
465 def onSlideChange(self, handler, new_slide): |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
466 if self._former_slide is new_slide: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
467 # FIXME: workaround for Kivy a95d67f (and above?), Carousel.current_slide |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
468 # binding now calls onSlideChange twice with the same widget (here |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
469 # "new_slide"). To be checked with Kivy team. |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
470 return |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
471 log.debug(f"Slide change: new_slide = {new_slide}") |
248
b6e33b35538b
core, widgets handler: visible_widgets now keep all CagouWidgets, not only QuickWidgets. visible_quick_widgets can be used if only QuickWidgets are desired.
Goffi <goffi@goffi.org>
parents:
177
diff
changeset
|
472 if self._former_slide is not None: |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
473 G.host._removeVisibleWidget(self._former_slide, ignore_missing=True) |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
474 self._former_slide = new_slide |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
475 if self.carousel_active: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
476 G.host.selected_widget = new_slide |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
477 if new_slide is not None: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
478 G.host._addVisibleWidget(new_slide) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
479 self._updateHiddenSlides() |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
480 |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
481 def hiddenList(self, visible_list, ignore=None): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
482 """return widgets of same class as carousel current one, if they are hidden |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
483 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
484 @param visible_list(list[QuickWidget]): widgets visible |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
485 @param ignore(QuickWidget, None): do no return this widget |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
486 @return (iter[QuickWidget]): widgets hidden |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
487 """ |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
488 # we want to avoid recreated widgets |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
489 added = [w.widget_hash for w in visible_list] |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
490 current_slide = self.carousel.current_slide |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
491 for w in G.host.widgets.getWidgets(current_slide.__class__, |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
492 profiles=current_slide.profiles): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
493 wid_hash = w.widget_hash |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
494 if w in visible_list or wid_hash in added: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
495 continue |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
496 if wid_hash == ignore.widget_hash: |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
497 continue |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
498 yield w |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
499 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
500 |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
501 def _updateHiddenSlides(self): |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
502 """adjust carousel slides according to visible widgets""" |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
503 if self._slides_update_lock or not self.carousel_active: |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
504 return |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
505 current_slide = self.carousel.current_slide |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
506 if not isinstance(current_slide, quick_widgets.QuickWidget): |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
507 return |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
508 # lock must be used here to avoid recursions |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
509 self._slides_update_lock += 1 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
510 visible_list = G.host.getVisibleList(current_slide.__class__) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
511 # we ignore current_slide as it may not be visible yet (e.g. if an other |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
512 # screen is shown |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
513 hidden = list(self.hiddenList(visible_list, ignore=current_slide)) |
405
84ff5c917064
widgets: implemented ordering in ContactItem and CagouWidget:
Goffi <goffi@goffi.org>
parents:
378
diff
changeset
|
514 slides_sorted = sorted(set(hidden + [current_slide])) |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
515 to_remove = set(self.carousel.slides).difference({current_slide}) |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
516 for w in to_remove: |
154 | 517 self.carousel.remove_widget(w) |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
518 if hidden: |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
519 # no need to add more than two widgets (next and previous), |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
520 # as the list will be updated on each new visible widget |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
521 current_idx = slides_sorted.index(current_slide) |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
522 try: |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
523 next_slide = slides_sorted[current_idx+1] |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
524 except IndexError: |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
525 next_slide = slides_sorted[0] |
154 | 526 self.carousel.add_widget(G.host.getOrClone(next_slide)) |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
527 if len(hidden)>1: |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
528 previous_slide = slides_sorted[current_idx-1] |
154 | 529 self.carousel.add_widget(G.host.getOrClone(previous_slide)) |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
530 |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
531 self._slides_update_lock -= 1 |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
532 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
533 |
154 | 534 class WidgetsHandlerLayout(Layout): |
535 count = 0 | |
13 | 536 |
154 | 537 def __init__(self, **kwargs): |
538 super(WidgetsHandlerLayout, self).__init__(**kwargs) | |
171
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
539 self._layout_size = None # size used for the last layout |
154 | 540 fbind = self.fbind |
541 update = self._trigger_layout | |
542 fbind('children', update) | |
543 fbind('parent', update) | |
171
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
544 fbind('size', self.adjust_prop) |
154 | 545 fbind('pos', update) |
13 | 546 |
14 | 547 @property |
548 def default_widget(self): | |
16
ba14b596b90e
host can now be get as a global value:
Goffi <goffi@goffi.org>
parents:
15
diff
changeset
|
549 return G.host.default_wid['factory'](G.host.default_wid, None, None) |
14 | 550 |
171
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
551 def adjust_prop(self, handler, new_size): |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
552 """Adjust children proportion |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
553 |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
554 useful when this widget is resized (e.g. when going to fullscreen) |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
555 """ |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
556 if len(self.children) > 1: |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
557 old_width, old_height = self._layout_size |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
558 if not old_width or not old_height: |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
559 # we don't want division by zero |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
560 return self._trigger_layout(handler, new_size) |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
561 width_factor = float(self.width) / old_width |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
562 height_factor = float(self.height) / old_height |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
563 for child in self.children: |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
564 child.width *= width_factor |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
565 child.height *= height_factor |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
566 child.x *= width_factor |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
567 child.y *= height_factor |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
568 self._trigger_layout(handler, new_size) |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
569 |
154 | 570 def do_layout(self, *args): |
171
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
571 self._layout_size = self.size[:] |
154 | 572 for child in self.children: |
573 # XXX: left must be calculated before right and bottom before top | |
574 # because they are the pos, and are used to caculate size (right and top) | |
575 # left | |
576 left = child._left_wid | |
170
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
577 left_end_x = self.x-1 if left is None else left.right |
154 | 578 if child.x != left_end_x + 1 and child._split == "None": |
579 child.x = left_end_x + 1 | |
580 # right | |
581 right = child._right_wid | |
170
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
582 right_x = self.right + 1 if right is None else right.x |
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
583 if child.right != right_x - 1: |
154 | 584 child.width = right_x - child.x - 1 |
585 # bottom | |
586 bottom = child._bottom_wid | |
587 if bottom is None: | |
170
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
588 if child.y != self.y: |
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
589 child.y = self.y |
154 | 590 else: |
170
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
591 if child.y != bottom.top + 1: |
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
592 child.y = bottom.top + 1 |
154 | 593 # top |
594 top = child._top_wid | |
170
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
595 top_y = self.top+1 if top is None else top.y |
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
596 if child.top != top_y - 1: |
154 | 597 if child._split == "None": |
598 child.height = top_y - child.y - 1 | |
599 | |
600 def remove_widget(self, wid): | |
601 super(WidgetsHandlerLayout, self).remove_widget(wid) | |
602 log.debug("widget deleted ({})".format(wid._wid_idx)) | |
603 | |
604 def add_widget(self, wid=None, index=0): | |
605 WidgetsHandlerLayout.count += 1 | |
606 if wid is None: | |
607 wid = self.default_widget | |
362
e1f56257cabc
core (widgets handler): use widget set in set_widget as selected_widget if selected_widget is None
Goffi <goffi@goffi.org>
parents:
355
diff
changeset
|
608 if G.host.selected_widget is None: |
e1f56257cabc
core (widgets handler): use widget set in set_widget as selected_widget if selected_widget is None
Goffi <goffi@goffi.org>
parents:
355
diff
changeset
|
609 G.host.selected_widget = wid |
154 | 610 wrapper = WHWrapper(_wid_idx=WidgetsHandlerLayout.count) |
611 log.debug("WHWrapper created ({})".format(wrapper._wid_idx)) | |
612 wrapper.set_widget(wid) | |
613 super(WidgetsHandlerLayout, self).add_widget(wrapper, index) | |
614 return wrapper | |
615 | |
616 | |
617 class WidgetsHandler(WidgetsHandlerLayout): | |
618 | |
619 def __init__(self, **kw): | |
620 super(WidgetsHandler, self).__init__(**kw) | |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
621 self.add_widget() |