Files
cbh/ElaWidgetTools/DeveloperComponents/ElaNavigationView.cpp
2025-09-20 01:41:33 +08:00

151 lines
5.8 KiB
C++

#include "ElaNavigationView.h"
#include <QDebug>
#include <QHeaderView>
#include <QModelIndex>
#include <QMouseEvent>
#include <QPainter>
#include <QScrollBar>
#include <QScroller>
#include "ElaMenu.h"
#include "ElaNavigationModel.h"
#include "ElaNavigationNode.h"
#include "ElaNavigationStyle.h"
#include "ElaScrollBar.h"
#include "ElaToolTip.h"
ElaNavigationView::ElaNavigationView(QWidget *parent) : QTreeView(parent) {
setObjectName("ElaNavigationView");
setStyleSheet("#ElaNavigationView{background-color:transparent;}");
setAnimated(true);
setHeaderHidden(true);
setRootIsDecorated(false);
setExpandsOnDoubleClick(false);
setAutoScroll(false);
setMouseTracking(true);
setSelectionMode(QAbstractItemView::NoSelection);
// 滚动条设置
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ElaScrollBar *vScrollBar = new ElaScrollBar(this);
connect(vScrollBar, &ElaScrollBar::rangeAnimationFinished, this, [=]() { doItemsLayout(); });
setVerticalScrollBar(vScrollBar);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
ElaScrollBar *floatVScrollBar = new ElaScrollBar(vScrollBar, this);
floatVScrollBar->setIsAnimation(true);
floatVScrollBar->installEventFilter(this);
_navigationStyle = new ElaNavigationStyle(this->style());
_navigationStyle->setNavigationView(this);
setStyle(_navigationStyle);
QScroller::grabGesture(this->viewport(), QScroller::LeftMouseButtonGesture);
QScroller *scroller = QScroller::scroller(this->viewport());
QScrollerProperties properties = scroller->scrollerProperties();
properties.setScrollMetric(QScrollerProperties::MousePressEventDelay, 0);
properties.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff);
properties.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, 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) {
_navigationStyle->setPressIndex(indexAt(mapFromGlobal(QCursor::pos())));
viewport()->update();
} else if (newstate == QScroller::Scrolling || newstate == QScroller::Inactive) {
_navigationStyle->setPressIndex(QModelIndex());
}
});
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, &ElaNavigationView::customContextMenuRequested, this, &ElaNavigationView::onCustomContextMenuRequested);
_compactToolTip = new ElaToolTip(this);
}
ElaNavigationView::~ElaNavigationView() {}
void ElaNavigationView::navigationNodeStateChange(QVariantMap data) { this->_navigationStyle->navigationNodeStateChange(data); }
void ElaNavigationView::onCustomContextMenuRequested(const QPoint &pos) {
if (!_pNavigationBarPrivate->_pIsAllowPageOpenInNewWindow) {
return;
}
QModelIndex posIndex = indexAt(pos);
if (!posIndex.isValid()) {
return;
}
ElaNavigationNode *posNode = static_cast<ElaNavigationNode *>(posIndex.internalPointer());
if (!posNode->getIsExpanderNode()) {
ElaMenu menu;
menu.setMenuItemHeight(27);
QAction *openAction = menu.addElaIconAction(ElaIconType::ObjectGroup, "在新窗口中打开");
connect(openAction, &QAction::triggered, this, [=]() { Q_EMIT navigationOpenNewWindow(posNode->getNodeKey()); });
menu.exec(mapToGlobal(pos));
}
}
void ElaNavigationView::mouseMoveEvent(QMouseEvent *event) {
if (_pNavigationBarPrivate->_currentDisplayMode == ElaNavigationType::NavigationDisplayMode::Compact) {
QModelIndex posIndex = indexAt(event->pos());
if (!posIndex.isValid()) {
_compactToolTip->hide();
return;
}
ElaNavigationNode *posNode = static_cast<ElaNavigationNode *>(posIndex.internalPointer());
_compactToolTip->setToolTip(posNode->getNodeTitle());
_compactToolTip->updatePos();
_compactToolTip->show();
} else {
_compactToolTip->hide();
}
QTreeView::mouseMoveEvent(event);
}
void ElaNavigationView::mouseDoubleClickEvent(QMouseEvent *event) {
_navigationStyle->setPressIndex(indexAt(event->pos()));
viewport()->update();
QTreeView::mouseDoubleClickEvent(event);
}
void ElaNavigationView::mouseReleaseEvent(QMouseEvent *event) {
QTreeView::mouseReleaseEvent(event);
if (event->button() == Qt::LeftButton) {
QModelIndex index = indexAt(event->pos());
if (index.isValid()) {
Q_EMIT navigationClicked(index);
}
_navigationStyle->setPressIndex(QModelIndex());
}
}
bool ElaNavigationView::eventFilter(QObject *watched, QEvent *event) {
switch (event->type()) {
case QEvent::MouseMove:
case QEvent::HoverMove: {
if (_pNavigationBarPrivate->_currentDisplayMode == ElaNavigationType::NavigationDisplayMode::Compact) {
QModelIndex posIndex = indexAt(mapFromGlobal(QCursor::pos()));
if (!posIndex.isValid()) {
_compactToolTip->hide();
break;
}
ElaNavigationNode *posNode = static_cast<ElaNavigationNode *>(posIndex.internalPointer());
_compactToolTip->setToolTip(posNode->getNodeTitle());
_compactToolTip->updatePos();
_compactToolTip->show();
} else {
_compactToolTip->hide();
}
break;
}
default: {
break;
}
}
return QAbstractItemView::eventFilter(watched, event);
}