Bombsquad-Ballistica-Modded.../dist/ba_data/python/bauiv1lib/confirm.py
2025-10-21 19:08:49 +05:30

209 lines
6.6 KiB
Python

# Released under the MIT License. See LICENSE for details.
#
"""Provides ConfirmWindow base class and commonly used derivatives."""
from __future__ import annotations
from typing import TYPE_CHECKING
import bauiv1 as bui
if TYPE_CHECKING:
from typing import Any, Callable
class ConfirmWindow:
"""Window for answering simple yes/no questions."""
def __init__(
self,
text: str | bui.Lstr | None = None,
action: Callable[[], Any] | None = 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 | bui.Lstr | None = None,
cancel_text: str | bui.Lstr | None = None,
origin_widget: bui.Widget | None = None,
permanent_ok_fade: bool = False,
):
# pylint: disable=too-many-locals
ui = bui.app.ui_v1
# Make sure our widgets have globally unique ids.
self._id_prefix = ui.new_id_prefix('confirm')
if text is None:
text = bui.Lstr(resource='areYouSureText')
if ok_text is None:
ok_text = bui.Lstr(resource='okText')
if cancel_text is None:
cancel_text = bui.Lstr(resource='cancelText')
height += 40
width = max(width, 360)
self._action = action
self._permanent_ok_fade = permanent_ok_fade
# If they provided an origin-widget, scale up from that.
self._transition_out: str | None
scale_origin: tuple[float, float] | None
if origin_widget is not None:
self._transition_out = 'out_scale'
scale_origin = origin_widget.get_screen_space_center()
transition = 'in_scale'
else:
self._transition_out = None
scale_origin = None
transition = 'in_right'
assert bui.app.classic is not None
uiscale = bui.app.ui_v1.uiscale
self.root_widget = bui.containerwidget(
size=(width, height),
transition=transition,
toolbar_visibility='menu_minimal_no_back',
parent=bui.get_special_widget('overlay_stack'),
scale=(
1.9
if uiscale is bui.UIScale.SMALL
else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.0
),
scale_origin_stack_offset=scale_origin,
darken_behind=True,
)
bui.textwidget(
parent=self.root_widget,
position=(width * 0.5, height - 5 - (height - 75) * 0.5),
size=(0, 0),
h_align='center',
v_align='center',
text=text,
scale=text_scale,
color=color,
maxwidth=width * 0.9,
max_height=height - 75,
)
cbtn: bui.Widget | None
if cancel_button:
cbtn = btn = bui.buttonwidget(
parent=self.root_widget,
id=f'{self._id_prefix}|cancel',
autoselect=True,
position=(20, 20),
size=(150, 50),
label=cancel_text,
on_activate_call=self._cancel,
)
bui.containerwidget(edit=self.root_widget, cancel_button=btn)
ok_button_h = width - 175
else:
# if they don't want a cancel button, we still want back
# presses to be able to dismiss the window; just wire it up
# to do the ok button
ok_button_h = width * 0.5 - 75
cbtn = None
btn = bui.buttonwidget(
parent=self.root_widget,
id=f'{self._id_prefix}|ok',
autoselect=True,
position=(ok_button_h, 20),
size=(150, 50),
label=ok_text,
on_activate_call=self._ok,
)
# if they didn't want a cancel button, we still want to be able
# to hit cancel/back/etc to dismiss the window
if not cancel_button:
bui.containerwidget(
edit=self.root_widget, on_cancel_call=btn.activate
)
bui.containerwidget(
edit=self.root_widget,
selected_child=(
cbtn if cbtn is not None and cancel_is_selected else btn
),
start_button=btn,
)
def _cancel(self) -> None:
bui.containerwidget(
edit=self.root_widget,
transition=(
'out_right'
if self._transition_out is None
else self._transition_out
),
)
def _ok(self) -> None:
if not self.root_widget:
return
bui.containerwidget(
edit=self.root_widget,
darken_behind_is_permanent=self._permanent_ok_fade,
transition=(
'out_left'
if self._transition_out is None
else self._transition_out
),
)
if self._action is not None:
self._action()
class QuitWindow:
"""Popup window to confirm quitting."""
def __init__(
self,
quit_type: bui.QuitType | None = None,
swish: bool = False,
origin_widget: bui.Widget | None = None,
):
ui = bui.app.ui_v1
platform = bui.app.env.platform
self._quit_type = quit_type
# If there's already one of us up somewhere, kill it.
if ui.quit_window is not None:
ui.quit_window.delete()
ui.quit_window = None
if swish:
bui.getsound('swish').play()
# Generally Macs say Quit and other stuff says Exit
quit_resource = (
'quitGameText'
if platform is type(platform).MACOS
else 'exitGameText'
)
self._root_widget = ui.quit_window = ConfirmWindow(
bui.Lstr(
resource=quit_resource,
subs=[('${APP_NAME}', bui.Lstr(resource='titleText'))],
),
lambda: (
bui.quit(confirm=False, quit_type=self._quit_type)
if self._quit_type is not None
else bui.quit(confirm=False)
),
origin_widget=origin_widget,
# In situations where the quit action will *actually* kill
# the process, tell the confirm to not fade back in when the
# confirm button is pressed. It just looks a bit visually
# odd if the confirm fades back in just before the app fades
# out to quit.
permanent_ok_fade=not bui.app.env.supports_soft_quit,
).root_widget