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_currency',
 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        if not bui.app.ui_v1.use_toolbars:
104            self._tickets_text_base = bui.Lstr(
105                resource='getTicketsWindow.youHaveShortText',
106                fallback_resource='getTicketsWindow.youHaveText',
107            ).evaluate()
108            self._tickets_text = bui.textwidget(
109                parent=self._root_widget,
110                text='',
111                flatness=1.0,
112                color=(0.2, 1.0, 0.2),
113                shadow=1.0,
114                position=(
115                    self._width * 0.5 + width_total_half,
116                    self._height - 50,
117                ),
118                size=(0, 0),
119                scale=0.35,
120                h_align='right',
121                v_align='center',
122            )
123        else:
124            self._tickets_text_base = None
125            self._tickets_text = None
126
127        self._counter_text = bui.textwidget(
128            parent=self._root_widget,
129            text=str(self._count),
130            color=(0.7, 0.7, 0.7),
131            scale=1.2,
132            size=(0, 0),
133            big=True,
134            position=(self._width * 0.5, self._height - 80),
135            flatness=1.0,
136            shadow=1.0,
137            h_align='center',
138            v_align='center',
139        )
140        self._cancel_button = bui.buttonwidget(
141            parent=self._root_widget,
142            position=(30, 30),
143            size=(120, 50),
144            label=bui.Lstr(resource='endText', fallback_resource='cancelText'),
145            autoselect=True,
146            enable_sound=False,
147            on_activate_call=self._on_cancel_press,
148        )
149        self._continue_button = bui.buttonwidget(
150            parent=self._root_widget,
151            label=bui.Lstr(resource='continueText'),
152            autoselect=True,
153            position=(self._width - 130, 30),
154            size=(120, 50),
155            on_activate_call=self._on_continue_press,
156        )
157        bui.containerwidget(
158            edit=self._root_widget,
159            cancel_button=self._cancel_button,
160            start_button=self._continue_button,
161            selected_child=self._cancel_button,
162        )
163
164        self._counting_down = True
165        self._countdown_timer = bui.AppTimer(
166            1.0, bui.WeakCall(self._tick), repeat=True
167        )
168
169        # If there is foreground activity, suspend it.
170        bui.app.classic.pause()
171        self._tick()
172
173    def __del__(self) -> None:
174        # If there is suspended foreground activity, resume it.
175        assert bui.app.classic is not None
176        bui.app.classic.resume()
177
178    def _tick(self) -> None:
179        plus = bui.app.plus
180        assert plus is not None
181
182        # if our target activity is gone or has ended, go away
183        activity = self._activity()
184        if activity is None or activity.has_ended():
185            self._on_cancel()
186            return
187
188        if plus.get_v1_account_state() == 'signed_in':
189            sval = bui.charstr(bui.SpecialChar.TICKET) + str(
190                plus.get_v1_account_ticket_count()
191            )
192        else:
193            sval = '?'
194        if self._tickets_text is not None:
195            assert self._tickets_text_base is not None
196            bui.textwidget(
197                edit=self._tickets_text,
198                text=self._tickets_text_base.replace('${COUNT}', sval),
199            )
200
201        if self._counting_down:
202            self._count -= 1
203            bui.getsound('tick').play()
204            if self._count <= 0:
205                self._on_cancel()
206            else:
207                bui.textwidget(edit=self._counter_text, text=str(self._count))
208
209    def _on_cancel_press(self) -> None:
210        # disallow for first second
211        if self._start_count - self._count < 2:
212            bui.getsound('error').play()
213        else:
214            self._on_cancel()
215
216    def _on_continue_press(self) -> None:
217        from bauiv1lib import getcurrency
218
219        plus = bui.app.plus
220        assert plus is not None
221
222        # Disallow for first second.
223        if self._start_count - self._count < 2:
224            bui.getsound('error').play()
225        else:
226            # If somehow we got signed out...
227            if plus.get_v1_account_state() != 'signed_in':
228                bui.screenmessage(
229                    bui.Lstr(resource='notSignedInText'), color=(1, 0, 0)
230                )
231                bui.getsound('error').play()
232                return
233
234            # If it appears we don't have enough tickets, offer to buy more.
235            tickets = plus.get_v1_account_ticket_count()
236            if tickets < self._cost:
237                # FIXME: Should we start the timer back up again after?
238                self._counting_down = False
239                bui.textwidget(edit=self._counter_text, text='')
240                bui.getsound('error').play()
241                getcurrency.show_get_tickets_prompt()
242                return
243            if not self._transitioning_out:
244                bui.getsound('swish').play()
245                self._transitioning_out = True
246                bui.containerwidget(
247                    edit=self._root_widget, transition='out_scale'
248                )
249                self._continue_call()
250
251    def _on_cancel(self) -> None:
252        if not self._transitioning_out:
253            bui.getsound('swish').play()
254            self._transitioning_out = True
255            bui.containerwidget(edit=self._root_widget, transition='out_scale')
256            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_currency',
 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        if not bui.app.ui_v1.use_toolbars:
