v2.0.0
Loading...
Searching...
No Matches
scalecontrol.cpp
Go to the documentation of this file.
1//=============================================================================================================
14
15#include "scalecontrol.h"
16#include "ui_scalecontrol.h"
17#include <math.h>
18
19#include <QInputDialog>
20
21using namespace DISPLIB;
22
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);
31
32//=============================================================================================================
33
35: ScaleControl(label, nullptr, m_dDefaultMin, m_dDefaultMax)
36{
37}
38
39//=============================================================================================================
40
42 QWidget* parent)
43: ScaleControl(label, parent, m_dDefaultMin, m_dDefaultMax)
44{
45}
46
47//=============================================================================================================
48
50 QWidget* parent,
51 double min,
52 double max)
53: QWidget(parent)
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)
62{
63 m_pUi->setupUi(this);
64 initLabel(label);
65 initSpinBox();
66 initSlider();
67 initMenu();
68 updateNLMapConstants();
69 setRange(min, max);
70}
71
72//=============================================================================================================
73
75
76//=============================================================================================================
77
78void ScaleControl::initLabel(const char* charTextLabel)
79{
80 m_pUi->label->setText(charTextLabel);
81}
82
83//=============================================================================================================
84
85void ScaleControl::initSpinBox()
86{
87 m_pUi->spinBox->setKeyboardTracking(false);
88 m_pUi->spinBox->setPrefix("+/- ");
89
90 connect(m_pUi->spinBox, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
91 this, &ScaleControl::spinBoxChanged);
92}
93
94//=============================================================================================================
95
96void ScaleControl::initSlider()
97{
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);
102
103 connect(m_pUi->slider, static_cast<void (QSlider::*)(int)>(&QSlider::valueChanged),
104 this, &ScaleControl::sliderChanged);
105}
106
107//=============================================================================================================
108
109Ui::ScaleControlWidget* ScaleControl::getUI()
110{
111 return m_pUi.get();
112}
113
114//=============================================================================================================
115
116void ScaleControl::setValue(double dScale)
117{
118 m_pUi->spinBox->setValue(dScale);
119}
120
121//=============================================================================================================
122
124{
125 if (m_pUi->spinBox->minimum() < s && s < m_pUi->spinBox->maximum()) {
126 m_fMaxSensitivityPoint = s;
127 updateNLMapConstants();
128 }
129}
130
131//=============================================================================================================
132
134{
135 if (0.0 < s && s < 1.0) {
136 m_fSensitivity = s;
137 updateNLMapConstants();
138 }
139}
140
141//=============================================================================================================
142
144 double max)
145{
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;
149 }
150 updateNLMapConstants();
151}
152
153//=============================================================================================================
154
155void ScaleControl::invertSlider(bool inverted)
156{
157 m_bSliderInverted = inverted;
158}
159
160//=============================================================================================================
161
162void ScaleControl::setSliderRange(int min,
163 int max)
164{
165 if ((0 < min) && (min < max)) {
166 m_pUi->slider->setRange(min, max);
167 updateNLMapConstants();
168 }
169}
170
171//=============================================================================================================
172
174{
175 m_pUi->spinBox->setDecimals(d);
176}
177
178//=============================================================================================================
179
180void ScaleControl::spinBoxChanged(double dScale)
181{
182 m_bManagingSpinBoxChange = true;
183 if (!m_bManagingSliderChange) {
184 m_pUi->slider->setValue(mapSpinBoxToSlider(dScale));
185 }
186 m_bManagingSpinBoxChange = false;
187 emit valueChanged(dScale);
188}
189
190//=============================================================================================================
191
192void ScaleControl::sliderChanged(int dScale)
193{
194 m_bManagingSliderChange = true;
195 if (!m_bManagingSpinBoxChange) {
196 m_pUi->spinBox->setValue(mapSliderToSpinBox(dScale));
197 }
198 m_bManagingSliderChange = false;
199}
200
201//=============================================================================================================
202
203inline float ScaleControl::weightedSensitivity(float s)
204{
205 return static_cast<double>(s) * s * s * 100 / m_pUi->spinBox->maximum();
206}
207
208//=============================================================================================================
209
210void ScaleControl::updateNLMapConstants()
211{
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);
214}
215
216//=============================================================================================================
217
218int ScaleControl::mapSpinBoxToSlider(double dScale)
219{
220 float map = m_fMapKconstant * (atanf(weightedSensitivity(m_fSensitivity) * (static_cast<float>(dScale) - m_fMaxSensitivityPoint)) - m_fMapYconstant);
221 int out;
222 if (m_bSliderInverted) {
223 out = m_pUi->slider->maximum() - static_cast<int>(roundf(map));
224 } else {
225 out = static_cast<int>(roundf(map));
226 }
227 return out;
228}
229
230//=============================================================================================================
231
232double ScaleControl::mapSliderToSpinBox(int dScale)
233{
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);
237}
238
239//=============================================================================================================
240
242{
243 return m_pUi->spinBox->value();
244}
245
246//=============================================================================================================
247
248void ScaleControl::initMenu()
249{
250 m_pSettingsMenu = new QMenu(this); //Scale Control takes ownership of this QMenu and will trigger its deletion.
251
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); //takes ownership
257
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); //takes ownership
263
264 m_pUi->toolButton->setMenu(m_pSettingsMenu);
265 m_pUi->toolButton->setPopupMode(QToolButton::InstantPopup);
266 m_pUi->toolButton->setArrowType(Qt::ArrowType::NoArrow);
267}
268
269//=============================================================================================================
270
271void ScaleControl::promptMinValueChange()
272{
273 bool ok;
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());
280 }
281}
282
283//=============================================================================================================
284
285void ScaleControl::promptMaxValueChange()
286{
287 bool ok;
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);
294 }
295}
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()
~ScaleControl() override
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)