Mercurial > libervia-desktop-kivy
annotate cagou/core/widgets_handler.py @ 171:27b4ceb977c7
widgets handler: keep proportion on resize
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 29 Apr 2018 13:10:14 +0200 |
parents | f4522b7c3318 |
children | 9835cafbd909 |
rev | line source |
---|---|
13 | 1 #!/usr/bin/python |
2 # -*- coding: utf-8 -*- | |
3 | |
4 # Cagou: desktop/mobile frontend for Salut à Toi XMPP client | |
126 | 5 # Copyright (C) 2016-2018 Jérôme Poisson (goffi@goffi.org) |
13 | 6 |
7 # This program is free software: you can redistribute it and/or modify | |
8 # it under the terms of the GNU Affero General Public License as published by | |
9 # the Free Software Foundation, either version 3 of the License, or | |
10 # (at your option) any later version. | |
11 | |
12 # This program is distributed in the hope that it will be useful, | |
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 # GNU Affero General Public License for more details. | |
16 | |
17 # You should have received a copy of the GNU Affero General Public License | |
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | |
20 | |
21 from sat.core import log as logging | |
22 log = logging.getLogger(__name__) | |
154 | 23 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
|
24 from sat_frontends.quick_frontend import quick_widgets |
154 | 25 from kivy.graphics import Color, Ellipse |
26 from kivy.uix.layout import Layout | |
13 | 27 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
|
28 from kivy.uix.stencilview import StencilView |
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 |
13 | 32 |
163
ef09dce878c7
widgets handler: removed constants which are not used anymore
Goffi <goffi@goffi.org>
parents:
160
diff
changeset
|
33 |
154 | 34 REMOVE_WID_LIMIT = dp(10) |
35 MIN_WIDTH = MIN_HEIGHT = dp(50) | |
13 | 36 |
37 | |
154 | 38 class WHWrapper(BoxLayout): |
39 carousel = properties.ObjectProperty(None) | |
40 split_size = properties.NumericProperty(dp(1)) | |
41 split_margin = properties.NumericProperty(dp(2)) | |
42 split_color = properties.ListProperty([0.8, 0.8, 0.8, 1]) | |
43 split_color_move = properties.ListProperty([0.0, 0.8, 0.8, 1]) | |
44 split_color_del = properties.ListProperty([0.8, 0.0, 0.0, 1]) | |
45 # sp stands for "split point" | |
46 sp_size = properties.NumericProperty(dp(1)) | |
47 sp_space = properties.NumericProperty(dp(4)) | |
48 sp_zone = properties.NumericProperty(dp(30)) | |
49 _split = properties.OptionProperty('None', options=['None', 'left', 'top']) | |
50 _split_del = properties.BooleanProperty(False) | |
51 | |
52 def __init__(self, **kwargs): | |
53 idx = kwargs.pop('_wid_idx') | |
54 self._wid_idx = idx | |
55 super(WHWrapper, self).__init__(**kwargs) | |
56 self._former_slide = None | |
57 self.carousel.bind(current_slide=self.onSlideChange) | |
58 self._slides_update_lock = False | |
59 self._left_wids = set() | |
60 self._top_wids = set() | |
61 self._right_wids = set() | |
62 self._bottom_wids = set() | |
63 | |
64 def __repr__(self): | |
65 return "WHWrapper_{idx}".format(idx=self._wid_idx) | |
66 | |
67 def _main_wid(self, wid_list): | |
68 """return main widget of a side list | |
69 | |
70 main widget is either the widget currently splitter | |
71 or any widget if none is split | |
72 @return (WHWrapper, None): main widget or None | |
73 if there is not widget | |
74 """ | |
75 if not wid_list: | |
76 return None | |
77 for wid in wid_list: | |
78 if wid._split != 'None': | |
79 return wid | |
80 return next(iter(wid_list)) | |
81 | |
82 @property | |
83 def _left_wid(self): | |
84 return self._main_wid(self._left_wids) | |
85 | |
86 @property | |
87 def _top_wid(self): | |
88 return self._main_wid(self._top_wids) | |
89 | |
90 @property | |
91 def _right_wid(self): | |
92 return self._main_wid(self._right_wids) | |
93 | |
94 @property | |
95 def _bottom_wid(self): | |
96 return self._main_wid(self._bottom_wids) | |
13 | 97 |
154 | 98 @property |
99 def current_slide(self): | |
100 return self.carousel.current_slide | |
101 | |
102 def _draw_ellipse(self): | |
103 """draw split ellipse""" | |
104 color = self.split_color_del if self._split_del else self.split_color_move | |
105 try: | |
106 self.canvas.after.remove(self.ellipse) | |
107 except AttributeError: | |
108 pass | |
109 if self._split == "top": | |
110 with self.canvas.after: | |
111 Color(*color) | |
112 self.ellipse = Ellipse(angle_start=90, angle_end=270, | |
113 pos=(self.x + self.width/2 - self.sp_zone/2, | |
114 self.y + self.height - self.sp_zone/2), | |
115 size=(self.sp_zone, self.sp_zone)) | |
116 elif self._split == "left": | |
117 with self.canvas.after: | |
118 Color(*color) | |
119 self.ellipse = Ellipse(angle_end=180, | |
120 pos=(self.x + -self.sp_zone/2, | |
121 self.y + self.height/2 - self.sp_zone/2), | |
122 size = (self.sp_zone, self.sp_zone)) | |
123 else: | |
124 raise exceptions.InternalError('unexpected split value') | |
13 | 125 |
154 | 126 def on_touch_down(self, touch): |
127 """activate split if touch is on a split zone""" | |
128 if not self.collide_point(*touch.pos): | |
129 return | |
130 log.debug("WIDGET IDX: {} (left: {}, top: {}, right: {}, bottom: {}), pos: {}, size: {}".format( | |
131 self._wid_idx, | |
132 'None' if not self._left_wids else [w._wid_idx for w in self._left_wids], | |
133 'None' if not self._top_wids else [w._wid_idx for w in self._top_wids], | |
134 'None' if not self._right_wids else [w._wid_idx for w in self._right_wids], | |
135 'None' if not self._bottom_wids else [w._wid_idx for w in self._bottom_wids], | |
136 self.pos, | |
137 self.size, | |
138 )) | |
139 touch_rx, touch_ry = self.to_widget(*touch.pos, relative=True) | |
140 if (touch_ry <= self.height and | |
141 touch_ry >= self.height - self.split_size - self.split_margin or | |
142 touch_ry <= self.height and | |
143 touch_ry >= self.height - self.sp_zone and | |
144 touch_rx >= self.width/2 - self.sp_zone/2 and | |
145 touch_rx <= self.width/2 + self.sp_zone/2): | |
146 # split area is touched, we activate top split mode | |
147 self._split = "top" | |
148 self._draw_ellipse() | |
149 elif (touch_rx >= 0 and | |
150 touch_rx <= self.split_size + self.split_margin or | |
151 touch_rx >= 0 and | |
152 touch_rx <= self.sp_zone and | |
153 touch_ry >= self.height/2 - self.sp_zone/2 and | |
154 touch_ry <= self.height/2 + self.sp_zone/2): | |
155 # split area is touched, we activate left split mode | |
156 self._split = "left" | |
157 touch.ud['ori_width'] = self.width | |
158 self._draw_ellipse() | |
13 | 159 else: |
155
a0e486074d91
widget handler: block carousel swiping when there is only one slide
Goffi <goffi@goffi.org>
parents:
154
diff
changeset
|
160 if len(self.carousel.slides) == 1: |
a0e486074d91
widget handler: block carousel swiping when there is only one slide
Goffi <goffi@goffi.org>
parents:
154
diff
changeset
|
161 # we don't want swipe if there is only one slide |
a0e486074d91
widget handler: block carousel swiping when there is only one slide
Goffi <goffi@goffi.org>
parents:
154
diff
changeset
|
162 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
|
163 else: |
a0e486074d91
widget handler: block carousel swiping when there is only one slide
Goffi <goffi@goffi.org>
parents:
154
diff
changeset
|
164 return super(WHWrapper, self).on_touch_down(touch) |
13 | 165 |
166 def on_touch_move(self, touch): | |
154 | 167 """handle size change and widget creation on split""" |
168 if self._split == 'None': | |
169 return super(WHWrapper, self).on_touch_move(touch) | |
170 | |
171 elif self._split == 'top': | |
172 new_height = touch.y - self.y | |
173 | |
174 if new_height < MIN_HEIGHT: | |
175 return | |
176 | |
177 # we must not pass the top widget/border | |
178 if self._top_wids: | |
179 top = next(iter(self._top_wids)) | |
180 y_limit = top.y + top.height | |
181 | |
182 if top.height <= REMOVE_WID_LIMIT: | |
183 # 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
|
184 if not self._split_del and self._top_wids: |
154 | 185 self._split_del = True |
186 self._draw_ellipse() | |
187 else: | |
188 if self._split_del: | |
189 self._split_del = False | |
190 self._draw_ellipse() | |
191 else: | |
192 y_limit = self.y + self.height | |
193 | |
194 if touch.y >= y_limit: | |
195 return | |
196 | |
197 # all right, we can change size | |
198 self.height = new_height | |
199 self.ellipse.pos = (self.ellipse.pos[0], touch.y - self.sp_zone/2) | |
200 | |
201 if not self._top_wids: | |
202 # we are the last widget on the top | |
203 # so we create a new widget | |
204 new_wid = self.parent.add_widget() | |
205 self._top_wids.add(new_wid) | |
206 new_wid._bottom_wids.add(self) | |
207 for w in self._right_wids: | |
208 new_wid._right_wids.add(w) | |
209 w._left_wids.add(new_wid) | |
210 for w in self._left_wids: | |
211 new_wid._left_wids.add(w) | |
212 w._right_wids.add(new_wid) | |
13 | 213 |
154 | 214 elif self._split == 'left': |
215 ori_width = touch.ud['ori_width'] | |
216 new_x = touch.x | |
217 new_width = ori_width - (touch.x - touch.ox) | |
218 | |
219 if new_width < MIN_WIDTH: | |
220 return | |
221 | |
222 # we must not pass the left widget/border | |
223 if self._left_wids: | |
224 left = next(iter(self._left_wids)) | |
225 x_limit = left.x | |
226 | |
227 if left.width <= REMOVE_WID_LIMIT: | |
228 # 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
|
229 if not self._split_del and self._left_wids: |
154 | 230 self._split_del = True |
231 self._draw_ellipse() | |
232 else: | |
233 if self._split_del: | |
234 self._split_del = False | |
235 self._draw_ellipse() | |
236 else: | |
237 x_limit = self.x | |
238 | |
239 if new_x <= x_limit: | |
240 return | |
241 | |
242 # all right, we can change position/size | |
243 self.x = new_x | |
244 self.width = new_width | |
245 self.ellipse.pos = (touch.x - self.sp_zone/2, self.ellipse.pos[1]) | |
246 | |
247 if not self._left_wids: | |
248 # we are the last widget on the left | |
249 # so we create a new widget | |
250 new_wid = self.parent.add_widget() | |
251 self._left_wids.add(new_wid) | |
252 new_wid._right_wids.add(self) | |
253 for w in self._top_wids: | |
254 new_wid._top_wids.add(w) | |
255 w._bottom_wids.add(new_wid) | |
256 for w in self._bottom_wids: | |
257 new_wid._bottom_wids.add(w) | |
258 w._top_wids.add(new_wid) | |
259 | |
260 else: | |
261 raise Exception.InternalError('invalid _split value') | |
13 | 262 |
263 def on_touch_up(self, touch): | |
154 | 264 if self._split == 'None': |
265 return super(WHWrapper, self).on_touch_up(touch) | |
266 if self._split == 'top': | |
267 # we remove all top widgets in delete zone, | |
268 # and update there side widgets list | |
269 for top in self._top_wids.copy(): | |
270 if top.height <= REMOVE_WID_LIMIT: | |
271 for w in top._top_wids: | |
272 w._bottom_wids.remove(top) | |
273 w._bottom_wids.update(top._bottom_wids) | |
274 for w in top._bottom_wids: | |
275 w._top_wids.remove(top) | |
276 w._top_wids.update(top._top_wids) | |
277 for w in top._left_wids: | |
278 w._right_wids.remove(top) | |
279 for w in top._right_wids: | |
280 w._left_wids.remove(top) | |
281 self.parent.remove_widget(top) | |
282 elif self._split == 'left': | |
283 # we remove all left widgets in delete zone, | |
284 # and update there side widgets list | |
285 for left in self._left_wids.copy(): | |
286 if left.width <= REMOVE_WID_LIMIT: | |
287 for w in left._left_wids: | |
288 w._right_wids.remove(left) | |
289 w._right_wids.update(left._right_wids) | |
290 for w in left._right_wids: | |
291 w._left_wids.remove(left) | |
292 w._left_wids.update(left._left_wids) | |
293 for w in left._top_wids: | |
294 w._bottom_wids.remove(left) | |
295 for w in left._bottom_wids: | |
296 w._top_wids.remove(left) | |
297 self.parent.remove_widget(left) | |
298 self._split = 'None' | |
299 self.canvas.after.remove(self.ellipse) | |
300 del self.ellipse | |
13 | 301 |
154 | 302 def set_widget(self, wid, index=0): |
303 self.carousel.add_widget(wid, index) | |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
304 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
305 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
|
306 """Change currently displayed widget |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
307 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
308 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
|
309 """ |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
310 # slides update need to be blocked to avoid the update in onSlideChange |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
311 # which would mess the removal of current widgets |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
312 self._slides_update_lock = True |
154 | 313 current = self.carousel.current_slide |
314 for w in self.carousel.slides: | |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
315 if w == current or w == new_widget: |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
316 continue |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
317 if isinstance(w, quick_widgets.QuickWidget): |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
318 G.host.widgets.deleteWidget(w) |
154 | 319 self.carousel.clear_widgets() |
320 self.carousel.add_widget(new_widget) | |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
321 self._slides_update_lock = False |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
322 self.updateHiddenSlides() |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
323 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
324 def onSlideChange(self, handler, new_slide): |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
325 if isinstance(self._former_slide, quick_widgets.QuickWidget): |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
326 G.host.removeVisibleWidget(self._former_slide) |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
327 self._former_slide = new_slide |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
328 if isinstance(new_slide, quick_widgets.QuickWidget): |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
329 G.host.addVisibleWidget(new_slide) |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
330 self.updateHiddenSlides() |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
331 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
332 def hiddenList(self, visible_list): |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
333 """return widgets of same class as holded one which are hidden |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
334 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
335 @param visible_list(list[QuickWidget]): widgets visible |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
336 @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
|
337 """ |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
338 added = [(w.targets, w.profiles) for w in visible_list] # we want to avoid recreated widgets |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
339 for w in G.host.widgets.getWidgets(self.current_slide.__class__, profiles=self.current_slide.profiles): |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
340 if w in visible_list or (w.targets, w.profiles) in added: |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
341 continue |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
342 yield w |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
343 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
344 def widgets_sort(self, widget): |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
345 """method used as key to sort the widgets |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
346 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
347 order of the widgets when changing slide is affected |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
348 @param widget(QuickWidget): widget to sort |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
349 @return: a value which will be used for sorting |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
350 """ |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
351 try: |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
352 return unicode(widget.target).lower() |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
353 except AttributeError: |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
354 return unicode(list(widget.targets)[0]).lower() |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
355 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
356 def updateHiddenSlides(self): |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
357 """adjust carousel slides according to visible widgets""" |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
358 if self._slides_update_lock: |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
359 return |
154 | 360 if not isinstance(self.carousel.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
|
361 return |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
362 # lock must be used here to avoid recursions |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
363 self._slides_update_lock = True |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
364 visible_list = G.host.getVisibleList(self.current_slide.__class__) |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
365 hidden = list(self.hiddenList(visible_list)) |
154 | 366 slides_sorted = sorted(hidden + [self.carousel.current_slide], key=self.widgets_sort) |
367 to_remove = set(self.carousel.slides).difference({self.carousel.current_slide}) | |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
368 for w in to_remove: |
154 | 369 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
|
370 if hidden: |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
371 # 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
|
372 # as the list will be updated on each new visible widget |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
373 current_idx = slides_sorted.index(self.current_slide) |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
374 try: |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
375 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
|
376 except IndexError: |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
377 next_slide = slides_sorted[0] |
154 | 378 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
|
379 if len(hidden)>1: |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
380 previous_slide = slides_sorted[current_idx-1] |
154 | 381 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
|
382 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
383 self._slides_update_lock = False |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
384 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
385 |
154 | 386 class WidgetsHandlerLayout(Layout): |
387 count = 0 | |
13 | 388 |
154 | 389 def __init__(self, **kwargs): |
390 super(WidgetsHandlerLayout, self).__init__(**kwargs) | |
171
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
391 self._layout_size = None # size used for the last layout |
154 | 392 fbind = self.fbind |
393 update = self._trigger_layout | |
394 fbind('children', update) | |
395 fbind('parent', update) | |
171
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
396 fbind('size', self.adjust_prop) |
154 | 397 fbind('pos', update) |
13 | 398 |
14 | 399 @property |
400 def default_widget(self): | |
16
ba14b596b90e
host can now be get as a global value:
Goffi <goffi@goffi.org>
parents:
15
diff
changeset
|
401 return G.host.default_wid['factory'](G.host.default_wid, None, None) |
14 | 402 |
171
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
403 def adjust_prop(self, handler, new_size): |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
404 """Adjust children proportion |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
405 |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
406 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
|
407 """ |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
408 if len(self.children) > 1: |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
409 old_width, old_height = self._layout_size |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
410 if not old_width or not old_height: |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
411 # we don't want division by zero |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
412 return self._trigger_layout(handler, new_size) |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
413 width_factor = float(self.width) / old_width |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
414 height_factor = float(self.height) / old_height |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
415 for child in self.children: |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
416 child.width *= width_factor |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
417 child.height *= height_factor |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
418 child.x *= width_factor |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
419 child.y *= height_factor |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
420 self._trigger_layout(handler, new_size) |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
421 |
154 | 422 def do_layout(self, *args): |
171
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
423 self._layout_size = self.size[:] |
154 | 424 for child in self.children: |
425 # XXX: left must be calculated before right and bottom before top | |
426 # because they are the pos, and are used to caculate size (right and top) | |
427 # left | |
428 left = child._left_wid | |
170
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
429 left_end_x = self.x-1 if left is None else left.right |
154 | 430 if child.x != left_end_x + 1 and child._split == "None": |
431 child.x = left_end_x + 1 | |
432 # right | |
433 right = child._right_wid | |
170
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
434 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
|
435 if child.right != right_x - 1: |
154 | 436 child.width = right_x - child.x - 1 |
437 # bottom | |
438 bottom = child._bottom_wid | |
439 if bottom is None: | |
170
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
440 if child.y != self.y: |
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
441 child.y = self.y |
154 | 442 else: |
170
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
443 if child.y != bottom.top + 1: |
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
444 child.y = bottom.top + 1 |
154 | 445 # top |
446 top = child._top_wid | |
170
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
447 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
|
448 if child.top != top_y - 1: |
154 | 449 if child._split == "None": |
450 child.height = top_y - child.y - 1 | |
451 | |
452 def remove_widget(self, wid): | |
453 super(WidgetsHandlerLayout, self).remove_widget(wid) | |
454 log.debug("widget deleted ({})".format(wid._wid_idx)) | |
455 | |
456 def add_widget(self, wid=None, index=0): | |
457 WidgetsHandlerLayout.count += 1 | |
458 if wid is None: | |
459 wid = self.default_widget | |
460 wrapper = WHWrapper(_wid_idx=WidgetsHandlerLayout.count) | |
461 log.debug("WHWrapper created ({})".format(wrapper._wid_idx)) | |
462 wrapper.set_widget(wid) | |
463 super(WidgetsHandlerLayout, self).add_widget(wrapper, index) | |
464 return wrapper | |
465 | |
466 | |
467 class WidgetsHandler(WidgetsHandlerLayout): | |
468 | |
469 def __init__(self, **kw): | |
470 super(WidgetsHandler, self).__init__(**kw) | |
471 self.wrapper = self.add_widget() | |
472 | |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
473 @property |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
474 def cagou_widget(self): |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
475 """get holded CagouWidget""" |
154 | 476 return self.wrapper.current_slide |