bauiv1lib.purchase

UI related to purchasing items.

  1# Released under the MIT License. See LICENSE for details.
  2#
  3"""UI related to purchasing items."""
  4
  5from __future__ import annotations
  6
  7from typing import TYPE_CHECKING
  8
  9import bauiv1 as bui
 10
 11if TYPE_CHECKING:
 12    from typing import Any
 13
 14
 15class PurchaseWindow(bui.Window):
 16    """Window for purchasing one or more items."""
 17
 18    def __init__(
 19        self,
 20        items: list[str],
 21        transition: str = 'in_right',
 22        header_text: bui.Lstr | None = None,
 23    ):
 24        from bauiv1lib.store.item import instantiate_store_item_display
 25
 26        plus = bui.app.plus
 27        assert plus is not None
 28
 29        assert bui.app.classic is not None
 30        store = bui.app.classic.store
 31
 32        if header_text is None:
 33            header_text = bui.Lstr(
 34                resource='unlockThisText',
 35                fallback_resource='unlockThisInTheStoreText',
 36            )
 37        if len(items) != 1:
 38            raise ValueError('expected exactly 1 item')
 39        self._items = list(items)
 40        self._width = 580
 41        self._height = 520
 42        uiscale = bui.app.ui_v1.uiscale
 43        super().__init__(
 44            root_widget=bui.containerwidget(
 45                size=(self._width, self._height),
 46                transition=transition,
 47                toolbar_visibility='menu_currency',
 48                scale=(
 49                    1.2
 50                    if uiscale is bui.UIScale.SMALL
 51                    else 1.1 if uiscale is bui.UIScale.MEDIUM else 1.0
 52                ),
 53                stack_offset=(
 54                    (0, -15) if uiscale is bui.UIScale.SMALL else (0, 0)
 55                ),
 56            )
 57        )
 58        self._is_double = False
 59        self._title_text = bui.textwidget(
 60            parent=self._root_widget,
 61            position=(self._width * 0.5, self._height - 30),
 62            size=(0, 0),
 63            text=header_text,
 64            h_align='center',
 65            v_align='center',
 66            maxwidth=self._width * 0.9 - 120,
 67            scale=1.2,
 68            color=(1, 0.8, 0.3, 1),
 69        )
 70        size = store.get_store_item_display_size(items[0])
 71        display: dict[str, Any] = {}
 72        instantiate_store_item_display(
 73            items[0],
 74            display,
 75            parent_widget=self._root_widget,
 76            b_pos=(
 77                self._width * 0.5
 78                - size[0] * 0.5
 79                + 10
 80                - ((size[0] * 0.5 + 30) if self._is_double else 0),
 81                self._height * 0.5
 82                - size[1] * 0.5
 83                + 30
 84                + (20 if self._is_double else 0),
 85            ),
 86            b_width=size[0],
 87            b_height=size[1],
 88            button=False,
 89        )
 90
 91        # Wire up the parts we need.
 92        if self._is_double:
 93            pass  # not working
 94        else:
 95            if self._items == ['pro']:
 96                price_str = plus.get_price(self._items[0])
 97                pyoffs = -15
 98            else:
 99                pyoffs = 0