105            self._tickets_text_base = bui.Lstr(
106                resource='getTicketsWindow.youHaveShortText',
107                fallback_resource='getTicketsWindow.youHaveText',
108            ).evaluate()
109            self._tickets_text = bui.textwidget(
110                parent=self._root_widget,
111                text='',
112                flatness=1.0,
113                color=(0.2, 1.0, 0.2),
114                shadow=1.0,
115                position=(
116                    self._width * 0.5 + width_total_half,
117                    self._height - 50,
118                ),
119                size=(0, 0),
120                scale=0.35,
121                h_align='right',
122                v_align='center',
123            )
124        else:
125            self._tickets_text_base = None
126            self._tickets_text = None
127
128        self._counter_text = bui.textwidget(
129            parent=self._root_widget,
130            text=str(self._count),
131            color=(0.7, 0.7, 0.7),
132            scale=1.2,
133            size=(0, 0),
134            big=True,
135            position=(self._width * 0.5, self._height - 80),
136            flatness=1.0,
137            shadow=1.0,
138            h_align='center',
139            v_align='center',
140        )
141        self._cancel_button = bui.buttonwidget(
142            parent=self._root_widget,
143            position=(30, 30),
144            size=(120, 50),
145            label=bui.Lstr(resource='endText', fallback_resource='cancelText'),
146            autoselect=True,
147            enable_sound=False,
148            on_activate_call=self._on_cancel_press,
149        )
150        self._continue_button = bui.buttonwidget(
151            parent=self._root_widget,
152            label=bui.Lstr(resource='continueText'),
153            autoselect=True,
154            position=(self._width - 130, 30),
155            size=(120, 50),
156            on_activate_call=self._on_continue_press,
157        )
158        bui.containerwidget(
159            edit=self._root_widget,
160            cancel_button=self._cancel_button,
161            start_button=self._continue_button,
162            selected_child=self._cancel_button,
163        )
164
165        self._counting_down = True
166        self._countdown_timer = bui.AppTimer(
167            1.0, bui.WeakCall(self._tick), repeat=True
168        )
169
170        # If there is foreground activity, suspend it.
171        bui.app.classic.pause()
172        self._tick()
173
174    def __del__(self) -> None:
175        # If there is suspended foreground activity, resume it.
176        assert bui.app.classic is not None
177        bui.app.classic.resume()
178
179    def _tick(self) -> None:
180        plus = bui.app.plus
181        assert plus is not None
182
183        # if our target activity is gone or has ended, go away
184        activity = self._activity()
185        if activity is None or activity.has_ended():
186            self._on_cancel()
187            return
188
189        if plus.get_v1_account_state() == 'signed_in':
190            sval = bui.charstr(bui.SpecialChar.TICKET) + str(
191                plus.get_v1_account_ticket_count()
192            )
193        else:
194            sval = '?'
195        if self._tickets_text is not None:
196            assert self._tickets_text_base is not None
197            bui.textwidget(
198                edit=self._tickets_text,
199                text=self._tickets_text_base.replace('${COUNT}', sval),
200            )
201
202        if self._counting_down:
203            self._count -= 1
204            bui.getsound('tick').play()
205            if self._count <= 0:
206                self._on_cancel()
207            else:
208                bui.textwidget(edit=self._counter_text, text=str(self._count))
209
210    def _on_cancel_press(self) -> None:
211        # disallow for first second
212        if self._start_count - self._count < 2:
213            bui.getsound('error').play()
214        else:
215            self._on_cancel()
216
217    def _on_continue_press(self) -> None:
218        from bauiv1lib import getcurrency
219
220        plus = bui.app.plus
221        assert plus is not None
222
223        # Disallow for first second.
224        if self._start_count - self._count < 2:
225            bui.getsound('error').play()
226        else:
227            # If somehow we got signed out...
228            if plus.get_v1_account_state() != 'signed_in':
229                bui.screenmessage(
230                    bui.Lstr(resource='notSignedInText'), color=(1, 0, 0)
231                )
232                bui.getsound('error').play()
233                return
234
235            # If it appears we don't have enough tickets, offer to buy more.
236            tickets = plus.get_v1_account_ticket_count()
237            if tickets < self._cost:
238                # FIXME: Should we start the timer back up again after?
239                self._counting_down = False
240                bui.textwidget(edit=self._counter_text, text='')
241                bui.getsound('error').play()
242                getcurrency.show_get_tickets_prompt()
243                return
244            if not self._transitioning_out:
245                bui.getsound('swish').play()
246                self._transitioning_out = True
247                bui.containerwidget(
248                    edit=self._root_widget, transition='out_scale'
249                )
250                self._continue_call()
251
252    def _on_cancel(self) -> None:
253        if not self._transitioning_out:
254            bui.getsound('swish').play()
255            self._transitioning_out = True
256            bui.containerwidget(edit=self._root_widget, transition='out_scale')
257            self._cancel_call()

