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))