feat(app): TopBar 升级为数据驱动类(工作空间/项目切换信号)
This commit is contained in:
parent
f4ca9bcd38
commit
6e78e50b0b
|
|
@ -127,12 +127,10 @@ QWidget* buildMenuBar(QWidget* parent)
|
|||
return mb;
|
||||
}
|
||||
|
||||
QWidget* buildTopToolBar(QWidget* parent)
|
||||
{
|
||||
auto* bar = new QWidget(parent);
|
||||
bar->setObjectName(QStringLiteral("appToolBar"));
|
||||
bar->setFixedHeight(56);
|
||||
bar->setStyleSheet(QStringLiteral(
|
||||
TopBar::TopBar(QWidget* parent) : QWidget(parent) {
|
||||
setObjectName(QStringLiteral("appToolBar"));
|
||||
setFixedHeight(56);
|
||||
setStyleSheet(QStringLiteral(
|
||||
"#appToolBar { background:#FFFFFF; border-bottom:1px solid #E1E6EE; }"
|
||||
"#topDivider { color:#E1E6EE; }"
|
||||
"#wsSwitcher { color:#1F2A3D; border:none; border-radius:8px; padding:8px 12px;"
|
||||
|
|
@ -146,81 +144,56 @@ QWidget* buildTopToolBar(QWidget* parent)
|
|||
"#userName { color:#1F2A3D; font-size:13px; font-weight:600; }"
|
||||
"#userRole { color:#8A93A3; font-size:11px; }"));
|
||||
|
||||
auto* lay = new QHBoxLayout(bar);
|
||||
auto* lay = new QHBoxLayout(this);
|
||||
lay->setContentsMargins(14, 0, 14, 0);
|
||||
lay->setSpacing(0);
|
||||
|
||||
// ── 工作空间切换(最左):显示当前空间,点击下拉切换 ──
|
||||
auto* wsBtn = new QToolButton(bar);
|
||||
wsBtn->setObjectName(QStringLiteral("wsSwitcher"));
|
||||
wsBtn->setIcon(makeGlyph(Glyph::Workspace, QColor("#2D6CB5"), kWorkspaceIcon));
|
||||
wsBtn->setIconSize(QSize(kWorkspaceIcon, kWorkspaceIcon));
|
||||
wsBtn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||
wsBtn->setPopupMode(QToolButton::InstantPopup);
|
||||
wsBtn->setCursor(Qt::PointingHandCursor);
|
||||
|
||||
auto* wsMenu = new QMenu(bar);
|
||||
auto* wsHeader = wsMenu->addAction(QStringLiteral("切换空间"));
|
||||
wsHeader->setEnabled(false);
|
||||
wsMenu->addSeparator();
|
||||
auto* wsGroup = new QActionGroup(bar);
|
||||
wsGroup->setExclusive(true);
|
||||
const QStringList spaces = {QStringLiteral("个人工作空间"), QStringLiteral("勘探一队"),
|
||||
QStringLiteral("研究院共享")};
|
||||
for (const auto& s : spaces) {
|
||||
auto* a = wsMenu->addAction(s);
|
||||
a->setCheckable(true);
|
||||
wsGroup->addAction(a);
|
||||
if (s == spaces.front()) a->setChecked(true);
|
||||
QObject::connect(a, &QAction::triggered, wsBtn,
|
||||
[wsBtn, s]() { wsBtn->setText(s + QStringLiteral(" ▾")); });
|
||||
}
|
||||
wsBtn->setMenu(wsMenu);
|
||||
wsBtn->setText(spaces.front() + QStringLiteral(" ▾"));
|
||||
lay->addWidget(wsBtn);
|
||||
// 工作空间切换器(数据驱动;初始占位文本,待 setWorkspaces 填充)。
|
||||
wsBtn_ = new QToolButton(this);
|
||||
wsBtn_->setObjectName(QStringLiteral("wsSwitcher"));
|
||||
wsBtn_->setIcon(makeGlyph(Glyph::Workspace, QColor("#2D6CB5"), kWorkspaceIcon));
|
||||
wsBtn_->setIconSize(QSize(kWorkspaceIcon, kWorkspaceIcon));
|
||||
wsBtn_->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||
wsBtn_->setPopupMode(QToolButton::InstantPopup);
|
||||
wsBtn_->setCursor(Qt::PointingHandCursor);
|
||||
wsBtn_->setText(QStringLiteral("(加载中…)"));
|
||||
wsBtn_->setMenu(new QMenu(wsBtn_));
|
||||
lay->addWidget(wsBtn_);
|
||||
|
||||
lay->addSpacing(10);
|
||||
lay->addWidget(makeDivider(bar));
|
||||
lay->addWidget(makeDivider(this));
|
||||
lay->addSpacing(10);
|
||||
|
||||
// ── 项目选择器(与工作空间切换同款样式:无边框 + 图标 + 文本 + 下拉)──
|
||||
auto* projBtn = new QToolButton(bar);
|
||||
projBtn->setObjectName(QStringLiteral("wsSwitcher"));
|
||||
projBtn->setIcon(makeGlyph(Glyph::Folder, QColor("#2D6CB5"), kWorkspaceIcon));
|
||||
projBtn->setIconSize(QSize(kWorkspaceIcon, kWorkspaceIcon));
|
||||
projBtn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||
projBtn->setPopupMode(QToolButton::InstantPopup);
|
||||
projBtn->setCursor(Qt::PointingHandCursor);
|
||||
auto* projMenu = new QMenu(bar);
|
||||
auto* projHeader = projMenu->addAction(QStringLiteral("切换项目"));
|
||||
projHeader->setEnabled(false);
|
||||
projMenu->addSeparator();
|
||||
auto* projCur = projMenu->addAction(QStringLiteral("青海湖北岸勘探项目"));
|
||||
projCur->setCheckable(true);
|
||||
projCur->setChecked(true);
|
||||
projBtn->setMenu(projMenu);
|
||||
projBtn->setText(QStringLiteral("青海湖北岸勘探项目 青海·海北州 ▾"));
|
||||
lay->addWidget(projBtn);
|
||||
// 项目切换器(数据驱动)。
|
||||
projBtn_ = new QToolButton(this);
|
||||
projBtn_->setObjectName(QStringLiteral("wsSwitcher"));
|
||||
projBtn_->setIcon(makeGlyph(Glyph::Folder, QColor("#2D6CB5"), kWorkspaceIcon));
|
||||
projBtn_->setIconSize(QSize(kWorkspaceIcon, kWorkspaceIcon));
|
||||
projBtn_->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||
projBtn_->setPopupMode(QToolButton::InstantPopup);
|
||||
projBtn_->setCursor(Qt::PointingHandCursor);
|
||||
projBtn_->setText(QStringLiteral("(加载中…)"));
|
||||
projBtn_->setMenu(new QMenu(projBtn_));
|
||||
lay->addWidget(projBtn_);
|
||||
|
||||
lay->addStretch();
|
||||
|
||||
// ── 右侧:帮助 / 通知 / 设置(仅图标,悬停显示文本)──
|
||||
lay->addWidget(makeIconButton(bar, Glyph::Help, QStringLiteral("帮助")));
|
||||
lay->addWidget(makeIconButton(bar, Glyph::Bell, QStringLiteral("通知")));
|
||||
lay->addWidget(makeIconButton(bar, Glyph::Gear, QStringLiteral("设置")));
|
||||
lay->addWidget(makeIconButton(this, Glyph::Help, QStringLiteral("帮助")));
|
||||
lay->addWidget(makeIconButton(this, Glyph::Bell, QStringLiteral("通知")));
|
||||
lay->addWidget(makeIconButton(this, Glyph::Gear, QStringLiteral("设置")));
|
||||
lay->addSpacing(10);
|
||||
lay->addWidget(makeDivider(bar));
|
||||
lay->addWidget(makeDivider(this));
|
||||
lay->addSpacing(12);
|
||||
|
||||
// ── 用户:圆形头像 + 姓名/职务 ──
|
||||
auto* avatar = new QLabel(QStringLiteral("ZL"), bar);
|
||||
// 用户区(本轮静态)。
|
||||
auto* avatar = new QLabel(QStringLiteral("ZL"), this);
|
||||
avatar->setObjectName(QStringLiteral("avatar"));
|
||||
avatar->setFixedSize(34, 34);
|
||||
avatar->setAlignment(Qt::AlignCenter);
|
||||
lay->addWidget(avatar);
|
||||
lay->addSpacing(8);
|
||||
|
||||
auto* userBox = new QWidget(bar);
|
||||
auto* userBox = new QWidget(this);
|
||||
auto* userLay = new QVBoxLayout(userBox);
|
||||
userLay->setContentsMargins(0, 0, 0, 0);
|
||||
userLay->setSpacing(0);
|
||||
|
|
@ -231,8 +204,56 @@ QWidget* buildTopToolBar(QWidget* parent)
|
|||
userLay->addWidget(userName);
|
||||
userLay->addWidget(userRole);
|
||||
lay->addWidget(userBox);
|
||||
}
|
||||
|
||||
return bar;
|
||||
void TopBar::setWorkspaces(const std::vector<data::Workspace>& list, const QString& currentId) {
|
||||
auto* menu = new QMenu(wsBtn_);
|
||||
auto* header = menu->addAction(QStringLiteral("切换空间"));
|
||||
header->setEnabled(false);
|
||||
menu->addSeparator();
|
||||
QString currentName;
|
||||
for (const auto& w : list) {
|
||||
const QString id = QString::fromStdString(w.id);
|
||||
const QString name = QString::fromStdString(w.name);
|
||||
auto* a = menu->addAction(name);
|
||||
a->setCheckable(true);
|
||||
a->setChecked(id == currentId);
|
||||
if (id == currentId) currentName = name;
|
||||
QObject::connect(a, &QAction::triggered, this,
|
||||
[this, id]() { emit workspaceSwitchRequested(id); });
|
||||
}
|
||||
if (list.empty()) {
|
||||
auto* none = menu->addAction(QStringLiteral("(暂无空间)"));
|
||||
none->setEnabled(false);
|
||||
}
|
||||
wsBtn_->setMenu(menu);
|
||||
wsBtn_->setText((currentName.isEmpty() ? QStringLiteral("选择空间") : currentName) +
|
||||
QStringLiteral(" ▾"));
|
||||
}
|
||||
|
||||
void TopBar::setProjects(const std::vector<data::ProjectSummary>& list, const QString& currentId) {
|
||||
auto* menu = new QMenu(projBtn_);
|
||||
auto* header = menu->addAction(QStringLiteral("切换项目"));
|
||||
header->setEnabled(false);
|
||||
menu->addSeparator();
|
||||
QString currentName;
|
||||
for (const auto& p : list) {
|
||||
const QString id = QString::fromStdString(p.id);
|
||||
const QString name = QString::fromStdString(p.name);
|
||||
auto* a = menu->addAction(name);
|
||||
a->setCheckable(true);
|
||||
a->setChecked(id == currentId);
|
||||
if (id == currentId) currentName = name;
|
||||
QObject::connect(a, &QAction::triggered, this,
|
||||
[this, id]() { emit projectSwitchRequested(id); });
|
||||
}
|
||||
if (list.empty()) {
|
||||
auto* none = menu->addAction(QStringLiteral("(暂无项目)"));
|
||||
none->setEnabled(false);
|
||||
}
|
||||
projBtn_->setMenu(menu);
|
||||
projBtn_->setText((currentName.isEmpty() ? QStringLiteral("选择项目") : currentName) +
|
||||
QStringLiteral(" ▾"));
|
||||
}
|
||||
|
||||
} // namespace geopro::app
|
||||
|
|
|
|||
|
|
@ -1,19 +1,31 @@
|
|||
#pragma once
|
||||
#include <QWidget>
|
||||
#include <vector>
|
||||
#include "repo/RepoTypes.hpp"
|
||||
|
||||
// 顶部应用区(对齐原型,静态视觉壳):
|
||||
// - buildMenuBar:最上方的菜单栏(视图 / 项目管理 / 业务工具 / 设备,含多级子菜单)。
|
||||
// - buildTopToolBar:菜单栏下方的工具条(工作空间切换 + 项目选择 + 帮助/通知/设置 + 用户)。
|
||||
// 调用方将两者纵向堆叠后经 QMainWindow::setMenuWidget 挂到主窗口顶部。
|
||||
// 菜单/按钮当前为静态占位,后续接真实页面与数据。
|
||||
|
||||
class QWidget;
|
||||
class QToolButton;
|
||||
|
||||
namespace geopro::app {
|
||||
|
||||
// 顶部菜单栏(返回 QWidget*,内部是 QMenuBar;调用方放在最上一行)。
|
||||
QWidget* buildMenuBar(QWidget* parent = nullptr);
|
||||
// 顶部菜单栏(静态,本轮不接真实页面)。
|
||||
QWidget* buildMenuBar(QWidget* parent);
|
||||
|
||||
// 菜单栏下方的工具条(工作空间/项目/帮助/通知/设置/用户)。
|
||||
QWidget* buildTopToolBar(QWidget* parent = nullptr);
|
||||
// 顶部工具条:数据驱动的工作空间/项目切换器 + 右侧图标 + 用户区。
|
||||
class TopBar : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TopBar(QWidget* parent = nullptr);
|
||||
|
||||
void setWorkspaces(const std::vector<data::Workspace>& list, const QString& currentId);
|
||||
void setProjects(const std::vector<data::ProjectSummary>& list, const QString& currentId);
|
||||
|
||||
signals:
|
||||
void workspaceSwitchRequested(const QString& tenantId);
|
||||
void projectSwitchRequested(const QString& projectId);
|
||||
|
||||
private:
|
||||
QToolButton* wsBtn_ = nullptr;
|
||||
QToolButton* projBtn_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace geopro::app
|
||||
|
|
|
|||
|
|
@ -790,7 +790,7 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
|||
topLayout->setContentsMargins(0, 0, 0, 0);
|
||||
topLayout->setSpacing(0);
|
||||
topLayout->addWidget(geopro::app::buildMenuBar(topChrome));
|
||||
topLayout->addWidget(geopro::app::buildTopToolBar(topChrome));
|
||||
topLayout->addWidget(new geopro::app::TopBar(topChrome));
|
||||
window.setMenuWidget(topChrome);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue