16#include "ui_scalecontrol.h"
19#include <QInputDialog>
23const static float m_dDefaultMin(0.0f);
24const static float m_dDefaultMax(1.0f);
25const static float m_dDefaultMaxSensitivityPoint((m_dDefaultMin + m_dDefaultMax) / 2.0f);
26const static float m_dDefaultSensitivity(0.3f);
27const static int m_iDefaultSliderMin(1);
28const static int m_iDefaultSliderMax(1000);
29const static int m_iDefaultSliderStep(1);
30const static int m_iDefaultSliderPageStep(10);
35:
ScaleControl(label, nullptr, m_dDefaultMin, m_dDefaultMax)
43:
ScaleControl(label, parent, m_dDefaultMin, m_dDefaultMax)
54, m_pUi(std::make_unique<Ui::ScaleControlWidget>())
55, m_bManagingSpinBoxChange(false)
56, m_bManagingSliderChange(false)
57, m_fSensitivity(m_dDefaultSensitivity)
58, m_fMaxSensitivityPoint(m_dDefaultMaxSensitivityPoint)
59, m_fMapYconstant(0.0f)
60, m_fMapKconstant(0.0f)
61, m_bSliderInverted(false)
68 updateNLMapConstants();
78void ScaleControl::initLabel(
const char* charTextLabel)
80 m_pUi->label->setText(charTextLabel);
85void ScaleControl::initSpinBox()
87 m_pUi->spinBox->setKeyboardTracking(
false);
88 m_pUi->spinBox->setPrefix(
"+/- ");
90 connect(m_pUi->spinBox,
static_cast<void (QDoubleSpinBox::*)(
double)
>(&QDoubleSpinBox::valueChanged),
91 this, &ScaleControl::spinBoxChanged);
96void ScaleControl::initSlider()
98 m_pUi->slider->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred));
99 m_pUi->slider->setSingleStep(m_iDefaultSliderStep);
100 m_pUi->slider->setPageStep(m_iDefaultSliderPageStep);
101 setSliderRange(m_iDefaultSliderMin, m_iDefaultSliderMax);
103 connect(m_pUi->slider,
static_cast<void (QSlider::*)(
int)
>(&QSlider::valueChanged),
104 this, &ScaleControl::sliderChanged);
118 m_pUi->spinBox->setValue(dScale);
125 if (m_pUi->spinBox->minimum() < s && s < m_pUi->spinBox->maximum()) {
126 m_fMaxSensitivityPoint = s;
127 updateNLMapConstants();
135 if (0.0 < s && s < 1.0) {
137 updateNLMapConstants();
146 m_pUi->spinBox->setRange(min, max);
147 if (m_fMaxSensitivityPoint < m_pUi->spinBox->minimum() || m_pUi->spinBox->maximum() < m_fMaxSensitivityPoint) {
148 m_fMaxSensitivityPoint = (m_pUi->spinBox->minimum() + m_pUi->spinBox->maximum()) / 2;
150 updateNLMapConstants();
157 m_bSliderInverted = inverted;
162void ScaleControl::setSliderRange(
int min,
165 if ((0 < min) && (min < max)) {
166 m_pUi->slider->setRange(min, max);
167 updateNLMapConstants();
175 m_pUi->spinBox->setDecimals(d);
180void ScaleControl::spinBoxChanged(
double dScale)
182 m_bManagingSpinBoxChange =
true;
183 if (!m_bManagingSliderChange) {
184 m_pUi->slider->setValue(mapSpinBoxToSlider(dScale));
186 m_bManagingSpinBoxChange =
false;
192void ScaleControl::sliderChanged(
int dScale)
194 m_bManagingSliderChange =
true;
195 if (!m_bManagingSpinBoxChange) {
196 m_pUi->spinBox->setValue(mapSliderToSpinBox(dScale));
198 m_bManagingSliderChange =
false;
203inline float ScaleControl::weightedSensitivity(
float s)
205 return static_cast<double>(s) * s * s * 100 / m_pUi->spinBox->maximum();
210void ScaleControl::updateNLMapConstants()
212 m_fMapYconstant = atanf(weightedSensitivity(m_fSensitivity) * (m_pUi->spinBox->minimum() - m_fMaxSensitivityPoint));
213 m_fMapKconstant = (m_pUi->slider->maximum() - m_pUi->slider->minimum()) / (atanf(weightedSensitivity(m_fSensitivity) * (m_pUi->spinBox->maximum() - m_fMaxSensitivityPoint)) - m_fMapYconstant);
218int ScaleControl::mapSpinBoxToSlider(
double dScale)
220 float map = m_fMapKconstant * (atanf(weightedSensitivity(m_fSensitivity) * (
static_cast<float>(dScale) - m_fMaxSensitivityPoint)) - m_fMapYconstant);
222 if (m_bSliderInverted) {
223 out = m_pUi->slider->maximum() -
static_cast<int>(roundf(map));
225 out =
static_cast<int>(roundf(map));
232double ScaleControl::mapSliderToSpinBox(
int dScale)
234 int valueCorrected = m_bSliderInverted ? m_pUi->slider->maximum() - dScale : dScale;
235 float map = (1 / weightedSensitivity(m_fSensitivity)) * tanf((
static_cast<float>(valueCorrected) / m_fMapKconstant) + m_fMapYconstant) + m_fMaxSensitivityPoint;
236 return static_cast<double>(map);
243 return m_pUi->spinBox->value();
248void ScaleControl::initMenu()
250 m_pSettingsMenu =
new QMenu(
this);
252 QAction* minVal =
new QAction(
"Edit minimum value");
253 connect(minVal, &QAction::triggered,
254 this, &ScaleControl::promptMinValueChange,
255 Qt::UniqueConnection);
256 m_pSettingsMenu->addAction(minVal);
258 QAction* maxVal =
new QAction(
"Edit maximum value");
259 connect(maxVal, &QAction::triggered,
260 this, &ScaleControl::promptMaxValueChange,
261 Qt::UniqueConnection);
262 m_pSettingsMenu->addAction(maxVal);
264 m_pUi->toolButton->setMenu(m_pSettingsMenu);
265 m_pUi->toolButton->setPopupMode(QToolButton::InstantPopup);
266 m_pUi->toolButton->setArrowType(Qt::ArrowType::NoArrow);
271void ScaleControl::promptMinValueChange()
274 double min = QInputDialog::getDouble(
this, tr(
"Minimum Value"),
275 tr(
"Please input a new minumum value:"),
276 m_pUi->spinBox->minimum(), 0.01, 100000,
277 2, &ok, Qt::WindowFlags(), 1);
278 if (ok && min <= m_pUi->spinBox->maximum()) {
279 setRange(min, m_pUi->spinBox->maximum());
285void ScaleControl::promptMaxValueChange()
288 double max = QInputDialog::getDouble(
this, tr(
"Maximum Value"),
289 tr(
"Please input a new maximum value:"),
290 m_pUi->spinBox->maximum(), 0.01, 100000,
291 2, &ok, Qt::WindowFlags(), 1);
292 if (ok && max >= m_pUi->spinBox->minimum()) {
293 setRange(m_pUi->spinBox->minimum(), max);
Composite slider + spinbox widget for picking a (possibly logarithmic) scale value.
2-D display widgets and visualisation helpers (charts, topography, colour maps).
Ui::ScaleControlWidget * getUI()
void invertSlider(bool inverted)
void setSensitivity(double s)
void setRange(double min, double max)
void setMaxSensitivityPoint(double s)
ScaleControl(const char *label)
void valueChanged(double dScale)
void setValue(double dScale)