bauiv1lib.coop.tournamentbutton
Defines button for co-op games.
1# Released under the MIT License. See LICENSE for details. 2# 3"""Defines button for co-op games.""" 4 5from __future__ import annotations 6 7from typing import TYPE_CHECKING 8import copy 9 10import bauiv1 as bui 11 12if TYPE_CHECKING: 13 from typing import Any, Callable 14 15 16class TournamentButton: 17 """Button showing a tournament in coop window.""" 18 19 def __init__( 20 self, 21 parent: bui.Widget, 22 x: float, 23 y: float, 24 select: bool, 25 on_pressed: Callable[[TournamentButton], None], 26 ) -> None: 27 self._r = 'coopSelectWindow' 28 sclx = 300 29 scly = 195.0 30 self.on_pressed = on_pressed 31 self.lsbt = bui.getmesh('level_select_button_transparent') 32 self.lsbo = bui.getmesh('level_select_button_opaque') 33 self.allow_ads = False 34 self.tournament_id: str | None = None 35 self.time_remaining: int = 0 36 self.has_time_remaining: bool = False 37 self.leader: Any = None 38 self.required_league: str | None = None 39 self.button = btn = bui.buttonwidget( 40 parent=parent, 41 position=(x + 23, y + 4), 42 size=(sclx, scly), 43 label='', 44 button_type='square', 45 autoselect=True, 46 on_activate_call=bui.WeakCall(self._pressed), 47 ) 48 bui.widget( 49 edit=btn, 50 show_buffer_bottom=50, 51 show_buffer_top=50, 52 show_buffer_left=400, 53 show_buffer_right=200, 54 ) 55 if select: 56 bui.containerwidget( 57 edit=parent, selected_child=btn, visible_child=btn 58 ) 59 image_width = sclx * 0.85 * 0.75 60 61 self.image = bui.imagewidget( 62 parent=parent, 63 draw_controller=btn, 64 position=(x + 21 + sclx * 0.5 - image_width * 0.5, y + scly - 150), 65 size=(image_width, image_width * 0.5), 66 mesh_transparent=self.lsbt, 67 mesh_opaque=self.lsbo, 68 texture=bui.gettexture('black'), 69 opacity=0.2, 70 mask_texture=bui.gettexture('mapPreviewMask'), 71 ) 72 73 self.lock_image = bui.imagewidget( 74 parent=parent, 75 draw_controller=btn, 76 position=(x + 21 + sclx * 0.5 - image_width * 0.25, y + scly - 150), 77 size=(image_width * 0.5, image_width * 0.5), 78 texture=bui.gettexture('lock'), 79 opacity=0.0, 80 ) 81 82 self.button_text = bui.textwidget( 83 parent=parent, 84 draw_controller=btn, 85 position=(x + 20 + sclx * 0.5, y + scly - 35), 86 size=(0, 0), 87 h_align='center', 88 text='-', 89 v_align='center', 90 maxwidth=sclx * 0.76, 91 scale=0.85, 92 color=(0.8, 1.0, 0.8, 1.0), 93 ) 94 95 header_color = (0.43, 0.4, 0.5, 1) 96 value_color = (0.6, 0.6, 0.6, 1) 97 98 x_offs = 0 99 bui.textwidget( 100 parent=parent, 101 draw_controller=btn, 102 position=(x + 360, y + scly - 20), 103 size=(0, 0), 104 h_align='center', 105 text=bui.Lstr(resource=self._r + '.entryFeeText'), 106 v_align='center', 107 maxwidth=100, 108 scale=0.9, 109 color=header_color, 110 flatness=1.0, 111 ) 112 113 self.entry_fee_text_top = bui.textwidget( 114 parent=parent, 115 draw_controller=btn, 116 position=(x + 360, y + scly - 60), 117 size=(0, 0), 118 h_align='center', 119 text='-', 120 v_align='center', 121 maxwidth=60, 122 scale=1.3, 123 color=value_color, 124 flatness=1.0, 125 ) 126 self.entry_fee_text_or = bui.textwidget( 127 parent=parent, 128 draw_controller=btn, 129 position=(x + 360, y + scly - 90), 130 size=(0, 0), 131 h_align='center', 132 text='', 133 v_align='center', 134 maxwidth=60, 135 scale=0.5, 136 color=value_color, 137 flatness=1.0, 138 ) 139 self.entry_fee_text_remaining = bui.textwidget( 140 parent=parent, 141 draw_controller=btn, 142 position=(x + 360, y + scly - 90), 143 size=(0, 0), 144 h_align='center', 145 text='', 146 v_align='center', 147 maxwidth=60, 148 scale=0.5, 149 color=value_color, 150 flatness=1.0, 151 ) 152 153 self.entry_fee_ad_image = bui.imagewidget( 154 parent=parent, 155 size=(40, 40), 156 draw_controller=btn, 157 position=(x + 360 - 20, y + scly - 140), 158 opacity=0.0, 159 texture=bui.gettexture('tv'), 160 ) 161 162 x_offs += 50 163 164 bui.textwidget( 165 parent=parent, 166 draw_controller=btn, 167 position=(x + 447 + x_offs, y + scly - 20), 168 size=(0, 0), 169 h_align='center', 170 text=bui.Lstr(resource=self._r + '.prizesText'), 171 v_align='center', 172 maxwidth=130, 173 scale=0.9, 174 color=header_color, 175 flatness=1.0, 176 ) 177 178 self.button_x = x 179 self.button_y = y 180 self.button_scale_y = scly 181 182 xo2 = 0 183 prize_value_scale = 1.5 184 185 self.prize_range_1_text = bui.textwidget( 186 parent=parent, 187 draw_controller=btn, 188 position=(x + 355 + xo2 + x_offs, y + scly - 93), 189 size=(0, 0), 190 h_align='right', 191 v_align='center', 192 maxwidth=50, 193 text='-', 194 scale=0.8, 195 color=header_color, 196 flatness=1.0, 197 ) 198 self.prize_value_1_text = bui.textwidget( 199 parent=parent, 200 draw_controller=btn, 201 position=(x + 380 + xo2 + x_offs, y + scly - 93), 202 size=(0, 0), 203 h_align='left', 204 text='-', 205 v_align='center', 206 maxwidth=100, 207 scale=prize_value_scale, 208 color=value_color, 209 flatness=1.0, 210 ) 211 212 self.prize_range_2_text = bui.textwidget( 213 parent=parent, 214 draw_controller=btn, 215 position=(x + 355 + xo2 + x_offs, y + scly - 93), 216 size=(0, 0), 217 h_align='right', 218 v_align='center', 219 maxwidth=50, 220 scale=0.8, 221 color=header_color, 222 flatness=1.0, 223 ) 224 self.prize_value_2_text = bui.textwidget( 225 parent=parent, 226 draw_controller=btn, 227 position=(x + 380 + xo2 + x_offs, y + scly - 93), 228 size=(0, 0), 229 h_align='left', 230 text='', 231 v_align='center', 232 maxwidth=100, 233 scale=prize_value_scale, 234 color=value_color, 235 flatness=1.0, 236 ) 237 238 self.prize_range_3_text = bui.textwidget( 239 parent=parent, 240 draw_controller=btn, 241 position=(x + 355 + xo2 + x_offs, y + scly - 93), 242 size=(0, 0), 243 h_align='right', 244 v_align='center', 245 maxwidth=50, 246 scale=0.8, 247 color=header_color, 248 flatness=1.0, 249 ) 250 self.prize_value_3_text = bui.textwidget( 251 parent=parent, 252 draw_controller=btn, 253 position=(x + 380 + xo2 + x_offs, y + scly - 93), 254 size=(0, 0), 255 h_align='left', 256 text='', 257 v_align='center', 258 maxwidth=100, 259 scale=prize_value_scale, 260 color=value_color, 261 flatness=1.0, 262 ) 263 264 bui.textwidget( 265 parent=parent, 266 draw_controller=btn, 267 position=(x + 620 + x_offs, y + scly - 20), 268 size=(0, 0), 269 h_align='center', 270 text=bui.Lstr(resource=self._r + '.currentBestText'), 271 v_align='center', 272 maxwidth=180, 273 scale=0.9, 274 color=header_color, 275 flatness=1.0, 276 ) 277 self.current_leader_name_text = bui.textwidget( 278 parent=parent, 279 draw_controller=btn, 280 position=( 281 x + 620 + x_offs - (170 / 1.4) * 0.5, 282 y + scly - 60 - 40 * 0.5, 283 ), 284 selectable=True, 285 click_activate=True, 286 autoselect=True, 287 on_activate_call=bui.WeakCall(self._show_leader), 288 size=(170 / 1.4, 40), 289 h_align='center', 290 text='-', 291 v_align='center', 292 maxwidth=170, 293 scale=1.4, 294 color=value_color, 295 flatness=1.0, 296 ) 297 self.current_leader_score_text = bui.textwidget( 298 parent=parent, 299 draw_controller=btn, 300 position=(x + 620 + x_offs, y + scly - 113 + 10), 301 size=(0, 0), 302 h_align='center', 303 text='-', 304 v_align='center', 305 maxwidth=170, 306 scale=1.8, 307 color=value_color, 308 flatness=1.0, 309 ) 310 311 self.more_scores_button = bui.buttonwidget( 312 parent=parent, 313 position=(x + 620 + x_offs - 60, y + scly - 50 - 125), 314 color=(0.5, 0.5, 0.6), 315 textcolor=(0.7, 0.7, 0.8), 316 label='-', 317 size=(120, 40), 318 autoselect=True, 319 up_widget=self.current_leader_name_text, 320 text_scale=0.6, 321 on_activate_call=bui.WeakCall(self._show_scores), 322 ) 323 bui.widget( 324 edit=self.current_leader_name_text, 325 down_widget=self.more_scores_button, 326 ) 327 328 bui.textwidget( 329 parent=parent, 330 draw_controller=btn, 331 position=(x + 820 + x_offs, y + scly - 20), 332 size=(0, 0), 333 h_align='center', 334 text=bui.Lstr(resource=self._r + '.timeRemainingText'), 335 v_align='center', 336 maxwidth=180, 337 scale=0.9, 338 color=header_color, 339 flatness=1.0, 340 ) 341 self.time_remaining_value_text = bui.textwidget( 342 parent=parent, 343 draw_controller=btn, 344 position=(x + 820 + x_offs, y + scly - 68), 345 size=(0, 0), 346 h_align='center', 347 text='-', 348 v_align='center', 349 maxwidth=180, 350 scale=2.0, 351 color=value_color, 352 flatness=1.0, 353 ) 354 self.time_remaining_out_of_text = bui.textwidget( 355 parent=parent, 356 draw_controller=btn, 357 position=(x + 820 + x_offs, y + scly - 110), 358 size=(0, 0), 359 h_align='center', 360 text='-', 361 v_align='center', 362 maxwidth=120, 363 scale=0.72, 364 color=(0.4, 0.4, 0.5), 365 flatness=1.0, 366 ) 367 368 def _pressed(self) -> None: 369 self.on_pressed(self) 370 371 def _show_leader(self) -> None: 372 # pylint: disable=cyclic-import 373 from bauiv1lib.account.viewer import AccountViewerWindow 374 375 tournament_id = self.tournament_id 376 377 # FIXME: This assumes a single player entry in leader; should expand 378 # this to work with multiple. 379 if ( 380 tournament_id is None 381 or self.leader is None 382 or len(self.leader[2]) != 1 383 ): 384 bui.getsound('error').play() 385 return 386 bui.getsound('swish').play() 387 AccountViewerWindow( 388 account_id=self.leader[2][0].get('a', None), 389 profile_id=self.leader[2][0].get('p', None), 390 position=self.current_leader_name_text.get_screen_space_center(), 391 ) 392 393 def _show_scores(self) -> None: 394 # pylint: disable=cyclic-import 395 from bauiv1lib.tournamentscores import TournamentScoresWindow 396 397 tournament_id = self.tournament_id 398 if tournament_id is None: 399 bui.getsound('error').play() 400 return 401 402 TournamentScoresWindow( 403 tournament_id=tournament_id, 404 position=self.more_scores_button.get_screen_space_center(), 405 ) 406 407 def update_for_data(self, entry: dict[str, Any]) -> None: 408 """Update for new incoming data.""" 409 # pylint: disable=too-many-statements 410 # pylint: disable=too-many-locals 411 # pylint: disable=too-many-branches 412 413 plus = bui.app.plus 414 assert plus is not None 415 416 assert bui.app.classic is not None 417 prize_y_offs = ( 418 34 419 if 'prizeRange3' in entry 420 else 20 421 if 'prizeRange2' in entry 422 else 12 423 ) 424 x_offs = 90 425 426 # pylint: disable=useless-suppression 427 # pylint: disable=unbalanced-tuple-unpacking 428 ( 429 pr1, 430 pv1, 431 pr2, 432 pv2, 433 pr3, 434 pv3, 435 ) = bui.app.classic.get_tournament_prize_strings(entry) 436 # pylint: enable=unbalanced-tuple-unpacking 437 # pylint: enable=useless-suppression 438 439 enabled = 'requiredLeague' not in entry 440 bui.buttonwidget( 441 edit=self.button, 442 color=(0.5, 0.7, 0.2) if enabled else (0.5, 0.5, 0.5), 443 ) 444 bui.imagewidget(edit=self.lock_image, opacity=0.0 if enabled else 1.0) 445 bui.textwidget( 446 edit=self.prize_range_1_text, 447 text='-' if pr1 == '' else pr1, 448 position=( 449 self.button_x + 365 + x_offs, 450 self.button_y + self.button_scale_y - 93 + prize_y_offs, 451 ), 452 ) 453 454 # We want to draw values containing tickets a bit smaller 455 # (scratch that; we now draw medals a bit bigger). 456 ticket_char = bui.charstr(bui.SpecialChar.TICKET_BACKING) 457 prize_value_scale_large = 1.0 458 prize_value_scale_small = 1.0 459 460 bui.textwidget( 461 edit=self.prize_value_1_text, 462 text='-' if pv1 == '' else pv1, 463 scale=prize_value_scale_large 464 if ticket_char not in pv1 465 else prize_value_scale_small, 466 position=( 467 self.button_x + 380 + x_offs, 468 self.button_y + self.button_scale_y - 93 + prize_y_offs, 469 ), 470 ) 471 472 bui.textwidget( 473 edit=self.prize_range_2_text, 474 text=pr2, 475 position=( 476 self.button_x + 365 + x_offs, 477 self.button_y + self.button_scale_y - 93 - 45 + prize_y_offs, 478 ), 479 ) 480 bui.textwidget( 481 edit=self.prize_value_2_text, 482 text=pv2, 483 scale=prize_value_scale_large 484 if ticket_char not in pv2 485 else prize_value_scale_small, 486 position=( 487 self.button_x + 380 + x_offs, 488 self.button_y + self.button_scale_y - 93 - 45 + prize_y_offs, 489 ), 490 ) 491 492 bui.textwidget( 493 edit=self.prize_range_3_text, 494 text=pr3, 495 position=( 496 self.button_x + 365 + x_offs, 497 self.button_y + self.button_scale_y - 93 - 90 + prize_y_offs, 498 ), 499 ) 500 bui.textwidget( 501 edit=self.prize_value_3_text, 502 text=pv3, 503 scale=prize_value_scale_large 504 if ticket_char not in pv3 505 else prize_value_scale_small, 506 position=( 507 self.button_x + 380 + x_offs, 508 self.button_y + self.button_scale_y - 93 - 90 + prize_y_offs, 509 ), 510 ) 511 512 leader_name = '-' 513 leader_score: str | bui.Lstr = '-' 514 if entry['scores']: 515 score = self.leader = copy.deepcopy(entry['scores'][0]) 516 leader_name = score[1] 517 leader_score = ( 518 bui.timestring((score[0] * 10) / 1000.0, centi=True) 519 if entry['scoreType'] == 'time' 520 else str(score[0]) 521 ) 522 else: 523 self.leader = None 524 525 bui.textwidget( 526 edit=self.current_leader_name_text, text=bui.Lstr(value=leader_name) 527 ) 528 bui.textwidget(edit=self.current_leader_score_text, text=leader_score) 529 bui.buttonwidget( 530 edit=self.more_scores_button, 531 label=bui.Lstr(resource=self._r + '.seeMoreText'), 532 ) 533 out_of_time_text: str | bui.Lstr = ( 534 '-' 535 if 'totalTime' not in entry 536 else bui.Lstr( 537 resource=self._r + '.ofTotalTimeText', 538 subs=[ 539 ( 540 '${TOTAL}', 541 bui.timestring(entry['totalTime'], centi=False), 542 ) 543 ], 544 ) 545 ) 546 bui.textwidget( 547 edit=self.time_remaining_out_of_text, text=out_of_time_text 548 ) 549 550 self.time_remaining = entry['timeRemaining'] 551 self.has_time_remaining = entry is not None 552 self.tournament_id = entry['tournamentID'] 553 self.required_league = ( 554 None if 'requiredLeague' not in entry else entry['requiredLeague'] 555 ) 556 557 assert bui.app.classic is not None 558 game = bui.app.classic.accounts.tournament_info[self.tournament_id][ 559 'game' 560 ] 561 562 if game is None: 563 bui.textwidget(edit=self.button_text, text='-') 564 bui.imagewidget( 565 edit=self.image, texture=bui.gettexture('black'), opacity=0.2 566 ) 567 else: 568 campaignname, levelname = game.split(':') 569 campaign = bui.app.classic.getcampaign(campaignname) 570 max_players = bui.app.classic.accounts.tournament_info[ 571 self.tournament_id 572 ]['maxPlayers'] 573 txt = bui.Lstr( 574 value='${A} ${B}', 575 subs=[ 576 ('${A}', campaign.getlevel(levelname).displayname), 577 ( 578 '${B}', 579 bui.Lstr( 580 resource='playerCountAbbreviatedText', 581 subs=[('${COUNT}', str(max_players))], 582 ), 583 ), 584 ], 585 ) 586 bui.textwidget(edit=self.button_text, text=txt) 587 bui.imagewidget( 588 edit=self.image, 589 texture=bui.gettexture( 590 campaign.getlevel(levelname).preview_texture_name 591 ), 592 opacity=1.0 if enabled else 0.5, 593 ) 594 595 fee = entry['fee'] 596 597 if fee is None: 598 fee_var = None 599 elif fee == 4: 600 fee_var = 'price.tournament_entry_4' 601 elif fee == 3: 602 fee_var = 'price.tournament_entry_3' 603 elif fee == 2: 604 fee_var = 'price.tournament_entry_2' 605 elif fee == 1: 606 fee_var = 'price.tournament_entry_1' 607 else: 608 if fee != 0: 609 print('Unknown fee value:', fee) 610 fee_var = 'price.tournament_entry_0' 611 612 self.allow_ads = allow_ads = entry['allowAds'] 613 614 final_fee: int | None = ( 615 None 616 if fee_var is None 617 else plus.get_v1_account_misc_read_val(fee_var, '?') 618 ) 619 620 final_fee_str: str | bui.Lstr 621 if fee_var is None: 622 final_fee_str = '' 623 else: 624 if final_fee == 0: 625 final_fee_str = bui.Lstr(resource='getTicketsWindow.freeText') 626 else: 627 final_fee_str = bui.charstr( 628 bui.SpecialChar.TICKET_BACKING 629 ) + str(final_fee) 630 631 assert bui.app.classic is not None 632 ad_tries_remaining = bui.app.classic.accounts.tournament_info[ 633 self.tournament_id 634 ]['adTriesRemaining'] 635 free_tries_remaining = bui.app.classic.accounts.tournament_info[ 636 self.tournament_id 637 ]['freeTriesRemaining'] 638 639 # Now, if this fee allows ads and we support video ads, show 640 # the 'or ad' version. 641 if allow_ads and bui.has_video_ads(): 642 ads_enabled = bui.have_incentivized_ad() 643 bui.imagewidget( 644 edit=self.entry_fee_ad_image, 645 opacity=1.0 if ads_enabled else 0.25, 646 ) 647 or_text = ( 648 bui.Lstr(resource='orText', subs=[('${A}', ''), ('${B}', '')]) 649 .evaluate() 650 .strip() 651 ) 652 bui.textwidget(edit=self.entry_fee_text_or, text=or_text) 653 bui.textwidget( 654 edit=self.entry_fee_text_top, 655 position=( 656 self.button_x + 360, 657 self.button_y + self.button_scale_y - 60, 658 ), 659 scale=1.3, 660 text=final_fee_str, 661 ) 662 663 # Possibly show number of ad-plays remaining. 664 bui.textwidget( 665 edit=self.entry_fee_text_remaining, 666 position=( 667 self.button_x + 360, 668 self.button_y + self.button_scale_y - 146, 669 ), 670 text='' 671 if ad_tries_remaining in [None, 0] 672 else ('' + str(ad_tries_remaining)), 673 color=(0.6, 0.6, 0.6, 1 if ads_enabled else 0.2), 674 ) 675 else: 676 bui.imagewidget(edit=self.entry_fee_ad_image, opacity=0.0) 677 bui.textwidget(edit=self.entry_fee_text_or, text='') 678 bui.textwidget( 679 edit=self.entry_fee_text_top, 680 position=( 681 self.button_x + 360, 682 self.button_y + self.button_scale_y - 80, 683 ), 684 scale=1.3, 685 text=final_fee_str, 686 ) 687 688 # Possibly show number of free-plays remaining. 689 bui.textwidget( 690 edit=self.entry_fee_text_remaining, 691 position=( 692 self.button_x + 360, 693 self.button_y + self.button_scale_y - 100, 694 ), 695 text=( 696 '' 697 if (free_tries_remaining in [None, 0] or final_fee != 0) 698 else ('' + str(free_tries_remaining)) 699 ), 700 color=(0.6, 0.6, 0.6, 1), 701 )
class
TournamentButton:
17class TournamentButton: 18 """Button showing a tournament in coop window.""" 19 20 def __init__( 21 self, 22 parent: bui.Widget, 23 x: float, 24 y: float, 25 select: bool, 26 on_pressed: Callable[[TournamentButton], None], 27 ) -> None: 28 self._r = 'coopSelectWindow' 29 sclx = 300 30 scly = 195.0 31 self.on_pressed = on_pressed 32 self.lsbt = bui.getmesh('level_select_button_transparent') 33 self.lsbo = bui.getmesh('level_select_button_opaque') 34 self.allow_ads = False 35 self.tournament_id: str | None = None 36 self.time_remaining: int = 0 37 self.has_time_remaining: bool = False 38 self.leader: Any = None 39 self.required_league: str | None = None 40 self.button = btn = bui.buttonwidget( 41 parent=parent, 42 position=(x + 23, y + 4), 43 size=(sclx, scly), 44 label='', 45 button_type='square', 46 autoselect=True, 47 on_activate_call=bui.WeakCall(self._pressed), 48 ) 49 bui.widget( 50 edit=btn, 51 show_buffer_bottom=50, 52 show_buffer_top=50, 53 show_buffer_left=400, 54 show_buffer_right=200, 55 ) 56 if select: 57 bui.containerwidget( 58 edit=parent, selected_child=btn, visible_child=btn 59 ) 60 image_width = sclx * 0.85 * 0.75 61 62 self.image = bui.imagewidget( 63 parent=parent, 64 draw_controller=btn, 65 position=(x + 21 + sclx * 0.5 - image_width * 0.5, y + scly - 150), 66 size=(image_width, image_width * 0.5), 67 mesh_transparent=self.lsbt, 68 mesh_opaque=self.lsbo, 69 texture=bui.gettexture('black'), 70 opacity=0.2, 71 mask_texture=bui.gettexture('mapPreviewMask'), 72 ) 73 74 self.lock_image = bui.imagewidget( 75 parent=parent, 76 draw_controller=btn, 77 position=(x + 21 + sclx * 0.5 - image_width * 0.25, y + scly - 150), 78 size=(image_width * 0.5, image_width * 0.5), 79 texture=bui.gettexture('lock'), 80 opacity=0.0, 81 ) 82 83 self.button_text = bui.textwidget( 84 parent=parent, 85 draw_controller=btn, 86 position=(x + 20 + sclx * 0.5, y + scly - 35), 87 size=(0, 0), 88 h_align='center', 89 text='-', 90 v_align='center', 91 maxwidth=sclx * 0.76, 92 scale=0.85, 93 color=(0.8, 1.0, 0.8, 1.0), 94 ) 95 96 header_color = (0.43, 0.4, 0.5, 1) 97 value_color = (0.6, 0.6, 0.6, 1) 98 99 x_offs = 0 100 bui.textwidget( 101 parent=parent, 102 draw_controller=btn, 103 position=(x + 360, y + scly - 20), 104 size=(0, 0), 105 h_align='center', 106 text=bui.Lstr(resource=self._r + '.entryFeeText'), 107 v_align='center', 108 maxwidth=100, 109 scale=0.9, 110 color=header_color, 111 flatness=1.0, 112 ) 113 114 self.entry_fee_text_top = bui.textwidget( 115 parent=parent, 116 draw_controller=btn, 117 position=(x + 360, y + scly - 60), 118 size=(0, 0), 119 h_align='center', 120 text='-', 121 v_align='center', 122 maxwidth=60, 123 scale=1.3, 124 color=value_color, 125 flatness=1.0, 126 ) 127 self.entry_fee_text_or = bui.textwidget( 128 parent=parent, 129 draw_controller=btn, 130 position=(x + 360, y + scly - 90), 131 size=(0, 0), 132 h_align='center', 133 text='', 134 v_align='center', 135 maxwidth=60, 136 scale=0.5, 137 color=value_color, 138 flatness=1.0, 139 ) 140 self.entry_fee_text_remaining = bui.textwidget( 141 parent=parent, 142 draw_controller=btn, 143 position=(x + 360, y + scly - 90), 144 size=(0, 0), 145 h_align='center', 146 text='', 147 v_align='center', 148 maxwidth=60, 149 scale=0.5, 150 color=value_color, 151 flatness=1.0, 152 ) 153 154 self.entry_fee_ad_image = bui.imagewidget( 155 parent=parent, 156 size=(40, 40), 157 draw_controller=btn, 158 position=(x + 360 - 20, y + scly - 140), 159 opacity=0.0, 160 texture=bui.gettexture('tv'), 161 ) 162 163 x_offs += 50 164 165 bui.textwidget( 166 parent=parent, 167 draw_controller=btn, 168 position=(x + 447 + x_offs, y + scly - 20), 169 size=(0, 0), 170 h_align='center', 171 text=bui.Lstr(resource=self._r + '.prizesText'), 172 v_align='center', 173 maxwidth=130, 174 scale=0.9, 175 color=header_color, 176 flatness=1.0, 177 ) 178 179 self.button_x = x 180 self.button_y = y 181 self.button_scale_y = scly 182 183 xo2 = 0 184 prize_value_scale = 1.5 185 186 self.prize_range_1_text = bui.textwidget( 187 parent=parent, 188 draw_controller=btn, 189 position=(x + 355 + xo2 + x_offs, y + scly - 93), 190 size=(0, 0), 191 h_align='right', 192 v_align='center', 193 maxwidth=50, 194 text='-', 195 scale=0.8, 196 color=header_color, 197 flatness=1.0, 198 ) 199 self.prize_value_1_text = bui.textwidget( 200 parent=parent, 201 draw_controller=btn, 202 position=(x + 380 + xo2 + x_offs, y + scly - 93), 203 size=(0, 0), 204 h_align='left', 205 text='-', 206 v_align='center', 207 maxwidth=100, 208 scale=prize_value_scale, 209 color=value_color, 210 flatness=1.0, 211 ) 212 213 self.prize_range_2_text = bui.textwidget( 214 parent=parent, 215 draw_controller=btn, 216 position=(x + 355 + xo2 + x_offs, y + scly - 93), 217 size=(0, 0), 218 h_align='right', 219 v_align='center', 220 maxwidth=50, 221 scale=0.8, 222 color=header_color, 223 flatness=1.0, 224 ) 225 self.prize_value_2_text = bui.textwidget( 226 parent=parent, 227 draw_controller=btn, 228 position=(x + 380 + xo2 + x_offs, y + scly - 93), 229 size=(0, 0), 230 h_align='left', 231 text='', 232 v_align='center', 233 maxwidth=100, 234 scale=prize_value_scale, 235 color=value_color, 236 flatness=1.0, 237 ) 238 239 self.prize_range_3_text = bui.textwidget( 240 parent=parent, 241 draw_controller=btn, 242 position=(x + 355 + xo2 + x_offs, y + scly - 93), 243 size=(0, 0), 244 h_align='right', 245 v_align='center', 246 maxwidth=50, 247 scale=0.8, 248 color=header_color, 249 flatness=1.0, 250 ) 251 self.prize_value_3_text = bui.textwidget( 252 parent=parent, 253 draw_controller=btn, 254 position=(x + 380 + xo2 + x_offs, y + scly - 93), 255 size=(0, 0), 256 h_align='left', 257 text='', 258 v_align='center', 259 maxwidth=100, 260 scale=prize_value_scale, 261 color=value_color, 262 flatness=1.0, 263 ) 264 265 bui.textwidget( 266 parent=parent, 267 draw_controller=btn, 268 position=(x + 620 + x_offs, y + scly - 20), 269 size=(0, 0), 270 h_align='center', 271 text=bui.Lstr(resource=self._r + '.currentBestText'), 272 v_align='center', 273 maxwidth=180, 274 scale=0.9, 275 color=header_color, 276 flatness=1.0, 277 ) 278 self.current_leader_name_text = bui.textwidget( 279 parent=parent, 280 draw_controller=btn, 281 position=( 282 x + 620 + x_offs - (170 / 1.4) * 0.5, 283 y + scly - 60 - 40 * 0.5, 284 ), 285 selectable=True, 286 click_activate=True, 287 autoselect=True, 288 on_activate_call=bui.WeakCall(self._show_leader), 289 size=(170 / 1.4, 40), 290 h_align='center', 291 text='-', 292 v_align='center', 293 maxwidth=170, 294 scale=1.4, 295 color=value_color, 296 flatness=1.0, 297 ) 298 self.current_leader_score_text = bui.textwidget( 299 parent=parent, 300 draw_controller=btn, 301 position=(x + 620 + x_offs, y + scly - 113 + 10), 302 size=(0, 0), 303 h_align='center', 304 text='-', 305 v_align='center', 306 maxwidth=170, 307 scale=1.8, 308 color=value_color, 309 flatness=1.0, 310 ) 311 312 self.more_scores_button = bui.buttonwidget( 313 parent=parent, 314 position=(x + 620 + x_offs - 60, y + scly - 50 - 125), 315 color=(0.5, 0.5, 0.6), 316 textcolor=(0.7, 0.7, 0.8), 317 label='-', 318 size=(120, 40), 319 autoselect=True, 320 up_widget=self.current_leader_name_text, 321 text_scale=0.6, 322 on_activate_call=bui.WeakCall(self._show_scores), 323 ) 324 bui.widget( 325 edit=self.current_leader_name_text, 326 down_widget=self.more_scores_button, 327 ) 328 329 bui.textwidget( 330 parent=parent, 331 draw_controller=btn, 332 position=(x + 820 + x_offs, y + scly - 20), 333 size=(0, 0), 334 h_align='center', 335 text=bui.Lstr(resource=self._r + '.timeRemainingText'), 336 v_align='center', 337 maxwidth=180, 338 scale=0.9, 339 color=header_color, 340 flatness=1.0, 341 ) 342 self.time_remaining_value_text = bui.textwidget( 343 parent=parent, 344 draw_controller=btn, 345 position=(x + 820 + x_offs, y + scly - 68), 346 size=(0, 0), 347 h_align='center', 348 text='-', 349 v_align='center', 350 maxwidth=180, 351 scale=2.0, 352 color=value_color, 353 flatness=1.0, 354 ) 355 self.time_remaining_out_of_text = bui.textwidget( 356 parent=parent, 357 draw_controller=btn, 358 position=(x + 820 + x_offs, y + scly - 110), 359 size=(0, 0), 360 h_align='center', 361 text='-', 362 v_align='center', 363 maxwidth=120, 364 scale=0.72, 365 color=(0.4, 0.4, 0.5), 366 flatness=1.0, 367 ) 368 369 def _pressed(self) -> None: 370 self.on_pressed(self) 371 372 def _show_leader(self) -> None: 373 # pylint: disable=cyclic-import 374 from bauiv1lib.account.viewer import AccountViewerWindow 375 376 tournament_id = self.tournament_id 377 378 # FIXME: This assumes a single player entry in leader; should expand 379 # this to work with multiple. 380 if ( 381 tournament_id is None 382 or self.leader is None 383 or len(self.leader[2]) != 1 384 ): 385 bui.getsound('error').play() 386 return 387 bui.getsound('swish').play() 388 AccountViewerWindow( 389 account_id=self.leader[2][0].get('a', None), 390 profile_id=self.leader[2][0].get('p', None), 391 position=self.current_leader_name_text.get_screen_space_center(), 392 ) 393 394 def _show_scores(self) -> None: 395 # pylint: disable=cyclic-import 396 from bauiv1lib.tournamentscores import TournamentScoresWindow 397 398 tournament_id = self.tournament_id 399 if tournament_id is None: 400 bui.getsound('error').play() 401 return 402 403 TournamentScoresWindow( 404 tournament_id=tournament_id, 405 position=self.more_scores_button.get_screen_space_center(), 406 ) 407 408 def update_for_data(self, entry: dict[str, Any]) -> None: 409 """Update for new incoming data.""" 410 # pylint: disable=too-many-statements 411 # pylint: disable=too-many-locals 412 # pylint: disable=too-many-branches 413 414 plus = bui.app.plus 415 assert plus is not None 416 417 assert bui.app.classic is not None 418 prize_y_offs = ( 419 34 420 if 'prizeRange3' in entry 421 else 20 422 if 'prizeRange2' in entry 423 else 12 424 ) 425 x_offs = 90 426 427 # pylint: disable=useless-suppression 428 # pylint: disable=unbalanced-tuple-unpacking 429 ( 430 pr1, 431 pv1, 432 pr2, 433 pv2, 434 pr3, 435 pv3, 436 ) = bui.app.classic.get_tournament_prize_strings(entry) 437 # pylint: enable=unbalanced-tuple-unpacking 438 # pylint: enable=useless-suppression 439 440 enabled = 'requiredLeague' not in entry 441 bui.buttonwidget( 442 edit=self.button, 443 color=(0.5, 0.7, 0.2) if enabled else (0.5, 0.5, 0.5), 444 ) 445 bui.imagewidget(edit=self.lock_image, opacity=0.0 if enabled else 1.0) 446 bui.textwidget( 447 edit=self.prize_range_1_text, 448 text='-' if pr1 == '' else pr1, 449 position=( 450 self.button_x + 365 + x_offs, 451 self.button_y + self.button_scale_y - 93 + prize_y_offs, 452 ), 453 ) 454 455 # We want to draw values containing tickets a bit smaller 456 # (scratch that; we now draw medals a bit bigger). 457 ticket_char = bui.charstr(bui.SpecialChar.TICKET_BACKING) 458 prize_value_scale_large = 1.0 459 prize_value_scale_small = 1.0 460 461 bui.textwidget( 462 edit=self.prize_value_1_text, 463 text='-' if pv1 == '' else pv1, 464 scale=prize_value_scale_large 465 if ticket_char not in pv1 466 else prize_value_scale_small, 467 position=( 468 self.button_x + 380 + x_offs, 469 self.button_y + self.button_scale_y - 93 + prize_y_offs, 470 ), 471 ) 472 473 bui.textwidget( 474 edit=self.prize_range_2_text, 475 text=pr2, 476 position=( 477 self.button_x + 365 + x_offs, 478 self.button_y + self.button_scale_y - 93 - 45 + prize_y_offs, 479 ), 480 ) 481 bui.textwidget( 482 edit=self.prize_value_2_text, 483 text=pv2, 484 scale=prize_value_scale_large 485 if ticket_char not in pv2 486 else prize_value_scale_small, 487 position=( 488 self.button_x + 380 + x_offs, 489 self.button_y + self.button_scale_y - 93 - 45 + prize_y_offs, 490 ), 491 ) 492 493 bui.textwidget( 494 edit=self.prize_range_3_text, 495 text=pr3, 496 position=( 497 self.button_x + 365 + x_offs, 498 self.button_y + self.button_scale_y - 93 - 90 + prize_y_offs, 499 ), 500 ) 501 bui.textwidget( 502 edit=self.prize_value_3_text, 503 text=pv3, 504 scale=prize_value_scale_large 505 if ticket_char not in pv3 506 else prize_value_scale_small, 507 position=( 508 self.button_x + 380 + x_offs, 509 self.button_y + self.button_scale_y - 93 - 90 + prize_y_offs, 510 ), 511 ) 512 513 leader_name = '-' 514 leader_score: str | bui.Lstr = '-' 515 if entry['scores']: 516 score = self.leader = copy.deepcopy(entry['scores'][0]) 517 leader_name = score[1] 518 leader_score = ( 519 bui.timestring((score[0] * 10) / 1000.0, centi=True) 520 if entry['scoreType'] == 'time' 521 else str(score[0]) 522 ) 523 else: 524 self.leader = None 525 526 bui.textwidget( 527 edit=self.current_leader_name_text, text=bui.Lstr(value=leader_name) 528 ) 529 bui.textwidget(edit=self.current_leader_score_text, text=leader_score) 530 bui.buttonwidget( 531 edit=self.more_scores_button, 532 label=bui.Lstr(resource=self._r + '.seeMoreText'), 533 ) 534 out_of_time_text: str | bui.Lstr = ( 535 '-' 536 if 'totalTime' not in entry 537 else bui.Lstr( 538 resource=self._r + '.ofTotalTimeText', 539 subs=[ 540 ( 541 '${TOTAL}', 542 bui.timestring(entry['totalTime'], centi=False), 543 ) 544 ], 545 ) 546 ) 547 bui.textwidget( 548 edit=self.time_remaining_out_of_text, text=out_of_time_text 549 ) 550 551 self.time_remaining = entry['timeRemaining'] 552 self.has_time_remaining = entry is not None 553 self.tournament_id = entry['tournamentID'] 554 self.required_league = ( 555 None if 'requiredLeague' not in entry else entry['requiredLeague'] 556 ) 557 558 assert bui.app.classic is not None 559 game = bui.app.classic.accounts.tournament_info[self.tournament_id][ 560 'game' 561 ] 562 563 if game is None: 564 bui.textwidget(edit=self.button_text, text='-') 565 bui.imagewidget( 566 edit=self.image, texture=bui.gettexture('black'), opacity=0.2 567 ) 568 else: 569 campaignname, levelname = game.split(':') 570 campaign = bui.app.classic.getcampaign(campaignname) 571 max_players = bui.app.classic.accounts.tournament_info[ 572 self.tournament_id 573 ]['maxPlayers'] 574 txt = bui.Lstr( 575 value='${A} ${B}', 576 subs=[ 577 ('${A}', campaign.getlevel(levelname).displayname), 578 ( 579 '${B}', 580 bui.Lstr( 581 resource='playerCountAbbreviatedText', 582 subs=[('${COUNT}', str(max_players))], 583 ), 584 ), 585 ], 586 ) 587 bui.textwidget(edit=self.button_text, text=txt) 588 bui.imagewidget( 589 edit=self.image, 590 texture=bui.gettexture( 591 campaign.getlevel(levelname).preview_texture_name 592 ), 593 opacity=1.0 if enabled else 0.5, 594 ) 595 596 fee = entry['fee'] 597 598 if fee is None: 599 fee_var = None 600 elif fee == 4: 601 fee_var = 'price.tournament_entry_4' 602 elif fee == 3: 603 fee_var = 'price.tournament_entry_3' 604 elif fee == 2: 605 fee_var = 'price.tournament_entry_2' 606 elif fee == 1: 607 fee_var = 'price.tournament_entry_1' 608 else: 609 if fee != 0: 610 print('Unknown fee value:', fee) 611 fee_var = 'price.tournament_entry_0' 612 613 self.allow_ads = allow_ads = entry['allowAds'] 614 615 final_fee: int | None = ( 616 None 617 if fee_var is None 618 else plus.get_v1_account_misc_read_val(fee_var, '?') 619 ) 620 621 final_fee_str: str | bui.Lstr 622 if fee_var is None: 623 final_fee_str = '' 624 else: 625 if final_fee == 0: 626 final_fee_str = bui.Lstr(resource='getTicketsWindow.freeText') 627 else: 628 final_fee_str = bui.charstr( 629 bui.SpecialChar.TICKET_BACKING 630 ) + str(final_fee) 631 632 assert bui.app.classic is not None 633 ad_tries_remaining = bui.app.classic.accounts.tournament_info[ 634 self.tournament_id 635 ]['adTriesRemaining'] 636 free_tries_remaining = bui.app.classic.accounts.tournament_info[ 637 self.tournament_id 638 ]['freeTriesRemaining'] 639 640 # Now, if this fee allows ads and we support video ads, show 641 # the 'or ad' version. 642 if allow_ads and bui.has_video_ads(): 643 ads_enabled = bui.have_incentivized_ad() 644 bui.imagewidget( 645 edit=self.entry_fee_ad_image, 646 opacity=1.0 if ads_enabled else 0.25, 647 ) 648 or_text = ( 649 bui.Lstr(resource='orText', subs=[('${A}', ''), ('${B}', '')]) 650 .evaluate() 651 .strip() 652 ) 653 bui.textwidget(edit=self.entry_fee_text_or, text=or_text) 654 bui.textwidget( 655 edit=self.entry_fee_text_top, 656 position=( 657 self.button_x + 360, 658 self.button_y + self.button_scale_y - 60, 659 ), 660 scale=1.3, 661 text=final_fee_str, 662 ) 663 664 # Possibly show number of ad-plays remaining. 665 bui.textwidget( 666 edit=self.entry_fee_text_remaining, 667 position=( 668 self.button_x + 360, 669 self.button_y + self.button_scale_y - 146, 670 ), 671 text='' 672 if ad_tries_remaining in [None, 0] 673 else ('' + str(ad_tries_remaining)), 674 color=(0.6, 0.6, 0.6, 1 if ads_enabled else 0.2), 675 ) 676 else: 677 bui.imagewidget(edit=self.entry_fee_ad_image, opacity=0.0) 678 bui.textwidget(edit=self.entry_fee_text_or, text='') 679 bui.textwidget( 680 edit=self.entry_fee_text_top, 681 position=( 682 self.button_x + 360, 683 self.button_y + self.button_scale_y - 80, 684 ), 685 scale=1.3, 686 text=final_fee_str, 687 ) 688 689 # Possibly show number of free-plays remaining. 690 bui.textwidget( 691 edit=self.entry_fee_text_remaining, 692 position=( 693 self.button_x + 360, 694 self.button_y + self.button_scale_y - 100, 695 ), 696 text=( 697 '' 698 if (free_tries_remaining in [None, 0] or final_fee != 0) 699 else ('' + str(free_tries_remaining)) 700 ), 701 color=(0.6, 0.6, 0.6, 1), 702 )
Button showing a tournament in coop window.
TournamentButton( parent: _bauiv1.Widget, x: float, y: float, select: bool, on_pressed: Callable[[TournamentButton], NoneType])
20 def __init__( 21 self, 22 parent: bui.Widget, 23 x: float, 24 y: float, 25 select: bool, 26 on_pressed: Callable[[TournamentButton], None], 27 ) -> None: 28 self._r = 'coopSelectWindow' 29 sclx = 300 30 scly = 195.0 31 self.on_pressed = on_pressed 32 self.lsbt = bui.getmesh('level_select_button_transparent') 33 self.lsbo = bui.getmesh('level_select_button_opaque') 34 self.allow_ads = False 35 self.tournament_id: str | None = None 36 self.time_remaining: int = 0 37 self.has_time_remaining: bool = False 38 self.leader: Any = None 39 self.required_league: str | None = None 40 self.button = btn = bui.buttonwidget( 41 parent=parent, 42 position=(x + 23, y + 4), 43 size=(sclx, scly), 44 label='', 45 button_type='square', 46 autoselect=True, 47 on_activate_call=bui.WeakCall(self._pressed), 48 ) 49 bui.widget( 50 edit=btn, 51 show_buffer_bottom=50, 52 show_buffer_top=50, 53 show_buffer_left=400, 54 show_buffer_right=200, 55 ) 56 if select: 57 bui.containerwidget( 58 edit=parent, selected_child=btn, visible_child=btn 59 ) 60 image_width = sclx * 0.85 * 0.75 61 62 self.image = bui.imagewidget( 63 parent=parent, 64 draw_controller=btn, 65 position=(x + 21 + sclx * 0.5 - image_width * 0.5, y + scly - 150), 66 size=(image_width, image_width * 0.5), 67 mesh_transparent=self.lsbt, 68 mesh_opaque=self.lsbo, 69 texture=bui.gettexture('black'), 70 opacity=0.2, 71 mask_texture=bui.gettexture('mapPreviewMask'), 72 ) 73 74 self.lock_image = bui.imagewidget( 75 parent=parent, 76 draw_controller=btn, 77 position=(x + 21 + sclx * 0.5 - image_width * 0.25, y + scly - 150), 78 size=(image_width * 0.5, image_width * 0.5), 79 texture=bui.gettexture('lock'), 80 opacity=0.0, 81 ) 82 83 self.button_text = bui.textwidget( 84 parent=parent, 85 draw_controller=btn, 86 position=(x + 20 + sclx * 0.5, y + scly - 35), 87 size=(0, 0), 88 h_align='center', 89 text='-', 90 v_align='center', 91 maxwidth=sclx * 0.76, 92 scale=0.85, 93 color=(0.8, 1.0, 0.8, 1.0), 94 ) 95 96 header_color = (0.43, 0.4, 0.5, 1) 97 value_color = (0.6, 0.6, 0.6, 1) 98 99 x_offs = 0 100 bui.textwidget( 101 parent=parent, 102 draw_controller=btn, 103 position=(x + 360, y + scly - 20), 104 size=(0, 0), 105 h_align='center', 106 text=bui.Lstr(resource=self._r + '.entryFeeText'), 107 v_align='center', 108 maxwidth=100, 109 scale=0.9, 110 color=header_color, 111 flatness=1.0, 112 ) 113 114 self.entry_fee_text_top = bui.textwidget( 115 parent=parent, 116 draw_controller=btn, 117 position=(x + 360, y + scly - 60), 118 size=(0, 0), 119 h_align='center', 120 text='-', 121 v_align='center', 122 maxwidth=60, 123 scale=1.3, 124 color=value_color, 125 flatness=1.0, 126 ) 127 self.entry_fee_text_or = bui.textwidget( 128 parent=parent, 129 draw_controller=btn, 130 position=(x + 360, y + scly - 90), 131 size=(0, 0), 132 h_align='center', 133 text='', 134 v_align='center', 135 maxwidth=60, 136 scale=0.5, 137 color=value_color, 138 flatness=1.0, 139 ) 140 self.entry_fee_text_remaining = bui.textwidget( 141 parent=parent, 142 draw_controller=btn, 143 position=(x + 360, y + scly - 90), 144 size=(0, 0), 145 h_align='center', 146 text='', 147 v_align='center', 148 maxwidth=60, 149 scale=0.5, 150 color=value_color, 151 flatness=1.0, 152 ) 153 154 self.entry_fee_ad_image = bui.imagewidget( 155 parent=parent, 156 size=(40, 40), 157 draw_controller=btn, 158 position=(x + 360 - 20, y + scly - 140), 159 opacity=0.0, 160 texture=bui.gettexture('tv'), 161 ) 162 163 x_offs += 50 164 165 bui.textwidget( 166 parent=parent, 167 draw_controller=btn, 168 position=(x + 447 + x_offs, y + scly - 20), 169 size=(0, 0), 170 h_align='center', 171 text=bui.Lstr(resource=self._r + '.prizesText'), 172 v_align='center', 173 maxwidth=130, 174 scale=0.9, 175 color=header_color, 176 flatness=1.0, 177 ) 178 179 self.button_x = x 180 self.button_y = y 181 self.button_scale_y = scly 182 183 xo2 = 0 184 prize_value_scale = 1.5 185 186 self.prize_range_1_text = bui.textwidget( 187 parent=parent, 188 draw_controller=btn, 189 position=(x + 355 + xo2 + x_offs, y + scly - 93), 190 size=(0, 0), 191 h_align='right', 192 v_align='center', 193 maxwidth=50, 194 text='-', 195 scale=0.8, 196 color=header_color, 197 flatness=1.0, 198 ) 199 self.prize_value_1_text = bui.textwidget( 200 parent=parent, 201 draw_controller=btn, 202 position=(x + 380 + xo2 + x_offs, y + scly - 93), 203 size=(0, 0), 204 h_align='left', 205 text='-', 206 v_align='center', 207 maxwidth=100, 208 scale=prize_value_scale, 209 color=value_color, 210 flatness=1.0, 211 ) 212 213 self.prize_range_2_text = bui.textwidget( 214 parent=parent, 215 draw_controller=btn, 216 position=(x + 355 + xo2 + x_offs, y + scly - 93), 217 size=(0, 0), 218 h_align='right', 219 v_align='center', 220 maxwidth=50, 221 scale=0.8, 222 color=header_color, 223 flatness=1.0, 224 ) 225 self.prize_value_2_text = bui.textwidget( 226 parent=parent, 227 draw_controller=btn, 228 position=(x + 380 + xo2 + x_offs, y + scly - 93), 229 size=(0, 0), 230 h_align='left', 231 text='', 232 v_align='center', 233 maxwidth=100, 234 scale=prize_value_scale, 235 color=value_color, 236 flatness=1.0, 237 ) 238 239 self.prize_range_3_text = bui.textwidget( 240 parent=parent, 241 draw_controller=btn, 242 position=(x + 355 + xo2 + x_offs, y + scly - 93), 243 size=(0, 0), 244 h_align='right', 245 v_align='center', 246 maxwidth=50, 247 scale=0.8, 248 color=header_color, 249 flatness=1.0, 250 ) 251 self.prize_value_3_text = bui.textwidget( 252 parent=parent, 253 draw_controller=btn, 254 position=(x + 380 + xo2 + x_offs, y + scly - 93), 255 size=(0, 0), 256 h_align='left', 257 text='', 258 v_align='center', 259 maxwidth=100, 260 scale=prize_value_scale, 261 color=value_color, 262 flatness=1.0, 263 ) 264 265 bui.textwidget( 266 parent=parent, 267 draw_controller=btn, 268 position=(x + 620 + x_offs, y + scly - 20), 269 size=(0, 0), 270 h_align='center', 271 text=bui.Lstr(resource=self._r + '.currentBestText'), 272 v_align='center', 273 maxwidth=180, 274 scale=0.9, 275 color=header_color, 276 flatness=1.0, 277 ) 278 self.current_leader_name_text = bui.textwidget( 279 parent=parent, 280 draw_controller=btn, 281 position=( 282 x + 620 + x_offs - (170 / 1.4) * 0.5, 283 y + scly - 60 - 40 * 0.5, 284 ), 285 selectable=True, 286 click_activate=True, 287 autoselect=True, 288 on_activate_call=bui.WeakCall(self._show_leader), 289 size=(170 / 1.4, 40), 290 h_align='center', 291 text='-', 292 v_align='center', 293 maxwidth=170, 294 scale=1.4, 295 color=value_color, 296 flatness=1.0, 297 ) 298 self.current_leader_score_text = bui.textwidget( 299 parent=parent, 300 draw_controller=btn, 301 position=(x + 620 + x_offs, y + scly - 113 + 10), 302 size=(0, 0), 303 h_align='center', 304 text='-', 305 v_align='center', 306 maxwidth=170, 307 scale=1.8, 308 color=value_color, 309 flatness=1.0, 310 ) 311 312 self.more_scores_button = bui.buttonwidget( 313 parent=parent, 314 position=(x + 620 + x_offs - 60, y + scly - 50 - 125), 315 color=(0.5, 0.5, 0.6), 316 textcolor=(0.7, 0.7, 0.8), 317 label='-', 318 size=(120, 40), 319 autoselect=True, 320 up_widget=self.current_leader_name_text, 321 text_scale=0.6, 322 on_activate_call=bui.WeakCall(self._show_scores), 323 ) 324 bui.widget( 325 edit=self.current_leader_name_text, 326 down_widget=self.more_scores_button, 327 ) 328 329 bui.textwidget( 330 parent=parent, 331 draw_controller=btn, 332 position=(x + 820 + x_offs, y + scly - 20), 333 size=(0, 0), 334 h_align='center', 335 text=bui.Lstr(resource=self._r + '.timeRemainingText'), 336 v_align='center', 337 maxwidth=180, 338 scale=0.9, 339 color=header_color, 340 flatness=1.0, 341 ) 342 self.time_remaining_value_text = bui.textwidget( 343 parent=parent, 344 draw_controller=btn, 345 position=(x + 820 + x_offs, y + scly - 68), 346 size=(0, 0), 347 h_align='center', 348 text='-', 349 v_align='center', 350 maxwidth=180, 351 scale=2.0, 352 color=value_color, 353 flatness=1.0, 354 ) 355 self.time_remaining_out_of_text = bui.textwidget( 356 parent=parent, 357 draw_controller=btn, 358 position=(x + 820 + x_offs, y + scly - 110), 359 size=(0, 0), 360 h_align='center', 361 text='-', 362 v_align='center', 363 maxwidth=120, 364 scale=0.72, 365 color=(0.4, 0.4, 0.5), 366 flatness=1.0, 367 )
def
update_for_data(self, entry: dict[str, typing.Any]) -> None:
408 def update_for_data(self, entry: dict[str, Any]) -> None: 409 """Update for new incoming data.""" 410 # pylint: disable=too-many-statements 411 # pylint: disable=too-many-locals 412 # pylint: disable=too-many-branches 413 414 plus = bui.app.plus 415 assert plus is not None 416 417 assert bui.app.classic is not None 418 prize_y_offs = ( 419 34 420 if 'prizeRange3' in entry 421 else 20 422 if 'prizeRange2' in entry 423 else 12 424 ) 425 x_offs = 90 426 427 # pylint: disable=useless-suppression 428 # pylint: disable=unbalanced-tuple-unpacking 429 ( 430 pr1, 431 pv1, 432 pr2, 433 pv2, 434 pr3, 435 pv3, 436 ) = bui.app.classic.get_tournament_prize_strings(entry) 437 # pylint: enable=unbalanced-tuple-unpacking 438 # pylint: enable=useless-suppression 439 440 enabled = 'requiredLeague' not in entry 441 bui.buttonwidget( 442 edit=self.button, 443 color=(0.5, 0.7, 0.2) if enabled else (0.5, 0.5, 0.5), 444 ) 445 bui.imagewidget(edit=self.lock_image, opacity=0.0 if enabled else 1.0) 446 bui.textwidget( 447 edit=self.prize_range_1_text, 448 text='-' if pr1 == '' else pr1, 449 position=( 450 self.button_x + 365 + x_offs, 451 self.button_y + self.button_scale_y - 93 + prize_y_offs, 452 ), 453 ) 454 455 # We want to draw values containing tickets a bit smaller 456 # (scratch that; we now draw medals a bit bigger). 457 ticket_char = bui.charstr(bui.SpecialChar.TICKET_BACKING) 458 prize_value_scale_large = 1.0 459 prize_value_scale_small = 1.0 460 461 bui.textwidget( 462 edit=self.prize_value_1_text, 463 text='-' if pv1 == '' else pv1, 464 scale=prize_value_scale_large 465 if ticket_char not in pv1 466 else prize_value_scale_small, 467 position=( 468 self.button_x + 380 + x_offs, 469 self.button_y + self.button_scale_y - 93 + prize_y_offs, 470 ), 471 ) 472 473 bui.textwidget( 474 edit=self.prize_range_2_text, 475 text=pr2, 476 position=( 477 self.button_x + 365 + x_offs, 478 self.button_y + self.button_scale_y - 93 - 45 + prize_y_offs, 479 ), 480 ) 481 bui.textwidget( 482 edit=self.prize_value_2_text, 483 text=pv2, 484 scale=prize_value_scale_large 485 if ticket_char not in pv2 486 else prize_value_scale_small, 487 position=( 488 self.button_x + 380 + x_offs, 489 self.button_y + self.button_scale_y - 93 - 45 + prize_y_offs, 490 ), 491 ) 492 493 bui.textwidget( 494 edit=self.prize_range_3_text, 495 text=pr3, 496 position=( 497 self.button_x + 365 + x_offs, 498 self.button_y + self.button_scale_y - 93 - 90 + prize_y_offs, 499 ), 500 ) 501 bui.textwidget( 502 edit=self.prize_value_3_text, 503 text=pv3, 504 scale=prize_value_scale_large 505 if ticket_char not in pv3 506 else prize_value_scale_small, 507 position=( 508 self.button_x + 380 + x_offs, 509 self.button_y + self.button_scale_y - 93 - 90 + prize_y_offs, 510 ), 511 ) 512 513 leader_name = '-' 514 leader_score: str | bui.Lstr = '-' 515 if entry['scores']: 516 score = self.leader = copy.deepcopy(entry['scores'][0]) 517 leader_name = score[1] 518 leader_score = ( 519 bui.timestring((score[0] * 10) / 1000.0, centi=True) 520 if entry['scoreType'] == 'time' 521 else str(score[0]) 522 ) 523 else: 524 self.leader = None 525 526 bui.textwidget( 527 edit=self.current_leader_name_text, text=bui.Lstr(value=leader_name) 528 ) 529 bui.textwidget(edit=self.current_leader_score_text, text=leader_score) 530 bui.buttonwidget( 531 edit=self.more_scores_button, 532 label=bui.Lstr(resource=self._r + '.seeMoreText'), 533 ) 534 out_of_time_text: str | bui.Lstr = ( 535 '-' 536 if 'totalTime' not in entry 537 else bui.Lstr( 538 resource=self._r + '.ofTotalTimeText', 539 subs=[ 540 ( 541 '${TOTAL}', 542 bui.timestring(entry['totalTime'], centi=False), 543 ) 544 ], 545 ) 546 ) 547 bui.textwidget( 548 edit=self.time_remaining_out_of_text, text=out_of_time_text 549 ) 550 551 self.time_remaining = entry['timeRemaining'] 552 self.has_time_remaining = entry is not None 553 self.tournament_id = entry['tournamentID'] 554 self.required_league = ( 555 None if 'requiredLeague' not in entry else entry['requiredLeague'] 556 ) 557 558 assert bui.app.classic is not None 559 game = bui.app.classic.accounts.tournament_info[self.tournament_id][ 560 'game' 561 ] 562 563 if game is None: 564 bui.textwidget(edit=self.button_text, text='-') 565 bui.imagewidget( 566 edit=self.image, texture=bui.gettexture('black'), opacity=0.2 567 ) 568 else: 569 campaignname, levelname = game.split(':') 570 campaign = bui.app.classic.getcampaign(campaignname) 571 max_players = bui.app.classic.accounts.tournament_info[ 572 self.tournament_id 573 ]['maxPlayers'] 574 txt = bui.Lstr( 575 value='${A} ${B}', 576 subs=[ 577 ('${A}', campaign.getlevel(levelname).displayname), 578 ( 579 '${B}', 580 bui.Lstr( 581 resource='playerCountAbbreviatedText', 582 subs=[('${COUNT}', str(max_players))], 583 ), 584 ), 585 ], 586 ) 587 bui.textwidget(edit=self.button_text, text=txt) 588 bui.imagewidget( 589 edit=self.image, 590 texture=bui.gettexture( 591 campaign.getlevel(levelname).preview_texture_name 592 ), 593 opacity=1.0 if enabled else 0.5, 594 ) 595 596 fee = entry['fee'] 597 598 if fee is None: 599 fee_var = None 600 elif fee == 4: 601 fee_var = 'price.tournament_entry_4' 602 elif fee == 3: 603 fee_var = 'price.tournament_entry_3' 604 elif fee == 2: 605 fee_var = 'price.tournament_entry_2' 606 elif fee == 1: 607 fee_var = 'price.tournament_entry_1' 608 else: 609 if fee != 0: 610 print('Unknown fee value:', fee) 611 fee_var = 'price.tournament_entry_0' 612 613 self.allow_ads = allow_ads = entry['allowAds'] 614 615 final_fee: int | None = ( 616 None 617 if fee_var is None 618 else plus.get_v1_account_misc_read_val(fee_var, '?') 619 ) 620 621 final_fee_str: str | bui.Lstr 622 if fee_var is None: 623 final_fee_str = '' 624 else: 625 if final_fee == 0: 626 final_fee_str = bui.Lstr(resource='getTicketsWindow.freeText') 627 else: 628 final_fee_str = bui.charstr( 629 bui.SpecialChar.TICKET_BACKING 630 ) + str(final_fee) 631 632 assert bui.app.classic is not None 633 ad_tries_remaining = bui.app.classic.accounts.tournament_info[ 634 self.tournament_id 635 ]['adTriesRemaining'] 636 free_tries_remaining = bui.app.classic.accounts.tournament_info[ 637 self.tournament_id 638 ]['freeTriesRemaining'] 639 640 # Now, if this fee allows ads and we support video ads, show 641 # the 'or ad' version. 642 if allow_ads and bui.has_video_ads(): 643 ads_enabled = bui.have_incentivized_ad() 644 bui.imagewidget( 645 edit=self.entry_fee_ad_image, 646 opacity=1.0 if ads_enabled else 0.25, 647 ) 648 or_text = ( 649 bui.Lstr(resource='orText', subs=[('${A}', ''), ('${B}', '')]) 650 .evaluate() 651 .strip() 652 ) 653 bui.textwidget(edit=self.entry_fee_text_or, text=or_text) 654 bui.textwidget( 655 edit=self.entry_fee_text_top, 656 position=( 657 self.button_x + 360, 658 self.button_y + self.button_scale_y - 60, 659 ), 660 scale=1.3, 661 text=final_fee_str, 662 ) 663 664 # Possibly show number of ad-plays remaining. 665 bui.textwidget( 666 edit=self.entry_fee_text_remaining, 667 position=( 668 self.button_x + 360, 669 self.button_y + self.button_scale_y - 146, 670 ), 671 text='' 672 if ad_tries_remaining in [None, 0] 673 else ('' + str(ad_tries_remaining)), 674 color=(0.6, 0.6, 0.6, 1 if ads_enabled else 0.2), 675 ) 676 else: 677 bui.imagewidget(edit=self.entry_fee_ad_image, opacity=0.0) 678 bui.textwidget(edit=self.entry_fee_text_or, text='') 679 bui.textwidget( 680 edit=self.entry_fee_text_top, 681 position=( 682 self.button_x + 360, 683 self.button_y + self.button_scale_y - 80, 684 ), 685 scale=1.3, 686 text=final_fee_str, 687 ) 688 689 # Possibly show number of free-plays remaining. 690 bui.textwidget( 691 edit=self.entry_fee_text_remaining, 692 position=( 693 self.button_x + 360, 694 self.button_y + self.button_scale_y - 100, 695 ), 696 text=( 697 '' 698 if (free_tries_remaining in [None, 0] or final_fee != 0) 699 else ('' + str(free_tries_remaining)) 700 ), 701 color=(0.6, 0.6, 0.6, 1), 702 )
Update for new incoming data.