| 386 | // ── CW sub-panel ───────────────────────────────────────────────────────────── |
| 387 | |
| 388 | void PhoneCwApplet::buildCwPanel() |
| 389 | { |
| 390 | m_cwPanel = new QWidget; |
| 391 | auto* vbox = new QVBoxLayout(m_cwPanel); |
| 392 | vbox->setContentsMargins(4, 2, 4, 6); |
| 393 | vbox->setSpacing(4); |
| 394 | |
| 395 | // ── ALC gauge (post-SW-ALC SSB-peak, dBFS) ────────────────────────── |
| 396 | // Mirrors the Phone-panel ALC gauge — both read from the same |
| 397 | // MeterModel::swAlcChanged source. Range covers normal operating |
| 398 | // window (-20…0 dBFS); excessive ALC pins at 0. |
| 399 | m_alcGaugeCw = new HGauge(kAlcGaugeFloorDbfs, 0.0f, -3.0f, "ALC", "dBFS", |
| 400 | {{-20, "-20"}, {-15, "-15"}, {-10, "-10"}, {-5, "-5"}, {0, "0"}}); |
| 401 | m_alcGaugeCw->setFillFromRight(true); // empty at -20, fills leftward toward 0 |
| 402 | m_alcGaugeCw->setValueImmediate(kAlcGaugeFloorDbfs); |
| 403 | m_alcGaugeCw->setAccessibleName("ALC gauge (CW)"); |
| 404 | m_alcGaugeCw->setAccessibleDescription("Automatic level control — post-software-ALC SSB peak (dBFS)"); |
| 405 | m_alcGaugeCw->setHoverValueFormatter(alcHoverFormatter()); |
| 406 | m_alcGaugeCw->setHoverValuePopupEnabled(true); |
| 407 | vbox->addWidget(m_alcGaugeCw); |
| 408 | vbox->addSpacing(2); |
| 409 | |
| 410 | // All left-side labels/buttons share the same width so sliders align. |
| 411 | static constexpr int kLeftColW = 70; |
| 412 | static constexpr int kValueW = 36; |
| 413 | static constexpr int kGap = 4; // pad between label/button and slider |
| 414 | |
| 415 | // ── Delay: label + slider + inset value ───────────────────────────── |
| 416 | { |
| 417 | auto* row = new QHBoxLayout; |
| 418 | row->setSpacing(4); |
| 419 | |
| 420 | auto* lbl = new QLabel("Delay:"); |
| 421 | AetherSDR::ThemeManager::instance().applyStyleSheet(lbl, "QLabel { color: {{color.text.secondary}}; font-size: 11px; }"); |
| 422 | lbl->setFixedWidth(kLeftColW); |
| 423 | row->addWidget(lbl); |
| 424 | |
| 425 | row->addSpacing(kGap); |
| 426 | |
| 427 | m_delaySlider = new GuardedSlider(Qt::Horizontal); |
| 428 | m_delaySlider->setRange(0, 2000); |
| 429 | m_delaySlider->setSingleStep(10); |
| 430 | m_delaySlider->setPageStep(100); |
| 431 | m_delaySlider->setAccessibleName("CW delay"); |
| 432 | m_delaySlider->setAccessibleDescription("CW break-in delay in milliseconds"); |
| 433 | applyPrimarySliderStyle(m_delaySlider); |
| 434 | row->addWidget(m_delaySlider, 1); |
| 435 | |
| 436 | m_delayEdit = new QLineEdit("500"); |
| 437 | m_delayEdit->setStyleSheet(kInsetEditStyle); |
| 438 | m_delayEdit->setFixedWidth(kValueW); |
| 439 | m_delayEdit->setAlignment(Qt::AlignCenter); |
| 440 | m_delayEdit->setValidator(new QIntValidator(0, 2000, m_delayEdit)); |
| 441 | m_delayEdit->setAccessibleName("CW delay value"); |
| 442 | m_delayEdit->setAccessibleDescription("CW break-in delay in milliseconds, 0 to 2000"); |
| 443 | row->addWidget(m_delayEdit); |
| 444 | |
| 445 | connect(m_delaySlider, &QSlider::valueChanged, this, [this](int v) { |
nothing calls this directly
no test coverage detected