Kstars

fitshistogrameditor.cpp
1 /*
2  SPDX-FileCopyrightText: 2015 Jasem Mutlaq <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "fitshistogrameditor.h"
8 
9 #include "fits_debug.h"
10 
11 #include "Options.h"
12 #include "fitsdata.h"
13 #include "fitstab.h"
14 #include "fitsview.h"
15 #include "fitsviewer.h"
16 
17 #include <KMessageBox>
18 
19 #include <QtConcurrent>
20 #include <type_traits>
21 
22 histogramUI::histogramUI(QDialog * parent) : QDialog(parent)
23 {
24  setupUi(parent);
25  setModal(false);
26 }
27 
28 FITSHistogramEditor::FITSHistogramEditor(QWidget * parent) : QDialog(parent)
29 {
30  ui = new histogramUI(this);
31 
32  minBoxes << ui->minREdit << ui->minGEdit << ui->minBEdit;
33  maxBoxes << ui->maxREdit << ui->maxGEdit << ui->maxBEdit;
34  sliders << ui->redSlider << ui->greenSlider << ui->blueSlider;
35 
36  ui->histogramPlot->setProperty("linear", !Options::nonLinearHistogram());
37 
38  connect(ui->applyB, &QPushButton::clicked, this, &FITSHistogramEditor::applyScale);
39  // connect(ui->hideSaturated, &QCheckBox::stateChanged, [this]()
40  // {
41  // m_ImageData->resetHistogram();
42  // m_ImageData->constructHistogram();
43  // ui->histogramPlot->syncGUI();
44  // });
45 
46  rgbWidgets.resize(3);
47  rgbWidgets[RED_CHANNEL] << ui->RLabel << ui->minREdit << ui->redSlider
48  << ui->maxREdit;
49  rgbWidgets[GREEN_CHANNEL] << ui->GLabel << ui->minGEdit << ui->greenSlider
50  << ui->maxGEdit;
51  rgbWidgets[BLUE_CHANNEL] << ui->BLabel << ui->minBEdit << ui->blueSlider
52  << ui->maxBEdit;
53 
54  for (int i = 0; i < 3; i++)
55  {
56  // Box --> Slider
57  QVector<QWidget *> w = rgbWidgets[i];
58  connect(qobject_cast<QDoubleSpinBox *>(w[1]), &QDoubleSpinBox::editingFinished, [this, i, w]()
59  {
60  double value = qobject_cast<QDoubleSpinBox *>(w[1])->value();
61  w[2]->blockSignals(true);
62  qobject_cast<ctkRangeSlider *>(w[2])->setMinimumPosition((value - m_ImageData->getMin(i))*sliderScale[i]);
63  w[2]->blockSignals(false);
64  });
65  connect(qobject_cast<QDoubleSpinBox *>(w[3]), &QDoubleSpinBox::editingFinished, [this, i, w]()
66  {
67  double value = qobject_cast<QDoubleSpinBox *>(w[3])->value();
68  w[2]->blockSignals(true);
69  qobject_cast<ctkRangeSlider *>(w[2])->setMaximumPosition((value - m_ImageData->getMin(i) - sliderTick[i])*sliderScale[i]);
70  w[2]->blockSignals(false);
71  });
72 
73  // Slider --> Box
74  connect(qobject_cast<ctkRangeSlider *>(w[2]), &ctkRangeSlider::minimumValueChanged, [this, i, w](int position)
75  {
76  qobject_cast<QDoubleSpinBox *>(w[1])->setValue(m_ImageData->getMin(i) + (position / sliderScale[i]));
77  });
78  connect(qobject_cast<ctkRangeSlider *>(w[2]), &ctkRangeSlider::maximumValueChanged, [this, i, w](int position)
79  {
80  qobject_cast<QDoubleSpinBox *>(w[3])->setValue(m_ImageData->getMin(i) + sliderTick[i] + (position / sliderScale[i]));
81  });
82  }
83 }
84 
85 void FITSHistogramEditor::showEvent(QShowEvent * event)
86 {
87  Q_UNUSED(event)
88  // if (!Options::nonLinearHistogram() && !m_ImageData->isHistogramConstructed())
89  // m_ImageData->constructHistogram();
90 
91  syncGUI();
92 
93 }
94 
95 //void FITSHistogramEditor::createNonLinearHistogram()
96 //{
97 // ui->histogramPlot->createNonLinearHistogram();
98 //}
99 
100 void FITSHistogramEditor::resizePlot()
101 {
102  ui->histogramPlot->resizePlot();
103 }
104 
105 void FITSHistogramEditor::syncGUI()
106 {
107  if (isGUISynced)
108  return;
109 
110  sliderTick.clear();
111  sliderScale.clear();
112  for (int n = 0; n < m_ImageData->channels(); n++)
113  {
114  sliderTick << fabs(m_ImageData->getMax(n) - m_ImageData->getMin(n)) / 99.0;
115  sliderScale << 99.0 / (m_ImageData->getMax(n) - m_ImageData->getMin(n) - sliderTick[n]);
116  }
117 
118  ui->histogramPlot->syncGUI();
119 
120  bool isColor = m_ImageData->channels() > 1;
121  // R/K is always enabled
122  for (auto w : rgbWidgets[RED_CHANNEL])
123  w->setEnabled(true);
124  // G Channel
125  for (auto w : rgbWidgets[GREEN_CHANNEL])
126  w->setEnabled(isColor);
127  // B Channel
128  for (auto w : rgbWidgets[BLUE_CHANNEL])
129  w->setEnabled(isColor);
130 
131  ui->meanEdit->setText(QString::number(m_ImageData->getMean()));
132  ui->medianEdit->setText(QString::number(m_ImageData->getMedian()));
133 
134  for (int n = 0; n < m_ImageData->channels(); n++)
135  {
136  double median = m_ImageData->getMedian(n);
137 
138  if (median > 100)
139  numDecimals << 0;
140  else if (median > 1)
141  numDecimals << 2;
142  else if (median > .01)
143  numDecimals << 4;
144  else if (median > .0001)
145  numDecimals << 6;
146  else
147  numDecimals << 10;
148 
149  minBoxes[n]->setDecimals(numDecimals[n]);
150  minBoxes[n]->setSingleStep(fabs(m_ImageData->getMax(n) - m_ImageData->getMin(n)) / 20.0);
151  minBoxes[n]->setMinimum(m_ImageData->getMin(n));
152  minBoxes[n]->setMaximum(m_ImageData->getMax(n) - sliderTick[n]);
153  minBoxes[n]->setValue(m_ImageData->getMin(n) + (sliders[n]->minimumValue() / sliderScale[n]));
154 
155  maxBoxes[n]->setDecimals(numDecimals[n]);
156  maxBoxes[n]->setSingleStep(fabs(m_ImageData->getMax(n) - m_ImageData->getMin(n)) / 20.0);
157  maxBoxes[n]->setMinimum(m_ImageData->getMin(n) + sliderTick[n]);
158  maxBoxes[n]->setMaximum(m_ImageData->getMax(n));
159  maxBoxes[n]->setValue(m_ImageData->getMin(n) + sliderTick[n] + (sliders[n]->maximumValue() / sliderScale[n]));
160  }
161 
162  ui->histogramPlot->syncGUI();
163 
164  isGUISynced = true;
165 }
166 
167 
168 
169 void FITSHistogramEditor::applyScale()
170 {
171  QVector<double> min, max;
172 
173  min << minBoxes[0]->value() << minBoxes[1]->value() << minBoxes[2]->value();
174  max << maxBoxes[0]->value() << maxBoxes[1]->value() << maxBoxes[2]->value();
175 
176  // if (ui->logR->isChecked())
177  // type = FITS_LOG;
178  // else
179  type = FITS_LINEAR;
180  emit newHistogramCommand(new FITSHistogramCommand(m_ImageData, this, type, min, max));
181 }
182 
183 void FITSHistogramEditor::applyFilter(FITSScale ftype)
184 {
185  QVector<double> min, max;
186  min.append(ui->minREdit->value());
187  type = ftype;
188 
189  emit newHistogramCommand(new FITSHistogramCommand(m_ImageData, this, type, min, max));
190 }
191 
192 void FITSHistogramEditor::setImageData(const QSharedPointer<FITSData> &data)
193 {
194  m_ImageData = data;
195  ui->histogramPlot->setImageData(data);
196 
197  connect(m_ImageData.data(), &FITSData::dataChanged, [this]
198  {
199  isGUISynced = false;
200  syncGUI();
201  });
202 }
void maximumValueChanged(int max)
This signal is emitted when the slider maximum value has changed, with the new slider value as argume...
QString number(int n, int base)
Type type(const QSqlDatabase &db)
T value() const const
void append(const T &value)
void clicked(bool checked)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
T value(int i) const const
QVariant value
FITS Header Key.
Definition: fitsdata.h:87
void editingFinished()
void minimumValueChanged(int min)
This signal is emitted when the slider minimum value has changed, with the new slider value as argume...
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Mon Aug 15 2022 04:04:01 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.