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