# Released under the MIT License. See LICENSE for details.
#
"""Provides a popup window to continue a game."""
from __future__ import annotations
import weakref
from typing import TYPE_CHECKING
import bauiv1 as bui
if TYPE_CHECKING:
from typing import Any, Callable
import bascenev1 as bs
[docs]
class ContinuesWindow(bui.Window):
"""A window to continue a game."""
def __init__(
self,
activity: bs.Activity,
cost: int,
continue_call: Callable[[], Any],
cancel_call: Callable[[], Any],
):
assert bui.app.classic is not None
self._activity = weakref.ref(activity)
self._cost = cost
self._continue_call = continue_call
self._cancel_call = cancel_call
self._start_count = self._count = 20
self._width = 300
self._height = 200
self._transitioning_out = False
super().__init__(
bui.containerwidget(
size=(self._width, self._height),
background=False,
toolbar_visibility='menu_currency',
transition='in_scale',
scale=1.5,
)
)
txt = (
bui.Lstr(resource='continuePurchaseText')
.evaluate()
.split('${PRICE}')
)
t_left = txt[0]
t_left_width = bui.get_string_width(t_left, suppress_warning=True)
t_price = bui.charstr(bui.SpecialChar.TICKET) + str(self._cost)
t_price_width = bui.get_string_width(t_price, suppress_warning=True)
t_right = txt[-1]
t_right_width = bui.get_string_width(t_right, suppress_warning=True)
width_total_half = (t_left_width + t_price_width + t_right_width) * 0.5
bui.textwidget(
parent=self._root_widget,
text=t_left,
flatness=1.0,
shadow=1.0,
size=(0, 0),
h_align='left',
v_align='center',
position=(self._width * 0.5 - width_total_half, self._height - 30),
)
bui.textwidget(
parent=self._root_widget,
text=t_price,
flatness=1.0,
shadow=1.0,
color=(0.2, 1.0, 0.2),
size=(0, 0),
position=(
self._width * 0.5 - width_total_half + t_left_width,
self._height - 30,
),
h_align='left',
v_align='center',
)
bui.textwidget(
parent=self._root_widget,
text=t_right,
flatness=1.0,
shadow=1.0,
size=(0, 0),
h_align='left',
v_align='center',
position=(
self._width * 0.5
- width_total_half
+ t_left_width
+ t_price_width
+ 5,
self._height - 30,
),
)
self._tickets_text_base: str | None
self._tickets_text: bui.Widget | None
if not bui.app.ui_v1.use_toolbars:
self._tickets_text_base = bui.Lstr(
resource='getTicketsWindow.youHaveShortText',
fallback_resource='getTicketsWindow.youHaveText',
).evaluate()
self._tickets_text = bui.textwidget(
parent=self._root_widget,
text='',
flatness=1.0,
color=(0.2, 1.0, 0.2),
shadow=1.0,
position=(
self._width * 0.5 + width_total_half,
self._height - 50,
),
size=(0, 0),
scale=0.35,
h_align='right',
v_align='center',
)
else:
self._tickets_text_base = None
self._tickets_text = None
self._counter_text = bui.textwidget(
parent=self._root_widget,
text=str(self._count),
color=(0.7, 0.7, 0.7),
scale=1.2,
size=(0, 0),
big=True,
position=(self._width * 0.5, self._height - 80),
flatness=1.0,
shadow=1.0,
h_align='center',
v_align='center',
)
self._cancel_button = bui.buttonwidget(
parent=self._root_widget,
position=(30, 30),
size=(120, 50),
label=bui.Lstr(resource='endText', fallback_resource='cancelText'),
autoselect=True,
enable_sound=False,
on_activate_call=self._on_cancel_press,
)
self._continue_button = bui.buttonwidget(
parent=self._root_widget,
label=bui.Lstr(resource='continueText'),
autoselect=True,
position=(self._width - 130, 30),
size=(120, 50),
on_activate_call=self._on_continue_press,
)
bui.containerwidget(
edit=self._root_widget,
cancel_button=self._cancel_button,
start_button=self._continue_button,
selected_child=self._cancel_button,
)
self._counting_down = True
self._countdown_timer = bui.AppTimer(
1.0, bui.WeakCall(self._tick), repeat=True
)
# If there is foreground activity, suspend it.
bui.app.classic.pause()
self._tick()
def __del__(self) -> None:
# If there is suspended foreground activity, resume it.
assert bui.app.classic is not None
bui.app.classic.resume()
def _tick(self) -> None:
plus = bui.app.plus
assert plus is not None
# if our target activity is gone or has ended, go away
activity = self._activity()
if activity is None or activity.has_ended():
self._on_cancel()
return
if plus.get_v1_account_state() == 'signed_in':
sval = bui.charstr(bui.SpecialChar.TICKET) + str(
plus.get_v1_account_ticket_count()
)
else:
sval = '?'
if self._tickets_text is not None:
assert self._tickets_text_base is not None
bui.textwidget(
edit=self._tickets_text,
text=self._tickets_text_base.replace('${COUNT}', sval),
)
if self._counting_down:
self._count -= 1
bui.getsound('tick').play()
if self._count <= 0:
self._on_cancel()
else:
bui.textwidget(edit=self._counter_text, text=str(self._count))
def _on_cancel_press(self) -> None:
# disallow for first second
if self._start_count - self._count < 2:
bui.getsound('error').play()
else:
self._on_cancel()
def _on_continue_press(self) -> None:
from bauiv1lib import getcurrency
plus = bui.app.plus
assert plus is not None
# Disallow for first second.
if self._start_count - self._count < 2:
bui.getsound('error').play()
else:
# If somehow we got signed out...
if plus.get_v1_account_state() != 'signed_in':
bui.screenmessage(
bui.Lstr(resource='notSignedInText'), color=(1, 0, 0)
)
bui.getsound('error').play()
return
# If it appears we don't have enough tickets, offer to buy more.
tickets = plus.get_v1_account_ticket_count()
if tickets < self._cost:
# FIXME: Should we start the timer back up again after?
self._counting_down = False
bui.textwidget(edit=self._counter_text, text='')
bui.getsound('error').play()
getcurrency.show_get_tickets_prompt()
return
if not self._transitioning_out:
bui.getsound('swish').play()
self._transitioning_out = True
bui.containerwidget(
edit=self._root_widget, transition='out_scale'
)
self._continue_call()
def _on_cancel(self) -> None:
if not self._transitioning_out:
bui.getsound('swish').play()
self._transitioning_out = True
bui.containerwidget(edit=self._root_widget, transition='out_scale')
self._cancel_call()