107 lines
3.6 KiB
Python
107 lines
3.6 KiB
Python
import pygame
|
|
import pygame.gfxdraw
|
|
import sys
|
|
|
|
# --- Colors (Bcut / Dark Theme) ---
|
|
COLOR_BG_ROOT = (19, 19, 19) # #131313
|
|
COLOR_BG_PANEL = (30, 30, 30) # #1E1E1E
|
|
COLOR_BORDER = (44, 44, 44) # #2C2C2C
|
|
COLOR_ACCENT = (255, 71, 87) # #FF4757 (Pinkish Red)
|
|
COLOR_ACCENT_HOVER = (255, 107, 129)
|
|
COLOR_TEXT_MAIN = (224, 224, 224) # #E0E0E0
|
|
COLOR_TEXT_DIM = (128, 128, 128) # #808080
|
|
COLOR_TIMELINE_BG = (25, 25, 25)
|
|
COLOR_TRACK_BG = (35, 35, 35)
|
|
|
|
class FontManager:
|
|
def __init__(self):
|
|
self.fonts = {}
|
|
# Try to find a good Chinese font
|
|
self.font_names = ['Microsoft YaHei', 'SimHei', 'PingFang SC', 'Segoe UI', 'Arial']
|
|
|
|
def get_font(self, size, bold=False):
|
|
key = (size, bold)
|
|
if key in self.fonts:
|
|
return self.fonts[key]
|
|
|
|
font = pygame.font.SysFont(self.font_names, size, bold=bold)
|
|
self.fonts[key] = font
|
|
return font
|
|
|
|
def draw_rounded_rect(surface, rect, color, radius=0.4, border_width=0):
|
|
"""
|
|
Draw a rectangle with rounded corners.
|
|
rect: tuple (x, y, w, h)
|
|
radius: float (0.0 to 1.0) or int (pixels)
|
|
"""
|
|
rect = pygame.Rect(rect)
|
|
color = pygame.Color(*color)
|
|
alpha = color.a
|
|
color.a = 0
|
|
pos = rect.topleft
|
|
rect.topleft = 0,0
|
|
rectangle = pygame.Surface(rect.size,pygame.SRCALPHA)
|
|
|
|
circle = pygame.Surface([min(rect.size)*3]*2,pygame.SRCALPHA)
|
|
pygame.draw.ellipse(circle,(0,0,0),circle.get_rect(),0)
|
|
circle = pygame.transform.smoothscale(circle,[int(min(rect.size)*radius)]*2)
|
|
|
|
radius = rectangle.blit(circle,(0,0))
|
|
radius.bottomright = rect.bottomright
|
|
rectangle.blit(circle,radius)
|
|
radius.topright = rect.topright
|
|
rectangle.blit(circle,radius)
|
|
radius.bottomleft = rect.bottomleft
|
|
rectangle.blit(circle,radius)
|
|
|
|
rectangle.fill((0,0,0),rect.inflate(-radius.w,0))
|
|
rectangle.fill((0,0,0),rect.inflate(0,-radius.h))
|
|
|
|
rectangle.fill(color, special_flags=pygame.BLEND_RGBA_MAX)
|
|
rectangle.fill((255, 255, 255, alpha), special_flags=pygame.BLEND_RGBA_MIN)
|
|
|
|
if border_width > 0:
|
|
# Simple border support (not perfect for rounded)
|
|
pygame.draw.rect(surface, color, pos, width=border_width) # Fallback
|
|
|
|
return surface.blit(rectangle, pos)
|
|
|
|
def draw_pill_btn(surface, text, rect, is_active, font_mgr):
|
|
color = COLOR_ACCENT if is_active else (60, 60, 60)
|
|
text_color = (255, 255, 255) if is_active else COLOR_TEXT_DIM
|
|
|
|
# Draw pill background
|
|
r = rect[3] // 2
|
|
|
|
# Left circle
|
|
pygame.gfxdraw.aacircle(surface, rect[0] + r, rect[1] + r, r, color)
|
|
pygame.gfxdraw.filled_circle(surface, rect[0] + r, rect[1] + r, r, color)
|
|
# Right circle
|
|
pygame.gfxdraw.aacircle(surface, rect[0] + rect[2] - r, rect[1] + r, r, color)
|
|
pygame.gfxdraw.filled_circle(surface, rect[0] + rect[2] - r, rect[1] + r, r, color)
|
|
# Center rect
|
|
pygame.draw.rect(surface, color, (rect[0] + r, rect[1], rect[2] - 2*r, rect[3]))
|
|
|
|
# Text
|
|
font = font_mgr.get_font(12, bold=True)
|
|
txt_surf = font.render(text, True, text_color)
|
|
text_rect = txt_surf.get_rect(center=(rect[0] + rect[2]//2, rect[1] + rect[3]//2))
|
|
surface.blit(txt_surf, text_rect)
|
|
|
|
def draw_icon_play(surface, center, size, color):
|
|
x, y = center
|
|
points = [
|
|
(x - size//3, y - size//2),
|
|
(x - size//3, y + size//2),
|
|
(x + size//2, y)
|
|
]
|
|
pygame.draw.polygon(surface, color, points)
|
|
|
|
def draw_icon_pause(surface, center, size, color):
|
|
x, y = center
|
|
w = size // 3
|
|
h = size
|
|
pygame.draw.rect(surface, color, (x - w - 2, y - h//2, w, h))
|
|
pygame.draw.rect(surface, color, (x + 2, y - h//2, w, h))
|
|
|