##// END OF EJS Templates
Call the calculation of the thresholds in the scale editor (with each click on the 'automatic' mode)
Alexandre Leroux -
r1062:b014e09f2329
parent child
Show More
@@ -1,164 +1,174
1 #include "Visualization/ColorScaleEditor.h"
1 #include "Visualization/ColorScaleEditor.h"
2 #include "Visualization/SqpColorScale.h"
2 #include "Visualization/SqpColorScale.h"
3
3
4 #include "ui_ColorScaleEditor.h"
4 #include "ui_ColorScaleEditor.h"
5
5
6 namespace {
6 namespace {
7
7
8 const auto GRADIENTS = QVariantMap{{"Candy", QCPColorGradient::gpCandy},
8 const auto GRADIENTS = QVariantMap{{"Candy", QCPColorGradient::gpCandy},
9 {"Cold", QCPColorGradient::gpCold},
9 {"Cold", QCPColorGradient::gpCold},
10 {"Geography", QCPColorGradient::gpGeography},
10 {"Geography", QCPColorGradient::gpGeography},
11 {"Grayscale", QCPColorGradient::gpGrayscale},
11 {"Grayscale", QCPColorGradient::gpGrayscale},
12 {"Hot", QCPColorGradient::gpHot},
12 {"Hot", QCPColorGradient::gpHot},
13 {"Hues", QCPColorGradient::gpHues},
13 {"Hues", QCPColorGradient::gpHues},
14 {"Ion", QCPColorGradient::gpIon},
14 {"Ion", QCPColorGradient::gpIon},
15 {"Jet", QCPColorGradient::gpJet},
15 {"Jet", QCPColorGradient::gpJet},
16 {"Night", QCPColorGradient::gpNight},
16 {"Night", QCPColorGradient::gpNight},
17 {"Polar", QCPColorGradient::gpPolar},
17 {"Polar", QCPColorGradient::gpPolar},
18 {"Spectrum", QCPColorGradient::gpSpectrum},
18 {"Spectrum", QCPColorGradient::gpSpectrum},
19 {"Thermal", QCPColorGradient::gpThermal}};
19 {"Thermal", QCPColorGradient::gpThermal}};
20
20
21 } // namespace
21 } // namespace
22
22
23 ColorScaleEditor::ColorScaleEditor(SqpColorScale &scale, QWidget *parent)
23 ColorScaleEditor::ColorScaleEditor(SqpColorScale &scale, QWidget *parent)
24 : QDialog{parent},
24 : QDialog{parent},
25 ui{new Ui::ColorScaleEditor},
25 ui{new Ui::ColorScaleEditor},
26 m_ThresholdGroup{new QButtonGroup{this}},
26 m_ThresholdGroup{new QButtonGroup{this}},
27 m_Scale{scale}
27 m_Scale{scale}
28 {
28 {
29 ui->setupUi(this);
29 ui->setupUi(this);
30
30
31 // Inits gradient combobox content
31 // Inits gradient combobox content
32 for (auto it = GRADIENTS.begin(), end = GRADIENTS.end(); it != end; ++it) {
32 for (auto it = GRADIENTS.begin(), end = GRADIENTS.end(); it != end; ++it) {
33 ui->gradientComboBox->addItem(it.key(), it.value());
33 ui->gradientComboBox->addItem(it.key(), it.value());
34 }
34 }
35
35
36 // Creates threshold group
36 // Creates threshold group
37 m_ThresholdGroup->addButton(ui->thresholdAutoButton);
37 m_ThresholdGroup->addButton(ui->thresholdAutoButton);
38 m_ThresholdGroup->addButton(ui->thresholdManualButton);
38 m_ThresholdGroup->addButton(ui->thresholdManualButton);
39
39
40 // Inits min/max spinboxes' properties
40 // Inits min/max spinboxes' properties
41 auto setSpinBoxProperties = [](auto &spinBox) {
41 auto setSpinBoxProperties = [](auto &spinBox) {
42 spinBox.setDecimals(3);
42 spinBox.setDecimals(3);
43 spinBox.setMinimum(-std::numeric_limits<double>::max());
43 spinBox.setMinimum(-std::numeric_limits<double>::max());
44 spinBox.setMaximum(std::numeric_limits<double>::max());
44 spinBox.setMaximum(std::numeric_limits<double>::max());
45 };
45 };
46 setSpinBoxProperties(*ui->minSpinBox);
46 setSpinBoxProperties(*ui->minSpinBox);
47 setSpinBoxProperties(*ui->maxSpinBox);
47 setSpinBoxProperties(*ui->maxSpinBox);
48
48
49 // Creates color scale preview
49 // Creates color scale preview
50 m_PreviewScale = new QCPColorScale{ui->plot};
50 m_PreviewScale = new QCPColorScale{ui->plot};
51 m_PreviewScale->setType(QCPAxis::atTop);
51 m_PreviewScale->setType(QCPAxis::atTop);
52 m_PreviewScale->setMinimumMargins(QMargins{5, 5, 5, 5});
52 m_PreviewScale->setMinimumMargins(QMargins{5, 5, 5, 5});
53 m_PreviewScale->axis()->setScaleType(QCPAxis::stLogarithmic);
53 m_PreviewScale->axis()->setScaleType(QCPAxis::stLogarithmic);
54 m_PreviewScale->axis()->setNumberPrecision(0);
54 m_PreviewScale->axis()->setNumberPrecision(0);
55 m_PreviewScale->axis()->setNumberFormat("eb");
55 m_PreviewScale->axis()->setNumberFormat("eb");
56 m_PreviewScale->axis()->setTicker(QSharedPointer<QCPAxisTickerLog>::create());
56 m_PreviewScale->axis()->setTicker(QSharedPointer<QCPAxisTickerLog>::create());
57 m_PreviewScale->setGradient(QCPColorGradient{QCPColorGradient::gpJet});
57 m_PreviewScale->setGradient(QCPColorGradient{QCPColorGradient::gpJet});
58
58
59 ui->plot->plotLayout()->clear();
59 ui->plot->plotLayout()->clear();
60 ui->plot->plotLayout()->insertRow(0);
60 ui->plot->plotLayout()->insertRow(0);
61 ui->plot->plotLayout()->addElement(0, 0, m_PreviewScale);
61 ui->plot->plotLayout()->addElement(0, 0, m_PreviewScale);
62
62
63 // Inits connections
63 // Inits connections
64 connect(ui->gradientComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updatePreview()));
64 connect(ui->gradientComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updatePreview()));
65 connect(ui->thresholdAutoButton, SIGNAL(toggled(bool)), this, SLOT(onThresholdChanged(bool)));
65 connect(ui->thresholdAutoButton, SIGNAL(toggled(bool)), this, SLOT(onThresholdChanged(bool)));
66 connect(ui->thresholdManualButton, SIGNAL(toggled(bool)), this, SLOT(onThresholdChanged(bool)));
66 connect(ui->thresholdManualButton, SIGNAL(toggled(bool)), this, SLOT(onThresholdChanged(bool)));
67 connect(ui->minSpinBox, SIGNAL(editingFinished()), this, SLOT(onMinChanged()));
67 connect(ui->minSpinBox, SIGNAL(editingFinished()), this, SLOT(onMinChanged()));
68 connect(ui->maxSpinBox, SIGNAL(editingFinished()), this, SLOT(onMaxChanged()));
68 connect(ui->maxSpinBox, SIGNAL(editingFinished()), this, SLOT(onMaxChanged()));
69
69
70 // OK/cancel buttons
70 // OK/cancel buttons
71 connect(ui->okButton, SIGNAL(clicked(bool)), this, SLOT(accept()));
71 connect(ui->okButton, SIGNAL(clicked(bool)), this, SLOT(accept()));
72 connect(ui->cancelButton, SIGNAL(clicked(bool)), this, SLOT(reject()));
72 connect(ui->cancelButton, SIGNAL(clicked(bool)), this, SLOT(reject()));
73
73
74 // Loads color scale
74 // Loads color scale
75 loadScale();
75 loadScale();
76 }
76 }
77
77
78 ColorScaleEditor::~ColorScaleEditor() noexcept
78 ColorScaleEditor::~ColorScaleEditor() noexcept
79 {
79 {
80 delete ui;
80 delete ui;
81 }
81 }
82
82
83 void ColorScaleEditor::loadScale()
83 void ColorScaleEditor::loadScale()
84 {
84 {
85 // Gradient
85 // Gradient
86 auto gradientPresetIndex = ui->gradientComboBox->findData(m_Scale.m_GradientPreset);
86 auto gradientPresetIndex = ui->gradientComboBox->findData(m_Scale.m_GradientPreset);
87 ui->gradientComboBox->setCurrentIndex(gradientPresetIndex);
87 ui->gradientComboBox->setCurrentIndex(gradientPresetIndex);
88
88
89 // Threshold mode
89 // Threshold mode
90 (m_Scale.m_AutomaticThreshold ? ui->thresholdAutoButton : ui->thresholdManualButton)
90 (m_Scale.m_AutomaticThreshold ? ui->thresholdAutoButton : ui->thresholdManualButton)
91 ->setChecked(true);
91 ->setChecked(true);
92
92
93 // Min/max
93 // Min/max
94 auto qcpColorScale = m_Scale.m_Scale;
94 auto qcpColorScale = m_Scale.m_Scale;
95 auto range = qcpColorScale->dataRange();
95 auto range = qcpColorScale->dataRange();
96 ui->minSpinBox->setValue(range.lower);
96 ui->minSpinBox->setValue(range.lower);
97 ui->maxSpinBox->setValue(range.upper);
97 ui->maxSpinBox->setValue(range.upper);
98
98
99 updatePreview();
99 updatePreview();
100 }
100 }
101
101
102 void ColorScaleEditor::saveScale()
102 void ColorScaleEditor::saveScale()
103 {
103 {
104 auto qcpColorScale = m_Scale.m_Scale;
104 auto qcpColorScale = m_Scale.m_Scale;
105
105
106 // Gradient
106 // Gradient
107 auto gradientPreset
107 auto gradientPreset
108 = ui->gradientComboBox->currentData().value<QCPColorGradient::GradientPreset>();
108 = ui->gradientComboBox->currentData().value<QCPColorGradient::GradientPreset>();
109 qcpColorScale->setGradient(gradientPreset);
109 qcpColorScale->setGradient(gradientPreset);
110 m_Scale.m_GradientPreset = gradientPreset;
110 m_Scale.m_GradientPreset = gradientPreset;
111
111
112 // Threshold mode
112 // Threshold mode
113 m_Scale.m_AutomaticThreshold = ui->thresholdAutoButton->isChecked();
113 m_Scale.m_AutomaticThreshold = ui->thresholdAutoButton->isChecked();
114
114
115 // Min/max
115 // Min/max
116 qcpColorScale->setDataRange(QCPRange{ui->minSpinBox->value(), ui->maxSpinBox->value()});
116 qcpColorScale->setDataRange(QCPRange{ui->minSpinBox->value(), ui->maxSpinBox->value()});
117 }
117 }
118
118
119 void ColorScaleEditor::accept()
119 void ColorScaleEditor::accept()
120 {
120 {
121 saveScale();
121 saveScale();
122 QDialog::accept();
122 QDialog::accept();
123 }
123 }
124
124
125 void ColorScaleEditor::onMaxChanged()
125 void ColorScaleEditor::onMaxChanged()
126 {
126 {
127 // Ensures that max >= min
127 // Ensures that max >= min
128 auto maxValue = ui->maxSpinBox->value();
128 auto maxValue = ui->maxSpinBox->value();
129 if (maxValue < ui->minSpinBox->value()) {
129 if (maxValue < ui->minSpinBox->value()) {
130 ui->minSpinBox->setValue(maxValue);
130 ui->minSpinBox->setValue(maxValue);
131 }
131 }
132
132
133 updatePreview();
133 updatePreview();
134 }
134 }
135
135
136 void ColorScaleEditor::onMinChanged()
136 void ColorScaleEditor::onMinChanged()
137 {
137 {
138 // Ensures that min <= max
138 // Ensures that min <= max
139 auto minValue = ui->minSpinBox->value();
139 auto minValue = ui->minSpinBox->value();
140 if (minValue > ui->maxSpinBox->value()) {
140 if (minValue > ui->maxSpinBox->value()) {
141 ui->maxSpinBox->setValue(minValue);
141 ui->maxSpinBox->setValue(minValue);
142 }
142 }
143
143
144 updatePreview();
144 updatePreview();
145 }
145 }
146
146
147 void ColorScaleEditor::onThresholdChanged(bool checked)
147 void ColorScaleEditor::onThresholdChanged(bool checked)
148 {
148 {
149 if (checked) {
149 if (checked) {
150 auto isAutomatic = ui->thresholdAutoButton == m_ThresholdGroup->checkedButton();
150 auto isAutomatic = ui->thresholdAutoButton == m_ThresholdGroup->checkedButton();
151
151
152 ui->minSpinBox->setEnabled(!isAutomatic);
152 ui->minSpinBox->setEnabled(!isAutomatic);
153 ui->maxSpinBox->setEnabled(!isAutomatic);
153 ui->maxSpinBox->setEnabled(!isAutomatic);
154
155 // Computes automatic thresholds
156 if (isAutomatic) {
157 double minThreshold, maxThreshold;
158 std::tie(minThreshold, maxThreshold) = SqpColorScale::computeThresholds(m_Scale);
159 ui->minSpinBox->setValue(minThreshold);
160 ui->maxSpinBox->setValue(maxThreshold);
161
162 updatePreview();
163 }
154 }
164 }
155 }
165 }
156
166
157 void ColorScaleEditor::updatePreview()
167 void ColorScaleEditor::updatePreview()
158 {
168 {
159 m_PreviewScale->setDataRange(QCPRange{ui->minSpinBox->value(), ui->maxSpinBox->value()});
169 m_PreviewScale->setDataRange(QCPRange{ui->minSpinBox->value(), ui->maxSpinBox->value()});
160 m_PreviewScale->setGradient(
170 m_PreviewScale->setGradient(
161 ui->gradientComboBox->currentData().value<QCPColorGradient::GradientPreset>());
171 ui->gradientComboBox->currentData().value<QCPColorGradient::GradientPreset>());
162
172
163 ui->plot->replot();
173 ui->plot->replot();
164 }
174 }
@@ -1,169 +1,163
1 <?xml version="1.0" encoding="UTF-8"?>
1 <?xml version="1.0" encoding="UTF-8"?>
2 <ui version="4.0">
2 <ui version="4.0">
3 <class>ColorScaleEditor</class>
3 <class>ColorScaleEditor</class>
4 <widget class="QDialog" name="ColorScaleEditor">
4 <widget class="QDialog" name="ColorScaleEditor">
5 <property name="geometry">
5 <property name="geometry">
6 <rect>
6 <rect>
7 <x>0</x>
7 <x>0</x>
8 <y>0</y>
8 <y>0</y>
9 <width>258</width>
9 <width>258</width>
10 <height>232</height>
10 <height>232</height>
11 </rect>
11 </rect>
12 </property>
12 </property>
13 <property name="windowTitle">
13 <property name="windowTitle">
14 <string>Color scale editor</string>
14 <string>Color scale editor</string>
15 </property>
15 </property>
16 <layout class="QGridLayout" name="gridLayout">
16 <layout class="QGridLayout" name="gridLayout">
17 <item row="3" column="0">
17 <item row="3" column="0">
18 <layout class="QHBoxLayout" name="horizontalLayout">
18 <layout class="QHBoxLayout" name="horizontalLayout">
19 <item>
19 <item>
20 <spacer name="horizontalSpacer">
20 <spacer name="horizontalSpacer">
21 <property name="orientation">
21 <property name="orientation">
22 <enum>Qt::Horizontal</enum>
22 <enum>Qt::Horizontal</enum>
23 </property>
23 </property>
24 <property name="sizeHint" stdset="0">
24 <property name="sizeHint" stdset="0">
25 <size>
25 <size>
26 <width>40</width>
26 <width>40</width>
27 <height>20</height>
27 <height>20</height>
28 </size>
28 </size>
29 </property>
29 </property>
30 </spacer>
30 </spacer>
31 </item>
31 </item>
32 <item>
32 <item>
33 <widget class="QPushButton" name="okButton">
33 <widget class="QPushButton" name="okButton">
34 <property name="text">
34 <property name="text">
35 <string>OK</string>
35 <string>OK</string>
36 </property>
36 </property>
37 <property name="default">
38 <bool>true</bool>
39 </property>
40 </widget>
37 </widget>
41 </item>
38 </item>
42 <item>
39 <item>
43 <widget class="QPushButton" name="cancelButton">
40 <widget class="QPushButton" name="cancelButton">
44 <property name="text">
41 <property name="text">
45 <string>Cancel</string>
42 <string>Cancel</string>
46 </property>
43 </property>
47 </widget>
44 </widget>
48 </item>
45 </item>
49 </layout>
46 </layout>
50 </item>
47 </item>
51 <item row="1" column="0">
48 <item row="1" column="0">
52 <widget class="QGroupBox" name="groupBox">
49 <widget class="QGroupBox" name="groupBox">
53 <property name="title">
50 <property name="title">
54 <string>Preview</string>
51 <string>Preview</string>
55 </property>
52 </property>
56 <layout class="QGridLayout" name="gridLayout_3">
53 <layout class="QGridLayout" name="gridLayout_3">
57 <item row="0" column="0">
54 <item row="0" column="0">
58 <widget class="QCustomPlot" name="plot" native="true"/>
55 <widget class="QCustomPlot" name="plot" native="true"/>
59 </item>
56 </item>
60 </layout>
57 </layout>
61 </widget>
58 </widget>
62 </item>
59 </item>
63 <item row="0" column="0">
60 <item row="0" column="0">
64 <layout class="QGridLayout" name="gridLayout_2">
61 <layout class="QGridLayout" name="gridLayout_2">
65 <item row="1" column="0">
62 <item row="1" column="0">
66 <widget class="QLabel" name="thresholdLabel">
63 <widget class="QLabel" name="thresholdLabel">
67 <property name="text">
64 <property name="text">
68 <string>Thresholds:</string>
65 <string>Thresholds:</string>
69 </property>
66 </property>
70 </widget>
67 </widget>
71 </item>
68 </item>
72 <item row="1" column="1">
69 <item row="1" column="1">
73 <widget class="QRadioButton" name="thresholdAutoButton">
70 <widget class="QRadioButton" name="thresholdAutoButton">
74 <property name="enabled">
75 <bool>false</bool>
76 </property>
77 <property name="text">
71 <property name="text">
78 <string>Automatic</string>
72 <string>Automatic</string>
79 </property>
73 </property>
80 <property name="checkable">
74 <property name="checkable">
81 <bool>true</bool>
75 <bool>true</bool>
82 </property>
76 </property>
83 <property name="checked">
77 <property name="checked">
84 <bool>false</bool>
78 <bool>false</bool>
85 </property>
79 </property>
86 </widget>
80 </widget>
87 </item>
81 </item>
88 <item row="1" column="2">
82 <item row="1" column="2">
89 <widget class="QRadioButton" name="thresholdManualButton">
83 <widget class="QRadioButton" name="thresholdManualButton">
90 <property name="text">
84 <property name="text">
91 <string>Manual</string>
85 <string>Manual</string>
92 </property>
86 </property>
93 </widget>
87 </widget>
94 </item>
88 </item>
95 <item row="2" column="0">
89 <item row="2" column="0">
96 <widget class="QLabel" name="minLabel">
90 <widget class="QLabel" name="minLabel">
97 <property name="text">
91 <property name="text">
98 <string>Min:</string>
92 <string>Min:</string>
99 </property>
93 </property>
100 </widget>
94 </widget>
101 </item>
95 </item>
102 <item row="3" column="0">
96 <item row="3" column="0">
103 <widget class="QLabel" name="maxLabel">
97 <widget class="QLabel" name="maxLabel">
104 <property name="text">
98 <property name="text">
105 <string>Max:</string>
99 <string>Max:</string>
106 </property>
100 </property>
107 </widget>
101 </widget>
108 </item>
102 </item>
109 <item row="2" column="1" colspan="2">
103 <item row="2" column="1" colspan="2">
110 <widget class="QDoubleSpinBox" name="minSpinBox">
104 <widget class="QDoubleSpinBox" name="minSpinBox">
111 <property name="showGroupSeparator" stdset="0">
105 <property name="showGroupSeparator" stdset="0">
112 <bool>true</bool>
106 <bool>true</bool>
113 </property>
107 </property>
114 </widget>
108 </widget>
115 </item>
109 </item>
116 <item row="3" column="1" colspan="2">
110 <item row="3" column="1" colspan="2">
117 <widget class="QDoubleSpinBox" name="maxSpinBox">
111 <widget class="QDoubleSpinBox" name="maxSpinBox">
118 <property name="showGroupSeparator" stdset="0">
112 <property name="showGroupSeparator" stdset="0">
119 <bool>true</bool>
113 <bool>true</bool>
120 </property>
114 </property>
121 </widget>
115 </widget>
122 </item>
116 </item>
123 <item row="0" column="0">
117 <item row="0" column="0">
124 <widget class="QLabel" name="gradientLabel">
118 <widget class="QLabel" name="gradientLabel">
125 <property name="text">
119 <property name="text">
126 <string>Gradient:</string>
120 <string>Gradient:</string>
127 </property>
121 </property>
128 </widget>
122 </widget>
129 </item>
123 </item>
130 <item row="0" column="1" colspan="2">
124 <item row="0" column="1" colspan="2">
131 <widget class="QComboBox" name="gradientComboBox"/>
125 <widget class="QComboBox" name="gradientComboBox"/>
132 </item>
126 </item>
133 </layout>
127 </layout>
134 </item>
128 </item>
135 <item row="2" column="0">
129 <item row="2" column="0">
136 <spacer name="verticalSpacer">
130 <spacer name="verticalSpacer">
137 <property name="orientation">
131 <property name="orientation">
138 <enum>Qt::Vertical</enum>
132 <enum>Qt::Vertical</enum>
139 </property>
133 </property>
140 <property name="sizeHint" stdset="0">
134 <property name="sizeHint" stdset="0">
141 <size>
135 <size>
142 <width>20</width>
136 <width>20</width>
143 <height>40</height>
137 <height>40</height>
144 </size>
138 </size>
145 </property>
139 </property>
146 </spacer>
140 </spacer>
147 </item>
141 </item>
148 </layout>
142 </layout>
149 </widget>
143 </widget>
150 <customwidgets>
144 <customwidgets>
151 <customwidget>
145 <customwidget>
152 <class>QCustomPlot</class>
146 <class>QCustomPlot</class>
153 <extends>QWidget</extends>
147 <extends>QWidget</extends>
154 <header>Visualization/qcustomplot.h</header>
148 <header>Visualization/qcustomplot.h</header>
155 <container>1</container>
149 <container>1</container>
156 </customwidget>
150 </customwidget>
157 </customwidgets>
151 </customwidgets>
158 <tabstops>
152 <tabstops>
159 <tabstop>gradientComboBox</tabstop>
153 <tabstop>gradientComboBox</tabstop>
160 <tabstop>thresholdAutoButton</tabstop>
154 <tabstop>thresholdAutoButton</tabstop>
161 <tabstop>okButton</tabstop>
162 <tabstop>thresholdManualButton</tabstop>
155 <tabstop>thresholdManualButton</tabstop>
163 <tabstop>maxSpinBox</tabstop>
164 <tabstop>minSpinBox</tabstop>
156 <tabstop>minSpinBox</tabstop>
157 <tabstop>maxSpinBox</tabstop>
158 <tabstop>okButton</tabstop>
165 <tabstop>cancelButton</tabstop>
159 <tabstop>cancelButton</tabstop>
166 </tabstops>
160 </tabstops>
167 <resources/>
161 <resources/>
168 <connections/>
162 <connections/>
169 </ui>
163 </ui>
General Comments 0
You need to be logged in to leave comments. Login now