235 lines
6.6 KiB
C++
235 lines
6.6 KiB
C++
|
|
//
|
||
|
|
// Created by Krad on 2021/11/24.
|
||
|
|
//
|
||
|
|
|
||
|
|
#include "SlidePickerBox.h"
|
||
|
|
#include <QPainter>
|
||
|
|
#include <QMouseEvent>
|
||
|
|
#include <QLabel>
|
||
|
|
#include <QFont>
|
||
|
|
#include <qdebug.h>
|
||
|
|
const int fontSize = 80;
|
||
|
|
SlidePickerBox::SlidePickerBox(QWidget *parent):QWidget(parent) {
|
||
|
|
this->setFixedHeight(360);
|
||
|
|
|
||
|
|
QLabel* label = new QLabel(this);
|
||
|
|
label->setText("1");
|
||
|
|
label->setFixedHeight(110);
|
||
|
|
label->setAlignment(Qt::AlignCenter);
|
||
|
|
label->setObjectName("sliderPickerLabel");
|
||
|
|
label->setFixedHeight(fontSize);
|
||
|
|
label->setFixedWidth(320);
|
||
|
|
QPoint p = this->mapToGlobal({this->contentsMargins().left(),50-fontSize/2});
|
||
|
|
label->move(p);
|
||
|
|
lbls.push_back(label);
|
||
|
|
QLabel* label1 = new QLabel(this);
|
||
|
|
label1->setText("2");
|
||
|
|
label1->setFixedHeight(110);
|
||
|
|
label1->setAlignment(Qt::AlignCenter);
|
||
|
|
label1->setObjectName("sliderPickerLabel");
|
||
|
|
label1->setFixedHeight(fontSize);
|
||
|
|
label1->setFixedWidth(320);
|
||
|
|
QPoint p1 = this->mapToGlobal({this->contentsMargins().left(),150-fontSize/2});
|
||
|
|
label1->move(p1);
|
||
|
|
lbls.push_back(label1);
|
||
|
|
QLabel* label2 = new QLabel(this);
|
||
|
|
label2->setText("3");
|
||
|
|
label2->setFixedHeight(110);
|
||
|
|
label2->setAlignment(Qt::AlignCenter);
|
||
|
|
label2->setObjectName("sliderPickerLabel");
|
||
|
|
label2->setFixedHeight(fontSize);
|
||
|
|
label2->setFixedWidth(320);
|
||
|
|
QPoint p2 = this->mapToGlobal({this->contentsMargins().left(),250-fontSize/2});
|
||
|
|
label2->move(p2);
|
||
|
|
lbls.push_back(label2);
|
||
|
|
|
||
|
|
selectedLbl = label1;
|
||
|
|
label1->setStyleSheet("color:white");
|
||
|
|
label->setStyleSheet("background:transparent");
|
||
|
|
label2->setStyleSheet("background:transparent" );
|
||
|
|
QWidget* line1 = new QWidget(this);
|
||
|
|
line1->setFixedSize(320,100);
|
||
|
|
line1->setObjectName("topBottomLine");
|
||
|
|
line1->raise();
|
||
|
|
QPoint lp = this->mapToGlobal({this->contentsMargins().left(),100});
|
||
|
|
line1->move(lp);
|
||
|
|
|
||
|
|
selectedIndex = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
void SlidePickerBox::mousePressEvent(QMouseEvent * ev) {
|
||
|
|
isDragging = true;
|
||
|
|
o_x = ev->pos().x();
|
||
|
|
o_y = ev->pos().y();
|
||
|
|
QWidget::mousePressEvent( ev);
|
||
|
|
}
|
||
|
|
|
||
|
|
void SlidePickerBox::mouseMoveEvent(QMouseEvent *ev) {
|
||
|
|
if(lbls.count()<2) return;
|
||
|
|
if(isDragging)
|
||
|
|
{
|
||
|
|
int offset = (ev->pos().y()-o_y);
|
||
|
|
//防止速度过快
|
||
|
|
while(abs(offset)>50)
|
||
|
|
{
|
||
|
|
offset=offset/2;
|
||
|
|
}
|
||
|
|
//防止拉过头
|
||
|
|
int selectItemCenter = selectedLbl->geometry().center().y();
|
||
|
|
if (selectedLbl == lbls.last() && selectItemCenter<=150 && offset<0) return;
|
||
|
|
if (selectedLbl == lbls.first() && selectItemCenter>=150 && offset>0) return;
|
||
|
|
int i = 0;
|
||
|
|
for (auto item : lbls)
|
||
|
|
{
|
||
|
|
//不需要横向
|
||
|
|
//int nx = item->geometry().left()+(ev->pos().x()-o_x);
|
||
|
|
int ny = item->geometry().top() + offset;
|
||
|
|
|
||
|
|
item->move(item->geometry().left(),ny);
|
||
|
|
int nc = item->geometry().center().y();
|
||
|
|
|
||
|
|
if (nc<=200 && nc>100)
|
||
|
|
{
|
||
|
|
item->setStyleSheet("color:white");
|
||
|
|
selectedLbl = item;
|
||
|
|
selectedIndex = i;
|
||
|
|
} else{
|
||
|
|
item->setStyleSheet("background:transparent");
|
||
|
|
}
|
||
|
|
i++;
|
||
|
|
}
|
||
|
|
o_x = ev->pos().x();
|
||
|
|
o_y = ev->pos().y();
|
||
|
|
repaint();
|
||
|
|
}
|
||
|
|
QWidget::mouseMoveEvent(ev);
|
||
|
|
}
|
||
|
|
|
||
|
|
void SlidePickerBox::mouseReleaseEvent(QMouseEvent *ev) {
|
||
|
|
isDragging = false;
|
||
|
|
adjustPositon();
|
||
|
|
QWidget::mouseReleaseEvent(ev);
|
||
|
|
}
|
||
|
|
|
||
|
|
void SlidePickerBox::adjustPositon() const {
|
||
|
|
if (selectedLbl->geometry().center().y() != 150)
|
||
|
|
{
|
||
|
|
//选择完毕,选中项回归正位
|
||
|
|
|
||
|
|
int offset = 150 - selectedLbl->geometry().center().y();
|
||
|
|
for (auto item : lbls)
|
||
|
|
{
|
||
|
|
int ny = item->geometry().top()+offset;
|
||
|
|
item->move(item->geometry().left(),ny);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void SlidePickerBox::paintEvent(QPaintEvent *ev) {
|
||
|
|
QWidget::paintEvent(ev);
|
||
|
|
}
|
||
|
|
|
||
|
|
void SlidePickerBox::paintText(QString txt, int x, int y, const QColor& color) {
|
||
|
|
QPainter painter(this);
|
||
|
|
painter.setRenderHint(QPainter::TextAntialiasing, true);
|
||
|
|
QFont f;
|
||
|
|
f.setPixelSize(30);
|
||
|
|
painter.setFont(f);
|
||
|
|
painter.setPen(color);
|
||
|
|
painter.drawText(x,y,txt);
|
||
|
|
}
|
||
|
|
|
||
|
|
void SlidePickerBox::setItems(QStringList itemsList) {
|
||
|
|
this->items = itemsList;
|
||
|
|
hideLabel(selectedLbl);
|
||
|
|
hideLabel(prevLbl);
|
||
|
|
hideLabel(nextLbl);
|
||
|
|
for (auto item : lbls)
|
||
|
|
{
|
||
|
|
delete item;
|
||
|
|
}
|
||
|
|
selectedLbl = nullptr;
|
||
|
|
prevLbl = nullptr;
|
||
|
|
nextLbl = nullptr;
|
||
|
|
lbls.clear();
|
||
|
|
|
||
|
|
for (QString str : this->items)
|
||
|
|
{
|
||
|
|
QLabel* lbl = new QLabel(this);
|
||
|
|
lbl->setText(str);
|
||
|
|
lbl->setFixedHeight(110);
|
||
|
|
lbl->setAlignment(Qt::AlignCenter);
|
||
|
|
lbl->setObjectName("sliderPickerLabel");
|
||
|
|
lbl->setFixedHeight(fontSize);
|
||
|
|
lbl->setFixedWidth(320);
|
||
|
|
lbls.push_back(lbl);
|
||
|
|
QPoint p = this->mapToGlobal({this->contentsMargins().left(),-150});
|
||
|
|
lbl->move(p);
|
||
|
|
}
|
||
|
|
selectedIndex = lbls.count()-1;
|
||
|
|
setSelectedValue(this->items.last());
|
||
|
|
}
|
||
|
|
|
||
|
|
QString SlidePickerBox::getSelectedValue() {
|
||
|
|
if (!selectedLbl) return "";
|
||
|
|
return selectedLbl->text();
|
||
|
|
}
|
||
|
|
|
||
|
|
void SlidePickerBox::setCurrentLabel(QLabel *label) {
|
||
|
|
if (selectedLbl)hideLabel(selectedLbl);
|
||
|
|
if (label) {
|
||
|
|
QPoint lp = this->mapToGlobal({this->contentsMargins().left(), 100});
|
||
|
|
label->move(lp);
|
||
|
|
label->show();
|
||
|
|
selectedLbl = label;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void SlidePickerBox::setNextLabel(QLabel *label) {
|
||
|
|
if (nextLbl)hideLabel(nextLbl);
|
||
|
|
if (label){
|
||
|
|
QPoint lp = this->mapToGlobal({this->contentsMargins().left(),200});
|
||
|
|
label->move(lp);
|
||
|
|
label->show();
|
||
|
|
nextLbl = label;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void SlidePickerBox::setPrevLabel(QLabel *label) {
|
||
|
|
if (prevLbl)hideLabel(prevLbl);
|
||
|
|
if (label) {
|
||
|
|
QPoint lp = this->mapToGlobal({this->contentsMargins().left(), 0});
|
||
|
|
label->move(lp);
|
||
|
|
label->show();
|
||
|
|
prevLbl = label;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void SlidePickerBox::hideLabel(QLabel *label) {
|
||
|
|
if (!label) return;
|
||
|
|
QPoint lp = this->mapToGlobal({this->contentsMargins().left(), -150});
|
||
|
|
label->move(lp);
|
||
|
|
}
|
||
|
|
|
||
|
|
void SlidePickerBox::setSelectedValue(QString& val) {
|
||
|
|
qDebug()<<"set value:"<<val;
|
||
|
|
for (int i = 0; i < lbls.count() ; ++i) {
|
||
|
|
if(lbls[i]->text() == val) {
|
||
|
|
selectedIndex = i;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
int first_y = -100 * (selectedIndex-1);
|
||
|
|
for (int i = 0; i < lbls.count() ; ++i) {
|
||
|
|
QPoint lp = {this->contentsMargins().left(), first_y+i*100};
|
||
|
|
lbls[i]->move(lp);
|
||
|
|
lbls[i]->show();
|
||
|
|
lbls[i]->setStyleSheet("background:transparent");
|
||
|
|
lbls[i]->lower();
|
||
|
|
}
|
||
|
|
selectedLbl = lbls[selectedIndex];
|
||
|
|
lbls[selectedIndex]->setStyleSheet("color:white");
|
||
|
|
adjustPositon();
|
||
|
|
}
|
||
|
|
|