refactor/pure-qt-ui #3
|
|
@ -81,7 +81,7 @@ QWidget* buildPanelHeader(Glyph icon, const QString& title, const QVector<Header
|
||||||
auto* header = new QWidget();
|
auto* header = new QWidget();
|
||||||
header->setObjectName(QStringLiteral("panelHeader"));
|
header->setObjectName(QStringLiteral("panelHeader"));
|
||||||
header->setFixedHeight(kHeaderHeight);
|
header->setFixedHeight(kHeaderHeight);
|
||||||
header->setStyleSheet(headerQss());
|
geopro::app::applyThemedStyleSheet(header, headerQss());
|
||||||
|
|
||||||
auto* lay = new QHBoxLayout(header);
|
auto* lay = new QHBoxLayout(header);
|
||||||
lay->setContentsMargins(12, 0, 8, 0);
|
lay->setContentsMargins(12, 0, 8, 0);
|
||||||
|
|
@ -114,7 +114,7 @@ TabbedPanel buildTabbedPanel(const QVector<PanelTab>& tabs, const QVector<Header
|
||||||
auto* header = new QWidget(box);
|
auto* header = new QWidget(box);
|
||||||
header->setObjectName(QStringLiteral("panelHeader"));
|
header->setObjectName(QStringLiteral("panelHeader"));
|
||||||
header->setFixedHeight(kHeaderHeight);
|
header->setFixedHeight(kHeaderHeight);
|
||||||
header->setStyleSheet(headerQss());
|
geopro::app::applyThemedStyleSheet(header, headerQss());
|
||||||
auto* hlay = new QHBoxLayout(header);
|
auto* hlay = new QHBoxLayout(header);
|
||||||
hlay->setContentsMargins(10, 0, 8, 0);
|
hlay->setContentsMargins(10, 0, 8, 0);
|
||||||
hlay->setSpacing(2);
|
hlay->setSpacing(2);
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,10 @@
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
#include <QFont>
|
#include <QFont>
|
||||||
|
#include <QObject>
|
||||||
#include <QPalette>
|
#include <QPalette>
|
||||||
#include <QStyleFactory>
|
#include <QStyleFactory>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
#include <ElaDef.h>
|
#include <ElaDef.h>
|
||||||
#include <ElaTheme.h>
|
#include <ElaTheme.h>
|
||||||
|
|
@ -407,6 +409,10 @@ const RoleMap kRoleMap[] = {
|
||||||
{"#E6EBF3", ElaThemeType::BasicDisable}, // 进度条底
|
{"#E6EBF3", ElaThemeType::BasicDisable}, // 进度条底
|
||||||
{"#EAF1FB", ElaThemeType::BasicHover}, // 工具按钮选中底
|
{"#EAF1FB", ElaThemeType::BasicHover}, // 工具按钮选中底
|
||||||
{"#C0392B", ElaThemeType::StatusDanger}, // 危险
|
{"#C0392B", ElaThemeType::StatusDanger}, // 危险
|
||||||
|
// 内联 chrome(TopBar/PanelHeader)额外用到的令牌:
|
||||||
|
{"#EEF1F5", ElaThemeType::BasicBorder}, // 菜单栏底边线
|
||||||
|
{"#E6EAF1", ElaThemeType::BasicBorder}, // 面板表头底边线
|
||||||
|
{"#EAEEF5", ElaThemeType::BasicBaseDeep}, // 面板徽标底
|
||||||
};
|
};
|
||||||
|
|
||||||
QColor roleColor(bool dark, ElaThemeType::ThemeColor role)
|
QColor roleColor(bool dark, ElaThemeType::ThemeColor role)
|
||||||
|
|
@ -414,15 +420,21 @@ QColor roleColor(bool dark, ElaThemeType::ThemeColor role)
|
||||||
return eTheme->getThemeColor(dark ? ElaThemeType::Dark : ElaThemeType::Light, role);
|
return eTheme->getThemeColor(dark ? ElaThemeType::Dark : ElaThemeType::Light, role);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 当前模式的全局 QSS:按 kRoleMap 把设计稿色令牌换成 ElaTheme 真实颜色(明/暗同源于外壳)。
|
// 把一段设计稿 QSS 按 ElaTheme 当前模式着色(浅色令牌→真实角色色)。供全局与内联样式共用。
|
||||||
QString styleSheetForMode(bool dark)
|
QString themedQss(const QString& designQss, bool dark)
|
||||||
{
|
{
|
||||||
QString s = QString::fromUtf8(kStyleSheet);
|
QString s = designQss;
|
||||||
for (const auto& rm : kRoleMap)
|
for (const auto& rm : kRoleMap)
|
||||||
s.replace(QLatin1String(rm.token), roleColor(dark, rm.role).name());
|
s.replace(QLatin1String(rm.token), roleColor(dark, rm.role).name());
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 当前模式的全局 QSS。
|
||||||
|
QString styleSheetForMode(bool dark)
|
||||||
|
{
|
||||||
|
return themedQss(QString::fromUtf8(kStyleSheet), dark);
|
||||||
|
}
|
||||||
|
|
||||||
// 调色板同样取自 ElaTheme,让无 QSS 覆盖处的标准控件也与外壳一致。
|
// 调色板同样取自 ElaTheme,让无 QSS 覆盖处的标准控件也与外壳一致。
|
||||||
QPalette buildPalette(bool dark)
|
QPalette buildPalette(bool dark)
|
||||||
{
|
{
|
||||||
|
|
@ -482,4 +494,19 @@ void applyTheme(QApplication& app)
|
||||||
applyThemeMode(app, false);
|
applyThemeMode(app, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isDarkTheme()
|
||||||
|
{
|
||||||
|
return eTheme->getThemeMode() == ElaThemeType::Dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
void applyThemedStyleSheet(QWidget* w, const QString& designQss)
|
||||||
|
{
|
||||||
|
if (!w) return;
|
||||||
|
w->setStyleSheet(themedQss(designQss, isDarkTheme()));
|
||||||
|
QObject::connect(eTheme, &ElaTheme::themeModeChanged, w,
|
||||||
|
[w, designQss](ElaThemeType::ThemeMode m) {
|
||||||
|
w->setStyleSheet(themedQss(designQss, m == ElaThemeType::Dark));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace geopro::app
|
} // namespace geopro::app
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,10 @@
|
||||||
// 文字 #1F2A3D 次要文字 #5A6B85 边框 #D5DBE5 强边框 #C2CCDA
|
// 文字 #1F2A3D 次要文字 #5A6B85 边框 #D5DBE5 强边框 #C2CCDA
|
||||||
// 危险 #C0392B
|
// 危险 #C0392B
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
class QApplication;
|
class QApplication;
|
||||||
|
class QWidget;
|
||||||
|
|
||||||
namespace geopro::app {
|
namespace geopro::app {
|
||||||
|
|
||||||
|
|
@ -87,4 +90,12 @@ void applyThemeMode(QApplication& app, bool dark);
|
||||||
// 浅色主题快捷入口(= applyThemeMode(app,false))。经典壳启动调用一次。
|
// 浅色主题快捷入口(= applyThemeMode(app,false))。经典壳启动调用一次。
|
||||||
void applyTheme(QApplication& app);
|
void applyTheme(QApplication& app);
|
||||||
|
|
||||||
|
// 当前 ElaTheme 是否暗色(供内联样式判断)。
|
||||||
|
bool isDarkTheme();
|
||||||
|
|
||||||
|
// 把一段「浅色设计稿 QSS」按当前 ElaTheme 配色着色应用到 widget,并随明/暗切换自动重着色。
|
||||||
|
// 用于 TopBar/PanelHeader/浮层 等带内联 setStyleSheet 的自定义 chrome——让它们也跟随主题
|
||||||
|
// (设计稿里用浅色令牌 #1F2A3D/#FFFFFF/#2D6CB5… 书写即可,与全局 QSS 同一套角色映射)。
|
||||||
|
void applyThemedStyleSheet(QWidget* w, const QString& designQss);
|
||||||
|
|
||||||
} // namespace geopro::app
|
} // namespace geopro::app
|
||||||
|
|
|
||||||
|
|
@ -116,12 +116,13 @@ QWidget* buildMenuBar(QWidget* parent)
|
||||||
auto* mb = new QMenuBar(parent);
|
auto* mb = new QMenuBar(parent);
|
||||||
mb->setObjectName(QStringLiteral("appMenuBar"));
|
mb->setObjectName(QStringLiteral("appMenuBar"));
|
||||||
// 自带样式(覆盖全局),加大字号/内边距,专业观感。
|
// 自带样式(覆盖全局),加大字号/内边距,专业观感。
|
||||||
mb->setStyleSheet(QStringLiteral(
|
geopro::app::applyThemedStyleSheet(
|
||||||
"#appMenuBar { background:#FFFFFF; border-bottom:1px solid #EEF1F5; padding:2px 8px; }"
|
mb, QStringLiteral(
|
||||||
"#appMenuBar::item { padding:7px 14px; border-radius:6px; font-size:%1px; color:#1F2A3D; }"
|
"#appMenuBar { background:#FFFFFF; border-bottom:1px solid #EEF1F5; padding:2px 8px; }"
|
||||||
"#appMenuBar::item:selected { background:#EAF1FB; color:#2D6CB5; }"
|
"#appMenuBar::item { padding:7px 14px; border-radius:6px; font-size:%1px; color:#1F2A3D; }"
|
||||||
"#appMenuBar::item:pressed { background:#DCE6F4; }")
|
"#appMenuBar::item:selected { background:#EAF1FB; color:#2D6CB5; }"
|
||||||
.arg(type::kBody));
|
"#appMenuBar::item:pressed { background:#DCE6F4; }")
|
||||||
|
.arg(type::kBody));
|
||||||
mb->addMenu(buildViewMenu(mb));
|
mb->addMenu(buildViewMenu(mb));
|
||||||
mb->addMenu(buildProjectMenu(mb));
|
mb->addMenu(buildProjectMenu(mb));
|
||||||
mb->addMenu(buildToolsMenu(mb));
|
mb->addMenu(buildToolsMenu(mb));
|
||||||
|
|
@ -134,25 +135,26 @@ TopBar::TopBar(QWidget* parent) : QWidget(parent) {
|
||||||
setFixedHeight(56);
|
setFixedHeight(56);
|
||||||
// 字号引用 Theme 排版令牌:工作空间切换器=title(15)、头像/用户名=body·label(13)、
|
// 字号引用 Theme 排版令牌:工作空间切换器=title(15)、头像/用户名=body·label(13)、
|
||||||
// 角色名=caption(12)。原 11px 角色名上调到 12,去掉只差 1px 的糊层级。
|
// 角色名=caption(12)。原 11px 角色名上调到 12,去掉只差 1px 的糊层级。
|
||||||
setStyleSheet(QStringLiteral(
|
geopro::app::applyThemedStyleSheet(
|
||||||
"#appToolBar { background:#FFFFFF; border-bottom:1px solid #E1E6EE; }"
|
this, QStringLiteral(
|
||||||
"#topDivider { color:#E1E6EE; }"
|
"#appToolBar { background:#FFFFFF; border-bottom:1px solid #E1E6EE; }"
|
||||||
"#wsSwitcher { color:#1F2A3D; border:none; border-radius:8px; padding:8px 12px;"
|
"#topDivider { color:#E1E6EE; }"
|
||||||
" font-size:%1px; font-weight:%5; }"
|
"#wsSwitcher { color:#1F2A3D; border:none; border-radius:8px; padding:8px 12px;"
|
||||||
"#wsSwitcher:hover { background:#EEF3FB; }"
|
" font-size:%1px; font-weight:%5; }"
|
||||||
"QToolButton#iconBtn { border:none; border-radius:8px; padding:8px; }"
|
"#wsSwitcher:hover { background:#EEF3FB; }"
|
||||||
"QToolButton#iconBtn:hover { background:#EEF3FB; }"
|
"QToolButton#iconBtn { border:none; border-radius:8px; padding:8px; }"
|
||||||
"QToolButton::menu-indicator { image:none; }"
|
"QToolButton#iconBtn:hover { background:#EEF3FB; }"
|
||||||
"#avatar { background:#2D6CB5; color:#FFFFFF; border-radius:17px; font-weight:%6;"
|
"QToolButton::menu-indicator { image:none; }"
|
||||||
" font-size:%2px; }"
|
"#avatar { background:#2D6CB5; color:#FFFFFF; border-radius:17px; font-weight:%6;"
|
||||||
"#userName { color:#1F2A3D; font-size:%3px; font-weight:%5; }"
|
" font-size:%2px; }"
|
||||||
"#userRole { color:#8A93A3; font-size:%4px; }")
|
"#userName { color:#1F2A3D; font-size:%3px; font-weight:%5; }"
|
||||||
.arg(type::kTitle)
|
"#userRole { color:#8A93A3; font-size:%4px; }")
|
||||||
.arg(type::kBody)
|
.arg(type::kTitle)
|
||||||
.arg(type::kLabel)
|
.arg(type::kBody)
|
||||||
.arg(type::kCaption)
|
.arg(type::kLabel)
|
||||||
.arg(type::kWeightSemibold)
|
.arg(type::kCaption)
|
||||||
.arg(type::kWeightBold));
|
.arg(type::kWeightSemibold)
|
||||||
|
.arg(type::kWeightBold));
|
||||||
|
|
||||||
auto* lay = new QHBoxLayout(this);
|
auto* lay = new QHBoxLayout(this);
|
||||||
lay->setContentsMargins(14, 0, 14, 0);
|
lay->setContentsMargins(14, 0, 14, 0);
|
||||||
|
|
|
||||||
|
|
@ -331,9 +331,10 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
// 仅三维视图显示;含 帘面 / 体素 勾选(体素=两交叉测线散点配准 IDW 的派生层,正确归宿)。
|
// 仅三维视图显示;含 帘面 / 体素 勾选(体素=两交叉测线散点配准 IDW 的派生层,正确归宿)。
|
||||||
auto* layerPanel = new QFrame(centerWidget);
|
auto* layerPanel = new QFrame(centerWidget);
|
||||||
layerPanel->setFrameShape(QFrame::StyledPanel);
|
layerPanel->setFrameShape(QFrame::StyledPanel);
|
||||||
layerPanel->setStyleSheet(
|
geopro::app::applyThemedStyleSheet(
|
||||||
QStringLiteral("QFrame{background:rgba(255,255,255,0.96);border:1px solid #D5DBE5;"
|
layerPanel,
|
||||||
"border-radius:8px;} QCheckBox{padding:2px 1px;color:#1F2A3D;}"
|
QStringLiteral("QFrame{background:#FFFFFF;border:1px solid #D5DBE5;border-radius:8px;}"
|
||||||
|
"QCheckBox{padding:2px 1px;color:#1F2A3D;}"
|
||||||
"QCheckBox:disabled{color:#9AA6B6;}"));
|
"QCheckBox:disabled{color:#9AA6B6;}"));
|
||||||
auto* layerLayout = new QVBoxLayout(layerPanel);
|
auto* layerLayout = new QVBoxLayout(layerPanel);
|
||||||
// 浮层内边距取间距令牌:左右 lg(12)、上下 ml(10),对称(原 13/10/15/11 是手调奇数)。
|
// 浮层内边距取间距令牌:左右 lg(12)、上下 ml(10),对称(原 13/10/15/11 是手调奇数)。
|
||||||
|
|
@ -341,11 +342,11 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
geopro::app::space::kLg, geopro::app::space::kMl);
|
geopro::app::space::kLg, geopro::app::space::kMl);
|
||||||
layerLayout->setSpacing(geopro::app::space::kSm);
|
layerLayout->setSpacing(geopro::app::space::kSm);
|
||||||
auto* layerTitle = new QLabel(QStringLiteral("视图详情"));
|
auto* layerTitle = new QLabel(QStringLiteral("视图详情"));
|
||||||
layerTitle->setStyleSheet(QStringLiteral(
|
geopro::app::applyThemedStyleSheet(
|
||||||
"font-weight:%1;color:#2D6CB5;border:none;background:transparent;"
|
layerTitle, QStringLiteral("font-weight:%1;color:#2D6CB5;border:none;background:transparent;"
|
||||||
"padding-bottom:3px;font-size:%2px;")
|
"padding-bottom:3px;font-size:%2px;")
|
||||||
.arg(geopro::app::type::kWeightSemibold)
|
.arg(geopro::app::type::kWeightSemibold)
|
||||||
.arg(geopro::app::type::kTitle));
|
.arg(geopro::app::type::kTitle));
|
||||||
auto* chkCurtain = new QCheckBox(QStringLiteral("帘面(断面墙)"));
|
auto* chkCurtain = new QCheckBox(QStringLiteral("帘面(断面墙)"));
|
||||||
chkCurtain->setChecked(true);
|
chkCurtain->setChecked(true);
|
||||||
auto* chkVoxel = new QCheckBox(QStringLiteral("体素(dd_voxel)"));
|
auto* chkVoxel = new QCheckBox(QStringLiteral("体素(dd_voxel)"));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue