TSK Manager v0.10.0
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
# tsk/ui/header.py
|
||||
from typing import Optional
|
||||
|
||||
import pyray as rl
|
||||
|
||||
from openpilot.system.ui.lib.application import gui_app
|
||||
from tsk.common.key_file_manager import KeyFileManager
|
||||
from tsk.ui.layout import Theme # Import Theme
|
||||
|
||||
|
||||
class Header:
|
||||
"""Renders the top navigation bar with title and key status."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initializes the Header."""
|
||||
self.key_manager = KeyFileManager()
|
||||
|
||||
def _draw_title(self, rect: rl.Rectangle, current_menu: int) -> None:
|
||||
"""Draws the title strip."""
|
||||
title_text_color = Theme.brighten_color(Theme.title_bg_color, Theme.brighten_amount)
|
||||
|
||||
menu_name = Theme.menu_names.get(current_menu, "Unknown Menu")
|
||||
full_title_text = "TSK Manager: " + menu_name
|
||||
full_title_text_size = rl.measure_text_ex(gui_app.font(), full_title_text, Theme.title_font_size, 1.0)
|
||||
|
||||
title_text_prefix_size = rl.measure_text_ex(gui_app.font(), "TSK Manager: ", Theme.title_font_size, 1.0)
|
||||
menu_name_x = gui_app.width * Theme.title_prefix_x_offset_percent + title_text_prefix_size.x + Theme.title_x_offset
|
||||
text_y = (self._calculate_height() - full_title_text_size.y) / 2
|
||||
|
||||
rl.draw_text_ex(gui_app.font(), "TSK Manager: ", rl.Vector2(gui_app.width * Theme.title_prefix_x_offset_percent + Theme.title_x_offset, text_y),
|
||||
Theme.title_font_size, 1.0, title_text_color)
|
||||
|
||||
rl.draw_text_ex(gui_app.font(), menu_name, rl.Vector2(menu_name_x, text_y), Theme.title_font_size, 1.0, title_text_color)
|
||||
|
||||
def _draw_navigation_buttons(self, rect: rl.Rectangle, current_menu: int) -> Optional[int]:
|
||||
"""Draws the navigation buttons and handles button clicks."""
|
||||
nav_button_width = self._calculate_nav_button_width()
|
||||
|
||||
left_button_x = 0
|
||||
left_button_rect = rl.Rectangle(left_button_x, 0, nav_button_width, rect.height)
|
||||
right_button_x = gui_app.width - nav_button_width
|
||||
right_button_rect = rl.Rectangle(right_button_x, 0, nav_button_width, rect.height)
|
||||
|
||||
new_menu = None
|
||||
|
||||
def handle_button(button_rect: rl.Rectangle, text: str, target_menu: int) -> Optional[int]:
|
||||
"""Handles drawing, input, and logic for a single navigation button."""
|
||||
mouse_pos = rl.get_mouse_position()
|
||||
is_hovering = rl.check_collision_point_rec(mouse_pos, button_rect)
|
||||
is_pressed = is_hovering and rl.is_mouse_button_pressed(rl.MouseButton.MOUSE_BUTTON_LEFT)
|
||||
|
||||
rl.draw_rectangle_rec(button_rect, Theme.button_color)
|
||||
|
||||
lines = text.splitlines()
|
||||
total_text_height = len(lines) * rl.measure_text_ex(gui_app.font(), "A", Theme.nav_button_font_size, 1.0).y
|
||||
start_y = rect.y + (rect.height - total_text_height) / 2
|
||||
|
||||
for i, line in enumerate(lines):
|
||||
text_size = rl.measure_text_ex(gui_app.font(), line, Theme.nav_button_font_size, 1.0)
|
||||
text_x = button_rect.x + (button_rect.width - text_size.x) / 2
|
||||
text_y = start_y + i * text_size.y
|
||||
font_color = Theme.brighten_color(rl.Color(100, 100, 100, 255), Theme.brighten_amount) # Use the same color as other buttons
|
||||
rl.draw_text_ex(gui_app.font(), line, rl.Vector2(text_x, text_y), Theme.nav_button_font_size, 1.0, font_color)
|
||||
|
||||
if is_pressed:
|
||||
return target_menu
|
||||
return None
|
||||
if current_menu == Theme.menu_reboot:
|
||||
new_menu = handle_button(left_button_rect, Theme.nav_button_text_left, Theme.menu_tools)
|
||||
|
||||
# --- Handle Right Button ---
|
||||
if current_menu == Theme.menu_tools:
|
||||
right_menu = handle_button(right_button_rect, Theme.nav_button_text_right, Theme.menu_reboot)
|
||||
if new_menu is None:
|
||||
new_menu = right_menu
|
||||
|
||||
return new_menu
|
||||
|
||||
def _draw_key_status(self, rect: rl.Rectangle) -> None:
|
||||
"""Draws the key status label."""
|
||||
key_status_text = f"Key installed: {self.key_manager.installed_key}" if self.key_manager.installed_key else "Key not installed"
|
||||
status_text_x = (gui_app.width - rl.measure_text_ex(gui_app.font(), key_status_text, Theme.key_status_font_size, 1.0).x) / 2
|
||||
status_text_y = rect.y + (rect.height - rl.measure_text_ex(gui_app.font(), key_status_text, Theme.key_status_font_size, 1.0).y) / 2 # Use rect.y
|
||||
rl.draw_text_ex(gui_app.font(), key_status_text, rl.Vector2(status_text_x, status_text_y), Theme.key_status_font_size, 1.0, Theme.key_text_color)
|
||||
|
||||
def _calculate_height(self) -> float:
|
||||
"""Calculates the height of the header."""
|
||||
title_text_prefix = "TSK Manager: "
|
||||
return rl.measure_text_ex(gui_app.font(), title_text_prefix, Theme.title_font_size, 1.0).y * 1.5
|
||||
|
||||
def _calculate_nav_button_width(self) -> float:
|
||||
"""Calculates the width of the navigation buttons."""
|
||||
return max(rl.measure_text_ex(gui_app.font(), Theme.nav_button_text_left, Theme.nav_button_font_size, 1.0).x,
|
||||
rl.measure_text_ex(gui_app.font(), Theme.nav_button_text_right, Theme.nav_button_font_size, 1.0).x) + 10
|
||||
|
||||
def render(self, rect: rl.Rectangle, current_menu: int) -> Optional[int]:
|
||||
"""Renders the top strip with the title and menu navigation."""
|
||||
|
||||
title_height = self._calculate_height()
|
||||
key_status_height = Theme.key_status_font_size * 1.5 # Approximate height
|
||||
|
||||
# --- Draw Title Strip ---
|
||||
title_rect = rl.Rectangle(0, 0, gui_app.width, title_height)
|
||||
rl.draw_rectangle_rec(title_rect, Theme.title_bg_color)
|
||||
self._draw_title(rect, current_menu)
|
||||
|
||||
# --- Draw Key Status Strip ---
|
||||
key_status_y = title_height
|
||||
key_status_rect = rl.Rectangle(0, key_status_y, gui_app.width, key_status_height)
|
||||
rl.draw_rectangle_rec(key_status_rect, Theme.nav_bg_color) # Use nav_bg_color for key status
|
||||
self._draw_key_status(key_status_rect)
|
||||
|
||||
# --- Draw Navigation Buttons (Overlapping) ---
|
||||
nav_rect = rl.Rectangle(0, 0, gui_app.width, title_height + key_status_height) # Overlap both
|
||||
new_menu = self._draw_navigation_buttons(nav_rect, current_menu)
|
||||
|
||||
if new_menu is not None:
|
||||
return new_menu
|
||||
return None
|
||||
Reference in New Issue
Block a user