mirror of https://github.com/qt/qtgraphs.git
387 lines
14 KiB
C++
387 lines
14 KiB
C++
// Copyright (C) 2023 The Qt Company Ltd.
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
|
|
|
#include "surfacegraph.h"
|
|
|
|
#include <QtGui/qpainter.h>
|
|
#include <QtWidgets/qboxlayout.h>
|
|
#include <QtWidgets/qcheckbox.h>
|
|
#include <QtWidgets/qcombobox.h>
|
|
#include <QtWidgets/qcommandlinkbutton.h>
|
|
#include <QtWidgets/qgroupbox.h>
|
|
#include <QtWidgets/qlabel.h>
|
|
#include <QtWidgets/qradiobutton.h>
|
|
|
|
using namespace Qt::StringLiterals;
|
|
|
|
static QPixmap gradientBtoYPB_Pixmap()
|
|
{
|
|
QLinearGradient grBtoY(0, 0, 1, 100);
|
|
grBtoY.setColorAt(1.f, Qt::black);
|
|
grBtoY.setColorAt(0.67f, Qt::blue);
|
|
grBtoY.setColorAt(0.33f, Qt::red);
|
|
grBtoY.setColorAt(0.f, Qt::yellow);
|
|
QPixmap pm(24, 100);
|
|
QPainter pmp(&pm);
|
|
pmp.setBrush(QBrush(grBtoY));
|
|
pmp.setPen(Qt::NoPen);
|
|
pmp.drawRect(0, 0, 24, 100);
|
|
return pm;
|
|
}
|
|
|
|
static QPixmap gradientGtoRPB_Pixmap()
|
|
{
|
|
QLinearGradient grGtoR(0, 0, 1, 100);
|
|
grGtoR.setColorAt(1.f, Qt::darkGreen);
|
|
grGtoR.setColorAt(0.5f, Qt::yellow);
|
|
grGtoR.setColorAt(0.2f, Qt::red);
|
|
grGtoR.setColorAt(0.f, Qt::darkRed);
|
|
QPixmap pm(24, 100);
|
|
QPainter pmp(&pm);
|
|
pmp.setBrush(QBrush(grGtoR));
|
|
pmp.drawRect(0, 0, 24, 100);
|
|
return pm;
|
|
}
|
|
|
|
static QPixmap highlightPixmap()
|
|
{
|
|
constexpr int height = 400;
|
|
constexpr int width = 110;
|
|
constexpr int border = 10;
|
|
QLinearGradient gr(0, 0, 1, height - 2 * border);
|
|
gr.setColorAt(1.f, Qt::black);
|
|
gr.setColorAt(0.8f, Qt::darkGreen);
|
|
gr.setColorAt(0.6f, Qt::green);
|
|
gr.setColorAt(0.4f, Qt::yellow);
|
|
gr.setColorAt(0.2f, Qt::red);
|
|
gr.setColorAt(0.f, Qt::darkRed);
|
|
|
|
QPixmap pmHighlight(width, height);
|
|
pmHighlight.fill(Qt::transparent);
|
|
QPainter pmpHighlight(&pmHighlight);
|
|
pmpHighlight.setBrush(QBrush(gr));
|
|
pmpHighlight.setPen(Qt::NoPen);
|
|
pmpHighlight.drawRect(border, border, 35, height - 2 * border);
|
|
pmpHighlight.setPen(Qt::black);
|
|
int step = (height - 2 * border) / 5;
|
|
for (int i = 0; i < 6; ++i) {
|
|
int yPos = i * step + border;
|
|
pmpHighlight.drawLine(border, yPos, 55, yPos);
|
|
const int height = 550 - (i * 110);
|
|
pmpHighlight.drawText(60, yPos + 2, QString::number(height) + u" m"_s);
|
|
}
|
|
return pmHighlight;
|
|
}
|
|
|
|
SurfaceGraph::SurfaceGraph()
|
|
{
|
|
m_surfaceGraph = new Q3DSurface();
|
|
initialize();
|
|
}
|
|
|
|
void SurfaceGraph::initialize()
|
|
{
|
|
m_surfaceWidget = new QWidget;
|
|
auto *hLayout = new QHBoxLayout(m_surfaceWidget);
|
|
QSize screenSize = m_surfaceGraph->screen()->size();
|
|
m_surfaceGraph->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 1.75));
|
|
m_surfaceGraph->setMaximumSize(screenSize);
|
|
m_surfaceGraph->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
m_surfaceGraph->setFocusPolicy(Qt::StrongFocus);
|
|
m_surfaceGraph->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
|
hLayout->addWidget(m_surfaceGraph, 1);
|
|
|
|
auto *vLayout = new QVBoxLayout();
|
|
hLayout->addLayout(vLayout);
|
|
vLayout->setAlignment(Qt::AlignTop);
|
|
|
|
// Create control widgets
|
|
auto *modelGroupBox = new QGroupBox(u"Model"_s);
|
|
|
|
auto *sqrtSinModelRB = new QRadioButton(m_surfaceWidget);
|
|
sqrtSinModelRB->setText(u"Sqrt && Sin"_s);
|
|
sqrtSinModelRB->setChecked(false);
|
|
|
|
auto *heightMapModelRB = new QRadioButton(m_surfaceWidget);
|
|
heightMapModelRB->setText(u"Multiseries\nHeight Map"_s);
|
|
heightMapModelRB->setChecked(false);
|
|
|
|
auto *texturedModelRB = new QRadioButton(m_surfaceWidget);
|
|
texturedModelRB->setText(u"Textured\nTopography"_s);
|
|
texturedModelRB->setChecked(false);
|
|
|
|
auto *modelVBox = new QVBoxLayout;
|
|
modelVBox->addWidget(sqrtSinModelRB);
|
|
modelVBox->addWidget(heightMapModelRB);
|
|
modelVBox->addWidget(texturedModelRB);
|
|
modelGroupBox->setLayout(modelVBox);
|
|
|
|
auto *selectionGroupBox = new QGroupBox(u"Graph Selection Mode"_s);
|
|
|
|
auto *modeNoneRB = new QRadioButton(m_surfaceWidget);
|
|
modeNoneRB->setText(u"No selection"_s);
|
|
modeNoneRB->setChecked(false);
|
|
|
|
auto *modeItemRB = new QRadioButton(m_surfaceWidget);
|
|
modeItemRB->setText(u"Item"_s);
|
|
modeItemRB->setChecked(false);
|
|
|
|
auto *modeSliceRowRB = new QRadioButton(m_surfaceWidget);
|
|
modeSliceRowRB->setText(u"Row Slice"_s);
|
|
modeSliceRowRB->setChecked(false);
|
|
|
|
auto *modeSliceColumnRB = new QRadioButton(m_surfaceWidget);
|
|
modeSliceColumnRB->setText(u"Column Slice"_s);
|
|
modeSliceColumnRB->setChecked(false);
|
|
|
|
auto *selectionVBox = new QVBoxLayout;
|
|
selectionVBox->addWidget(modeNoneRB);
|
|
selectionVBox->addWidget(modeItemRB);
|
|
selectionVBox->addWidget(modeSliceRowRB);
|
|
selectionVBox->addWidget(modeSliceColumnRB);
|
|
selectionGroupBox->setLayout(selectionVBox);
|
|
|
|
auto *axisGroupBox = new QGroupBox(u"Axis ranges"_s);
|
|
|
|
auto *axisMinSliderX = new QSlider(Qt::Horizontal);
|
|
axisMinSliderX->setMinimum(0);
|
|
axisMinSliderX->setTickInterval(1);
|
|
axisMinSliderX->setEnabled(true);
|
|
auto *axisMaxSliderX = new QSlider(Qt::Horizontal);
|
|
axisMaxSliderX->setMinimum(1);
|
|
axisMaxSliderX->setTickInterval(1);
|
|
axisMaxSliderX->setEnabled(true);
|
|
auto *axisMinSliderZ = new QSlider(Qt::Horizontal);
|
|
axisMinSliderZ->setMinimum(0);
|
|
axisMinSliderZ->setTickInterval(1);
|
|
axisMinSliderZ->setEnabled(true);
|
|
auto *axisMaxSliderZ = new QSlider(Qt::Horizontal);
|
|
axisMaxSliderZ->setMinimum(1);
|
|
axisMaxSliderZ->setTickInterval(1);
|
|
axisMaxSliderZ->setEnabled(true);
|
|
|
|
auto *axisVBox = new QVBoxLayout;
|
|
axisVBox->addWidget(new QLabel(u"Column range"_s));
|
|
axisVBox->addWidget(axisMinSliderX);
|
|
axisVBox->addWidget(axisMaxSliderX);
|
|
axisVBox->addWidget(new QLabel(u"Row range"_s));
|
|
axisVBox->addWidget(axisMinSliderZ);
|
|
axisVBox->addWidget(axisMaxSliderZ);
|
|
axisGroupBox->setLayout(axisVBox);
|
|
|
|
// Mode-dependent controls
|
|
// sqrt-sin
|
|
auto *colorGroupBox = new QGroupBox(u"Custom gradient"_s);
|
|
|
|
QPixmap pixmap = gradientBtoYPB_Pixmap();
|
|
auto *gradientBtoYPB = new QPushButton(m_surfaceWidget);
|
|
gradientBtoYPB->setIcon(QIcon(pixmap));
|
|
gradientBtoYPB->setIconSize(pixmap.size());
|
|
|
|
pixmap = gradientGtoRPB_Pixmap();
|
|
auto *gradientGtoRPB = new QPushButton(m_surfaceWidget);
|
|
gradientGtoRPB->setIcon(QIcon(pixmap));
|
|
gradientGtoRPB->setIconSize(pixmap.size());
|
|
|
|
auto *colorHBox = new QHBoxLayout;
|
|
colorHBox->addWidget(gradientBtoYPB);
|
|
colorHBox->addWidget(gradientGtoRPB);
|
|
colorGroupBox->setLayout(colorHBox);
|
|
|
|
// Multiseries heightmap
|
|
auto *showGroupBox = new QGroupBox(u"_show Object"_s);
|
|
showGroupBox->setVisible(false);
|
|
|
|
auto *checkboxShowOilRigOne = new QCheckBox(u"Oil Rig 1"_s);
|
|
checkboxShowOilRigOne->setChecked(true);
|
|
|
|
auto *checkboxShowOilRigTwo = new QCheckBox(u"Oil Rig 2"_s);
|
|
checkboxShowOilRigTwo->setChecked(true);
|
|
|
|
auto *checkboxShowRefinery = new QCheckBox(u"Refinery"_s);
|
|
|
|
auto *showVBox = new QVBoxLayout;
|
|
showVBox->addWidget(checkboxShowOilRigOne);
|
|
showVBox->addWidget(checkboxShowOilRigTwo);
|
|
showVBox->addWidget(checkboxShowRefinery);
|
|
showGroupBox->setLayout(showVBox);
|
|
|
|
auto *visualsGroupBox = new QGroupBox(u"Visuals"_s);
|
|
visualsGroupBox->setVisible(false);
|
|
|
|
auto *checkboxVisualsSeeThrough = new QCheckBox(u"See-Through"_s);
|
|
|
|
auto *checkboxHighlightOil = new QCheckBox(u"Highlight Oil"_s);
|
|
|
|
auto *checkboxShowShadows = new QCheckBox(u"Shadows"_s);
|
|
checkboxShowShadows->setChecked(true);
|
|
|
|
auto *visualVBox = new QVBoxLayout;
|
|
visualVBox->addWidget(checkboxVisualsSeeThrough);
|
|
visualVBox->addWidget(checkboxHighlightOil);
|
|
visualVBox->addWidget(checkboxShowShadows);
|
|
visualsGroupBox->setLayout(visualVBox);
|
|
|
|
auto *labelSelection = new QLabel(u"Selection:"_s);
|
|
labelSelection->setVisible(false);
|
|
|
|
auto *labelSelectedItem = new QLabel(u"Nothing"_s);
|
|
labelSelectedItem->setVisible(false);
|
|
|
|
// Textured topography heightmap
|
|
auto *enableTexture = new QCheckBox(u"Surface texture"_s);
|
|
enableTexture->setVisible(false);
|
|
|
|
auto *label = new QLabel(m_surfaceWidget);
|
|
label->setPixmap(highlightPixmap());
|
|
|
|
auto *heightMapGroupBox = new QGroupBox(u"Highlight color map"_s);
|
|
auto *colorMapVBox = new QVBoxLayout;
|
|
colorMapVBox->addWidget(label);
|
|
heightMapGroupBox->setLayout(colorMapVBox);
|
|
heightMapGroupBox->setVisible(false);
|
|
|
|
// Populate vertical layout
|
|
// Common
|
|
vLayout->addWidget(modelGroupBox);
|
|
vLayout->addWidget(selectionGroupBox);
|
|
vLayout->addWidget(axisGroupBox);
|
|
|
|
// Sqrt Sin
|
|
vLayout->addWidget(colorGroupBox);
|
|
|
|
// Multiseries heightmap
|
|
vLayout->addWidget(showGroupBox);
|
|
vLayout->addWidget(visualsGroupBox);
|
|
vLayout->addWidget(labelSelection);
|
|
vLayout->addWidget(labelSelectedItem);
|
|
|
|
// Textured topography
|
|
vLayout->addWidget(heightMapGroupBox);
|
|
vLayout->addWidget(enableTexture);
|
|
|
|
// Raise the graph to the top of the widget stack, to hide UI if resized smaller
|
|
m_surfaceGraph->raise();
|
|
|
|
// Create the controller
|
|
m_modifier = new SurfaceGraphModifier(m_surfaceGraph, labelSelectedItem, this);
|
|
|
|
// Connect widget controls to controller
|
|
QObject::connect(heightMapModelRB,
|
|
&QRadioButton::toggled,
|
|
m_modifier,
|
|
&SurfaceGraphModifier::enableHeightMapModel);
|
|
QObject::connect(sqrtSinModelRB,
|
|
&QRadioButton::toggled,
|
|
m_modifier,
|
|
&SurfaceGraphModifier::enableSqrtSinModel);
|
|
QObject::connect(texturedModelRB,
|
|
&QRadioButton::toggled,
|
|
m_modifier,
|
|
&SurfaceGraphModifier::enableTopographyModel);
|
|
|
|
QObject::connect(modeNoneRB,
|
|
&QRadioButton::toggled,
|
|
m_modifier,
|
|
&SurfaceGraphModifier::toggleModeNone);
|
|
QObject::connect(modeItemRB,
|
|
&QRadioButton::toggled,
|
|
m_modifier,
|
|
&SurfaceGraphModifier::toggleModeItem);
|
|
QObject::connect(modeSliceRowRB,
|
|
&QRadioButton::toggled,
|
|
m_modifier,
|
|
&SurfaceGraphModifier::toggleModeSliceRow);
|
|
QObject::connect(modeSliceColumnRB,
|
|
&QRadioButton::toggled,
|
|
m_modifier,
|
|
&SurfaceGraphModifier::toggleModeSliceColumn);
|
|
|
|
QObject::connect(axisMinSliderX,
|
|
&QSlider::valueChanged,
|
|
m_modifier,
|
|
&SurfaceGraphModifier::adjustXMin);
|
|
QObject::connect(axisMaxSliderX,
|
|
&QSlider::valueChanged,
|
|
m_modifier,
|
|
&SurfaceGraphModifier::adjustXMax);
|
|
QObject::connect(axisMinSliderZ,
|
|
&QSlider::valueChanged,
|
|
m_modifier,
|
|
&SurfaceGraphModifier::adjustZMin);
|
|
QObject::connect(axisMaxSliderZ,
|
|
&QSlider::valueChanged,
|
|
m_modifier,
|
|
&SurfaceGraphModifier::adjustZMax);
|
|
|
|
// Mode dependent connections
|
|
QObject::connect(gradientBtoYPB,
|
|
&QPushButton::pressed,
|
|
m_modifier,
|
|
&SurfaceGraphModifier::setBlackToYellowGradient);
|
|
QObject::connect(gradientGtoRPB,
|
|
&QPushButton::pressed,
|
|
m_modifier,
|
|
&SurfaceGraphModifier::setGreenToRedGradient);
|
|
|
|
QObject::connect(checkboxShowOilRigOne,
|
|
&QCheckBox::stateChanged,
|
|
m_modifier,
|
|
&SurfaceGraphModifier::toggleItemOne);
|
|
QObject::connect(checkboxShowOilRigTwo,
|
|
&QCheckBox::stateChanged,
|
|
m_modifier,
|
|
&SurfaceGraphModifier::toggleItemTwo);
|
|
QObject::connect(checkboxShowRefinery,
|
|
&QCheckBox::stateChanged,
|
|
m_modifier,
|
|
&SurfaceGraphModifier::toggleItemThree);
|
|
|
|
QObject::connect(checkboxVisualsSeeThrough,
|
|
&QCheckBox::stateChanged,
|
|
m_modifier,
|
|
&SurfaceGraphModifier::toggleSeeThrough);
|
|
QObject::connect(checkboxHighlightOil,
|
|
&QCheckBox::stateChanged,
|
|
m_modifier,
|
|
&SurfaceGraphModifier::toggleOilHighlight);
|
|
QObject::connect(checkboxShowShadows,
|
|
&QCheckBox::stateChanged,
|
|
m_modifier,
|
|
&SurfaceGraphModifier::toggleShadows);
|
|
|
|
QObject::connect(enableTexture,
|
|
&QCheckBox::stateChanged,
|
|
m_modifier,
|
|
&SurfaceGraphModifier::toggleSurfaceTexture);
|
|
|
|
// Connections to disable features depending on mode
|
|
QObject::connect(sqrtSinModelRB, &QRadioButton::toggled, colorGroupBox, &QGroupBox::setVisible);
|
|
|
|
QObject::connect(heightMapModelRB, &QRadioButton::toggled, showGroupBox, &QGroupBox::setVisible);
|
|
QObject::connect(heightMapModelRB,
|
|
&QRadioButton::toggled,
|
|
visualsGroupBox,
|
|
&QGroupBox::setVisible);
|
|
QObject::connect(heightMapModelRB, &QRadioButton::toggled, labelSelection, &QLabel::setVisible);
|
|
QObject::connect(heightMapModelRB,
|
|
&QRadioButton::toggled,
|
|
labelSelectedItem,
|
|
&QLabel::setVisible);
|
|
|
|
QObject::connect(texturedModelRB, &QRadioButton::toggled, enableTexture, &QLabel::setVisible);
|
|
QObject::connect(texturedModelRB,
|
|
&QRadioButton::toggled,
|
|
heightMapGroupBox,
|
|
&QGroupBox::setVisible);
|
|
|
|
m_modifier->setAxisMinSliderX(axisMinSliderX);
|
|
m_modifier->setAxisMaxSliderX(axisMaxSliderX);
|
|
m_modifier->setAxisMinSliderZ(axisMinSliderZ);
|
|
m_modifier->setAxisMaxSliderZ(axisMaxSliderZ);
|
|
|
|
sqrtSinModelRB->setChecked(true);
|
|
modeItemRB->setChecked(true);
|
|
enableTexture->setChecked(true);
|
|
}
|