bastd.ui.continues
Provides a popup window to continue a game.
1# Released under the MIT License. See LICENSE for details. 2# 3"""Provides a popup window to continue a game.""" 4 5from __future__ import annotations 6 7import weakref 8from typing import TYPE_CHECKING 9 10import _ba 11import ba 12 13if TYPE_CHECKING: 14 from typing import Any, Callable 15 16 17class ContinuesWindow(ba.Window): 18 """A window to continue a game.""" 19 20 def __init__(self, activity: ba.Activity, cost: int, 21 continue_call: Callable[[], Any], cancel_call: Callable[[], 22 Any]): 23 self._activity = weakref.ref(activity) 24 self._cost = cost 25 self._continue_call = continue_call 26 self._cancel_call = cancel_call 27 self._start_count = self._count = 20 28 self._width = 300 29 self._height = 200 30 self._transitioning_out = False 31 super().__init__( 32 ba.containerwidget(size=(self._width, self._height), 33 background=False, 34 toolbar_visibility='menu_currency', 35 transition='in_scale', 36 scale=1.5)) 37 txt = (ba.Lstr( 38 resource='continuePurchaseText').evaluate().split('${PRICE}')) 39 t_left = txt[0] 40 t_left_width = _ba.get_string_width(t_left, suppress_warning=True) 41 t_price = ba.charstr(ba.SpecialChar.TICKET) + str(self._cost) 42 t_price_width = _ba.get_string_width(t_price, suppress_warning=True) 43 t_right = txt[-1] 44 t_right_width = _ba.get_string_width(t_right, suppress_warning=True) 45 width_total_half = (t_left_width + t_price_width + t_right_width) * 0.5 46 47 ba.textwidget(parent=self._root_widget, 48 text=t_left, 49 flatness=1.0, 50 shadow=1.0, 51 size=(0, 0), 52 h_align='left', 53 v_align='center', 54 position=(self._width * 0.5 - width_total_half, 55 self._height - 30)) 56 ba.textwidget(parent=self._root_widget, 57 text=t_price, 58 flatness=1.0, 59 shadow=1.0, 60 color=(0.2, 1.0, 0.2), 61 size=(0, 0), 62 position=(self._width * 0.5 - width_total_half + 63 t_left_width, self._height - 30), 64 h_align='left', 65 v_align='center') 66 ba.textwidget(parent=self._root_widget, 67 text=t_right, 68 flatness=1.0, 69 shadow=1.0, 70 size=(0, 0), 71 h_align='left', 72 v_align='center', 73 position=(self._width * 0.5 - width_total_half + 74 t_left_width + t_price_width + 5, 75 self._height - 30)) 76 77 self._tickets_text_base: str | None 78 self._tickets_text: ba.Widget | None 79 if not ba.app.ui.use_toolbars: 80 self._tickets_text_base = ba.Lstr( 81 resource='getTicketsWindow.youHaveShortText', 82 fallback_resource='getTicketsWindow.youHaveText').evaluate() 83 self._tickets_text = ba.textwidget( 84 parent=self._root_widget, 85 text='', 86 flatness=1.0, 87 color=(0.2, 1.0, 0.2), 88 shadow=1.0, 89 position=(self._width * 0.5 + width_total_half, 90 self._height - 50), 91 size=(0, 0), 92 scale=0.35, 93 h_align='right', 94 v_align='center') 95 else: 96 self._tickets_text_base = None 97 self._tickets_text = None 98 99 self._counter_text = ba.textwidget(parent=self._root_widget, 100 text=str(self._count), 101 color=(0.7, 0.7, 0.7), 102 scale=1.2, 103 size=(0, 0), 104 big=True, 105 position=(self._width * 0.5, 106 self._height - 80), 107 flatness=1.0, 108 shadow=1.0, 109 h_align='center', 110 v_align='center') 111 self._cancel_button = ba.buttonwidget( 112 parent=self._root_widget, 113 position=(30, 30), 114 size=(120, 50), 115 label=ba.Lstr(resource='endText', fallback_resource='cancelText'), 116 autoselect=True, 117 enable_sound=False, 118 on_activate_call=self._on_cancel_press) 119 self._continue_button = ba.buttonwidget( 120 parent=self._root_widget, 121 label=ba.Lstr(resource='continueText'), 122 autoselect=True, 123 position=(self._width - 130, 30), 124 size=(120, 50), 125 on_activate_call=self._on_continue_press) 126 ba.containerwidget(edit=self._root_widget, 127 cancel_button=self._cancel_button, 128 start_button=self._continue_button, 129 selected_child=self._cancel_button) 130 131 self._counting_down = True 132 self._countdown_timer = ba.Timer(1.0, 133 ba.WeakCall(self._tick), 134 repeat=True, 135 timetype=ba.TimeType.REAL) 136 self._tick() 137 138 def _tick(self) -> None: 139 # if our target activity is gone or has ended, go away 140 activity = self._activity() 141 if activity is None or activity.has_ended(): 142 self._on_cancel() 143 return 144 145 if _ba.get_v1_account_state() == 'signed_in': 146 sval = (ba.charstr(ba.SpecialChar.TICKET) + 147 str(_ba.get_v1_account_ticket_count())) 148 else: 149 sval = '?' 150 if self._tickets_text is not None: 151 assert self._tickets_text_base is not None 152 ba.textwidget(edit=self._tickets_text, 153 text=self._tickets_text_base.replace( 154 '${COUNT}', sval)) 155 156 if self._counting_down: 157 self._count -= 1 158 ba.playsound(ba.getsound('tick')) 159 if self._count <= 0: 160 self._on_cancel() 161 else: 162 ba.textwidget(edit=self._counter_text, text=str(self._count)) 163 164 def _on_cancel_press(self) -> None: 165 # disallow for first second 166 if self._start_count - self._count < 2: 167 ba.playsound(ba.getsound('error')) 168 else: 169 self._on_cancel() 170 171 def _on_continue_press(self) -> None: 172 from bastd.ui import getcurrency 173 174 # Disallow for first second. 175 if self._start_count - self._count < 2: 176 ba.playsound(ba.getsound('error')) 177 else: 178 # If somehow we got signed out... 179 if _ba.get_v1_account_state() != 'signed_in': 180 ba.screenmessage(ba.Lstr(resource='notSignedInText'), 181 color=(1, 0, 0)) 182 ba.playsound(ba.getsound('error')) 183 return 184 185 # If it appears we don't have enough tickets, offer to buy more. 186 tickets = _ba.get_v1_account_ticket_count() 187 if tickets < self._cost: 188 # FIXME: Should we start the timer back up again after? 189 self._counting_down = False 190 ba.textwidget(edit=self._counter_text, text='') 191 ba.playsound(ba.getsound('error')) 192 getcurrency.show_get_tickets_prompt() 193 return 194 if not self._transitioning_out: 195 ba.playsound(ba.getsound('swish')) 196 self._transitioning_out = True 197 ba.containerwidget(edit=self._root_widget, 198 transition='out_scale') 199 self._continue_call() 200 201 def _on_cancel(self) -> None: 202 if not self._transitioning_out: 203 ba.playsound(ba.getsound('swish')) 204 self._transitioning_out = True 205 ba.containerwidget(edit=self._root_widget, transition='out_scale') 206 self._cancel_call()
class
ContinuesWindow(ba.ui.Window):
18class ContinuesWindow(ba.Window): 19 """A window to continue a game.""" 20 21 def __init__(self, activity: ba.Activity, cost: int, 22 continue_call: Callable[[], Any], cancel_call: Callable[[], 23 Any]): 24 self._activity = weakref.ref(activity) 25 self._cost = cost 26 self._continue_call = continue_call 27 self._cancel_call = cancel_call 28 self._start_count = self._count = 20 29 self._width = 300 30 self._height = 200 31 self._transitioning_out = False 32 super().__init__( 33 ba.containerwidget(size=(self._width, self._height), 34 background=False, 35 toolbar_visibility='menu_currency', 36 transition='in_scale', 37 scale=1.5)) 38 txt = (ba.Lstr( 39 resource='continuePurchaseText').evaluate().split('${PRICE}')) 40 t_left = txt[0] 41 t_left_width = _ba.get_string_width(t_left, suppress_warning=True) 42 t_price = ba.charstr(ba.SpecialChar.TICKET) + str(self._cost) 43 t_price_width = _ba.get_string_width(t_price, suppress_warning=True) 44 t_right = txt[-1] 45 t_right_width = _ba.get_string_width(t_right, suppress_warning=True) 46 width_total_half = (t_left_width + t_price_width + t_right_width) * 0.5 47 48 ba.textwidget(parent=self._root_widget, 49 text=t_left, 50 flatness=1.0, 51 shadow=1.0, 52 size=(0, 0), 53 h_align='left', 54 v_align='center', 55 position=(self._width * 0.5 - width_total_half, 56 self._height - 30)) 57 ba.textwidget(parent=self._root_widget, 58 text=t_price, 59 flatness=1.0, 60 shadow=1.0, 61 color=(0.2, 1.0, 0.2), 62 size=(0, 0), 63 position=(self._width * 0.5 - width_total_half + 64 t_left_width, self._height - 30), 65 h_align='left', 66 v_align='center') 67 ba.textwidget(parent=self._root_widget, 68 text=t_right, 69 flatness=1.0, 70 shadow=1.0, 71 size=(0, 0), 72 h_align='left', 73 v_align='center', 74 position=(self._width * 0.5 - width_total_half + 75 t_left_width + t_price_width + 5, 76 self._height - 30)) 77 78 self._tickets_text_base: str | None 79 self._tickets_text: ba.Widget | None 80 if not ba.app.ui.use_toolbars: 81 self._tickets_text_base = ba.Lstr( 82 resource='getTicketsWindow.youHaveShortText', 83 fallback_resource='getTicketsWindow.youHaveText').evaluate() 84 self._tickets_text = ba.textwidget( 85 parent=self._root_widget, 86 text='', 87 flatness=1.0, 88 color=(0.2, 1.0, 0.2), 89 shadow=1.0, 90 position=(self._width * 0.5 + width_total_half, 91 self._height - 50), 92 size=(0, 0), 93 scale=0.35, 94 h_align='right', 95 v_align='center') 96 else: 97 self._tickets_text_base = None 98 self._tickets_text = None 99 100 self._counter_text = ba.textwidget(parent=self._root_widget, 101 text=str(self._count), 102 color=(0.7, 0.7, 0.7), 103 scale=1.2, 104 size=(0, 0), 105 big=True, 106 position=(self._width * 0.5, 107 self._height - 80), 108 flatness=1.0, 109 shadow=1.0, 110 h_align='center', 111 v_align='center') 112 self._cancel_button = ba.buttonwidget( 113 parent=self._root_widget, 114 position=(30, 30), 115 size=(120, 50), 116 label=ba.Lstr(resource='endText', fallback_resource='cancelText'), 117 autoselect=True, 118 enable_sound=False, 119 on_activate_call=self._on_cancel_press) 120 self._continue_button = ba.buttonwidget( 121 parent=self._root_widget, 122 label=ba.Lstr(resource='continueText'), 123 autoselect=True, 124 position=(self._width - 130, 30), 125 size=(120, 50), 126 on_activate_call=self._on_continue_press) 127 ba.containerwidget(edit=self._root_widget, 128 cancel_button=self._cancel_button, 129 start_button=self._continue_button, 130 selected_child=self._cancel_button) 131 132 self._counting_down = True 133 self._countdown_timer = ba.Timer(1.0, 134 ba.WeakCall(self._tick), 135 repeat=True, 136 timetype=ba.TimeType.REAL) 137 self._tick() 138 139 def _tick(self) -> None: 140 # if our target activity is gone or has ended, go away 141 activity = self._activity() 142 if activity is None or activity.has_ended(): 143 self._on_cancel() 144 return 145 146 if _ba.get_v1_account_state() == 'signed_in': 147 sval = (ba.charstr(ba.SpecialChar.TICKET) + 148 str(_ba.get_v1_account_ticket_count())) 149 else: 150 sval = '?' 151 if self._tickets_text is not None: 152 assert self._tickets_text_base is not None 153 ba.textwidget(edit=self._tickets_text, 154 text=self._tickets_text_base.replace( 155 '${COUNT}', sval)) 156 157 if self._counting_down: 158 self._count -= 1 159 ba.playsound(ba.getsound('tick')) 160 if self._count <= 0: 161 self._on_cancel() 162 else: 163 ba.textwidget(edit=self._counter_text, text=str(self._count)) 164 165 def _on_cancel_press(self) -> None: 166 # disallow for first second 167 if self._start_count - self._count < 2: 168 ba.playsound(ba.getsound('error')) 169 else: 170 self._on_cancel() 171 172 def _on_continue_press(self) -> None: 173 from bastd.ui import getcurrency 174 175 # Disallow for first second. 176 if self._start_count - self._count < 2: 177 ba.playsound(ba.getsound('error')) 178 else: 179 # If somehow we got signed out... 180 if _ba.get_v1_account_state() != 'signed_in': 181 ba.screenmessage(ba.Lstr(resource='notSignedInText'), 182 color=(1, 0, 0)) 183 ba.playsound(ba.getsound('error')) 184 return 185 186 # If it appears we don't have enough tickets, offer to buy more. 187 tickets = _ba.get_v1_account_ticket_count() 188 if tickets < self._cost: 189 # FIXME: Should we start the timer back up again after? 190 self._counting_down = False 191 ba.textwidget(edit=self._counter_text, text='') 192 ba.playsound(ba.getsound('error')) 193 getcurrency.show_get_tickets_prompt() 194 return 195 if not self._transitioning_out: 196 ba.playsound(ba.getsound('swish')) 197 self._transitioning_out = True 198 ba.containerwidget(edit=self._root_widget, 199 transition='out_scale') 200 self._continue_call() 201 202 def _on_cancel(self) -> None: 203 if not self._transitioning_out: 204 ba.playsound(ba.getsound('swish')) 205 self._transitioning_out = True 206 ba.containerwidget(edit=self._root_widget, transition='out_scale') 207 self._cancel_call()
A window to continue a game.
ContinuesWindow( activity: ba._activity.Activity, cost: int, continue_call: Callable[[], Any], cancel_call: Callable[[], Any])
21 def __init__(self, activity: ba.Activity, cost: int, 22 continue_call: Callable[[], Any], cancel_call: Callable[[], 23 Any]): 24 self._activity = weakref.ref(activity) 25 self._cost = cost 26 self._continue_call = continue_call 27 self._cancel_call = cancel_call 28 self._start_count = self._count = 20 29 self._width = 300 30 self._height = 200 31 self._transitioning_out = False 32 super().__init__( 33 ba.containerwidget(size=(self._width, self._height), 34 background=False, 35 toolbar_visibility='menu_currency', 36 transition='in_scale', 37 scale=1.5)) 38 txt = (ba.Lstr( 39 resource='continuePurchaseText').evaluate().split('${PRICE}')) 40 t_left = txt[0] 41 t_left_width = _ba.get_string_width(t_left, suppress_warning=True) 42 t_price = ba.charstr(ba.SpecialChar.TICKET) + str(self._cost) 43 t_price_width = _ba.get_string_width(t_price, suppress_warning=True) 44 t_right = txt[-1] 45 t_right_width = _ba.get_string_width(t_right, suppress_warning=True) 46 width_total_half = (t_left_width + t_price_width + t_right_width) * 0.5 47 48 ba.textwidget(parent=self._root_widget, 49 text=t_left, 50 flatness=1.0, 51 shadow=1.0, 52 size=(0, 0), 53 h_align='left', 54 v_align='center', 55 position=(self._width * 0.5 - width_total_half, 56 self._height - 30)) 57 ba.textwidget(parent=self._root_widget, 58 text=t_price, 59 flatness=1.0, 60 shadow=1.0, 61 color=(0.2, 1.0, 0.2), 62 size=(0, 0), 63 position=(self._width * 0.5 - width_total_half + 64 t_left_width, self._height - 30), 65 h_align='left', 66 v_align='center') 67 ba.textwidget(parent=self._root_widget, 68 text=t_right, 69 flatness=1.0, 70 shadow=1.0, 71 size=(0, 0), 72 h_align='left', 73 v_align='center', 74 position=(self._width * 0.5 - width_total_half + 75 t_left_width + t_price_width + 5, 76 self._height - 30)) 77 78 self._tickets_text_base: str | None 79 self._tickets_text: ba.Widget | None 80 if not ba.app.ui.use_toolbars: 81 self._tickets_text_base = ba.Lstr( 82 resource='getTicketsWindow.youHaveShortText', 83 fallback_resource='getTicketsWindow.youHaveText').evaluate() 84 self._tickets_text = ba.textwidget( 85 parent=self._root_widget, 86 text='', 87 flatness=1.0, 88 color=(0.2, 1.0, 0.2), 89 shadow=1.0, 90 position=(self._width * 0.5 + width_total_half, 91 self._height - 50), 92 size=(0, 0), 93 scale=0.35, 94 h_align='right', 95 v_align='center') 96 else: 97 self._tickets_text_base = None 98 self._tickets_text = None 99 100 self._counter_text = ba.textwidget(parent=self._root_widget, 101 text=str(self._count), 102 color=(0.7, 0.7, 0.7), 103 scale=1.2, 104 size=(0, 0), 105 big=True, 106 position=(self._width * 0.5, 107 self._height - 80), 108 flatness=1.0, 109 shadow=1.0, 110 h_align='center', 111 v_align='center') 112 self._cancel_button = ba.buttonwidget( 113 parent=self._root_widget, 114 position=(30, 30), 115 size=(120, 50), 116 label=ba.Lstr(resource='endText', fallback_resource='cancelText'), 117 autoselect=True, 118 enable_sound=False, 119 on_activate_call=self._on_cancel_press) 120 self._continue_button = ba.buttonwidget( 121 parent=self._root_widget, 122 label=ba.Lstr(resource='continueText'), 123 autoselect=True, 124 position=(self._width - 130, 30), 125 size=(120, 50), 126 on_activate_call=self._on_continue_press) 127 ba.containerwidget(edit=self._root_widget, 128 cancel_button=self._cancel_button, 129 start_button=self._continue_button, 130 selected_child=self._cancel_button) 131 132 self._counting_down = True 133 self._countdown_timer = ba.Timer(1.0, 134 ba.WeakCall(self._tick), 135 repeat=True, 136 timetype=ba.TimeType.REAL) 137 self._tick()
Inherited Members
- ba.ui.Window
- get_root_widget