From b497fe547ca405f948a11f715c028f66752d4845 Mon Sep 17 00:00:00 2001 From: gaozheng Date: Thu, 25 Jun 2026 16:46:32 +0800 Subject: [PATCH] =?UTF-8?q?fix(ui):=20=E5=88=86=E6=AE=B5=E6=A0=91=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D(=E6=89=B92)-=E9=80=89=E4=B8=AD=E9=AB=98=E4=BA=AE?= =?UTF-8?q?=E7=BB=9F=E4=B8=80=E5=AF=B9=E8=B1=A1=E6=A0=91+=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E8=BF=98=E5=8E=9FTM=E6=8C=82=E8=BD=BD+=E7=BC=A9?= =?UTF-8?q?=E8=BF=9B=E4=B8=80=E8=87=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - #2 DatasetCardDelegate 选中/hover 改与对象树(ObjectRowDelegate)一致:整行方角填充 (去圆角卡)+左2px accent竖条满高+选中标题加粗;保留双行卡片(创建时间·类型副标题) - #4 CategorySection 树结构:派生 ds(反演剖面)带派生父指向已被筛掉/属别段的原始 ds 时, 按 parentId 挂载失败→ds 浮到根平铺。改:派生父在本段保留嵌套(体>切片),否则回退挂 结构容器 structParentId(TM),还原 项目/GS/TM/DS 真实层级 - #6 三维体段体相对TM缩进过大:容器节点(项目/GS/TM)不画复选框但保留同宽复选框列,使 各级缩进只差一个树级(原先容器无列宽→子级带框缩进多撑出复选框列宽),与对象树一致 构建:app 链接通过 --- src/app/panels/DatasetListPanel.cpp | 29 +++++++++++++--------- src/app/panels/columns/CategorySection.cpp | 8 +++++- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/app/panels/DatasetListPanel.cpp b/src/app/panels/DatasetListPanel.cpp index 24ea496..fe38637 100644 --- a/src/app/panels/DatasetListPanel.cpp +++ b/src/app/panels/DatasetListPanel.cpp @@ -70,25 +70,27 @@ public: return; } - // 卡片 + // 选中/hover:与对象树(ObjectRowDelegate)完全一致——整行方角填充(非圆角卡)+ 左 2px + // accent 竖条贴行左缘满高 + 选中标题加粗。保留双行卡片内容(标题 + 创建时间·类型副标题)。 const QRect r = opt.rect.adjusted(4, 2, -4, -2); const bool selected = opt.state & QStyle::State_Selected; const bool hover = opt.state & QStyle::State_MouseOver; - if (selected || hover) { - QPainterPath path; - path.addRoundedRect(r, 6, 6); - p->fillPath(path, geopro::app::tokenColor(selected ? "bg/selected" : "bg/hover")); - } - if (selected) { // 左 2px 强调竖条(规范§6.2) - p->fillRect(QRect(r.left(), r.top() + 4, 2, r.height() - 8), + if (selected || hover) + p->fillRect(opt.rect, geopro::app::tokenColor(selected ? "bg/selected" : "bg/hover")); + if (selected) + p->fillRect(QRect(opt.rect.left(), opt.rect.top(), 2, opt.rect.height()), geopro::app::tokenColor("accent/primary")); - } - // 可勾选项:左侧画复选框(用当前 style 的指示器),文本整体右移。无复选框项(容器节点)左留白小。 + // 可勾选项:左侧画复选框(用当前 style 的指示器),文本整体右移。 + // 容器节点(项目/GS/TM)虽不画复选框,也保留同宽复选框列——否则其子级(带复选框)相对容器的 + // 视觉缩进 = 树级缩进 + 复选框列宽,比「子带框→孙带框」的缩进大一截(用户实测 #6:三维体段 + // 体相对 TM 缩进过大)。保留同宽列后各级缩进只差一个树级,与对象树一致。 + const int box = 16; + const int checkColPad = 12 + box + 8; // 复选框列总宽(复选框 + 两侧留白) int textLeftPad = 6; const bool checkable = (idx.flags() & Qt::ItemIsUserCheckable); + const bool isContainer = idx.data(kDsDdCodeRole).toString() == QStringLiteral("container"); if (checkable) { - const int box = 16; QRect checkRect(r.left() + 12, r.top() + (r.height() - box) / 2, box, box); const auto cs = static_cast(idx.data(Qt::CheckStateRole).toInt()); QStyleOptionViewItem o(opt); @@ -98,7 +100,9 @@ public: const QWidget* w = opt.widget; QStyle* st = w ? w->style() : QApplication::style(); st->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &o, p, w); - textLeftPad = 12 + box + 8; // 复选框右侧留白后再放文本 + textLeftPad = checkColPad; // 复选框右侧留白后再放文本 + } else if (isContainer) { + textLeftPad = checkColPad; // 容器保留同宽列(不画框),使子级缩进与对象树一致 } QString title = disp, meta; @@ -111,6 +115,7 @@ public: const QRect textR = r.adjusted(textLeftPad, 4, -12, -4); QFont tf = opt.font; tf.setPixelSize(geopro::app::scaledPx(13)); + if (selected) tf.setWeight(QFont::DemiBold); // 选中加粗,与对象树一致 p->setFont(tf); p->setPen(geopro::app::tokenColor("text/primary")); if (meta.isEmpty()) { diff --git a/src/app/panels/columns/CategorySection.cpp b/src/app/panels/columns/CategorySection.cpp index fe4773b..b4fb383 100644 --- a/src/app/panels/columns/CategorySection.cpp +++ b/src/app/panels/columns/CategorySection.cpp @@ -194,9 +194,15 @@ void CategorySection::rebuildList() { display.push_back(std::move(c)); } } + // 分段树是「项目/GS/TM」组织树:ds 应挂到其结构容器(TM)下。但派生 ds(如反演剖面)带派生父 + // parentId(指向原始 ds),若该原始 ds 不在本段(被筛掉/属别类型段),按 parentId 挂载会失败 → + // ds 浮到树根平铺(用户实测 bug:ds 没挂在 tm 下)。故:派生父在本段则保留派生嵌套(如 体>切片), + // 否则回退挂到结构容器 structParentId(TM)。 + std::set presentIds; + for (const auto& d : filtered) presentIds.insert(d.id); for (const auto& d : filtered) { DsRow x = d; - if (x.parentId.empty()) x.parentId = x.structParentId; // 源 ds / 体 → 挂结构容器 + if (x.parentId.empty() || !presentIds.count(x.parentId)) x.parentId = x.structParentId; display.push_back(std::move(x)); }