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