Refactor SlidePickerBox.
This commit is contained in:
@@ -3,125 +3,113 @@
|
||||
//
|
||||
|
||||
#include "SlidePickerBox.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QLayout>
|
||||
#include <QMouseEvent>
|
||||
#include <QLabel>
|
||||
|
||||
#include <qdebug.h>
|
||||
const int fontSize = 80;
|
||||
SlidePickerBox::SlidePickerBox(QWidget *parent):QWidget(parent) {
|
||||
|
||||
|
||||
namespace {
|
||||
const int LABEL_FONT_SIZE = 80;
|
||||
const int LABEL_CENTER_Y = 150;
|
||||
const int LABEL_HEIGHT = 110;
|
||||
const int LINE_HEIGHT = 100;
|
||||
const int LABEL_WIDTH = 320;
|
||||
const int MARGIN_LEFT = 0;
|
||||
const int MARGIN_TOP = 100;
|
||||
const int SELECTED_AREA_TOP = 100;
|
||||
const int SELECTED_AREA_BOTTOM = 200;
|
||||
}
|
||||
SlidePickerBox::SlidePickerBox(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, mIsDragging(false)
|
||||
, mOriginPosY(0)
|
||||
, mSelectedIndex(0)
|
||||
, mSelectedLbl(new QLabel(this))
|
||||
{
|
||||
this->setFixedHeight(360);
|
||||
mSelectedLbl->setText("2");
|
||||
mSelectedLbl->setFixedHeight(LABEL_HEIGHT);
|
||||
mSelectedLbl->setAlignment(Qt::AlignCenter);
|
||||
mSelectedLbl->setObjectName("sliderPickerLabel");
|
||||
mSelectedLbl->setFixedHeight(LABEL_FONT_SIZE);
|
||||
mSelectedLbl->setFixedWidth(LABEL_WIDTH);
|
||||
QPoint p1 = {MARGIN_LEFT, LABEL_CENTER_Y - LABEL_FONT_SIZE / 2};
|
||||
mSelectedLbl->move(p1);
|
||||
mLabels.push_back(mSelectedLbl);
|
||||
mSelectedLbl->setStyleSheet("color:white");
|
||||
|
||||
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 = {0,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 = {0,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 = {0,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 = {0,100};
|
||||
line1->move(lp);
|
||||
|
||||
selectedIndex = 1;
|
||||
auto linePlaceholderWidget = new QWidget(this);
|
||||
linePlaceholderWidget->setFixedSize(LABEL_WIDTH, LINE_HEIGHT);
|
||||
linePlaceholderWidget->setObjectName("topBottomLine");
|
||||
linePlaceholderWidget->raise();
|
||||
QPoint lp = {MARGIN_LEFT, MARGIN_TOP};
|
||||
linePlaceholderWidget->move(lp);
|
||||
}
|
||||
|
||||
void SlidePickerBox::mousePressEvent(QMouseEvent * ev) {
|
||||
isDragging = true;
|
||||
o_x = ev->pos().x();
|
||||
o_y = ev->pos().y();
|
||||
mIsDragging = true;
|
||||
mOriginPosY = ev->pos().y();
|
||||
QWidget::mousePressEvent( ev);
|
||||
}
|
||||
|
||||
void SlidePickerBox::mouseMoveEvent(QMouseEvent *ev) {
|
||||
if(lbls.count()<2) return;
|
||||
if(isDragging)
|
||||
//只有一个label,无需滑动
|
||||
if (mLabels.count() < 2) return;
|
||||
if (nullptr == mSelectedLbl) return;
|
||||
if (mIsDragging)
|
||||
{
|
||||
int offset = (ev->pos().y()-o_y);
|
||||
int offset = (ev->pos().y() - mOriginPosY);
|
||||
//防止速度过快
|
||||
while(abs(offset)>50)
|
||||
{
|
||||
offset=offset/2;
|
||||
}
|
||||
//防止拉过头
|
||||
int selectItemCenter = selectedLbl->geometry().center().y();
|
||||
if (selectedLbl == getEnabledLastLabel() && selectItemCenter<=150 && offset<0) return;
|
||||
if (selectedLbl == getEnabledFirstLabel() && selectItemCenter>=150 && offset>0) return;
|
||||
int selItemCenterY = mSelectedLbl->geometry().center().y();
|
||||
if (mSelectedLbl == getEnabledLastLabel() && selItemCenterY <= LABEL_CENTER_Y && offset < 0) return;
|
||||
if (mSelectedLbl == getEnabledFirstLabel() && selItemCenterY >= LABEL_CENTER_Y && offset > 0) return;
|
||||
int i = 0;
|
||||
for (auto item : lbls)
|
||||
for (auto item : mLabels)
|
||||
{
|
||||
if (disableItems.contains(item->text()))continue;
|
||||
|
||||
//不需要横向
|
||||
//int nx = item->geometry().left()+(ev->pos().x()-o_x);
|
||||
if (mDisabledItems.contains(item->text()))continue;
|
||||
//不需要横向,只需要纵向
|
||||
int ny = item->geometry().top() + offset;
|
||||
|
||||
item->move(item->geometry().left(),ny);
|
||||
int nc = item->geometry().center().y();
|
||||
|
||||
if (nc<=200 && nc>100)
|
||||
int centerY = item->geometry().center().y();
|
||||
if (centerY <= SELECTED_AREA_BOTTOM
|
||||
&& centerY > SELECTED_AREA_TOP)
|
||||
{
|
||||
item->setStyleSheet("color:white");
|
||||
selectedLbl = item;
|
||||
selectedIndex = i;
|
||||
mSelectedLbl = item;
|
||||
mSelectedIndex = i;
|
||||
} else{
|
||||
item->setStyleSheet("background:transparent");
|
||||
}
|
||||
i++;
|
||||
}
|
||||
o_x = ev->pos().x();
|
||||
o_y = ev->pos().y();
|
||||
mOriginPosY = ev->pos().y();
|
||||
repaint();
|
||||
}
|
||||
QWidget::mouseMoveEvent(ev);
|
||||
}
|
||||
|
||||
void SlidePickerBox::mouseReleaseEvent(QMouseEvent *ev) {
|
||||
isDragging = false;
|
||||
adjustPositon();
|
||||
mIsDragging = false;
|
||||
adjustPosition();
|
||||
QWidget::mouseReleaseEvent(ev);
|
||||
QString v = getSelectedValue();
|
||||
emit valueChanged(v);
|
||||
}
|
||||
|
||||
void SlidePickerBox::adjustPositon() const {
|
||||
if (selectedLbl->geometry().center().y() != 150)
|
||||
void SlidePickerBox::adjustPosition() const {
|
||||
if (mSelectedLbl->geometry().center().y() != LABEL_CENTER_Y)
|
||||
{
|
||||
//选择完毕,选中项回归正位
|
||||
|
||||
int offset = 150 - selectedLbl->geometry().center().y();
|
||||
for (auto item : lbls)
|
||||
int offset = LABEL_CENTER_Y - mSelectedLbl->geometry().center().y();
|
||||
for (auto item : mLabels)
|
||||
{
|
||||
int ny = item->geometry().top()+offset;
|
||||
item->move(item->geometry().left(),ny);
|
||||
@@ -129,148 +117,129 @@ void SlidePickerBox::adjustPositon() const {
|
||||
}
|
||||
}
|
||||
|
||||
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(const QStringList& itemsList) {
|
||||
this->items = itemsList;
|
||||
hideLabel(selectedLbl);
|
||||
hideLabel(prevLbl);
|
||||
hideLabel(nextLbl);
|
||||
for (auto item : lbls)
|
||||
this->mItems = itemsList;
|
||||
hideLabel(mSelectedLbl);
|
||||
for (auto item : mLabels)
|
||||
{
|
||||
delete item;
|
||||
}
|
||||
selectedLbl = nullptr;
|
||||
prevLbl = nullptr;
|
||||
nextLbl = nullptr;
|
||||
lbls.clear();
|
||||
|
||||
for (QString str : this->items)
|
||||
mSelectedLbl = nullptr;
|
||||
mLabels.clear();
|
||||
QPoint p = {MARGIN_LEFT,-LABEL_CENTER_Y};
|
||||
for (const QString& str : this->mItems)
|
||||
{
|
||||
QLabel* lbl = new QLabel(this);
|
||||
auto lbl = new QLabel(this);
|
||||
lbl->setText(str);
|
||||
lbl->setFixedHeight(110);
|
||||
lbl->setFixedHeight(LABEL_HEIGHT);
|
||||
lbl->setAlignment(Qt::AlignCenter);
|
||||
lbl->setObjectName("sliderPickerLabel");
|
||||
lbl->setFixedHeight(fontSize);
|
||||
lbl->setFixedWidth(320);
|
||||
lbls.push_back(lbl);
|
||||
QPoint p = {0,-150};
|
||||
lbl->setFixedHeight(LABEL_FONT_SIZE);
|
||||
lbl->setFixedWidth(LABEL_WIDTH);
|
||||
mLabels.push_back(lbl);
|
||||
lbl->move(p);
|
||||
}
|
||||
selectedIndex = lbls.count()-1;
|
||||
setSelectedValue(this->items.last());
|
||||
mSelectedIndex = mLabels.count() - 1;
|
||||
setSelectedValue(this->mItems.last());
|
||||
}
|
||||
|
||||
QString SlidePickerBox::getSelectedValue() {
|
||||
if (!selectedLbl) return "";
|
||||
return selectedLbl->text();
|
||||
if (!mSelectedLbl) return "";
|
||||
return mSelectedLbl->text();
|
||||
}
|
||||
|
||||
void SlidePickerBox::setCurrentLabel(QLabel *label) {
|
||||
if (selectedLbl)hideLabel(selectedLbl);
|
||||
if (mSelectedLbl)hideLabel(mSelectedLbl);
|
||||
if (label) {
|
||||
QPoint lp = {0, 100};
|
||||
label->move(lp);
|
||||
QPoint p = {MARGIN_LEFT, MARGIN_TOP};
|
||||
label->move(p);
|
||||
label->show();
|
||||
selectedLbl = label;
|
||||
mSelectedLbl = label;
|
||||
}
|
||||
}
|
||||
|
||||
QLabel * SlidePickerBox::getEnabledFirstLabel() {
|
||||
if (disableItems.empty()) return lbls.first();
|
||||
for(int idx = 0; idx<disableItems.size(); idx++){
|
||||
if(disableItems.contains(lbls[idx]->text()))continue;
|
||||
return lbls[idx];
|
||||
if (mDisabledItems.empty()) return mLabels.first();
|
||||
for(int idx = 0; idx < mDisabledItems.size(); ++idx){
|
||||
if(mDisabledItems.contains(mLabels[idx]->text()))continue;
|
||||
return mLabels[idx];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QLabel * SlidePickerBox::getEnabledLastLabel() {
|
||||
if (disableItems.empty()) return lbls.last();
|
||||
for(int idx = lbls.size()-1; idx>=0; idx--){
|
||||
if(disableItems.contains(lbls[idx]->text()))continue;
|
||||
return lbls[idx];
|
||||
if (mDisabledItems.empty()) return mLabels.last();
|
||||
for(int idx = mLabels.size() - 1; idx >= 0; --idx){
|
||||
if(mDisabledItems.contains(mLabels[idx]->text()))continue;
|
||||
return mLabels[idx];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SlidePickerBox::hideLabel(QLabel *label) {
|
||||
if (!label) return;
|
||||
QPoint lp = {0, -150};
|
||||
label->move(lp);
|
||||
QPoint p = {MARGIN_LEFT, -LABEL_CENTER_Y};
|
||||
label->move(p);
|
||||
}
|
||||
|
||||
void SlidePickerBox::setSelectedValue(const QString& val) {
|
||||
qDebug()<<"set value:"<<val;
|
||||
for (int i = 0; i < lbls.count() ; ++i) {
|
||||
if(lbls[i]->text() == val) {
|
||||
selectedIndex = i;
|
||||
for (int i = 0; i < mLabels.count() ; ++i) {
|
||||
if(mLabels[i]->text() == val) {
|
||||
mSelectedIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int first_y = -100 * (selectedIndex-1);
|
||||
for (int i = 0; i < lbls.count() ; ++i) {
|
||||
int firstLabelY = -LABEL_HEIGHT * (mSelectedIndex - 1);
|
||||
for (int i = 0; i < mLabels.count() ; ++i) {
|
||||
|
||||
QPoint lp = this->mapTo(this,{0, first_y+i*100});
|
||||
lbls[i]->move(lp);
|
||||
lbls[i]->show();
|
||||
lbls[i]->setStyleSheet("background:transparent");
|
||||
QPoint leftPoint = this->mapTo(this, {MARGIN_LEFT, firstLabelY + i * LABEL_HEIGHT});
|
||||
mLabels[i]->move(leftPoint);
|
||||
mLabels[i]->show();
|
||||
mLabels[i]->setStyleSheet("background:transparent");
|
||||
|
||||
}
|
||||
selectedLbl = lbls[selectedIndex];
|
||||
lbls[selectedIndex]->setStyleSheet("color:white");
|
||||
adjustPositon();
|
||||
mSelectedLbl = mLabels[mSelectedIndex];
|
||||
mLabels[mSelectedIndex]->setStyleSheet("color:white");
|
||||
adjustPosition();
|
||||
}
|
||||
|
||||
void SlidePickerBox::resizeLabelWidth() {
|
||||
for (int i = 0; i < lbls.count() ; ++i) {
|
||||
lbls[i]->setAlignment(defaultAlign);
|
||||
lbls[i]->setFixedWidth(this->width()+this->contentsMargins().left()+this->contentsMargins().right());
|
||||
for (int i = 0; i < mLabels.count() ; ++i) {
|
||||
mLabels[i]->setAlignment(Qt::AlignCenter);
|
||||
mLabels[i]->setFixedWidth(this->width() + this->contentsMargins().left() + this->contentsMargins().right());
|
||||
}
|
||||
}
|
||||
|
||||
void SlidePickerBox::disableItem(const QString& val) {
|
||||
if (!disableItems.contains(val)){
|
||||
disableItems.append(val);
|
||||
if (!mDisabledItems.contains(val)){
|
||||
mDisabledItems.append(val);
|
||||
rearrangeLabels();
|
||||
}
|
||||
}
|
||||
|
||||
void SlidePickerBox::enableItem(const QString &val) {
|
||||
if (disableItems.contains(val)){
|
||||
disableItems.removeOne(val);
|
||||
if (mDisabledItems.contains(val)){
|
||||
mDisabledItems.removeOne(val);
|
||||
rearrangeLabels();
|
||||
}
|
||||
}
|
||||
|
||||
void SlidePickerBox::rearrangeLabels() {
|
||||
int first_y = -100 * (selectedIndex-1);
|
||||
int r_index = 0;
|
||||
for (int i = 0; i < lbls.count() ; ++i) {
|
||||
if (disableItems.contains(lbls[i]->text())){
|
||||
lbls[i]->hide();
|
||||
int firstLabelY = -100 * (mSelectedIndex - 1);
|
||||
int visibleItemIndex = 0;
|
||||
for (int i = 0; i < mLabels.count() ; ++i) {
|
||||
if (mDisabledItems.contains(mLabels[i]->text())){
|
||||
mLabels[i]->hide();
|
||||
continue;
|
||||
}
|
||||
QPoint lp = this->mapTo(this,{0, first_y+r_index*100});
|
||||
r_index++;
|
||||
lbls[i]->move(lp);
|
||||
lbls[i]->show();
|
||||
lbls[i]->setStyleSheet("background:transparent");
|
||||
|
||||
QPoint p = this->mapTo(this, {MARGIN_LEFT, firstLabelY + visibleItemIndex * LABEL_HEIGHT});
|
||||
visibleItemIndex++;
|
||||
mLabels[i]->move(p);
|
||||
mLabels[i]->show();
|
||||
mLabels[i]->setStyleSheet("background:transparent");
|
||||
}
|
||||
selectedLbl = lbls[selectedIndex];
|
||||
lbls[selectedIndex]->setStyleSheet("color:white");
|
||||
adjustPositon();
|
||||
mSelectedLbl = mLabels[mSelectedIndex];
|
||||
mLabels[mSelectedIndex]->setStyleSheet("color:white");
|
||||
adjustPosition();
|
||||
}
|
||||
|
||||
|
||||
@@ -14,50 +14,38 @@ public:
|
||||
QString getSelectedValue();
|
||||
void setItems(const QStringList& itemsList);
|
||||
void addItem(QString& item) {
|
||||
this->items.append(item);
|
||||
this->mItems.append(item);
|
||||
}
|
||||
void disableItem(const QString& val);
|
||||
void enableItem(const QString& val);
|
||||
int getItemsCount(){
|
||||
return items.size();
|
||||
return mItems.size();
|
||||
}
|
||||
void setSelectedValue(const QString& val);
|
||||
void resizeLabelWidth();
|
||||
void setDefaultAlignment(QFlags<Qt::AlignmentFlag> align){
|
||||
this->defaultAlign = align;
|
||||
}
|
||||
signals:
|
||||
|
||||
signals:
|
||||
void valueChanged(QString & value);
|
||||
protected:
|
||||
|
||||
bool isDragging;
|
||||
// QPropertyAnimation *homingAni;
|
||||
|
||||
bool mIsDragging;
|
||||
void mousePressEvent(QMouseEvent * ev) override ;
|
||||
void mouseMoveEvent(QMouseEvent * ev) override ;
|
||||
void mouseReleaseEvent(QMouseEvent * ev) override ;
|
||||
void paintEvent(QPaintEvent * ev) override ;
|
||||
void paintText(QString txt,int x, int y, const QColor& color);
|
||||
void paintText(QString txt,int x, int y){
|
||||
paintText(txt, x, y, QColor(0,0,0));
|
||||
}
|
||||
void setCurrentLabel(QLabel* label);
|
||||
|
||||
QLabel * getEnabledLastLabel();
|
||||
QLabel * getEnabledFirstLabel();
|
||||
void hideLabel(QLabel* label);
|
||||
static void hideLabel(QLabel* label);
|
||||
void rearrangeLabels();
|
||||
private:
|
||||
int o_x=0,o_y=10;
|
||||
int selectedIndex = -1;
|
||||
QLabel* selectedLbl = nullptr;
|
||||
QLabel* prevLbl = nullptr;
|
||||
QLabel* nextLbl = nullptr;
|
||||
QList<QLabel*> lbls;
|
||||
QStringList items;
|
||||
QStringList disableItems;
|
||||
QFlags<Qt::AlignmentFlag> defaultAlign= Qt::AlignCenter;
|
||||
void adjustPositon() const;
|
||||
int mOriginPosY;
|
||||
int mSelectedIndex;
|
||||
QLabel* mSelectedLbl;
|
||||
QList<QLabel*> mLabels;
|
||||
QStringList mItems;
|
||||
QStringList mDisabledItems;
|
||||
void adjustPosition() const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user