bauiv1lib.store.button
UI functionality for a button leading to the store.
1# Released under the MIT License. See LICENSE for details. 2# 3"""UI functionality for a button leading to the store.""" 4from __future__ import annotations 5 6import logging 7from typing import TYPE_CHECKING 8 9import bauiv1 as bui 10 11if TYPE_CHECKING: 12 from typing import Any, Sequence, Callable 13 14 15class StoreButton: 16 """A button leading to the store.""" 17 18 def __init__( 19 self, 20 parent: bui.Widget, 21 position: Sequence[float], 22 size: Sequence[float], 23 scale: float, 24 on_activate_call: Callable[[], Any] | None = None, 25 transition_delay: float | None = None, 26 color: Sequence[float] | None = None, 27 textcolor: Sequence[float] | None = None, 28 show_tickets: bool = False, 29 button_type: str | None = None, 30 sale_scale: float = 1.0, 31 ): 32 self._position = position 33 self._size = size 34 self._scale = scale 35 36 if on_activate_call is None: 37 on_activate_call = bui.WeakCall(self._default_on_activate_call) 38 self._on_activate_call = on_activate_call 39 40 self._button = bui.buttonwidget( 41 parent=parent, 42 size=size, 43 label='' if show_tickets else bui.Lstr(resource='storeText'), 44 scale=scale, 45 autoselect=True, 46 on_activate_call=self._on_activate, 47 transition_delay=transition_delay, 48 color=color, 49 button_type=button_type, 50 ) 51 52 self._title_text: bui.Widget | None 53 self._ticket_text: bui.Widget | None 54 55 if show_tickets: 56 self._title_text = bui.textwidget( 57 parent=parent, 58 position=( 59 position[0] + size[0] * 0.5 * scale, 60 position[1] + size[1] * 0.65 * scale, 61 ), 62 size=(0, 0), 63 h_align='center', 64 v_align='center', 65 maxwidth=size[0] * scale * 0.65, 66 text=bui.Lstr(resource='storeText'), 67 draw_controller=self._button, 68 scale=scale, 69 transition_delay=transition_delay, 70 color=textcolor, 71 ) 72 self._ticket_text = bui.textwidget( 73 parent=parent, 74 size=(0, 0), 75 h_align='center', 76 v_align='center', 77 maxwidth=size[0] * scale * 0.85, 78 text='', 79 color=(0.2, 1.0, 0.2), 80 flatness=1.0, 81 shadow=0.0, 82 scale=scale * 0.6, 83 transition_delay=transition_delay, 84 ) 85 else: 86 self._title_text = None 87 self._ticket_text = None 88 89 self._circle_rad = 12 * scale 90 self._circle_center = (0.0, 0.0) 91 self._sale_circle_center = (0.0, 0.0) 92 93 self._available_purchase_backing = bui.imagewidget( 94 parent=parent, 95 color=(1, 0, 0), 96 draw_controller=self._button, 97 size=(2.2 * self._circle_rad, 2.2 * self._circle_rad), 98 texture=bui.gettexture('circleShadow'), 99 transition_delay=transition_delay, 100 ) 101 self._available_purchase_text = bui.textwidget( 102 parent=parent, 103 size=(0, 0), 104 h_align='center', 105 v_align='center', 106 text='', 107 draw_controller=self._button, 108 color=(1, 1, 1), 109 flatness=1.0, 110 shadow=1.0, 111 scale=0.6 * scale, 112 maxwidth=self._circle_rad * 1.4, 113 transition_delay=transition_delay, 114 ) 115 116 self._sale_circle_rad = 18 * scale * sale_scale 117 self._sale_backing = bui.imagewidget( 118 parent=parent, 119 color=(0.5, 0, 1.0), 120 draw_controller=self._button, 121 size=(2 * self._sale_circle_rad, 2 * self._sale_circle_rad), 122 texture=bui.gettexture('circleZigZag'), 123 transition_delay=transition_delay, 124 ) 125 self._sale_title_text = bui.textwidget( 126 parent=parent, 127 size=(0, 0), 128 h_align='center', 129 v_align='center', 130 draw_controller=self._button, 131 color=(0, 1, 0), 132 flatness=1.0, 133 shadow=0.0, 134 scale=0.5 * scale * sale_scale, 135 maxwidth=self._sale_circle_rad * 1.5, 136 transition_delay=transition_delay, 137 ) 138 self._sale_time_text = bui.textwidget( 139 parent=parent, 140 size=(0, 0), 141 h_align='center', 142 v_align='center', 143 draw_controller=self._button, 144 color=(0, 1, 0), 145 flatness=1.0, 146 shadow=0.0, 147 scale=0.4 * scale * sale_scale, 148 maxwidth=self._sale_circle_rad * 1.5, 149 transition_delay=transition_delay, 150 ) 151 152 self.set_position(position) 153 self._update_timer = bui.AppTimer( 154 1.0, bui.WeakCall(self._update), repeat=True 155 ) 156 self._update() 157 158 def _on_activate(self) -> None: 159 bui.increment_analytics_count('Store button press') 160 self._on_activate_call() 161 162 def set_position(self, position: Sequence[float]) -> None: 163 """Set the button position.""" 164 self._position = position 165 self._circle_center = ( 166 position[0] + 0.1 * self._size[0] * self._scale, 167 position[1] + self._size[1] * self._scale * 0.8, 168 ) 169 self._sale_circle_center = ( 170 position[0] + 0.07 * self._size[0] * self._scale, 171 position[1] + self._size[1] * self._scale * 0.8, 172 ) 173 174 if not self._button: 175 return 176 bui.buttonwidget(edit=self._button, position=self._position) 177 if self._title_text is not None: 178 bui.textwidget( 179 edit=self._title_text, 180 position=( 181 self._position[0] + self._size[0] * 0.5 * self._scale, 182 self._position[1] + self._size[1] * 0.65 * self._scale, 183 ), 184 ) 185 if self._ticket_text is not None: 186 bui.textwidget( 187 edit=self._ticket_text, 188 position=( 189 position[0] + self._size[0] * 0.5 * self._scale, 190 position[1] + self._size[1] * 0.28 * self._scale, 191 ), 192 size=(0, 0), 193 ) 194 bui.imagewidget( 195 edit=self._available_purchase_backing, 196 position=( 197 self._circle_center[0] - self._circle_rad * 1.02, 198 self._circle_center[1] - self._circle_rad * 1.13, 199 ), 200 ) 201 bui.textwidget( 202 edit=self._available_purchase_text, position=self._circle_center 203 ) 204 205 bui.imagewidget( 206 edit=self._sale_backing, 207 position=( 208 self._sale_circle_center[0] - self._sale_circle_rad, 209 self._sale_circle_center[1] - self._sale_circle_rad, 210 ), 211 ) 212 bui.textwidget( 213 edit=self._sale_title_text, 214 position=( 215 self._sale_circle_center[0], 216 self._sale_circle_center[1] + self._sale_circle_rad * 0.3, 217 ), 218 ) 219 bui.textwidget( 220 edit=self._sale_time_text, 221 position=( 222 self._sale_circle_center[0], 223 self._sale_circle_center[1] - self._sale_circle_rad * 0.3, 224 ), 225 ) 226 227 def _default_on_activate_call(self) -> None: 228 # pylint: disable=cyclic-import 229 from bauiv1lib.account import show_sign_in_prompt 230 from bauiv1lib.store.browser import StoreBrowserWindow 231 232 plus = bui.app.plus 233 assert plus is not None 234 if plus.get_v1_account_state() != 'signed_in': 235 show_sign_in_prompt() 236 return 237 StoreBrowserWindow(modal=True, origin_widget=self._button) 238 239 def get_button(self) -> bui.Widget: 240 """Return the underlying button widget.""" 241 return self._button 242 243 def _update(self) -> None: 244 # pylint: disable=too-many-branches 245 # pylint: disable=cyclic-import 246 from babase import SpecialChar 247 248 plus = bui.app.plus 249 assert plus is not None 250 assert bui.app.classic is not None 251 store = bui.app.classic.store 252 253 if not self._button: 254 return # Our instance may outlive our UI objects. 255 256 if self._ticket_text is not None: 257 if plus.get_v1_account_state() == 'signed_in': 258 sval = bui.charstr(SpecialChar.TICKET) + str( 259 plus.get_v1_account_ticket_count() 260 ) 261 else: 262 sval = '-' 263 bui.textwidget(edit=self._ticket_text, text=sval) 264 available_purchases = store.get_available_purchase_count() 265 266 # Old pro sale stuff.. 267 sale_time = store.get_available_sale_time('extras') 268 269 # ..also look for new style sales. 270 if sale_time is None: 271 import datetime 272 273 sales_raw = plus.get_v1_account_misc_read_val('sales', {}) 274 sale_times = [] 275 try: 276 # Look at the current set of sales; filter any with time 277 # remaining that we don't own. 278 for sale_item, sale_info in list(sales_raw.items()): 279 if not plus.get_purchased(sale_item): 280 to_end = ( 281 datetime.datetime.utcfromtimestamp(sale_info['e']) 282 - datetime.datetime.utcnow() 283 ).total_seconds() 284 if to_end > 0: 285 sale_times.append(to_end) 286 except Exception: 287 logging.exception('Error parsing sales.') 288 if sale_times: 289 sale_time = int(min(sale_times) * 1000) 290 291 if sale_time is not None: 292 bui.textwidget( 293 edit=self._sale_title_text, 294 text=bui.Lstr(resource='store.saleText'), 295 ) 296 bui.textwidget( 297 edit=self._sale_time_text, 298 text=bui.timestring(sale_time / 1000.0, centi=False), 299 ) 300 bui.imagewidget(edit=self._sale_backing, opacity=1.0) 301 bui.imagewidget(edit=self._available_purchase_backing, opacity=1.0) 302 bui.textwidget(edit=self._available_purchase_text, text='') 303 bui.imagewidget(edit=self._available_purchase_backing, opacity=0.0) 304 else: 305 bui.imagewidget(edit=self._sale_backing, opacity=0.0) 306 bui.textwidget(edit=self._sale_time_text, text='') 307 bui.textwidget(edit=self._sale_title_text, text='') 308 if available_purchases > 0: 309 bui.textwidget( 310 edit=self._available_purchase_text, 311 text=str(available_purchases), 312 ) 313 bui.imagewidget( 314 edit=self._available_purchase_backing, opacity=1.0 315 ) 316 else: 317 bui.textwidget(edit=self._available_purchase_text, text='') 318 bui.imagewidget( 319 edit=self._available_purchase_backing, opacity=0.0 320 )
class
StoreButton:
16class StoreButton: 17 """A button leading to the store.""" 18 19 def __init__( 20 self, 21 parent: bui.Widget, 22 position: Sequence[float], 23 size: Sequence[float], 24 scale: float, 25 on_activate_call: Callable[[], Any] | None = None, 26 transition_delay: float | None = None, 27 color: Sequence[float] | None = None, 28 textcolor: Sequence[float] | None = None, 29 show_tickets: bool = False, 30 button_type: str | None = None, 31 sale_scale: float = 1.0, 32 ): 33 self._position = position 34 self._size = size 35 self._scale = scale 36 37 if on_activate_call is None: 38 on_activate_call = bui.WeakCall(self._default_on_activate_call) 39 self._on_activate_call = on_activate_call 40 41 self._button = bui.buttonwidget( 42 parent=parent, 43 size=size, 44 label='' if show_tickets else bui.Lstr(resource='storeText'), 45 scale=scale, 46 autoselect=True, 47 on_activate_call=self._on_activate, 48 transition_delay=transition_delay, 49 color=color, 50 button_type=button_type, 51 ) 52 53 self._title_text: bui.Widget | None 54 self._ticket_text: bui.Widget | None 55 56 if show_tickets: 57 self._title_text = bui.textwidget( 58 parent=parent, 59 position=( 60 position[0] + size[0] * 0.5 * scale, 61 position[1] + size[1] * 0.65 * scale, 62 ), 63 size=(0, 0), 64 h_align='center', 65 v_align='center', 66 maxwidth=size[0] * scale * 0.65, 67 text=bui.Lstr(resource='storeText'), 68 draw_controller=self._button, 69 scale=scale, 70 transition_delay=transition_delay, 71 color=textcolor, 72 ) 73 self._ticket_text = bui.textwidget( 74 parent=parent, 75 size=(0, 0), 76 h_align='center', 77 v_align='center', 78 maxwidth=size[0] * scale * 0.85, 79 text='', 80 color=(0.2, 1.0, 0.2), 81 flatness=1.0, 82 shadow=0.0, 83 scale=scale * 0.6, 84 transition_delay=transition_delay, 85 ) 86 else: 87 self._title_text = None 88 self._ticket_text = None 89 90 self._circle_rad = 12 * scale 91 self._circle_center = (0.0, 0.0) 92 self._sale_circle_center = (0.0, 0.0) 93 94 self._available_purchase_backing = bui.imagewidget( 95 parent=parent, 96 color=(1, 0, 0), 97 draw_controller=self._button, 98 size=(2.2 * self._circle_rad, 2.2 * self._circle_rad), 99 texture=bui.gettexture('circleShadow'), 100 transition_delay=transition_delay, 101 ) 102 self._available_purchase_text = bui.textwidget( 103 parent=parent, 104 size=(0, 0), 105 h_align='center', 106 v_align='center', 107 text='', 108 draw_controller=self._button, 109 color=(1, 1, 1), 110 flatness=1.0, 111 shadow=1.0, 112 scale=0.6 * scale, 113 maxwidth=self._circle_rad * 1.4, 114 transition_delay=transition_delay, 115 ) 116 117 self._sale_circle_rad = 18 * scale * sale_scale 118 self._sale_backing = bui.imagewidget( 119 parent=parent, 120 color=(0.5, 0, 1.0), 121 draw_controller=self._button, 122 size=(2 * self._sale_circle_rad, 2 * self._sale_circle_rad), 123 texture=bui.gettexture('circleZigZag'), 124 transition_delay=transition_delay, 125 ) 126 self._sale_title_text = bui.textwidget( 127 parent=parent, 128 size=(0, 0), 129 h_align='center', 130 v_align='center', 131 draw_controller=self._button, 132 color=(0, 1, 0), 133 flatness=1.0, 134 shadow=0.0, 135 scale=0.5 * scale * sale_scale, 136 maxwidth=self._sale_circle_rad * 1.5, 137 transition_delay=transition_delay, 138 ) 139 self._sale_time_text = bui.textwidget( 140 parent=parent, 141 size=(0, 0), 142 h_align='center', 143 v_align='center', 144 draw_controller=self._button, 145 color=(0, 1, 0), 146 flatness=1.0, 147 shadow=0.0, 148 scale=0.4 * scale * sale_scale, 149 maxwidth=self._sale_circle_rad * 1.5, 150 transition_delay=transition_delay, 151 ) 152 153 self.set_position(position) 154 self._update_timer = bui.AppTimer( 155 1.0, bui.WeakCall(self._update), repeat=True 156 ) 157 self._update() 158 159 def _on_activate(self) -> None: 160 bui.increment_analytics_count('Store button press') 161 self._on_activate_call() 162 163 def set_position(self, position: Sequence[float]) -> None: 164 """Set the button position.""" 165 self._position = position 166 self._circle_center = ( 167 position[0] + 0.1 * self._size[0] * self._scale, 168 position[1] + self._size[1] * self._scale * 0.8, 169 ) 170 self._sale_circle_center = ( 171 position[0] + 0.07 * self._size[0] * self._scale, 172 position[1] + self._size[1] * self._scale * 0.8, 173 ) 174 175 if not self._button: 176 return 177 bui.buttonwidget(edit=self._button, position=self._position) 178 if self._title_text is not None: 179 bui.textwidget( 180 edit=self._title_text, 181 position=( 182 self._position[0] + self._size[0] * 0.5 * self._scale, 183 self._position[1] + self._size[1] * 0.65 * self._scale, 184 ), 185 ) 186 if self._ticket_text is not None: 187 bui.textwidget( 188 edit=self._ticket_text, 189 position=( 190 position[0] + self._size[0] * 0.5 * self._scale, 191 position[1] + self._size[1] * 0.28 * self._scale, 192 ), 193 size=(0, 0), 194 ) 195 bui.imagewidget( 196 edit=self._available_purchase_backing, 197 position=( 198 self._circle_center[0] - self._circle_rad * 1.02, 199 self._circle_center[1] - self._circle_rad * 1.13, 200 ), 201 ) 202 bui.textwidget( 203 edit=self._available_purchase_text, position=self._circle_center 204 ) 205 206 bui.imagewidget( 207 edit=self._sale_backing, 208 position=( 209 self._sale_circle_center[0] - self._sale_circle_rad, 210 self._sale_circle_center[1] - self._sale_circle_rad, 211 ), 212 ) 213 bui.textwidget( 214 edit=self._sale_title_text, 215 position=( 216 self._sale_circle_center[0], 217 self._sale_circle_center[1] + self._sale_circle_rad * 0.3, 218 ), 219 ) 220 bui.textwidget( 221 edit=self._sale_time_text, 222 position=( 223 self._sale_circle_center[0], 224 self._sale_circle_center[1] - self._sale_circle_rad * 0.3, 225 ), 226 ) 227 228 def _default_on_activate_call(self) -> None: 229 # pylint: disable=cyclic-import 230 from bauiv1lib.account import show_sign_in_prompt 231 from bauiv1lib.store.browser import StoreBrowserWindow 232 233 plus = bui.app.plus 234 assert plus is not None 235 if plus.get_v1_account_state() != 'signed_in': 236 show_sign_in_prompt() 237 return 238 StoreBrowserWindow(modal=True, origin_widget=self._button) 239 240 def get_button(self) -> bui.Widget: 241 """Return the underlying button widget.""" 242 return self._button 243 244 def _update(self) -> None: 245 # pylint: disable=too-many-branches 246 # pylint: disable=cyclic-import 247 from babase import SpecialChar 248 249 plus = bui.app.plus 250 assert plus is not None 251 assert bui.app.classic is not None 252 store = bui.app.classic.store 253 254 if not self._button: 255 return # Our instance may outlive our UI objects. 256 257 if self._ticket_text is not None: 258 if plus.get_v1_account_state() == 'signed_in': 259 sval = bui.charstr(SpecialChar.TICKET) + str( 260 plus.get_v1_account_ticket_count() 261 ) 262 else: 263 sval = '-' 264 bui.textwidget(edit=self._ticket_text, text=sval) 265 available_purchases = store.get_available_purchase_count() 266 267 # Old pro sale stuff.. 268 sale_time = store.get_available_sale_time('extras') 269 270 # ..also look for new style sales. 271 if sale_time is None: 272 import datetime 273 274 sales_raw = plus.get_v1_account_misc_read_val('sales', {}) 275 sale_times = [] 276 try: 277 # Look at the current set of sales; filter any with time 278 # remaining that we don't own. 279 for sale_item, sale_info in list(sales_raw.items()): 280 if not plus.get_purchased(sale_item): 281 to_end = ( 282 datetime.datetime.utcfromtimestamp(sale_info['e']) 283 - datetime.datetime.utcnow() 284 ).total_seconds() 285 if to_end > 0: 286 sale_times.append(to_end) 287 except Exception: 288 logging.exception('Error parsing sales.') 289 if sale_times: 290 sale_time = int(min(sale_times) * 1000) 291 292 if sale_time is not None: 293 bui.textwidget( 294 edit=self._sale_title_text, 295 text=bui.Lstr(resource='store.saleText'), 296 ) 297 bui.textwidget( 298 edit=self._sale_time_text, 299 text=bui.timestring(sale_time / 1000.0, centi=False), 300 ) 301 bui.imagewidget(edit=self._sale_backing, opacity=1.0) 302 bui.imagewidget(edit=self._available_purchase_backing, opacity=1.0) 303 bui.textwidget(edit=self._available_purchase_text, text='') 304 bui.imagewidget(edit=self._available_purchase_backing, opacity=0.0) 305 else: 306 bui.imagewidget(edit=self._sale_backing, opacity=0.0) 307 bui.textwidget(edit=self._sale_time_text, text='') 308 bui.textwidget(edit=self._sale_title_text, text='') 309 if available_purchases > 0: 310 bui.textwidget( 311 edit=self._available_purchase_text, 312 text=str(available_purchases), 313 ) 314 bui.imagewidget( 315 edit=self._available_purchase_backing, opacity=1.0 316 ) 317 else: 318 bui.textwidget(edit=self._available_purchase_text, text='') 319 bui.imagewidget( 320 edit=self._available_purchase_backing, opacity=0.0 321 )
A button leading to the store.
StoreButton( parent: _bauiv1.Widget, position: Sequence[float], size: Sequence[float], scale: float, on_activate_call: Optional[Callable[[], Any]] = None, transition_delay: float | None = None, color: Optional[Sequence[float]] = None, textcolor: Optional[Sequence[float]] = None, show_tickets: bool = False, button_type: str | None = None, sale_scale: float = 1.0)
19 def __init__( 20 self, 21 parent: bui.Widget, 22 position: Sequence[float], 23 size: Sequence[float], 24 scale: float, 25 on_activate_call: Callable[[], Any] | None = None, 26 transition_delay: float | None = None, 27 color: Sequence[float] | None = None, 28 textcolor: Sequence[float] | None = None, 29 show_tickets: bool = False, 30 button_type: str | None = None, 31 sale_scale: float = 1.0, 32 ): 33 self._position = position 34 self._size = size 35 self._scale = scale 36 37 if on_activate_call is None: 38 on_activate_call = bui.WeakCall(self._default_on_activate_call) 39 self._on_activate_call = on_activate_call 40 41 self._button = bui.buttonwidget( 42 parent=parent, 43 size=size, 44 label='' if show_tickets else bui.Lstr(resource='storeText'), 45 scale=scale, 46 autoselect=True, 47 on_activate_call=self._on_activate, 48 transition_delay=transition_delay, 49 color=color, 50 button_type=button_type, 51 ) 52 53 self._title_text: bui.Widget | None 54 self._ticket_text: bui.Widget | None 55 56 if show_tickets: 57 self._title_text = bui.textwidget( 58 parent=parent, 59 position=( 60 position[0] + size[0] * 0.5 * scale, 61 position[1] + size[1] * 0.65 * scale, 62 ), 63 size=(0, 0), 64 h_align='center', 65 v_align='center', 66 maxwidth=size[0] * scale * 0.65, 67 text=bui.Lstr(resource='storeText'), 68 draw_controller=self._button, 69 scale=scale, 70 transition_delay=transition_delay, 71 color=textcolor, 72 ) 73 self._ticket_text = bui.textwidget( 74 parent=parent, 75 size=(0, 0), 76 h_align='center', 77 v_align='center', 78 maxwidth=size[0] * scale * 0.85, 79 text='', 80 color=(0.2, 1.0, 0.2), 81 flatness=1.0, 82 shadow=0.0, 83 scale=scale * 0.6, 84 transition_delay=transition_delay, 85 ) 86 else: 87 self._title_text = None 88 self._ticket_text = None 89 90 self._circle_rad = 12 * scale 91 self._circle_center = (0.0, 0.0) 92 self._sale_circle_center = (0.0, 0.0) 93 94 self._available_purchase_backing = bui.imagewidget( 95 parent=parent, 96 color=(1, 0, 0), 97 draw_controller=self._button, 98 size=(2.2 * self._circle_rad, 2.2 * self._circle_rad), 99 texture=bui.gettexture('circleShadow'), 100 transition_delay=transition_delay, 101 ) 102 self._available_purchase_text = bui.textwidget( 103 parent=parent, 104 size=(0, 0), 105 h_align='center', 106 v_align='center', 107 text='', 108 draw_controller=self._button, 109 color=(1, 1, 1), 110 flatness=1.0, 111 shadow=1.0, 112 scale=0.6 * scale, 113 maxwidth=self._circle_rad * 1.4, 114 transition_delay=transition_delay, 115 ) 116 117 self._sale_circle_rad = 18 * scale * sale_scale 118 self._sale_backing = bui.imagewidget( 119 parent=parent, 120 color=(0.5, 0, 1.0), 121 draw_controller=self._button, 122 size=(2 * self._sale_circle_rad, 2 * self._sale_circle_rad), 123 texture=bui.gettexture('circleZigZag'), 124 transition_delay=transition_delay, 125 ) 126 self._sale_title_text = bui.textwidget( 127 parent=parent, 128 size=(0, 0), 129 h_align='center', 130 v_align='center', 131 draw_controller=self._button, 132 color=(0, 1, 0), 133 flatness=1.0, 134 shadow=0.0, 135 scale=0.5 * scale * sale_scale, 136 maxwidth=self._sale_circle_rad * 1.5, 137 transition_delay=transition_delay, 138 ) 139 self._sale_time_text = bui.textwidget( 140 parent=parent, 141 size=(0, 0), 142 h_align='center', 143 v_align='center', 144 draw_controller=self._button, 145 color=(0, 1, 0), 146 flatness=1.0, 147 shadow=0.0, 148 scale=0.4 * scale * sale_scale, 149 maxwidth=self._sale_circle_rad * 1.5, 150 transition_delay=transition_delay, 151 ) 152 153 self.set_position(position) 154 self._update_timer = bui.AppTimer( 155 1.0, bui.WeakCall(self._update), repeat=True 156 ) 157 self._update()
def
set_position(self, position: Sequence[float]) -> None:
163 def set_position(self, position: Sequence[float]) -> None: 164 """Set the button position.""" 165 self._position = position 166 self._circle_center = ( 167 position[0] + 0.1 * self._size[0] * self._scale, 168 position[1] + self._size[1] * self._scale * 0.8, 169 ) 170 self._sale_circle_center = ( 171 position[0] + 0.07 * self._size[0] * self._scale, 172 position[1] + self._size[1] * self._scale * 0.8, 173 ) 174 175 if not self._button: 176 return 177 bui.buttonwidget(edit=self._button, position=self._position) 178 if self._title_text is not None: 179 bui.textwidget( 180 edit=self._title_text, 181 position=( 182 self._position[0] + self._size[0] * 0.5 * self._scale, 183 self._position[1] + self._size[1] * 0.65 * self._scale, 184 ), 185 ) 186 if self._ticket_text is not None: 187 bui.textwidget( 188 edit=self._ticket_text, 189 position=( 190 position[0] + self._size[0] * 0.5 * self._scale, 191 position[1] + self._size[1] * 0.28 * self._scale, 192 ), 193 size=(0, 0), 194 ) 195 bui.imagewidget( 196 edit=self._available_purchase_backing, 197 position=( 198 self._circle_center[0] - self._circle_rad * 1.02, 199 self._circle_center[1] - self._circle_rad * 1.13, 200 ), 201 ) 202 bui.textwidget( 203 edit=self._available_purchase_text, position=self._circle_center 204 ) 205 206 bui.imagewidget( 207 edit=self._sale_backing, 208 position=( 209 self._sale_circle_center[0] - self._sale_circle_rad, 210 self._sale_circle_center[1] - self._sale_circle_rad, 211 ), 212 ) 213 bui.textwidget( 214 edit=self._sale_title_text, 215 position=( 216 self._sale_circle_center[0], 217 self._sale_circle_center[1] + self._sale_circle_rad * 0.3, 218 ), 219 ) 220 bui.textwidget( 221 edit=self._sale_time_text, 222 position=( 223 self._sale_circle_center[0], 224 self._sale_circle_center[1] - self._sale_circle_rad * 0.3, 225 ), 226 )
Set the button position.