diff --git a/src/core.h b/src/core.h index b34025d..6a3b7cd 100644 --- a/src/core.h +++ b/src/core.h @@ -199,7 +199,7 @@ struct Node { QString offsetExpr; // C/C++ expression → absolute address (static fields only) int arrayLen = 1; // Array: element count int strLen = 64; - bool collapsed = false; + bool collapsed = true; uint64_t refId = 0; // Pointer32/64: id of Struct to expand at *ptr NodeKind elementKind = NodeKind::UInt8; // Array: element type; Pointer with ptrDepth>0: target type int ptrDepth = 0; // Pointer: 0=struct/void ptr, 1=primitive*, 2=primitive** @@ -285,7 +285,7 @@ struct Node { n.offsetExpr = o["offsetExpr"].toString(); n.arrayLen = qBound(1, o["arrayLen"].toInt(1), 1000000); n.strLen = qBound(1, o["strLen"].toInt(64), 1000000); - n.collapsed = o["collapsed"].toBool(false); + n.collapsed = o["collapsed"].toBool(true); n.refId = o["refId"].toString("0").toULongLong(); n.elementKind = kindFromString(o["elementKind"].toString("UInt8")); n.ptrDepth = qBound(0, o["ptrDepth"].toInt(0), 2); diff --git a/src/main.cpp b/src/main.cpp index a588dc9..d423d49 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2314,10 +2314,6 @@ void MainWindow::applyTheme(const Theme& theme) { // Dock separator is 1px via PM_DockWidgetSeparatorExtent in MenuBarStyle - // Custom title bar - if (m_titleBar) - m_titleBar->applyTheme(theme); - // Start page if (m_startPage) m_startPage->applyTheme(theme); @@ -2333,6 +2329,11 @@ void MainWindow::applyTheme(const Theme& theme) { "QDockWidget { border: none; }" "QDockWidget > QWidget { border: none; }")); + // Custom title bar — applied AFTER setStyleSheet() because the MainWindow + // stylesheet re-resolves descendant palettes and would reset the QMenuBar palette. + if (m_titleBar) + m_titleBar->applyTheme(theme); + for (auto* tabBar : findChildren()) { // Only style tab bars owned directly by this QMainWindow (dock tabs), // skip ones inside SplitPane QTabWidgets etc. @@ -2416,19 +2417,19 @@ void MainWindow::applyTheme(const Theme& theme) { tp.setColor(QPalette::HighlightedText, theme.text); m_workspaceTree->setPalette(tp); m_workspaceTree->setStyleSheet(QStringLiteral( - "QTreeView { background: %1; border: none; }") + "QTreeView { background: %1; border: none; }" + "QTreeView::branch:has-children:closed { image: url(:/chevron-right.svg); }" + "QTreeView::branch:has-children:open { image: url(:/chevron-down.svg); }") .arg(theme.background.name())); m_workspaceTree->viewport()->update(); } if (m_workspaceSearch) { m_workspaceSearch->setStyleSheet(QStringLiteral( - "QLineEdit { background: %1; color: %2; border: 1px solid %3;" + "QLineEdit { background: %1; color: %2; border: none;" " padding: 4px 8px; }" - "QLineEdit:focus { border-color: %4; }" "QLineEdit QToolButton { padding: 0px 4px; }" - "QLineEdit QToolButton:hover { background: %5; }") + "QLineEdit QToolButton:hover { background: %3; }") .arg(theme.background.name(), theme.textDim.name(), - theme.border.name(), theme.borderFocused.name(), theme.hover.name())); } @@ -2450,6 +2451,9 @@ void MainWindow::applyTheme(const Theme& theme) { .arg(theme.textDim.name(), theme.indHoverSpan.name())); if (m_dockGrip) m_dockGrip->setGripColor(theme.textFaint); + if (m_workspaceDock) + m_workspaceDock->setStyleSheet(QStringLiteral( + "QDockWidget { border: 1px solid %1; }").arg(theme.border.name())); // Scanner dock if (m_scannerPanel) @@ -3331,7 +3335,7 @@ void MainWindow::createWorkspaceDock() { const auto& t = ThemeManager::instance().current(); auto* titleBar = new QWidget(m_workspaceDock); - titleBar->setFixedHeight(24); + titleBar->setFixedHeight(26); titleBar->setAutoFillBackground(true); { QPalette tbPal = titleBar->palette(); @@ -3373,6 +3377,13 @@ void MainWindow::createWorkspaceDock() { m_workspaceDock->setTitleBarWidget(titleBar); } + // Outer border around entire dock (header + search + tree) + { + const auto& t = ThemeManager::instance().current(); + m_workspaceDock->setStyleSheet(QStringLiteral( + "QDockWidget { border: 1px solid %1; }").arg(t.border.name())); + } + // Container widget: search box + tree view auto* dockContainer = new QWidget(m_workspaceDock); auto* dockLayout = new QVBoxLayout(dockContainer); @@ -3421,13 +3432,11 @@ void MainWindow::createWorkspaceDock() { { const auto& t = ThemeManager::instance().current(); m_workspaceSearch->setStyleSheet(QStringLiteral( - "QLineEdit { background: %1; color: %2; border: 1px solid %3;" + "QLineEdit { background: %1; color: %2; border: none;" " padding: 4px 8px; }" - "QLineEdit:focus { border-color: %4; }" "QLineEdit QToolButton { padding: 0px 4px; }" - "QLineEdit QToolButton:hover { background: %5; }") + "QLineEdit QToolButton:hover { background: %3; }") .arg(t.background.name(), t.textDim.name(), - t.border.name(), t.borderFocused.name(), t.hover.name())); } dockLayout->addWidget(m_workspaceSearch); @@ -3473,7 +3482,9 @@ void MainWindow::createWorkspaceDock() { m_workspaceTree->setPalette(tp); m_workspaceTree->setStyleSheet(QStringLiteral( - "QTreeView { background: %1; border: none; }") + "QTreeView { background: %1; border: none; }" + "QTreeView::branch:has-children:closed { image: url(:/chevron-right.svg); }" + "QTreeView::branch:has-children:open { image: url(:/chevron-down.svg); }") .arg(t.background.name())); } diff --git a/src/workspace_model.h b/src/workspace_model.h index 756e88e..9fb9089 100644 --- a/src/workspace_model.h +++ b/src/workspace_model.h @@ -165,9 +165,15 @@ inline void syncProjectExplorer(QStandardItemModel* model, item->setText(display); item->setData(QVariant::fromValue(e.subPtr), Qt::UserRole); - // Refresh children for structs - if (!e.isEnum) - buildStructChildren(item, e.tree, id, e.subPtr); + // Refresh children only when count changed (avoids destroying expansion state) + if (!e.isEnum) { + QVector members = e.tree->childrenOf(id); + int visCount = 0; + for (int mi : members) + if (!isHexPad(e.tree->nodes[mi].kind)) ++visCount; + if (item->rowCount() != visCount) + buildStructChildren(item, e.tree, id, e.subPtr); + } } // Add new items