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>]
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 )