Files
cbh/ElaWidgetTools/ElaPivot.cpp
2025-09-19 22:40:52 +08:00

171 lines
5.1 KiB
C++

#include "ElaPivot.h"
#include <QPainter>
#include <QScroller>
#include <QVBoxLayout>
#include "ElaPivotModel.h"
#include "ElaPivotPrivate.h"
#include "ElaPivotStyle.h"
#include "ElaPivotView.h"
ElaPivot::ElaPivot(QWidget* parent)
: QWidget{parent}, d_ptr(new ElaPivotPrivate())
{
Q_D(ElaPivot);
d->q_ptr = this;
d->_pTextPixelSize = 20;
setFixedHeight(40);
setObjectName("ElaPivot");
setStyleSheet("#ElaPivot{background-color:transparent;}");
setMouseTracking(true);
d->_listView = new ElaPivotView(this);
d->_listView->setMinimumHeight(0);
d->_listView->setFlow(QListView::LeftToRight);
d->_listView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
d->_listView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
d->_listModel = new ElaPivotModel(this);
d->_listView->setModel(d->_listModel);
d->_listStyle = new ElaPivotStyle(d->_listView->style());
d->_listView->setStyle(d->_listStyle);
d->_listView->setPivotStyle(d->_listStyle);
QFont textFont = this->font();
textFont.setLetterSpacing(QFont::AbsoluteSpacing, 0.5);
textFont.setPixelSize(d->_pTextPixelSize);
d->_listView->setFont(textFont);
QScroller::grabGesture(d->_listView->viewport(), QScroller::LeftMouseButtonGesture);
QScroller* scroller = QScroller::scroller(d->_listView->viewport());
QScrollerProperties properties = scroller->scrollerProperties();
properties.setScrollMetric(QScrollerProperties::MousePressEventDelay, 0);
properties.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QScrollerProperties::OvershootAlwaysOn);
properties.setScrollMetric(QScrollerProperties::OvershootDragResistanceFactor, 0.35);
properties.setScrollMetric(QScrollerProperties::OvershootScrollTime, 0.5);
properties.setScrollMetric(QScrollerProperties::FrameRate, QScrollerProperties::Fps60);
scroller->setScrollerProperties(properties);
connect(scroller, &QScroller::stateChanged, this, [=](QScroller::State newstate) {
if (newstate == QScroller::Pressed)
{
d->_listStyle->setPressIndex(d->_listView->indexAt(d->_listView->mapFromGlobal(QCursor::pos())));
d->_listView->viewport()->update();
}
else if (newstate == QScroller::Scrolling || newstate == QScroller::Inactive)
{
d->_listStyle->setPressIndex(QModelIndex());
d->_listView->viewport()->update();
}
});
connect(d->_listView, &ElaPivotView::clicked, this, [=](const QModelIndex& index) {
if (index.row() != d->_listStyle->getCurrentIndex())
{
Q_EMIT pCurrentIndexChanged();
}
d->_listView->doCurrentIndexChangedAnimation(index);
d->_listStyle->setCurrentIndex(index.row());
Q_EMIT pivotClicked(index.row());
});
connect(d->_listView, &ElaPivotView::doubleClicked, this, [=](const QModelIndex& index) {
Q_EMIT pivotDoubleClicked(index.row());
});
QVBoxLayout* mainLayout = new QVBoxLayout(this);
mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->addWidget(d->_listView);
}
ElaPivot::~ElaPivot()
{
Q_D(ElaPivot);
delete d->_listStyle;
}
void ElaPivot::appendPivot(QString pivotTitle)
{
Q_D(ElaPivot);
d->_listModel->appendPivot(pivotTitle);
d->_checkCurrentIndex();
}
void ElaPivot::removePivot(QString pivotTitle)
{
Q_D(ElaPivot);
d->_listModel->removePivot(pivotTitle);
d->_checkCurrentIndex();
}
void ElaPivot::setTextPixelSize(int textPixelSize)
{
Q_D(ElaPivot);
if (textPixelSize > 0)
{
d->_pTextPixelSize = textPixelSize;
QFont textFont = this->font();
textFont.setLetterSpacing(QFont::AbsoluteSpacing, 0.5);
textFont.setPixelSize(d->_pTextPixelSize);
d->_listView->setFont(textFont);
Q_EMIT pTextPixelSizeChanged();
}
}
int ElaPivot::getTextPixelSize() const
{
Q_D(const ElaPivot);
return d->_pTextPixelSize;
}
void ElaPivot::setCurrentIndex(int currentIndex)
{
Q_D(ElaPivot);
if (currentIndex < d->_listModel->getPivotListCount())
{
QModelIndex index = d->_listModel->index(currentIndex, 0);
d->_listView->doCurrentIndexChangedAnimation(index);
if (index.row() != d->_listStyle->getCurrentIndex())
{
Q_EMIT pCurrentIndexChanged();
}
d->_listStyle->setCurrentIndex(currentIndex);
}
}
int ElaPivot::getCurrentIndex() const
{
Q_D(const ElaPivot);
return d->_listView->currentIndex().row();
}
void ElaPivot::setPivotSpacing(int pivotSpacing)
{
Q_D(ElaPivot);
if (pivotSpacing >= 0)
{
d->_listStyle->setPivotSpacing(pivotSpacing);
d->_listView->doItemsLayout();
Q_EMIT pPivotSpacingChanged();
}
}
int ElaPivot::getPivotSpacing() const
{
Q_D(const ElaPivot);
return d->_listStyle->getPivotSpacing();
}
void ElaPivot::setMarkWidth(int markWidth)
{
Q_D(ElaPivot);
if (markWidth >= 0)
{
d->_listView->setMarkWidth(markWidth);
d->_listView->viewport()->update();
Q_EMIT pMarkWidthChanged();
}
}
int ElaPivot::getMarkWidth() const
{
Q_D(const ElaPivot);
return d->_listView->getMarkWidth();
}