bauiv1lib.settings.devtools
UI functionality for Modding Tools.
1# Released under the MIT License. See LICENSE for details. 2# 3"""UI functionality for Modding Tools.""" 4 5from __future__ import annotations 6 7from typing import override 8 9import babase 10import bauiv1 as bui 11from bauiv1lib.popup import PopupMenu 12from bauiv1lib.confirm import ConfirmWindow 13from bauiv1lib.config import ConfigCheckBox 14 15 16class DevToolsWindow(bui.MainWindow): 17 """Window for accessing modding tools.""" 18 19 def __init__( 20 self, 21 transition: str | None = 'in_right', 22 origin_widget: bui.Widget | None = None, 23 ): 24 25 app = bui.app 26 assert app.classic is not None 27 28 uiscale = app.ui_v1.uiscale 29 self._width = 1200.0 if uiscale is bui.UIScale.SMALL else 670.0 30 self._height = ( 31 800 32 if uiscale is bui.UIScale.SMALL 33 else 450.0 if uiscale is bui.UIScale.MEDIUM else 520.0 34 ) 35 self._spacing = 32 36 37 # Do some fancy math to fill all available screen area up to the 38 # size of our backing container. This lets us fit to the exact 39 # screen shape at small ui scale. 40 screensize = bui.get_virtual_screen_size() 41 scale = ( 42 2.13 43 if uiscale is bui.UIScale.SMALL 44 else 1.4 if uiscale is bui.UIScale.MEDIUM else 1.0 45 ) 46 # Calc screen size in our local container space and clamp to a 47 # bit smaller than our container size. 48 target_width = min(self._width - 80, screensize[0] / scale) 49 target_height = min(self._height - 90, screensize[1] / scale) 50 51 # To get top/left coords, go to the center of our window and 52 # offset by half the width/height of our target area. 53 yoffs = 0.5 * self._height + 0.5 * target_height + 30.0 54 55 self._scroll_width = target_width 56 self._scroll_height = target_height - 35 57 self._scroll_bottom = yoffs - 64 - self._scroll_height 58 59 self._sub_width = self._scroll_width * 0.95 60 self._sub_height = 300.0 61 62 super().__init__( 63 root_widget=bui.containerwidget( 64 size=(self._width, self._height), 65 toolbar_visibility=( 66 'menu_minimal' 67 if uiscale is bui.UIScale.SMALL 68 else 'menu_full' 69 ), 70 scale=scale, 71 ), 72 transition=transition, 73 origin_widget=origin_widget, 74 # We're affected by screen size only at small ui-scale. 75 refresh_on_screen_size_changes=uiscale is bui.UIScale.SMALL, 76 ) 77 78 self._r = 'settingsDevTools' 79 80 if uiscale is bui.UIScale.SMALL: 81 bui.containerwidget( 82 edit=self._root_widget, on_cancel_call=self.main_window_back 83 ) 84 self._back_button = None 85 else: 86 self._back_button = bui.buttonwidget( 87 parent=self._root_widget, 88 position=(53, yoffs - 50), 89 size=(140, 60), 90 scale=0.8, 91 autoselect=True, 92 label=bui.Lstr(resource='backText'), 93 button_type='back', 94 on_activate_call=self.main_window_back, 95 ) 96 bui.containerwidget( 97 edit=self._root_widget, cancel_button=self._back_button 98 ) 99 100 self._title_text = bui.textwidget( 101 parent=self._root_widget, 102 position=( 103 self._width * 0.5, 104 yoffs - (60 if uiscale is bui.UIScale.SMALL else 42), 105 ), 106 size=(0, 25), 107 scale=(0.8 if uiscale is bui.UIScale.SMALL else 1.0), 108 maxwidth=self._width - 200, 109 text=bui.Lstr(resource='settingsWindowAdvanced.devToolsText'), 110 color=app.ui_v1.title_color, 111 h_align='center', 112 v_align='center', 113 ) 114 115 if self._back_button is not None: 116 bui.buttonwidget( 117 edit=self._back_button, 118 button_type='backSmall', 119 size=(60, 60), 120 label=bui.charstr(bui.SpecialChar.BACK), 121 ) 122 123 self._scrollwidget = bui.scrollwidget( 124 parent=self._root_widget, 125 position=( 126 self._width * 0.5 - self._scroll_width * 0.5, 127 self._scroll_bottom, 128 ), 129 simple_culling_v=20.0, 130 highlight=False, 131 size=(self._scroll_width, self._scroll_height), 132 selection_loops_to_parent=True, 133 border_opacity=0.4, 134 ) 135 bui.widget(edit=self._scrollwidget, right_widget=self._scrollwidget) 136 self._subcontainer = bui.containerwidget( 137 parent=self._scrollwidget, 138 size=(self._sub_width, self._sub_height), 139 background=False, 140 selection_loops_to_parent=True, 141 ) 142 143 v = self._sub_height - 35 144 this_button_width = 410 145 146 v -= self._spacing * 2.5 147 self._show_dev_console_button_check_box = ConfigCheckBox( 148 parent=self._subcontainer, 149 position=(90, v + 40), 150 size=(self._sub_width - 100, 30), 151 configkey='Show Dev Console Button', 152 displayname=bui.Lstr( 153 resource='settingsWindowAdvanced.showDevConsoleButtonText' 154 ), 155 scale=1.0, 156 maxwidth=400, 157 ) 158 if self._back_button is not None: 159 bui.widget( 160 edit=self._show_dev_console_button_check_box.widget, 161 up_widget=self._back_button, 162 ) 163 164 v -= self._spacing * 1.2 165 self._create_user_system_scripts_button = bui.buttonwidget( 166 parent=self._subcontainer, 167 position=(self._sub_width / 2 - this_button_width / 2, v - 10), 168 size=(this_button_width, 60), 169 autoselect=True, 170 label=bui.Lstr(resource='userSystemScriptsCreateText'), 171 text_scale=1.0, 172 on_activate_call=babase.modutils.create_user_system_scripts, 173 ) 174 175 v -= self._spacing * 2.5 176 self._delete_user_system_scripts_button = bui.buttonwidget( 177 parent=self._subcontainer, 178 position=(self._sub_width / 2 - this_button_width / 2, v - 10), 179 size=(this_button_width, 60), 180 autoselect=True, 181 label=bui.Lstr(resource='userSystemScriptsDeleteText'), 182 text_scale=1.0, 183 on_activate_call=lambda: ConfirmWindow( 184 action=babase.modutils.delete_user_system_scripts, 185 ), 186 ) 187 188 # Currently this is not wired up. The current official way to test 189 # UIScales is either to use the switcher in the dev-console or to 190 # set the BA_UI_SCALE env var. 191 if bool(False): 192 v -= self._spacing * 2.5 193 bui.textwidget( 194 parent=self._subcontainer, 195 position=(170, v + 10), 196 size=(0, 0), 197 text=bui.Lstr(resource='uiScaleText'), 198 color=app.ui_v1.title_color, 199 h_align='center', 200 v_align='center', 201 ) 202 203 PopupMenu( 204 parent=self._subcontainer, 205 position=(230, v - 20), 206 button_size=(200.0, 60.0), 207 width=100.0, 208 choices=[ 209 'auto', 210 'small', 211 'medium', 212 'large', 213 ], 214 choices_display=[ 215 bui.Lstr(resource='autoText'), 216 bui.Lstr(resource='sizeSmallText'), 217 bui.Lstr(resource='sizeMediumText'), 218 bui.Lstr(resource='sizeLargeText'), 219 ], 220 current_choice=app.config.get('UI Scale', 'auto'), 221 on_value_change_call=self._set_uiscale, 222 ) 223 224 @override 225 def get_main_window_state(self) -> bui.MainWindowState: 226 # Support recreating our window for back/refresh purposes. 227 cls = type(self) 228 return bui.BasicMainWindowState( 229 create_call=lambda transition, origin_widget: cls( 230 transition=transition, origin_widget=origin_widget 231 ) 232 ) 233 234 def _set_uiscale(self, val: str) -> None: 235 cfg = bui.app.config 236 cfg['UI Scale'] = val 237 cfg.apply_and_commit() 238 if bui.app.ui_v1.uiscale.name != val.upper(): 239 bui.screenmessage( 240 bui.Lstr(resource='settingsWindowAdvanced.mustRestartText'), 241 color=(1.0, 0.5, 0.0), 242 )
class
DevToolsWindow(bauiv1._uitypes.MainWindow):
17class DevToolsWindow(bui.MainWindow): 18 """Window for accessing modding tools.""" 19 20 def __init__( 21 self, 22 transition: str | None = 'in_right', 23 origin_widget: bui.Widget | None = None, 24 ): 25 26 app = bui.app 27 assert app.classic is not None 28 29 uiscale = app.ui_v1.uiscale 30 self._width = 1200.0 if uiscale is bui.UIScale.SMALL else 670.0 31 self._height = ( 32 800 33 if uiscale is bui.UIScale.SMALL 34 else 450.0 if uiscale is bui.UIScale.MEDIUM else 520.0 35 ) 36 self._spacing = 32 37 38 # Do some fancy math to fill all available screen area up to the 39 # size of our backing container. This lets us fit to the exact 40 # screen shape at small ui scale. 41 screensize = bui.get_virtual_screen_size() 42 scale = ( 43 2.13 44 if uiscale is bui.UIScale.SMALL 45 else 1.4 if uiscale is bui.UIScale.MEDIUM else 1.0 46 ) 47 # Calc screen size in our local container space and clamp to a 48 # bit smaller than our container size. 49 target_width = min(self._width - 80, screensize[0] / scale) 50 target_height = min(self._height - 90, screensize[1] / scale) 51 52 # To get top/left coords, go to the center of our window and 53 # offset by half the width/height of our target area. 54 yoffs = 0.5 * self._height + 0.5 * target_height + 30.0 55 56 self._scroll_width = target_width 57 self._scroll_height = target_height - 35 58 self._scroll_bottom = yoffs - 64 - self._scroll_height 59 60 self._sub_width = self._scroll_width * 0.95 61 self._sub_height = 300.0 62 63 super().__init__( 64 root_widget=bui.containerwidget( 65 size=(self._width, self._height), 66 toolbar_visibility=( 67 'menu_minimal' 68 if uiscale is bui.UIScale.SMALL 69 else 'menu_full' 70 ), 71 scale=scale, 72 ), 73 transition=transition, 74 origin_widget=origin_widget, 75 # We're affected by screen size only at small ui-scale. 76 refresh_on_screen_size_changes=uiscale is bui.UIScale.SMALL, 77 ) 78 79 self._r = 'settingsDevTools' 80 81 if uiscale is bui.UIScale.SMALL: 82 bui.containerwidget( 83 edit=self._root_widget, on_cancel_call=self.main_window_back 84 ) 85 self._back_button = None 86 else: 87 self._back_button = bui.buttonwidget( 88 parent=self._root_widget, 89 position=(53, yoffs - 50), 90 size=(140, 60), 91 scale=0.8, 92 autoselect=True, 93 label=bui.Lstr(resource='backText'), 94 button_type='back', 95 on_activate_call=self.main_window_back, 96 ) 97 bui.containerwidget( 98 edit=self._root_widget, cancel_button=self._back_button 99 ) 100 101 self._title_text = bui.textwidget( 102 parent=self._root_widget, 103 position=( 104 self._width * 0.5, 105 yoffs - (60 if uiscale is bui.UIScale.SMALL else 42), 106 ), 107 size=(0, 25), 108 scale=(0.8 if uiscale is bui.UIScale.SMALL else 1.0), 109 maxwidth=self._width - 200, 110 text=bui.Lstr(resource='settingsWindowAdvanced.devToolsText'), 111 color=app.ui_v1.title_color, 112 h_align='center', 113 v_align='center', 114 ) 115 116 if self._back_button is not None: 117 bui.buttonwidget( 118 edit=self._back_button, 119 button_type='backSmall', 120 size=(60, 60), 121 label=bui.charstr(bui.SpecialChar.BACK), 122 ) 123 124 self._scrollwidget = bui.scrollwidget( 125 parent=self._root_widget, 126 position=( 127 self._width * 0.5 - self._scroll_width * 0.5, 128 self._scroll_bottom, 129 ), 130 simple_culling_v=20.0, 131 highlight=False, 132 size=(self._scroll_width, self._scroll_height), 133 selection_loops_to_parent=True, 134 border_opacity=0.4, 135 ) 136 bui.widget(edit=self._scrollwidget, right_widget=self._scrollwidget) 137 self._subcontainer = bui.containerwidget( 138 parent=self._scrollwidget, 139 size=(self._sub_width, self._sub_height), 140 background=False, 141 selection_loops_to_parent=True, 142 ) 143 144 v = self._sub_height - 35 145 this_button_width = 410 146 147 v -= self._spacing * 2.5 148 self._show_dev_console_button_check_box = ConfigCheckBox( 149 parent=self._subcontainer, 150 position=(90, v + 40), 151 size=(self._sub_width - 100, 30), 152 configkey='Show Dev Console Button', 153 displayname=bui.Lstr( 154 resource='settingsWindowAdvanced.showDevConsoleButtonText' 155 ), 156 scale=1.0, 157 maxwidth=400, 158 ) 159 if self._back_button is not None: 160 bui.widget( 161 edit=self._show_dev_console_button_check_box.widget, 162 up_widget=self._back_button, 163 ) 164 165 v -= self._spacing * 1.2 166 self._create_user_system_scripts_button = bui.buttonwidget( 167 parent=self._subcontainer, 168 position=(self._sub_width / 2 - this_button_width / 2, v - 10), 169 size=(this_button_width, 60), 170 autoselect=True, 171 label=bui.Lstr(resource='userSystemScriptsCreateText'), 172 text_scale=1.0, 173 on_activate_call=babase.modutils.create_user_system_scripts, 174 ) 175 176 v -= self._spacing * 2.5 177 self._delete_user_system_scripts_button = bui.buttonwidget( 178 parent=self._subcontainer, 179 position=(self._sub_width / 2 - this_button_width / 2, v - 10), 180 size=(this_button_width, 60), 181 autoselect=True, 182 label=bui.Lstr(resource='userSystemScriptsDeleteText'), 183 text_scale=1.0, 184 on_activate_call=lambda: ConfirmWindow( 185 action=babase.modutils.delete_user_system_scripts, 186 ), 187 ) 188 189 # Currently this is not wired up. The current official way to test 190 # UIScales is either to use the switcher in the dev-console or to 191 # set the BA_UI_SCALE env var. 192 if bool(False): 193 v -= self._spacing * 2.5 194 bui.textwidget( 195 parent=self._subcontainer, 196 position=(170, v + 10), 197 size=(0, 0), 198 text=bui.Lstr(resource='uiScaleText'), 199 color=app.ui_v1.title_color, 200 h_align='center', 201 v_align='center', 202 ) 203 204 PopupMenu( 205 parent=self._subcontainer, 206 position=(230, v - 20), 207 button_size=(200.0, 60.0), 208 width=100.0, 209 choices=[ 210 'auto', 211 'small', 212 'medium', 213 'large', 214 ], 215 choices_display=[ 216 bui.Lstr(resource='autoText'), 217 bui.Lstr(resource='sizeSmallText'), 218 bui.Lstr(resource='sizeMediumText'), 219 bui.Lstr(resource='sizeLargeText'), 220 ], 221 current_choice=app.config.get('UI Scale', 'auto'), 222 on_value_change_call=self._set_uiscale, 223 ) 224 225 @override 226 def get_main_window_state(self) -> bui.MainWindowState: 227 # Support recreating our window for back/refresh purposes. 228 cls = type(self) 229 return bui.BasicMainWindowState( 230 create_call=lambda transition, origin_widget: cls( 231 transition=transition, origin_widget=origin_widget 232 ) 233 ) 234 235 def _set_uiscale(self, val: str) -> None: 236 cfg = bui.app.config 237 cfg['UI Scale'] = val 238 cfg.apply_and_commit() 239 if bui.app.ui_v1.uiscale.name != val.upper(): 240 bui.screenmessage( 241 bui.Lstr(resource='settingsWindowAdvanced.mustRestartText'), 242 color=(1.0, 0.5, 0.0), 243 )
Window for accessing modding tools.
DevToolsWindow( 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 26 app = bui.app 27 assert app.classic is not None 28 29 uiscale = app.ui_v1.uiscale 30 self._width = 1200.0 if uiscale is bui.UIScale.SMALL else 670.0 31 self._height = ( 32 800 33 if uiscale is bui.UIScale.SMALL 34 else 450.0 if uiscale is bui.UIScale.MEDIUM else 520.0 35 ) 36 self._spacing = 32 37 38 # Do some fancy math to fill all available screen area up to the 39 # size of our backing container. This lets us fit to the exact 40 # screen shape at small ui scale. 41 screensize = bui.get_virtual_screen_size() 42 scale = ( 43 2.13 44 if uiscale is bui.UIScale.SMALL 45 else 1.4 if uiscale is bui.UIScale.MEDIUM else 1.0 46 ) 47 # Calc screen size in our local container space and clamp to a 48 # bit smaller than our container size. 49 target_width = min(self._width - 80, screensize[0] / scale) 50 target_height = min(self._height - 90, screensize[1] / scale) 51 52 # To get top/left coords, go to the center of our window and 53 # offset by half the width/height of our target area. 54 yoffs = 0.5 * self._height + 0.5 * target_height + 30.0 55 56 self._scroll_width = target_width 57 self._scroll_height = target_height - 35 58 self._scroll_bottom = yoffs - 64 - self._scroll_height 59 60 self._sub_width = self._scroll_width * 0.95 61 self._sub_height = 300.0 62 63 super().__init__( 64 root_widget=bui.containerwidget( 65 size=(self._width, self._height), 66 toolbar_visibility=( 67 'menu_minimal' 68 if uiscale is bui.UIScale.SMALL 69 else 'menu_full' 70 ), 71 scale=scale, 72 ), 73 transition=transition, 74 origin_widget=origin_widget, 75 # We're affected by screen size only at small ui-scale. 76 refresh_on_screen_size_changes=uiscale is bui.UIScale.SMALL, 77 ) 78 79 self._r = 'settingsDevTools' 80 81 if uiscale is bui.UIScale.SMALL: 82 bui.containerwidget( 83 edit=self._root_widget, on_cancel_call=self.main_window_back 84 ) 85 self._back_button = None 86 else: 87 self._back_button = bui.buttonwidget( 88 parent=self._root_widget, 89 position=(53, yoffs - 50), 90 size=(140, 60), 91 scale=0.8, 92 autoselect=True, 93 label=bui.Lstr(resource='backText'), 94 button_type='back', 95 on_activate_call=self.main_window_back, 96 ) 97 bui.containerwidget( 98 edit=self._root_widget, cancel_button=self._back_button 99 ) 100 101 self._title_text = bui.textwidget( 102 parent=self._root_widget, 103 position=( 104 self._width * 0.5, 105 yoffs - (60 if uiscale is bui.UIScale.SMALL else 42), 106 ), 107 size=(0, 25), 108 scale=(0.8 if uiscale is bui.UIScale.SMALL else 1.0), 109 maxwidth=self._width - 200, 110 text=bui.Lstr(resource='settingsWindowAdvanced.devToolsText'), 111 color=app.ui_v1.title_color, 112 h_align='center', 113 v_align='center', 114 ) 115 116 if self._back_button is not None: 117 bui.buttonwidget( 118 edit=self._back_button, 119 button_type='backSmall', 120 size=(60, 60), 121 label=bui.charstr(bui.SpecialChar.BACK), 122 ) 123 124 self._scrollwidget = bui.scrollwidget( 125 parent=self._root_widget, 126 position=( 127 self._width * 0.5 - self._scroll_width * 0.5, 128 self._scroll_bottom, 129 ), 130 simple_culling_v=20.0, 131 highlight=False, 132 size=(self._scroll_width, self._scroll_height), 133 selection_loops_to_parent=True, 134 border_opacity=0.4, 135 ) 136 bui.widget(edit=self._scrollwidget, right_widget=self._scrollwidget) 137 self._subcontainer = bui.containerwidget( 138 parent=self._scrollwidget, 139 size=(self._sub_width, self._sub_height), 140 background=False, 141 selection_loops_to_parent=True, 142 ) 143 144 v = self._sub_height - 35 145 this_button_width = 410 146 147 v -= self._spacing * 2.5 148 self._show_dev_console_button_check_box = ConfigCheckBox( 149 parent=self._subcontainer, 150 position=(90, v + 40), 151 size=(self._sub_width - 100, 30), 152 configkey='Show Dev Console Button', 153 displayname=bui.Lstr( 154 resource='settingsWindowAdvanced.showDevConsoleButtonText' 155 ), 156 scale=1.0, 157 maxwidth=400, 158 ) 159 if self._back_button is not None: 160 bui.widget( 161 edit=self._show_dev_console_button_check_box.widget, 162 up_widget=self._back_button, 163 ) 164 165 v -= self._spacing * 1.2 166 self._create_user_system_scripts_button = bui.buttonwidget( 167 parent=self._subcontainer, 168 position=(self._sub_width / 2 - this_button_width / 2, v - 10), 169 size=(this_button_width, 60), 170 autoselect=True, 171 label=bui.Lstr(resource='userSystemScriptsCreateText'), 172 text_scale=1.0, 173 on_activate_call=babase.modutils.create_user_system_scripts, 174 ) 175 176 v -= self._spacing * 2.5 177 self._delete_user_system_scripts_button = bui.buttonwidget( 178 parent=self._subcontainer, 179 position=(self._sub_width / 2 - this_button_width / 2, v - 10), 180 size=(this_button_width, 60), 181 autoselect=True, 182 label=bui.Lstr(resource='userSystemScriptsDeleteText'), 183 text_scale=1.0, 184 on_activate_call=lambda: ConfirmWindow( 185 action=babase.modutils.delete_user_system_scripts, 186 ), 187 ) 188 189 # Currently this is not wired up. The current official way to test 190 # UIScales is either to use the switcher in the dev-console or to 191 # set the BA_UI_SCALE env var. 192 if bool(False): 193 v -= self._spacing * 2.5 194 bui.textwidget( 195 parent=self._subcontainer, 196 position=(170, v + 10), 197 size=(0, 0), 198 text=bui.Lstr(resource='uiScaleText'), 199 color=app.ui_v1.title_color, 200 h_align='center', 201 v_align='center', 202 ) 203 204 PopupMenu( 205 parent=self._subcontainer, 206 position=(230, v - 20), 207 button_size=(200.0, 60.0), 208 width=100.0, 209 choices=[ 210 'auto', 211 'small', 212 'medium', 213 'large', 214 ], 215 choices_display=[ 216 bui.Lstr(resource='autoText'), 217 bui.Lstr(resource='sizeSmallText'), 218 bui.Lstr(resource='sizeMediumText'), 219 bui.Lstr(resource='sizeLargeText'), 220 ], 221 current_choice=app.config.get('UI Scale', 'auto'), 222 on_value_change_call=self._set_uiscale, 223 )
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.
225 @override 226 def get_main_window_state(self) -> bui.MainWindowState: 227 # Support recreating our window for back/refresh purposes. 228 cls = type(self) 229 return bui.BasicMainWindowState( 230 create_call=lambda transition, origin_widget: cls( 231 transition=transition, origin_widget=origin_widget 232 ) 233 )
Return a WindowState to recreate this window, if supported.