mirror of
https://github.com/hypervortex/VH-Bombsquad-Modded-Server-Files
synced 2025-11-07 17:36:08 +00:00
169 lines
5.2 KiB
Python
169 lines
5.2 KiB
Python
|
|
# Released under the MIT License. See LICENSE for details.
|
||
|
|
#
|
||
|
|
"""Dialog window controlled by the master server."""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import logging
|
||
|
|
from dataclasses import dataclass, field
|
||
|
|
from typing import TYPE_CHECKING, Annotated
|
||
|
|
|
||
|
|
from efro.dataclassio import ioprepped, IOAttrs
|
||
|
|
|
||
|
|
import ba
|
||
|
|
import ba.internal
|
||
|
|
|
||
|
|
if TYPE_CHECKING:
|
||
|
|
pass
|
||
|
|
|
||
|
|
|
||
|
|
@ioprepped
|
||
|
|
@dataclass
|
||
|
|
class ServerDialogData:
|
||
|
|
"""Data for ServerDialog."""
|
||
|
|
|
||
|
|
dialog_id: Annotated[str, IOAttrs('dialogID')]
|
||
|
|
text: Annotated[str, IOAttrs('text')]
|
||
|
|
subs: Annotated[list[tuple[str, str]], IOAttrs('subs')] = field(
|
||
|
|
default_factory=list
|
||
|
|
)
|
||
|
|
show_cancel: Annotated[bool, IOAttrs('showCancel')] = True
|
||
|
|
copy_text: Annotated[str | None, IOAttrs('copyText')] = None
|
||
|
|
|
||
|
|
|
||
|
|
class ServerDialogWindow(ba.Window):
|
||
|
|
"""A dialog window driven by the master-server."""
|
||
|
|
|
||
|
|
def __init__(self, data: ServerDialogData):
|
||
|
|
self._data = data
|
||
|
|
txt = ba.Lstr(
|
||
|
|
translate=('serverResponses', data.text), subs=data.subs
|
||
|
|
).evaluate()
|
||
|
|
txt = txt.strip()
|
||
|
|
txt_scale = 1.5
|
||
|
|
txt_height = (
|
||
|
|
ba.internal.get_string_height(txt, suppress_warning=True)
|
||
|
|
* txt_scale
|
||
|
|
)
|
||
|
|
self._width = 500
|
||
|
|
self._height = 160 + min(200, txt_height)
|
||
|
|
uiscale = ba.app.ui.uiscale
|
||
|
|
super().__init__(
|
||
|
|
root_widget=ba.containerwidget(
|
||
|
|
size=(self._width, self._height),
|
||
|
|
transition='in_scale',
|
||
|
|
scale=(
|
||
|
|
1.8
|
||
|
|
if uiscale is ba.UIScale.SMALL
|
||
|
|
else 1.35
|
||
|
|
if uiscale is ba.UIScale.MEDIUM
|
||
|
|
else 1.0
|
||
|
|
),
|
||
|
|
)
|
||
|
|
)
|
||
|
|
self._starttime = ba.time(ba.TimeType.REAL)
|
||
|
|
|
||
|
|
ba.playsound(ba.getsound('swish'))
|
||
|
|
ba.textwidget(
|
||
|
|
parent=self._root_widget,
|
||
|
|
position=(self._width * 0.5, 70 + (self._height - 70) * 0.5),
|
||
|
|
size=(0, 0),
|
||
|
|
color=(1.0, 3.0, 1.0),
|
||
|
|
scale=txt_scale,
|
||
|
|
h_align='center',
|
||
|
|
v_align='center',
|
||
|
|
text=txt,
|
||
|
|
maxwidth=self._width * 0.85,
|
||
|
|
max_height=(self._height - 110),
|
||
|
|
)
|
||
|
|
|
||
|
|
show_copy = data.copy_text is not None and ba.clipboard_is_supported()
|
||
|
|
|
||
|
|
# Currently can't do both copy and cancel since they go in the same
|
||
|
|
# spot. Cancel wins in this case since it is important functionality
|
||
|
|
# and copy is just for convenience (and not even always available).
|
||
|
|
if show_copy and data.show_cancel:
|
||
|
|
logging.warning(
|
||
|
|
'serverdialog requesting both copy and cancel;'
|
||
|
|
' copy will not be shown.'
|
||
|
|
)
|
||
|
|
show_copy = False
|
||
|
|
|
||
|
|
self._cancel_button = (
|
||
|
|
None
|
||
|
|
if not data.show_cancel
|
||
|
|
else ba.buttonwidget(
|
||
|
|
parent=self._root_widget,
|
||
|
|
position=(30, 30),
|
||
|
|
size=(160, 60),
|
||
|
|
autoselect=True,
|
||
|
|
label=ba.Lstr(resource='cancelText'),
|
||
|
|
on_activate_call=self._cancel_press,
|
||
|
|
)
|
||
|
|
)
|
||
|
|
|
||
|
|
self._copy_button = (
|
||
|
|
None
|
||
|
|
if not show_copy
|
||
|
|
else ba.buttonwidget(
|
||
|
|
parent=self._root_widget,
|
||
|
|
position=(30, 30),
|
||
|
|
size=(160, 60),
|
||
|
|
autoselect=True,
|
||
|
|
label=ba.Lstr(resource='copyText'),
|
||
|
|
on_activate_call=self._copy_press,
|
||
|
|
)
|
||
|
|
)
|
||
|
|
|
||
|
|
self._ok_button = ba.buttonwidget(
|
||
|
|
parent=self._root_widget,
|
||
|
|
position=(
|
||
|
|
(self._width - 182)
|
||
|
|
if (data.show_cancel or show_copy)
|
||
|
|
else (self._width * 0.5 - 80),
|
||
|
|
30,
|
||
|
|
),
|
||
|
|
size=(160, 60),
|
||
|
|
autoselect=True,
|
||
|
|
label=ba.Lstr(resource='okText'),
|
||
|
|
on_activate_call=self._ok_press,
|
||
|
|
)
|
||
|
|
|
||
|
|
ba.containerwidget(
|
||
|
|
edit=self._root_widget,
|
||
|
|
cancel_button=self._cancel_button,
|
||
|
|
start_button=self._ok_button,
|
||
|
|
selected_child=self._ok_button,
|
||
|
|
)
|
||
|
|
|
||
|
|
def _copy_press(self) -> None:
|
||
|
|
assert self._data.copy_text is not None
|
||
|
|
ba.clipboard_set_text(self._data.copy_text)
|
||
|
|
ba.screenmessage(ba.Lstr(resource='copyConfirmText'), color=(0, 1, 0))
|
||
|
|
|
||
|
|
def _ok_press(self) -> None:
|
||
|
|
if ba.time(ba.TimeType.REAL) - self._starttime < 1.0:
|
||
|
|
ba.playsound(ba.getsound('error'))
|
||
|
|
return
|
||
|
|
ba.internal.add_transaction(
|
||
|
|
{
|
||
|
|
'type': 'DIALOG_RESPONSE',
|
||
|
|
'dialogID': self._data.dialog_id,
|
||
|
|
'response': 1,
|
||
|
|
}
|
||
|
|
)
|
||
|
|
ba.containerwidget(edit=self._root_widget, transition='out_scale')
|
||
|
|
|
||
|
|
def _cancel_press(self) -> None:
|
||
|
|
if ba.time(ba.TimeType.REAL) - self._starttime < 1.0:
|
||
|
|
ba.playsound(ba.getsound('error'))
|
||
|
|
return
|
||
|
|
ba.internal.add_transaction(
|
||
|
|
{
|
||
|
|
'type': 'DIALOG_RESPONSE',
|
||
|
|
'dialogID': self._data.dialog_id,
|
||
|
|
'response': 0,
|
||
|
|
}
|
||
|
|
)
|
||
|
|
ba.containerwidget(edit=self._root_widget, transition='out_scale')
|