vh-bombsquad-modded-server-.../dist/ba_data/python/bastd/ui/settings/keyboard.py
2024-06-06 19:50:58 +05:30

381 lines
12 KiB
Python

# Released under the MIT License. See LICENSE for details.
#
"""Keyboard settings related UI functionality."""
from __future__ import annotations
from typing import TYPE_CHECKING
import ba
import ba.internal
if TYPE_CHECKING:
from typing import Any
class ConfigKeyboardWindow(ba.Window):
"""Window for configuring keyboards."""
def __init__(self, c: ba.InputDevice, transition: str = 'in_right'):
self._r = 'configKeyboardWindow'
self._input = c
self._name = self._input.name
self._unique_id = self._input.unique_identifier
dname_raw = self._name
if self._unique_id != '#1':
dname_raw += ' ' + self._unique_id.replace('#', 'P')
self._displayname = ba.Lstr(translate=('inputDeviceNames', dname_raw))
self._width = 700
if self._unique_id != '#1':
self._height = 480
else:
self._height = 375
self._spacing = 40
uiscale = ba.app.ui.uiscale
super().__init__(
root_widget=ba.containerwidget(
size=(self._width, self._height),
scale=(
1.6
if uiscale is ba.UIScale.SMALL
else 1.3
if uiscale is ba.UIScale.MEDIUM
else 1.0
),
stack_offset=(0, 5) if uiscale is ba.UIScale.SMALL else (0, 0),
transition=transition,
)
)
self._rebuild_ui()
def _rebuild_ui(self) -> None:
from ba.internal import get_device_value
for widget in self._root_widget.get_children():
widget.delete()
# Fill our temp config with present values.
self._settings: dict[str, int] = {}
for button in [
'buttonJump',
'buttonPunch',
'buttonBomb',
'buttonPickUp',
'buttonStart',
'buttonStart2',
'buttonUp',
'buttonDown',
'buttonLeft',
'buttonRight',
]:
self._settings[button] = get_device_value(self._input, button)
cancel_button = ba.buttonwidget(
parent=self._root_widget,
autoselect=True,
position=(38, self._height - 85),
size=(170, 60),
label=ba.Lstr(resource='cancelText'),
scale=0.9,
on_activate_call=self._cancel,
)
save_button = ba.buttonwidget(
parent=self._root_widget,
autoselect=True,
position=(self._width - 190, self._height - 85),
size=(180, 60),
label=ba.Lstr(resource='saveText'),
scale=0.9,
text_scale=0.9,
on_activate_call=self._save,
)
ba.containerwidget(
edit=self._root_widget,
cancel_button=cancel_button,
start_button=save_button,
)
ba.widget(edit=cancel_button, right_widget=save_button)
ba.widget(edit=save_button, left_widget=cancel_button)
v = self._height - 74.0
ba.textwidget(
parent=self._root_widget,
position=(self._width * 0.5, v + 15),
size=(0, 0),
text=ba.Lstr(
resource=self._r + '.configuringText',
subs=[('${DEVICE}', self._displayname)],
),
color=ba.app.ui.title_color,
h_align='center',
v_align='center',
maxwidth=270,
scale=0.83,
)
v -= 20
if self._unique_id != '#1':
v -= 20
v -= self._spacing
ba.textwidget(
parent=self._root_widget,
position=(0, v + 19),
size=(self._width, 50),
text=ba.Lstr(resource=self._r + '.keyboard2NoteText'),
scale=0.7,
maxwidth=self._width * 0.75,
max_height=110,
color=ba.app.ui.infotextcolor,
h_align='center',
v_align='top',
)
v -= 40
v -= 10
v -= self._spacing * 2.2
v += 25
v -= 42
h_offs = 160
dist = 70
d_color = (0.4, 0.4, 0.8)
self._capture_button(
pos=(h_offs, v + 0.95 * dist),
color=d_color,
button='buttonUp',
texture=ba.gettexture('upButton'),
scale=1.0,
)
self._capture_button(
pos=(h_offs - 1.2 * dist, v),
color=d_color,
button='buttonLeft',
texture=ba.gettexture('leftButton'),
scale=1.0,
)
self._capture_button(
pos=(h_offs + 1.2 * dist, v),
color=d_color,
button='buttonRight',
texture=ba.gettexture('rightButton'),
scale=1.0,
)
self._capture_button(
pos=(h_offs, v - 0.95 * dist),
color=d_color,
button='buttonDown',
texture=ba.gettexture('downButton'),
scale=1.0,
)
if self._unique_id == '#2':
self._capture_button(
pos=(self._width * 0.5, v + 0.1 * dist),
color=(0.4, 0.4, 0.6),
button='buttonStart',
texture=ba.gettexture('startButton'),
scale=0.8,
)
h_offs = self._width - 160
self._capture_button(
pos=(h_offs, v + 0.95 * dist),
color=(0.6, 0.4, 0.8),
button='buttonPickUp',
texture=ba.gettexture('buttonPickUp'),
scale=1.0,
)
self._capture_button(
pos=(h_offs - 1.2 * dist, v),
color=(0.7, 0.5, 0.1),
button='buttonPunch',
texture=ba.gettexture('buttonPunch'),
scale=1.0,
)
self._capture_button(
pos=(h_offs + 1.2 * dist, v),
color=(0.5, 0.2, 0.1),
button='buttonBomb',
texture=ba.gettexture('buttonBomb'),
scale=1.0,
)
self._capture_button(
pos=(h_offs, v - 0.95 * dist),
color=(0.2, 0.5, 0.2),
button='buttonJump',
texture=ba.gettexture('buttonJump'),
scale=1.0,
)
def _capture_button(
self,
pos: tuple[float, float],
color: tuple[float, float, float],
texture: ba.Texture,
button: str,
scale: float = 1.0,
) -> None:
base_size = 79
btn = ba.buttonwidget(
parent=self._root_widget,
autoselect=True,
position=(
pos[0] - base_size * 0.5 * scale,
pos[1] - base_size * 0.5 * scale,
),
size=(base_size * scale, base_size * scale),
texture=texture,
label='',
color=color,
)
# Do this deferred so it shows up on top of other buttons. (ew.)
def doit() -> None:
if not self._root_widget:
return
uiscale = 0.66 * scale * 2.0
maxwidth = 76.0 * scale
txt = ba.textwidget(
parent=self._root_widget,
position=(pos[0] + 0.0 * scale, pos[1] - (57.0 - 18.0) * scale),
color=(1, 1, 1, 0.3),
size=(0, 0),
h_align='center',
v_align='top',
scale=uiscale,
maxwidth=maxwidth,
text=self._input.get_button_name(self._settings[button]),
)
ba.buttonwidget(
edit=btn,
autoselect=True,
on_activate_call=ba.Call(
AwaitKeyboardInputWindow, button, txt, self._settings
),
)
ba.pushcall(doit)
def _cancel(self) -> None:
from bastd.ui.settings.controls import ControlsSettingsWindow
ba.containerwidget(edit=self._root_widget, transition='out_right')
ba.app.ui.set_main_menu_window(
ControlsSettingsWindow(transition='in_left').get_root_widget()
)
def _save(self) -> None:
from bastd.ui.settings.controls import ControlsSettingsWindow
from ba.internal import (
get_input_device_config,
should_submit_debug_info,
master_server_post,
)
ba.containerwidget(edit=self._root_widget, transition='out_right')
ba.playsound(ba.getsound('gunCocking'))
# There's a chance the device disappeared; handle that gracefully.
if not self._input:
return
dst = get_input_device_config(self._input, default=False)
dst2: dict[str, Any] = dst[0][dst[1]]
dst2.clear()
# Store any values that aren't -1.
for key, val in list(self._settings.items()):
if val != -1:
dst2[key] = val
# If we're allowed to phone home, send this config so we can generate
# more defaults in the future.
if should_submit_debug_info():
master_server_post(
'controllerConfig',
{
'ua': ba.app.user_agent_string,
'name': self._name,
'b': ba.app.build_number,
'config': dst2,
'v': 2,
},
)
ba.app.config.apply_and_commit()
ba.app.ui.set_main_menu_window(
ControlsSettingsWindow(transition='in_left').get_root_widget()
)
class AwaitKeyboardInputWindow(ba.Window):
"""Window for capturing a keypress."""
def __init__(self, button: str, ui: ba.Widget, settings: dict):
self._capture_button = button
self._capture_key_ui = ui
self._settings = settings
width = 400
height = 150
uiscale = ba.app.ui.uiscale
super().__init__(
root_widget=ba.containerwidget(
size=(width, height),
transition='in_right',
scale=(
2.0
if uiscale is ba.UIScale.SMALL
else 1.5
if uiscale is ba.UIScale.MEDIUM
else 1.0
),
)
)
ba.textwidget(
parent=self._root_widget,
position=(0, height - 60),
size=(width, 25),
text=ba.Lstr(resource='pressAnyKeyText'),
h_align='center',
v_align='top',
)
self._counter = 5
self._count_down_text = ba.textwidget(
parent=self._root_widget,
h_align='center',
position=(0, height - 110),
size=(width, 25),
color=(1, 1, 1, 0.3),
text=str(self._counter),
)
self._decrement_timer: ba.Timer | None = ba.Timer(
1.0, self._decrement, repeat=True, timetype=ba.TimeType.REAL
)
ba.internal.capture_keyboard_input(ba.WeakCall(self._button_callback))
def __del__(self) -> None:
ba.internal.release_keyboard_input()
def _die(self) -> None:
# This strong-refs us; killing it allows us to die now.
self._decrement_timer = None
if self._root_widget:
ba.containerwidget(edit=self._root_widget, transition='out_left')
def _button_callback(self, event: dict[str, Any]) -> None:
self._settings[self._capture_button] = event['button']
if event['type'] == 'BUTTONDOWN':
bname = event['input_device'].get_button_name(event['button'])
ba.textwidget(edit=self._capture_key_ui, text=bname)
ba.playsound(ba.getsound('gunCocking'))
self._die()
def _decrement(self) -> None:
self._counter -= 1
if self._counter >= 1:
ba.textwidget(edit=self._count_down_text, text=str(self._counter))
else:
self._die()