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 origin_widget: bui.Widget | None = None, 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 44 if origin_widget is not None: 45 scale_origin = origin_widget.get_screen_space_center() 46 else: 47 scale_origin = None 48 49 super().__init__( 50 root_widget=bui.containerwidget( 51 parent=bui.get_special_widget('overlay_stack'), 52 size=(self._width, self._height), 53 transition='in_scale', 54 toolbar_visibility='menu_store', 55 scale=( 56 1.2 57 if uiscale is bui.UIScale.SMALL 58 else 1.1 if uiscale is bui.UIScale.MEDIUM else 1.0 59 ), 60 scale_origin_stack_offset=scale_origin, 61 stack_offset=( 62 (0, -15) if uiscale is bui.UIScale.SMALL else (0, 0) 63 ), 64 ) 65 ) 66 self._is_double = False 67 self._title_text = bui.textwidget( 68 parent=self._root_widget, 69 position=(self._width * 0.5, self._height - 30), 70 size=(0, 0), 71 text=header_text, 72 h_align='center', 73 v_align='center', 74 maxwidth=self._width * 0.9 - 120, 75 scale=1.2, 76 color=(1, 0.8, 0.3, 1), 77 ) 78 size = store.get_store_item_display_size(items[0]) 79 display: dict[str, Any] = {} 80 instantiate_store_item_display( 81 items[0], 82 display, 83 parent_widget=self._root_widget, 84 b_pos=( 85 self._width * 0.5 86 - size[0] * 0.5 87 + 10 88 - ((size[0] * 0.5 + 30) if self._is_double else 0), 89 self._height * 0.5 90 - size[1] * 0.5 91 + 30 92 + (20 if self._is_double else 0), 93 ), 94 b_width=size[0], 95 b_height=size[1], 96 button=False, 97 ) 98 99 # Wire up the parts we need. 100 if self._is_double: 101 pass # not working 102 else: 103 if self._items == ['pro']: 104 price_str = plus.get_price(self._items[0]) 105 pyoffs = -15 106 else: 107 pyoffs = 0 108 price = self._price = plus.get_v1_account_misc_read_val( 109 'price.' + str(items[0]), -1 110 ) 111 price_str = bui.charstr(bui.SpecialChar.TICKET) + str(price) 112 self._price_text = bui.textwidget( 113 parent=self._root_widget, 114 position=(self._width * 0.5, 150 + pyoffs), 115 size=(0, 0), 116 text=price_str, 117 h_align='center', 118 v_align='center', 119 maxwidth=self._width * 0.9, 120 scale=1.4, 121 color=(0.2, 1, 0.2), 122 ) 123 124 self._update_timer = bui.AppTimer( 125 1.0, bui.WeakCall(self._update), repeat=True 126 ) 127 128 self._cancel_button = bui.buttonwidget( 129 parent=self._root_widget, 130 position=(50, 40), 131 size=(150, 60), 132 scale=1.0, 133 on_activate_call=self._cancel, 134 autoselect=True, 135 label=bui.Lstr(resource='cancelText'), 136 ) 137 self._purchase_button = bui.buttonwidget( 138 parent=self._root_widget, 139 position=(self._width - 200, 40), 140 size=(150, 60), 141 scale=1.0, 142 on_activate_call=self._purchase, 143 autoselect=True, 144 label=bui.Lstr(resource='store.purchaseText'), 145 ) 146 147 bui.containerwidget( 148 edit=self._root_widget, 149 cancel_button=self._cancel_button, 150 start_button=self._purchase_button, 151 selected_child=self._purchase_button, 152 ) 153 154 def _update(self) -> None: 155 can_die = False 156 157 plus = bui.app.plus 158 assert plus is not None 159 160 # We go away if we see that our target item is owned. 161 if self._items == ['pro']: 162 assert bui.app.classic is not None 163 if bui.app.classic.accounts.have_pro(): 164 can_die = True 165 else: 166 if plus.get_v1_account_product_purchased(self._items[0]): 167 can_die = True 168 169 if can_die: 170 bui.containerwidget(edit=self._root_widget, transition='out_scale') 171 172 def _purchase(self) -> None: 173 174 plus = bui.app.plus 175 assert plus is not None 176 177 if self._items == ['pro']: 178 plus.purchase('pro') 179 else: 180 ticket_count: int | None 181 try: 182 ticket_count = plus.get_v1_account_ticket_count() 183 except Exception: 184 ticket_count = None 185 if ticket_count is not None and ticket_count < self._price: 186 bui.getsound('error').play() 187 bui.screenmessage( 188 bui.Lstr(resource='notEnoughTicketsText'), 189 color=(1, 0, 0), 190 ) 191 # gettickets.show_get_tickets_prompt() 192 return 193 194 def do_it() -> None: 195 assert plus is not None 196 197 plus.in_game_purchase(self._items[0], self._price) 198 199 bui.getsound('swish').play() 200 do_it() 201 202 def _cancel(self) -> None: 203 bui.containerwidget(edit=self._root_widget, transition='out_scale')
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 origin_widget: bui.Widget | None = None, 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 45 if origin_widget is not None: 46 scale_origin = origin_widget.get_screen_space_center() 47 else: 48 scale_origin = None 49 50 super().__init__( 51 root_widget=bui.containerwidget( 52 parent=bui.get_special_widget('overlay_stack'), 53 size=(self._width, self._height), 54 transition='in_scale', 55 toolbar_visibility='menu_store', 56 scale=( 57 1.2 58 if uiscale is bui.UIScale.SMALL 59 else 1.1 if uiscale is bui.UIScale.MEDIUM else 1.0 60 ), 61 scale_origin_stack_offset=scale_origin, 62 stack_offset=( 63 (0, -15) if uiscale is bui.UIScale.SMALL else (0, 0) 64 ), 65 ) 66 ) 67 self._is_double = False 68 self._title_text = bui.textwidget( 69 parent=self._root_widget, 70 position=(self._width * 0.5, self._height - 30), 71 size=(0, 0), 72 text=header_text, 73 h_align='center', 74 v_align='center', 75 maxwidth=self._width * 0.9 - 120, 76 scale=1.2, 77 color=(1, 0.8, 0.3, 1), 78 ) 79 size = store.get_store_item_display_size(items[0]) 80 display: dict[str, Any] = {} 81 instantiate_store_item_display( 82 items[0], 83 display, 84 parent_widget=self._root_widget, 85 b_pos=( 86 self._width * 0.5 87 - size[0] * 0.5 88 + 10 89 - ((size[0] * 0.5 + 30) if self._is_double else 0), 90 self._height * 0.5 91 - size[1] * 0.5 92 + 30 93 + (20 if self._is_double else 0), 94 ), 95 b_width=size[0], 96 b_height=size[1], 97 button=False, 98 ) 99 100 # Wire up the parts we need. 101 if self._is_double: 102 pass # not working 103 else: 104 if self._items == ['pro']: 105 price_str = plus.get_price(self._items[0]) 106 pyoffs = -15 107 else: 108 pyoffs = 0 109 price = self._price = plus.get_v1_account_misc_read_val( 110 'price.' + str(items[0]), -1 111 ) 112 price_str = bui.charstr(bui.SpecialChar.TICKET) + str(price) 113 self._price_text = bui.textwidget( 114 parent=self._root_widget, 115 position=(self._width * 0.5, 150 + pyoffs), 116 size=(0, 0), 117 text=price_str, 118 h_align='center', 119 v_align='center', 120 maxwidth=self._width * 0.9, 121 scale=1.4, 122 color=(0.2, 1, 0.2), 123 ) 124 125 self._update_timer = bui.AppTimer( 126 1.0, bui.WeakCall(self._update), repeat=True 127 ) 128 129 self._cancel_button = bui.buttonwidget( 130 parent=self._root_widget, 131 position=(50, 40), 132 size=(150, 60), 133 scale=1.0, 134 on_activate_call=self._cancel, 135 autoselect=True, 136 label=bui.Lstr(resource='cancelText'), 137 ) 138 self._purchase_button = bui.buttonwidget( 139 parent=self._root_widget, 140 position=(self._width - 200, 40), 141 size=(150, 60), 142 scale=1.0, 143 on_activate_call=self._purchase, 144 autoselect=True, 145 label=bui.Lstr(resource='store.purchaseText'), 146 ) 147 148 bui.containerwidget( 149 edit=self._root_widget, 150 cancel_button=self._cancel_button, 151 start_button=self._purchase_button, 152 selected_child=self._purchase_button, 153 ) 154 155 def _update(self) -> None: 156 can_die = False 157 158 plus = bui.app.plus 159 assert plus is not None 160 161 # We go away if we see that our target item is owned. 162 if self._items == ['pro']: 163 assert bui.app.classic is not None 164 if bui.app.classic.accounts.have_pro(): 165 can_die = True 166 else: 167 if plus.get_v1_account_product_purchased(self._items[0]): 168 can_die = True 169 170 if can_die: 171 bui.containerwidget(edit=self._root_widget, transition='out_scale') 172 173 def _purchase(self) -> None: 174 175 plus = bui.app.plus 176 assert plus is not None 177 178 if self._items == ['pro']: 179 plus.purchase('pro') 180 else: 181 ticket_count: int | None 182 try: 183 ticket_count = plus.get_v1_account_ticket_count() 184 except Exception: 185 ticket_count = None 186 if ticket_count is not None and ticket_count < self._price: 187 bui.getsound('error').play() 188 bui.screenmessage( 189 bui.Lstr(resource='notEnoughTicketsText'), 190 color=(1, 0, 0), 191 ) 192 # gettickets.show_get_tickets_prompt() 193 return 194 195 def do_it() -> None: 196 assert plus is not None 197 198 plus.in_game_purchase(self._items[0], self._price) 199 200 bui.getsound('swish').play() 201 do_it() 202 203 def _cancel(self) -> None: 204 bui.containerwidget(edit=self._root_widget, transition='out_scale')
Window for purchasing one or more items.
PurchaseWindow( items: list[str], origin_widget: _bauiv1.Widget | None = None, header_text: babase.Lstr | None = None)
19 def __init__( 20 self, 21 items: list[str], 22 origin_widget: bui.Widget | None = None, 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 45 if origin_widget is not None: 46 scale_origin = origin_widget.get_screen_space_center() 47 else: 48 scale_origin = None 49 50 super().__init__( 51 root_widget=bui.containerwidget( 52 parent=bui.get_special_widget('overlay_stack'), 53 size=(self._width, self._height), 54 transition='in_scale', 55 toolbar_visibility='menu_store', 56 scale=( 57 1.2 58 if uiscale is bui.UIScale.SMALL 59 else 1.1 if uiscale is bui.UIScale.MEDIUM else 1.0 60 ), 61 scale_origin_stack_offset=scale_origin, 62 stack_offset=( 63 (0, -15) if uiscale is bui.UIScale.SMALL else (0, 0) 64 ), 65 ) 66 ) 67 self._is_double = False 68 self._title_text = bui.textwidget( 69 parent=self._root_widget, 70 position=(self._width * 0.5, self._height - 30), 71 size=(0, 0), 72 text=header_text, 73 h_align='center', 74 v_align='center', 75 maxwidth=self._width * 0.9 - 120, 76 scale=1.2, 77 color=(1, 0.8, 0.3, 1), 78 ) 79 size = store.get_store_item_display_size(items[0]) 80 display: dict[str, Any] = {} 81 instantiate_store_item_display( 82 items[0], 83 display, 84 parent_widget=self._root_widget, 85 b_pos=( 86 self._width * 0.5 87 - size[0] * 0.5 88 + 10 89 - ((size[0] * 0.5 + 30) if self._is_double else 0), 90 self._height * 0.5 91 - size[1] * 0.5 92 + 30 93 + (20 if self._is_double else 0), 94 ), 95 b_width=size[0], 96 b_height=size[1], 97 button=False, 98 ) 99 100 # Wire up the parts we need. 101 if self._is_double: 102 pass # not working 103 else: 104 if self._items == ['pro']: 105 price_str = plus.get_price(self._items[0]) 106 pyoffs = -15 107 else: 108 pyoffs = 0 109 price = self._price = plus.get_v1_account_misc_read_val( 110 'price.' + str(items[0]), -1 111 ) 112 price_str = bui.charstr(bui.SpecialChar.TICKET) + str(price) 113 self._price_text = bui.textwidget( 114 parent=self._root_widget, 115 position=(self._width * 0.5, 150 + pyoffs), 116 size=(0, 0), 117 text=price_str, 118 h_align='center', 119 v_align='center', 120 maxwidth=self._width * 0.9, 121 scale=1.4, 122 color=(0.2, 1, 0.2), 123 ) 124 125 self._update_timer = bui.AppTimer( 126 1.0, bui.WeakCall(self._update), repeat=True 127 ) 128 129 self._cancel_button = bui.buttonwidget( 130 parent=self._root_widget, 131 position=(50, 40), 132 size=(150, 60), 133 scale=1.0, 134 on_activate_call=self._cancel, 135 autoselect=True, 136 label=bui.Lstr(resource='cancelText'), 137 ) 138 self._purchase_button = bui.buttonwidget( 139 parent=self._root_widget, 140 position=(self._width - 200, 40), 141 size=(150, 60), 142 scale=1.0, 143 on_activate_call=self._purchase, 144 autoselect=True, 145 label=bui.Lstr(resource='store.purchaseText'), 146 ) 147 148 bui.containerwidget( 149 edit=self._root_widget, 150 cancel_button=self._cancel_button, 151 start_button=self._purchase_button, 152 selected_child=self._purchase_button, 153 )