100                price = self._price = plus.get_v1_account_misc_read_val(
101                    'price.' + str(items[0]), -1
102                )
103                price_str = bui.charstr(bui.SpecialChar.TICKET) + str(price)
104            self._price_text = bui.textwidget(
105                parent=self._root_widget,
106                position=(self._width * 0.5, 150 + pyoffs),
107                size=(0, 0),
108                text=price_str,
109                h_align='center',
110                v_align='center',
111                maxwidth=self._width * 0.9,
112                scale=1.4,
113                color=(0.2, 1, 0.2),
114            )
115
116        self._update_timer = bui.AppTimer(
117            1.0, bui.WeakCall(self._update), repeat=True
118        )
119
120        self._cancel_button = bui.buttonwidget(
121            parent=self._root_widget,
122            position=(50, 40),
123            size=(150, 60),
124            scale=1.0,
125            on_activate_call=self._cancel,
126            autoselect=True,
127            label=bui.Lstr(resource='cancelText'),
128        )
129        self._purchase_button = bui.buttonwidget(
130            parent=self._root_widget,
131            position=(self._width - 200, 40),
132            size=(150, 60),
133            scale=1.0,
134            on_activate_call=self._purchase,
135            autoselect=True,
136            label=bui.Lstr(resource='store.purchaseText'),
137        )
138
139        bui.containerwidget(
140            edit=self._root_widget,
141            cancel_button=self._cancel_button,
142            start_button=self._purchase_button,
143            selected_child=self._purchase_button,
144        )
145
146    def _update(self) -> None:
147        can_die = False
148
149        plus = bui.app.plus
150        assert plus is not None
151
152        # We go away if we see that our target item is owned.
153        if self._items == ['pro']:
154            assert bui.app.classic is not None
155            if bui.app.classic.accounts.have_pro():
156                can_die = True
157        else:
158            if plus.get_purchased(self._items[0]):
159                can_die = True
160
161        if can_die:
162            bui.containerwidget(edit=self._root_widget, transition='out_left')
163
164    def _purchase(self) -> None:
165        from bauiv1lib import getcurrency
166
167        plus = bui.app.plus
168        assert plus is not None
169
170        if self._items == ['pro']:
171            plus.purchase('pro')
172        else:
173            ticket_count: int | None
174            try:
175                ticket_count = plus.get_v1_account_ticket_count()
176            except Exception:
177                ticket_count = None
178            if ticket_count is not None and ticket_count < self._price:
179                getcurrency.show_get_tickets_prompt()
180                bui.getsound('error').play()
181                return
182
183            def do_it() -> None:
184                assert plus is not None
185
186                plus.in_game_purchase(self._items[0], self._price)
187
188            bui.getsound('swish').play()
189            do_it()
190
191    def _cancel(self) -> None:
192        bui.containerwidget(edit=self._root_widget, transition='out_right')
class PurchaseWindow(bauiv1._uitypes.Window):
 16class PurchaseWindow(bui.Window):
 17    """Window for purchasing one or more items."""
 18
 19    def __init__(
 20        self,
 21        items: list[str],
 22        transition: str = 'in_right',
 23        header_text: bui.Lstr | None = None,
 24    ):
 25        from bauiv1lib.store.item import instantiate_store_item_display
 26
 27        plus = bui.app.plus
 28        assert plus is not None
 29
 30        assert bui.app.classic is not None
 31        store = bui.app.classic.store
 32
 33        if header_text is None:
 34            header_text = bui.Lstr(
 35                resource='unlockThisText',
 36                fallback_resource='unlockThisInTheStoreText',
 37            )
 38        if len(items) != 1:
 39            raise ValueError('expected exactly 1 item')
 40        self._items = list(items)
 41        self._width = 580
 42        self._height = 520
 43        uiscale = bui.app.ui_v1.uiscale
 44        super().__init__(
 45            root_widget=bui.containerwidget(
 46                size=(self._width, self._height),
 47                transition=transition,
 48                toolbar_visibility='menu_currency',
 49                scale=(
 50                    1.2
 51                    if uiscale is bui.UIScale.SMALL
 52                    else 1.1 if uiscale is bui.UIScale.MEDIUM else 1.0
 53                ),
 54                stack_offset=(
 55                    (0, -15) if uiscale is bui.UIScale.SMALL else (0, 0)
 56                ),
 57            )
 58        )
 59        self._is_double = False
 60        self._title_text = bui.textwidget(
 61            parent=self._root_widget,
 62            position=(self._width * 0.5, self._height - 30),
 63            size=(0, 0),
 64            text=header_text,
 65            h_align='center',
 66            v_align='center',
 67            maxwidth=self._width * 0.9 - 120,
 68            scale=1.2,
 69            color=(1, 0.8, 0.3, 1),
 70        )
 71        size = store.get_store_item_display_size(items[0])
 72        display: dict[str, Any] = {}
 73        instantiate_store_item_display(
 74            items[0],
 75            display,
 76            parent_widget=self._root_widget,
 77            b_pos=(
 78                self._width * 0.5
 79                - size[0] * 0.5
 80                + 10
 81                - ((size[0] * 0.5 + 30) if self._is_double else 0),
 82                self._height * 0.5
 83                - size[1] * 0.5
 84                + 30
 85                + (20 if self._is_double else 0),
 86            ),
 87            b_width=size[0],
 88            b_height=size[1],
 89            button=False,
 90        )
 91
 92        # Wire up the parts we need.
 93        if self._is_double:
 94            pass  # not working
 95        else:
 96            if self._items == ['pro']:
 97                price_str = plus.get_price(self._items[0])
 98                pyoffs = -15
 99            else:
