Mercurial > libervia-desktop-kivy
annotate cagou/core/widgets_handler.py @ 353:19422bbd9c8e
core (widgets handler): refactoring:
- CagouWidget now has class properties (to be overridden when needed) which indicate how
if the widget handle must add a wrapping ScreenManager (global_screen_manager) or show
all instances of the class in a Carousel (collection_carousel). If none of those
options is used, a ScrollView will be wrapping the widget, to be sure that the widget
will be resized correctly when necessary (without it, the widget could still be
drawn in the backround when the size is too small and overflow on the WidgetWrapper,
this would be the case with WidgetSelector)
- some helper methods/properties have been added to CagouWidget. Check docstrings for
details
- better handling of (in)visible widget in WidgetsHandler
- thanks to the new wrapping ScrollView, WidgetSelect will show scroll bars if the
available space is too small.
- bugs fixes
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 17 Jan 2020 18:44:35 +0100 |
parents | 772c170b47a9 |
children | 8b6621cc142c |
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 | |
282 | 4 # Copyright (C) 2016-2019 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 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
29 from kivy.uix.scrollview import ScrollView |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
30 from kivy.metrics import dp |
13 | 31 from kivy import properties |
16
ba14b596b90e
host can now be get as a global value:
Goffi <goffi@goffi.org>
parents:
15
diff
changeset
|
32 from cagou import G |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
33 from .constants import Const as C |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
34 from . import cagou_widget |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
35 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
36 log = logging.getLogger(__name__) |
13 | 37 |
163
ef09dce878c7
widgets handler: removed constants which are not used anymore
Goffi <goffi@goffi.org>
parents:
160
diff
changeset
|
38 |
269
a5dfc789eeaf
widgets_handler: increased remove limit and min height/width:
Goffi <goffi@goffi.org>
parents:
263
diff
changeset
|
39 REMOVE_WID_LIMIT = dp(50) |
a5dfc789eeaf
widgets_handler: increased remove limit and min height/width:
Goffi <goffi@goffi.org>
parents:
263
diff
changeset
|
40 MIN_WIDTH = MIN_HEIGHT = dp(70) |
13 | 41 |
42 | |
154 | 43 class WHWrapper(BoxLayout): |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
44 main_container = properties.ObjectProperty(None) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
45 screen_manager = properties.ObjectProperty(None, allownone=True) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
46 carousel = properties.ObjectProperty(None, allownone=True) |
154 | 47 split_size = properties.NumericProperty(dp(1)) |
48 split_margin = properties.NumericProperty(dp(2)) | |
49 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
|
50 split_color_move = C.COLOR_SEC_DARK |
154 | 51 split_color_del = properties.ListProperty([0.8, 0.0, 0.0, 1]) |
52 # sp stands for "split point" | |
53 sp_size = properties.NumericProperty(dp(1)) | |
54 sp_space = properties.NumericProperty(dp(4)) | |
55 sp_zone = properties.NumericProperty(dp(30)) | |
56 _split = properties.OptionProperty('None', options=['None', 'left', 'top']) | |
57 _split_del = properties.BooleanProperty(False) | |
58 | |
59 def __init__(self, **kwargs): | |
60 idx = kwargs.pop('_wid_idx') | |
61 self._wid_idx = idx | |
62 super(WHWrapper, self).__init__(**kwargs) | |
63 self._left_wids = set() | |
64 self._top_wids = set() | |
65 self._right_wids = set() | |
66 self._bottom_wids = set() | |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
67 self._clear_attributes() |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
68 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
69 def _clear_attributes(self): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
70 self._former_slide = None |
154 | 71 |
72 def __repr__(self): | |
73 return "WHWrapper_{idx}".format(idx=self._wid_idx) | |
74 | |
75 def _main_wid(self, wid_list): | |
76 """return main widget of a side list | |
77 | |
263
fe540a6dc14d
widgets handler: call host._removeVisibleWidget when a widget is deleted (using split)
Goffi <goffi@goffi.org>
parents:
260
diff
changeset
|
78 main widget is either the widget currently splitted |
154 | 79 or any widget if none is split |
80 @return (WHWrapper, None): main widget or None | |
81 if there is not widget | |
82 """ | |
83 if not wid_list: | |
84 return None | |
85 for wid in wid_list: | |
86 if wid._split != 'None': | |
87 return wid | |
88 return next(iter(wid_list)) | |
89 | |
90 @property | |
91 def _left_wid(self): | |
92 return self._main_wid(self._left_wids) | |
93 | |
94 @property | |
95 def _top_wid(self): | |
96 return self._main_wid(self._top_wids) | |
97 | |
98 @property | |
99 def _right_wid(self): | |
100 return self._main_wid(self._right_wids) | |
101 | |
102 @property | |
103 def _bottom_wid(self): | |
104 return self._main_wid(self._bottom_wids) | |
13 | 105 |
154 | 106 @property |
107 def current_slide(self): | |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
108 if (self.carousel is not None |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
109 and (self.screen_manager is None or self.screen_manager.current == '')): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
110 return self.carousel.current_slide |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
111 elif self.screen_manager is not None: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
112 # 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
|
113 return self.screen_manager.current_screen.children[0] |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
114 else: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
115 try: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
116 return self.main_container.children[0] |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
117 except IndexError: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
118 log.error("No child found, this should not happen") |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
119 return None |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
120 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
121 @property |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
122 def carousel_active(self): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
123 """Return True if Carousel is used and active""" |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
124 if self.carousel is None: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
125 return False |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
126 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
|
127 return False |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
128 return True |
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 former_screen_wid(self): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
132 """Return widget currently active for former screen""" |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
133 if self.screen_manager is None: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
134 raise exceptions.InternalError( |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
135 "former_screen_wid can only be used if ScreenManager is used") |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
136 if self._former_screen_name is None: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
137 return None |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
138 return self.getScreenWidget(self._former_screen_name) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
139 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
140 def getScreenWidget(self, screen_name): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
141 """Return screen main widget, handling carousel if necessary""" |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
142 if self.carousel is not None and screen_name == '': |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
143 return self.carousel.current_slide |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
144 try: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
145 return self.screen_manager.get_screen(screen_name).children[0] |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
146 except IndexError: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
147 return None |
154 | 148 |
149 def _draw_ellipse(self): | |
150 """draw split ellipse""" | |
151 color = self.split_color_del if self._split_del else self.split_color_move | |
152 try: | |
153 self.canvas.after.remove(self.ellipse) | |
154 except AttributeError: | |
155 pass | |
156 if self._split == "top": | |
157 with self.canvas.after: | |
158 Color(*color) | |
159 self.ellipse = Ellipse(angle_start=90, angle_end=270, | |
160 pos=(self.x + self.width/2 - self.sp_zone/2, | |
161 self.y + self.height - self.sp_zone/2), | |
162 size=(self.sp_zone, self.sp_zone)) | |
163 elif self._split == "left": | |
164 with self.canvas.after: | |
165 Color(*color) | |
166 self.ellipse = Ellipse(angle_end=180, | |
167 pos=(self.x + -self.sp_zone/2, | |
168 self.y + self.height/2 - self.sp_zone/2), | |
169 size = (self.sp_zone, self.sp_zone)) | |
170 else: | |
171 raise exceptions.InternalError('unexpected split value') | |
13 | 172 |
154 | 173 def on_touch_down(self, touch): |
174 """activate split if touch is on a split zone""" | |
175 if not self.collide_point(*touch.pos): | |
176 return | |
177 log.debug("WIDGET IDX: {} (left: {}, top: {}, right: {}, bottom: {}), pos: {}, size: {}".format( | |
178 self._wid_idx, | |
179 'None' if not self._left_wids else [w._wid_idx for w in self._left_wids], | |
180 'None' if not self._top_wids else [w._wid_idx for w in self._top_wids], | |
181 'None' if not self._right_wids else [w._wid_idx for w in self._right_wids], | |
182 'None' if not self._bottom_wids else [w._wid_idx for w in self._bottom_wids], | |
183 self.pos, | |
184 self.size, | |
185 )) | |
186 touch_rx, touch_ry = self.to_widget(*touch.pos, relative=True) | |
187 if (touch_ry <= self.height and | |
188 touch_ry >= self.height - self.split_size - self.split_margin or | |
189 touch_ry <= self.height and | |
190 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
|
191 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
|
192 touch_rx <= self.width//2 + self.sp_zone//2): |
154 | 193 # split area is touched, we activate top split mode |
194 self._split = "top" | |
195 self._draw_ellipse() | |
196 elif (touch_rx >= 0 and | |
197 touch_rx <= self.split_size + self.split_margin or | |
198 touch_rx >= 0 and | |
199 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
|
200 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
|
201 touch_ry <= self.height//2 + self.sp_zone//2): |
154 | 202 # split area is touched, we activate left split mode |
203 self._split = "left" | |
204 touch.ud['ori_width'] = self.width | |
205 self._draw_ellipse() | |
13 | 206 else: |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
207 if self.carousel_active and len(self.carousel.slides) <= 1: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
208 # 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
|
209 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
|
210 else: |
a0e486074d91
widget handler: block carousel swiping when there is only one slide
Goffi <goffi@goffi.org>
parents:
154
diff
changeset
|
211 return super(WHWrapper, self).on_touch_down(touch) |
13 | 212 |
213 def on_touch_move(self, touch): | |
154 | 214 """handle size change and widget creation on split""" |
215 if self._split == 'None': | |
216 return super(WHWrapper, self).on_touch_move(touch) | |
217 | |
218 elif self._split == 'top': | |
219 new_height = touch.y - self.y | |
220 | |
221 if new_height < MIN_HEIGHT: | |
222 return | |
223 | |
224 # we must not pass the top widget/border | |
225 if self._top_wids: | |
226 top = next(iter(self._top_wids)) | |
227 y_limit = top.y + top.height | |
228 | |
229 if top.height <= REMOVE_WID_LIMIT: | |
230 # 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
|
231 if not self._split_del and self._top_wids: |
154 | 232 self._split_del = True |
233 self._draw_ellipse() | |
234 else: | |
235 if self._split_del: | |
236 self._split_del = False | |
237 self._draw_ellipse() | |
238 else: | |
239 y_limit = self.y + self.height | |
240 | |
241 if touch.y >= y_limit: | |
242 return | |
243 | |
244 # all right, we can change size | |
245 self.height = new_height | |
246 self.ellipse.pos = (self.ellipse.pos[0], touch.y - self.sp_zone/2) | |
247 | |
248 if not self._top_wids: | |
249 # we are the last widget on the top | |
250 # so we create a new widget | |
251 new_wid = self.parent.add_widget() | |
252 self._top_wids.add(new_wid) | |
253 new_wid._bottom_wids.add(self) | |
254 for w in self._right_wids: | |
255 new_wid._right_wids.add(w) | |
256 w._left_wids.add(new_wid) | |
257 for w in self._left_wids: | |
258 new_wid._left_wids.add(w) | |
259 w._right_wids.add(new_wid) | |
13 | 260 |
154 | 261 elif self._split == 'left': |
262 ori_width = touch.ud['ori_width'] | |
263 new_x = touch.x | |
264 new_width = ori_width - (touch.x - touch.ox) | |
265 | |
266 if new_width < MIN_WIDTH: | |
267 return | |
268 | |
269 # we must not pass the left widget/border | |
270 if self._left_wids: | |
271 left = next(iter(self._left_wids)) | |
272 x_limit = left.x | |
273 | |
274 if left.width <= REMOVE_WID_LIMIT: | |
275 # 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
|
276 if not self._split_del and self._left_wids: |
154 | 277 self._split_del = True |
278 self._draw_ellipse() | |
279 else: | |
280 if self._split_del: | |
281 self._split_del = False | |
282 self._draw_ellipse() | |
283 else: | |
284 x_limit = self.x | |
285 | |
286 if new_x <= x_limit: | |
287 return | |
288 | |
289 # all right, we can change position/size | |
290 self.x = new_x | |
291 self.width = new_width | |
292 self.ellipse.pos = (touch.x - self.sp_zone/2, self.ellipse.pos[1]) | |
293 | |
294 if not self._left_wids: | |
295 # we are the last widget on the left | |
296 # so we create a new widget | |
297 new_wid = self.parent.add_widget() | |
298 self._left_wids.add(new_wid) | |
299 new_wid._right_wids.add(self) | |
300 for w in self._top_wids: | |
301 new_wid._top_wids.add(w) | |
302 w._bottom_wids.add(new_wid) | |
303 for w in self._bottom_wids: | |
304 new_wid._bottom_wids.add(w) | |
305 w._top_wids.add(new_wid) | |
306 | |
307 else: | |
308 raise Exception.InternalError('invalid _split value') | |
13 | 309 |
310 def on_touch_up(self, touch): | |
154 | 311 if self._split == 'None': |
312 return super(WHWrapper, self).on_touch_up(touch) | |
313 if self._split == 'top': | |
314 # we remove all top widgets in delete zone, | |
315 # and update there side widgets list | |
316 for top in self._top_wids.copy(): | |
317 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
|
318 G.host._removeVisibleWidget(top.current_slide) |
154 | 319 for w in top._top_wids: |
320 w._bottom_wids.remove(top) | |
321 w._bottom_wids.update(top._bottom_wids) | |
322 for w in top._bottom_wids: | |
323 w._top_wids.remove(top) | |
324 w._top_wids.update(top._top_wids) | |
325 for w in top._left_wids: | |
326 w._right_wids.remove(top) | |
327 for w in top._right_wids: | |
328 w._left_wids.remove(top) | |
329 self.parent.remove_widget(top) | |
330 elif self._split == 'left': | |
331 # we remove all left widgets in delete zone, | |
332 # and update there side widgets list | |
333 for left in self._left_wids.copy(): | |
334 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
|
335 G.host._removeVisibleWidget(left.current_slide) |
154 | 336 for w in left._left_wids: |
337 w._right_wids.remove(left) | |
338 w._right_wids.update(left._right_wids) | |
339 for w in left._right_wids: | |
340 w._left_wids.remove(left) | |
341 w._left_wids.update(left._left_wids) | |
342 for w in left._top_wids: | |
343 w._bottom_wids.remove(left) | |
344 for w in left._bottom_wids: | |
345 w._top_wids.remove(left) | |
346 self.parent.remove_widget(left) | |
347 self._split = 'None' | |
348 self.canvas.after.remove(self.ellipse) | |
349 del self.ellipse | |
13 | 350 |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
351 def clear_widgets(self): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
352 current_slide = self.current_slide |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
353 if current_slide is not None: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
354 G.host._removeVisibleWidget(current_slide) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
355 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
356 super().clear_widgets() |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
357 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
358 self.screen_manager = None |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
359 self.carousel = None |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
360 self._clear_attributes() |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
361 |
154 | 362 def set_widget(self, wid, index=0): |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
363 assert len(self.children) == 0 |
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 if wid.collection_carousel or wid.global_screen_manager: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
366 self.main_container = self |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
367 else: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
368 self.main_container = ScrollView() |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
369 self.add_widget(self.main_container) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
370 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
371 if self.carousel is not None: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
372 return self.carousel.add_widget(wid, index) |
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.global_screen_manager: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
375 if self.screen_manager is None: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
376 self.screen_manager = ScreenManager() |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
377 self.main_container.add_widget(self.screen_manager) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
378 parent = Screen() |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
379 self.screen_manager.add_widget(parent) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
380 self._former_screen_name = '' |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
381 self.screen_manager.bind(current=self.onScreenChange) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
382 wid.screenManagerInit(self.screen_manager) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
383 else: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
384 parent = self.main_container |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
385 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
386 if wid.collection_carousel: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
387 # 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
|
388 # so we need to create the carousel |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
389 self.carousel = Carousel( |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
390 direction = "right", |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
391 ignore_perpendicular_swipes = True, |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
392 loop = True, |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
393 ) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
394 self._slides_update_lock = 0 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
395 self.carousel.bind(current_slide=self.onSlideChange) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
396 parent.add_widget(self.carousel) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
397 self.carousel.add_widget(wid, index) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
398 else: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
399 # no Carousel requested, we add the widget as a direct child |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
400 parent.add_widget(wid) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
401 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
|
402 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
403 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
|
404 """Change currently displayed widget |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
405 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
406 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
|
407 """ |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
408 if (self.carousel is not None |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
409 and self.carousel.current_slide.__class__ == new_widget.__class__): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
410 # 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
|
411 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
412 if self.carousel.current_slide != new_widget: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
413 # 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
|
414 # which would mess the removal of current widgets |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
415 self._slides_update_lock += 1 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
416 new_wid = None |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
417 for w in self.carousel.slides[:]: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
418 if w.widget_hash == new_widget.widget_hash: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
419 new_wid = w |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
420 continue |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
421 self.carousel.remove_widget(w) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
422 if isinstance(w, quick_widgets.QuickWidget): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
423 G.host.widgets.deleteWidget(w) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
424 if new_wid is None: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
425 new_wid = G.host.getOrClone(new_widget) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
426 self.carousel.add_widget(new_wid) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
427 self._updateHiddenSlides() |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
428 self._slides_update_lock -= 1 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
429 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
430 if self.screen_manager is not None: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
431 self.screen_manager.clear_widgets([ |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
432 s for s in self.screen_manager.screens if s.name != '']) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
433 new_wid.screenManagerInit(self.screen_manager) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
434 else: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
435 # else, we restart fresh |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
436 self.clear_widgets() |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
437 self.set_widget(G.host.getOrClone(new_widget)) |
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 def onScreenChange(self, screen_manager, new_screen): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
440 try: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
441 new_screen_wid = self.current_slide |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
442 except IndexError: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
443 new_screen_wid = None |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
444 log.warning("Switching to a screen without children") |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
445 if new_screen == '' and self.carousel is not None: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
446 # 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
|
447 self._updateHiddenSlides() |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
448 former_screen_wid = self.former_screen_wid |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
449 if isinstance(former_screen_wid, cagou_widget.CagouWidget): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
450 G.host._removeVisibleWidget(former_screen_wid) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
451 if isinstance(new_screen_wid, cagou_widget.CagouWidget): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
452 G.host._addVisibleWidget(new_screen_wid) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
453 self._former_screen_name = new_screen |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
454 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
|
455 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
456 def onSlideChange(self, handler, new_slide): |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
457 if self._former_slide is new_slide: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
458 # FIXME: workaround for Kivy a95d67f (and above?), Carousel.current_slide |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
459 # binding now calls onSlideChange twice with the same widget (here |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
460 # "new_slide"). To be checked with Kivy team. |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
461 return |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
462 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
|
463 if self._former_slide is not None: |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
464 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
|
465 self._former_slide = new_slide |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
466 if self.carousel_active: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
467 G.host.selected_widget = new_slide |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
468 if new_slide is not None: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
469 G.host._addVisibleWidget(new_slide) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
470 self._updateHiddenSlides() |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
471 |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
472 def hiddenList(self, visible_list, ignore=None): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
473 """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
|
474 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
475 @param visible_list(list[QuickWidget]): widgets visible |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
476 @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
|
477 @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
|
478 """ |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
479 # we want to avoid recreated widgets |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
480 added = [w.widget_hash for w in visible_list] |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
481 current_slide = self.carousel.current_slide |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
482 for w in G.host.widgets.getWidgets(current_slide.__class__, |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
483 profiles=current_slide.profiles): |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
484 wid_hash = w.widget_hash |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
485 if w in visible_list or wid_hash in added: |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
486 continue |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
487 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
|
488 continue |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
489 yield w |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
490 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
491 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
|
492 """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
|
493 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
494 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
|
495 @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
|
496 @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
|
497 """ |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
498 try: |
312 | 499 return str(widget.target).lower() |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
500 except AttributeError: |
312 | 501 return str(list(widget.targets)[0]).lower() |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
502 |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
503 def _updateHiddenSlides(self): |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
504 """adjust carousel slides according to visible widgets""" |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
505 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
|
506 return |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
507 current_slide = self.carousel.current_slide |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
508 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
|
509 return |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
510 # lock must be used here to avoid recursions |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
511 self._slides_update_lock += 1 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
512 visible_list = G.host.getVisibleList(current_slide.__class__) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
513 # 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
|
514 # screen is shown |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
515 hidden = list(self.hiddenList(visible_list, ignore=current_slide)) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
516 slides_sorted = sorted(set(hidden + [current_slide]), key=self.widgets_sort) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
517 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
|
518 for w in to_remove: |
154 | 519 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
|
520 if hidden: |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
521 # 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
|
522 # 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
|
523 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
|
524 try: |
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[current_idx+1] |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
526 except IndexError: |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
527 next_slide = slides_sorted[0] |
154 | 528 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
|
529 if len(hidden)>1: |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
530 previous_slide = slides_sorted[current_idx-1] |
154 | 531 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
|
532 |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
533 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
|
534 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
535 |
154 | 536 class WidgetsHandlerLayout(Layout): |
537 count = 0 | |
13 | 538 |
154 | 539 def __init__(self, **kwargs): |
540 super(WidgetsHandlerLayout, self).__init__(**kwargs) | |
171
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
541 self._layout_size = None # size used for the last layout |
154 | 542 fbind = self.fbind |
543 update = self._trigger_layout | |
544 fbind('children', update) | |
545 fbind('parent', update) | |
171
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
546 fbind('size', self.adjust_prop) |
154 | 547 fbind('pos', update) |
13 | 548 |
14 | 549 @property |
550 def default_widget(self): | |
16
ba14b596b90e
host can now be get as a global value:
Goffi <goffi@goffi.org>
parents:
15
diff
changeset
|
551 return G.host.default_wid['factory'](G.host.default_wid, None, None) |
14 | 552 |
171
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
553 def adjust_prop(self, handler, new_size): |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
554 """Adjust children proportion |
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 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
|
557 """ |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
558 if len(self.children) > 1: |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
559 old_width, old_height = self._layout_size |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
560 if not old_width or not old_height: |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
561 # we don't want division by zero |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
562 return self._trigger_layout(handler, new_size) |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
563 width_factor = float(self.width) / old_width |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
564 height_factor = float(self.height) / old_height |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
565 for child in self.children: |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
566 child.width *= width_factor |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
567 child.height *= height_factor |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
568 child.x *= width_factor |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
569 child.y *= height_factor |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
570 self._trigger_layout(handler, new_size) |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
571 |
154 | 572 def do_layout(self, *args): |
171
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
573 self._layout_size = self.size[:] |
154 | 574 for child in self.children: |
575 # XXX: left must be calculated before right and bottom before top | |
576 # because they are the pos, and are used to caculate size (right and top) | |
577 # left | |
578 left = child._left_wid | |
170
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
579 left_end_x = self.x-1 if left is None else left.right |
154 | 580 if child.x != left_end_x + 1 and child._split == "None": |
581 child.x = left_end_x + 1 | |
582 # right | |
583 right = child._right_wid | |
170
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
584 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
|
585 if child.right != right_x - 1: |
154 | 586 child.width = right_x - child.x - 1 |
587 # bottom | |
588 bottom = child._bottom_wid | |
589 if bottom is None: | |
170
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
590 if child.y != self.y: |
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
591 child.y = self.y |
154 | 592 else: |
170
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
593 if child.y != bottom.top + 1: |
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
594 child.y = bottom.top + 1 |
154 | 595 # top |
596 top = child._top_wid | |
170
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
597 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
|
598 if child.top != top_y - 1: |
154 | 599 if child._split == "None": |
600 child.height = top_y - child.y - 1 | |
601 | |
602 def remove_widget(self, wid): | |
603 super(WidgetsHandlerLayout, self).remove_widget(wid) | |
604 log.debug("widget deleted ({})".format(wid._wid_idx)) | |
605 | |
606 def add_widget(self, wid=None, index=0): | |
607 WidgetsHandlerLayout.count += 1 | |
608 if wid is None: | |
609 wid = self.default_widget | |
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() |