feat: Add top navigation tabs - Plugins | Widgets | Settings
NEW UI LAYOUT: - Added tab bar at top of content area with 3 tabs: * 🔌 Plugins - Shows plugin list from sidebar + plugin content * 🎨 Widgets - Widget gallery to add overlay widgets * ⚙️ Settings - All settings in one place WIDGETS TAB FEATURES: - Built-in widgets section with Clock and System Monitor - Each widget has Add button to create overlay - Plugin widgets section (placeholder for plugin-added widgets) - Descriptions for each widget type SETTINGS TAB FEATURES: - Moved settings from dialog into dedicated tab - Sub-tabs: Plugins, Plugin Store, Hotkeys, Appearance, About - Removed Settings button from header (now in tabs) CHANGES: - _create_content_area() replaced with _create_content_area_with_tabs() - Added _switch_tab() method - Added _create_plugins_tab(), _create_widgets_tab(), _create_settings_tab() - Added _create_widget_button() helper - Added _add_clock_widget() and _add_system_monitor_widget() - Removed Settings button from header bar - Removed old _open_settings() dialog approach The UI is now organized with clear navigation between plugins, widgets, and settings via top tabs.
This commit is contained in:
parent
a81e5caf64
commit
ab506cf7fa
|
|
@ -274,7 +274,7 @@ class OverlayWindow(QMainWindow):
|
||||||
self.splitter.addWidget(self.sidebar)
|
self.splitter.addWidget(self.sidebar)
|
||||||
|
|
||||||
# Main content area
|
# Main content area
|
||||||
self.content_area = self._create_content_area()
|
self.content_area = self._create_content_area_with_tabs()
|
||||||
self.splitter.addWidget(self.content_area)
|
self.splitter.addWidget(self.content_area)
|
||||||
|
|
||||||
# Set splitter sizes (sidebar takes ~220px, content takes rest)
|
# Set splitter sizes (sidebar takes ~220px, content takes rest)
|
||||||
|
|
@ -344,14 +344,6 @@ class OverlayWindow(QMainWindow):
|
||||||
self.theme_btn.clicked.connect(self._toggle_theme)
|
self.theme_btn.clicked.connect(self._toggle_theme)
|
||||||
layout.addWidget(self.theme_btn)
|
layout.addWidget(self.theme_btn)
|
||||||
|
|
||||||
# Settings button
|
|
||||||
settings_btn = AnimatedButton("Settings")
|
|
||||||
settings_btn.setStyleSheet(get_button_style('secondary', 'sm'))
|
|
||||||
settings_btn.setAccessibleName("Settings")
|
|
||||||
settings_btn.setAccessibleDescription("Open application settings")
|
|
||||||
settings_btn.clicked.connect(self._open_settings)
|
|
||||||
layout.addWidget(settings_btn)
|
|
||||||
|
|
||||||
# Close button
|
# Close button
|
||||||
close_btn = QPushButton()
|
close_btn = QPushButton()
|
||||||
close_pixmap = self.icon_manager.get_pixmap('close', size=20)
|
close_pixmap = self.icon_manager.get_pixmap('close', size=20)
|
||||||
|
|
@ -1457,3 +1449,305 @@ class OverlayWindow(QMainWindow):
|
||||||
self.hide_overlay()
|
self.hide_overlay()
|
||||||
else:
|
else:
|
||||||
super().keyPressEvent(event)
|
super().keyPressEvent(event)
|
||||||
|
# Add these methods to overlay_window.py
|
||||||
|
|
||||||
|
def _create_content_area_with_tabs(self) -> QWidget:
|
||||||
|
"""Create the main content area with top tabs."""
|
||||||
|
c = get_all_colors()
|
||||||
|
|
||||||
|
content = QWidget()
|
||||||
|
content.setStyleSheet(f"""
|
||||||
|
QWidget {{
|
||||||
|
background-color: {c['bg_primary']};
|
||||||
|
}}
|
||||||
|
""")
|
||||||
|
|
||||||
|
layout = QVBoxLayout(content)
|
||||||
|
layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
layout.setSpacing(0)
|
||||||
|
|
||||||
|
# Tab bar
|
||||||
|
self.tab_bar = QWidget()
|
||||||
|
self.tab_bar.setFixedHeight(48)
|
||||||
|
self.tab_bar.setStyleSheet(f"""
|
||||||
|
QWidget {{
|
||||||
|
background-color: {c['bg_secondary']};
|
||||||
|
border-bottom: 1px solid {c['border_default']};
|
||||||
|
}}
|
||||||
|
""")
|
||||||
|
|
||||||
|
from PyQt6.QtWidgets import QHBoxLayout, QPushButton
|
||||||
|
tab_layout = QHBoxLayout(self.tab_bar)
|
||||||
|
tab_layout.setContentsMargins(16, 0, 16, 0)
|
||||||
|
tab_layout.setSpacing(0)
|
||||||
|
|
||||||
|
# Create tab buttons
|
||||||
|
self.tab_buttons = {}
|
||||||
|
tabs = [
|
||||||
|
('plugins', '🔌 Plugins', 0),
|
||||||
|
('widgets', '🎨 Widgets', 1),
|
||||||
|
('settings', '⚙️ Settings', 2),
|
||||||
|
]
|
||||||
|
|
||||||
|
for tab_id, tab_name, idx in tabs:
|
||||||
|
btn = QPushButton(tab_name)
|
||||||
|
btn.setCheckable(True)
|
||||||
|
btn.setFixedHeight(36)
|
||||||
|
btn.setStyleSheet(f"""
|
||||||
|
QPushButton {{
|
||||||
|
background-color: transparent;
|
||||||
|
color: {c['text_secondary']};
|
||||||
|
font-size: {EU_TYPOGRAPHY['size_sm']};
|
||||||
|
font-weight: {EU_TYPOGRAPHY['weight_medium']};
|
||||||
|
border: none;
|
||||||
|
border-bottom: 3px solid transparent;
|
||||||
|
padding: 0 20px;
|
||||||
|
margin: 0 4px;
|
||||||
|
}}
|
||||||
|
QPushButton:hover {{
|
||||||
|
color: {c['text_primary']};
|
||||||
|
background-color: {c['bg_hover']};
|
||||||
|
}}
|
||||||
|
QPushButton:checked {{
|
||||||
|
color: {c['accent_orange']};
|
||||||
|
border-bottom: 3px solid {c['accent_orange']};
|
||||||
|
font-weight: {EU_TYPOGRAPHY['weight_bold']};
|
||||||
|
}}
|
||||||
|
""")
|
||||||
|
btn.clicked.connect(lambda checked, t=tab_id: self._switch_tab(t))
|
||||||
|
self.tab_buttons[tab_id] = btn
|
||||||
|
tab_layout.addWidget(btn)
|
||||||
|
|
||||||
|
tab_layout.addStretch()
|
||||||
|
layout.addWidget(self.tab_bar)
|
||||||
|
|
||||||
|
# Tab content stack
|
||||||
|
self.tab_stack = QStackedWidget()
|
||||||
|
self.tab_stack.setStyleSheet("background: transparent;")
|
||||||
|
|
||||||
|
# Plugins tab content
|
||||||
|
self.plugins_tab = self._create_plugins_tab()
|
||||||
|
self.tab_stack.addWidget(self.plugins_tab)
|
||||||
|
|
||||||
|
# Widgets tab content
|
||||||
|
self.widgets_tab = self._create_widgets_tab()
|
||||||
|
self.tab_stack.addWidget(self.widgets_tab)
|
||||||
|
|
||||||
|
# Settings tab content
|
||||||
|
self.settings_tab = self._create_settings_tab()
|
||||||
|
self.tab_stack.addWidget(self.settings_tab)
|
||||||
|
|
||||||
|
layout.addWidget(self.tab_stack, 1)
|
||||||
|
|
||||||
|
# Set initial tab
|
||||||
|
self._switch_tab('plugins')
|
||||||
|
|
||||||
|
return content
|
||||||
|
|
||||||
|
def _switch_tab(self, tab_id: str):
|
||||||
|
"""Switch to the specified tab."""
|
||||||
|
# Update button states
|
||||||
|
for btn_id, btn in self.tab_buttons.items():
|
||||||
|
btn.setChecked(btn_id == tab_id)
|
||||||
|
|
||||||
|
# Update stack
|
||||||
|
tab_index = {'plugins': 0, 'widgets': 1, 'settings': 2}
|
||||||
|
if tab_id in tab_index:
|
||||||
|
self.tab_stack.setCurrentIndex(tab_index[tab_id])
|
||||||
|
|
||||||
|
def _create_plugins_tab(self) -> QWidget:
|
||||||
|
"""Create the plugins tab content."""
|
||||||
|
c = get_all_colors()
|
||||||
|
|
||||||
|
tab = QWidget()
|
||||||
|
layout = QVBoxLayout(tab)
|
||||||
|
layout.setContentsMargins(24, 24, 24, 24)
|
||||||
|
layout.setSpacing(0)
|
||||||
|
|
||||||
|
# Plugin stack (where plugin UIs are shown)
|
||||||
|
self.plugin_stack = QStackedWidget()
|
||||||
|
self.plugin_stack.setStyleSheet("background: transparent;")
|
||||||
|
layout.addWidget(self.plugin_stack, 1)
|
||||||
|
|
||||||
|
return tab
|
||||||
|
|
||||||
|
def _create_widgets_tab(self) -> QWidget:
|
||||||
|
"""Create the widgets tab content."""
|
||||||
|
c = get_all_colors()
|
||||||
|
|
||||||
|
tab = QWidget()
|
||||||
|
layout = QVBoxLayout(tab)
|
||||||
|
layout.setContentsMargins(24, 24, 24, 24)
|
||||||
|
layout.setSpacing(16)
|
||||||
|
|
||||||
|
# Header
|
||||||
|
header = QLabel("🎨 Widgets")
|
||||||
|
header.setStyleSheet(f"""
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: {EU_TYPOGRAPHY['weight_bold']};
|
||||||
|
color: {c['text_primary']};
|
||||||
|
""")
|
||||||
|
layout.addWidget(header)
|
||||||
|
|
||||||
|
# Description
|
||||||
|
desc = QLabel("Add overlay widgets to your game. Drag to position, resize, and configure.")
|
||||||
|
desc.setStyleSheet(f"color: {c['text_secondary']}; font-size: 12px;")
|
||||||
|
desc.setWordWrap(True)
|
||||||
|
layout.addWidget(desc)
|
||||||
|
|
||||||
|
# Built-in widgets section
|
||||||
|
builtin_header = QLabel("Built-in Widgets")
|
||||||
|
builtin_header.setStyleSheet(f"""
|
||||||
|
color: {c['text_primary']};
|
||||||
|
font-weight: {EU_TYPOGRAPHY['weight_bold']};
|
||||||
|
font-size: 14px;
|
||||||
|
margin-top: 16px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px solid {c['border_default']};
|
||||||
|
""")
|
||||||
|
layout.addWidget(builtin_header)
|
||||||
|
|
||||||
|
# Clock widget button
|
||||||
|
clock_btn = self._create_widget_button(
|
||||||
|
"⏰ Clock",
|
||||||
|
"A customizable clock with 12/24h format and date display",
|
||||||
|
lambda: self._add_clock_widget()
|
||||||
|
)
|
||||||
|
layout.addWidget(clock_btn)
|
||||||
|
|
||||||
|
# System monitor widget button
|
||||||
|
monitor_btn = self._create_widget_button(
|
||||||
|
"📊 System Monitor",
|
||||||
|
"Monitor CPU and RAM usage in real-time",
|
||||||
|
lambda: self._add_system_monitor_widget()
|
||||||
|
)
|
||||||
|
layout.addWidget(monitor_btn)
|
||||||
|
|
||||||
|
# Plugin widgets section
|
||||||
|
plugin_header = QLabel("Plugin Widgets")
|
||||||
|
plugin_header.setStyleSheet(f"""
|
||||||
|
color: {c['text_primary']};
|
||||||
|
font-weight: {EU_TYPOGRAPHY['weight_bold']};
|
||||||
|
font-size: 14px;
|
||||||
|
margin-top: 24px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px solid {c['border_default']};
|
||||||
|
""")
|
||||||
|
layout.addWidget(plugin_header)
|
||||||
|
|
||||||
|
plugin_info = QLabel("Install plugins from the Plugin Store to add more widgets here.")
|
||||||
|
plugin_info.setStyleSheet(f"color: {c['text_muted']}; font-size: 12px; font-style: italic;")
|
||||||
|
plugin_info.setWordWrap(True)
|
||||||
|
layout.addWidget(plugin_info)
|
||||||
|
|
||||||
|
layout.addStretch()
|
||||||
|
|
||||||
|
return tab
|
||||||
|
|
||||||
|
def _create_widget_button(self, name: str, description: str, callback) -> QFrame:
|
||||||
|
"""Create a widget button card."""
|
||||||
|
c = get_all_colors()
|
||||||
|
|
||||||
|
frame = QFrame()
|
||||||
|
frame.setStyleSheet(f"""
|
||||||
|
QFrame {{
|
||||||
|
background-color: {c['bg_secondary']};
|
||||||
|
border: 1px solid {c['border_default']};
|
||||||
|
border-radius: {EU_SIZES['radius_md']};
|
||||||
|
padding: 4px;
|
||||||
|
}}
|
||||||
|
QFrame:hover {{
|
||||||
|
border-color: {c['accent_orange']};
|
||||||
|
background-color: {c['bg_hover']};
|
||||||
|
}}
|
||||||
|
""")
|
||||||
|
frame.setCursor(Qt.CursorShape.PointingHandCursor)
|
||||||
|
|
||||||
|
layout = QHBoxLayout(frame)
|
||||||
|
layout.setContentsMargins(16, 12, 16, 12)
|
||||||
|
layout.setSpacing(12)
|
||||||
|
|
||||||
|
# Name and description
|
||||||
|
text_layout = QVBoxLayout()
|
||||||
|
|
||||||
|
name_label = QLabel(name)
|
||||||
|
name_label.setStyleSheet(f"""
|
||||||
|
color: {c['text_primary']};
|
||||||
|
font-weight: {EU_TYPOGRAPHY['weight_bold']};
|
||||||
|
font-size: 14px;
|
||||||
|
""")
|
||||||
|
text_layout.addWidget(name_label)
|
||||||
|
|
||||||
|
desc_label = QLabel(description)
|
||||||
|
desc_label.setStyleSheet(f"color: {c['text_secondary']}; font-size: 11px;")
|
||||||
|
desc_label.setWordWrap(True)
|
||||||
|
text_layout.addWidget(desc_label)
|
||||||
|
|
||||||
|
layout.addLayout(text_layout, 1)
|
||||||
|
|
||||||
|
# Add button
|
||||||
|
from PyQt6.QtWidgets import QPushButton
|
||||||
|
add_btn = QPushButton("➕ Add")
|
||||||
|
add_btn.setStyleSheet(get_button_style('primary', 'sm'))
|
||||||
|
add_btn.clicked.connect(callback)
|
||||||
|
layout.addWidget(add_btn)
|
||||||
|
|
||||||
|
return frame
|
||||||
|
|
||||||
|
def _create_settings_tab(self) -> QWidget:
|
||||||
|
"""Create the settings tab content."""
|
||||||
|
from PyQt6.QtWidgets import QScrollArea, QTabWidget
|
||||||
|
c = get_all_colors()
|
||||||
|
|
||||||
|
tab = QWidget()
|
||||||
|
layout = QVBoxLayout(tab)
|
||||||
|
layout.setContentsMargins(24, 24, 24, 24)
|
||||||
|
layout.setSpacing(16)
|
||||||
|
|
||||||
|
# Create tabs for different settings categories
|
||||||
|
settings_tabs = QTabWidget()
|
||||||
|
settings_tabs.setStyleSheet(get_table_style())
|
||||||
|
|
||||||
|
# Plugins settings
|
||||||
|
plugins_tab = self._create_plugins_settings_tab()
|
||||||
|
settings_tabs.addTab(plugins_tab, "🔌 Plugins")
|
||||||
|
|
||||||
|
# Plugin Store
|
||||||
|
store_tab = self._create_plugin_store_tab()
|
||||||
|
settings_tabs.addTab(store_tab, "📦 Plugin Store")
|
||||||
|
|
||||||
|
# Hotkeys
|
||||||
|
hotkeys_tab = self._create_hotkeys_settings_tab()
|
||||||
|
settings_tabs.addTab(hotkeys_tab, "⌨️ Hotkeys")
|
||||||
|
|
||||||
|
# Appearance
|
||||||
|
appearance_tab = self._create_appearance_settings_tab()
|
||||||
|
settings_tabs.addTab(appearance_tab, "🎨 Appearance")
|
||||||
|
|
||||||
|
# About
|
||||||
|
about_tab = self._create_about_tab()
|
||||||
|
settings_tabs.addTab(about_tab, "ℹ️ About")
|
||||||
|
|
||||||
|
layout.addWidget(settings_tabs, 1)
|
||||||
|
|
||||||
|
return tab
|
||||||
|
|
||||||
|
def _add_clock_widget(self):
|
||||||
|
"""Add a clock widget to the overlay."""
|
||||||
|
try:
|
||||||
|
from core.widget_system import ClockWidget
|
||||||
|
widget = ClockWidget()
|
||||||
|
widget.show()
|
||||||
|
print("[Overlay] Clock widget added")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[Overlay] Error adding clock widget: {e}")
|
||||||
|
|
||||||
|
def _add_system_monitor_widget(self):
|
||||||
|
"""Add a system monitor widget to the overlay."""
|
||||||
|
try:
|
||||||
|
from core.widget_system import SystemMonitorWidget
|
||||||
|
widget = SystemMonitorWidget()
|
||||||
|
widget.show()
|
||||||
|
print("[Overlay] System monitor widget added")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[Overlay] Error adding system monitor widget: {e}")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue