bauiv1lib.serverdialog

Dialog window controlled by the master server.

  1# Released under the MIT License. See LICENSE for details.
  2#
  3"""Dialog window controlled by the master server."""
  4
  5from __future__ import annotations
  6
  7import logging
  8from dataclasses import dataclass, field
  9from typing import Annotated
 10
 11from efro.dataclassio import ioprepped, IOAttrs
 12
 13import bauiv1 as bui
 14
 15
 16@ioprepped
 17@dataclass
 18class ServerDialogData:
 19    """Data for ServerDialog."""
 20
 21    dialog_id: Annotated[str, IOAttrs('dialogID')]
 22    text: Annotated[str, IOAttrs('text')]
 23    subs: Annotated[list[tuple[str, str]], IOAttrs('subs')] = field(
 24        default_factory=list
 25    )
 26    show_cancel: Annotated[bool, IOAttrs('showCancel')] = True
 27    copy_text: Annotated[str | None, IOAttrs('copyText')] = None
 28
 29
 30class ServerDialogWindow(bui.Window):
 31    """A dialog window driven by the master-server."""
 32
 33    def __init__(self, data: ServerDialogData):
 34        self._data = data
 35        txt = bui.Lstr(
 36            translate=('serverResponses', data.text), subs=data.subs
 37        ).evaluate()
 38        txt = txt.strip()
 39        txt_scale = 1.5
 40        txt_height = (
 41            bui.get_string_height(txt, suppress_warning=True) * txt_scale
 42        )
 43        self._width = 500
 44        self._height = 160 + min(200, txt_height)
 45        assert bui.app.classic is not None
 46        uiscale = bui.app.ui_v1.uiscale
 47        super().__init__(
 48            root_widget=bui.containerwidget(
 49                size=(self._width, self._height),
 50                transition='in_scale',
 51                scale=(
 52                    1.8
 53                    if uiscale is bui.UIScale.SMALL
 54                    else 1.35 if uiscale is bui.UIScale.MEDIUM else 1.0
 55                ),
 56            )
 57        )
 58        self._starttime = bui.apptime()
 59
 60        bui.getsound('swish').play()
 61        bui.textwidget(
 62            parent=self._root_widget,
 63            position=(self._width * 0.5, 70 + (self._height - 70) * 0.5),
 64            size=(0, 0),
 65            color=(1.0, 3.0, 1.0),
 66            scale=txt_scale,
 67            h_align='center',
 68            v_align='center',
 69            text=txt,
 70            maxwidth=self._width * 0.85,
 71            max_height=(self._height - 110),
 72        )
 73
 74        show_copy = data.copy_text is not None and bui.clipboard_is_supported()
 75
 76        # Currently can't do both copy and cancel since they go in the same
 77        # spot. Cancel wins in this case since it is important functionality
 78        # and copy is just for convenience (and not even always available).
 79        if show_copy and data.show_cancel:
 80            logging.warning(
 81                'serverdialog requesting both copy and cancel;'
 82                ' copy will not be shown.'
 83            )
 84            show_copy = False
 85
 86        self._cancel_button = (
 87            None
 88            if not data.show_cancel
 89            else bui.buttonwidget(
 90                parent=self._root_widget,
 91                position=(30, 30),
 92                size=(160, 60),
 93                autoselect=True,
 94                label=bui.Lstr(resource='cancelText'),
 95                on_activate_call=self._cancel_press,
 96            )
 97        )
 98
 99        self._copy_button = (
100            None
101            if not show_copy
102            else bui.buttonwidget(
103                parent=self._root_widget,
104                position=(30, 30),
105                size=(160, 60),
106                autoselect=True,
107                label=bui.Lstr(resource='copyText'),
108                on_activate_call=self._copy_press,
109            )
110        )
111
112        self._ok_button = bui.buttonwidget(
113            parent=self._root_widget,
114            position=(
115                (
116                    (self._width - 182)
117                    if (data.show_cancel or show_copy)
118                    else (self._width * 0.5 - 80)
119                ),
120                30,
121            ),
122            size=(160, 60),
123            autoselect=True,
124            label=bui.Lstr(resource='okText'),
125            on_activate_call=self._ok_press,
126        )
127
128        bui.containerwidget(
129            edit=self._root_widget,
130            cancel_button=self._cancel_button,
131            start_button=self._ok_button,
132            selected_child=self._ok_button,
133        )
134
135    def _copy_press(self) -> None:
136        assert self._data.copy_text is not None
137        bui.clipboard_set_text(self._data.copy_text)
138        bui.screenmessage(bui.Lstr(resource='copyConfirmText'), color=(0, 1, 0))
139
140    def _ok_press(self) -> None:
141        plus = bui.app.plus
142        assert plus is not None
143        if bui.apptime() - self._starttime < 1.0:
144            bui.getsound('error').play()
145            return
146        plus.add_v1_account_transaction(
147            {
148                'type': 'DIALOG_RESPONSE',
149                'dialogID': self._data.dialog_id,
150                'response': 1,
151            }
152        )
153        bui.containerwidget(edit=self._root_widget, transition='out_scale')
154
155    def _cancel_press(self) -> None:
156        plus = bui.app.plus
157        assert plus is not None
158        if bui.apptime() - self._starttime < 1.0:
159            bui.getsound('error').play()
160            return
161        plus.add_v1_account_transaction(
162            {
163                'type': 'DIALOG_RESPONSE',
164                'dialogID': self._data.dialog_id,
165                'response': 0,
166            }
167        )
168        bui.containerwidget(edit=self._root_widget, transition='out_scale')
@ioprepped
@dataclass
class ServerDialogData:
17@ioprepped
18@dataclass
19class ServerDialogData:
20    """Data for ServerDialog."""
21
22    dialog_id: Annotated[str, IOAttrs('dialogID')]
23    text: Annotated[str, IOAttrs('text')]
24    subs: Annotated[list[tuple[str, str]], IOAttrs('subs')] = field(
25        default_factory=list
26    )
27    show_cancel: Annotated[bool, IOAttrs('showCancel')] = True
28    copy_text: Annotated[str | None, IOAttrs('copyText')] = None

