bauiv1lib.play
Provides the top level play window.
1# Released under the MIT License. See LICENSE for details. 2# 3"""Provides the top level play window.""" 4 5from __future__ import annotations 6 7import logging 8from typing import override 9 10import bascenev1 as bs 11import bauiv1 as bui 12 13 14class PlayWindow(bui.MainWindow): 15 """Window for selecting overall play type.""" 16 17 def __init__( 18 self, 19 transition: str | None = 'in_right', 20 origin_widget: bui.Widget | None = None, 21 ): 22 # pylint: disable=too-many-statements 23 # pylint: disable=too-many-locals 24 25 # Preload some modules we use in a background thread so we won't 26 # have a visual hitch when the user taps them. 27 bui.app.threadpool_submit_no_wait(self._preload_modules) 28 29 classic = bui.app.classic 30 assert classic is not None 31 32 # We can currently be used either for main window duty or 33 # modally for selecting playlists. Ideally we should clean 34 # things up and make playlist selection go through the 35 # main-window mechanism. 36 self._is_main_menu = not classic.selecting_private_party_playlist 37 38 uiscale = bui.app.ui_v1.uiscale 39 width = 1100 if uiscale is bui.UIScale.SMALL else 800 40 x_offs = 150 if uiscale is bui.UIScale.SMALL else 0 41 height = 550 42 button_width = 400 43 44 if origin_widget is not None: 45 46 # Need to store this ourself since we can function as a 47 # non-main window. 48 self._transition_out = 'out_scale' 49 else: 50 self._transition_out = 'out_right' 51 52 self._r = 'playWindow' 53 54 super().__init__( 55 root_widget=bui.containerwidget( 56 size=(width, height), 57 toolbar_visibility='menu_full', 58 scale=( 59 1.35 60 if uiscale is bui.UIScale.SMALL 61 else 0.9 if uiscale is bui.UIScale.MEDIUM else 0.8 62 ), 63 stack_offset=( 64 (0, 20) if uiscale is bui.UIScale.SMALL else (0, 0) 65 ), 66 ), 67 transition=transition, 68 origin_widget=origin_widget, 69 ) 70 self._back_button = back_button = btn = bui.buttonwidget( 71 parent=self._root_widget, 72 position=(55 + x_offs, height - 132), 73 size=(120, 60), 74 scale=1.1, 75 text_res_scale=1.5, 76 text_scale=1.2, 77 autoselect=True, 78 label=bui.Lstr(resource='backText'), 79 button_type='back', 80 ) 81 82 txt = bui.textwidget( 83 parent=self._root_widget, 84 position=(width * 0.5, height - 101), 85 # position=(width * 0.5, height - 86 # (101 if main_menu else 61)), 87 size=(0, 0), 88 text=bui.Lstr( 89 resource=( 90 (f'{self._r}.titleText') 91 if self._is_main_menu 92 else 'playlistsText' 93 ) 94 ), 95 scale=1.7, 96 res_scale=2.0, 97 maxwidth=400, 98 color=bui.app.ui_v1.heading_color, 99 h_align='center', 100 v_align='center', 101 ) 102 103 bui.buttonwidget( 104 edit=btn, 105 button_type='backSmall', 106 size=(60, 60), 107 label=bui.charstr(bui.SpecialChar.BACK), 108 ) 109 if uiscale is bui.UIScale.SMALL: 110 bui.textwidget(edit=txt, text='') 111 112 v = height - (110 if self._is_main_menu else 90) 113 v -= 100 114 clr = (0.6, 0.7, 0.6, 1.0) 115 v -= 280 if self._is_main_menu else 180 116 v += 30 if uiscale is bui.UIScale.SMALL else 0 117 hoffs = x_offs + 80 if self._is_main_menu else x_offs - 100 118 scl = 1.13 if self._is_main_menu else 0.68 119 120 self._lineup_tex = bui.gettexture('playerLineup') 121 angry_computer_transparent_mesh = bui.getmesh( 122 'angryComputerTransparent' 123 ) 124 self._lineup_1_transparent_mesh = bui.getmesh( 125 'playerLineup1Transparent' 126 ) 127 self._lineup_2_transparent_mesh = bui.getmesh( 128 'playerLineup2Transparent' 129 ) 130 self._lineup_3_transparent_mesh = bui.getmesh( 131 'playerLineup3Transparent' 132 ) 133 self._lineup_4_transparent_mesh = bui.getmesh( 134 'playerLineup4Transparent' 135 ) 136 self._eyes_mesh = bui.getmesh('plasticEyesTransparent') 137 138 self._coop_button: bui.Widget | None = None 139 140 # Only show coop button in main-menu variant. 141 if self._is_main_menu: 142 self._coop_button = btn = bui.buttonwidget( 143 parent=self._root_widget, 144 position=(hoffs, v + (scl * 15)), 145 size=( 146 scl * button_width, 147 scl * 300, 148 ), 149 extra_touch_border_scale=0.1, 150 autoselect=True, 151 label='', 152 button_type='square', 153 text_scale=1.13, 154 on_activate_call=self._coop, 155 ) 156 157 if uiscale is bui.UIScale.SMALL: 158 bui.widget( 159 edit=btn, 160 left_widget=bui.get_special_widget('back_button'), 161 ) 162 bui.widget( 163 edit=btn, 164 up_widget=bui.get_special_widget('account_button'), 165 ) 166 bui.widget( 167 edit=btn, 168 down_widget=bui.get_special_widget('settings_button'), 169 ) 170 171 self._draw_dude( 172 0, 173 btn, 174 hoffs, 175 v, 176 scl, 177 position=(140, 30), 178 color=(0.72, 0.4, 1.0), 179 ) 180 self._draw_dude( 181 1, 182 btn, 183 hoffs, 184 v, 185 scl, 186 position=(185, 53), 187 color=(0.71, 0.5, 1.0), 188 ) 189 self._draw_dude( 190 2, 191 btn, 192 hoffs, 193 v, 194 scl, 195 position=(220, 27), 196 color=(0.67, 0.44, 1.0), 197 ) 198 self._draw_dude( 199 3, btn, hoffs, v, scl, position=(255, 57), color=(0.7, 0.3, 1.0) 200 ) 201 bui.imagewidget( 202 parent=self._root_widget, 203 draw_controller=btn, 204 position=(hoffs + scl * 230, v + scl * 153), 205 size=(scl * 115, scl * 115), 206 texture=self._lineup_tex, 207 mesh_transparent=angry_computer_transparent_mesh, 208 ) 209 210 bui.textwidget( 211 parent=self._root_widget, 212 draw_controller=btn, 213 position=(hoffs + scl * (-10), v + scl * 95), 214 size=(scl * button_width, scl * 50), 215 text=bui.Lstr( 216 resource='playModes.singlePlayerCoopText', 217 fallback_resource='playModes.coopText', 218 ), 219 maxwidth=scl * button_width * 0.7, 220 res_scale=1.5, 221 h_align='center', 222 v_align='center', 223 color=(0.7, 0.9, 0.7, 1.0), 224 scale=scl * 2.3, 225 ) 226 227 bui.textwidget( 228 parent=self._root_widget, 229 draw_controller=btn, 230 position=(hoffs + scl * (-10), v + (scl * 54)), 231 size=(scl * button_width, scl * 30), 232 text=bui.Lstr(resource=f'{self._r}.oneToFourPlayersText'), 233 h_align='center', 234 v_align='center', 235 scale=0.83 * scl, 236 flatness=1.0, 237 maxwidth=scl * button_width * 0.7, 238 color=clr, 239 ) 240 241 scl = 0.5 if self._is_main_menu else 0.68 242 hoffs += 440 if self._is_main_menu else 216 243 v += 180 if self._is_main_menu else -68 244 245 self._teams_button = btn = bui.buttonwidget( 246 parent=self._root_widget, 247 position=(hoffs, v + (scl * 15 if self._is_main_menu else 0)), 248 size=( 249 scl * button_width, 250 scl * (300 if self._is_main_menu else 360), 251 ), 252 extra_touch_border_scale=0.1, 253 autoselect=True, 254 label='', 255 button_type='square', 256 text_scale=1.13, 257 on_activate_call=self._team_tourney, 258 ) 259 260 bui.widget( 261 edit=btn, 262 up_widget=bui.get_special_widget('get_tokens_button'), 263 right_widget=bui.get_special_widget('squad_button'), 264 ) 265 266 xxx = -14 267 self._draw_dude( 268 2, 269 btn, 270 hoffs, 271 v, 272 scl, 273 position=(xxx + 148, 30), 274 color=(0.2, 0.4, 1.0), 275 ) 276 self._draw_dude( 277 3, 278 btn, 279 hoffs, 280 v, 281 scl, 282 position=(xxx + 181, 53), 283 color=(0.3, 0.4, 1.0), 284 ) 285 self._draw_dude( 286 1, 287 btn, 288 hoffs, 289 v, 290 scl, 291 position=(xxx + 216, 33), 292 color=(0.3, 0.5, 1.0), 293 ) 294 self._draw_dude( 295 0, 296 btn, 297 hoffs, 298 v, 299 scl, 300 position=(xxx + 245, 57), 301 color=(0.3, 0.5, 1.0), 302 ) 303 304 xxx = 155 305 self._draw_dude( 306 0, 307 btn, 308 hoffs, 309 v, 310 scl, 311 position=(xxx + 151, 30), 312 color=(1.0, 0.5, 0.4), 313 ) 314 self._draw_dude( 315 1, 316 btn, 317 hoffs, 318 v, 319 scl, 320 position=(xxx + 189, 53), 321 color=(1.0, 0.58, 0.58), 322 ) 323 self._draw_dude( 324 3, 325 btn, 326 hoffs, 327 v, 328 scl, 329 position=(xxx + 223, 27), 330 color=(1.0, 0.5, 0.5), 331 ) 332 self._draw_dude( 333 2, 334 btn, 335 hoffs, 336 v, 337 scl, 338 position=(xxx + 257, 57), 339 color=(1.0, 0.5, 0.5), 340 ) 341 342 bui.textwidget( 343 parent=self._root_widget, 344 draw_controller=btn, 345 position=(hoffs + scl * (-10), v + scl * 95), 346 size=(scl * button_width, scl * 50), 347 text=bui.Lstr( 348 resource='playModes.teamsText', fallback_resource='teamsText' 349 ), 350 res_scale=1.5, 351 maxwidth=scl * button_width * 0.7, 352 h_align='center', 353 v_align='center', 354 color=(0.7, 0.9, 0.7, 1.0), 355 scale=scl * 2.3, 356 ) 357 bui.textwidget( 358 parent=self._root_widget, 359 draw_controller=btn, 360 position=(hoffs + scl * (-10), v + (scl * 54)), 361 size=(scl * button_width, scl * 30), 362 text=bui.Lstr(resource=f'{self._r}.twoToEightPlayersText'), 363 h_align='center', 364 v_align='center', 365 res_scale=1.5, 366 scale=0.9 * scl, 367 flatness=1.0, 368 maxwidth=scl * button_width * 0.7, 369 color=clr, 370 ) 371 372 hoffs += 0 if self._is_main_menu else 300 373 v -= 155 if self._is_main_menu else 0 374 self._free_for_all_button = btn = bui.buttonwidget( 375 parent=self._root_widget, 376 position=(hoffs, v + (scl * 15 if self._is_main_menu else 0)), 377 size=( 378 scl * button_width, 379 scl * (300 if self._is_main_menu else 360), 380 ), 381 extra_touch_border_scale=0.1, 382 autoselect=True, 383 label='', 384 button_type='square', 385 text_scale=1.13, 386 on_activate_call=self._free_for_all, 387 ) 388 389 xxx = -5 390 self._draw_dude( 391 0, 392 btn, 393 hoffs, 394 v, 395 scl, 396 position=(xxx + 140, 30), 397 color=(0.4, 1.0, 0.4), 398 ) 399 self._draw_dude( 400 3, 401 btn, 402 hoffs, 403 v, 404 scl, 405 position=(xxx + 185, 53), 406 color=(1.0, 0.4, 0.5), 407 ) 408 self._draw_dude( 409 1, 410 btn, 411 hoffs, 412 v, 413 scl, 414 position=(xxx + 220, 27), 415 color=(0.4, 0.5, 1.0), 416 ) 417 self._draw_dude( 418 2, 419 btn, 420 hoffs, 421 v, 422 scl, 423 position=(xxx + 255, 57), 424 color=(0.5, 1.0, 0.4), 425 ) 426 xxx = 140 427 self._draw_dude( 428 2, 429 btn, 430 hoffs, 431 v, 432 scl, 433 position=(xxx + 148, 30), 434 color=(1.0, 0.9, 0.4), 435 ) 436 self._draw_dude( 437 0, 438 btn, 439 hoffs, 440 v, 441 scl, 442 position=(xxx + 182, 53), 443 color=(0.7, 1.0, 0.5), 444 ) 445 self._draw_dude( 446 3, 447 btn, 448 hoffs, 449 v, 450 scl, 451 position=(xxx + 233, 27), 452 color=(0.7, 0.5, 0.9), 453 ) 454 self._draw_dude( 455 1, 456 btn, 457 hoffs, 458 v, 459 scl, 460 position=(xxx + 266, 53), 461 color=(0.4, 0.5, 0.8), 462 ) 463 bui.textwidget( 464 parent=self._root_widget, 465 draw_controller=btn, 466 position=(hoffs + scl * (-10), v + scl * 95), 467 size=(scl * button_width, scl * 50), 468 text=bui.Lstr( 469 resource='playModes.freeForAllText', 470 fallback_resource='freeForAllText', 471 ), 472 maxwidth=scl * button_width * 0.7, 473 h_align='center', 474 v_align='center', 475 color=(0.7, 0.9, 0.7, 1.0), 476 scale=scl * 1.9, 477 ) 478 bui.textwidget( 479 parent=self._root_widget, 480 draw_controller=btn, 481 position=(hoffs + scl * (-10), v + (scl * 54)), 482 size=(scl * button_width, scl * 30), 483 text=bui.Lstr(resource=f'{self._r}.twoToEightPlayersText'), 484 h_align='center', 485 v_align='center', 486 scale=0.9 * scl, 487 flatness=1.0, 488 maxwidth=scl * button_width * 0.7, 489 color=clr, 490 ) 491 492 if uiscale is bui.UIScale.SMALL: 493 back_button.delete() 494 bui.containerwidget( 495 edit=self._root_widget, 496 on_cancel_call=self._back, 497 # cancel_button=bui.get_special_widget('back_button'), 498 selected_child=( 499 self._coop_button 500 if self._is_main_menu 501 else self._teams_button 502 ), 503 ) 504 else: 505 bui.buttonwidget(edit=back_button, on_activate_call=self._back) 506 bui.containerwidget( 507 edit=self._root_widget, 508 cancel_button=back_button, 509 selected_child=( 510 self._coop_button 511 if self._is_main_menu 512 else self._teams_button 513 ), 514 ) 515 516 self._restore_state() 517 518 @override 519 def get_main_window_state(self) -> bui.MainWindowState: 520 # Support recreating our window for back/refresh purposes. 521 cls = type(self) 522 return bui.BasicMainWindowState( 523 create_call=lambda transition, origin_widget: cls( 524 transition=transition, origin_widget=origin_widget 525 ) 526 ) 527 528 @override 529 def on_main_window_close(self) -> None: 530 self._save_state() 531 532 @staticmethod 533 def _preload_modules() -> None: 534 """Preload modules we use; avoids hitches (called in bg thread).""" 535 import bauiv1lib.mainmenu as _unused1 536 import bauiv1lib.account as _unused2 537 import bauiv1lib.coop.browser as _unused3 538 import bauiv1lib.playlist.browser as _unused4 539 540 def _back(self) -> None: 541 # pylint: disable=cyclic-import 542 543 # no-op if we're not currently in control. 544 if not self.can_change_main_window(): 545 return 546 547 if self._is_main_menu: 548 self.main_window_back() 549 else: 550 from bauiv1lib.gather import GatherWindow 551 552 assert bui.app.classic is not None 553 554 self._save_state() 555 bui.app.ui_v1.set_main_window( 556 GatherWindow(transition='in_left'), 557 from_window=self, 558 is_back=True, 559 ) 560 bui.containerwidget( 561 edit=self._root_widget, transition=self._transition_out 562 ) 563 564 def _coop(self) -> None: 565 # pylint: disable=cyclic-import 566 from bauiv1lib.account import show_sign_in_prompt 567 from bauiv1lib.coop.browser import CoopBrowserWindow 568 569 # no-op if we're not currently in control. 570 if not self.can_change_main_window(): 571 return 572 573 plus = bui.app.plus 574 assert plus is not None 575 576 if plus.get_v1_account_state() != 'signed_in': 577 show_sign_in_prompt() 578 return 579 self._save_state() 580 bui.containerwidget(edit=self._root_widget, transition='out_left') 581 assert bui.app.classic is not None 582 bui.app.ui_v1.set_main_window( 583 CoopBrowserWindow(origin_widget=self._coop_button), from_window=self 584 ) 585 586 def _team_tourney(self) -> None: 587 # pylint: disable=cyclic-import 588 from bauiv1lib.playlist.browser import PlaylistBrowserWindow 589 590 # no-op if we're not currently in control. 591 if not self.can_change_main_window(): 592 return 593 594 self._save_state() 595 596 self.main_window_replace( 597 PlaylistBrowserWindow( 598 origin_widget=self._teams_button, sessiontype=bs.DualTeamSession 599 ) 600 ) 601 602 def _free_for_all(self) -> None: 603 # pylint: disable=cyclic-import 604 from bauiv1lib.playlist.browser import PlaylistBrowserWindow 605 606 # no-op if we're not currently in control. 607 if not self.can_change_main_window(): 608 return 609 610 self._save_state() 611 bui.containerwidget(edit=self._root_widget, transition='out_left') 612 assert bui.app.classic is not None 613 bui.app.ui_v1.set_main_window( 614 PlaylistBrowserWindow( 615 origin_widget=self._free_for_all_button, 616 sessiontype=bs.FreeForAllSession, 617 ), 618 from_window=self, 619 ) 620 621 def _draw_dude( 622 self, 623 i: int, 624 btn: bui.Widget, 625 hoffs: float, 626 v: float, 627 scl: float, 628 position: tuple[float, float], 629 color: tuple[float, float, float], 630 ) -> None: 631 h_extra = -100 632 v_extra = 130 633 eye_color = ( 634 0.7 * 1.0 + 0.3 * color[0], 635 0.7 * 1.0 + 0.3 * color[1], 636 0.7 * 1.0 + 0.3 * color[2], 637 ) 638 if i == 0: 639 bui.imagewidget( 640 parent=self._root_widget, 641 draw_controller=btn, 642 position=( 643 hoffs + scl * (h_extra + position[0]), 644 v + scl * (v_extra + position[1]), 645 ), 646 size=(scl * 60, scl * 80), 647 color=color, 648 texture=self._lineup_tex, 649 mesh_transparent=self._lineup_1_transparent_mesh, 650 ) 651 bui.imagewidget( 652 parent=self._root_widget, 653 draw_controller=btn, 654 position=( 655 hoffs + scl * (h_extra + position[0] + 12), 656 v + scl * (v_extra + position[1] + 53), 657 ), 658 size=(scl * 36, scl * 18), 659 texture=self._lineup_tex, 660 color=eye_color, 661 mesh_transparent=self._eyes_mesh, 662 ) 663 elif i == 1: 664 bui.imagewidget( 665 parent=self._root_widget, 666 draw_controller=btn, 667 position=( 668 hoffs + scl * (h_extra + position[0]), 669 v + scl * (v_extra + position[1]), 670 ), 671 size=(scl * 45, scl * 90), 672 color=color, 673 texture=self._lineup_tex, 674 mesh_transparent=self._lineup_2_transparent_mesh, 675 ) 676 bui.imagewidget( 677 parent=self._root_widget, 678 draw_controller=btn, 679 position=( 680 hoffs + scl * (h_extra + position[0] + 5), 681 v + scl * (v_extra + position[1] + 67), 682 ), 683 size=(scl * 32, scl * 16), 684 texture=self._lineup_tex, 685 color=eye_color, 686 mesh_transparent=self._eyes_mesh, 687 ) 688 elif i == 2: 689 bui.imagewidget( 690 parent=self._root_widget, 691 draw_controller=btn, 692 position=( 693 hoffs + scl * (h_extra + position[0]), 694 v + scl * (v_extra + position[1]), 695 ), 696 size=(scl * 45, scl * 90), 697 color=color, 698 texture=self._lineup_tex, 699 mesh_transparent=self._lineup_3_transparent_mesh, 700 ) 701 bui.imagewidget( 702 parent=self._root_widget, 703 draw_controller=btn, 704 position=( 705 hoffs + scl * (h_extra + position[0] + 5), 706 v + scl * (v_extra + position[1] + 59), 707 ), 708 size=(scl * 34, scl * 17), 709 texture=self._lineup_tex, 710 color=eye_color, 711 mesh_transparent=self._eyes_mesh, 712 ) 713 elif i == 3: 714 bui.imagewidget( 715 parent=self._root_widget, 716 draw_controller=btn, 717 position=( 718 hoffs + scl * (h_extra + position[0]), 719 v + scl * (v_extra + position[1]), 720 ), 721 size=(scl * 48, scl * 96), 722 color=color, 723 texture=self._lineup_tex, 724 mesh_transparent=self._lineup_4_transparent_mesh, 725 ) 726 bui.imagewidget( 727 parent=self._root_widget, 728 draw_controller=btn, 729 position=( 730 hoffs + scl * (h_extra + position[0] + 2), 731 v + scl * (v_extra + position[1] + 62), 732 ), 733 size=(scl * 38, scl * 19), 734 texture=self._lineup_tex, 735 color=eye_color, 736 mesh_transparent=self._eyes_mesh, 737 ) 738 739 def _save_state(self) -> None: 740 try: 741 sel = self._root_widget.get_selected_child() 742 if sel == self._teams_button: 743 sel_name = 'Team Games' 744 elif self._coop_button is not None and sel == self._coop_button: 745 sel_name = 'Co-op Games' 746 elif sel == self._free_for_all_button: 747 sel_name = 'Free-for-All Games' 748 elif sel == self._back_button: 749 sel_name = 'Back' 750 else: 751 raise ValueError(f'unrecognized selection {sel}') 752 assert bui.app.classic is not None 753 bui.app.ui_v1.window_states[type(self)] = sel_name 754 except Exception: 755 logging.exception('Error saving state for %s.', self) 756 757 def _restore_state(self) -> None: 758 try: 759 assert bui.app.classic is not None 760 sel_name = bui.app.ui_v1.window_states.get(type(self)) 761 if sel_name == 'Team Games': 762 sel = self._teams_button 763 elif sel_name == 'Co-op Games' and self._coop_button is not None: 764 sel = self._coop_button 765 elif sel_name == 'Free-for-All Games': 766 sel = self._free_for_all_button 767 elif sel_name == 'Back': 768 sel = self._back_button 769 else: 770 sel = ( 771 self._coop_button 772 if self._coop_button is not None 773 else self._teams_button 774 ) 775 bui.containerwidget(edit=self._root_widget, selected_child=sel) 776 except Exception: 777 logging.exception('Error restoring state for %s.', self)
class
PlayWindow(bauiv1._uitypes.MainWindow):
15class PlayWindow(bui.MainWindow): 16 """Window for selecting overall play type.""" 17 18 def __init__( 19 self, 20 transition: str | None = 'in_right', 21 origin_widget: bui.Widget | None = None, 22 ): 23 # pylint: disable=too-many-statements 24 # pylint: disable=too-many-locals 25 26 # Preload some modules we use in a background thread so we won't 27 # have a visual hitch when the user taps them. 28 bui.app.threadpool_submit_no_wait(self._preload_modules) 29 30 classic = bui.app.classic 31 assert classic is not None 32 33 # We can currently be used either for main window duty or 34 # modally for selecting playlists. Ideally we should clean 35 # things up and make playlist selection go through the 36 # main-window mechanism. 37 self._is_main_menu = not classic.selecting_private_party_playlist 38 39 uiscale = bui.app.ui_v1.uiscale 40 width = 1100 if uiscale is bui.UIScale.SMALL else 800 41 x_offs = 150 if uiscale is bui.UIScale.SMALL else 0 42 height = 550 43 button_width = 400 44 45 if origin_widget is not None: 46 47 # Need to store this ourself since we can function as a 48 # non-main window. 49 self._transition_out = 'out_scale' 50 else: 51 self._transition_out = 'out_right' 52 53 self._r = 'playWindow' 54 55 super().__init__( 56 root_widget=bui.containerwidget( 57 size=(width, height), 58 toolbar_visibility='menu_full', 59 scale=( 60 1.35 61 if uiscale is bui.UIScale.SMALL 62 else 0.9 if uiscale is bui.UIScale.MEDIUM else 0.8 63 ), 64 stack_offset=( 65 (0, 20) if uiscale is bui.UIScale.SMALL else (0, 0) 66 ), 67 ), 68 transition=transition, 69 origin_widget=origin_widget, 70 ) 71 self._back_button = back_button = btn = bui.buttonwidget( 72 parent=self._root_widget, 73 position=(55 + x_offs, height - 132), 74 size=(120, 60), 75 scale=1.1, 76 text_res_scale=1.5, 77 text_scale=1.2, 78 autoselect=True, 79 label=bui.Lstr(resource='backText'), 80 button_type='back', 81 ) 82 83 txt = bui.textwidget( 84 parent=self._root_widget, 85 position=(width * 0.5, height - 101), 86 # position=(width * 0.5, height - 87 # (101 if main_menu else 61)), 88 size=(0, 0), 89 text=bui.Lstr( 90 resource=( 91 (f'{self._r}.titleText') 92 if self._is_main_menu 93 else 'playlistsText' 94 ) 95 ), 96 scale=1.7, 97 res_scale=2.0, 98 maxwidth=400, 99 color=bui.app.ui_v1.heading_color, 100 h_align='center', 101 v_align='center', 102 ) 103 104 bui.buttonwidget( 105 edit=btn, 106 button_type='backSmall', 107 size=(60, 60), 108 label=bui.charstr(bui.SpecialChar.BACK), 109 ) 110 if uiscale is bui.UIScale.SMALL: 111 bui.textwidget(edit=txt, text='') 112 113 v = height - (110 if self._is_main_menu else 90) 114 v -= 100 115 clr = (0.6, 0.7, 0.6, 1.0) 116 v -= 280 if self._is_main_menu else 180 117 v += 30 if uiscale is bui.UIScale.SMALL else 0 118 hoffs = x_offs + 80 if self._is_main_menu else x_offs - 100 119 scl = 1.13 if self._is_main_menu else 0.68 120 121 self._lineup_tex = bui.gettexture('playerLineup') 122 angry_computer_transparent_mesh = bui.getmesh( 123 'angryComputerTransparent' 124 ) 125 self._lineup_1_transparent_mesh = bui.getmesh( 126 'playerLineup1Transparent' 127 ) 128 self._lineup_2_transparent_mesh = bui.getmesh( 129 'playerLineup2Transparent' 130 ) 131 self._lineup_3_transparent_mesh = bui.getmesh( 132 'playerLineup3Transparent' 133 ) 134 self._lineup_4_transparent_mesh = bui.getmesh( 135 'playerLineup4Transparent' 136 ) 137 self._eyes_mesh = bui.getmesh('plasticEyesTransparent') 138 139 self._coop_button: bui.Widget | None = None 140 141 # Only show coop button in main-menu variant. 142 if self._is_main_menu: 143 self._coop_button = btn = bui.buttonwidget( 144 parent=self._root_widget, 145 position=(hoffs, v + (scl * 15)), 146 size=( 147 scl * button_width, 148 scl * 300, 149 ), 150 extra_touch_border_scale=0.1, 151 autoselect=True, 152 label='', 153 button_type='square', 154 text_scale=1.13, 155 on_activate_call=self._coop, 156 ) 157 158 if uiscale is bui.UIScale.SMALL: 159 bui.widget( 160 edit=btn, 161 left_widget=bui.get_special_widget('back_button'), 162 ) 163 bui.widget( 164 edit=btn, 165 up_widget=bui.get_special_widget('account_button'), 166 ) 167 bui.widget( 168 edit=btn, 169 down_widget=bui.get_special_widget('settings_button'), 170 ) 171 172 self._draw_dude( 173 0, 174 btn, 175 hoffs, 176 v, 177 scl, 178 position=(140, 30), 179 color=(0.72, 0.4, 1.0), 180 ) 181 self._draw_dude( 182 1, 183 btn, 184 hoffs, 185 v, 186 scl, 187 position=(185, 53), 188 color=(0.71, 0.5, 1.0), 189 ) 190 self._draw_dude( 191 2, 192 btn, 193 hoffs, 194 v, 195 scl, 196 position=(220, 27), 197 color=(0.67, 0.44, 1.0), 198 ) 199 self._draw_dude( 200 3, btn, hoffs, v, scl, position=(255, 57), color=(0.7, 0.3, 1.0) 201 ) 202 bui.imagewidget( 203 parent=self._root_widget, 204 draw_controller=btn, 205 position=(hoffs + scl * 230, v + scl * 153), 206 size=(scl * 115, scl * 115), 207 texture=self._lineup_tex, 208 mesh_transparent=angry_computer_transparent_mesh, 209 ) 210 211 bui.textwidget( 212 parent=self._root_widget, 213 draw_controller=btn, 214 position=(hoffs + scl * (-10), v + scl * 95), 215 size=(scl * button_width, scl * 50), 216 text=bui.Lstr( 217 resource='playModes.singlePlayerCoopText', 218 fallback_resource='playModes.coopText', 219 ), 220 maxwidth=scl * button_width * 0.7, 221 res_scale=1.5, 222 h_align='center', 223 v_align='center', 224 color=(0.7, 0.9, 0.7, 1.0), 225 scale=scl * 2.3, 226 ) 227 228 bui.textwidget( 229 parent=self._root_widget, 230 draw_controller=btn, 231 position=(hoffs + scl * (-10), v + (scl * 54)), 232 size=(scl * button_width, scl * 30), 233 text=bui.Lstr(resource=f'{self._r}.oneToFourPlayersText'), 234 h_align='center', 235 v_align='center', 236 scale=0.83 * scl, 237 flatness=1.0, 238 maxwidth=scl * button_width * 0.7, 239 color=clr, 240 ) 241 242 scl = 0.5 if self._is_main_menu else 0.68 243 hoffs += 440 if self._is_main_menu else 216 244 v += 180 if self._is_main_menu else -68 245 246 self._teams_button = btn = bui.buttonwidget( 247 parent=self._root_widget, 248 position=(hoffs, v + (scl * 15 if self._is_main_menu else 0)), 249 size=( 250 scl * button_width, 251 scl * (300 if self._is_main_menu else 360), 252 ), 253 extra_touch_border_scale=0.1, 254 autoselect=True, 255 label='', 256 button_type='square', 257 text_scale=1.13, 258 on_activate_call=self._team_tourney, 259 ) 260 261 bui.widget( 262 edit=btn, 263 up_widget=bui.get_special_widget('get_tokens_button'), 264 right_widget=bui.get_special_widget('squad_button'), 265 ) 266 267 xxx = -14 268 self._draw_dude( 269 2, 270 btn, 271 hoffs, 272 v, 273 scl, 274 position=(xxx + 148, 30), 275 color=(0.2, 0.4, 1.0), 276 ) 277 self._draw_dude( 278 3, 279 btn, 280 hoffs, 281 v, 282 scl, 283 position=(xxx + 181, 53), 284 color=(0.3, 0.4, 1.0), 285 ) 286 self._draw_dude( 287 1, 288 btn, 289 hoffs, 290 v, 291 scl, 292 position=(xxx + 216, 33), 293 color=(0.3, 0.5, 1.0), 294 ) 295 self._draw_dude( 296 0, 297 btn, 298 hoffs, 299 v, 300 scl, 301 position=(xxx + 245, 57), 302 color=(0.3, 0.5, 1.0), 303 ) 304 305 xxx = 155 306 self._draw_dude( 307 0, 308 btn, 309 hoffs, 310 v, 311 scl, 312 position=(xxx + 151, 30), 313 color=(1.0, 0.5, 0.4), 314 ) 315 self._draw_dude( 316 1, 317 btn, 318 hoffs, 319 v, 320 scl, 321 position=(xxx + 189, 53), 322 color=(1.0, 0.58, 0.58), 323 ) 324 self._draw_dude( 325 3, 326 btn, 327 hoffs, 328 v, 329 scl, 330 position=(xxx + 223, 27), 331 color=(1.0, 0.5, 0.5), 332 ) 333 self._draw_dude( 334 2, 335 btn, 336 hoffs, 337 v, 338 scl, 339 position=(xxx + 257, 57), 340 color=(1.0, 0.5, 0.5), 341 ) 342 343 bui.textwidget( 344 parent=self._root_widget, 345 draw_controller=btn, 346 position=(hoffs + scl * (-10), v + scl * 95), 347 size=(scl * button_width, scl * 50), 348 text=bui.Lstr( 349 resource='playModes.teamsText', fallback_resource='teamsText' 350 ), 351 res_scale=1.5, 352 maxwidth=scl * button_width * 0.7, 353 h_align='center', 354 v_align='center', 355 color=(0.7, 0.9, 0.7, 1.0), 356 scale=scl * 2.3, 357 ) 358 bui.textwidget( 359 parent=self._root_widget, 360 draw_controller=btn, 361 position=(hoffs + scl * (-10), v + (scl * 54)), 362 size=(scl * button_width, scl * 30), 363 text=bui.Lstr(resource=f'{self._r}.twoToEightPlayersText'), 364 h_align='center', 365 v_align='center', 366 res_scale=1.5, 367 scale=0.9 * scl, 368 flatness=1.0, 369 maxwidth=scl * button_width * 0.7, 370 color=clr, 371 ) 372 373 hoffs += 0 if self._is_main_menu else 300 374 v -= 155 if self._is_main_menu else 0 375 self._free_for_all_button = btn = bui.buttonwidget( 376 parent=self._root_widget, 377 position=(hoffs, v + (scl * 15 if self._is_main_menu else 0)), 378 size=( 379 scl * button_width, 380 scl * (300 if self._is_main_menu else 360), 381 ), 382 extra_touch_border_scale=0.1, 383 autoselect=True, 384 label='', 385 button_type='square', 386 text_scale=1.13, 387 on_activate_call=self._free_for_all, 388 ) 389 390 xxx = -5 391 self._draw_dude( 392 0, 393 btn, 394 hoffs, 395 v, 396 scl, 397 position=(xxx + 140, 30), 398 color=(0.4, 1.0, 0.4), 399 ) 400 self._draw_dude( 401 3, 402 btn, 403 hoffs, 404 v, 405 scl, 406 position=(xxx + 185, 53), 407 color=(1.0, 0.4, 0.5), 408 ) 409 self._draw_dude( 410 1, 411 btn, 412 hoffs, 413 v, 414 scl, 415 position=(xxx + 220, 27), 416 color=(0.4, 0.5, 1.0), 417 ) 418 self._draw_dude( 419 2, 420 btn, 421 hoffs, 422 v, 423 scl, 424 position=(xxx + 255, 57), 425 color=(0.5, 1.0, 0.4), 426 ) 427 xxx = 140 428 self._draw_dude( 429 2, 430 btn, 431 hoffs, 432 v, 433 scl, 434 position=(xxx + 148, 30), 435 color=(1.0, 0.9, 0.4), 436 ) 437 self._draw_dude( 438 0, 439 btn, 440 hoffs, 441 v, 442 scl, 443 position=(xxx + 182, 53), 444 color=(0.7, 1.0, 0.5), 445 ) 446 self._draw_dude( 447 3, 448 btn, 449 hoffs, 450 v, 451 scl, 452 position=(xxx + 233, 27), 453 color=(0.7, 0.5, 0.9), 454 ) 455 self._draw_dude( 456 1, 457 btn, 458 hoffs, 459 v, 460 scl, 461 position=(xxx + 266, 53), 462 color=(0.4, 0.5, 0.8), 463 ) 464 bui.textwidget( 465 parent=self._root_widget, 466 draw_controller=btn, 467 position=(hoffs + scl * (-10), v + scl * 95), 468 size=(scl * button_width, scl * 50), 469 text=bui.Lstr( 470 resource='playModes.freeForAllText', 471 fallback_resource='freeForAllText', 472 ), 473 maxwidth=scl * button_width * 0.7, 474 h_align='center', 475 v_align='center', 476 color=(0.7, 0.9, 0.7, 1.0), 477 scale=scl * 1.9, 478 ) 479 bui.textwidget( 480 parent=self._root_widget, 481 draw_controller=btn, 482 position=(hoffs + scl * (-10), v + (scl * 54)), 483 size=(scl * button_width, scl * 30), 484 text=bui.Lstr(resource=f'{self._r}.twoToEightPlayersText'), 485 h_align='center', 486 v_align='center', 487 scale=0.9 * scl, 488 flatness=1.0, 489 maxwidth=scl * button_width * 0.7, 490 color=clr, 491 ) 492 493 if uiscale is bui.UIScale.SMALL: 494 back_button.delete() 495 bui.containerwidget( 496 edit=self._root_widget, 497 on_cancel_call=self._back, 498 # cancel_button=bui.get_special_widget('back_button'), 499 selected_child=( 500 self._coop_button 501 if self._is_main_menu 502 else self._teams_button 503 ), 504 ) 505 else: 506 bui.buttonwidget(edit=back_button, on_activate_call=self._back) 507 bui.containerwidget( 508 edit=self._root_widget, 509 cancel_button=back_button, 510 selected_child=( 511 self._coop_button 512 if self._is_main_menu 513 else self._teams_button 514 ), 515 ) 516 517 self._restore_state() 518 519 @override 520 def get_main_window_state(self) -> bui.MainWindowState: 521 # Support recreating our window for back/refresh purposes. 522 cls = type(self) 523 return bui.BasicMainWindowState( 524 create_call=lambda transition, origin_widget: cls( 525 transition=transition, origin_widget=origin_widget 526 ) 527 ) 528 529 @override 530 def on_main_window_close(self) -> None: 531 self._save_state() 532 533 @staticmethod 534 def _preload_modules() -> None: 535 """Preload modules we use; avoids hitches (called in bg thread).""" 536 import bauiv1lib.mainmenu as _unused1 537 import bauiv1lib.account as _unused2 538 import bauiv1lib.coop.browser as _unused3 539 import bauiv1lib.playlist.browser as _unused4 540 541 def _back(self) -> None: 542 # pylint: disable=cyclic-import 543 544 # no-op if we're not currently in control. 545 if not self.can_change_main_window(): 546 return 547 548 if self._is_main_menu: 549 self.main_window_back() 550 else: 551 from bauiv1lib.gather import GatherWindow 552 553 assert bui.app.classic is not None 554 555 self._save_state() 556 bui.app.ui_v1.set_main_window( 557 GatherWindow(transition='in_left'), 558 from_window=self, 559 is_back=True, 560 ) 561 bui.containerwidget( 562 edit=self._root_widget, transition=self._transition_out 563 ) 564 565 def _coop(self) -> None: 566 # pylint: disable=cyclic-import 567 from bauiv1lib.account import show_sign_in_prompt 568 from bauiv1lib.coop.browser import CoopBrowserWindow 569 570 # no-op if we're not currently in control. 571 if not self.can_change_main_window(): 572 return 573 574 plus = bui.app.plus 575 assert plus is not None 576 577 if plus.get_v1_account_state() != 'signed_in': 578 show_sign_in_prompt() 579 return 580 self._save_state() 581 bui.containerwidget(edit=self._root_widget, transition='out_left') 582 assert bui.app.classic is not None 583 bui.app.ui_v1.set_main_window( 584 CoopBrowserWindow(origin_widget=self._coop_button), from_window=self 585 ) 586 587 def _team_tourney(self) -> None: 588 # pylint: disable=cyclic-import 589 from bauiv1lib.playlist.browser import PlaylistBrowserWindow 590 591 # no-op if we're not currently in control. 592 if not self.can_change_main_window(): 593 return 594 595 self._save_state() 596 597 self.main_window_replace( 598 PlaylistBrowserWindow( 599 origin_widget=self._teams_button, sessiontype=bs.DualTeamSession 600 ) 601 ) 602 603 def _free_for_all(self) -> None: 604 # pylint: disable=cyclic-import 605 from bauiv1lib.playlist.browser import PlaylistBrowserWindow 606 607 # no-op if we're not currently in control. 608 if not self.can_change_main_window(): 609 return 610 611 self._save_state() 612 bui.containerwidget(edit=self._root_widget, transition='out_left') 613 assert bui.app.classic is not None 614 bui.app.ui_v1.set_main_window( 615 PlaylistBrowserWindow( 616 origin_widget=self._free_for_all_button, 617 sessiontype=bs.FreeForAllSession, 618 ), 619 from_window=self, 620 ) 621 622 def _draw_dude( 623 self, 624 i: int, 625 btn: bui.Widget, 626 hoffs: float, 627 v: float, 628 scl: float, 629 position: tuple[float, float], 630 color: tuple[float, float, float], 631 ) -> None: 632 h_extra = -100 633 v_extra = 130 634 eye_color = ( 635 0.7 * 1.0 + 0.3 * color[0], 636 0.7 * 1.0 + 0.3 * color[1], 637 0.7 * 1.0 + 0.3 * color[2], 638 ) 639 if i == 0: 640 bui.imagewidget( 641 parent=self._root_widget, 642 draw_controller=btn, 643 position=( 644 hoffs + scl * (h_extra + position[0]), 645 v + scl * (v_extra + position[1]), 646 ), 647 size=(scl * 60, scl * 80), 648 color=color, 649 texture=self._lineup_tex, 650 mesh_transparent=self._lineup_1_transparent_mesh, 651 ) 652 bui.imagewidget( 653 parent=self._root_widget, 654 draw_controller=btn, 655 position=( 656 hoffs + scl * (h_extra + position[0] + 12), 657 v + scl * (v_extra + position[1] + 53), 658 ), 659 size=(scl * 36, scl * 18), 660 texture=self._lineup_tex, 661 color=eye_color, 662 mesh_transparent=self._eyes_mesh, 663 ) 664 elif i == 1: 665 bui.imagewidget( 666 parent=self._root_widget, 667 draw_controller=btn, 668 position=( 669 hoffs + scl * (h_extra + position[0]), 670 v + scl * (v_extra + position[1]), 671 ), 672 size=(scl * 45, scl * 90), 673 color=color, 674 texture=self._lineup_tex, 675 mesh_transparent=self._lineup_2_transparent_mesh, 676 ) 677 bui.imagewidget( 678 parent=self._root_widget, 679 draw_controller=btn, 680 position=( 681 hoffs + scl * (h_extra + position[0] + 5), 682 v + scl * (v_extra + position[1] + 67), 683 ), 684 size=(scl * 32, scl * 16), 685 texture=self._lineup_tex, 686 color=eye_color, 687 mesh_transparent=self._eyes_mesh, 688 ) 689 elif i == 2: 690 bui.imagewidget( 691 parent=self._root_widget, 692 draw_controller=btn, 693 position=( 694 hoffs + scl * (h_extra + position[0]), 695 v + scl * (v_extra + position[1]), 696 ), 697 size=(scl * 45, scl * 90), 698 color=color, 699 texture=self._lineup_tex, 700 mesh_transparent=self._lineup_3_transparent_mesh, 701 ) 702 bui.imagewidget( 703 parent=self._root_widget, 704 draw_controller=btn, 705 position=( 706 hoffs + scl * (h_extra + position[0] + 5), 707 v + scl * (v_extra + position[1] + 59), 708 ), 709 size=(scl * 34, scl * 17), 710 texture=self._lineup_tex, 711 color=eye_color, 712 mesh_transparent=self._eyes_mesh, 713 ) 714 elif i == 3: 715 bui.imagewidget( 716 parent=self._root_widget, 717 draw_controller=btn, 718 position=( 719 hoffs + scl * (h_extra + position[0]), 720 v + scl * (v_extra + position[1]), 721 ), 722 size=(scl * 48, scl * 96), 723 color=color, 724 texture=self._lineup_tex, 725 mesh_transparent=self._lineup_4_transparent_mesh, 726 ) 727 bui.imagewidget( 728 parent=self._root_widget, 729 draw_controller=btn, 730 position=( 731 hoffs + scl * (h_extra + position[0] + 2), 732 v + scl * (v_extra + position[1] + 62), 733 ), 734 size=(scl * 38, scl * 19), 735 texture=self._lineup_tex, 736 color=eye_color, 737 mesh_transparent=self._eyes_mesh, 738 ) 739 740 def _save_state(self) -> None: 741 try: 742 sel = self._root_widget.get_selected_child() 743 if sel == self._teams_button: 744 sel_name = 'Team Games' 745 elif self._coop_button is not None and sel == self._coop_button: 746 sel_name = 'Co-op Games' 747 elif sel == self._free_for_all_button: 748 sel_name = 'Free-for-All Games' 749 elif sel == self._back_button: 750 sel_name = 'Back' 751 else: 752 raise ValueError(f'unrecognized selection {sel}') 753 assert bui.app.classic is not None 754 bui.app.ui_v1.window_states[type(self)] = sel_name 755 except Exception: 756 logging.exception('Error saving state for %s.', self) 757 758 def _restore_state(self) -> None: 759 try: 760 assert bui.app.classic is not None 761 sel_name = bui.app.ui_v1.window_states.get(type(self)) 762 if sel_name == 'Team Games': 763 sel = self._teams_button 764 elif sel_name == 'Co-op Games' and self._coop_button is not None: 765 sel = self._coop_button 766 elif sel_name == 'Free-for-All Games': 767 sel = self._free_for_all_button 768 elif sel_name == 'Back': 769 sel = self._back_button 770 else: 771 sel = ( 772 self._coop_button 773 if self._coop_button is not None 774 else self._teams_button 775 ) 776 bui.containerwidget(edit=self._root_widget, selected_child=sel) 777 except Exception: 778 logging.exception('Error restoring state for %s.', self)
Window for selecting overall play type.
PlayWindow( transition: str | None = 'in_right', origin_widget: _bauiv1.Widget | None = None)
18 def __init__( 19 self, 20 transition: str | None = 'in_right', 21 origin_widget: bui.Widget | None = None, 22 ): 23 # pylint: disable=too-many-statements 24 # pylint: disable=too-many-locals 25 26 # Preload some modules we use in a background thread so we won't 27 # have a visual hitch when the user taps them. 28 bui.app.threadpool_submit_no_wait(self._preload_modules) 29 30 classic = bui.app.classic 31 assert classic is not None 32 33 # We can currently be used either for main window duty or 34 # modally for selecting playlists. Ideally we should clean 35 # things up and make playlist selection go through the 36 # main-window mechanism. 37 self._is_main_menu = not classic.selecting_private_party_playlist 38 39 uiscale = bui.app.ui_v1.uiscale 40 width = 1100 if uiscale is bui.UIScale.SMALL else 800 41 x_offs = 150 if uiscale is bui.UIScale.SMALL else 0 42 height = 550 43 button_width = 400 44 45 if origin_widget is not None: 46 47 # Need to store this ourself since we can function as a 48 # non-main window. 49 self._transition_out = 'out_scale' 50 else: 51 self._transition_out = 'out_right' 52 53 self._r = 'playWindow' 54 55 super().__init__( 56 root_widget=bui.containerwidget( 57 size=(width, height), 58 toolbar_visibility='menu_full', 59 scale=( 60 1.35 61 if uiscale is bui.UIScale.SMALL 62 else 0.9 if uiscale is bui.UIScale.MEDIUM else 0.8 63 ), 64 stack_offset=( 65 (0, 20) if uiscale is bui.UIScale.SMALL else (0, 0) 66 ), 67 ), 68 transition=transition, 69 origin_widget=origin_widget, 70 ) 71 self._back_button = back_button = btn = bui.buttonwidget( 72 parent=self._root_widget, 73 position=(55 + x_offs, height - 132), 74 size=(120, 60), 75 scale=1.1, 76 text_res_scale=1.5, 77 text_scale=1.2, 78 autoselect=True, 79 label=bui.Lstr(resource='backText'), 80 button_type='back', 81 ) 82 83 txt = bui.textwidget( 84 parent=self._root_widget, 85 position=(width * 0.5, height - 101), 86 # position=(width * 0.5, height - 87 # (101 if main_menu else 61)), 88 size=(0, 0), 89 text=bui.Lstr( 90 resource=( 91 (f'{self._r}.titleText') 92 if self._is_main_menu 93 else 'playlistsText' 94 ) 95 ), 96 scale=1.7, 97 res_scale=2.0, 98 maxwidth=400, 99 color=bui.app.ui_v1.heading_color, 100 h_align='center', 101 v_align='center', 102 ) 103 104 bui.buttonwidget( 105 edit=btn, 106 button_type='backSmall', 107 size=(60, 60), 108 label=bui.charstr(bui.SpecialChar.BACK), 109 ) 110 if uiscale is bui.UIScale.SMALL: 111 bui.textwidget(edit=txt, text='') 112 113 v = height - (110 if self._is_main_menu else 90) 114 v -= 100 115 clr = (0.6, 0.7, 0.6, 1.0) 116 v -= 280 if self._is_main_menu else 180 117 v += 30 if uiscale is bui.UIScale.SMALL else 0 118 hoffs = x_offs + 80 if self._is_main_menu else x_offs - 100 119 scl = 1.13 if self._is_main_menu else 0.68 120 121 self._lineup_tex = bui.gettexture('playerLineup') 122 angry_computer_transparent_mesh = bui.getmesh( 123 'angryComputerTransparent' 124 ) 125 self._lineup_1_transparent_mesh = bui.getmesh( 126 'playerLineup1Transparent' 127 ) 128 self._lineup_2_transparent_mesh = bui.getmesh( 129 'playerLineup2Transparent' 130 ) 131 self._lineup_3_transparent_mesh = bui.getmesh( 132 'playerLineup3Transparent' 133 ) 134 self._lineup_4_transparent_mesh = bui.getmesh( 135 'playerLineup4Transparent' 136 ) 137 self._eyes_mesh = bui.getmesh('plasticEyesTransparent') 138 139 self._coop_button: bui.Widget | None = None 140 141 # Only show coop button in main-menu variant. 142 if self._is_main_menu: 143 self._coop_button = btn = bui.buttonwidget( 144 parent=self._root_widget, 145 position=(hoffs, v + (scl * 15)), 146 size=( 147 scl * button_width, 148 scl * 300, 149 ), 150 extra_touch_border_scale=0.1, 151 autoselect=True, 152 label='', 153 button_type='square', 154 text_scale=1.13, 155 on_activate_call=self._coop, 156 ) 157 158 if uiscale is bui.UIScale.SMALL: 159 bui.widget( 160 edit=btn, 161 left_widget=bui.get_special_widget('back_button'), 162 ) 163 bui.widget( 164 edit=btn, 165 up_widget=bui.get_special_widget('account_button'), 166 ) 167 bui.widget( 168 edit=btn, 169 down_widget=bui.get_special_widget('settings_button'), 170 ) 171 172 self._draw_dude( 173 0, 174 btn, 175 hoffs, 176 v, 177 scl, 178 position=(140, 30), 179 color=(0.72, 0.4, 1.0), 180 ) 181 self._draw_dude( 182 1, 183 btn, 184 hoffs, 185 v, 186 scl, 187 position=(185, 53), 188 color=(0.71, 0.5, 1.0), 189 ) 190 self._draw_dude( 191 2, 192 btn, 193 hoffs, 194 v, 195 scl, 196 position=(220, 27), 197 color=(0.67, 0.44, 1.0), 198 ) 199 self._draw_dude( 200 3, btn, hoffs, v, scl, position=(255, 57), color=(0.7, 0.3, 1.0) 201 ) 202 bui.imagewidget( 203 parent=self._root_widget, 204 draw_controller=btn, 205 position=(hoffs + scl * 230, v + scl * 153), 206 size=(scl * 115, scl * 115), 207 texture=self._lineup_tex, 208 mesh_transparent=angry_computer_transparent_mesh, 209 ) 210 211 bui.textwidget( 212 parent=self._root_widget, 213 draw_controller=btn, 214 position=(hoffs + scl * (-10), v + scl * 95), 215 size=(scl * button_width, scl * 50), 216 text=bui.Lstr( 217 resource='playModes.singlePlayerCoopText', 218 fallback_resource='playModes.coopText', 219 ), 220 maxwidth=scl * button_width * 0.7, 221 res_scale=1.5, 222 h_align='center', 223 v_align='center', 224 color=(0.7, 0.9, 0.7, 1.0), 225 scale=scl * 2.3, 226 ) 227 228 bui.textwidget( 229 parent=self._root_widget, 230 draw_controller=btn, 231 position=(hoffs + scl * (-10), v + (scl * 54)), 232 size=(scl * button_width, scl * 30), 233 text=bui.Lstr(resource=f'{self._r}.oneToFourPlayersText'), 234 h_align='center', 235 v_align='center', 236 scale=0.83 * scl, 237 flatness=1.0, 238 maxwidth=scl * button_width * 0.7, 239 color=clr, 240 ) 241 242 scl = 0.5 if self._is_main_menu else 0.68 243 hoffs += 440 if self._is_main_menu else 216 244 v += 180 if self._is_main_menu else -68 245 246 self._teams_button = btn = bui.buttonwidget( 247 parent=self._root_widget, 248 position=(hoffs, v + (scl * 15 if self._is_main_menu else 0)), 249 size=( 250 scl * button_width, 251 scl * (300 if self._is_main_menu else 360), 252 ), 253 extra_touch_border_scale=0.1, 254 autoselect=True, 255 label='', 256 button_type='square', 257 text_scale=1.13, 258 on_activate_call=self._team_tourney, 259 ) 260 261 bui.widget( 262 edit=btn, 263 up_widget=bui.get_special_widget('get_tokens_button'), 264 right_widget=bui.get_special_widget('squad_button'), 265 ) 266 267 xxx = -14 268 self._draw_dude( 269 2, 270 btn, 271 hoffs, 272 v, 273 scl, 274 position=(xxx + 148, 30), 275 color=(0.2, 0.4, 1.0), 276 ) 277 self._draw_dude( 278 3, 279 btn, 280 hoffs, 281 v, 282 scl, 283 position=(xxx + 181, 53), 284 color=(0.3, 0.4, 1.0), 285 ) 286 self._draw_dude( 287 1, 288 btn, 289 hoffs, 290 v, 291 scl, 292 position=(xxx + 216, 33), 293 color=(0.3, 0.5, 1.0), 294 ) 295 self._draw_dude( 296 0, 297 btn, 298 hoffs, 299 v, 300 scl, 301 position=(xxx + 245, 57), 302 color=(0.3, 0.5, 1.0), 303 ) 304 305 xxx = 155 306 self._draw_dude( 307 0, 308 btn, 309 hoffs, 310 v, 311 scl, 312 position=(xxx + 151, 30), 313 color=(1.0, 0.5, 0.4), 314 ) 315 self._draw_dude( 316 1, 317 btn, 318 hoffs, 319 v, 320 scl, 321 position=(xxx + 189, 53), 322 color=(1.0, 0.58, 0.58), 323 ) 324 self._draw_dude( 325 3, 326 btn, 327 hoffs, 328 v, 329 scl, 330 position=(xxx + 223, 27), 331 color=(1.0, 0.5, 0.5), 332 ) 333 self._draw_dude( 334 2, 335 btn, 336 hoffs, 337 v, 338 scl, 339 position=(xxx + 257, 57), 340 color=(1.0, 0.5, 0.5), 341 ) 342 343 bui.textwidget( 344 parent=self._root_widget, 345 draw_controller=btn, 346 position=(hoffs + scl * (-10), v + scl * 95), 347 size=(scl * button_width, scl * 50), 348 text=bui.Lstr( 349 resource='playModes.teamsText', fallback_resource='teamsText' 350 ), 351 res_scale=1.5, 352 maxwidth=scl * button_width * 0.7, 353 h_align='center', 354 v_align='center', 355 color=(0.7, 0.9, 0.7, 1.0), 356 scale=scl * 2.3, 357 ) 358 bui.textwidget( 359 parent=self._root_widget, 360 draw_controller=btn, 361 position=(hoffs + scl * (-10), v + (scl * 54)), 362 size=(scl * button_width, scl * 30), 363 text=bui.Lstr(resource=f'{self._r}.twoToEightPlayersText'), 364 h_align='center', 365 v_align='center', 366 res_scale=1.5, 367 scale=0.9 * scl, 368 flatness=1.0, 369 maxwidth=scl * button_width * 0.7, 370 color=clr, 371 ) 372 373 hoffs += 0 if self._is_main_menu else 300 374 v -= 155 if self._is_main_menu else 0 375 self._free_for_all_button = btn = bui.buttonwidget( 376 parent=self._root_widget, 377 position=(hoffs, v + (scl * 15 if self._is_main_menu else 0)), 378 size=( 379 scl * button_width, 380 scl * (300 if self._is_main_menu else 360), 381 ), 382 extra_touch_border_scale=0.1, 383 autoselect=True, 384 label='', 385 button_type='square', 386 text_scale=1.13, 387 on_activate_call=self._free_for_all, 388 ) 389 390 xxx = -5 391 self._draw_dude( 392 0, 393 btn, 394 hoffs, 395 v, 396 scl, 397 position=(xxx + 140, 30), 398 color=(0.4, 1.0, 0.4), 399 ) 400 self._draw_dude( 401 3, 402 btn, 403 hoffs, 404 v, 405 scl, 406 position=(xxx + 185, 53), 407 color=(1.0, 0.4, 0.5), 408 ) 409 self._draw_dude( 410 1, 411 btn, 412 hoffs, 413 v, 414 scl, 415 position=(xxx + 220, 27), 416 color=(0.4, 0.5, 1.0), 417 ) 418 self._draw_dude( 419 2, 420 btn, 421 hoffs, 422 v, 423 scl, 424 position=(xxx + 255, 57), 425 color=(0.5, 1.0, 0.4), 426 ) 427 xxx = 140 428 self._draw_dude( 429 2, 430 btn, 431 hoffs, 432 v, 433 scl, 434 position=(xxx + 148, 30), 435 color=(1.0, 0.9, 0.4), 436 ) 437 self._draw_dude( 438 0, 439 btn, 440 hoffs, 441 v, 442 scl, 443 position=(xxx + 182, 53), 444 color=(0.7, 1.0, 0.5), 445 ) 446 self._draw_dude( 447 3, 448 btn, 449 hoffs, 450 v, 451 scl, 452 position=(xxx + 233, 27), 453 color=(0.7, 0.5, 0.9), 454 ) 455 self._draw_dude( 456 1, 457 btn, 458 hoffs, 459 v, 460 scl, 461 position=(xxx + 266, 53), 462 color=(0.4, 0.5, 0.8), 463 ) 464 bui.textwidget( 465 parent=self._root_widget, 466 draw_controller=btn, 467 position=(hoffs + scl * (-10), v + scl * 95), 468 size=(scl * button_width, scl * 50), 469 text=bui.Lstr( 470 resource='playModes.freeForAllText', 471 fallback_resource='freeForAllText', 472 ), 473 maxwidth=scl * button_width * 0.7, 474 h_align='center', 475 v_align='center', 476 color=(0.7, 0.9, 0.7, 1.0), 477 scale=scl * 1.9, 478 ) 479 bui.textwidget( 480 parent=self._root_widget, 481 draw_controller=btn, 482 position=(hoffs + scl * (-10), v + (scl * 54)), 483 size=(scl * button_width, scl * 30), 484 text=bui.Lstr(resource=f'{self._r}.twoToEightPlayersText'), 485 h_align='center', 486 v_align='center', 487 scale=0.9 * scl, 488 flatness=1.0, 489 maxwidth=scl * button_width * 0.7, 490 color=clr, 491 ) 492 493 if uiscale is bui.UIScale.SMALL: 494 back_button.delete() 495 bui.containerwidget( 496 edit=self._root_widget, 497 on_cancel_call=self._back, 498 # cancel_button=bui.get_special_widget('back_button'), 499 selected_child=( 500 self._coop_button 501 if self._is_main_menu 502 else self._teams_button 503 ), 504 ) 505 else: 506 bui.buttonwidget(edit=back_button, on_activate_call=self._back) 507 bui.containerwidget( 508 edit=self._root_widget, 509 cancel_button=back_button, 510 selected_child=( 511 self._coop_button 512 if self._is_main_menu 513 else self._teams_button 514 ), 515 ) 516 517 self._restore_state()
Create a MainWindow given a root widget and transition info.
Automatically handles in and out transitions on the provided widget, so there is no need to set transitions when creating it.
519 @override 520 def get_main_window_state(self) -> bui.MainWindowState: 521 # Support recreating our window for back/refresh purposes. 522 cls = type(self) 523 return bui.BasicMainWindowState( 524 create_call=lambda transition, origin_widget: cls( 525 transition=transition, origin_widget=origin_widget 526 ) 527 )
Return a WindowState to recreate this window, if supported.
@override
def
on_main_window_close(self) -> None:
Called before transitioning out a main window.
A good opportunity to save window state/etc.
Inherited Members
- bauiv1._uitypes.MainWindow
- main_window_back_state
- main_window_close
- can_change_main_window
- main_window_back
- main_window_replace
- bauiv1._uitypes.Window
- get_root_widget