ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
ecvAxesGridDialog.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #include "ecvAxesGridDialog.h"
9 
10 #include <QCheckBox>
11 #include <QColorDialog>
12 #include <QDialogButtonBox>
13 #include <QDoubleSpinBox>
14 #include <QFormLayout>
15 #include <QGroupBox>
16 #include <QHBoxLayout>
17 #include <QLabel>
18 #include <QLineEdit>
19 #include <QPushButton>
20 #include <QVBoxLayout>
21 
22 #include "ecvCustomLabelsWidget.h"
23 
24 ecvAxesGridDialog::ecvAxesGridDialog(const QString& title, QWidget* parent)
25  : QDialog(parent), m_currentColor(127, 127, 127) {
26  setWindowTitle(title);
27  // Non-modal for real-time preview (ParaView-style)
28  setWindowModality(Qt::NonModal);
29  setWindowFlags(Qt::Window | Qt::WindowTitleHint |
30  Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint);
31  setupUI();
32  setMinimumWidth(400);
33  setMinimumHeight(500);
34 }
35 
37 
38 void ecvAxesGridDialog::setupUI() {
39  QVBoxLayout* mainLayout = new QVBoxLayout(this);
40  mainLayout->setSpacing(8);
41  mainLayout->setContentsMargins(10, 10, 10, 10);
42 
43  // Section 1: Title Texts
44  QGroupBox* titleTextsGroup = new QGroupBox(tr("Title Texts"), this);
45  QFormLayout* titleTextsLayout = new QFormLayout(titleTextsGroup);
46  titleTextsLayout->setContentsMargins(8, 12, 8, 8);
47 
48  m_xTitleEdit = new QLineEdit("X Axis", this);
49  titleTextsLayout->addRow(tr("X Title:"), m_xTitleEdit);
50 
51  m_yTitleEdit = new QLineEdit("Y Axis", this);
52  titleTextsLayout->addRow(tr("Y Title:"), m_yTitleEdit);
53 
54  m_zTitleEdit = new QLineEdit("Z Axis", this);
55  titleTextsLayout->addRow(tr("Z Title:"), m_zTitleEdit);
56 
57  mainLayout->addWidget(titleTextsGroup);
58 
59  // Section 2: Face Properties
60  QGroupBox* facePropertiesGroup = new QGroupBox(tr("Face Properties"), this);
61  QFormLayout* faceLayout = new QFormLayout(facePropertiesGroup);
62  faceLayout->setContentsMargins(8, 12, 8, 8);
63 
64  m_gridColorButton = new QPushButton(this);
65  m_gridColorButton->setFixedSize(80, 24);
66  updateColorButton();
67  connect(m_gridColorButton, &QPushButton::clicked, this,
68  &ecvAxesGridDialog::onColorButtonClicked);
69  faceLayout->addRow(tr("Grid Color:"), m_gridColorButton);
70 
71  m_showGridCheckBox = new QCheckBox(this);
72  m_showGridCheckBox->setChecked(false);
73  faceLayout->addRow(tr("Show Grid:"), m_showGridCheckBox);
74 
75  mainLayout->addWidget(facePropertiesGroup);
76 
77  // Section 3: X Axis
78  m_xAxisGroup = new QGroupBox(tr("X Axis Label Properties"), this);
79  QVBoxLayout* xAxisLayout = new QVBoxLayout(m_xAxisGroup);
80  xAxisLayout->setContentsMargins(8, 12, 8, 8);
81 
82  m_xAxisUseCustomLabelsCheckBox =
83  new QCheckBox(tr("X Axis Use Custom Labels"), this);
84  xAxisLayout->addWidget(m_xAxisUseCustomLabelsCheckBox);
85 
86  m_xAxisCustomLabelsWidget = new ecvCustomLabelsWidget(this);
87  m_xAxisCustomLabelsWidget->setVisible(false);
88  xAxisLayout->addWidget(m_xAxisCustomLabelsWidget);
89 
90  connect(m_xAxisUseCustomLabelsCheckBox, &QCheckBox::toggled, this,
91  &ecvAxesGridDialog::onXAxisUseCustomLabelsToggled);
92 
93  mainLayout->addWidget(m_xAxisGroup);
94 
95  // Section 4: Y Axis
96  m_yAxisGroup = new QGroupBox(tr("Y Axis Label Properties"), this);
97  QVBoxLayout* yAxisLayout = new QVBoxLayout(m_yAxisGroup);
98  yAxisLayout->setContentsMargins(8, 12, 8, 8);
99 
100  m_yAxisUseCustomLabelsCheckBox =
101  new QCheckBox(tr("Y Axis Use Custom Labels"), this);
102  yAxisLayout->addWidget(m_yAxisUseCustomLabelsCheckBox);
103 
104  m_yAxisCustomLabelsWidget = new ecvCustomLabelsWidget(this);
105  m_yAxisCustomLabelsWidget->setVisible(false);
106  yAxisLayout->addWidget(m_yAxisCustomLabelsWidget);
107 
108  connect(m_yAxisUseCustomLabelsCheckBox, &QCheckBox::toggled, this,
109  &ecvAxesGridDialog::onYAxisUseCustomLabelsToggled);
110 
111  mainLayout->addWidget(m_yAxisGroup);
112 
113  // Section 5: Z Axis
114  m_zAxisGroup = new QGroupBox(tr("Z Axis Label Properties"), this);
115  QVBoxLayout* zAxisLayout = new QVBoxLayout(m_zAxisGroup);
116  zAxisLayout->setContentsMargins(8, 12, 8, 8);
117 
118  m_zAxisUseCustomLabelsCheckBox =
119  new QCheckBox(tr("Z Axis Use Custom Labels"), this);
120  zAxisLayout->addWidget(m_zAxisUseCustomLabelsCheckBox);
121 
122  m_zAxisCustomLabelsWidget = new ecvCustomLabelsWidget(this);
123  m_zAxisCustomLabelsWidget->setVisible(false);
124  zAxisLayout->addWidget(m_zAxisCustomLabelsWidget);
125 
126  connect(m_zAxisUseCustomLabelsCheckBox, &QCheckBox::toggled, this,
127  &ecvAxesGridDialog::onZAxisUseCustomLabelsToggled);
128 
129  mainLayout->addWidget(m_zAxisGroup);
130 
131  // Section 6: Bounds (ParaView-style)
132  QGroupBox* boundsGroup = new QGroupBox(tr("Bounds"), this);
133  QVBoxLayout* boundsLayout = new QVBoxLayout(boundsGroup);
134  boundsLayout->setContentsMargins(8, 12, 8, 8);
135 
136  m_useCustomBoundsCheckBox = new QCheckBox(tr("Use Custom Bounds"), this);
137  boundsLayout->addWidget(m_useCustomBoundsCheckBox);
138 
139  // Custom bounds input fields (6 spinboxes: xmin, xmax, ymin, ymax, zmin,
140  // zmax)
141  m_customBoundsWidget = new QWidget(this);
142  QFormLayout* boundsInputLayout = new QFormLayout(m_customBoundsWidget);
143  boundsInputLayout->setContentsMargins(20, 8, 8,
144  8); // Indent for visual hierarchy
145 
146  m_xMinSpinBox = new QDoubleSpinBox(m_customBoundsWidget);
147  m_xMinSpinBox->setRange(-1e10, 1e10);
148  m_xMinSpinBox->setDecimals(3);
149  m_xMinSpinBox->setValue(0.0); // Default: 0.0
150  boundsInputLayout->addRow(tr("X Min:"), m_xMinSpinBox);
151 
152  m_xMaxSpinBox = new QDoubleSpinBox(m_customBoundsWidget);
153  m_xMaxSpinBox->setRange(-1e10, 1e10);
154  m_xMaxSpinBox->setDecimals(3);
155  m_xMaxSpinBox->setValue(1.0); // Default: 1.0
156  boundsInputLayout->addRow(tr("X Max:"), m_xMaxSpinBox);
157 
158  m_yMinSpinBox = new QDoubleSpinBox(m_customBoundsWidget);
159  m_yMinSpinBox->setRange(-1e10, 1e10);
160  m_yMinSpinBox->setDecimals(3);
161  m_yMinSpinBox->setValue(0.0); // Default: 0.0
162  boundsInputLayout->addRow(tr("Y Min:"), m_yMinSpinBox);
163 
164  m_yMaxSpinBox = new QDoubleSpinBox(m_customBoundsWidget);
165  m_yMaxSpinBox->setRange(-1e10, 1e10);
166  m_yMaxSpinBox->setDecimals(3);
167  m_yMaxSpinBox->setValue(1.0); // Default: 1.0
168  boundsInputLayout->addRow(tr("Y Max:"), m_yMaxSpinBox);
169 
170  m_zMinSpinBox = new QDoubleSpinBox(m_customBoundsWidget);
171  m_zMinSpinBox->setRange(-1e10, 1e10);
172  m_zMinSpinBox->setDecimals(3);
173  m_zMinSpinBox->setValue(0.0); // Default: 0.0
174  boundsInputLayout->addRow(tr("Z Min:"), m_zMinSpinBox);
175 
176  m_zMaxSpinBox = new QDoubleSpinBox(m_customBoundsWidget);
177  m_zMaxSpinBox->setRange(-1e10, 1e10);
178  m_zMaxSpinBox->setDecimals(3);
179  m_zMaxSpinBox->setValue(1.0); // Default: 1.0
180  boundsInputLayout->addRow(tr("Z Max:"), m_zMaxSpinBox);
181 
182  m_customBoundsWidget->setVisible(
183  false); // Initially hidden (ParaView default)
184  boundsLayout->addWidget(m_customBoundsWidget);
185 
186  connect(m_useCustomBoundsCheckBox, &QCheckBox::toggled, this,
187  &ecvAxesGridDialog::onUseCustomBoundsToggled);
188 
189  mainLayout->addWidget(boundsGroup);
190 
191  // Buttons
192  QDialogButtonBox* buttonBox = new QDialogButtonBox(this);
193  QPushButton* applyButton = buttonBox->addButton(QDialogButtonBox::Apply);
194  QPushButton* resetButton = buttonBox->addButton(QDialogButtonBox::Reset);
195  buttonBox->addButton(QDialogButtonBox::Cancel);
196  buttonBox->addButton(QDialogButtonBox::Ok);
197 
198  connect(applyButton, &QPushButton::clicked, this,
199  &ecvAxesGridDialog::onApply);
200  connect(resetButton, &QPushButton::clicked, this,
201  &ecvAxesGridDialog::onReset);
202  connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
203  connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
204 
205  mainLayout->addWidget(buttonBox);
206 
207  storeInitialValues();
208 }
209 
210 void ecvAxesGridDialog::updateColorButton() {
211  QString styleSheet = QString("QPushButton { background-color: rgb(%1, %2, "
212  "%3); border: 1px solid #999; }")
213  .arg(m_currentColor.red())
214  .arg(m_currentColor.green())
215  .arg(m_currentColor.blue());
216  m_gridColorButton->setStyleSheet(styleSheet);
217 }
218 
219 void ecvAxesGridDialog::onColorButtonClicked() {
220  QColor newColor = QColorDialog::getColor(m_currentColor, this,
221  tr("Select Grid Color"));
222  if (newColor.isValid()) {
223  m_currentColor = newColor;
224  updateColorButton();
225  }
226 }
227 
228 void ecvAxesGridDialog::storeInitialValues() {
229  m_initialXTitle = m_xTitleEdit->text();
230  m_initialYTitle = m_yTitleEdit->text();
231  m_initialZTitle = m_zTitleEdit->text();
232  m_initialColor = m_currentColor;
233  m_initialShowGrid = m_showGridCheckBox->isChecked();
234  m_initialXCustomLabels = m_xAxisUseCustomLabelsCheckBox->isChecked();
235  m_initialYCustomLabels = m_yAxisUseCustomLabelsCheckBox->isChecked();
236  m_initialZCustomLabels = m_zAxisUseCustomLabelsCheckBox->isChecked();
237  m_initialXLabels = m_xAxisCustomLabelsWidget->getLabels();
238  m_initialYLabels = m_yAxisCustomLabelsWidget->getLabels();
239  m_initialZLabels = m_zAxisCustomLabelsWidget->getLabels();
240  m_initialCustomBounds = m_useCustomBoundsCheckBox->isChecked();
241 
242  // Store custom bounds values
243  m_initialXMin = m_xMinSpinBox->value();
244  m_initialXMax = m_xMaxSpinBox->value();
245  m_initialYMin = m_yMinSpinBox->value();
246  m_initialYMax = m_yMaxSpinBox->value();
247  m_initialZMin = m_zMinSpinBox->value();
248  m_initialZMax = m_zMaxSpinBox->value();
249 }
250 
251 void ecvAxesGridDialog::restoreInitialValues() {
252  m_xTitleEdit->setText(m_initialXTitle);
253  m_yTitleEdit->setText(m_initialYTitle);
254  m_zTitleEdit->setText(m_initialZTitle);
255  m_currentColor = m_initialColor;
256  updateColorButton();
257  m_showGridCheckBox->setChecked(m_initialShowGrid);
258  m_xAxisUseCustomLabelsCheckBox->setChecked(m_initialXCustomLabels);
259  m_yAxisUseCustomLabelsCheckBox->setChecked(m_initialYCustomLabels);
260  m_zAxisUseCustomLabelsCheckBox->setChecked(m_initialZCustomLabels);
261  m_xAxisCustomLabelsWidget->setLabels(m_initialXLabels);
262  m_yAxisCustomLabelsWidget->setLabels(m_initialYLabels);
263  m_zAxisCustomLabelsWidget->setLabels(m_initialZLabels);
264  m_useCustomBoundsCheckBox->setChecked(m_initialCustomBounds);
265 
266  // Restore custom bounds values
267  m_xMinSpinBox->setValue(m_initialXMin);
268  m_xMaxSpinBox->setValue(m_initialXMax);
269  m_yMinSpinBox->setValue(m_initialYMin);
270  m_yMaxSpinBox->setValue(m_initialYMax);
271  m_zMinSpinBox->setValue(m_initialZMin);
272  m_zMaxSpinBox->setValue(m_initialZMax);
273 }
274 
275 void ecvAxesGridDialog::onApply() {
276  emit applyRequested();
277  emit propertiesChanged();
278 }
279 
280 void ecvAxesGridDialog::onReset() {
281  restoreInitialValues();
282  emit applyRequested();
283  emit propertiesChanged();
284 }
285 
286 void ecvAxesGridDialog::onXAxisUseCustomLabelsToggled(bool checked) {
287  m_xAxisCustomLabelsWidget->setVisible(checked);
288  adjustSize();
289 }
290 
291 void ecvAxesGridDialog::onYAxisUseCustomLabelsToggled(bool checked) {
292  m_yAxisCustomLabelsWidget->setVisible(checked);
293  adjustSize();
294 }
295 
296 void ecvAxesGridDialog::onZAxisUseCustomLabelsToggled(bool checked) {
297  m_zAxisCustomLabelsWidget->setVisible(checked);
298  adjustSize();
299 }
300 
301 // Getters and Setters
302 QString ecvAxesGridDialog::getXTitle() const { return m_xTitleEdit->text(); }
303 void ecvAxesGridDialog::setXTitle(const QString& title) {
304  m_xTitleEdit->setText(title);
305 }
306 QString ecvAxesGridDialog::getYTitle() const { return m_yTitleEdit->text(); }
307 void ecvAxesGridDialog::setYTitle(const QString& title) {
308  m_yTitleEdit->setText(title);
309 }
310 QString ecvAxesGridDialog::getZTitle() const { return m_zTitleEdit->text(); }
311 void ecvAxesGridDialog::setZTitle(const QString& title) {
312  m_zTitleEdit->setText(title);
313 }
314 
315 QColor ecvAxesGridDialog::getGridColor() const { return m_currentColor; }
317  m_currentColor = color;
318  updateColorButton();
319 }
321  return m_showGridCheckBox->isChecked();
322 }
324  m_showGridCheckBox->setChecked(show);
325 }
326 
328  return m_xAxisUseCustomLabelsCheckBox->isChecked();
329 }
331  m_xAxisUseCustomLabelsCheckBox->setChecked(use);
332 }
333 QList<QPair<double, QString>> ecvAxesGridDialog::getXAxisCustomLabels() const {
334  return m_xAxisCustomLabelsWidget->getLabels();
335 }
337  const QList<QPair<double, QString>>& labels) {
338  m_xAxisCustomLabelsWidget->setLabels(labels);
339 }
340 
342  return m_yAxisUseCustomLabelsCheckBox->isChecked();
343 }
345  m_yAxisUseCustomLabelsCheckBox->setChecked(use);
346 }
347 QList<QPair<double, QString>> ecvAxesGridDialog::getYAxisCustomLabels() const {
348  return m_yAxisCustomLabelsWidget->getLabels();
349 }
351  const QList<QPair<double, QString>>& labels) {
352  m_yAxisCustomLabelsWidget->setLabels(labels);
353 }
354 
356  return m_zAxisUseCustomLabelsCheckBox->isChecked();
357 }
359  m_zAxisUseCustomLabelsCheckBox->setChecked(use);
360 }
361 QList<QPair<double, QString>> ecvAxesGridDialog::getZAxisCustomLabels() const {
362  return m_zAxisCustomLabelsWidget->getLabels();
363 }
365  const QList<QPair<double, QString>>& labels) {
366  m_zAxisCustomLabelsWidget->setLabels(labels);
367 }
368 
370  return m_useCustomBoundsCheckBox->isChecked();
371 }
373  m_useCustomBoundsCheckBox->setChecked(use);
374 }
375 
376 void ecvAxesGridDialog::onUseCustomBoundsToggled(bool checked) {
377  m_customBoundsWidget->setVisible(checked);
378  adjustSize();
379 }
380 
381 double ecvAxesGridDialog::getXMin() const { return m_xMinSpinBox->value(); }
382 void ecvAxesGridDialog::setXMin(double value) {
383  m_xMinSpinBox->setValue(value);
384 }
385 double ecvAxesGridDialog::getXMax() const { return m_xMaxSpinBox->value(); }
386 void ecvAxesGridDialog::setXMax(double value) {
387  m_xMaxSpinBox->setValue(value);
388 }
389 double ecvAxesGridDialog::getYMin() const { return m_yMinSpinBox->value(); }
390 void ecvAxesGridDialog::setYMin(double value) {
391  m_yMinSpinBox->setValue(value);
392 }
393 double ecvAxesGridDialog::getYMax() const { return m_yMaxSpinBox->value(); }
394 void ecvAxesGridDialog::setYMax(double value) {
395  m_yMaxSpinBox->setValue(value);
396 }
397 double ecvAxesGridDialog::getZMin() const { return m_zMinSpinBox->value(); }
398 void ecvAxesGridDialog::setZMin(double value) {
399  m_zMinSpinBox->setValue(value);
400 }
401 double ecvAxesGridDialog::getZMax() const { return m_zMaxSpinBox->value(); }
402 void ecvAxesGridDialog::setZMax(double value) {
403  m_zMaxSpinBox->setValue(value);
404 }
math::float4 color
void Reset(void)
double getXMin() const
bool getZAxisUseCustomLabels() const
bool getYAxisUseCustomLabels() const
void setZTitle(const QString &title)
double getYMin() const
double getZMax() const
void setZMin(double value)
void setZMax(double value)
QString getXTitle() const
void setXAxisCustomLabels(const QList< QPair< double, QString >> &labels)
void setZAxisUseCustomLabels(bool use)
void setXTitle(const QString &title)
QList< QPair< double, QString > > getZAxisCustomLabels() const
void setXMin(double value)
bool getXAxisUseCustomLabels() const
QList< QPair< double, QString > > getXAxisCustomLabels() const
void setXMax(double value)
double getYMax() const
void setGridColor(const QColor &color)
void setZAxisCustomLabels(const QList< QPair< double, QString >> &labels)
void setYMax(double value)
void setYAxisUseCustomLabels(bool use)
void setUseCustomBounds(bool use)
bool getUseCustomBounds() const
QString getYTitle() const
QString getZTitle() const
ecvAxesGridDialog(const QString &title, QWidget *parent=nullptr)
void setYMin(double value)
void setYTitle(const QString &title)
void setYAxisCustomLabels(const QList< QPair< double, QString >> &labels)
void setShowGrid(bool show)
double getXMax() const
QList< QPair< double, QString > > getYAxisCustomLabels() const
QColor getGridColor() const
~ecvAxesGridDialog() override
void propertiesChanged()
void setXAxisUseCustomLabels(bool use)
double getZMin() const
ParaView-style Custom Labels Editor Widget.
void setLabels(const QList< QPair< double, QString >> &labels)
QList< QPair< double, QString > > getLabels() const
struct Window Window
Definition: sqlite3.c:14678