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