mirror of
https://github.com/hypervortex/VH-Bombsquad-Modded-Server-Files
synced 2025-11-07 17:36:08 +00:00
Delete dist directory
This commit is contained in:
parent
2e2c838750
commit
867634cc5c
1779 changed files with 0 additions and 565850 deletions
416
dist/ba_data/python/bastd/ui/popup.py
vendored
416
dist/ba_data/python/bastd/ui/popup.py
vendored
|
|
@ -1,416 +0,0 @@
|
|||
# Released under the MIT License. See LICENSE for details.
|
||||
#
|
||||
"""Popup window/menu related functionality."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import weakref
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import ba
|
||||
import ba.internal
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Sequence, Callable
|
||||
|
||||
|
||||
class PopupWindow:
|
||||
"""A transient window that positions and scales itself for visibility.
|
||||
|
||||
Category: UI Classes"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
position: tuple[float, float],
|
||||
size: tuple[float, float],
|
||||
scale: float = 1.0,
|
||||
offset: tuple[float, float] = (0, 0),
|
||||
bg_color: tuple[float, float, float] = (0.35, 0.55, 0.15),
|
||||
focus_position: tuple[float, float] = (0, 0),
|
||||
focus_size: tuple[float, float] | None = None,
|
||||
toolbar_visibility: str = 'menu_minimal_no_back',
|
||||
):
|
||||
# pylint: disable=too-many-locals
|
||||
if focus_size is None:
|
||||
focus_size = size
|
||||
|
||||
# In vr mode we can't have windows going outside the screen.
|
||||
if ba.app.vr_mode:
|
||||
focus_size = size
|
||||
focus_position = (0, 0)
|
||||
|
||||
width = focus_size[0]
|
||||
height = focus_size[1]
|
||||
|
||||
# Ok, we've been given a desired width, height, and scale;
|
||||
# we now need to ensure that we're all onscreen by scaling down if
|
||||
# need be and clamping it to the UI bounds.
|
||||
bounds = ba.app.ui_bounds
|
||||
edge_buffer = 15
|
||||
bounds_width = bounds[1] - bounds[0] - edge_buffer * 2
|
||||
bounds_height = bounds[3] - bounds[2] - edge_buffer * 2
|
||||
|
||||
fin_width = width * scale
|
||||
fin_height = height * scale
|
||||
if fin_width > bounds_width:
|
||||
scale /= fin_width / bounds_width
|
||||
fin_width = width * scale
|
||||
fin_height = height * scale
|
||||
if fin_height > bounds_height:
|
||||
scale /= fin_height / bounds_height
|
||||
fin_width = width * scale
|
||||
fin_height = height * scale
|
||||
|
||||
x_min = bounds[0] + edge_buffer + fin_width * 0.5
|
||||
y_min = bounds[2] + edge_buffer + fin_height * 0.5
|
||||
x_max = bounds[1] - edge_buffer - fin_width * 0.5
|
||||
y_max = bounds[3] - edge_buffer - fin_height * 0.5
|
||||
|
||||
x_fin = min(max(x_min, position[0] + offset[0]), x_max)
|
||||
y_fin = min(max(y_min, position[1] + offset[1]), y_max)
|
||||
|
||||
# ok, we've calced a valid x/y position and a scale based on or
|
||||
# focus area. ..now calc the difference between the center of our
|
||||
# focus area and the center of our window to come up with the
|
||||
# offset we'll need to plug in to the window
|
||||
x_offs = (
|
||||
(focus_position[0] + focus_size[0] * 0.5) - (size[0] * 0.5)
|
||||
) * scale
|
||||
y_offs = (
|
||||
(focus_position[1] + focus_size[1] * 0.5) - (size[1] * 0.5)
|
||||
) * scale
|
||||
|
||||
self.root_widget = ba.containerwidget(
|
||||
transition='in_scale',
|
||||
scale=scale,
|
||||
toolbar_visibility=toolbar_visibility,
|
||||
size=size,
|
||||
parent=ba.internal.get_special_widget('overlay_stack'),
|
||||
stack_offset=(x_fin - x_offs, y_fin - y_offs),
|
||||
scale_origin_stack_offset=(position[0], position[1]),
|
||||
on_outside_click_call=self.on_popup_cancel,
|
||||
claim_outside_clicks=True,
|
||||
color=bg_color,
|
||||
on_cancel_call=self.on_popup_cancel,
|
||||
)
|
||||
# complain if we outlive our root widget
|
||||
ba.uicleanupcheck(self, self.root_widget)
|
||||
|
||||
def on_popup_cancel(self) -> None:
|
||||
"""Called when the popup is canceled.
|
||||
|
||||
Cancels can occur due to clicking outside the window,
|
||||
hitting escape, etc.
|
||||
"""
|
||||
|
||||
|
||||
class PopupMenuWindow(PopupWindow):
|
||||
"""A menu built using popup-window functionality."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
position: tuple[float, float],
|
||||
choices: Sequence[str],
|
||||
current_choice: str,
|
||||
delegate: Any = None,
|
||||
width: float = 230.0,
|
||||
maxwidth: float | None = None,
|
||||
scale: float = 1.0,
|
||||
choices_disabled: Sequence[str] | None = None,
|
||||
choices_display: Sequence[ba.Lstr] | None = None,
|
||||
):
|
||||
# FIXME: Clean up a bit.
|
||||
# pylint: disable=too-many-branches
|
||||
# pylint: disable=too-many-locals
|
||||
# pylint: disable=too-many-statements
|
||||
if choices_disabled is None:
|
||||
choices_disabled = []
|
||||
if choices_display is None:
|
||||
choices_display = []
|
||||
|
||||
# FIXME: For the moment we base our width on these strings so
|
||||
# we need to flatten them.
|
||||
choices_display_fin: list[str] = []
|
||||
for choice_display in choices_display:
|
||||
choices_display_fin.append(choice_display.evaluate())
|
||||
|
||||
if maxwidth is None:
|
||||
maxwidth = width * 1.5
|
||||
|
||||
self._transitioning_out = False
|
||||
self._choices = list(choices)
|
||||
self._choices_display = list(choices_display_fin)
|
||||
self._current_choice = current_choice
|
||||
self._choices_disabled = list(choices_disabled)
|
||||
self._done_building = False
|
||||
if not choices:
|
||||
raise TypeError('Must pass at least one choice')
|
||||
self._width = width
|
||||
self._scale = scale
|
||||
if len(choices) > 8:
|
||||
self._height = 280
|
||||
self._use_scroll = True
|
||||
else:
|
||||
self._height = 20 + len(choices) * 33
|
||||
self._use_scroll = False
|
||||
self._delegate = None # don't want this stuff called just yet..
|
||||
|
||||
# extend width to fit our longest string (or our max-width)
|
||||
for index, choice in enumerate(choices):
|
||||
if len(choices_display_fin) == len(choices):
|
||||
choice_display_name = choices_display_fin[index]
|
||||
else:
|
||||
choice_display_name = choice
|
||||
if self._use_scroll:
|
||||
self._width = max(
|
||||
self._width,
|
||||
min(
|
||||
maxwidth,
|
||||
ba.internal.get_string_width(
|
||||
choice_display_name, suppress_warning=True
|
||||
),
|
||||
)
|
||||
+ 75,
|
||||
)
|
||||
else:
|
||||
self._width = max(
|
||||
self._width,
|
||||
min(
|
||||
maxwidth,
|
||||
ba.internal.get_string_width(
|
||||
choice_display_name, suppress_warning=True
|
||||
),
|
||||
)
|
||||
+ 60,
|
||||
)
|
||||
|
||||
# init parent class - this will rescale and reposition things as
|
||||
# needed and create our root widget
|
||||
PopupWindow.__init__(
|
||||
self, position, size=(self._width, self._height), scale=self._scale
|
||||
)
|
||||
|
||||
if self._use_scroll:
|
||||
self._scrollwidget = ba.scrollwidget(
|
||||
parent=self.root_widget,
|
||||
position=(20, 20),
|
||||
highlight=False,
|
||||
color=(0.35, 0.55, 0.15),
|
||||
size=(self._width - 40, self._height - 40),
|
||||
)
|
||||
self._columnwidget = ba.columnwidget(
|
||||
parent=self._scrollwidget, border=2, margin=0
|
||||
)
|
||||
else:
|
||||
self._offset_widget = ba.containerwidget(
|
||||
parent=self.root_widget,
|
||||
position=(30, 15),
|
||||
size=(self._width - 40, self._height),
|
||||
background=False,
|
||||
)
|
||||
self._columnwidget = ba.columnwidget(
|
||||
parent=self._offset_widget, border=2, margin=0
|
||||
)
|
||||
for index, choice in enumerate(choices):
|
||||
if len(choices_display_fin) == len(choices):
|
||||
choice_display_name = choices_display_fin[index]
|
||||
else:
|
||||
choice_display_name = choice
|
||||
inactive = choice in self._choices_disabled
|
||||
wdg = ba.textwidget(
|
||||
parent=self._columnwidget,
|
||||
size=(self._width - 40, 28),
|
||||
on_select_call=ba.Call(self._select, index),
|
||||
click_activate=True,
|
||||
color=(0.5, 0.5, 0.5, 0.5)
|
||||
if inactive
|
||||
else (
|
||||
(0.5, 1, 0.5, 1)
|
||||
if choice == self._current_choice
|
||||
else (0.8, 0.8, 0.8, 1.0)
|
||||
),
|
||||
padding=0,
|
||||
maxwidth=maxwidth,
|
||||
text=choice_display_name,
|
||||
on_activate_call=self._activate,
|
||||
v_align='center',
|
||||
selectable=(not inactive),
|
||||
)
|
||||
if choice == self._current_choice:
|
||||
ba.containerwidget(
|
||||
edit=self._columnwidget,
|
||||
selected_child=wdg,
|
||||
visible_child=wdg,
|
||||
)
|
||||
|
||||
# ok from now on our delegate can be called
|
||||
self._delegate = weakref.ref(delegate)
|
||||
self._done_building = True
|
||||
|
||||
def _select(self, index: int) -> None:
|
||||
if self._done_building:
|
||||
self._current_choice = self._choices[index]
|
||||
|
||||
def _activate(self) -> None:
|
||||
ba.playsound(ba.getsound('swish'))
|
||||
ba.timer(0.05, self._transition_out, timetype=ba.TimeType.REAL)
|
||||
delegate = self._getdelegate()
|
||||
if delegate is not None:
|
||||
# Call this in a timer so it doesn't interfere with us killing
|
||||
# our widgets and whatnot.
|
||||
call = ba.Call(
|
||||
delegate.popup_menu_selected_choice, self, self._current_choice
|
||||
)
|
||||
ba.timer(0, call, timetype=ba.TimeType.REAL)
|
||||
|
||||
def _getdelegate(self) -> Any:
|
||||
return None if self._delegate is None else self._delegate()
|
||||
|
||||
def _transition_out(self) -> None:
|
||||
if not self.root_widget:
|
||||
return
|
||||
if not self._transitioning_out:
|
||||
self._transitioning_out = True
|
||||
delegate = self._getdelegate()
|
||||
if delegate is not None:
|
||||
delegate.popup_menu_closing(self)
|
||||
ba.containerwidget(edit=self.root_widget, transition='out_scale')
|
||||
|
||||
def on_popup_cancel(self) -> None:
|
||||
if not self._transitioning_out:
|
||||
ba.playsound(ba.getsound('swish'))
|
||||
self._transition_out()
|
||||
|
||||
|
||||
class PopupMenu:
|
||||
"""A complete popup-menu control.
|
||||
|
||||
This creates a button and wrangles its pop-up menu.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
parent: ba.Widget,
|
||||
position: tuple[float, float],
|
||||
choices: Sequence[str],
|
||||
current_choice: str | None = None,
|
||||
on_value_change_call: Callable[[str], Any] | None = None,
|
||||
opening_call: Callable[[], Any] | None = None,
|
||||
closing_call: Callable[[], Any] | None = None,
|
||||
width: float = 230.0,
|
||||
maxwidth: float | None = None,
|
||||
scale: float | None = None,
|
||||
choices_disabled: Sequence[str] | None = None,
|
||||
choices_display: Sequence[ba.Lstr] | None = None,
|
||||
button_size: tuple[float, float] = (160.0, 50.0),
|
||||
autoselect: bool = True,
|
||||
):
|
||||
# pylint: disable=too-many-locals
|
||||
if choices_disabled is None:
|
||||
choices_disabled = []
|
||||
if choices_display is None:
|
||||
choices_display = []
|
||||
uiscale = ba.app.ui.uiscale
|
||||
if scale is None:
|
||||
scale = (
|
||||
2.3
|
||||
if uiscale is ba.UIScale.SMALL
|
||||
else 1.65
|
||||
if uiscale is ba.UIScale.MEDIUM
|
||||
else 1.23
|
||||
)
|
||||
if current_choice not in choices:
|
||||
current_choice = None
|
||||
self._choices = list(choices)
|
||||
if not choices:
|
||||
raise TypeError('no choices given')
|
||||
self._choices_display = list(choices_display)
|
||||
self._choices_disabled = list(choices_disabled)
|
||||
self._width = width
|
||||
self._maxwidth = maxwidth
|
||||
self._scale = scale
|
||||
self._current_choice = (
|
||||
current_choice if current_choice is not None else self._choices[0]
|
||||
)
|
||||
self._position = position
|
||||
self._parent = parent
|
||||
if not choices:
|
||||
raise TypeError('Must pass at least one choice')
|
||||
self._parent = parent
|
||||
self._button_size = button_size
|
||||
|
||||
self._button = ba.buttonwidget(
|
||||
parent=self._parent,
|
||||
position=(self._position[0], self._position[1]),
|
||||
autoselect=autoselect,
|
||||
size=self._button_size,
|
||||
scale=1.0,
|
||||
label='',
|
||||
on_activate_call=lambda: ba.timer(
|
||||
0, self._make_popup, timetype=ba.TimeType.REAL
|
||||
),
|
||||
)
|
||||
self._on_value_change_call = None # Don't wanna call for initial set.
|
||||
self._opening_call = opening_call
|
||||
self._autoselect = autoselect
|
||||
self._closing_call = closing_call
|
||||
self.set_choice(self._current_choice)
|
||||
self._on_value_change_call = on_value_change_call
|
||||
self._window_widget: ba.Widget | None = None
|
||||
|
||||
# Complain if we outlive our button.
|
||||
ba.uicleanupcheck(self, self._button)
|
||||
|
||||
def _make_popup(self) -> None:
|
||||
if not self._button:
|
||||
return
|
||||
if self._opening_call:
|
||||
self._opening_call()
|
||||
self._window_widget = PopupMenuWindow(
|
||||
position=self._button.get_screen_space_center(),
|
||||
delegate=self,
|
||||
width=self._width,
|
||||
maxwidth=self._maxwidth,
|
||||
scale=self._scale,
|
||||
choices=self._choices,
|
||||
current_choice=self._current_choice,
|
||||
choices_disabled=self._choices_disabled,
|
||||
choices_display=self._choices_display,
|
||||
).root_widget
|
||||
|
||||
def get_button(self) -> ba.Widget:
|
||||
"""Return the menu's button widget."""
|
||||
return self._button
|
||||
|
||||
def get_window_widget(self) -> ba.Widget | None:
|
||||
"""Return the menu's window widget (or None if nonexistent)."""
|
||||
return self._window_widget
|
||||
|
||||
def popup_menu_selected_choice(
|
||||
self, popup_window: PopupWindow, choice: str
|
||||
) -> None:
|
||||
"""Called when a choice is selected."""
|
||||
del popup_window # Unused here.
|
||||
self.set_choice(choice)
|
||||
if self._on_value_change_call:
|
||||
self._on_value_change_call(choice)
|
||||
|
||||
def popup_menu_closing(self, popup_window: PopupWindow) -> None:
|
||||
"""Called when the menu is closing."""
|
||||
del popup_window # Unused here.
|
||||
if self._button:
|
||||
ba.containerwidget(edit=self._parent, selected_child=self._button)
|
||||
self._window_widget = None
|
||||
if self._closing_call:
|
||||
self._closing_call()
|
||||
|
||||
def set_choice(self, choice: str) -> None:
|
||||
"""Set the selected choice."""
|
||||
self._current_choice = choice
|
||||
displayname: str | ba.Lstr
|
||||
if len(self._choices_display) == len(self._choices):
|
||||
displayname = self._choices_display[self._choices.index(choice)]
|
||||
else:
|
||||
displayname = choice
|
||||
if self._button:
|
||||
ba.buttonwidget(edit=self._button, label=displayname)
|
||||
Loading…
Add table
Add a link
Reference in a new issue