Source code for bauiv1lib.serverdialog

# 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 Annotated

from efro.dataclassio import ioprepped, IOAttrs

import bauiv1 as bui


[docs] @ioprepped @dataclass class ServerDialogData: """Data for ServerDialog.""" dialog_id: str text: str subs: list[tuple[str, str]] = field( default_factory=list ) show_cancel: bool = True copy_text: str | None = None
[docs] class ServerDialogWindow(bui.Window): """A dialog window driven by the master-server.""" def __init__(self, data: ServerDialogData): self._data = data txt = bui.Lstr( translate=('serverResponses', data.text), subs=data.subs ).evaluate() txt = txt.strip() txt_scale = 1.5 txt_height = ( bui.get_string_height(txt, suppress_warning=True) * txt_scale ) self._width = 500 self._height = 160 + min(200, txt_height) assert bui.app.classic is not None uiscale = bui.app.ui_v1.uiscale super().__init__( root_widget=bui.containerwidget( size=(self._width, self._height), transition='in_scale', scale=( 1.8 if uiscale is bui.UIScale.SMALL else 1.35 if uiscale is bui.UIScale.MEDIUM else 1.0 ), ) ) self._starttime = bui.apptime() bui.getsound('swish').play() bui.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 bui.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 bui.buttonwidget( parent=self._root_widget, position=(30, 30), size=(160, 60), autoselect=True, label=bui.Lstr(resource='cancelText'), on_activate_call=self._cancel_press, ) ) self._copy_button = ( None if not show_copy else bui.buttonwidget( parent=self._root_widget, position=(30, 30), size=(160, 60), autoselect=True, label=bui.Lstr(resource='copyText'), on_activate_call=self._copy_press, ) ) self._ok_button = bui.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=bui.Lstr(resource='okText'), on_activate_call=self._ok_press, ) bui.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 bui.clipboard_set_text(self._data.copy_text) bui.screenmessage(bui.Lstr(resource='copyConfirmText'), color=(0, 1, 0)) def _ok_press(self) -> None: plus = bui.app.plus assert plus is not None if bui.apptime() - self._starttime < 1.0: bui.getsound('error').play() return plus.add_v1_account_transaction( { 'type': 'DIALOG_RESPONSE', 'dialogID': self._data.dialog_id, 'response': 1, } ) bui.containerwidget(edit=self._root_widget, transition='out_scale') def _cancel_press(self) -> None: plus = bui.app.plus assert plus is not None if bui.apptime() - self._starttime < 1.0: bui.getsound('error').play() return plus.add_v1_account_transaction( { 'type': 'DIALOG_RESPONSE', 'dialogID': self._data.dialog_id, 'response': 0, } ) bui.containerwidget(edit=self._root_widget, transition='out_scale')
# Docs-generation hack; import some stuff that we likely only forward-declared # in our actual source code so that docs tools can find it. from typing import (Coroutine, Any, Literal, Callable, Generator, Awaitable, Sequence, Self) import asyncio from concurrent.futures import Future from pathlib import Path from enum import Enum