Data for ServerDialog.

ServerDialogData( dialog_id: Annotated[str, <efro.dataclassio.IOAttrs object>], text: Annotated[str, <efro.dataclassio.IOAttrs object>], subs: Annotated[list[tuple[str, str]], <efro.dataclassio.IOAttrs object>] = <factory>, show_cancel: Annotated[bool, <efro.dataclassio.IOAttrs object>] = True, copy_text: Annotated[str | None, <efro.dataclassio.IOAttrs object>] = None)
dialog_id: Annotated[str, <efro.dataclassio.IOAttrs object at 0x11f4213a0>]
text: Annotated[str, <efro.dataclassio.IOAttrs object at 0x11f421940>]
subs: Annotated[list[tuple[str, str]], <efro.dataclassio.IOAttrs object at 0x11f421c10>]
show_cancel: Annotated[bool, <efro.dataclassio.IOAttrs object at 0x11f421e80>] = True
copy_text: Annotated[str | None, <efro.dataclassio.IOAttrs object at 0x11f421eb0>] = None
class ServerDialogWindow(bauiv1._uitypes.Window):
 31class ServerDialogWindow(bui.Window):
 32    """A dialog window driven by the master-server."""
 33
 34    def __init__(self, data: ServerDialogData):
 35        self._data = data
 36        txt = bui.Lstr(
 37            translate=('serverResponses', data.text), subs=data.subs
 38        ).evaluate()
 39        txt = txt.strip()
 40        txt_scale = 1.5
 41        txt_height = (
 42            bui.get_string_height(txt, suppress_warning=True) * txt_scale
 43        )
 44        self._width = 500
 45        self._height = 160 + min(200, txt_height)
 46        assert bui.app.classic is not None
 47        uiscale = bui.app.ui_v1.uiscale
 48        super().__init__(
 49            root_widget=bui.containerwidget(
 50                size=(self._width, self._height),
 51                transition='in_scale',
 52                scale=(
 53                    1.8
 54                    if uiscale is bui.UIScale.SMALL
 55                    else 1.35 if uiscale is bui.UIScale.MEDIUM else 1.0
 56                ),
 57            )
 58        )
 59        self._starttime = bui.apptime()
 60
 61        bui.getsound('swish').play()
 62        bui.textwidget(
 63            parent=self._root_widget,
 64            position=(self._width * 0.5, 70 + (self._height - 70) * 0.5),
 65            size=(0, 0),
 66            color=(1.0, 3.0, 1.0),
 67            scale=txt_scale,
 68            h_align='center',
 69            v_align='center',
 70            text=txt,
 71            maxwidth=self._width * 0.85,
 72            max_height=(self._height - 110),
 73        )
 74
 75        show_copy = data.copy_text is not None and bui.clipboard_is_supported()
 76
 77        # Currently can't do both copy and cancel since they go in the same
 78        # spot. Cancel wins in this case since it is important functionality
 79        # and copy is just for convenience (and not even always available).
 80        if show_copy and data.show_cancel:
 81            logging.warning(
 82                'serverdialog requesting both copy and cancel;'
 83                ' copy will not be shown.'
 84            )
 85            show_copy = False
 86
 87        self._cancel_button = (
 88            None
 89            if not data.show_cancel
 90            else bui.buttonwidget(
 91                parent=self._root_widget,
 92                position=(30, 30),
 93                size=(160, 60),
 94                autoselect=True,
 95                label=bui.Lstr(resource='cancelText'),
 96                on_activate_call=self._cancel_press,
 97            )
 98        )
 99
