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=f'{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=f'{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=f'{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 glow_type='uniform', 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=f'{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 if 'prizeRange2' in entry else 12 422 ) 423 x_offs = 90 424 425 # pylint: disable=useless-suppression 426 # pylint: disable=unbalanced-tuple-unpacking 427 ( 428 pr1, 429 pv1, 430 pr2, 431 pv2, 432 pr3, 433 pv3, 434 ) = bui.app.classic.get_tournament_prize_strings(entry) 435 # pylint: enable=unbalanced-tuple-unpacking 436 # pylint: enable=useless-suppression 437 438 enabled = 'requiredLeague' not in entry 439 bui.buttonwidget( 440 edit=self.button, 441 color=(0.5, 0.7, 0.2) if enabled else (0.5, 0.5, 0.5), 442 ) 443 bui.imagewidget(edit=self.lock_image, opacity=0.0 if enabled else 1.0) 444 bui.textwidget( 445 edit=self.prize_range_1_text, 446 text='-' if pr1 == '' else pr1, 447 position=( 448 self.button_x + 365 + x_offs, 449 self.button_y + self.button_scale_y - 93 + prize_y_offs, 450 ), 451 ) 452 453 # We want to draw values containing tickets a bit smaller 454 # (scratch that; we now draw medals a bit bigger). 455 ticket_char = bui.charstr(bui.SpecialChar.TICKET_BACKING) 456 prize_value_scale_large = 1.0 457 prize_value_scale_small = 1.0 458 459 bui.textwidget( 460 edit=self.prize_value_1_text, 461 text='-' if pv1 == '' else pv1, 462 scale=( 463 prize_value_scale_large 464 if ticket_char not in pv1 465 else prize_value_scale_small 466 ), 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=( 485 prize_value_scale_large 486 if ticket_char not in pv2 487 else prize_value_scale_small 488 ), 489 position=( 490 self.button_x + 380 + x_offs, 491 self.button_y + self.button_scale_y - 93 - 45 + prize_y_offs, 492 ), 493 ) 494 495 bui.textwidget( 496 edit=self.prize_range_3_text, 497 text=pr3, 498 position=( 499 self.button_x + 365 + x_offs, 500 self.button_y + self.button_scale_y - 93 - 90 + prize_y_offs, 501 ), 502 ) 503 bui.textwidget( 504 edit=self.prize_value_3_text, 505 text=pv3, 506 scale=( 507 prize_value_scale_large 508 if ticket_char not in pv3 509 else prize_value_scale_small 510 ), 511 position=( 512 self.button_x + 380 + x_offs, 513 self.button_y + self.button_scale_y - 93 - 90 + prize_y_offs, 514 ), 515 ) 516 517 leader_name = '-' 518 leader_score: str | bui.Lstr = '-' 519 if entry['scores']: 520 score = self.leader = copy.deepcopy(entry['scores'][0]) 521 leader_name = score[1] 522 leader_score = ( 523 bui.timestring((score[0] * 10) / 1000.0, centi=True) 524 if entry['scoreType'] == 'time' 525 else str(score[0]) 526 ) 527 else: 528 self.leader = None 529 530 bui.textwidget( 531 edit=self.current_leader_name_text, text=bui.Lstr(value=leader_name) 532 ) 533 bui.textwidget(edit=self.current_leader_score_text, text=leader_score) 534 bui.buttonwidget( 535 edit=self.more_scores_button, 536 label=bui.Lstr(resource=f'{self._r}.seeMoreText'), 537 ) 538 out_of_time_text: str | bui.Lstr = ( 539 '-' 540 if 'totalTime' not in entry 541 else bui.Lstr( 542 resource=f'{self._r}.ofTotalTimeText', 543 subs=[ 544 ( 545 '${TOTAL}', 546 bui.timestring(entry['totalTime'], centi=False), 547 ) 548 ], 549 ) 550 ) 551 bui.textwidget( 552 edit=self.time_remaining_out_of_text, text=out_of_time_text 553 ) 554 555 self.time_remaining = entry['timeRemaining'] 556 self.has_time_remaining = entry is not None 557 self.tournament_id = entry['tournamentID'] 558 self.required_league = ( 559 None if 'requiredLeague' not in entry else entry['requiredLeague'] 560 ) 561 562 assert bui.app.classic is not None 563 game = bui.app.classic.accounts.tournament_info[self.tournament_id][ 564 'game' 565 ] 566 567 if game is None: 568 bui.textwidget(edit=self.button_text, text='-') 569 bui.imagewidget( 570 edit=self.image, texture=bui.gettexture('black'), opacity=0.2 571 ) 572 else: 573 campaignname, levelname = game.split(':') 574 campaign = bui.app.classic.getcampaign(campaignname) 575 max_players = bui.app.classic.accounts.tournament_info[ 576 self.tournament_id 577 ]['maxPlayers'] 578 txt = bui.Lstr( 579 value='${A} ${B}', 580 subs=[ 581 ('${A}', campaign.getlevel(levelname).displayname), 582 ( 583 '${B}', 584 bui.Lstr( 585 resource='playerCountAbbreviatedText', 586 subs=[('${COUNT}', str(max_players))], 587 ), 588 ), 589 ], 590 ) 591 bui.textwidget(edit=self.button_text, text=txt) 592 bui.imagewidget( 593 edit=self.image, 594 texture=bui.gettexture( 595 campaign.getlevel(levelname).preview_texture_name 596 ), 597 opacity=1.0 if enabled else 0.5, 598 ) 599 600 fee = entry['fee'] 601 602 if fee is None: 603 fee_var = None 604 elif fee == 4: 605 fee_var = 'price.tournament_entry_4' 606 elif fee == 3: 607 fee_var = 'price.tournament_entry_3' 608 elif fee == 2: 609 fee_var = 'price.tournament_entry_2' 610 elif fee == 1: 611 fee_var = 'price.tournament_entry_1' 612 else: 613 if fee != 0: 614 print('Unknown fee value:', fee) 615 fee_var = 'price.tournament_entry_0' 616 617 self.allow_ads = allow_ads = entry['allowAds'] 618 619 final_fee: int | None = ( 620 None 621 if fee_var is None 622 else plus.get_v1_account_misc_read_val(fee_var, '?') 623 ) 624 625 final_fee_str: str | bui.Lstr 626 if fee_var is None: 627 final_fee_str = '' 628 else: 629 if final_fee == 0: 630 final_fee_str = bui.Lstr(resource='getTicketsWindow.freeText') 631 else: 632 final_fee_str = bui.charstr( 633 bui.SpecialChar.TICKET_BACKING 634 ) + str(final_fee) 635 636 assert bui.app.classic is not None 637 ad_tries_remaining = bui.app.classic.accounts.tournament_info[ 638 self.tournament_id 639 ]['adTriesRemaining'] 640 free_tries_remaining = bui.app.classic.accounts.tournament_info[ 641 self.tournament_id 642 ]['freeTriesRemaining'] 643 644 # Now, if this fee allows ads and we support video ads, show 645 # the 'or ad' version. 646 if allow_ads and plus.has_video_ads(): 647 ads_enabled = plus.have_incentivized_ad() 648 bui.imagewidget( 649 edit=self.entry_fee_ad_image, 650 opacity=1.0 if ads_enabled else 0.25, 651 ) 652 or_text = ( 653 bui.Lstr(resource='orText', subs=[('${A}', ''), ('${B}', '')]) 654 .evaluate() 655 .strip() 656 ) 657 bui.textwidget(edit=self.entry_fee_text_or, text=or_text) 658 bui.textwidget( 659 edit=self.entry_fee_text_top, 660 position=( 661 self.button_x + 360, 662 self.button_y + self.button_scale_y - 60, 663 ), 664 scale=1.3, 665 text=final_fee_str, 666 ) 667 668 # Possibly show number of ad-plays remaining. 669 bui.textwidget( 670 edit=self.entry_fee_text_remaining, 671 position=( 672 self.button_x + 360, 673 self.button_y + self.button_scale_y - 146, 674 ), 675 text=( 676 '' 677 if ad_tries_remaining in [None, 0] 678 else ('' + str(ad_tries_remaining)) 679 ), 680 color=(0.6, 0.6, 0.6, 1 if ads_enabled else 0.2), 681 ) 682 else: 683 bui.imagewidget(edit=self.entry_fee_ad_image, opacity=0.0) 684 bui.textwidget(edit=self.entry_fee_text_or, text='') 685 bui.textwidget( 686 edit=self.entry_fee_text_top, 687 position=( 688 self.button_x + 360, 689 self.button_y + self.button_scale_y - 80, 690 ), 691 scale=1.3, 692 text=final_fee_str, 693 ) 694 695 # Possibly show number of free-plays remaining. 696 bui.textwidget( 697 edit=self.entry_fee_text_remaining, 698 position=( 699 self.button_x + 360, 700 self.button_y + self.button_scale_y - 100, 701 ), 702 text=( 703 '' 704 if (free_tries_remaining in [None, 0] or final_fee != 0) 705 else ('' + str(free_tries_remaining)) 706 ), 707 color=(0.6, 0.6, 0.6, 1), 708 )
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=f'{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=f'{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=f'{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 glow_type='uniform', 295 scale=1.4, 296 color=value_color, 297 flatness=1.0, 298 ) 299 self.current_leader_score_text = bui.textwidget( 300 parent=parent, 301 draw_controller=btn, 302 position=(x + 620 + x_offs, y + scly - 113 + 10), 303 size=(0, 0), 304 h_align='center', 305 text='-', 306 v_align='center', 307 maxwidth=170, 308 scale=1.8, 309 color=value_color, 310 flatness=1.0, 311 ) 312 313 self.more_scores_button = bui.buttonwidget( 314 parent=parent, 315 position=(x + 620 + x_offs - 60, y + scly - 50 - 125), 316 color=(0.5, 0.5, 0.6), 317 textcolor=(0.7, 0.7, 0.8), 318 label='-', 319 size=(120, 40), 320 autoselect=True, 321 up_widget=self.current_leader_name_text, 322 text_scale=0.6, 323 on_activate_call=bui.WeakCall(self._show_scores), 324 ) 325 bui.widget( 326 edit=self.current_leader_name_text, 327 down_widget=self.more_scores_button, 328 ) 329 330 bui.textwidget( 331 parent=parent, 332 draw_controller=btn, 333 position=(x + 820 + x_offs, y + scly - 20), 334 size=(0, 0), 335 h_align='center', 336 text=bui.Lstr(resource=f'{self._r}.timeRemainingText'), 337 v_align='center', 338 maxwidth=180, 339 scale=0.9, 340 color=header_color, 341 flatness=1.0, 342 ) 343 self.time_remaining_value_text = bui.textwidget( 344 parent=parent, 345 draw_controller=btn, 346 position=(x + 820 + x_offs, y + scly - 68), 347 size=(0, 0), 348 h_align='center', 349 text='-', 350 v_align='center', 351 maxwidth=180, 352 scale=2.0, 353 color=value_color, 354 flatness=1.0, 355 ) 356 self.time_remaining_out_of_text = bui.textwidget( 357 parent=parent, 358 draw_controller=btn, 359 position=(x + 820 + x_offs, y + scly - 110), 360 size=(0, 0), 361 h_align='center', 362 text='-', 363 v_align='center', 364 maxwidth=120, 365 scale=0.72, 366 color=(0.4, 0.4, 0.5), 367 flatness=1.0, 368 ) 369 370 def _pressed(self) -> None: 371 self.on_pressed(self) 372 373 def _show_leader(self) -> None: 374 # pylint: disable=cyclic-import 375 from bauiv1lib.account.viewer import AccountViewerWindow 376 377 tournament_id = self.tournament_id 378 379 # FIXME: This assumes a single player entry in leader; should expand 380 # this to work with multiple. 381 if ( 382 tournament_id is None 383 or self.leader is None 384 or len(self.leader[2]) != 1 385 ): 386 bui.getsound('error').play() 387 return 388 bui.getsound('swish').play() 389 AccountViewerWindow( 390 account_id=self.leader[2][0].get('a', None), 391 profile_id=self.leader[2][0].get('p', None), 392 position=self.current_leader_name_text.get_screen_space_center(), 393 ) 394 395 def _show_scores(self) -> None: 396 # pylint: disable=cyclic-import 397 from bauiv1lib.tournamentscores import TournamentScoresWindow 398 399 tournament_id = self.tournament_id 400 if tournament_id is None: 401 bui.getsound('error').play() 402 return 403 404 TournamentScoresWindow( 405 tournament_id=tournament_id, 406 position=self.more_scores_button.get_screen_space_center(), 407 ) 408 409 def update_for_data(self, entry: dict[str, Any]) -> None: 410 """Update for new incoming data.""" 411 # pylint: disable=too-many-statements 412 # pylint: disable=too-many-locals 413 # pylint: disable=too-many-branches 414 415 plus = bui.app.plus 416 assert plus is not None 417 418 assert bui.app.classic is not None 419 prize_y_offs = ( 420 34 421 if 'prizeRange3' in entry 422 else 20 if 'prizeRange2' in entry 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=( 464 prize_value_scale_large 465 if ticket_char not in pv1 466 else prize_value_scale_small 467 ), 468 position=( 469 self.button_x + 380 + x_offs, 470 self.button_y + self.button_scale_y - 93 + prize_y_offs, 471 ), 472 ) 473 474 bui.textwidget( 475 edit=self.prize_range_2_text, 476 text=pr2, 477 position=( 478 self.button_x + 365 + x_offs, 479 self.button_y + self.button_scale_y - 93 - 45 + prize_y_offs, 480 ), 481 ) 482 bui.textwidget( 483 edit=self.prize_value_2_text, 484 text=pv2, 485 scale=( 486 prize_value_scale_large 487 if ticket_char not in pv2 488 else prize_value_scale_small 489 ), 490 position=( 491 self.button_x + 380 + x_offs, 492 self.button_y + self.button_scale_y - 93 - 45 + prize_y_offs, 493 ), 494 ) 495 496 bui.textwidget( 497 edit=self.prize_range_3_text, 498 text=pr3, 499 position=( 500 self.button_x + 365 + x_offs, 501 self.button_y + self.button_scale_y - 93 - 90 + prize_y_offs, 502 ), 503 ) 504 bui.textwidget( 505 edit=self.prize_value_3_text, 506 text=pv3, 507 scale=( 508 prize_value_scale_large 509 if ticket_char not in pv3 510 else prize_value_scale_small 511 ), 512 position=( 513 self.button_x + 380 + x_offs, 514 self.button_y + self.button_scale_y - 93 - 90 + prize_y_offs, 515 ), 516 ) 517 518 leader_name = '-' 519 leader_score: str | bui.Lstr = '-' 520 if entry['scores']: 521 score = self.leader = copy.deepcopy(entry['scores'][0]) 522 leader_name = score[1] 523 leader_score = ( 524 bui.timestring((score[0] * 10) / 1000.0, centi=True) 525 if entry['scoreType'] == 'time' 526 else str(score[0]) 527 ) 528 else: 529 self.leader = None 530 531 bui.textwidget( 532 edit=self.current_leader_name_text, text=bui.Lstr(value=leader_name) 533 ) 534 bui.textwidget(edit=self.current_leader_score_text, text=leader_score) 535 bui.buttonwidget( 536 edit=self.more_scores_button, 537 label=bui.Lstr(resource=f'{self._r}.seeMoreText'), 538 ) 539 out_of_time_text: str | bui.Lstr = ( 540 '-' 541 if 'totalTime' not in entry 542 else bui.Lstr( 543 resource=f'{self._r}.ofTotalTimeText', 544 subs=[ 545 ( 546 '${TOTAL}', 547 bui.timestring(entry['totalTime'], centi=False), 548 ) 549 ], 550 ) 551 ) 552 bui.textwidget( 553 edit=self.time_remaining_out_of_text, text=out_of_time_text 554 ) 555 556 self.time_remaining = entry['timeRemaining'] 557 self.has_time_remaining = entry is not None 558 self.tournament_id = entry['tournamentID'] 559 self.required_league = ( 560 None if 'requiredLeague' not in entry else entry['requiredLeague'] 561 ) 562 563 assert bui.app.classic is not None 564 game = bui.app.classic.accounts.tournament_info[self.tournament_id][ 565 'game' 566 ] 567 568 if game is None: 569 bui.textwidget(edit=self.button_text, text='-') 570 bui.imagewidget( 571 edit=self.image, texture=bui.gettexture('black'), opacity=0.2 572 ) 573 else: 574 campaignname, levelname = game.split(':') 575 campaign = bui.app.classic.getcampaign(campaignname) 576 max_players = bui.app.classic.accounts.tournament_info[ 577 self.tournament_id 578 ]['maxPlayers'] 579 txt = bui.Lstr( 580 value='${A} ${B}', 581 subs=[ 582 ('${A}', campaign.getlevel(levelname).displayname), 583 ( 584 '${B}', 585 bui.Lstr( 586 resource='playerCountAbbreviatedText', 587 subs=[('${COUNT}', str(max_players))], 588 ), 589 ), 590 ], 591 ) 592 bui.textwidget(edit=self.button_text, text=txt) 593 bui.imagewidget( 594 edit=self.image, 595 texture=bui.gettexture( 596 campaign.getlevel(levelname).preview_texture_name 597 ), 598 opacity=1.0 if enabled else 0.5, 599 ) 600 601 fee = entry['fee'] 602 603 if fee is None: 604 fee_var = None 605 elif fee == 4: 606 fee_var = 'price.tournament_entry_4' 607 elif fee == 3: 608 fee_var = 'price.tournament_entry_3' 609 elif fee == 2: 610 fee_var = 'price.tournament_entry_2' 611 elif fee == 1: 612 fee_var = 'price.tournament_entry_1' 613 else: 614 if fee != 0: 615 print('Unknown fee value:', fee) 616 fee_var = 'price.tournament_entry_0' 617 618 self.allow_ads = allow_ads = entry['allowAds'] 619 620 final_fee: int | None = ( 621 None 622 if fee_var is None 623 else plus.get_v1_account_misc_read_val(fee_var, '?') 624 ) 625 626 final_fee_str: str | bui.Lstr 627 if fee_var is None: 628 final_fee_str = '' 629 else: 630 if final_fee == 0: 631 final_fee_str = bui.Lstr(resource='getTicketsWindow.freeText') 632 else: 633 final_fee_str = bui.charstr( 634 bui.SpecialChar.TICKET_BACKING 635 ) + str(final_fee) 636 637 assert bui.app.classic is not None 638 ad_tries_remaining = bui.app.classic.accounts.tournament_info[ 639 self.tournament_id 640 ]['adTriesRemaining'] 641 free_tries_remaining = bui.app.classic.accounts.tournament_info[ 642 self.tournament_id 643 ]['freeTriesRemaining'] 644 645 # Now, if this fee allows ads and we support video ads, show 646 # the 'or ad' version. 647 if allow_ads and plus.has_video_ads(): 648 ads_enabled = plus.have_incentivized_ad() 649 bui.imagewidget( 650 edit=self.entry_fee_ad_image, 651 opacity=1.0 if ads_enabled else 0.25, 652 ) 653 or_text = ( 654 bui.Lstr(resource='orText', subs=[('${A}', ''), ('${B}', '')]) 655 .evaluate() 656 .strip() 657 ) 658 bui.textwidget(edit=self.entry_fee_text_or, text=or_text) 659 bui.textwidget( 660 edit=self.entry_fee_text_top, 661 position=( 662 self.button_x + 360, 663 self.button_y + self.button_scale_y - 60, 664 ), 665 scale=1.3, 666 text=final_fee_str, 667 ) 668 669 # Possibly show number of ad-plays remaining. 670 bui.textwidget( 671 edit=self.entry_fee_text_remaining, 672 position=( 673 self.button_x + 360, 674 self.button_y + self.button_scale_y - 146, 675 ), 676 text=( 677 '' 678 if ad_tries_remaining in [None, 0] 679 else ('' + str(ad_tries_remaining)) 680 ), 681 color=(0.6, 0.6, 0.6, 1 if ads_enabled else 0.2), 682 ) 683 else: 684 bui.imagewidget(edit=self.entry_fee_ad_image, opacity=0.0) 685 bui.textwidget(edit=self.entry_fee_text_or, text='') 686 bui.textwidget( 687 edit=self.entry_fee_text_top, 688 position=( 689 self.button_x + 360, 690 self.button_y + self.button_scale_y - 80, 691 ), 692 scale=1.3, 693 text=final_fee_str, 694 ) 695 696 # Possibly show number of free-plays remaining. 697 bui.textwidget( 698 edit=self.entry_fee_text_remaining, 699 position=( 700 self.button_x + 360, 701 self.button_y + self.button_scale_y - 100, 702 ), 703 text=( 704 '' 705 if (free_tries_remaining in [None, 0] or final_fee != 0) 706 else ('' + str(free_tries_remaining)) 707 ), 708 color=(0.6, 0.6, 0.6, 1), 709 )
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=f'{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=f'{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=f'{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 glow_type='uniform', 295 scale=1.4, 296 color=value_color, 297 flatness=1.0, 298 ) 299 self.current_leader_score_text = bui.textwidget( 300 parent=parent, 301 draw_controller=btn, 302 position=(x + 620 + x_offs, y + scly - 113 + 10), 303 size=(0, 0), 304 h_align='center', 305 text='-', 306 v_align='center', 307 maxwidth=170, 308 scale=1.8, 309 color=value_color, 310 flatness=1.0, 311 ) 312 313 self.more_scores_button = bui.buttonwidget( 314 parent=parent, 315 position=(x + 620 + x_offs - 60, y + scly - 50 - 125), 316 color=(0.5, 0.5, 0.6), 317 textcolor=(0.7, 0.7, 0.8), 318 label='-', 319 size=(120, 40), 320 autoselect=True, 321 up_widget=self.current_leader_name_text, 322 text_scale=0.6, 323 on_activate_call=bui.WeakCall(self._show_scores), 324 ) 325 bui.widget( 326 edit=self.current_leader_name_text, 327 down_widget=self.more_scores_button, 328 ) 329 330 bui.textwidget( 331 parent=parent, 332 draw_controller=btn, 333 position=(x + 820 + x_offs, y + scly - 20), 334 size=(0, 0), 335 h_align='center', 336 text=bui.Lstr(resource=f'{self._r}.timeRemainingText'), 337 v_align='center', 338 maxwidth=180, 339 scale=0.9, 340 color=header_color, 341 flatness=1.0, 342 ) 343 self.time_remaining_value_text = bui.textwidget( 344 parent=parent, 345 draw_controller=btn, 346 position=(x + 820 + x_offs, y + scly - 68), 347 size=(0, 0), 348 h_align='center', 349 text='-', 350 v_align='center', 351 maxwidth=180, 352 scale=2.0, 353 color=value_color, 354 flatness=1.0, 355 ) 356 self.time_remaining_out_of_text = bui.textwidget( 357 parent=parent, 358 draw_controller=btn, 359 position=(x + 820 + x_offs, y + scly - 110), 360 size=(0, 0), 361 h_align='center', 362 text='-', 363 v_align='center', 364 maxwidth=120, 365 scale=0.72, 366 color=(0.4, 0.4, 0.5), 367 flatness=1.0, 368 )
def
update_for_data(self, entry: dict[str, typing.Any]) -> None:
409 def update_for_data(self, entry: dict[str, Any]) -> None: 410 """Update for new incoming data.""" 411 # pylint: disable=too-many-statements 412 # pylint: disable=too-many-locals 413 # pylint: disable=too-many-branches 414 415 plus = bui.app.plus 416 assert plus is not None 417 418 assert bui.app.classic is not None 419 prize_y_offs = ( 420 34 421 if 'prizeRange3' in entry 422 else 20 if 'prizeRange2' in entry 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=( 464 prize_value_scale_large 465 if ticket_char not in pv1 466 else prize_value_scale_small 467 ), 468 position=( 469 self.button_x + 380 + x_offs, 470 self.button_y + self.button_scale_y - 93 + prize_y_offs, 471 ), 472 ) 473 474 bui.textwidget( 475 edit=self.prize_range_2_text, 476 text=pr2, 477 position=( 478 self.button_x + 365 + x_offs, 479 self.button_y + self.button_scale_y - 93 - 45 + prize_y_offs, 480 ), 481 ) 482 bui.textwidget( 483 edit=self.prize_value_2_text, 484 text=pv2, 485 scale=( 486 prize_value_scale_large 487 if ticket_char not in pv2 488 else prize_value_scale_small 489 ), 490 position=( 491 self.button_x + 380 + x_offs, 492 self.button_y + self.button_scale_y - 93 - 45 + prize_y_offs, 493 ), 494 ) 495 496 bui.textwidget( 497 edit=self.prize_range_3_text, 498 text=pr3, 499 position=( 500 self.button_x + 365 + x_offs, 501 self.button_y + self.button_scale_y - 93 - 90 + prize_y_offs, 502 ), 503 ) 504 bui.textwidget( 505 edit=self.prize_value_3_text, 506 text=pv3, 507 scale=( 508 prize_value_scale_large 509 if ticket_char not in pv3 510 else prize_value_scale_small 511 ), 512 position=( 513 self.button_x + 380 + x_offs, 514 self.button_y + self.button_scale_y - 93 - 90 + prize_y_offs, 515 ), 516 ) 517 518 leader_name = '-' 519 leader_score: str | bui.Lstr = '-' 520 if entry['scores']: 521 score = self.leader = copy.deepcopy(entry['scores'][0]) 522 leader_name = score[1] 523 leader_score = ( 524 bui.timestring((score[0] * 10) / 1000.0, centi=True) 525 if entry['scoreType'] == 'time' 526 else str(score[0]) 527 ) 528 else: 529 self.leader = None 530 531 bui.textwidget( 532 edit=self.current_leader_name_text, text=bui.Lstr(value=leader_name) 533 ) 534 bui.textwidget(edit=self.current_leader_score_text, text=leader_score) 535 bui.buttonwidget( 536 edit=self.more_scores_button, 537 label=bui.Lstr(resource=f'{self._r}.seeMoreText'), 538 ) 539 out_of_time_text: str | bui.Lstr = ( 540 '-' 541 if 'totalTime' not in entry 542 else bui.Lstr( 543 resource=f'{self._r}.ofTotalTimeText', 544 subs=[ 545 ( 546 '${TOTAL}', 547 bui.timestring(entry['totalTime'], centi=False), 548 ) 549 ], 550 ) 551 ) 552 bui.textwidget( 553 edit=self.time_remaining_out_of_text, text=out_of_time_text 554 ) 555 556 self.time_remaining = entry['timeRemaining'] 557 self.has_time_remaining = entry is not None 558 self.tournament_id = entry['tournamentID'] 559 self.required_league = ( 560 None if 'requiredLeague' not in entry else entry['requiredLeague'] 561 ) 562 563 assert bui.app.classic is not None 564 game = bui.app.classic.accounts.tournament_info[self.tournament_id][ 565 'game' 566 ] 567 568 if game is None: 569 bui.textwidget(edit=self.button_text, text='-') 570 bui.imagewidget( 571 edit=self.image, texture=bui.gettexture('black'), opacity=0.2 572 ) 573 else: 574 campaignname, levelname = game.split(':') 575 campaign = bui.app.classic.getcampaign(campaignname) 576 max_players = bui.app.classic.accounts.tournament_info[ 577 self.tournament_id 578 ]['maxPlayers'] 579 txt = bui.Lstr( 580 value='${A} ${B}', 581 subs=[ 582 ('${A}', campaign.getlevel(levelname).displayname), 583 ( 584 '${B}', 585 bui.Lstr( 586 resource='playerCountAbbreviatedText', 587 subs=[('${COUNT}', str(max_players))], 588 ), 589 ), 590 ], 591 ) 592 bui.textwidget(edit=self.button_text, text=txt) 593 bui.imagewidget( 594 edit=self.image, 595 texture=bui.gettexture( 596 campaign.getlevel(levelname).preview_texture_name 597 ), 598 opacity=1.0 if enabled else 0.5, 599 ) 600 601 fee = entry['fee'] 602 603 if fee is None: 604 fee_var = None 605 elif fee == 4: 606 fee_var = 'price.tournament_entry_4' 607 elif fee == 3: 608 fee_var = 'price.tournament_entry_3' 609 elif fee == 2: 610 fee_var = 'price.tournament_entry_2' 611 elif fee == 1: 612 fee_var = 'price.tournament_entry_1' 613 else: 614 if fee != 0: 615 print('Unknown fee value:', fee) 616 fee_var = 'price.tournament_entry_0' 617 618 self.allow_ads = allow_ads = entry['allowAds'] 619 620 final_fee: int | None = ( 621 None 622 if fee_var is None 623 else plus.get_v1_account_misc_read_val(fee_var, '?') 624 ) 625 626 final_fee_str: str | bui.Lstr 627 if fee_var is None: 628 final_fee_str = '' 629 else: 630 if final_fee == 0: 631 final_fee_str = bui.Lstr(resource='getTicketsWindow.freeText') 632 else: 633 final_fee_str = bui.charstr( 634 bui.SpecialChar.TICKET_BACKING 635 ) + str(final_fee) 636 637 assert bui.app.classic is not None 638 ad_tries_remaining = bui.app.classic.accounts.tournament_info[ 639 self.tournament_id 640 ]['adTriesRemaining'] 641 free_tries_remaining = bui.app.classic.accounts.tournament_info[ 642 self.tournament_id 643 ]['freeTriesRemaining'] 644 645 # Now, if this fee allows ads and we support video ads, show 646 # the 'or ad' version. 647 if allow_ads and plus.has_video_ads(): 648 ads_enabled = plus.have_incentivized_ad() 649 bui.imagewidget( 650 edit=self.entry_fee_ad_image, 651 opacity=1.0 if ads_enabled else 0.25, 652 ) 653 or_text = ( 654 bui.Lstr(resource='orText', subs=[('${A}', ''), ('${B}', '')]) 655 .evaluate() 656 .strip() 657 ) 658 bui.textwidget(edit=self.entry_fee_text_or, text=or_text) 659 bui.textwidget( 660 edit=self.entry_fee_text_top, 661 position=( 662 self.button_x + 360, 663 self.button_y + self.button_scale_y - 60, 664 ), 665 scale=1.3, 666 text=final_fee_str, 667 ) 668 669 # Possibly show number of ad-plays remaining. 670 bui.textwidget( 671 edit=self.entry_fee_text_remaining, 672 position=( 673 self.button_x + 360, 674 self.button_y + self.button_scale_y - 146, 675 ), 676 text=( 677 '' 678 if ad_tries_remaining in [None, 0] 679 else ('' + str(ad_tries_remaining)) 680 ), 681 color=(0.6, 0.6, 0.6, 1 if ads_enabled else 0.2), 682 ) 683 else: 684 bui.imagewidget(edit=self.entry_fee_ad_image, opacity=0.0) 685 bui.textwidget(edit=self.entry_fee_text_or, text='') 686 bui.textwidget( 687 edit=self.entry_fee_text_top, 688 position=( 689 self.button_x + 360, 690 self.button_y + self.button_scale_y - 80, 691 ), 692 scale=1.3, 693 text=final_fee_str, 694 ) 695 696 # Possibly show number of free-plays remaining. 697 bui.textwidget( 698 edit=self.entry_fee_text_remaining, 699 position=( 700 self.button_x + 360, 701 self.button_y + self.button_scale_y - 100, 702 ), 703 text=( 704 '' 705 if (free_tries_remaining in [None, 0] or final_fee != 0) 706 else ('' + str(free_tries_remaining)) 707 ), 708 color=(0.6, 0.6, 0.6, 1), 709 )
Update for new incoming data.