A window to continue a game.

ContinuesWindow( activity: bascenev1._activity.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_currency',
 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        if not bui.app.ui_v1.use_toolbars:
105            self._tickets_text_base = bui.Lstr(
106                resource='getTicketsWindow.youHaveShortText',
107                fallback_resource='getTicketsWindow.youHaveText',
108            ).evaluate()
109            self._tickets_text = bui.textwidget(
110                parent=self._root_widget,
111                text='',
112                flatness=1.0,
113                color=(0.2, 1.0, 0.2),
114                shadow=1.0,
115                position=(
116                    self._width * 0.5 + width_total_half,
117                    self._height - 50,
118                ),
119                size=(0, 0),
120                scale=0.35,
121                h_align='right',
122                v_align='center',
123            )
124        else:
125            self._tickets_text_base = None
126            self._tickets_text = None
127
128        self._counter_text = bui.textwidget(
129            parent=self._root_widget,
130            text=str(self._count),
131            color=(0.7, 0.7, 0.7),
132            scale=1.2,
133            size=(0, 0),
134            big=True,
135            position=(self._width * 0.5, self._height - 80),
136            flatness=1.0,
137            shadow=1.0,
138            h_align='center',
139            v_align='center',
140        )
141        self._cancel_button = bui.buttonwidget(
142            parent=self._root_widget,
143            position=(30, 30),
144            size=(120, 50),
145            label=bui.Lstr(resource='endText', fallback_resource='cancelText'),
146            autoselect=True,
147            enable_sound=False,
148            on_activate_call=self._on_cancel_press,
149        )
150        self._continue_button = bui.buttonwidget(
151            parent=self._root_widget,
152            label=bui.Lstr(resource='continueText'),
153            autoselect=True,
154            position=(self._width - 130, 30),
155            size=(120, 50),
156            on_activate_call=self._on_continue_press,
157        )
158        bui.containerwidget(
159            edit=self._root_widget,
160            cancel_button=self._cancel_button,
161            start_button=self._continue_button,
162            selected_child=self._cancel_button,
163        )
164
165        self._counting_down = True
166        self._countdown_timer = bui.AppTimer(
167            1.0, bui.WeakCall(self._tick), repeat=True
168        )
169
170        # If there is foreground activity, suspend it.
171        bui.app.classic.pause()
172        self._tick()
Inherited Members
bauiv1._uitypes.Window
get_root_widget