2026-02-14 10:07:07 +01:00
|
|
|
|
# Hard Work (took me 54 hours), and thx for Polish
|
2026-02-07 13:20:52 +01:00
|
|
|
|
# ba_meta require api 9
|
2026-02-14 10:07:07 +01:00
|
|
|
|
"""
|
|
|
|
|
|
Players List v1.7 - An Live Players View.
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
from typing import TYPE_CHECKING
|
2026-02-07 13:20:52 +01:00
|
|
|
|
import babase
|
2026-02-14 10:07:07 +01:00
|
|
|
|
import bauiv1 as bui
|
|
|
|
|
|
import bascenev1 as bs
|
|
|
|
|
|
from bauiv1 import (
|
|
|
|
|
|
containerwidget as cw,
|
|
|
|
|
|
buttonwidget as bw,
|
|
|
|
|
|
textwidget as tw,
|
|
|
|
|
|
checkboxwidget as cbw,
|
|
|
|
|
|
scrollwidget as sw,
|
|
|
|
|
|
get_special_widget as gsw
|
|
|
|
|
|
)
|
|
|
|
|
|
from bauiv1lib.popup import PopupMenu
|
|
|
|
|
|
from colorsys import hsv_to_rgb
|
2026-02-07 13:20:52 +01:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
if TYPE_CHECKING:
|
|
|
|
|
|
from typing import Any
|
2026-02-07 16:26:10 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
plugman = dict(
|
|
|
|
|
|
plugin_name="players_list",
|
|
|
|
|
|
description="A plugin that shows you live players list",
|
|
|
|
|
|
external_url="https://m.youtube.com/drap_bs",
|
|
|
|
|
|
authors=[
|
|
|
|
|
|
{"name": "Drap", "email": "mrunittest@gmail.com", "discord": "drap_bs"}
|
|
|
|
|
|
],
|
|
|
|
|
|
version="1.7.0",
|
|
|
|
|
|
)
|
2026-02-07 16:26:10 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
PLAYERS_ICON = ""
|
2026-02-07 13:20:52 +01:00
|
|
|
|
|
|
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
class ColorPickerWindow:
|
|
|
|
|
|
"""Advanced color picker with custom RGB and preset colors"""
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Preset colors grid (4 rows × 8 columns = 32 colors)
|
|
|
|
|
|
PRESET_COLORS = [
|
|
|
|
|
|
# Row 1 - Reds to Greens
|
2026-02-14 09:07:30 +00:00
|
|
|
|
[(1.2, 0.0, 0.0), (0.65, 0.0, 0.0), (1.2, 0.8, 0.0), (0.89, 0.59, 0.0),
|
|
|
|
|
|
(0.67, 1.0, 0.0), (0.52, 0.78, 0.0), (0.0, 1.2, 0.0), (0.0, 0.78, 0.0)],
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Row 2 - Cyans to Purples
|
2026-02-14 09:07:30 +00:00
|
|
|
|
[(0.0, 1.2, 0.8), (0.0, 0.78, 0.52), (0.0, 0.8, 1.2), (0.0, 0.52, 0.78),
|
|
|
|
|
|
(0.0, 0.0, 1.2), (0.0, 0.0, 0.78), (0.8, 0.0, 1.2), (0.52, 0.0, 0.78)],
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Row 3 - Browns/Tans
|
|
|
|
|
|
[(1.0, 0.82, 0.48), (0.8, 0.62, 0.28), (0.8, 0.8, 0.0), (0.55, 0.55, 0.0)],
|
|
|
|
|
|
]
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def __init__(self, callback, parent_window):
|
|
|
|
|
|
self._callback = callback
|
|
|
|
|
|
self._parent = parent_window
|
|
|
|
|
|
self._width = 1100
|
|
|
|
|
|
self._height = 750
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Current RGB values
|
|
|
|
|
|
self._r = 1.25
|
|
|
|
|
|
self._g = 1.25
|
|
|
|
|
|
self._b = 1.25
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Load saved colors from config
|
|
|
|
|
|
cfg = babase.app.config
|
|
|
|
|
|
self._saved_colors = cfg.get('Players Display - Saved Colors', [])
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
self._root_widget = cw(
|
|
|
|
|
|
parent=gsw('overlay_stack'),
|
|
|
|
|
|
size=(self._width, self._height),
|
|
|
|
|
|
transition='in_scale',
|
|
|
|
|
|
stack_offset=(250.0, -11.0),
|
|
|
|
|
|
color=(0.25, 0.25, 0.25)
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# ═══════════════════════════════════════════════════
|
|
|
|
|
|
# LEFT SECTION - Custom Color Creator
|
|
|
|
|
|
# ═══════════════════════════════════════════════════
|
|
|
|
|
|
left_container = cw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(-531.9, 5.9),
|
|
|
|
|
|
size=(520.0, 750.0),
|
|
|
|
|
|
color=(0.25, 0.25, 0.25),
|
|
|
|
|
|
root_selectable=True
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# "Custom" title
|
|
|
|
|
|
tw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(-306.8, 711.5),
|
|
|
|
|
|
size=(100, 30),
|
|
|
|
|
|
text='Custom',
|
|
|
|
|
|
color=(0.75, 0.75, 0.75),
|
|
|
|
|
|
scale=1.65
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# ═══ RGB Color Displays ═══
|
|
|
|
|
|
# Red display
|
|
|
|
|
|
self._red_display = bw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(-481.5, 602.3),
|
|
|
|
|
|
size=(120.0, 85.0),
|
|
|
|
|
|
label='',
|
|
|
|
|
|
button_type='square',
|
|
|
|
|
|
color=(self._r, 0, 0),
|
|
|
|
|
|
enable_sound=False
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Green display
|
|
|
|
|
|
self._green_display = bw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(-481.5, 516.3),
|
|
|
|
|
|
size=(120.0, 85.0),
|
|
|
|
|
|
label='',
|
|
|
|
|
|
button_type='square',
|
|
|
|
|
|
color=(0, self._g, 0),
|
|
|
|
|
|
enable_sound=False
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Blue display
|
|
|
|
|
|
self._blue_display = bw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(-481.5, 429.3),
|
|
|
|
|
|
size=(120.0, 85.0),
|
|
|
|
|
|
label='',
|
|
|
|
|
|
button_type='square',
|
|
|
|
|
|
color=(0, 0, self._b),
|
|
|
|
|
|
enable_sound=False
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Preview display (gray box)
|
|
|
|
|
|
self._preview_display = bw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(-481.5, 316.3),
|
|
|
|
|
|
size=(120.0, 85.0),
|
|
|
|
|
|
label='',
|
|
|
|
|
|
button_type='square',
|
|
|
|
|
|
color=(self._r, self._g, self._b),
|
|
|
|
|
|
enable_sound=False
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# ═══ RGB Control Buttons ═══
|
|
|
|
|
|
# RED controls
|
|
|
|
|
|
bw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(-358.4, 599.3),
|
|
|
|
|
|
size=(150.0, 90.0),
|
|
|
|
|
|
label='+',
|
|
|
|
|
|
button_type='square',
|
|
|
|
|
|
textcolor=(0.75, 0.0, 0.0),
|
|
|
|
|
|
text_scale=2,
|
|
|
|
|
|
color=(0.15, 0.1, 0.1),
|
|
|
|
|
|
on_activate_call=lambda: self._adjust_color('r', 0.05)
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
bw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(-208.4, 599.3),
|
|
|
|
|
|
size=(130.0, 90.0),
|
|
|
|
|
|
label='−',
|
|
|
|
|
|
button_type='square',
|
|
|
|
|
|
color=(0.15, 0.1, 0.1),
|
|
|
|
|
|
text_scale=2,
|
|
|
|
|
|
textcolor=(0.75, 0, 0),
|
|
|
|
|
|
on_activate_call=lambda: self._adjust_color('r', -0.05)
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# GREEN controls
|
|
|
|
|
|
bw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(-358.4, 509.3),
|
|
|
|
|
|
size=(150.0, 90.0),
|
|
|
|
|
|
label='+',
|
|
|
|
|
|
button_type='square',
|
|
|
|
|
|
textcolor=(0, 0.75, 0.0),
|
|
|
|
|
|
text_scale=2,
|
|
|
|
|
|
color=(0.1, 0.15, 0.1),
|
|
|
|
|
|
on_activate_call=lambda: self._adjust_color('g', 0.05)
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
bw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(-208.4, 509.3),
|
|
|
|
|
|
size=(130.0, 90.0),
|
|
|
|
|
|
label='−',
|
|
|
|
|
|
button_type='square',
|
|
|
|
|
|
color=(0.1, 0.15, 0.1),
|
|
|
|
|
|
text_scale=2,
|
|
|
|
|
|
textcolor=(0, 0.75, 0),
|
|
|
|
|
|
on_activate_call=lambda: self._adjust_color('g', -0.05)
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# BLUE controls
|
|
|
|
|
|
bw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(-358.4, 419.3),
|
|
|
|
|
|
size=(150.0, 90.0),
|
|
|
|
|
|
label='+',
|
|
|
|
|
|
button_type='square',
|
|
|
|
|
|
textcolor=(0, 0.0, 0.75),
|
|
|
|
|
|
text_scale=2,
|
|
|
|
|
|
color=(0.1, 0.1, 0.15),
|
|
|
|
|
|
on_activate_call=lambda: self._adjust_color('b', 0.05)
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
bw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(-208.4, 418.3),
|
|
|
|
|
|
size=(130.0, 90.0),
|
|
|
|
|
|
label='−',
|
|
|
|
|
|
button_type='square',
|
|
|
|
|
|
color=(0.1, 0.1, 0.15),
|
|
|
|
|
|
text_scale=2,
|
|
|
|
|
|
textcolor=(0, 0, 0.75),
|
|
|
|
|
|
on_activate_call=lambda: self._adjust_color('b', -0.05)
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# ═══ RGB Value Displays ═══
|
|
|
|
|
|
self._r_text = tw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(-343.5, 343.4),
|
|
|
|
|
|
size=(100, 30),
|
|
|
|
|
|
text=f'{self._r:.2f}',
|
|
|
|
|
|
color=(1.0, 0.0, 0.0)
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
self._g_text = tw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(-253.5, 343.4),
|
|
|
|
|
|
size=(100, 30),
|
|
|
|
|
|
text=f'{self._g:.2f}',
|
|
|
|
|
|
color=(0.0, 1.0, 0.0)
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
self._b_text = tw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(-153.5, 343.4),
|
|
|
|
|
|
size=(100, 30),
|
|
|
|
|
|
text=f'{self._b:.2f}',
|
|
|
|
|
|
color=(0.0, 0.0, 1.0)
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# ═══ Separator Lines ═══
|
|
|
|
|
|
bui.imagewidget(
|
|
|
|
|
|
texture=bui.gettexture('white'),
|
|
|
|
|
|
opacity=0.6,
|
|
|
|
|
|
position=(-460.6, 406.2),
|
|
|
|
|
|
size=(370.0, 4.0),
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
color=(0.4, 0.4, 0.4)
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
bui.imagewidget(
|
|
|
|
|
|
texture=bui.gettexture('white'),
|
|
|
|
|
|
opacity=0.6,
|
|
|
|
|
|
position=(-478.6, 246.2),
|
|
|
|
|
|
size=(400.0, 4.0),
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
color=(0.4, 0.4, 0.4)
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
bui.imagewidget(
|
|
|
|
|
|
texture=bui.gettexture('white'),
|
|
|
|
|
|
opacity=0.2,
|
|
|
|
|
|
position=(-281.3, 250.8),
|
|
|
|
|
|
size=(4.0, 52.0),
|
|
|
|
|
|
parent=self._root_widget
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# ═══ Action Buttons ═══
|
|
|
|
|
|
# Save button
|
|
|
|
|
|
bw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(-483.2, 255.0),
|
|
|
|
|
|
size=(200.0, 45.0),
|
|
|
|
|
|
label='Save',
|
|
|
|
|
|
button_type='square',
|
|
|
|
|
|
textcolor=(1.2, 1.2, 1.2),
|
|
|
|
|
|
color=(0.0, 0.89, 0.0),
|
|
|
|
|
|
on_activate_call=self._save_color
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Apply button
|
|
|
|
|
|
bw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(-271.2, 256.0),
|
|
|
|
|
|
size=(200.0, 45.0),
|
|
|
|
|
|
label='Apply',
|
|
|
|
|
|
button_type='square',
|
|
|
|
|
|
textcolor=(1.2, 1.2, 1.2),
|
|
|
|
|
|
color=(0.0, 0.89, 0.0),
|
|
|
|
|
|
on_activate_call=self._apply_custom_color
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# ═══ Saved Colors Section ═══
|
|
|
|
|
|
tw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(-476.8, 212.5),
|
|
|
|
|
|
size=(100, 30),
|
|
|
|
|
|
text='Saved',
|
|
|
|
|
|
color=(0.65, 0.65, 0.65),
|
|
|
|
|
|
scale=1.2
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
self._saved_scroll = bui.hscrollwidget(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(-487.9, 63.4),
|
|
|
|
|
|
size=(420.0, 140.0),
|
|
|
|
|
|
capture_arrows=True,
|
|
|
|
|
|
border_opacity=1.2
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# ═══════════════════════════════════════════════════
|
|
|
|
|
|
# RIGHT SECTION - Preset Colors
|
|
|
|
|
|
# ═══════════════════════════════════════════════════
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# "Colors" title
|
|
|
|
|
|
tw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(193.2, 711.5),
|
|
|
|
|
|
size=(100, 30),
|
|
|
|
|
|
text='Colors',
|
|
|
|
|
|
color=(0.75, 0.75, 0.75),
|
|
|
|
|
|
scale=1.65
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
tw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(273.2, 702.5),
|
|
|
|
|
|
size=(100, 30),
|
|
|
|
|
|
text='pick one for your list !',
|
|
|
|
|
|
color=(0.55, 0.55, 0.55),
|
|
|
|
|
|
scale=0.875
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Separator line
|
|
|
|
|
|
bui.imagewidget(
|
|
|
|
|
|
texture=bui.gettexture('white'),
|
|
|
|
|
|
opacity=0.6,
|
|
|
|
|
|
position=(139.4, 396.2),
|
|
|
|
|
|
size=(750.0, 7.5),
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
color=(0.4, 0.4, 0.4)
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
bui.imagewidget(
|
|
|
|
|
|
texture=bui.gettexture('white'),
|
|
|
|
|
|
opacity=0.2,
|
|
|
|
|
|
position=(495.7, 402.8),
|
|
|
|
|
|
size=(7.5, 87.5),
|
|
|
|
|
|
parent=self._root_widget
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Preset colors grid
|
|
|
|
|
|
self._create_preset_colors()
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# "More Colors Soon...." text
|
|
|
|
|
|
tw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(442.6, 347.5),
|
|
|
|
|
|
size=(100, 30),
|
|
|
|
|
|
text='More Colors Soon....',
|
|
|
|
|
|
color=(0.32, 0.32, 0.32),
|
|
|
|
|
|
shadow=False
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Loading spinner
|
|
|
|
|
|
bui.spinnerwidget(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(554.3, 323.2),
|
|
|
|
|
|
size=45.0
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Back button (top left corner)
|
|
|
|
|
|
bw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(-510, 690),
|
|
|
|
|
|
size=(60, 50),
|
|
|
|
|
|
label='<',
|
|
|
|
|
|
color=(0.6, 0.1, 0.1),
|
|
|
|
|
|
textcolor=(1, 0.8, 0.8),
|
|
|
|
|
|
text_scale=1.5,
|
|
|
|
|
|
on_activate_call=self._close
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Load saved colors
|
|
|
|
|
|
self._load_saved_colors()
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
cw(edit=self._root_widget, on_cancel_call=self._close)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _load_saved_colors(self):
|
|
|
|
|
|
"""Load and display saved colors from config"""
|
|
|
|
|
|
if not self._saved_colors:
|
|
|
|
|
|
return
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Create container for saved colors
|
|
|
|
|
|
self._saved_container = bui.containerwidget(
|
|
|
|
|
|
parent=self._saved_scroll,
|
|
|
|
|
|
size=(max(1000, len(self._saved_colors) * 70), 100),
|
|
|
|
|
|
background=False
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Add all saved color buttons
|
|
|
|
|
|
for idx, color in enumerate(self._saved_colors):
|
|
|
|
|
|
x_pos = idx * 70
|
|
|
|
|
|
bw(
|
|
|
|
|
|
parent=self._saved_container,
|
|
|
|
|
|
position=(x_pos, 10),
|
|
|
|
|
|
size=(60, 90),
|
|
|
|
|
|
label='',
|
|
|
|
|
|
button_type='square',
|
|
|
|
|
|
color=color,
|
|
|
|
|
|
on_activate_call=lambda c=color: self._select_saved_color(c)
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _create_preset_colors(self):
|
|
|
|
|
|
"""Create preset color buttons grid"""
|
|
|
|
|
|
# Starting positions
|
|
|
|
|
|
start_x = 88.1
|
|
|
|
|
|
button_size = 80.0
|
|
|
|
|
|
spacing = 20.0
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
row_positions = [589.1, 499.1, 409.1]
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
for row_idx, row_colors in enumerate(self.PRESET_COLORS):
|
|
|
|
|
|
y = row_positions[row_idx]
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
for col_idx, color in enumerate(row_colors):
|
|
|
|
|
|
x = start_x + col_idx * (button_size + spacing)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
bw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(x, y),
|
|
|
|
|
|
size=(button_size, button_size),
|
|
|
|
|
|
label='',
|
|
|
|
|
|
button_type='square',
|
|
|
|
|
|
color=color,
|
|
|
|
|
|
on_activate_call=lambda c=color: self._select_preset_color(c)
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _adjust_color(self, channel: str, amount: float):
|
|
|
|
|
|
"""Adjust RGB values"""
|
|
|
|
|
|
if channel == 'r':
|
|
|
|
|
|
self._r = max(0.0, min(1.5, self._r + amount))
|
|
|
|
|
|
elif channel == 'g':
|
|
|
|
|
|
self._g = max(0.0, min(1.5, self._g + amount))
|
|
|
|
|
|
elif channel == 'b':
|
|
|
|
|
|
self._b = max(0.0, min(1.5, self._b + amount))
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
self._update_displays()
|
|
|
|
|
|
bui.getsound('click01').play()
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _update_displays(self):
|
|
|
|
|
|
"""Update all color displays"""
|
|
|
|
|
|
# Update individual color displays
|
|
|
|
|
|
bw(edit=self._red_display, color=(self._r, 0, 0))
|
|
|
|
|
|
bw(edit=self._green_display, color=(0, self._g, 0))
|
|
|
|
|
|
bw(edit=self._blue_display, color=(0, 0, self._b))
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Update preview
|
|
|
|
|
|
bw(edit=self._preview_display, color=(self._r, self._g, self._b))
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Update RGB text displays
|
|
|
|
|
|
tw(edit=self._r_text, text=f'{self._r:.2f}')
|
|
|
|
|
|
tw(edit=self._g_text, text=f'{self._g:.2f}')
|
|
|
|
|
|
tw(edit=self._b_text, text=f'{self._b:.2f}')
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _save_color(self):
|
|
|
|
|
|
"""Save current color to saved list"""
|
|
|
|
|
|
current_color = (self._r, self._g, self._b)
|
|
|
|
|
|
self._saved_colors.append(current_color)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Save to config
|
|
|
|
|
|
cfg = babase.app.config
|
|
|
|
|
|
cfg['Players Display - Saved Colors'] = self._saved_colors
|
|
|
|
|
|
cfg.commit()
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Create container for saved colors if doesn't exist
|
|
|
|
|
|
if not hasattr(self, '_saved_container'):
|
|
|
|
|
|
self._saved_container = bui.containerwidget(
|
|
|
|
|
|
parent=self._saved_scroll,
|
|
|
|
|
|
size=(1000, 100),
|
|
|
|
|
|
background=False
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Add color button in horizontal line
|
|
|
|
|
|
x_pos = (len(self._saved_colors) - 1) * 70 # 70 = button width + spacing
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
saved_btn = bw(
|
|
|
|
|
|
parent=self._saved_container,
|
|
|
|
|
|
position=(x_pos, 10),
|
|
|
|
|
|
size=(60, 90),
|
|
|
|
|
|
label='',
|
|
|
|
|
|
button_type='square',
|
|
|
|
|
|
color=current_color,
|
|
|
|
|
|
on_activate_call=lambda c=current_color: self._select_saved_color(c)
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
bui.screenmessage('Saved!', color=(0, 1, 0))
|
|
|
|
|
|
bui.getsound('cashRegister').play()
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _select_saved_color(self, color: tuple):
|
|
|
|
|
|
"""Select a saved color and apply it"""
|
|
|
|
|
|
# Update custom RGB values
|
|
|
|
|
|
self._r, self._g, self._b = color
|
|
|
|
|
|
self._update_displays()
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Apply the color
|
|
|
|
|
|
self._callback(color)
|
|
|
|
|
|
bui.screenmessage('Applied!', color=(0, 1, 0))
|
|
|
|
|
|
bui.getsound('ding').play()
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _apply_custom_color(self):
|
|
|
|
|
|
"""Apply the custom RGB color (don't close)"""
|
|
|
|
|
|
self._callback((self._r, self._g, self._b))
|
|
|
|
|
|
bui.screenmessage('Applied!', color=(0, 1, 0))
|
|
|
|
|
|
bui.getsound('dingSmall').play()
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _select_preset_color(self, color: tuple):
|
|
|
|
|
|
"""Select a preset color and close the window"""
|
|
|
|
|
|
self._callback(color)
|
|
|
|
|
|
self._close() # Close the window after selecting
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _close(self):
|
|
|
|
|
|
cw(edit=self._root_widget, transition='out_scale')
|
2026-02-07 13:20:52 +01:00
|
|
|
|
|
|
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
class SettingsWindow:
|
|
|
|
|
|
"""Main settings window with live preview"""
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Design styles
|
|
|
|
|
|
DESIGNS = ['box', 'simple', 'minimal']
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def __init__(self, source_widget=None):
|
|
|
|
|
|
self._width = 1150
|
|
|
|
|
|
self._height = 700
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Get current settings
|
|
|
|
|
|
cfg = babase.app.config
|
|
|
|
|
|
self._temp_show_full = cfg.get('Players Display - Show Full Name', False)
|
|
|
|
|
|
self._temp_name_type = cfg.get('Players Display - Name Type', 'Player Name')
|
|
|
|
|
|
self._temp_color = cfg.get('Players Display - Color', (1, 1, 1))
|
|
|
|
|
|
self._temp_rainbow = cfg.get('Players Display - Rainbow', False)
|
|
|
|
|
|
self._temp_show_id = cfg.get('Players Display - Show Client ID', True)
|
|
|
|
|
|
self._temp_style = cfg.get('Players Display - Style', 'box')
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
self._root_widget = cw(
|
|
|
|
|
|
parent=gsw('overlay_stack'),
|
|
|
|
|
|
size=(self._width, self._height),
|
|
|
|
|
|
transition='in_scale',
|
|
|
|
|
|
stack_offset=(-250.0, -20.0),
|
|
|
|
|
|
color=(0.25, 0.25, 0.25)
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# ═══════════════════════════════════════════════════
|
|
|
|
|
|
# HEADER
|
|
|
|
|
|
# ═══════════════════════════════════════════════════
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Back button
|
|
|
|
|
|
bw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(9.6, 626.3),
|
|
|
|
|
|
size=(135.0, 120.0),
|
|
|
|
|
|
label='«',
|
|
|
|
|
|
color=(1.2, 0.0, 0.0),
|
|
|
|
|
|
textcolor=(1.5, 1.5, 1.5),
|
|
|
|
|
|
text_scale=2,
|
|
|
|
|
|
scale=0.75,
|
|
|
|
|
|
on_activate_call=self._close
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Settings title
|
|
|
|
|
|
tw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(188.3, 661.9),
|
|
|
|
|
|
size=(100, 30),
|
|
|
|
|
|
text='Settings',
|
|
|
|
|
|
color=(0.75, 0.75, 0.75),
|
|
|
|
|
|
scale=2
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
tw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(318.3, 651.9),
|
|
|
|
|
|
size=(100, 30),
|
|
|
|
|
|
text='Customize Your Players List.',
|
|
|
|
|
|
color=(0.55, 0.55, 0.55),
|
|
|
|
|
|
scale=0.85,
|
|
|
|
|
|
shadow=0.4
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Apply button
|
|
|
|
|
|
bw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(877.9, 639.1),
|
|
|
|
|
|
size=(185.0, 100.0),
|
|
|
|
|
|
label='Apply',
|
|
|
|
|
|
color=(0.0, 0.89, 0.0),
|
|
|
|
|
|
textcolor=(1, 1, 1),
|
|
|
|
|
|
on_activate_call=self._apply_changes
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# ═══════════════════════════════════════════════════
|
|
|
|
|
|
# MAIN SCROLL AREA
|
|
|
|
|
|
# ═══════════════════════════════════════════════════
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
scroll = sw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(86.8, 61.7),
|
|
|
|
|
|
size=(1000.0, 569.0),
|
|
|
|
|
|
border_opacity=1.25
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# ═══════════════════════════════════════════════════
|
|
|
|
|
|
# SHOW PLAYER SECTION
|
|
|
|
|
|
# ═══════════════════════════════════════════════════
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
tw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(111.4, 581.4),
|
|
|
|
|
|
size=(100, 30),
|
|
|
|
|
|
text='Show Player',
|
|
|
|
|
|
scale=1.25,
|
|
|
|
|
|
color=(0.85, 0.85, 0.85)
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Separator line
|
|
|
|
|
|
bui.imagewidget(
|
|
|
|
|
|
texture=bui.gettexture('white'),
|
|
|
|
|
|
opacity=0.6,
|
|
|
|
|
|
position=(94.3, 480.9),
|
|
|
|
|
|
size=(975.0, 4.0),
|
|
|
|
|
|
parent=self._root_widget
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Name type label
|
|
|
|
|
|
tw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(95, 535),
|
|
|
|
|
|
size=(0, 0),
|
|
|
|
|
|
text='Name Type:',
|
|
|
|
|
|
color=(0.85, 0.85, 0.85),
|
|
|
|
|
|
h_align='left',
|
|
|
|
|
|
v_align='center',
|
|
|
|
|
|
scale=0.8
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Popup menu for name type selection
|
|
|
|
|
|
PopupMenu(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(95, 487),
|
|
|
|
|
|
choices=['Account Name', 'Player Name'],
|
|
|
|
|
|
current_choice=self._temp_name_type,
|
|
|
|
|
|
on_value_change_call=self._set_name_type,
|
|
|
|
|
|
button_size=(185, 45)
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Vertical separator 1
|
|
|
|
|
|
bui.imagewidget(
|
|
|
|
|
|
texture=bui.gettexture('white'),
|
|
|
|
|
|
opacity=0.45,
|
|
|
|
|
|
position=(275.8, 483.6),
|
|
|
|
|
|
size=(4.0, 90.0),
|
|
|
|
|
|
parent=self._root_widget
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Full Name checkbox (shows both names)
|
|
|
|
|
|
cbw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(288.0, 513.1),
|
|
|
|
|
|
size=(100, 30),
|
|
|
|
|
|
text='Full Name',
|
|
|
|
|
|
color=(0.0, 0.89, 0.0),
|
|
|
|
|
|
scale=1.2,
|
|
|
|
|
|
textcolor=(1, 1, 1),
|
|
|
|
|
|
value=self._temp_show_full,
|
|
|
|
|
|
on_value_change_call=self._on_full_name_change
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Vertical separator 2
|
|
|
|
|
|
bui.imagewidget(
|
|
|
|
|
|
texture=bui.gettexture('white'),
|
|
|
|
|
|
opacity=0.45,
|
|
|
|
|
|
position=(495.8, 483.6),
|
|
|
|
|
|
size=(4.0, 90.0),
|
|
|
|
|
|
parent=self._root_widget
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Client ID checkbox
|
|
|
|
|
|
cbw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(509.9, 510.8),
|
|
|
|
|
|
size=(100, 30),
|
|
|
|
|
|
text='Client ID',
|
|
|
|
|
|
textcolor=(1, 1, 1.0),
|
|
|
|
|
|
color=(0.05, 0.78, 0.05),
|
|
|
|
|
|
scale=1.25,
|
|
|
|
|
|
value=self._temp_show_id,
|
|
|
|
|
|
on_value_change_call=self._on_client_id_change
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# ═══════════════════════════════════════════════════
|
|
|
|
|
|
# COLOR SECTION
|
|
|
|
|
|
# ═══════════════════════════════════════════════════
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
tw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(108.3, 431.9),
|
|
|
|
|
|
size=(100, 30),
|
|
|
|
|
|
text='Color',
|
|
|
|
|
|
color=(0.75, 0.75, 0.75),
|
|
|
|
|
|
scale=1.35
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Separator line
|
|
|
|
|
|
bui.imagewidget(
|
|
|
|
|
|
texture=bui.gettexture('white'),
|
|
|
|
|
|
opacity=0.6,
|
|
|
|
|
|
position=(94.3, 336.9),
|
|
|
|
|
|
size=(975.0, 2.5),
|
|
|
|
|
|
parent=self._root_widget
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Color display button
|
|
|
|
|
|
self._color_display = bw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(97.0, 341.5),
|
|
|
|
|
|
size=(85.0, 85.0),
|
|
|
|
|
|
label='',
|
|
|
|
|
|
color=self._temp_color,
|
|
|
|
|
|
enable_sound=False
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Vertical separator
|
|
|
|
|
|
bui.imagewidget(
|
|
|
|
|
|
texture=bui.gettexture('white'),
|
|
|
|
|
|
opacity=0.45,
|
|
|
|
|
|
position=(192.8, 338.6),
|
|
|
|
|
|
size=(5.0, 80.0),
|
|
|
|
|
|
parent=self._root_widget
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Pick button
|
|
|
|
|
|
bw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(198.6, 343.3),
|
|
|
|
|
|
size=(160.0, 80.0),
|
|
|
|
|
|
label='Pick',
|
|
|
|
|
|
button_type='square',
|
|
|
|
|
|
color=(0.0, 0.0, 0.3555),
|
|
|
|
|
|
textcolor=(0.9, 0.9, 1),
|
|
|
|
|
|
on_activate_call=self._open_color_picker
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Vertical separator
|
|
|
|
|
|
bui.imagewidget(
|
|
|
|
|
|
texture=bui.gettexture('white'),
|
|
|
|
|
|
opacity=0.45,
|
|
|
|
|
|
position=(362.8, 338.6),
|
|
|
|
|
|
size=(5.0, 80.0),
|
|
|
|
|
|
parent=self._root_widget
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Rainbow checkbox
|
|
|
|
|
|
cbw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(378.0, 353.1),
|
|
|
|
|
|
size=(100, 30),
|
|
|
|
|
|
text='Rainbow',
|
|
|
|
|
|
color=(0.0, 0.89, 0.0),
|
|
|
|
|
|
scale=1.2,
|
|
|
|
|
|
textcolor=(1, 1, 1),
|
|
|
|
|
|
value=self._temp_rainbow,
|
|
|
|
|
|
on_value_change_call=self._on_rainbow_change
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# ═══════════════════════════════════════════════════
|
|
|
|
|
|
# DESIGN SECTION
|
|
|
|
|
|
# ═══════════════════════════════════════════════════
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
tw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(108.3, 301.9),
|
|
|
|
|
|
size=(100, 30),
|
|
|
|
|
|
text='Design',
|
|
|
|
|
|
color=(0.75, 0.75, 0.75),
|
|
|
|
|
|
scale=1.35
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Design buttons (3 styles)
|
|
|
|
|
|
self._design_btns = []
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Box style
|
|
|
|
|
|
btn1 = bw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(84.2, 63.8),
|
|
|
|
|
|
size=(350.0, 225.0),
|
|
|
|
|
|
label='BOX Style',
|
|
|
|
|
|
button_type='square',
|
|
|
|
|
|
color=(0.1, 1.2, 0.1) if self._temp_style == 'box' else (0.75, 0.85, 0.75),
|
|
|
|
|
|
on_activate_call=lambda: self._set_style('box')
|
|
|
|
|
|
)
|
|
|
|
|
|
self._design_btns.append(btn1)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Simple style
|
|
|
|
|
|
btn2 = bw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(417.2, 63.8),
|
|
|
|
|
|
size=(350.0, 225.0),
|
|
|
|
|
|
label='Simple Style',
|
|
|
|
|
|
button_type='square',
|
|
|
|
|
|
color=(0.1, 1.2, 0.1) if self._temp_style == 'simple' else (0.75, 0.85, 0.75),
|
|
|
|
|
|
on_activate_call=lambda: self._set_style('simple')
|
|
|
|
|
|
)
|
|
|
|
|
|
self._design_btns.append(btn2)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Minimal style
|
|
|
|
|
|
btn3 = bw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(744.2, 63.8),
|
|
|
|
|
|
size=(350.0, 225.0),
|
|
|
|
|
|
label='Minimal Style',
|
|
|
|
|
|
button_type='square',
|
|
|
|
|
|
color=(0.1, 1.2, 0.1) if self._temp_style == 'minimal' else (0.75, 0.85, 0.75),
|
|
|
|
|
|
on_activate_call=lambda: self._set_style('minimal')
|
|
|
|
|
|
)
|
|
|
|
|
|
self._design_btns.append(btn3)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# ═══════════════════════════════════════════════════
|
|
|
|
|
|
# RESULT SECTION (Preview)
|
|
|
|
|
|
# ═══════════════════════════════════════════════════
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
result_container = cw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(1147.2, 121.9),
|
|
|
|
|
|
size=(450.0, 500.0),
|
|
|
|
|
|
color=(0.25, 0.25, 0.25)
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
tw(
|
|
|
|
|
|
parent=self._root_widget,
|
|
|
|
|
|
position=(1328.3, 581.9),
|
|
|
|
|
|
size=(100, 30),
|
|
|
|
|
|
text='Result',
|
|
|
|
|
|
color=(0.75, 0.75, 0.75),
|
|
|
|
|
|
scale=1.55
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Preview text widget
|
|
|
|
|
|
self._preview_text = tw(
|
|
|
|
|
|
parent=result_container,
|
|
|
|
|
|
position=(225, 350),
|
|
|
|
|
|
size=(0, 0),
|
|
|
|
|
|
text=self._generate_preview_text(),
|
|
|
|
|
|
color=self._temp_color,
|
|
|
|
|
|
h_align='center',
|
|
|
|
|
|
v_align='center',
|
|
|
|
|
|
scale=0.5,
|
|
|
|
|
|
maxwidth=400
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Start preview update loop
|
|
|
|
|
|
self._update_preview()
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
cw(edit=self._root_widget, on_cancel_call=self._close)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _generate_preview_text(self):
|
|
|
|
|
|
"""Generate preview text based on current settings"""
|
|
|
|
|
|
player_count = 3 # Sample count
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Get icon
|
|
|
|
|
|
icon_text = f"{PLAYERS_ICON} " if PLAYERS_ICON else ""
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
"""Generate preview text based on current settings"""
|
|
|
|
|
|
player_count = 3 # Sample count
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
if self._temp_style == 'box':
|
|
|
|
|
|
header = "╔═══════════════════╗\n"
|
|
|
|
|
|
header += f"║ PLAYERS ({player_count}) ║\n"
|
|
|
|
|
|
header += "╠═══════════════════╣\n\n"
|
|
|
|
|
|
footer = "\n\n╚═══════════════════╝"
|
|
|
|
|
|
elif self._temp_style == 'simple':
|
|
|
|
|
|
header = "━━━━━━━━━━━━━━━━━━━\n"
|
|
|
|
|
|
header += f" PLAYERS ({player_count})\n"
|
|
|
|
|
|
header += "━━━━━━━━━━━━━━━━━━━\n\n"
|
|
|
|
|
|
footer = "\n\n━━━━━━━━━━━━━━━━━━━"
|
|
|
|
|
|
else: # minimal
|
|
|
|
|
|
header = f" PLAYERS ({player_count})\n\n"
|
|
|
|
|
|
footer = ""
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Sample names
|
|
|
|
|
|
player_name = "YT!Drap"
|
|
|
|
|
|
account_name = "Drap"
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Build player line based on settings
|
|
|
|
|
|
if self._temp_show_full:
|
|
|
|
|
|
# Full name: show both
|
|
|
|
|
|
name_part = f"{player_name} | {account_name}"
|
|
|
|
|
|
else:
|
|
|
|
|
|
# Show based on name type
|
|
|
|
|
|
if self._temp_name_type == 'Account Name':
|
|
|
|
|
|
name_part = account_name
|
|
|
|
|
|
else:
|
|
|
|
|
|
name_part = player_name
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Add client ID if enabled
|
|
|
|
|
|
if self._temp_show_id:
|
|
|
|
|
|
player_line = f" • {name_part} [#42]"
|
|
|
|
|
|
else:
|
|
|
|
|
|
player_line = f" • {name_part}"
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
return header + player_line + footer
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _update_preview(self):
|
|
|
|
|
|
"""Update preview with rainbow effect if enabled"""
|
|
|
|
|
|
if not hasattr(self, '_preview_text') or not self._preview_text.exists():
|
|
|
|
|
|
return
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Update preview text
|
|
|
|
|
|
tw(edit=self._preview_text, text=self._generate_preview_text())
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Update color (rainbow or static)
|
|
|
|
|
|
if self._temp_rainbow:
|
|
|
|
|
|
# Smooth rainbow loop
|
|
|
|
|
|
if not hasattr(self, '_rainbow_hue'):
|
|
|
|
|
|
self._rainbow_hue = 0.0
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
self._rainbow_hue = (self._rainbow_hue + 0.02) % 1.0
|
|
|
|
|
|
color = hsv_to_rgb(self._rainbow_hue, 1.0, 1.0)
|
|
|
|
|
|
tw(edit=self._preview_text, color=color)
|
|
|
|
|
|
else:
|
|
|
|
|
|
tw(edit=self._preview_text, color=self._temp_color)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Schedule next update
|
|
|
|
|
|
babase.apptimer(0.05, babase.WeakCall(self._update_preview))
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _set_name_type(self, name_type: str):
|
|
|
|
|
|
"""Set name type"""
|
|
|
|
|
|
self._temp_name_type = name_type
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _set_style(self, style: str):
|
|
|
|
|
|
"""Set design style and update button colors"""
|
|
|
|
|
|
self._temp_style = style
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Update all design buttons
|
|
|
|
|
|
for idx, btn in enumerate(self._design_btns):
|
|
|
|
|
|
if self.DESIGNS[idx] == style:
|
|
|
|
|
|
bw(edit=btn, color=(0.1, 1.2, 0.1))
|
|
|
|
|
|
else:
|
|
|
|
|
|
bw(edit=btn, color=(0.75, 0.85, 0.75))
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _on_full_name_change(self, value: bool):
|
|
|
|
|
|
self._temp_show_full = value
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _on_client_id_change(self, value: bool):
|
|
|
|
|
|
self._temp_show_id = value
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _on_rainbow_change(self, value: bool):
|
|
|
|
|
|
self._temp_rainbow = value
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _on_color_selected(self, color: tuple):
|
|
|
|
|
|
self._temp_color = color
|
|
|
|
|
|
bw(edit=self._color_display, color=color)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _open_color_picker(self):
|
|
|
|
|
|
ColorPickerWindow(self._on_color_selected, self)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _apply_changes(self):
|
|
|
|
|
|
"""Apply all changes and save to config"""
|
|
|
|
|
|
cfg = babase.app.config
|
|
|
|
|
|
cfg['Players Display - Show Full Name'] = self._temp_show_full
|
|
|
|
|
|
cfg['Players Display - Name Type'] = self._temp_name_type
|
|
|
|
|
|
cfg['Players Display - Color'] = self._temp_color
|
|
|
|
|
|
cfg['Players Display - Rainbow'] = self._temp_rainbow
|
|
|
|
|
|
cfg['Players Display - Show Client ID'] = self._temp_show_id
|
|
|
|
|
|
cfg['Players Display - Style'] = self._temp_style
|
|
|
|
|
|
cfg.commit()
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
bui.screenmessage('Settings Applied!', color=(0, 1, 0))
|
|
|
|
|
|
bui.getsound('cashRegister').play()
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _close(self):
|
|
|
|
|
|
cw(edit=self._root_widget, transition='out_scale')
|
|
|
|
|
|
|
2026-02-07 16:26:10 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
class PlayersDisplay:
|
|
|
|
|
|
"""Main display class"""
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def __init__(self):
|
|
|
|
|
|
self.container = None
|
|
|
|
|
|
self.rainbow_hue = 0.0
|
|
|
|
|
|
self.current_players = {} # Track: {client_id: (player_name, account_name)}
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def on_app_running(self):
|
|
|
|
|
|
self._update_loop()
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _update_loop(self):
|
|
|
|
|
|
self._update_display()
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Check if rainbow mode is enabled
|
|
|
|
|
|
cfg = babase.app.config
|
|
|
|
|
|
is_rainbow = cfg.get('Players Display - Rainbow', False)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Use faster loop for smooth rainbow, slower for normal updates
|
|
|
|
|
|
delay = 0.05 if is_rainbow else 0.5
|
|
|
|
|
|
babase.apptimer(delay, babase.WeakCall(self._update_loop))
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _get_display_color(self):
|
|
|
|
|
|
cfg = babase.app.config
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
if cfg.get('Players Display - Rainbow', False):
|
|
|
|
|
|
# Smooth rainbow loop with smaller increment
|
|
|
|
|
|
self.rainbow_hue = (self.rainbow_hue + 0.01) % 1.0
|
|
|
|
|
|
return hsv_to_rgb(self.rainbow_hue, 1.0, 1.0)
|
|
|
|
|
|
else:
|
|
|
|
|
|
return cfg.get('Players Display - Color', (0.7, 0.7, 0.7))
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _show_message(self, message: str, color: tuple, duration: float = 1.0):
|
|
|
|
|
|
"""Show a temporary message with fade in/out animation"""
|
|
|
|
|
|
try:
|
|
|
|
|
|
activity = bs.get_foreground_host_activity()
|
|
|
|
|
|
if activity is None:
|
|
|
|
|
|
return
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
with activity.context:
|
|
|
|
|
|
# Create message node
|
|
|
|
|
|
msg_node = bs.newnode(
|
|
|
|
|
|
'text',
|
|
|
|
|
|
attrs={
|
|
|
|
|
|
'text': message,
|
|
|
|
|
|
'scale': 0.65,
|
|
|
|
|
|
'color': color,
|
|
|
|
|
|
'h_attach': 'right',
|
|
|
|
|
|
'v_attach': 'top',
|
|
|
|
|
|
'h_align': 'left',
|
|
|
|
|
|
'v_align': 'top',
|
|
|
|
|
|
'position': (-240, -270), # Below the main list
|
|
|
|
|
|
'flatness': 0.0,
|
|
|
|
|
|
'shadow': 1.2,
|
|
|
|
|
|
'opacity': 0.0 # Start invisible
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Fade in animation (0.2 seconds)
|
|
|
|
|
|
bs.animate(msg_node, 'opacity', {
|
|
|
|
|
|
0.0: 0.0,
|
|
|
|
|
|
0.2: 0.95
|
|
|
|
|
|
})
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Fade out animation (starts after duration)
|
|
|
|
|
|
bs.animate(msg_node, 'opacity', {
|
|
|
|
|
|
duration: 0.95,
|
|
|
|
|
|
duration + 0.3: 0.0
|
|
|
|
|
|
})
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Delete node after animations complete
|
|
|
|
|
|
bs.timer(duration + 0.4, msg_node.delete)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
except Exception:
|
|
|
|
|
|
pass
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _check_player_changes(self, new_players: dict):
|
|
|
|
|
|
"""Check for players joining or leaving
|
|
|
|
|
|
new_players: {client_id: (player_name, account_name)}
|
|
|
|
|
|
"""
|
|
|
|
|
|
new_ids = set(new_players.keys())
|
|
|
|
|
|
old_ids = set(self.current_players.keys())
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Players who joined
|
|
|
|
|
|
joined = new_ids - old_ids
|
|
|
|
|
|
for player_id in joined:
|
|
|
|
|
|
player_name, account_name = new_players[player_id]
|
|
|
|
|
|
message = f"{account_name} joined the server"
|
|
|
|
|
|
color = self._get_display_color()
|
|
|
|
|
|
self._show_message(message, color, duration=1.0)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Players who left
|
|
|
|
|
|
left = old_ids - new_ids
|
|
|
|
|
|
for player_id in left:
|
|
|
|
|
|
player_name, account_name = self.current_players[player_id]
|
|
|
|
|
|
message = f"{player_name} left the server"
|
|
|
|
|
|
color = (1.2, 0.2, 0.2) # Glowing red
|
|
|
|
|
|
self._show_message(message, color, duration=1.0)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Update current players
|
|
|
|
|
|
self.current_players = new_players.copy()
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def _update_display(self):
|
|
|
|
|
|
try:
|
|
|
|
|
|
activity = bs.get_foreground_host_activity()
|
|
|
|
|
|
except Exception:
|
|
|
|
|
|
activity = None
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-07 13:20:52 +01:00
|
|
|
|
if activity is None:
|
2026-02-14 10:07:07 +01:00
|
|
|
|
if self.container is not None:
|
|
|
|
|
|
try:
|
|
|
|
|
|
self.container.delete()
|
|
|
|
|
|
except Exception:
|
|
|
|
|
|
pass
|
2026-02-07 13:20:52 +01:00
|
|
|
|
self.container = None
|
|
|
|
|
|
return
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
cfg = babase.app.config
|
|
|
|
|
|
show_full = cfg.get('Players Display - Show Full Name', False)
|
|
|
|
|
|
name_type = cfg.get('Players Display - Name Type', 'Player Name')
|
|
|
|
|
|
show_client_id = cfg.get('Players Display - Show Client ID', True)
|
|
|
|
|
|
style = cfg.get('Players Display - Style', 'box')
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-07 13:20:52 +01:00
|
|
|
|
player_names = []
|
2026-02-14 10:07:07 +01:00
|
|
|
|
new_players_data = {} # {client_id: (player_name, account_name)}
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-07 13:20:52 +01:00
|
|
|
|
for p in activity.players:
|
2026-02-14 10:07:07 +01:00
|
|
|
|
try:
|
|
|
|
|
|
# Get both player name and account name
|
|
|
|
|
|
player_name = p.getname(full=True)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
try:
|
|
|
|
|
|
account_name = p.sessionplayer.inputdevice.get_v1_account_name(full=True)
|
|
|
|
|
|
if not account_name:
|
|
|
|
|
|
account_name = player_name
|
|
|
|
|
|
except Exception:
|
|
|
|
|
|
account_name = player_name
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Get client ID
|
|
|
|
|
|
try:
|
|
|
|
|
|
client_id = p.sessionplayer.inputdevice.client_id
|
|
|
|
|
|
except Exception:
|
|
|
|
|
|
client_id = id(p) # Fallback to object id
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Store for tracking
|
|
|
|
|
|
new_players_data[client_id] = (player_name, account_name)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Build name based on settings
|
|
|
|
|
|
if show_full:
|
|
|
|
|
|
# Full name: show both names
|
|
|
|
|
|
if player_name != account_name:
|
|
|
|
|
|
name = f"{player_name} | {account_name}"
|
|
|
|
|
|
else:
|
|
|
|
|
|
name = player_name
|
|
|
|
|
|
else:
|
|
|
|
|
|
# Show based on name type
|
|
|
|
|
|
if name_type == 'Account Name':
|
|
|
|
|
|
name = account_name
|
|
|
|
|
|
else:
|
|
|
|
|
|
name = player_name
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Add client ID if enabled
|
|
|
|
|
|
if show_client_id:
|
|
|
|
|
|
try:
|
|
|
|
|
|
player_names.append(f" • {name} [#{client_id}]")
|
|
|
|
|
|
except Exception:
|
|
|
|
|
|
player_names.append(f" • {name}")
|
|
|
|
|
|
else:
|
|
|
|
|
|
player_names.append(f" • {name}")
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
except Exception:
|
|
|
|
|
|
continue
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Check for player changes (join/leave)
|
|
|
|
|
|
self._check_player_changes(new_players_data)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Get player count
|
|
|
|
|
|
player_count = len(player_names)
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Get icon
|
|
|
|
|
|
icon_text = f"{PLAYERS_ICON} " if PLAYERS_ICON else ""
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# Different styles with player count
|
|
|
|
|
|
if style == 'box':
|
|
|
|
|
|
header = "╔═══════════════════╗\n"
|
|
|
|
|
|
header += f"║ PLAYERS ({player_count}) ║\n"
|
|
|
|
|
|
header += "╠═══════════════════╣\n\n"
|
|
|
|
|
|
footer = "\n\n╚═══════════════════╝"
|
|
|
|
|
|
elif style == 'simple':
|
|
|
|
|
|
header = "━━━━━━━━━━━━━━━━━━━\n"
|
|
|
|
|
|
header += f"{icon_text}PLAYERS ({player_count})\n"
|
|
|
|
|
|
header += "━━━━━━━━━━━━━━━━━━━\n\n"
|
|
|
|
|
|
footer = "\n\n━━━━━━━━━━━━━━━━━━━"
|
|
|
|
|
|
else: # minimal
|
|
|
|
|
|
header = f" PLAYERS ({player_count})\n\n"
|
|
|
|
|
|
footer = ""
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
if player_names:
|
|
|
|
|
|
players_str = "\n".join(player_names)
|
|
|
|
|
|
else:
|
|
|
|
|
|
players_str = " ⏳ Waiting...\n No players yet"
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-07 13:20:52 +01:00
|
|
|
|
final_text = header + players_str + footer
|
2026-02-14 10:07:07 +01:00
|
|
|
|
current_color = self._get_display_color()
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
try:
|
|
|
|
|
|
with activity.context:
|
|
|
|
|
|
if self.container is None or not self.container.exists():
|
|
|
|
|
|
self.container = bs.newnode(
|
|
|
|
|
|
'text',
|
|
|
|
|
|
attrs={
|
|
|
|
|
|
'text': final_text,
|
|
|
|
|
|
'scale': 0.7,
|
|
|
|
|
|
'color': current_color,
|
|
|
|
|
|
'h_attach': 'right',
|
|
|
|
|
|
'v_attach': 'top',
|
|
|
|
|
|
'h_align': 'left',
|
|
|
|
|
|
'v_align': 'top',
|
|
|
|
|
|
'position': (-240, -90),
|
|
|
|
|
|
'flatness': 0.0,
|
|
|
|
|
|
'shadow': 1.2,
|
|
|
|
|
|
'opacity': 0.95
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
else:
|
|
|
|
|
|
self.container.text = final_text
|
|
|
|
|
|
self.container.color = current_color
|
|
|
|
|
|
except Exception:
|
|
|
|
|
|
pass
|
2026-02-07 13:20:52 +01:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
# My First Cool Mod ,WooHoo.
|
|
|
|
|
|
# ba_meta export babase.Plugin
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
|
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
class CoolList(babase.Plugin):
|
|
|
|
|
|
"""Main plugin class"""
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def __init__(self):
|
|
|
|
|
|
cfg = babase.app.config
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
if 'Players Display - Show Full Name' not in cfg:
|
|
|
|
|
|
cfg['Players Display - Show Full Name'] = False # Default to single name
|
|
|
|
|
|
if 'Players Display - Name Type' not in cfg:
|
|
|
|
|
|
cfg['Players Display - Name Type'] = 'Player Name' # Default to player name
|
|
|
|
|
|
if 'Players Display - Color' not in cfg:
|
|
|
|
|
|
cfg['Players Display - Color'] = (1, 1, 1)
|
|
|
|
|
|
if 'Players Display - Rainbow' not in cfg:
|
|
|
|
|
|
cfg['Players Display - Rainbow'] = False
|
|
|
|
|
|
if 'Players Display - Show Client ID' not in cfg:
|
|
|
|
|
|
cfg['Players Display - Show Client ID'] = True
|
|
|
|
|
|
if 'Players Display - Style' not in cfg:
|
|
|
|
|
|
cfg['Players Display - Style'] = 'box'
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
cfg.commit()
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
self.display = PlayersDisplay()
|
|
|
|
|
|
self.display.on_app_running()
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def has_settings_ui(self) -> bool:
|
|
|
|
|
|
return True
|
2026-02-14 09:07:30 +00:00
|
|
|
|
|
2026-02-14 10:07:07 +01:00
|
|
|
|
def show_settings_ui(self, source_widget: Any) -> None:
|
|
|
|
|
|
SettingsWindow(source_widget)
|