| 1323 | #endif |
| 1324 | |
| 1325 | void MainWindow::applyFlexControlWheelAction(const QString& actionId, int steps) |
| 1326 | { |
| 1327 | if (steps == 0) |
| 1328 | return; |
| 1329 | |
| 1330 | if (actionId == "WheelFrequency") { |
| 1331 | auto* s = activeSlice(); |
| 1332 | if (!s) return; |
| 1333 | if (s->isLocked()) { |
| 1334 | s->notifyTuneBlockedByLock(); |
| 1335 | // Drop queued tuning so unlock does not replay stale wheel input. |
| 1336 | m_flexTargetMhz = -1.0; |
| 1337 | return; |
| 1338 | } |
| 1339 | auto* sw = spectrumForSlice(s); |
| 1340 | const int stepHz = sw ? sw->stepSize() |
| 1341 | : (s->stepHz() > 0 ? s->stepHz() : 100); |
| 1342 | if (m_flexTargetMhz < 0.0 || |
| 1343 | (!m_flexCoalesceTimer.isActive() && |
| 1344 | std::abs(m_flexTargetMhz - s->frequency()) > 0.001)) { |
| 1345 | // Snap the base to the active step grid so encoder ticks land on |
| 1346 | // clean multiples even when the slice frequency is off-grid |
| 1347 | // (e.g. after a step-size change or a typed entry). Mirrors the |
| 1348 | // MIDI tune-knob path at the top of this file (#3260). |
| 1349 | const long long curHz = |
| 1350 | static_cast<long long>(std::round(s->frequency() * 1e6)); |
| 1351 | const long long snapped = stepHz > 0 |
| 1352 | ? ((curHz + stepHz / 2) / stepHz) * stepHz |
| 1353 | : curHz; |
| 1354 | m_flexTargetMhz = snapped / 1e6; |
| 1355 | } |
| 1356 | m_flexTargetMhz += steps * stepHz / 1e6; |
| 1357 | pushSliceFrequencyToOverlays(s, m_flexTargetMhz); |
| 1358 | if (!m_flexCoalesceTimer.isActive()) |
| 1359 | m_flexCoalesceTimer.start(); |
| 1360 | } else if (actionId == "WheelRit") { |
| 1361 | if (auto* s = activeSlice()) { |
| 1362 | const int hz = std::clamp(s->ritFreq() + steps * 10, -9999, 9999); |
| 1363 | s->setRit(true, hz); |
| 1364 | #ifdef HAVE_HIDAPI |
| 1365 | triggerTMate2Overlay(TMate2Overlay::Rit, hz); |
| 1366 | #endif |
| 1367 | } |
| 1368 | } else if (actionId == "WheelXit") { |
| 1369 | if (auto* s = activeSlice()) { |
| 1370 | const int hz = std::clamp(s->xitFreq() + steps * 10, -9999, 9999); |
| 1371 | s->setXit(true, hz); |
| 1372 | #ifdef HAVE_HIDAPI |
| 1373 | triggerTMate2Overlay(TMate2Overlay::Xit, hz); |
| 1374 | #endif |
| 1375 | } |
| 1376 | } else if (actionId == "WheelVolume" || actionId == "WheelMasterAf") { |
| 1377 | // Route to master volume to match SmartSDR behavior (#2921). |
| 1378 | // "WheelMasterAf" is the legacy action name from #2888; accepted |
| 1379 | // here for back-compat with saved FlexControl bindings made |
| 1380 | // before the #2986 consolidation but routes to the same code path. |
| 1381 | const int current = AppSettings::instance().value("MasterVolume", "100").toInt(); |
| 1382 | const int next = std::clamp(current + steps * 2, 0, 100); |
nothing calls this directly
no test coverage detected