100        self._copy_button = (
101            None
102            if not show_copy
103            else bui.buttonwidget(
104                parent=self._root_widget,
105                position=(30, 30),
106                size=(160, 60),
107                autoselect=True,
108                label=bui.Lstr(resource='copyText'),
109                on_activate_call=self._copy_press,
110            )
111        )
112
113        self._ok_button = bui.buttonwidget(
114            parent=self._root_widget,
115            position=(
116                (
117                    (self._width - 182)
118                    if (data.show_cancel or show_copy)
119                    else (self._width * 0.5 - 80)
120                ),
121                30,
122            ),
123            size=(160, 60),
124            autoselect=True,
125            label=bui.Lstr(resource='okText'),
126            on_activate_call=self._ok_press,
127        )
128
129        bui.containerwidget(
130            edit=self._root_widget,
131            cancel_button=self._cancel_button,
132            start_button=self._ok_button,
133            selected_child=self._ok_button,
134        )
135
136    def _copy_press(self) -> None:
137        assert self._data.copy_text is not None
138        bui.clipboard_set_text(self._data.copy_text)
139        bui.screenmessage(bui.Lstr(resource='copyConfirmText'), color=(0, 1, 0))
140
141    def _ok_press(self) -> None:
142        plus = bui.app.plus
143        assert plus is not None
144        if bui.apptime() - self._starttime < 1.0:
145            bui.getsound('error').play()
146            return
147        plus.add_v1_account_transaction(
148            {
149                'type': 'DIALOG_RESPONSE',
150                'dialogID': self._data.dialog_id,
151                'response': 1,
152            }
153        )
154        bui.containerwidget(edit=self._root_widget, transition='out_scale')
155
156    def _cancel_press(self) -> None:
157        plus = bui.app.plus
158        assert plus is not None
159        if bui.apptime() - self._starttime < 1.0:
160            bui.getsound('error').play()
161            return
162        plus.add_v1_account_transaction(
163            {
164                'type': 'DIALOG_RESPONSE',
165                'dialogID': self._data.dialog_id,
166                'response': 0,
167            }
168        )
169        bui.containerwidget(edit=self._root_widget, transition='out_scale')

A dialog window driven by the master-server.

ServerDialogWindow(data: ServerDialogData)
 34    def __init__(self, data: ServerDialogData):
 35        self._data = data
 36        txt = bui.Lstr(
 37            translate=('serverResponses', data.text), subs=data.subs
 38        ).evaluate()
 39        txt = txt.strip()
 40        txt_scale = 1.5
 41        txt_height = (
 42            bui.get_string_height(txt, suppress_warning=True) * txt_scale
 43        )
 44        self._width = 500
 45        self._height = 160 + min(200, txt_height)
 46        assert bui.app.classic is not None
 47        uiscale = bui.app.ui_v1.uiscale
 48        super().__init__(
 49            root_widget=bui.containerwidget(
 50                size=(self._width, self._height),
 51                transition='in_scale',
 52                scale=(
 53                    1.8
 54                    if uiscale is bui.UIScale.SMALL
 55                    else 1.35 if uiscale is bui.UIScale.MEDIUM else 1.0
 56                ),
 57            )
 58        )
 59        self._starttime = bui.apptime()
 60
 61        bui.getsound('swish').play()
 62        bui.textwidget(
 63            parent=self._root_widget,
 64            position=(self._width * 0.5, 70 + (self._height - 70) * 0.5),
 65            size=(0, 0),
 66            color=(1.0, 3.0, 1.0),
 67            scale=txt_scale,
 68            h_align='center',
 69            v_align='center',
 70            text=txt,
 71            maxwidth=self._width * 0.85,
 72            max_height=(self._height - 110),
 73        )
 74
 75        show_copy = data.copy_text is not None and bui.clipboard_is_supported()
 76
 77        # Currently can't do both copy and cancel since they go in the same
 78        # spot. Cancel wins in this case since it is important functionality
 79        # and copy is just for convenience (and not even always available).
 80        if show_copy and data.show_cancel:
 81            logging.warning(
 82                'serverdialog requesting both copy and cancel;'
 83                ' copy will not be shown.'
 84            )
 85            show_copy = False
 86
 87        self._cancel_button = (
 88            None
 89            if not data.show_cancel
 90            else bui.buttonwidget(
 91                parent=self._root_widget,
 92                position=(30, 30),
 93                size=(160, 60),
 94                autoselect=True,
 95                label=bui.Lstr(resource='cancelText'),
 96                on_activate_call=self._cancel_press,
 97            )
 98        )
 99
100        self._copy_button = (
101            None
102            if not show_copy
103            else bui.buttonwidget(
104                parent=self._root_widget,
105                position=(30, 30),
106                size=(160, 60),
107                autoselect=True,
108                label=bui.Lstr(resource='copyText'),
109                on_activate_call=self._copy_press,
110            )
111        )
112
113        self._ok_button = bui.buttonwidget(
114            parent=self._root_widget,
115            position=(
116                (
117                    (self._width - 182)
118                    if (data.show_cancel or show_copy)
119                    else (self._width * 0.5 - 80)
120                ),
121                30,
122            ),
123            size=(160, 60),
124            autoselect=True,
125            label=bui.Lstr(resource='okText'),
126            on_activate_call=self._ok_press,
127        )
128
129        bui.containerwidget(
130            edit=self._root_widget,
131            cancel_button=self._cancel_button,
132            start_button=self._ok_button,
133            selected_child=self._ok_button,
134        )