#include "PanelHeader.hpp" #include #include #include #include #include #include #include #include #include namespace geopro::app { namespace { // ── 专业图标/字号尺寸(统一放大)── constexpr int kHeaderHeight = 42; constexpr int kTitleIcon = 20; // 表头标题图标 constexpr int kActionIcon = 19; // 表头操作按钮图标 constexpr int kTabIcon = 19; // Tab 图标 // 表头统一样式(标准表头 + Tab 表头共用)。 const char* kHeaderQss = "#panelHeader { background:#FFFFFF; border-bottom:1px solid #E6EAF1; }" "#panelTitle { color:#1F2A3D; font-size:14px; font-weight:600; }" "#panelBadge { background:#EAEEF5; color:#5A6B85; border-radius:9px;" " padding:1px 7px; font-size:12px; font-weight:600; }" "QToolButton#panelAction { border:none; border-radius:7px; padding:5px; }" "QToolButton#panelAction:hover { background:#EEF3FB; }" "QToolButton#tabBtn { border:none; border-bottom:2px solid transparent; color:#5A6B85;" " padding:8px 4px; font-size:14px; }" "QToolButton#tabBtn:hover { color:#1F2A3D; }" "QToolButton#tabBtn:checked { color:#1F2A3D; font-weight:600;" " border-bottom:2px solid #2D6CB5; }"; // 数量徽标(默认隐藏,调用方 setText+setVisible 显示)。 QLabel* makeBadge(QWidget* parent) { auto* badge = new QLabel(parent); badge->setObjectName(QStringLiteral("panelBadge")); badge->setAlignment(Qt::AlignCenter); badge->setMinimumWidth(16); badge->setVisible(false); return badge; } // 表头操作按钮(静态占位)。 QToolButton* makeActionButton(QWidget* parent, const HeaderAction& a) { auto* btn = new QToolButton(parent); btn->setObjectName(QStringLiteral("panelAction")); btn->setIcon(makeGlyph(a.first, QColor("#5A6B85"), kActionIcon)); btn->setIconSize(QSize(kActionIcon, kActionIcon)); btn->setCursor(Qt::PointingHandCursor); btn->setToolTip(a.second + QStringLiteral("(占位)")); btn->setAutoRaise(true); return btn; } } // namespace QWidget* buildPanelHeader(Glyph icon, const QString& title, const QVector& actions) { auto* header = new QWidget(); header->setObjectName(QStringLiteral("panelHeader")); header->setFixedHeight(kHeaderHeight); header->setStyleSheet(QString::fromUtf8(kHeaderQss)); auto* lay = new QHBoxLayout(header); lay->setContentsMargins(12, 0, 8, 0); lay->setSpacing(8); auto* iconLbl = new QLabel(header); iconLbl->setPixmap(makeGlyph(icon, QColor("#44546B"), kTitleIcon).pixmap(kTitleIcon, kTitleIcon)); lay->addWidget(iconLbl); auto* titleLbl = new QLabel(title, header); titleLbl->setObjectName(QStringLiteral("panelTitle")); lay->addWidget(titleLbl); lay->addWidget(makeBadge(header)); // 默认隐藏,调用方可经 findChild 更新 lay->addStretch(); for (const auto& a : actions) lay->addWidget(makeActionButton(header, a)); return header; } TabbedPanel buildTabbedPanel(const QVector& tabs, const QVector& actions) { auto* box = new QWidget(); auto* v = new QVBoxLayout(box); v->setContentsMargins(0, 0, 0, 0); v->setSpacing(0); auto* header = new QWidget(box); header->setObjectName(QStringLiteral("panelHeader")); header->setFixedHeight(kHeaderHeight); header->setStyleSheet(QString::fromUtf8(kHeaderQss)); auto* hlay = new QHBoxLayout(header); hlay->setContentsMargins(10, 0, 8, 0); hlay->setSpacing(2); auto* stack = new QStackedWidget(box); auto* group = new QButtonGroup(box); group->setExclusive(true); TabbedPanel result; result.container = box; for (int i = 0; i < tabs.size(); ++i) { const PanelTab& t = tabs[i]; auto* btn = new QToolButton(header); btn->setObjectName(QStringLiteral("tabBtn")); btn->setText(t.title); btn->setIcon(makeGlyph(t.icon, QColor("#5A6B85"), kTabIcon)); btn->setIconSize(QSize(kTabIcon, kTabIcon)); btn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); btn->setCheckable(true); btn->setCursor(Qt::PointingHandCursor); btn->setAutoRaise(true); group->addButton(btn, i); hlay->addWidget(btn); QLabel* badge = nullptr; if (t.hasBadge) { badge = makeBadge(header); hlay->addWidget(badge); } result.badges.append(badge); stack->addWidget(t.content); hlay->addSpacing(10); } hlay->addStretch(); for (const auto& a : actions) hlay->addWidget(makeActionButton(header, a)); QObject::connect(group, &QButtonGroup::idClicked, stack, &QStackedWidget::setCurrentIndex); if (auto* first = group->button(0)) first->setChecked(true); stack->setCurrentIndex(0); v->addWidget(header); v->addWidget(stack, 1); return result; } } // namespace geopro::app