diff --git a/src/components/SlidePickerBox.cpp b/src/components/SlidePickerBox.cpp index 6ccb97c..22ebc60 100644 --- a/src/components/SlidePickerBox.cpp +++ b/src/components/SlidePickerBox.cpp @@ -3,125 +3,113 @@ // #include "SlidePickerBox.h" + #include +#include #include #include - #include -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; idxtext()))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:"<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(); } diff --git a/src/components/SlidePickerBox.h b/src/components/SlidePickerBox.h index f3e96f0..2a28632 100644 --- a/src/components/SlidePickerBox.h +++ b/src/components/SlidePickerBox.h @@ -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 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 lbls; - QStringList items; - QStringList disableItems; - QFlags defaultAlign= Qt::AlignCenter; - void adjustPositon() const; + int mOriginPosY; + int mSelectedIndex; + QLabel* mSelectedLbl; + QList mLabels; + QStringList mItems; + QStringList mDisabledItems; + void adjustPosition() const; };