Mercurial > libervia-desktop-kivy
comparison libervia/desktop_kivy/core/cagou_widget.py @ 493:b3cedbee561d
refactoring: rename `cagou` to `libervia.desktop_kivy` + update imports and names following backend changes
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 02 Jun 2023 18:26:16 +0200 |
parents | cagou/core/cagou_widget.py@203755bbe0fe |
children |
comparison
equal
deleted
inserted
replaced
492:5114bbb5daa3 | 493:b3cedbee561d |
---|---|
1 #!/usr/bin/env python3 | |
2 | |
3 | |
4 #Libervia Desktop-Kivy | |
5 # Copyright (C) 2016-2021 Jérôme Poisson (goffi@goffi.org) | |
6 | |
7 # This program is free software: you can redistribute it and/or modify | |
8 # it under the terms of the GNU Affero General Public License as published by | |
9 # the Free Software Foundation, either version 3 of the License, or | |
10 # (at your option) any later version. | |
11 | |
12 # This program is distributed in the hope that it will be useful, | |
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 # GNU Affero General Public License for more details. | |
16 | |
17 # You should have received a copy of the GNU Affero General Public License | |
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | |
20 | |
21 from functools import total_ordering | |
22 from libervia.backend.core import log as logging | |
23 from libervia.backend.core import exceptions | |
24 from kivy.uix.behaviors import ButtonBehavior | |
25 from kivy.uix.boxlayout import BoxLayout | |
26 from kivy.uix.dropdown import DropDown | |
27 from kivy.uix.screenmanager import Screen | |
28 from kivy.uix.textinput import TextInput | |
29 from kivy import properties | |
30 from libervia.desktop_kivy import G | |
31 from .common import ActionIcon | |
32 from . import menu | |
33 | |
34 | |
35 log = logging.getLogger(__name__) | |
36 | |
37 | |
38 class HeaderChoice(ButtonBehavior, BoxLayout): | |
39 pass | |
40 | |
41 | |
42 class HeaderChoiceWidget(HeaderChoice): | |
43 cagou_widget = properties.ObjectProperty() | |
44 plugin_info = properties.ObjectProperty() | |
45 | |
46 def __init__(self, **kwargs): | |
47 super().__init__(**kwargs) | |
48 self.bind(on_release=lambda btn: self.cagou_widget.switch_widget( | |
49 self.plugin_info)) | |
50 | |
51 | |
52 class HeaderChoiceExtraMenu(HeaderChoice): | |
53 pass | |
54 | |
55 | |
56 class HeaderWidgetCurrent(ButtonBehavior, ActionIcon): | |
57 pass | |
58 | |
59 | |
60 class HeaderWidgetSelector(DropDown): | |
61 | |
62 def __init__(self, cagou_widget): | |
63 super(HeaderWidgetSelector, self).__init__() | |
64 plg_info_cls = cagou_widget.plugin_info_class or cagou_widget.__class__ | |
65 for plugin_info in G.host.get_plugged_widgets(except_cls=plg_info_cls): | |
66 choice = HeaderChoiceWidget( | |
67 cagou_widget=cagou_widget, | |
68 plugin_info=plugin_info, | |
69 ) | |
70 self.add_widget(choice) | |
71 main_menu = HeaderChoiceExtraMenu(on_press=self.on_extra_menu) | |
72 self.add_widget(main_menu) | |
73 | |
74 def add_widget(self, *args): | |
75 widget = args[0] | |
76 widget.bind(minimum_width=self.set_width) | |
77 return super(HeaderWidgetSelector, self).add_widget(*args) | |
78 | |
79 def set_width(self, choice, minimum_width): | |
80 self.width = max([c.minimum_width for c in self.container.children]) | |
81 | |
82 def on_extra_menu(self, *args): | |
83 self.dismiss() | |
84 menu.ExtraSideMenu().show() | |
85 | |
86 | |
87 @total_ordering | |
88 class LiberviaDesktopKivyWidget(BoxLayout): | |
89 main_container = properties.ObjectProperty(None) | |
90 header_input = properties.ObjectProperty(None) | |
91 header_box = properties.ObjectProperty(None) | |
92 use_header_input = False | |
93 # set to True if you want to be able to switch between visible widgets of this | |
94 # class using a carousel | |
95 collection_carousel = False | |
96 # set to True if you a global ScreenManager global to all widgets of this class. | |
97 # The screen manager is created in WHWrapper | |
98 global_screen_manager = False | |
99 # override this if a specific class (i.e. not self.__class__) must be used for | |
100 # plugin info. Useful when a LiberviaDesktopKivyWidget is used with global_screen_manager. | |
101 plugin_info_class = None | |
102 | |
103 def __init__(self, **kwargs): | |
104 plg_info_cls = self.plugin_info_class or self.__class__ | |
105 for p in G.host.get_plugged_widgets(): | |
106 if p['main'] == plg_info_cls: | |
107 self.plugin_info = p | |
108 break | |
109 super().__init__(**kwargs) | |
110 self.selector = HeaderWidgetSelector(self) | |
111 if self.use_header_input: | |
112 self.header_input = TextInput( | |
113 background_normal=G.host.app.expand( | |
114 '{media}/misc/borders/border_hollow_light.png'), | |
115 multiline=False, | |
116 ) | |
117 self.header_input.bind( | |
118 on_text_validate=lambda *args: self.on_header_wid_input(), | |
119 text=self.on_header_wid_input_complete, | |
120 ) | |
121 self.header_box.add_widget(self.header_input) | |
122 | |
123 def __lt__(self, other): | |
124 # XXX: sorting is notably used when collection_carousel is set | |
125 try: | |
126 target = str(self.target) | |
127 except AttributeError: | |
128 target = str(list(self.targets)[0]) | |
129 other_target = str(list(other.targets)[0]) | |
130 else: | |
131 other_target = str(other.target) | |
132 return target < other_target | |
133 | |
134 @property | |
135 def screen_manager(self): | |
136 if ((not self.global_screen_manager | |
137 and not (self.plugin_info_class is not None | |
138 and self.plugin_info_class.global_screen_manager))): | |
139 raise exceptions.InternalError( | |
140 "screen_manager property can't be used if global_screen_manager is not " | |
141 "set") | |
142 screen = self.get_ancestor(Screen) | |
143 if screen is None: | |
144 raise exceptions.NotFound("Can't find parent Screen") | |
145 if screen.manager is None: | |
146 raise exceptions.NotFound("Can't find parent ScreenManager") | |
147 return screen.manager | |
148 | |
149 @property | |
150 def whwrapper(self): | |
151 """Retrieve parent widget handler""" | |
152 return G.host.get_parent_wh_wrapper(self) | |
153 | |
154 def screen_manager_init(self, screen_manager): | |
155 """Override this method to do init when ScreenManager is instantiated | |
156 | |
157 This is only called once even if collection_carousel is used. | |
158 """ | |
159 if not self.global_screen_manager: | |
160 raise exceptions.InternalError("screen_manager_init should not be called") | |
161 | |
162 def get_ancestor(self, cls): | |
163 """Helper method to use host.get_ancestor_widget with self""" | |
164 return G.host.get_ancestor_widget(self, cls) | |
165 | |
166 def switch_widget(self, plugin_info): | |
167 self.selector.dismiss() | |
168 factory = plugin_info["factory"] | |
169 new_widget = factory(plugin_info, None, iter(G.host.profiles)) | |
170 G.host.switch_widget(self, new_widget) | |
171 | |
172 def key_input(self, window, key, scancode, codepoint, modifier): | |
173 if key == 27: | |
174 # we go back to root screen | |
175 G.host.switch_widget(self) | |
176 return True | |
177 | |
178 def on_header_wid_input(self): | |
179 log.info("header input text entered") | |
180 | |
181 def on_header_wid_input_complete(self, wid, text): | |
182 return | |
183 | |
184 def on_touch_down(self, touch): | |
185 if self.collide_point(*touch.pos): | |
186 G.host.selected_widget = self | |
187 return super(LiberviaDesktopKivyWidget, self).on_touch_down(touch) | |
188 | |
189 def header_input_add_extra(self, widget): | |
190 """add a widget on the right of header input""" | |
191 self.header_box.add_widget(widget) | |
192 | |
193 def on_visible(self): | |
194 pass | |
195 # log.debug(u"{self} is visible".format(self=self)) | |
196 | |
197 def on_not_visible(self): | |
198 pass | |
199 # log.debug(u"{self} is not visible anymore".format(self=self)) |