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