bauiv1lib.settings.allsettings
UI for top level settings categories.
1# Released under the MIT License. See LICENSE for details. 2# 3"""UI for top level settings categories.""" 4 5from __future__ import annotations 6 7from typing import TYPE_CHECKING, override 8import logging 9 10import bauiv1 as bui 11 12if TYPE_CHECKING: 13 pass 14 15 16class AllSettingsWindow(bui.MainWindow): 17 """Window for selecting a settings category.""" 18 19 def __init__( 20 self, 21 transition: str | None = 'in_right', 22 origin_widget: bui.Widget | None = None, 23 ): 24 # pylint: disable=too-many-statements 25 # pylint: disable=too-many-locals 26 27 # Preload some modules we use in a background thread so we won't 28 # have a visual hitch when the user taps them. 29 bui.app.threadpool_submit_no_wait(self._preload_modules) 30 31 bui.set_analytics_screen('Settings Window') 32 assert bui.app.classic is not None 33 uiscale = bui.app.ui_v1.uiscale 34 width = 1000 if uiscale is bui.UIScale.SMALL else 580 35 x_inset = 125 if uiscale is bui.UIScale.SMALL else 0 36 height = 500 if uiscale is bui.UIScale.SMALL else 435 37 self._r = 'settingsWindow' 38 top_extra = 20 if uiscale is bui.UIScale.SMALL else 0 39 yoffs = -30 if uiscale is bui.UIScale.SMALL else 0 40 41 uiscale = bui.app.ui_v1.uiscale 42 super().__init__( 43 root_widget=bui.containerwidget( 44 size=(width, height + top_extra), 45 toolbar_visibility=( 46 'menu_minimal' 47 if uiscale is bui.UIScale.SMALL 48 else 'menu_full' 49 ), 50 scale=( 51 1.5 52 if uiscale is bui.UIScale.SMALL 53 else 1.25 if uiscale is bui.UIScale.MEDIUM else 1.0 54 ), 55 stack_offset=( 56 (0, 0) if uiscale is bui.UIScale.SMALL else (0, 0) 57 ), 58 ), 59 transition=transition, 60 origin_widget=origin_widget, 61 ) 62 63 if uiscale is bui.UIScale.SMALL: 64 self._back_button = None 65 bui.containerwidget( 66 edit=self._root_widget, on_cancel_call=self.main_window_back 67 ) 68 else: 69 self._back_button = btn = bui.buttonwidget( 70 parent=self._root_widget, 71 autoselect=True, 72 position=(40 + x_inset, height - 55 + yoffs), 73 size=(130, 60), 74 scale=0.8, 75 text_scale=1.2, 76 label=bui.Lstr(resource='backText'), 77 button_type='back', 78 on_activate_call=self.main_window_back, 79 ) 80 bui.containerwidget(edit=self._root_widget, cancel_button=btn) 81 82 bui.textwidget( 83 parent=self._root_widget, 84 position=(0, height - 44 + yoffs), 85 size=(width, 25), 86 text=bui.Lstr(resource=f'{self._r}.titleText'), 87 color=bui.app.ui_v1.title_color, 88 h_align='center', 89 v_align='center', 90 maxwidth=130, 91 ) 92 93 if self._back_button is not None: 94 bui.buttonwidget( 95 edit=self._back_button, 96 button_type='backSmall', 97 size=(60, 60), 98 label=bui.charstr(bui.SpecialChar.BACK), 99 ) 100 101 v = height - 80 + yoffs 102 v -= 145 103 104 basew = 280 if uiscale is bui.UIScale.SMALL else 230 105 baseh = 170 106 x_offs = ( 107 x_inset + (105 if uiscale is bui.UIScale.SMALL else 72) - basew 108 ) # now unused 109 x_offs2 = x_offs + basew - 7 110 x_offs3 = x_offs + 2 * (basew - 7) 111 x_offs4 = x_offs2 112 x_offs5 = x_offs3 113 114 def _b_title( 115 x: float, y: float, button: bui.Widget, text: str | bui.Lstr 116 ) -> None: 117 bui.textwidget( 118 parent=self._root_widget, 119 text=text, 120 position=(x + basew * 0.47, y + baseh * 0.22), 121 maxwidth=basew * 0.7, 122 size=(0, 0), 123 h_align='center', 124 v_align='center', 125 draw_controller=button, 126 color=(0.7, 0.9, 0.7, 1.0), 127 ) 128 129 ctb = self._controllers_button = bui.buttonwidget( 130 parent=self._root_widget, 131 autoselect=True, 132 position=(x_offs2, v), 133 size=(basew, baseh), 134 button_type='square', 135 label='', 136 on_activate_call=self._do_controllers, 137 ) 138 if self._back_button is None: 139 bbtn = bui.get_special_widget('back_button') 140 bui.widget(edit=ctb, left_widget=bbtn) 141 _b_title( 142 x_offs2, v, ctb, bui.Lstr(resource=f'{self._r}.controllersText') 143 ) 144 imgw = imgh = 130 145 bui.imagewidget( 146 parent=self._root_widget, 147 position=(x_offs2 + basew * 0.49 - imgw * 0.5, v + 35), 148 size=(imgw, imgh), 149 texture=bui.gettexture('controllerIcon'), 150 draw_controller=ctb, 151 ) 152 153 gfxb = self._graphics_button = bui.buttonwidget( 154 parent=self._root_widget, 155 autoselect=True, 156 position=(x_offs3, v), 157 size=(basew, baseh), 158 button_type='square', 159 label='', 160 on_activate_call=self._do_graphics, 161 ) 162 pbtn = bui.get_special_widget('squad_button') 163 bui.widget(edit=gfxb, up_widget=pbtn, right_widget=pbtn) 164 _b_title(x_offs3, v, gfxb, bui.Lstr(resource=f'{self._r}.graphicsText')) 165 imgw = imgh = 110 166 bui.imagewidget( 167 parent=self._root_widget, 168 position=(x_offs3 + basew * 0.49 - imgw * 0.5, v + 42), 169 size=(imgw, imgh), 170 texture=bui.gettexture('graphicsIcon'), 171 draw_controller=gfxb, 172 ) 173 174 v -= baseh - 5 175 176 abtn = self._audio_button = bui.buttonwidget( 177 parent=self._root_widget, 178 autoselect=True, 179 position=(x_offs4, v), 180 size=(basew, baseh), 181 button_type='square', 182 label='', 183 on_activate_call=self._do_audio, 184 ) 185 _b_title(x_offs4, v, abtn, bui.Lstr(resource=f'{self._r}.audioText')) 186 imgw = imgh = 120 187 bui.imagewidget( 188 parent=self._root_widget, 189 position=(x_offs4 + basew * 0.49 - imgw * 0.5 + 5, v + 35), 190 size=(imgw, imgh), 191 color=(1, 1, 0), 192 texture=bui.gettexture('audioIcon'), 193 draw_controller=abtn, 194 ) 195 196 avb = self._advanced_button = bui.buttonwidget( 197 parent=self._root_widget, 198 autoselect=True, 199 position=(x_offs5, v), 200 size=(basew, baseh), 201 button_type='square', 202 label='', 203 on_activate_call=self._do_advanced, 204 ) 205 _b_title(x_offs5, v, avb, bui.Lstr(resource=f'{self._r}.advancedText')) 206 imgw = imgh = 120 207 bui.imagewidget( 208 parent=self._root_widget, 209 position=(x_offs5 + basew * 0.49 - imgw * 0.5 + 5, v + 35), 210 size=(imgw, imgh), 211 color=(0.8, 0.95, 1), 212 texture=bui.gettexture('advancedIcon'), 213 draw_controller=avb, 214 ) 215 self._restore_state() 216 217 @override 218 def get_main_window_state(self) -> bui.MainWindowState: 219 # Support recreating our window for back/refresh purposes. 220 cls = type(self) 221 return bui.BasicMainWindowState( 222 create_call=lambda transition, origin_widget: cls( 223 transition=transition, origin_widget=origin_widget 224 ) 225 ) 226 227 @override 228 def on_main_window_close(self) -> None: 229 self._save_state() 230 231 @staticmethod 232 def _preload_modules() -> None: 233 """Preload modules we use; avoids hitches (called in bg thread).""" 234 import bauiv1lib.mainmenu as _unused1 235 import bauiv1lib.settings.controls as _unused2 236 import bauiv1lib.settings.graphics as _unused3 237 import bauiv1lib.settings.audio as _unused4 238 import bauiv1lib.settings.advanced as _unused5 239 240 def _do_controllers(self) -> None: 241 # pylint: disable=cyclic-import 242 from bauiv1lib.settings.controls import ControlsSettingsWindow 243 244 # no-op if we're not in control. 245 if not self.main_window_has_control(): 246 return 247 248 self.main_window_replace( 249 ControlsSettingsWindow(origin_widget=self._controllers_button) 250 ) 251 252 def _do_graphics(self) -> None: 253 # pylint: disable=cyclic-import 254 from bauiv1lib.settings.graphics import GraphicsSettingsWindow 255 256 # no-op if we're not in control. 257 if not self.main_window_has_control(): 258 return 259 260 self.main_window_replace( 261 GraphicsSettingsWindow(origin_widget=self._graphics_button) 262 ) 263 264 def _do_audio(self) -> None: 265 # pylint: disable=cyclic-import 266 from bauiv1lib.settings.audio import AudioSettingsWindow 267 268 # no-op if we're not in control. 269 if not self.main_window_has_control(): 270 return 271 272 self.main_window_replace( 273 AudioSettingsWindow(origin_widget=self._audio_button) 274 ) 275 276 def _do_advanced(self) -> None: 277 # pylint: disable=cyclic-import 278 from bauiv1lib.settings.advanced import AdvancedSettingsWindow 279 280 # no-op if we're not in control. 281 if not self.main_window_has_control(): 282 return 283 284 self.main_window_replace( 285 AdvancedSettingsWindow(origin_widget=self._advanced_button) 286 ) 287 288 def _save_state(self) -> None: 289 try: 290 sel = self._root_widget.get_selected_child() 291 if sel == self._controllers_button: 292 sel_name = 'Controllers' 293 elif sel == self._graphics_button: 294 sel_name = 'Graphics' 295 elif sel == self._audio_button: 296 sel_name = 'Audio' 297 elif sel == self._advanced_button: 298 sel_name = 'Advanced' 299 elif sel == self._back_button: 300 sel_name = 'Back' 301 else: 302 raise ValueError(f'unrecognized selection \'{sel}\'') 303 assert bui.app.classic is not None 304 bui.app.ui_v1.window_states[type(self)] = {'sel_name': sel_name} 305 except Exception: 306 logging.exception('Error saving state for %s.', self) 307 308 def _restore_state(self) -> None: 309 try: 310 assert bui.app.classic is not None 311 sel_name = bui.app.ui_v1.window_states.get(type(self), {}).get( 312 'sel_name' 313 ) 314 sel: bui.Widget | None 315 if sel_name == 'Controllers': 316 sel = self._controllers_button 317 elif sel_name == 'Graphics': 318 sel = self._graphics_button 319 elif sel_name == 'Audio': 320 sel = self._audio_button 321 elif sel_name == 'Advanced': 322 sel = self._advanced_button 323 elif sel_name == 'Back': 324 sel = self._back_button 325 else: 326 sel = self._controllers_button 327 if sel is not None: 328 bui.containerwidget(edit=self._root_widget, selected_child=sel) 329 except Exception: 330 logging.exception('Error restoring state for %s.', self)
class
AllSettingsWindow(bauiv1._uitypes.MainWindow):
17class AllSettingsWindow(bui.MainWindow): 18 """Window for selecting a settings category.""" 19 20 def __init__( 21 self, 22 transition: str | None = 'in_right', 23 origin_widget: bui.Widget | None = None, 24 ): 25 # pylint: disable=too-many-statements 26 # pylint: disable=too-many-locals 27 28 # Preload some modules we use in a background thread so we won't 29 # have a visual hitch when the user taps them. 30 bui.app.threadpool_submit_no_wait(self._preload_modules) 31 32 bui.set_analytics_screen('Settings Window') 33 assert bui.app.classic is not None 34 uiscale = bui.app.ui_v1.uiscale 35 width = 1000 if uiscale is bui.UIScale.SMALL else 580 36 x_inset = 125 if uiscale is bui.UIScale.SMALL else 0 37 height = 500 if uiscale is bui.UIScale.SMALL else 435 38 self._r = 'settingsWindow' 39 top_extra = 20 if uiscale is bui.UIScale.SMALL else 0 40 yoffs = -30 if uiscale is bui.UIScale.SMALL else 0 41 42 uiscale = bui.app.ui_v1.uiscale 43 super().__init__( 44 root_widget=bui.containerwidget( 45 size=(width, height + top_extra), 46 toolbar_visibility=( 47 'menu_minimal' 48 if uiscale is bui.UIScale.SMALL 49 else 'menu_full' 50 ), 51 scale=( 52 1.5 53 if uiscale is bui.UIScale.SMALL 54 else 1.25 if uiscale is bui.UIScale.MEDIUM else 1.0 55 ), 56 stack_offset=( 57 (0, 0) if uiscale is bui.UIScale.SMALL else (0, 0) 58 ), 59 ), 60 transition=transition, 61 origin_widget=origin_widget, 62 ) 63 64 if uiscale is bui.UIScale.SMALL: 65 self._back_button = None 66 bui.containerwidget( 67 edit=self._root_widget, on_cancel_call=self.main_window_back 68 ) 69 else: 70 self._back_button = btn = bui.buttonwidget( 71 parent=self._root_widget, 72 autoselect=True, 73 position=(40 + x_inset, height - 55 + yoffs), 74 size=(130, 60), 75 scale=0.8, 76 text_scale=1.2, 77 label=bui.Lstr(resource='backText'), 78 button_type='back', 79 on_activate_call=self.main_window_back, 80 ) 81 bui.containerwidget(edit=self._root_widget, cancel_button=btn) 82 83 bui.textwidget( 84 parent=self._root_widget, 85 position=(0, height - 44 + yoffs), 86 size=(width, 25), 87 text=bui.Lstr(resource=f'{self._r}.titleText'), 88 color=bui.app.ui_v1.title_color, 89 h_align='center', 90 v_align='center', 91 maxwidth=130, 92 ) 93 94 if self._back_button is not None: 95 bui.buttonwidget( 96 edit=self._back_button, 97 button_type='backSmall', 98 size=(60, 60), 99 label=bui.charstr(bui.SpecialChar.BACK), 100 ) 101 102 v = height - 80 + yoffs 103 v -= 145 104 105 basew = 280 if uiscale is bui.UIScale.SMALL else 230 106 baseh = 170 107 x_offs = ( 108 x_inset + (105 if uiscale is bui.UIScale.SMALL else 72) - basew 109 ) # now unused 110 x_offs2 = x_offs + basew - 7 111 x_offs3 = x_offs + 2 * (basew - 7) 112 x_offs4 = x_offs2 113 x_offs5 = x_offs3 114 115 def _b_title( 116 x: float, y: float, button: bui.Widget, text: str | bui.Lstr 117 ) -> None: 118 bui.textwidget( 119 parent=self._root_widget, 120 text=text, 121 position=(x + basew * 0.47, y + baseh * 0.22), 122 maxwidth=basew * 0.7, 123 size=(0, 0), 124 h_align='center', 125 v_align='center', 126 draw_controller=button, 127 color=(0.7, 0.9, 0.7, 1.0), 128 ) 129 130 ctb = self._controllers_button = bui.buttonwidget( 131 parent=self._root_widget, 132 autoselect=True, 133 position=(x_offs2, v), 134 size=(basew, baseh), 135 button_type='square', 136 label='', 137 on_activate_call=self._do_controllers, 138 ) 139 if self._back_button is None: 140 bbtn = bui.get_special_widget('back_button') 141 bui.widget(edit=ctb, left_widget=bbtn) 142 _b_title( 143 x_offs2, v, ctb, bui.Lstr(resource=f'{self._r}.controllersText') 144 ) 145 imgw = imgh = 130 146 bui.imagewidget( 147 parent=self._root_widget, 148 position=(x_offs2 + basew * 0.49 - imgw * 0.5, v + 35), 149 size=(imgw, imgh), 150 texture=bui.gettexture('controllerIcon'), 151 draw_controller=ctb, 152 ) 153 154 gfxb = self._graphics_button = bui.buttonwidget( 155 parent=self._root_widget, 156 autoselect=True, 157 position=(x_offs3, v), 158 size=(basew, baseh), 159 button_type='square', 160 label='', 161 on_activate_call=self._do_graphics, 162 ) 163 pbtn = bui.get_special_widget('squad_button') 164 bui.widget(edit=gfxb, up_widget=pbtn, right_widget=pbtn) 165 _b_title(x_offs3, v, gfxb, bui.Lstr(resource=f'{self._r}.graphicsText')) 166 imgw = imgh = 110 167 bui.imagewidget( 168 parent=self._root_widget, 169 position=(x_offs3 + basew * 0.49 - imgw * 0.5, v + 42), 170 size=(imgw, imgh), 171 texture=bui.gettexture('graphicsIcon'), 172 draw_controller=gfxb, 173 ) 174 175 v -= baseh - 5 176 177 abtn = self._audio_button = bui.buttonwidget( 178 parent=self._root_widget, 179 autoselect=True, 180 position=(x_offs4, v), 181 size=(basew, baseh), 182 button_type='square', 183 label='', 184 on_activate_call=self._do_audio, 185 ) 186 _b_title(x_offs4, v, abtn, bui.Lstr(resource=f'{self._r}.audioText')) 187 imgw = imgh = 120 188 bui.imagewidget( 189 parent=self._root_widget, 190 position=(x_offs4 + basew * 0.49 - imgw * 0.5 + 5, v + 35), 191 size=(imgw, imgh), 192 color=(1, 1, 0), 193 texture=bui.gettexture('audioIcon'), 194 draw_controller=abtn, 195 ) 196 197 avb = self._advanced_button = bui.buttonwidget( 198 parent=self._root_widget, 199 autoselect=True, 200 position=(x_offs5, v), 201 size=(basew, baseh), 202 button_type='square', 203 label='', 204 on_activate_call=self._do_advanced, 205 ) 206 _b_title(x_offs5, v, avb, bui.Lstr(resource=f'{self._r}.advancedText')) 207 imgw = imgh = 120 208 bui.imagewidget( 209 parent=self._root_widget, 210 position=(x_offs5 + basew * 0.49 - imgw * 0.5 + 5, v + 35), 211 size=(imgw, imgh), 212 color=(0.8, 0.95, 1), 213 texture=bui.gettexture('advancedIcon'), 214 draw_controller=avb, 215 ) 216 self._restore_state() 217 218 @override 219 def get_main_window_state(self) -> bui.MainWindowState: 220 # Support recreating our window for back/refresh purposes. 221 cls = type(self) 222 return bui.BasicMainWindowState( 223 create_call=lambda transition, origin_widget: cls( 224 transition=transition, origin_widget=origin_widget 225 ) 226 ) 227 228 @override 229 def on_main_window_close(self) -> None: 230 self._save_state() 231 232 @staticmethod 233 def _preload_modules() -> None: 234 """Preload modules we use; avoids hitches (called in bg thread).""" 235 import bauiv1lib.mainmenu as _unused1 236 import bauiv1lib.settings.controls as _unused2 237 import bauiv1lib.settings.graphics as _unused3 238 import bauiv1lib.settings.audio as _unused4 239 import bauiv1lib.settings.advanced as _unused5 240 241 def _do_controllers(self) -> None: 242 # pylint: disable=cyclic-import 243 from bauiv1lib.settings.controls import ControlsSettingsWindow 244 245 # no-op if we're not in control. 246 if not self.main_window_has_control(): 247 return 248 249 self.main_window_replace( 250 ControlsSettingsWindow(origin_widget=self._controllers_button) 251 ) 252 253 def _do_graphics(self) -> None: 254 # pylint: disable=cyclic-import 255 from bauiv1lib.settings.graphics import GraphicsSettingsWindow 256 257 # no-op if we're not in control. 258 if not self.main_window_has_control(): 259 return 260 261 self.main_window_replace( 262 GraphicsSettingsWindow(origin_widget=self._graphics_button) 263 ) 264 265 def _do_audio(self) -> None: 266 # pylint: disable=cyclic-import 267 from bauiv1lib.settings.audio import AudioSettingsWindow 268 269 # no-op if we're not in control. 270 if not self.main_window_has_control(): 271 return 272 273 self.main_window_replace( 274 AudioSettingsWindow(origin_widget=self._audio_button) 275 ) 276 277 def _do_advanced(self) -> None: 278 # pylint: disable=cyclic-import 279 from bauiv1lib.settings.advanced import AdvancedSettingsWindow 280 281 # no-op if we're not in control. 282 if not self.main_window_has_control(): 283 return 284 285 self.main_window_replace( 286 AdvancedSettingsWindow(origin_widget=self._advanced_button) 287 ) 288 289 def _save_state(self) -> None: 290 try: 291 sel = self._root_widget.get_selected_child() 292 if sel == self._controllers_button: 293 sel_name = 'Controllers' 294 elif sel == self._graphics_button: 295 sel_name = 'Graphics' 296 elif sel == self._audio_button: 297 sel_name = 'Audio' 298 elif sel == self._advanced_button: 299 sel_name = 'Advanced' 300 elif sel == self._back_button: 301 sel_name = 'Back' 302 else: 303 raise ValueError(f'unrecognized selection \'{sel}\'') 304 assert bui.app.classic is not None 305 bui.app.ui_v1.window_states[type(self)] = {'sel_name': sel_name} 306 except Exception: 307 logging.exception('Error saving state for %s.', self) 308 309 def _restore_state(self) -> None: 310 try: 311 assert bui.app.classic is not None 312 sel_name = bui.app.ui_v1.window_states.get(type(self), {}).get( 313 'sel_name' 314 ) 315 sel: bui.Widget | None 316 if sel_name == 'Controllers': 317 sel = self._controllers_button 318 elif sel_name == 'Graphics': 319 sel = self._graphics_button 320 elif sel_name == 'Audio': 321 sel = self._audio_button 322 elif sel_name == 'Advanced': 323 sel = self._advanced_button 324 elif sel_name == 'Back': 325 sel = self._back_button 326 else: 327 sel = self._controllers_button 328 if sel is not None: 329 bui.containerwidget(edit=self._root_widget, selected_child=sel) 330 except Exception: 331 logging.exception('Error restoring state for %s.', self)
Window for selecting a settings category.
AllSettingsWindow( transition: str | None = 'in_right', origin_widget: _bauiv1.Widget | None = None)
20 def __init__( 21 self, 22 transition: str | None = 'in_right', 23 origin_widget: bui.Widget | None = None, 24 ): 25 # pylint: disable=too-many-statements 26 # pylint: disable=too-many-locals 27 28 # Preload some modules we use in a background thread so we won't 29 # have a visual hitch when the user taps them. 30 bui.app.threadpool_submit_no_wait(self._preload_modules) 31 32 bui.set_analytics_screen('Settings Window') 33 assert bui.app.classic is not None 34 uiscale = bui.app.ui_v1.uiscale 35 width = 1000 if uiscale is bui.UIScale.SMALL else 580 36 x_inset = 125 if uiscale is bui.UIScale.SMALL else 0 37 height = 500 if uiscale is bui.UIScale.SMALL else 435 38 self._r = 'settingsWindow' 39 top_extra = 20 if uiscale is bui.UIScale.SMALL else 0 40 yoffs = -30 if uiscale is bui.UIScale.SMALL else 0 41 42 uiscale = bui.app.ui_v1.uiscale 43 super().__init__( 44 root_widget=bui.containerwidget( 45 size=(width, height + top_extra), 46 toolbar_visibility=( 47 'menu_minimal' 48 if uiscale is bui.UIScale.SMALL 49 else 'menu_full' 50 ), 51 scale=( 52 1.5 53 if uiscale is bui.UIScale.SMALL 54 else 1.25 if uiscale is bui.UIScale.MEDIUM else 1.0 55 ), 56 stack_offset=( 57 (0, 0) if uiscale is bui.UIScale.SMALL else (0, 0) 58 ), 59 ), 60 transition=transition, 61 origin_widget=origin_widget, 62 ) 63 64 if uiscale is bui.UIScale.SMALL: 65 self._back_button = None 66 bui.containerwidget( 67 edit=self._root_widget, on_cancel_call=self.main_window_back 68 ) 69 else: 70 self._back_button = btn = bui.buttonwidget( 71 parent=self._root_widget, 72 autoselect=True, 73 position=(40 + x_inset, height - 55 + yoffs), 74 size=(130, 60), 75 scale=0.8, 76 text_scale=1.2, 77 label=bui.Lstr(resource='backText'), 78 button_type='back', 79 on_activate_call=self.main_window_back, 80 ) 81 bui.containerwidget(edit=self._root_widget, cancel_button=btn) 82 83 bui.textwidget( 84 parent=self._root_widget, 85 position=(0, height - 44 + yoffs), 86 size=(width, 25), 87 text=bui.Lstr(resource=f'{self._r}.titleText'), 88 color=bui.app.ui_v1.title_color, 89 h_align='center', 90 v_align='center', 91 maxwidth=130, 92 ) 93 94 if self._back_button is not None: 95 bui.buttonwidget( 96 edit=self._back_button, 97 button_type='backSmall', 98 size=(60, 60), 99 label=bui.charstr(bui.SpecialChar.BACK), 100 ) 101 102 v = height - 80 + yoffs 103 v -= 145 104 105 basew = 280 if uiscale is bui.UIScale.SMALL else 230 106 baseh = 170 107 x_offs = ( 108 x_inset + (105 if uiscale is bui.UIScale.SMALL else 72) - basew 109 ) # now unused 110 x_offs2 = x_offs + basew - 7 111 x_offs3 = x_offs + 2 * (basew - 7) 112 x_offs4 = x_offs2 113 x_offs5 = x_offs3 114 115 def _b_title( 116 x: float, y: float, button: bui.Widget, text: str | bui.Lstr 117 ) -> None: 118 bui.textwidget( 119 parent=self._root_widget, 120 text=text, 121 position=(x + basew * 0.47, y + baseh * 0.22), 122 maxwidth=basew * 0.7, 123 size=(0, 0), 124 h_align='center', 125 v_align='center', 126 draw_controller=button, 127 color=(0.7, 0.9, 0.7, 1.0), 128 ) 129 130 ctb = self._controllers_button = bui.buttonwidget( 131 parent=self._root_widget, 132 autoselect=True, 133 position=(x_offs2, v), 134 size=(basew, baseh), 135 button_type='square', 136 label='', 137 on_activate_call=self._do_controllers, 138 ) 139 if self._back_button is None: 140 bbtn = bui.get_special_widget('back_button') 141 bui.widget(edit=ctb, left_widget=bbtn) 142 _b_title( 143 x_offs2, v, ctb, bui.Lstr(resource=f'{self._r}.controllersText') 144 ) 145 imgw = imgh = 130 146 bui.imagewidget( 147 parent=self._root_widget, 148 position=(x_offs2 + basew * 0.49 - imgw * 0.5, v + 35), 149 size=(imgw, imgh), 150 texture=bui.gettexture('controllerIcon'), 151 draw_controller=ctb, 152 ) 153 154 gfxb = self._graphics_button = bui.buttonwidget( 155 parent=self._root_widget, 156 autoselect=True, 157 position=(x_offs3, v), 158 size=(basew, baseh), 159 button_type='square', 160 label='', 161 on_activate_call=self._do_graphics, 162 ) 163 pbtn = bui.get_special_widget('squad_button') 164 bui.widget(edit=gfxb, up_widget=pbtn, right_widget=pbtn) 165 _b_title(x_offs3, v, gfxb, bui.Lstr(resource=f'{self._r}.graphicsText')) 166 imgw = imgh = 110 167 bui.imagewidget( 168 parent=self._root_widget, 169 position=(x_offs3 + basew * 0.49 - imgw * 0.5, v + 42), 170 size=(imgw, imgh), 171 texture=bui.gettexture('graphicsIcon'), 172 draw_controller=gfxb, 173 ) 174 175 v -= baseh - 5 176 177 abtn = self._audio_button = bui.buttonwidget( 178 parent=self._root_widget, 179 autoselect=True, 180 position=(x_offs4, v), 181 size=(basew, baseh), 182 button_type='square', 183 label='', 184 on_activate_call=self._do_audio, 185 ) 186 _b_title(x_offs4, v, abtn, bui.Lstr(resource=f'{self._r}.audioText')) 187 imgw = imgh = 120 188 bui.imagewidget( 189 parent=self._root_widget, 190 position=(x_offs4 + basew * 0.49 - imgw * 0.5 + 5, v + 35), 191 size=(imgw, imgh), 192 color=(1, 1, 0), 193 texture=bui.gettexture('audioIcon'), 194 draw_controller=abtn, 195 ) 196 197 avb = self._advanced_button = bui.buttonwidget( 198 parent=self._root_widget, 199 autoselect=True, 200 position=(x_offs5, v), 201 size=(basew, baseh), 202 button_type='square', 203 label='', 204 on_activate_call=self._do_advanced, 205 ) 206 _b_title(x_offs5, v, avb, bui.Lstr(resource=f'{self._r}.advancedText')) 207 imgw = imgh = 120 208 bui.imagewidget( 209 parent=self._root_widget, 210 position=(x_offs5 + basew * 0.49 - imgw * 0.5 + 5, v + 35), 211 size=(imgw, imgh), 212 color=(0.8, 0.95, 1), 213 texture=bui.gettexture('advancedIcon'), 214 draw_controller=avb, 215 ) 216 self._restore_state()
Create a MainWindow given a root widget and transition info.
Automatically handles in and out transitions on the provided widget, so there is no need to set transitions when creating it.
218 @override 219 def get_main_window_state(self) -> bui.MainWindowState: 220 # Support recreating our window for back/refresh purposes. 221 cls = type(self) 222 return bui.BasicMainWindowState( 223 create_call=lambda transition, origin_widget: cls( 224 transition=transition, origin_widget=origin_widget 225 ) 226 )
Return a WindowState to recreate this window, if supported.