| 237 | } |
| 238 | |
| 239 | void RC28MappingDialog::buildEncoderSection() |
| 240 | { |
| 241 | auto* group = new QGroupBox("Encoder"); |
| 242 | group->setStyleSheet(kGroupStyle); |
| 243 | auto* vbox = new QVBoxLayout(group); |
| 244 | vbox->setSpacing(4); |
| 245 | vbox->setContentsMargins(8, 6, 8, 8); |
| 246 | |
| 247 | auto* invertCheck = new QCheckBox("Invert encoder direction"); |
| 248 | invertCheck->setStyleSheet(kLabelStyle); |
| 249 | invertCheck->setChecked( |
| 250 | AppSettings::instance().value("HidEncoderInvertDir", "False").toString() == "True"); |
| 251 | connect(invertCheck, &QCheckBox::toggled, this, [this](bool on) { |
| 252 | AppSettings::instance().setValue("HidEncoderInvertDir", on ? "True" : "False"); |
| 253 | AppSettings::instance().save(); |
| 254 | if (m_encoder) |
| 255 | QMetaObject::invokeMethod(m_encoder.data(), [enc = m_encoder.data(), on] { |
| 256 | enc->setInvertDirection(on); |
| 257 | }); |
| 258 | }); |
| 259 | vbox->addWidget(invertCheck); |
| 260 | |
| 261 | // Sensitivity divider: how many encoder pulses are required to produce one |
| 262 | // frequency step. 1 = normal (every pulse fires), 10 = most reduced. (#3841) |
| 263 | auto* sensRow = new QHBoxLayout; |
| 264 | auto* sensKey = new QLabel("Pulses per step:"); |
| 265 | sensKey->setStyleSheet(kDimStyle); |
| 266 | m_sensitivitySlider = new QSlider(Qt::Horizontal); |
| 267 | m_sensitivitySlider->setRange(1, 10); |
| 268 | m_sensitivitySlider->setTickPosition(QSlider::TicksBelow); |
| 269 | m_sensitivitySlider->setTickInterval(1); |
| 270 | const int savedSens = HidEncoderManager::rc28MappingField("sensitivity", "1").toInt(); |
| 271 | m_sensitivitySlider->setValue(savedSens >= 1 && savedSens <= 10 ? savedSens : 1); |
| 272 | m_sensitivityValueLabel = new QLabel(QString::number(m_sensitivitySlider->value())); |
| 273 | m_sensitivityValueLabel->setStyleSheet(kLabelStyle); |
| 274 | m_sensitivityValueLabel->setFixedWidth(18); |
| 275 | m_sensitivityValueLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); |
| 276 | sensRow->addWidget(sensKey); |
| 277 | sensRow->addWidget(m_sensitivitySlider); |
| 278 | sensRow->addWidget(m_sensitivityValueLabel); |
| 279 | connect(m_sensitivitySlider, &QSlider::valueChanged, this, [this](int v) { |
| 280 | m_sensitivityValueLabel->setText(QString::number(v)); |
| 281 | HidEncoderManager::setRc28MappingField("sensitivity", QString::number(v)); |
| 282 | emit mappingFieldChanged("sensitivity", QString::number(v)); |
| 283 | }); |
| 284 | vbox->addLayout(sensRow); |
| 285 | |
| 286 | // Auto-snap: after the knob stops for 600 ms, snap to the nearest 1 kHz |
| 287 | // without recentering the spectrum display. (#3841) |
| 288 | m_autoSnapCheck = new QCheckBox("Auto-snap to nearest 1 kHz after rotation stops"); |
| 289 | m_autoSnapCheck->setStyleSheet(kLabelStyle); |
| 290 | m_autoSnapCheck->setChecked( |
| 291 | HidEncoderManager::rc28MappingField("autoSnap", "False") == "True"); |
| 292 | connect(m_autoSnapCheck, &QCheckBox::toggled, this, [this](bool on) { |
| 293 | HidEncoderManager::setRc28MappingField("autoSnap", on ? "True" : "False"); |
| 294 | emit mappingFieldChanged("autoSnap", on ? "True" : "False"); |
| 295 | }); |
| 296 | vbox->addWidget(m_autoSnapCheck); |