#include "pch.h" #include "RangeSlider.h" #include #include #include "util.h" RangeSlider::RangeSlider(QWidget *parent) : QWidget(parent), sliderRangeColor(200,200,200), rangeColor(0,122,204) { QVBoxLayout* layoutOuter = new QVBoxLayout(this); layoutOuter->setContentsMargins(0, 0, 0, 0); QHBoxLayout* buttonPanelLayout = new QHBoxLayout(); buttonPanelLayout->setContentsMargins(0, 0, 0, 0); layoutOuter->addLayout(buttonPanelLayout); layoutOuter->insertStretch(1); titleLabel = new QLabel("Title"); buttonPanelLayout->addWidget(titleLabel); buttonPanelLayout->insertStretch(1); QComboBox* combobox = new QComboBox(this); combobox->addItem("Range"); combobox->addItem("Iteration"); connect(combobox, static_cast(&QComboBox::currentIndexChanged), this, [this](int index) {this->setMode((DisplayMode)index); }); buttonPanelLayout->addWidget(combobox); this->setMaximumHeight(70); this->setMinimumHeight(70); } RangeSlider::~RangeSlider() { } void RangeSlider::setMinSliderValue(int value) { value = std::clamp(value, minRange, maxRange); if (value > maxSliderValue) { minSliderValue = maxSliderValue; maxSliderValue = value; emit minChanged(minSliderValue); emit maxChanged(maxSliderValue); } else { minSliderValue = value; emit minChanged(minSliderValue); } } void RangeSlider::setMaxSliderValue(int value) { value = std::clamp(value, minRange, maxRange); if (value < minSliderValue) { maxSliderValue = minSliderValue; minSliderValue = value; emit minChanged(minSliderValue); emit maxChanged(maxSliderValue); } else { maxSliderValue = value; emit maxChanged(maxSliderValue); } } void RangeSlider::setItertionSliderValue(int value) { value = std::clamp(value, minRange, maxRange); itertionSliderValue = value; emit minChanged(itertionSliderValue); emit maxChanged(itertionSliderValue); } void RangeSlider::setRange(int min, int max) { if (min > max) { std::swap(min, max); } minRange = min; maxRange = max; } int RangeSlider::getMinRange() const { return minRange; } int RangeSlider::getMaxRange() const { return maxRange; } void RangeSlider::setMinRange(int value) { if (value > maxRange) { minRange = maxRange; maxRange = value; } else { minRange = value; } emit minChanged(minSliderValue); } void RangeSlider::setMaxRange(int value) { if (value < minRange) { maxRange = minRange; minRange = value; } else { maxRange = value; } emit maxChanged(maxSliderValue); } void RangeSlider::setMode(DisplayMode mode) { this->mode = mode; switch (mode) { case Iteration: emit minChanged(itertionSliderValue); emit maxChanged(itertionSliderValue); break; default: case Range: emit minChanged(minSliderValue); emit maxChanged(maxSliderValue); break; } update(); } void RangeSlider::setTitle(QString string) { titleLabel->setText(string); } void RangeSlider::paintEvent(QPaintEvent* event) { QPainter painter(this); painter.setRenderHint(QPainter::RenderHint::HighQualityAntialiasing); painter.setPen(sliderRangeColor); //painter.setBrush(sliderRangeColor); //FindMiddle int middle = 35; painter.drawRect(QRect(QPoint(minPos(), middle + 2), QPoint(maxPos(), middle - 2))); painter.setPen(Qt::black); painter.setFont(QFont("Arial", 8)); QRect textRect(0, 0, 30, 9); textRect.moveCenter(QPoint(minPos(), middle + 20)); painter.drawText(textRect, Qt::AlignCenter, QString::number(this->minRange, 'f', 0)); textRect.moveCenter(QPoint(maxPos(), middle + 20)); painter.drawText(textRect, Qt::AlignCenter, QString::number(this->maxRange, 'f', 0)); //DrawSlider QPen pen(rangeColor); pen.setWidth(2); painter.setPen(pen); painter.setBrush(sliderRangeColor); switch (mode) { case Iteration: { double itertionSliderAlpha = util::inverseLinearInterpolation(minRange, maxRange, itertionSliderValue); double itertionSliderPos = util::linearInterpolate(minPos(), maxPos(), itertionSliderAlpha); painter.drawEllipse(QPointF(itertionSliderPos, (double)middle + 1), 10, 10); painter.setPen(Qt::black); textRect.moveCenter(QPoint(itertionSliderPos, middle + 20)); painter.drawText(textRect, Qt::AlignCenter, QString::number(this->itertionSliderValue, 'f', 0)); break; } default: case Range: { double minSliderAlpha = util::inverseLinearInterpolation(minRange, maxRange, minSliderValue); double minSliderPos = util::linearInterpolate(minPos(), maxPos(), minSliderAlpha); double maxSliderAlpha = util::inverseLinearInterpolation(minRange, maxRange, maxSliderValue); double maxSliderPos = util::linearInterpolate(minPos(), maxPos(), maxSliderAlpha); //DrawRange painter.fillRect(QRectF(QPointF(minSliderPos, (double)middle - 2), QPointF(maxSliderPos, (double)middle + 2)), rangeColor); painter.drawEllipse(QPointF(minSliderPos, (double)middle + 1), 10, 10); painter.drawEllipse(QPointF(maxSliderPos, (double)middle + 1), 10, 10); painter.setPen(Qt::black); textRect.moveCenter(QPoint(minSliderPos, middle + 20)); painter.drawText(textRect, Qt::AlignCenter, QString::number(this->minSliderValue, 'f', 0)); textRect.moveCenter(QPoint(maxSliderPos, middle + 20)); painter.drawText(textRect, Qt::AlignCenter, QString::number(this->maxSliderValue, 'f', 0)); break; } } } void RangeSlider::mouseMoveEvent(QMouseEvent* event) { if (childAt(event->pos()) != nullptr) { return; } updateSliderPosition(event); } void RangeSlider::mousePressEvent(QMouseEvent* event) { if (childAt(event->pos()) != nullptr) { return; } updateSliderPosition(event); } void RangeSlider::updateSliderPosition(QMouseEvent* event) { //pos to alpha double alpha = util::inverseLinearInterpolation(minPos(), maxPos(), event->pos().x()); double minSliderAlpha = util::inverseLinearInterpolation(minRange, maxRange, minSliderValue); double maxSliderAlpha = util::inverseLinearInterpolation(minRange, maxRange, maxSliderValue); double value = util::linearInterpolate(minRange, maxRange, alpha); switch (mode) { case Iteration: setItertionSliderValue(value); break; default: case Range: double distanceToMin = std::abs(minSliderValue - value); double distanceToMax = std::abs(maxSliderValue - value); if (distanceToMin < distanceToMax) { setMinSliderValue(value); } else { setMaxSliderValue(value); } break; } update(); } int RangeSlider::maxPos() { return rect().right() - 11; } int RangeSlider::minPos() { return rect().left() + 11; }