| 4388 | } |
| 4389 | |
| 4390 | void MainWindow::buildLocalToolbar() { |
| 4391 | // Populates the plot-config page of the right-sidepanel stack: a |
| 4392 | // "Curve Width" header + flow-strip, a "Curve Style" header + |
| 4393 | // flow-strip, then the CurveEditor (added by the caller). Sections |
| 4394 | // wrap as the panel narrows; below ~72 px the headers hide and the |
| 4395 | // icon strips stack into a 1- or 2-col snap. |
| 4396 | auto* outer = qobject_cast<QVBoxLayout*>(plot_config_page_->layout()); |
| 4397 | if (outer == nullptr) { |
| 4398 | return; |
| 4399 | } |
| 4400 | |
| 4401 | struct ToolSpec { |
| 4402 | const char* object_name; |
| 4403 | const char* icon_path; |
| 4404 | const char* tooltip; |
| 4405 | std::function<void()> on_click; |
| 4406 | }; |
| 4407 | const auto on_width = [this](double w) { return [this, w]() { applyActivePlotWidth(w); }; }; |
| 4408 | const auto on_style = [this](int s) { return [this, s]() { applyActivePlotStyle(s); }; }; |
| 4409 | |
| 4410 | auto build_section = [this, outer]( |
| 4411 | const QString& heading, const QString& header_object_name, |
| 4412 | const std::vector<ToolSpec>& specs) -> QWidget* { |
| 4413 | // Heading: the shared titlebar-tone band (pj_widgets SectionHeaderBand, |
| 4414 | // themed via the PJ--SectionHeaderBand QSS class rule). The objectName is |
| 4415 | // kept for widget-tree selectors; the chrome-metrics handler resizes it. |
| 4416 | auto* header = new SectionHeaderBand(heading, plot_config_page_); |
| 4417 | header->setObjectName(header_object_name); |
| 4418 | header->setFixedHeight(chrome_metrics_.icon_size + chrome_metrics_.icon_padding); |
| 4419 | outer->addWidget(header); |
| 4420 | |
| 4421 | // Icon strip: FlowLayout, spacing 0 so icons sit flush with each |
| 4422 | // other and the chrome bands. Each button is the standard chrome |
| 4423 | // 24×24 with a 20×20 icon, matching every other icon in the app. |
| 4424 | // |
| 4425 | // hasHeightForWidth(true) on the size policy is what lets the strip |
| 4426 | // grow tall when it has to wrap — without it, the parent QVBoxLayout |
| 4427 | // asks for sizeHint().height() (one row's worth, 24 px), and the |
| 4428 | // wrapped rows render below the strip's bottom edge and get clipped. |
| 4429 | // Each strip wraps independently inside its own section, so icons |
| 4430 | // never cross a section header. |
| 4431 | auto* strip = new QWidget(plot_config_page_); |
| 4432 | QSizePolicy strip_policy(QSizePolicy::Preferred, QSizePolicy::Minimum); |
| 4433 | strip_policy.setHeightForWidth(true); |
| 4434 | strip->setSizePolicy(strip_policy); |
| 4435 | auto* flow = new FlowLayout(strip, /*margin=*/0, /*h_spacing=*/0, /*v_spacing=*/0); |
| 4436 | for (const auto& spec : specs) { |
| 4437 | auto* btn = new SvgButton(strip); |
| 4438 | btn->setObjectName(QString::fromLatin1(spec.object_name)); |
| 4439 | btn->setIconPath(QString::fromLatin1(spec.icon_path)); |
| 4440 | btn->setExtent(chrome_metrics_.icon_size + chrome_metrics_.icon_padding, chrome_metrics_.icon_size); |
| 4441 | btn->setToolTip(tr(spec.tooltip)); |
| 4442 | connect(btn, &QToolButton::clicked, this, spec.on_click); |
| 4443 | flow->addWidget(btn); |
| 4444 | } |
| 4445 | outer->addWidget(strip); |
| 4446 | return header; |
| 4447 | }; |
nothing calls this directly
no test coverage detected