100                pyoffs = 0
101                price = self._price = plus.get_v1_account_misc_read_val(
102                    'price.' + str(items[0]), -1
103                )
104                price_str = bui.charstr(bui.SpecialChar.TICKET) + str(price)
105            self._price_text = bui.textwidget(
106                parent=self._root_widget,
107                position=(self._width * 0.5, 150 + pyoffs),
108                size=(0, 0),
109                text=price_str,
110                h_align='center',
111                v_align='center',
112                maxwidth=self._width * 0.9,
113                scale=1.4,
114                color=(0.2, 1, 0.2),
115            )
116
117        self._update_timer = bui.AppTimer(
118            1.0, bui.WeakCall(self._update), repeat=True
119        )
120
121        self._cancel_button = bui.buttonwidget(
122            parent=self._root_widget,
123            position=(50, 40),
124            size=(150, 60),
125            scale=1.0,
126            on_activate_call=self._cancel,
127            autoselect=True,
128            label=bui.Lstr(resource='cancelText'),
129        )
130        self._purchase_button = bui.buttonwidget(
131            parent=self._root_widget,
132            position=(self._width - 200, 40),
133            size=(150, 60),
134            scale=1.0,
135            on_activate_call=self._purchase,
136            autoselect=True,
137            label=bui.Lstr(resource='store.purchaseText'),
138        )
139
140        bui.containerwidget(
141            edit=self._root_widget,
142            cancel_button=self._cancel_button,
143            start_button=self._purchase_button,
144            selected_child=self._purchase_button,
145        )
146
147    def _update(self) -> None:
148        can_die = False
149
150        plus = bui.app.plus
151        assert plus is not None
152
153        # We go away if we see that our target item is owned.
154        if self._items == ['pro']:
155            assert bui.app.classic is not None
156            if bui.app.classic.accounts.have_pro():
157                can_die = True
158        else:
159            if plus.get_purchased(self._items[0]):
160                can_die = True
161
162        if can_die:
163            bui.containerwidget(edit=self._root_widget, transition='out_left')
164
165    def _purchase(self) -> None:
166        from bauiv1lib import getcurrency
167
168        plus = bui.app.plus
169        assert plus is not None
170
171        if self._items == ['pro']:
172            plus.purchase('pro')
173        else:
174            ticket_count: int | None
175            try:
176                ticket_count = plus.get_v1_account_ticket_count()
177            except Exception:
178                ticket_count = None
179            if ticket_count is not None and ticket_count < self._price:
180                getcurrency.show_get_tickets_prompt()
181                bui.getsound('error').play()
182                return
183
184            def do_it() -> None:
185                assert plus is not None
186
187                plus.in_game_purchase(self._items[0], self._price)
188
189            bui.getsound('swish').play()
190            do_it()
191
192    def _cancel(self) -> None:
193        bui.containerwidget(edit=self._root_widget, transition='out_right')

Window for purchasing one or more items.

