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))