Mercurial > libervia-desktop-kivy
annotate cagou/core/widgets_handler.py @ 378:4d660b252487
dates update
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 29 Jan 2020 09:52:46 +0100 |
parents | 9c6fe392d623 |
children | 84ff5c917064 |
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 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
|
501 """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
|
502 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
503 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
|
504 @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
|
505 @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
|
506 """ |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
507 try: |
312 | 508 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
|
509 except AttributeError: |
312 | 510 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
|
511 |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
512 def _updateHiddenSlides(self): |
38
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
513 """adjust carousel slides according to visible widgets""" |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
514 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
|
515 return |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
516 current_slide = self.carousel.current_slide |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
517 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
|
518 return |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
519 # lock must be used here to avoid recursions |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
520 self._slides_update_lock += 1 |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
521 visible_list = G.host.getVisibleList(current_slide.__class__) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
522 # 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
|
523 # screen is shown |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
524 hidden = list(self.hiddenList(visible_list, ignore=current_slide)) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
525 slides_sorted = sorted(set(hidden + [current_slide]), key=self.widgets_sort) |
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
526 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
|
527 for w in to_remove: |
154 | 528 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
|
529 if hidden: |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
530 # 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
|
531 # 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
|
532 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
|
533 try: |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
534 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
|
535 except IndexError: |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
536 next_slide = slides_sorted[0] |
154 | 537 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
|
538 if len(hidden)>1: |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
539 previous_slide = slides_sorted[current_idx-1] |
154 | 540 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
|
541 |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
542 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
|
543 |
9f45098289cc
widgets handler, core: hidden widgets can now be shown with swipes:
Goffi <goffi@goffi.org>
parents:
34
diff
changeset
|
544 |
154 | 545 class WidgetsHandlerLayout(Layout): |
546 count = 0 | |
13 | 547 |
154 | 548 def __init__(self, **kwargs): |
549 super(WidgetsHandlerLayout, self).__init__(**kwargs) | |
171
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
550 self._layout_size = None # size used for the last layout |
154 | 551 fbind = self.fbind |
552 update = self._trigger_layout | |
553 fbind('children', update) | |
554 fbind('parent', update) | |
171
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
555 fbind('size', self.adjust_prop) |
154 | 556 fbind('pos', update) |
13 | 557 |
14 | 558 @property |
559 def default_widget(self): | |
16
ba14b596b90e
host can now be get as a global value:
Goffi <goffi@goffi.org>
parents:
15
diff
changeset
|
560 return G.host.default_wid['factory'](G.host.default_wid, None, None) |
14 | 561 |
171
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
562 def adjust_prop(self, handler, new_size): |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
563 """Adjust children proportion |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
564 |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
565 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
|
566 """ |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
567 if len(self.children) > 1: |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
568 old_width, old_height = self._layout_size |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
569 if not old_width or not old_height: |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
570 # we don't want division by zero |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
571 return self._trigger_layout(handler, new_size) |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
572 width_factor = float(self.width) / old_width |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
573 height_factor = float(self.height) / old_height |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
574 for child in self.children: |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
575 child.width *= width_factor |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
576 child.height *= height_factor |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
577 child.x *= width_factor |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
578 child.y *= height_factor |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
579 self._trigger_layout(handler, new_size) |
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
580 |
154 | 581 def do_layout(self, *args): |
171
27b4ceb977c7
widgets handler: keep proportion on resize
Goffi <goffi@goffi.org>
parents:
170
diff
changeset
|
582 self._layout_size = self.size[:] |
154 | 583 for child in self.children: |
584 # XXX: left must be calculated before right and bottom before top | |
585 # because they are the pos, and are used to caculate size (right and top) | |
586 # left | |
587 left = child._left_wid | |
170
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
588 left_end_x = self.x-1 if left is None else left.right |
154 | 589 if child.x != left_end_x + 1 and child._split == "None": |
590 child.x = left_end_x + 1 | |
591 # right | |
592 right = child._right_wid | |
170
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
593 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
|
594 if child.right != right_x - 1: |
154 | 595 child.width = right_x - child.x - 1 |
596 # bottom | |
597 bottom = child._bottom_wid | |
598 if bottom is None: | |
170
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
599 if child.y != self.y: |
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
600 child.y = self.y |
154 | 601 else: |
170
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
602 if child.y != bottom.top + 1: |
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
603 child.y = bottom.top + 1 |
154 | 604 # top |
605 top = child._top_wid | |
170
f4522b7c3318
widgets handler: use widget's top and right
Goffi <goffi@goffi.org>
parents:
163
diff
changeset
|
606 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
|
607 if child.top != top_y - 1: |
154 | 608 if child._split == "None": |
609 child.height = top_y - child.y - 1 | |
610 | |
611 def remove_widget(self, wid): | |
612 super(WidgetsHandlerLayout, self).remove_widget(wid) | |
613 log.debug("widget deleted ({})".format(wid._wid_idx)) | |
614 | |
615 def add_widget(self, wid=None, index=0): | |
616 WidgetsHandlerLayout.count += 1 | |
617 if wid is None: | |
618 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
|
619 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
|
620 G.host.selected_widget = wid |
154 | 621 wrapper = WHWrapper(_wid_idx=WidgetsHandlerLayout.count) |
622 log.debug("WHWrapper created ({})".format(wrapper._wid_idx)) | |
623 wrapper.set_widget(wid) | |
624 super(WidgetsHandlerLayout, self).add_widget(wrapper, index) | |
625 return wrapper | |
626 | |
627 | |
628 class WidgetsHandler(WidgetsHandlerLayout): | |
629 | |
630 def __init__(self, **kw): | |
631 super(WidgetsHandler, self).__init__(**kw) | |
353
19422bbd9c8e
core (widgets handler): refactoring:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
632 self.add_widget() |