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

186 lines
6.0 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);
}