From 9ebe5fe40b0159de1a95a450cde7f57338e3161a Mon Sep 17 00:00:00 2001 From: Chad <167274875+UnsignedChad@users.noreply.github.com> Date: Sun, 24 May 2026 20:28:50 -0400 Subject: [PATCH] pdnkit GUI: editable layer thickness on LayerPanel The thickness column in the Layers dock was a read-only label. Now it is a QDoubleSpinBox: edit the value and a new thickness_changed signal fires. MainWindow listens and writes the new thickness into board_->stackup.layers[i].thickness so the next analysis sees it. In-memory only -- the change does not save back to the .kicad_pcb file. Persisting requires an S-expression emitter in circuitcore::sexpr (read-only today); that is a separate PR. Useful for: trying alternate stackups quickly (1 oz vs 2 oz copper, different substrate thickness) without re-spinning the board file. --- pdnkit/LayerPanel.cpp | 24 +++++++++++++++++++----- pdnkit/LayerPanel.h | 6 ++++++ pdnkit/MainWindow.cpp | 16 ++++++++++++++++ 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/pdnkit/LayerPanel.cpp b/pdnkit/LayerPanel.cpp index f57e876..1bad1c0 100644 --- a/pdnkit/LayerPanel.cpp +++ b/pdnkit/LayerPanel.cpp @@ -1,6 +1,7 @@ #include "LayerPanel.h" #include +#include #include #include #include @@ -71,13 +72,26 @@ void LayerPanel::setLayers(const std::vector& layers) { name->setMinimumWidth(70); h->addWidget(name); - // Thickness label -- pulled from the LayerPanel Entry. Empty if the - // (setup (stackup ...)) block did not supply a value for this layer. - if (L.thickness_um > 0.0) { - auto* t = new QLabel(QString::number(L.thickness_um, 'f', 1) + " um"); + // Thickness spinbox -- pre-loaded from the parsed stackup. Editing + // it propagates a thickness_changed() so MainWindow can override + // board_->stackup.layers[i].thickness in memory. Persisting back + // to the .kicad_pcb file needs an S-expr emitter -- separate work. + auto* t = new QDoubleSpinBox(); + t->setRange(0.0, 1000.0); + t->setDecimals(2); + t->setSingleStep(1.0); + t->setSuffix(" um"); + t->setValue(L.thickness_um); + t->setMaximumWidth(110); + if (L.thickness_um <= 0.0) { t->setStyleSheet("color: #888;"); - h->addWidget(t); + t->setSpecialValueText("(unset)"); } + connect(t, QOverload::of(&QDoubleSpinBox::valueChanged), + this, [this, ord](double v) { + emit thickness_changed(ord, v * 1.0e-6); + }); + h->addWidget(t); h->addStretch(); rows_layout_->addWidget(row); diff --git a/pdnkit/LayerPanel.h b/pdnkit/LayerPanel.h index fdbe85b..ed14997 100644 --- a/pdnkit/LayerPanel.h +++ b/pdnkit/LayerPanel.h @@ -27,6 +27,12 @@ class LayerPanel : public QWidget { signals: void visibility_changed(int ordinal, bool visible); + // Emitted when the user edits a layer's thickness spinbox. The + // value is in meters (the panel does the um -> m conversion). + // MainWindow listens and writes board_->stackup.layers[i].thickness + // so the next analysis uses the override. + void thickness_changed(int ordinal, double thickness_m); + private: void clearRows(); diff --git a/pdnkit/MainWindow.cpp b/pdnkit/MainWindow.cpp index 8fada24..bfb9799 100644 --- a/pdnkit/MainWindow.cpp +++ b/pdnkit/MainWindow.cpp @@ -67,6 +67,22 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) { dock->setWidget(layers_scroll); dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); addDockWidget(Qt::RightDockWidgetArea, dock); + connect(layer_panel_, &LayerPanel::thickness_changed, + this, [this](int ord, double thickness_m) { + if (!board_) return; + for (auto& L : board_->stackup.layers) { + if (L.ordinal == ord) { + L.thickness = thickness_m; + break; + } + } + statusBar()->showMessage( + QString("Layer %1 thickness updated to %2 um " + "(in-memory, next analysis will use it)") + .arg(ord) + .arg(thickness_m * 1.0e6, 0, 'f', 1), + 6000); + }); connect(layer_panel_, &LayerPanel::visibility_changed, canvas_, &PcbCanvas::setLayerVisibility);