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