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 55 if uiscale is bui.UIScale.MEDIUM 56 else 1.0 57 ), 58 ) 59 ) 60 self._starttime = bui.apptime() 61 62 bui.getsound('swish').play() 63 bui.textwidget( 64 parent=self._root_widget, 65 position=(self._width * 0.5, 70 + (self._height - 70) * 0.5), 66 size=(0, 0), 67 color=(1.0, 3.0, 1.0), 68 scale=txt_scale, 69 h_align='center', 70 v_align='center', 71 text=txt, 72 maxwidth=self._width * 0.85, 73 max_height=(self._height - 110), 74 ) 75 76 show_copy = data.copy_text is not None and bui.clipboard_is_supported() 77 78 # Currently can't do both copy and cancel since they go in the same 79 # spot. Cancel wins in this case since it is important functionality 80 # and copy is just for convenience (and not even always available). 81 if show_copy and data.show_cancel: 82 logging.warning( 83 'serverdialog requesting both copy and cancel;' 84 ' copy will not be shown.' 85 ) 86 show_copy = False 87 88 self._cancel_button = ( 89 None 90 if not data.show_cancel 91 else bui.buttonwidget( 92 parent=self._root_widget, 93 position=(30, 30), 94 size=(160, 60), 95 autoselect=True, 96 label=bui.Lstr(resource='cancelText'), 97 on_activate_call=self._cancel_press, 98 ) 99 ) 100 101 self._copy_button = ( 102 None 103 if not show_copy 104 else bui.buttonwidget( 105 parent=self._root_widget, 106 position=(30, 30), 107 size=(160, 60), 108 autoselect=True, 109 label=bui.Lstr(resource='copyText'), 110 on_activate_call=self._copy_press, 111 ) 112 ) 113 114 self._ok_button = bui.buttonwidget( 115 parent=self._root_widget, 116 position=( 117 (self._width - 182) 118 if (data.show_cancel or show_copy) 119 else (self._width * 0.5 - 80), 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: typing.Annotated[str, <efro.dataclassio._base.IOAttrs object at 0x111c2a750>], text: typing.Annotated[str, <efro.dataclassio._base.IOAttrs object at 0x111c2a5d0>], subs: typing.Annotated[list[tuple[str, str]], <efro.dataclassio._base.IOAttrs object at 0x111c2a850>] = <factory>, show_cancel: typing.Annotated[bool, <efro.dataclassio._base.IOAttrs object at 0x111c2a910>] = True, copy_text: typing.Annotated[str | None, <efro.dataclassio._base.IOAttrs object at 0x111c2a8d0>] = 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 56 if uiscale is bui.UIScale.MEDIUM 57 else 1.0 58 ), 59 ) 60 ) 61 self._starttime = bui.apptime() 62 63 bui.getsound('swish').play() 64 bui.textwidget( 65 parent=self._root_widget, 66 position=(self._width * 0.5, 70 + (self._height - 70) * 0.5), 67 size=(0, 0), 68 color=(1.0, 3.0, 1.0), 69 scale=txt_scale, 70 h_align='center', 71 v_align='center', 72 text=txt, 73 maxwidth=self._width * 0.85, 74 max_height=(self._height - 110), 75 ) 76 77 show_copy = data.copy_text is not None and bui.clipboard_is_supported() 78 79 # Currently can't do both copy and cancel since they go in the same 80 # spot. Cancel wins in this case since it is important functionality 81 # and copy is just for convenience (and not even always available). 82 if show_copy and data.show_cancel: 83 logging.warning( 84 'serverdialog requesting both copy and cancel;' 85 ' copy will not be shown.' 86 ) 87 show_copy = False 88 89 self._cancel_button = ( 90 None 91 if not data.show_cancel 92 else bui.buttonwidget( 93 parent=self._root_widget, 94 position=(30, 30), 95 size=(160, 60), 96 autoselect=True, 97 label=bui.Lstr(resource='cancelText'), 98 on_activate_call=self._cancel_press, 99 ) 100 ) 101 102 self._copy_button = ( 103 None 104 if not show_copy 105 else bui.buttonwidget( 106 parent=self._root_widget, 107 position=(30, 30), 108 size=(160, 60), 109 autoselect=True, 110 label=bui.Lstr(resource='copyText'), 111 on_activate_call=self._copy_press, 112 ) 113 ) 114 115 self._ok_button = bui.buttonwidget( 116 parent=self._root_widget, 117 position=( 118 (self._width - 182) 119 if (data.show_cancel or show_copy) 120 else (self._width * 0.5 - 80), 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 56 if uiscale is bui.UIScale.MEDIUM 57 else 1.0 58 ), 59 ) 60 ) 61 self._starttime = bui.apptime() 62 63 bui.getsound('swish').play() 64 bui.textwidget( 65 parent=self._root_widget, 66 position=(self._width * 0.5, 70 + (self._height - 70) * 0.5), 67 size=(0, 0), 68 color=(1.0, 3.0, 1.0), 69 scale=txt_scale, 70 h_align='center', 71 v_align='center', 72 text=txt, 73 maxwidth=self._width * 0.85, 74 max_height=(self._height - 110), 75 ) 76 77 show_copy = data.copy_text is not None and bui.clipboard_is_supported() 78 79 # Currently can't do both copy and cancel since they go in the same 80 # spot. Cancel wins in this case since it is important functionality 81 # and copy is just for convenience (and not even always available). 82 if show_copy and data.show_cancel: 83 logging.warning( 84 'serverdialog requesting both copy and cancel;' 85 ' copy will not be shown.' 86 ) 87 show_copy = False 88 89 self._cancel_button = ( 90 None 91 if not data.show_cancel 92 else bui.buttonwidget( 93 parent=self._root_widget, 94 position=(30, 30), 95 size=(160, 60), 96 autoselect=True, 97 label=bui.Lstr(resource='cancelText'), 98 on_activate_call=self._cancel_press, 99 ) 100 ) 101 102 self._copy_button = ( 103 None 104 if not show_copy 105 else bui.buttonwidget( 106 parent=self._root_widget, 107 position=(30, 30), 108 size=(160, 60), 109 autoselect=True, 110 label=bui.Lstr(resource='copyText'), 111 on_activate_call=self._copy_press, 112 ) 113 ) 114 115 self._ok_button = bui.buttonwidget( 116 parent=self._root_widget, 117 position=( 118 (self._width - 182) 119 if (data.show_cancel or show_copy) 120 else (self._width * 0.5 - 80), 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 )
Inherited Members
- bauiv1._uitypes.Window
- get_root_widget