TSI_Config/rangeslider.cpp

139 lines
4.2 KiB
C++
Raw Normal View History

2025-04-17 14:06:21 +08:00
#include "rangeslider.h"
#include <QPainter>
#include <QMouseEvent>
#include <QDebug>
RangeSlider::RangeSlider(int style,QWidget *parent)
: QWidget(parent) {
setMinimumSize(20, 240);
}
void RangeSlider::setRange(int min, int max) {
m_min = min;
m_max = max;
m_lower = qBound(m_min, m_lower, m_max);
m_upper = qBound(m_lower, m_upper, m_max);
update();
}
void RangeSlider::setSliderWidth(int width) {
sliderWidth = width;
update(); // 更新界面
}
float RangeSlider::lowerValue() const { return m_lower; }
float RangeSlider::upperValue() const { return m_upper; }
float RangeSlider::valueToY(float value) const {
double ratio = (value - m_min) / double(m_max - m_min);
return height() - handleRadius - ratio * (height() - 2 * handleRadius);
}
float RangeSlider::yToValue(float y) const {
double ratio = (height() - handleRadius - y) / double(height() - 2 * handleRadius);
ratio = qBound(0.0, ratio, 1.0);
float rawValue = m_min + ratio * (m_max - m_min);
float steppedValue = qRound(rawValue * 10) / 10.0f;
return qBound(m_min, steppedValue, m_max);
}
RangeSlider::HandleType RangeSlider::handleHitTest(float y) const {
int yLower = valueToY(m_lower);
int yUpper = valueToY(m_upper);
if (qAbs(y - yLower) <= handleRadius + 2) return LowerHandle;
if (qAbs(y - yUpper) <= handleRadius + 2) return UpperHandle;
return NoHandle;
}
void RangeSlider::mousePressEvent(QMouseEvent *event) {
currentHandle = handleHitTest(event->pos().y());
}
void RangeSlider::mouseMoveEvent(QMouseEvent *event) {
if (currentHandle == NoHandle) return;
float val = yToValue(event->pos().y());
if (currentHandle == LowerHandle) {
m_lower = qBound(m_min, val, m_upper);
} else if (currentHandle == UpperHandle) {
m_upper = qBound(m_lower, val, m_max);
}
update();
emit rangeChanged(m_lower, m_upper);
}
void RangeSlider::mouseReleaseEvent(QMouseEvent *) {
currentHandle = NoHandle;
}
void RangeSlider::paintEvent(QPaintEvent *) {
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
int x = width() / 2;
int yLower = valueToY(m_lower);
int yUpper = valueToY(m_upper);
// Draw Temperature-style background (gradient)
drawTemperatureStyle(&p);
// Draw selected range (green)
// Draw selected range (green)
p.setPen(Qt::NoPen);
p.setBrush(Qt::green);
p.drawRect(x - sliderWidth / 2, yUpper, sliderWidth, yLower - yUpper);
// Draw simple red handles (circles)
p.setPen(Qt::NoPen);
p.setBrush(Qt::red);
p.drawEllipse(QPointF(x, yLower), handleRadius, handleRadius);
p.drawEllipse(QPointF(x, yUpper), handleRadius, handleRadius);
// Draw ticks
drawTicks(&p);
}
void RangeSlider::setLowerValue(float val) {
m_lower = qBound(m_min, val, m_upper);
update();
emit rangeChanged(m_lower, m_upper);
}
void RangeSlider::setUpperValue(float val) {
m_upper = qBound(m_lower, val, m_max);
update();
emit rangeChanged(m_lower, m_upper);
}
void RangeSlider::drawTemperatureStyle(QPainter *p) {
int x = width() / 2;
int yTop = handleRadius;
int yBottom = height() - handleRadius;
// Draw border (black)
p->setPen(Qt::black);
p->setBrush(Qt::NoBrush);
p->drawRect(x - sliderWidth / 2, yTop, sliderWidth, yBottom - yTop);
// Draw yellow outside the range
p->setBrush(Qt::yellow);
p->drawRect(x - sliderWidth / 2, yTop, sliderWidth, valueToY(m_lower) - yTop); // Above lower range
p->drawRect(x - sliderWidth / 2, valueToY(m_upper), sliderWidth, yBottom - valueToY(m_upper)); // Below upper range
// Draw green inside the range
p->setBrush(Qt::green);
p->drawRect(x - sliderWidth / 2, valueToY(m_upper), sliderWidth, valueToY(m_lower) - valueToY(m_upper)); // Green area
}
void RangeSlider::drawTicks(QPainter *p) {
int tickCount = 11;
p->setPen(Qt::black);
p->setFont(QFont("Arial", 8));
int x = width() / 2 + handleRadius + 4;
for (int i = 0; i < tickCount; ++i) {
int val = m_min + i * (m_max - m_min) / (tickCount - 1);
int y = valueToY(val);
p->drawLine(x, y, x + 3, y); // 刻度宽度
p->drawText(x + 8, y + 4, QString::number(val));
}
}