bauiv1lib.confirm
Provides ConfirmWindow base class and commonly used derivatives.
1# Released under the MIT License. See LICENSE for details. 2# 3"""Provides ConfirmWindow base class and commonly used derivatives.""" 4 5from __future__ import annotations 6 7from typing import TYPE_CHECKING 8import logging 9 10import bauiv1 as bui 11 12if TYPE_CHECKING: 13 from typing import Any, Callable 14 15 16class ConfirmWindow: 17 """Window for answering simple yes/no questions.""" 18 19 def __init__( 20 self, 21 text: str | bui.Lstr | None = None, 22 action: Callable[[], Any] | None = None, 23 width: float = 360.0, 24 height: float = 100.0, 25 cancel_button: bool = True, 26 cancel_is_selected: bool = False, 27 color: tuple[float, float, float] = (1, 1, 1), 28 text_scale: float = 1.0, 29 ok_text: str | bui.Lstr | None = None, 30 cancel_text: str | bui.Lstr | None = None, 31 origin_widget: bui.Widget | None = None, 32 ): 33 # pylint: disable=too-many-locals 34 if text is None: 35 text = bui.Lstr(resource='areYouSureText') 36 if ok_text is None: 37 ok_text = bui.Lstr(resource='okText') 38 if cancel_text is None: 39 cancel_text = bui.Lstr(resource='cancelText') 40 height += 40 41 width = max(width, 360) 42 self._action = action 43 44 # if they provided an origin-widget, scale up from that 45 self._transition_out: str | None 46 scale_origin: tuple[float, float] | None 47 if origin_widget is not None: 48 self._transition_out = 'out_scale' 49 scale_origin = origin_widget.get_screen_space_center() 50 transition = 'in_scale' 51 else: 52 self._transition_out = None 53 scale_origin = None 54 transition = 'in_right' 55 56 assert bui.app.classic is not None 57 uiscale = bui.app.ui_v1.uiscale 58 self.root_widget = bui.containerwidget( 59 size=(width, height), 60 transition=transition, 61 toolbar_visibility='menu_minimal_no_back', 62 parent=bui.get_special_widget('overlay_stack'), 63 scale=( 64 1.9 65 if uiscale is bui.UIScale.SMALL 66 else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0 67 ), 68 scale_origin_stack_offset=scale_origin, 69 ) 70 71 bui.textwidget( 72 parent=self.root_widget, 73 position=(width * 0.5, height - 5 - (height - 75) * 0.5), 74 size=(0, 0), 75 h_align='center', 76 v_align='center', 77 text=text, 78 scale=text_scale, 79 color=color, 80 maxwidth=width * 0.9, 81 max_height=height - 75, 82 ) 83 84 cbtn: bui.Widget | None 85 if cancel_button: 86 cbtn = btn = bui.buttonwidget( 87 parent=self.root_widget, 88 autoselect=True, 89 position=(20, 20), 90 size=(150, 50), 91 label=cancel_text, 92 on_activate_call=self._cancel, 93 ) 94 bui.containerwidget(edit=self.root_widget, cancel_button=btn) 95 ok_button_h = width - 175 96 else: 97 # if they don't want a cancel button, we still want back presses to 98 # be able to dismiss the window; just wire it up to do the ok 99 # button 100 ok_button_h = width * 0.5 - 75 101 cbtn = None 102 btn = bui.buttonwidget( 103 parent=self.root_widget, 104 autoselect=True, 105 position=(ok_button_h, 20), 106 size=(150, 50), 107 label=ok_text, 108 on_activate_call=self._ok, 109 ) 110 111 # if they didn't want a cancel button, we still want to be able to hit 112 # cancel/back/etc to dismiss the window 113 if not cancel_button: 114 bui.containerwidget( 115 edit=self.root_widget, on_cancel_call=btn.activate 116 ) 117 118 bui.containerwidget( 119 edit=self.root_widget, 120 selected_child=( 121 cbtn if cbtn is not None and cancel_is_selected else btn 122 ), 123 start_button=btn, 124 ) 125 126 def _cancel(self) -> None: 127 bui.containerwidget( 128 edit=self.root_widget, 129 transition=( 130 'out_right' 131 if self._transition_out is None 132 else self._transition_out 133 ), 134 ) 135 136 def _ok(self) -> None: 137 if not self.root_widget: 138 return 139 bui.containerwidget( 140 edit=self.root_widget, 141 transition=( 142 'out_left' 143 if self._transition_out is None 144 else self._transition_out 145 ), 146 ) 147 if self._action is not None: 148 self._action() 149 150 151class QuitWindow: 152 """Popup window to confirm quitting.""" 153 154 def __init__( 155 self, 156 quit_type: bui.QuitType | None = None, 157 swish: bool = False, 158 origin_widget: bui.Widget | None = None, 159 ): 160 classic = bui.app.classic 161 assert classic is not None 162 ui = bui.app.ui_v1 163 app = bui.app 164 self._quit_type = quit_type 165 166 # If there's already one of us up somewhere, kill it. 167 if ui.quit_window is not None: 168 ui.quit_window.delete() 169 ui.quit_window = None 170 if swish: 171 bui.getsound('swish').play() 172 173 if app.classic is None: 174 if bui.do_once(): 175 logging.warning( 176 'QuitWindow needs to be updated to work without classic.' 177 ) 178 quit_resource = 'exitGameText' 179 else: 180 quit_resource = ( 181 'quitGameText' 182 if app.classic.platform == 'mac' 183 else 'exitGameText' 184 ) 185 self._root_widget = ui.quit_window = ConfirmWindow( 186 bui.Lstr( 187 resource=quit_resource, 188 subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))], 189 ), 190 lambda: ( 191 bui.quit(confirm=False, quit_type=self._quit_type) 192 if self._quit_type is not None 193 else bui.quit(confirm=False) 194 ), 195 origin_widget=origin_widget, 196 ).root_widget
class
ConfirmWindow:
17class ConfirmWindow: 18 """Window for answering simple yes/no questions.""" 19 20 def __init__( 21 self, 22 text: str | bui.Lstr | None = None, 23 action: Callable[[], Any] | None = None, 24 width: float = 360.0, 25 height: float = 100.0, 26 cancel_button: bool = True, 27 cancel_is_selected: bool = False, 28 color: tuple[float, float, float] = (1, 1, 1), 29 text_scale: float = 1.0, 30 ok_text: str | bui.Lstr | None = None, 31 cancel_text: str | bui.Lstr | None = None, 32 origin_widget: bui.Widget | None = None, 33 ): 34 # pylint: disable=too-many-locals 35 if text is None: 36 text = bui.Lstr(resource='areYouSureText') 37 if ok_text is None: 38 ok_text = bui.Lstr(resource='okText') 39 if cancel_text is None: 40 cancel_text = bui.Lstr(resource='cancelText') 41 height += 40 42 width = max(width, 360) 43 self._action = action 44 45 # if they provided an origin-widget, scale up from that 46 self._transition_out: str | None 47 scale_origin: tuple[float, float] | None 48 if origin_widget is not None: 49 self._transition_out = 'out_scale' 50 scale_origin = origin_widget.get_screen_space_center() 51 transition = 'in_scale' 52 else: 53 self._transition_out = None 54 scale_origin = None 55 transition = 'in_right' 56 57 assert bui.app.classic is not None 58 uiscale = bui.app.ui_v1.uiscale 59 self.root_widget = bui.containerwidget( 60 size=(width, height), 61 transition=transition, 62 toolbar_visibility='menu_minimal_no_back', 63 parent=bui.get_special_widget('overlay_stack'), 64 scale=( 65 1.9 66 if uiscale is bui.UIScale.SMALL 67 else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0 68 ), 69 scale_origin_stack_offset=scale_origin, 70 ) 71 72 bui.textwidget( 73 parent=self.root_widget, 74 position=(width * 0.5, height - 5 - (height - 75) * 0.5), 75 size=(0, 0), 76 h_align='center', 77 v_align='center', 78 text=text, 79 scale=text_scale, 80 color=color, 81 maxwidth=width * 0.9, 82 max_height=height - 75, 83 ) 84 85 cbtn: bui.Widget | None 86 if cancel_button: 87 cbtn = btn = bui.buttonwidget( 88 parent=self.root_widget, 89 autoselect=True, 90 position=(20, 20), 91 size=(150, 50), 92 label=cancel_text, 93 on_activate_call=self._cancel, 94 ) 95 bui.containerwidget(edit=self.root_widget, cancel_button=btn) 96 ok_button_h = width - 175 97 else: 98 # if they don't want a cancel button, we still want back presses to 99 # be able to dismiss the window; just wire it up to do the ok 100 # button 101 ok_button_h = width * 0.5 - 75 102 cbtn = None 103 btn = bui.buttonwidget( 104 parent=self.root_widget, 105 autoselect=True, 106 position=(ok_button_h, 20), 107 size=(150, 50), 108 label=ok_text, 109 on_activate_call=self._ok, 110 ) 111 112 # if they didn't want a cancel button, we still want to be able to hit 113 # cancel/back/etc to dismiss the window 114 if not cancel_button: 115 bui.containerwidget( 116 edit=self.root_widget, on_cancel_call=btn.activate 117 ) 118 119 bui.containerwidget( 120 edit=self.root_widget, 121 selected_child=( 122 cbtn if cbtn is not None and cancel_is_selected else btn 123 ), 124 start_button=btn, 125 ) 126 127 def _cancel(self) -> None: 128 bui.containerwidget( 129 edit=self.root_widget, 130 transition=( 131 'out_right' 132 if self._transition_out is None 133 else self._transition_out 134 ), 135 ) 136 137 def _ok(self) -> None: 138 if not self.root_widget: 139 return 140 bui.containerwidget( 141 edit=self.root_widget, 142 transition=( 143 'out_left' 144 if self._transition_out is None 145 else self._transition_out 146 ), 147 ) 148 if self._action is not None: 149 self._action()
Window for answering simple yes/no questions.
ConfirmWindow( text: str | babase.Lstr | None = None, action: Optional[Callable[[], Any]] = None, width: float = 360.0, height: float = 100.0, cancel_button: bool = True, cancel_is_selected: bool = False, color: tuple[float, float, float] = (1, 1, 1), text_scale: float = 1.0, ok_text: str | babase.Lstr | None = None, cancel_text: str | babase.Lstr | None = None, origin_widget: _bauiv1.Widget | None = None)
20 def __init__( 21 self, 22 text: str | bui.Lstr | None = None, 23 action: Callable[[], Any] | None = None, 24 width: float = 360.0, 25 height: float = 100.0, 26 cancel_button: bool = True, 27 cancel_is_selected: bool = False, 28 color: tuple[float, float, float] = (1, 1, 1), 29 text_scale: float = 1.0, 30 ok_text: str | bui.Lstr | None = None, 31 cancel_text: str | bui.Lstr | None = None, 32 origin_widget: bui.Widget | None = None, 33 ): 34 # pylint: disable=too-many-locals 35 if text is None: 36 text = bui.Lstr(resource='areYouSureText') 37 if ok_text is None: 38 ok_text = bui.Lstr(resource='okText') 39 if cancel_text is None: 40 cancel_text = bui.Lstr(resource='cancelText') 41 height += 40 42 width = max(width, 360) 43 self._action = action 44 45 # if they provided an origin-widget, scale up from that 46 self._transition_out: str | None 47 scale_origin: tuple[float, float] | None 48 if origin_widget is not None: 49 self._transition_out = 'out_scale' 50 scale_origin = origin_widget.get_screen_space_center() 51 transition = 'in_scale' 52 else: 53 self._transition_out = None 54 scale_origin = None 55 transition = 'in_right' 56 57 assert bui.app.classic is not None 58 uiscale = bui.app.ui_v1.uiscale 59 self.root_widget = bui.containerwidget( 60 size=(width, height), 61 transition=transition, 62 toolbar_visibility='menu_minimal_no_back', 63 parent=bui.get_special_widget('overlay_stack'), 64 scale=( 65 1.9 66 if uiscale is bui.UIScale.SMALL 67 else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0 68 ), 69 scale_origin_stack_offset=scale_origin, 70 ) 71 72 bui.textwidget( 73 parent=self.root_widget, 74 position=(width * 0.5, height - 5 - (height - 75) * 0.5), 75 size=(0, 0), 76 h_align='center', 77 v_align='center', 78 text=text, 79 scale=text_scale, 80 color=color, 81 maxwidth=width * 0.9, 82 max_height=height - 75, 83 ) 84 85 cbtn: bui.Widget | None 86 if cancel_button: 87 cbtn = btn = bui.buttonwidget( 88 parent=self.root_widget, 89 autoselect=True, 90 position=(20, 20), 91 size=(150, 50), 92 label=cancel_text, 93 on_activate_call=self._cancel, 94 ) 95 bui.containerwidget(edit=self.root_widget, cancel_button=btn) 96 ok_button_h = width - 175 97 else: 98 # if they don't want a cancel button, we still want back presses to 99 # be able to dismiss the window; just wire it up to do the ok 100 # button 101 ok_button_h = width * 0.5 - 75 102 cbtn = None 103 btn = bui.buttonwidget( 104 parent=self.root_widget, 105 autoselect=True, 106 position=(ok_button_h, 20), 107 size=(150, 50), 108 label=ok_text, 109 on_activate_call=self._ok, 110 ) 111 112 # if they didn't want a cancel button, we still want to be able to hit 113 # cancel/back/etc to dismiss the window 114 if not cancel_button: 115 bui.containerwidget( 116 edit=self.root_widget, on_cancel_call=btn.activate 117 ) 118 119 bui.containerwidget( 120 edit=self.root_widget, 121 selected_child=( 122 cbtn if cbtn is not None and cancel_is_selected else btn 123 ), 124 start_button=btn, 125 )
class
QuitWindow:
152class QuitWindow: 153 """Popup window to confirm quitting.""" 154 155 def __init__( 156 self, 157 quit_type: bui.QuitType | None = None, 158 swish: bool = False, 159 origin_widget: bui.Widget | None = None, 160 ): 161 classic = bui.app.classic 162 assert classic is not None 163 ui = bui.app.ui_v1 164 app = bui.app 165 self._quit_type = quit_type 166 167 # If there's already one of us up somewhere, kill it. 168 if ui.quit_window is not None: 169 ui.quit_window.delete() 170 ui.quit_window = None 171 if swish: 172 bui.getsound('swish').play() 173 174 if app.classic is None: 175 if bui.do_once(): 176 logging.warning( 177 'QuitWindow needs to be updated to work without classic.' 178 ) 179 quit_resource = 'exitGameText' 180 else: 181 quit_resource = ( 182 'quitGameText' 183 if app.classic.platform == 'mac' 184 else 'exitGameText' 185 ) 186 self._root_widget = ui.quit_window = ConfirmWindow( 187 bui.Lstr( 188 resource=quit_resource, 189 subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))], 190 ), 191 lambda: ( 192 bui.quit(confirm=False, quit_type=self._quit_type) 193 if self._quit_type is not None 194 else bui.quit(confirm=False) 195 ), 196 origin_widget=origin_widget, 197 ).root_widget
Popup window to confirm quitting.
QuitWindow( quit_type: babase.QuitType | None = None, swish: bool = False, origin_widget: _bauiv1.Widget | None = None)
155 def __init__( 156 self, 157 quit_type: bui.QuitType | None = None, 158 swish: bool = False, 159 origin_widget: bui.Widget | None = None, 160 ): 161 classic = bui.app.classic 162 assert classic is not None 163 ui = bui.app.ui_v1 164 app = bui.app 165 self._quit_type = quit_type 166 167 # If there's already one of us up somewhere, kill it. 168 if ui.quit_window is not None: 169 ui.quit_window.delete() 170 ui.quit_window = None 171 if swish: 172 bui.getsound('swish').play() 173 174 if app.classic is None: 175 if bui.do_once(): 176 logging.warning( 177 'QuitWindow needs to be updated to work without classic.' 178 ) 179 quit_resource = 'exitGameText' 180 else: 181 quit_resource = ( 182 'quitGameText' 183 if app.classic.platform == 'mac' 184 else 'exitGameText' 185 ) 186 self._root_widget = ui.quit_window = ConfirmWindow( 187 bui.Lstr( 188 resource=quit_resource, 189 subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))], 190 ), 191 lambda: ( 192 bui.quit(confirm=False, quit_type=self._quit_type) 193 if self._quit_type is not None 194 else bui.quit(confirm=False) 195 ), 196 origin_widget=origin_widget, 197 ).root_widget