Add CmdForge welcome page to sidebar
- Create welcome_page.py with branded landing page - Add quick action cards for common tasks (Create Tool, Registry, etc.) - Add "CmdForge" entry at top of sidebar navigation - Update page indices for navigation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
88c9a8a1e7
commit
4d9a0e5943
|
|
@ -71,6 +71,7 @@ class MainWindow(QMainWindow):
|
||||||
def _setup_sidebar(self):
|
def _setup_sidebar(self):
|
||||||
"""Set up sidebar navigation items."""
|
"""Set up sidebar navigation items."""
|
||||||
items = [
|
items = [
|
||||||
|
("CmdForge", "Welcome to CmdForge"),
|
||||||
("Tools", "Manage your tools"),
|
("Tools", "Manage your tools"),
|
||||||
("Registry", "Browse and install tools"),
|
("Registry", "Browse and install tools"),
|
||||||
("Providers", "Configure AI providers"),
|
("Providers", "Configure AI providers"),
|
||||||
|
|
@ -80,26 +81,34 @@ class MainWindow(QMainWindow):
|
||||||
font = QFont()
|
font = QFont()
|
||||||
font.setPointSize(11)
|
font.setPointSize(11)
|
||||||
|
|
||||||
for name, tooltip in items:
|
for i, (name, tooltip) in enumerate(items):
|
||||||
item = QListWidgetItem(name)
|
item = QListWidgetItem(name)
|
||||||
item.setFont(font)
|
item.setFont(font)
|
||||||
item.setToolTip(tooltip)
|
item.setToolTip(tooltip)
|
||||||
item.setSizeHint(QSize(180, 48))
|
item.setSizeHint(QSize(180, 48))
|
||||||
|
# Style the CmdForge item differently
|
||||||
|
if i == 0:
|
||||||
|
bold_font = QFont(font)
|
||||||
|
bold_font.setBold(True)
|
||||||
|
item.setFont(bold_font)
|
||||||
self.sidebar.addItem(item)
|
self.sidebar.addItem(item)
|
||||||
|
|
||||||
def _setup_pages(self):
|
def _setup_pages(self):
|
||||||
"""Set up content pages."""
|
"""Set up content pages."""
|
||||||
# Import pages here to avoid circular imports
|
# Import pages here to avoid circular imports
|
||||||
|
from .pages.welcome_page import WelcomePage
|
||||||
from .pages.tools_page import ToolsPage
|
from .pages.tools_page import ToolsPage
|
||||||
from .pages.registry_page import RegistryPage
|
from .pages.registry_page import RegistryPage
|
||||||
from .pages.providers_page import ProvidersPage
|
from .pages.providers_page import ProvidersPage
|
||||||
from .pages.profiles_page import ProfilesPage
|
from .pages.profiles_page import ProfilesPage
|
||||||
|
|
||||||
|
self.welcome_page = WelcomePage(self)
|
||||||
self.tools_page = ToolsPage(self)
|
self.tools_page = ToolsPage(self)
|
||||||
self.registry_page = RegistryPage(self)
|
self.registry_page = RegistryPage(self)
|
||||||
self.providers_page = ProvidersPage(self)
|
self.providers_page = ProvidersPage(self)
|
||||||
self.profiles_page = ProfilesPage(self)
|
self.profiles_page = ProfilesPage(self)
|
||||||
|
|
||||||
|
self.pages.addWidget(self.welcome_page)
|
||||||
self.pages.addWidget(self.tools_page)
|
self.pages.addWidget(self.tools_page)
|
||||||
self.pages.addWidget(self.registry_page)
|
self.pages.addWidget(self.registry_page)
|
||||||
self.pages.addWidget(self.providers_page)
|
self.pages.addWidget(self.providers_page)
|
||||||
|
|
@ -121,10 +130,12 @@ class MainWindow(QMainWindow):
|
||||||
def navigate_to(self, page_name: str):
|
def navigate_to(self, page_name: str):
|
||||||
"""Navigate to a specific page by name."""
|
"""Navigate to a specific page by name."""
|
||||||
page_map = {
|
page_map = {
|
||||||
"tools": 0,
|
"welcome": 0,
|
||||||
"registry": 1,
|
"cmdforge": 0,
|
||||||
"providers": 2,
|
"tools": 1,
|
||||||
"profiles": 3,
|
"registry": 2,
|
||||||
|
"providers": 3,
|
||||||
|
"profiles": 4,
|
||||||
}
|
}
|
||||||
if page_name.lower() in page_map:
|
if page_name.lower() in page_map:
|
||||||
self.sidebar.setCurrentRow(page_map[page_name.lower()])
|
self.sidebar.setCurrentRow(page_map[page_name.lower()])
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
"""GUI pages."""
|
"""GUI pages."""
|
||||||
|
|
||||||
|
from .welcome_page import WelcomePage
|
||||||
from .tools_page import ToolsPage
|
from .tools_page import ToolsPage
|
||||||
from .tool_builder_page import ToolBuilderPage
|
from .tool_builder_page import ToolBuilderPage
|
||||||
from .registry_page import RegistryPage
|
from .registry_page import RegistryPage
|
||||||
from .providers_page import ProvidersPage
|
from .providers_page import ProvidersPage
|
||||||
|
|
||||||
__all__ = ["ToolsPage", "ToolBuilderPage", "RegistryPage", "ProvidersPage"]
|
__all__ = ["WelcomePage", "ToolsPage", "ToolBuilderPage", "RegistryPage", "ProvidersPage"]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,175 @@
|
||||||
|
"""Welcome page - CmdForge landing page."""
|
||||||
|
|
||||||
|
from PySide6.QtWidgets import (
|
||||||
|
QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton,
|
||||||
|
QFrame, QGridLayout, QSizePolicy
|
||||||
|
)
|
||||||
|
from PySide6.QtCore import Qt
|
||||||
|
|
||||||
|
|
||||||
|
class WelcomePage(QWidget):
|
||||||
|
"""CmdForge welcome/landing page."""
|
||||||
|
|
||||||
|
def __init__(self, main_window):
|
||||||
|
super().__init__()
|
||||||
|
self.main_window = main_window
|
||||||
|
self._setup_ui()
|
||||||
|
|
||||||
|
def _setup_ui(self):
|
||||||
|
"""Set up the UI."""
|
||||||
|
layout = QVBoxLayout(self)
|
||||||
|
layout.setContentsMargins(48, 48, 48, 48)
|
||||||
|
layout.setSpacing(32)
|
||||||
|
|
||||||
|
# Top spacer
|
||||||
|
layout.addStretch(1)
|
||||||
|
|
||||||
|
# Logo/title
|
||||||
|
title = QLabel("CmdForge")
|
||||||
|
title.setStyleSheet("""
|
||||||
|
font-size: 48px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #667eea;
|
||||||
|
""")
|
||||||
|
title.setAlignment(Qt.AlignCenter)
|
||||||
|
layout.addWidget(title)
|
||||||
|
|
||||||
|
# Tagline
|
||||||
|
tagline = QLabel("Build AI-powered command-line tools")
|
||||||
|
tagline.setStyleSheet("""
|
||||||
|
font-size: 18px;
|
||||||
|
color: #718096;
|
||||||
|
""")
|
||||||
|
tagline.setAlignment(Qt.AlignCenter)
|
||||||
|
layout.addWidget(tagline)
|
||||||
|
|
||||||
|
layout.addSpacing(24)
|
||||||
|
|
||||||
|
# Quick actions
|
||||||
|
actions_container = QWidget()
|
||||||
|
actions_container.setMaximumWidth(600)
|
||||||
|
actions_layout = QGridLayout(actions_container)
|
||||||
|
actions_layout.setSpacing(16)
|
||||||
|
|
||||||
|
# Create tool card
|
||||||
|
create_card = self._create_action_card(
|
||||||
|
"Create Tool",
|
||||||
|
"Build a new AI-powered command-line tool with prompts, code, and data flow",
|
||||||
|
"New Tool",
|
||||||
|
self._on_create_tool
|
||||||
|
)
|
||||||
|
actions_layout.addWidget(create_card, 0, 0)
|
||||||
|
|
||||||
|
# Browse registry card
|
||||||
|
registry_card = self._create_action_card(
|
||||||
|
"Browse Registry",
|
||||||
|
"Discover and install tools shared by the community",
|
||||||
|
"Open Registry",
|
||||||
|
self._on_browse_registry
|
||||||
|
)
|
||||||
|
actions_layout.addWidget(registry_card, 0, 1)
|
||||||
|
|
||||||
|
# Manage tools card
|
||||||
|
tools_card = self._create_action_card(
|
||||||
|
"My Tools",
|
||||||
|
"View, edit, and run your existing tools",
|
||||||
|
"Open Tools",
|
||||||
|
self._on_open_tools
|
||||||
|
)
|
||||||
|
actions_layout.addWidget(tools_card, 1, 0)
|
||||||
|
|
||||||
|
# Providers card
|
||||||
|
providers_card = self._create_action_card(
|
||||||
|
"AI Providers",
|
||||||
|
"Configure AI backends like Claude, GPT, and custom providers",
|
||||||
|
"Configure",
|
||||||
|
self._on_open_providers
|
||||||
|
)
|
||||||
|
actions_layout.addWidget(providers_card, 1, 1)
|
||||||
|
|
||||||
|
# Center the actions container
|
||||||
|
actions_wrapper = QHBoxLayout()
|
||||||
|
actions_wrapper.addStretch()
|
||||||
|
actions_wrapper.addWidget(actions_container)
|
||||||
|
actions_wrapper.addStretch()
|
||||||
|
layout.addLayout(actions_wrapper)
|
||||||
|
|
||||||
|
# Bottom spacer
|
||||||
|
layout.addStretch(2)
|
||||||
|
|
||||||
|
# Footer
|
||||||
|
footer = QLabel("CmdForge - AI Tool Builder")
|
||||||
|
footer.setStyleSheet("color: #a0aec0; font-size: 12px;")
|
||||||
|
footer.setAlignment(Qt.AlignCenter)
|
||||||
|
layout.addWidget(footer)
|
||||||
|
|
||||||
|
def _create_action_card(self, title: str, description: str, button_text: str, callback) -> QFrame:
|
||||||
|
"""Create an action card widget."""
|
||||||
|
card = QFrame()
|
||||||
|
card.setStyleSheet("""
|
||||||
|
QFrame {
|
||||||
|
background-color: white;
|
||||||
|
border: 1px solid #e2e8f0;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
QFrame:hover {
|
||||||
|
border-color: #667eea;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
card.setMinimumSize(260, 140)
|
||||||
|
|
||||||
|
layout = QVBoxLayout(card)
|
||||||
|
layout.setContentsMargins(16, 16, 16, 16)
|
||||||
|
layout.setSpacing(8)
|
||||||
|
|
||||||
|
# Title
|
||||||
|
title_label = QLabel(title)
|
||||||
|
title_label.setStyleSheet("font-size: 16px; font-weight: 600; color: #2d3748; border: none;")
|
||||||
|
layout.addWidget(title_label)
|
||||||
|
|
||||||
|
# Description
|
||||||
|
desc_label = QLabel(description)
|
||||||
|
desc_label.setWordWrap(True)
|
||||||
|
desc_label.setStyleSheet("font-size: 13px; color: #718096; border: none;")
|
||||||
|
layout.addWidget(desc_label, 1)
|
||||||
|
|
||||||
|
# Button
|
||||||
|
btn = QPushButton(button_text)
|
||||||
|
btn.clicked.connect(callback)
|
||||||
|
btn.setStyleSheet("""
|
||||||
|
QPushButton {
|
||||||
|
background-color: #667eea;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
QPushButton:hover {
|
||||||
|
background-color: #5a67d8;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
layout.addWidget(btn)
|
||||||
|
|
||||||
|
return card
|
||||||
|
|
||||||
|
def _on_create_tool(self):
|
||||||
|
"""Handle create tool action."""
|
||||||
|
self.main_window.open_tool_builder()
|
||||||
|
|
||||||
|
def _on_browse_registry(self):
|
||||||
|
"""Handle browse registry action."""
|
||||||
|
self.main_window.navigate_to("registry")
|
||||||
|
|
||||||
|
def _on_open_tools(self):
|
||||||
|
"""Handle open tools action."""
|
||||||
|
self.main_window.navigate_to("tools")
|
||||||
|
|
||||||
|
def _on_open_providers(self):
|
||||||
|
"""Handle open providers action."""
|
||||||
|
self.main_window.navigate_to("providers")
|
||||||
|
|
||||||
|
def refresh(self):
|
||||||
|
"""Refresh the page (nothing to refresh)."""
|
||||||
|
pass
|
||||||
Loading…
Reference in New Issue