PurchaseWindow( items: list[str], transition: str = 'in_right', header_text: babase._language.Lstr | None = None)
 19    def __init__(
 20        self,
 21        items: list[str],
 22        transition: str = 'in_right',
 23        header_text: bui.Lstr | None = None,
 24    ):
 25        from bauiv1lib.store.item import instantiate_store_item_display
 26
 27        plus = bui.app.plus
 28        assert plus is not None
 29
 30        assert bui.app.classic is not None
 31        store = bui.app.classic.store
 32
 33        if header_text is None:
 34            header_text = bui.Lstr(
 35                resource='unlockThisText',
 36                fallback_resource='unlockThisInTheStoreText',
 37            )
 38        if len(items) != 1:
 39            raise ValueError('expected exactly 1 item')
 40        self._items = list(items)
 41        self._width = 580
 42        self._height = 520
 43        uiscale = bui.app.ui_v1.uiscale
 44        super().__init__(
 45            root_widget=bui.containerwidget(
 46                size=(self._width, self._height),
 47                transition=transition,
 48                toolbar_visibility='menu_currency',
 49                scale=(
 50                    1.2
 51                    if uiscale is bui.UIScale.SMALL
 52                    else 1.1 if uiscale is bui.UIScale.MEDIUM else 1.0
 53                ),
 54                stack_offset=(
 55                    (0, -15) if uiscale is bui.UIScale.SMALL else (0, 0)
 56                ),
 57            )
 58        )
 59        self._is_double = False
 60        self._title_text = bui.textwidget(
 61            parent=self._root_widget,
 62            position=(self._width * 0.5, self._height - 30),
 63            size=(0, 0),
 64            text=header_text,
 65            h_align='center',
 66            v_align='center',
 67            maxwidth=self._width * 0.9 - 120,
 68            scale=1.2,
 69            color=(1, 0.8, 0.3, 1),
 70        )
 71        size = store.get_store_item_display_size(items[0])
 72        display: dict[str, Any] = {}
 73        instantiate_store_item_display(
 74            items[0],
 75            display,
 76            parent_widget=self._root_widget,
 77            b_pos=(
 78                self._width * 0.5
 79                - size[0] * 0.5
 80                + 10
 81                - ((size[0] * 0.5 + 30) if self._is_double else 0),
 82                self._height * 0.5
 83                - size[1] * 0.5
 84                + 30
 85                + (20 if self._is_double else 0),
 86            ),
 87            b_width=size[0],
 88            b_height=size[1],
 89            button=False,
 90        )
 91
 92        # Wire up the parts we need.
 93        if self._is_double:
 94            pass  # not working
 95        else:
 96            if self._items == ['pro']:
 97                price_str = plus.get_price(self._items[0])
 98                pyoffs = -15
 99            else:
100                pyoffs = 0
101                price = self._price = plus.get_v1_account_misc_read_val(
102                    'price.' + str(items[0]), -1
103                )
104                price_str = bui.charstr(bui.SpecialChar.TICKET) + str(price)
105            self._price_text = bui.textwidget(
106                parent=self._root_widget,
107                position=(self._width * 0.5, 150 + pyoffs),
108                size=(0, 0),
109                text=price_str,
110                h_align='center',
111                v_align='center',
112                maxwidth=self._width * 0.9,
113                scale=1.4,
114                color=(0.2, 1, 0.2),
115            )
116
117        self._update_timer = bui.AppTimer(
118            1.0, bui.WeakCall(self._update), repeat=True
119        )
120
121        self._cancel_button = bui.buttonwidget(
122            parent=self._root_widget,
123            position=(50, 40),
124            size=(150, 60),
125            scale=1.0,
126            on_activate_call=self._cancel,
127            autoselect=True,
128            label=bui.Lstr(resource='cancelText'),
129        )
130        self._purchase_button = bui.buttonwidget(
131            parent=self._root_widget,
132            position=(self._width - 200, 40),
133            size=(150, 60),
134            scale=1.0,
135            on_activate_call=self._purchase,
136            autoselect=True,
137            label=bui.Lstr(resource='store.purchaseText'),
138        )
139
140        bui.containerwidget(
141            edit=self._root_widget,
142            cancel_button=self._cancel_button,
143            start_button=self._purchase_button,
144            selected_child=self._purchase_button,
145        )
Inherited Members
bauiv1._uitypes.Window
get_root_widget