2024-11-05 09:24:21 +08:00
|
|
|
|
#include "customTabBar.h"
|
|
|
|
|
|
#include "customTab.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include <QBoxLayout>
|
|
|
|
|
|
#include <QDragEnterEvent>
|
|
|
|
|
|
#include <QMimeData>
|
|
|
|
|
|
|
|
|
|
|
|
CustomTabBar::CustomTabBar(QWidget* parent)
|
|
|
|
|
|
:QScrollArea(parent)
|
|
|
|
|
|
{
|
|
|
|
|
|
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
|
|
|
|
|
setFrameStyle(QFrame::NoFrame);
|
|
|
|
|
|
setWidgetResizable(true);
|
|
|
|
|
|
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
|
|
|
|
setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
|
|
|
|
|
|
|
|
|
|
|
m_pPosMarking = new QWidget(this);
|
|
|
|
|
|
m_pPosMarking->setStyleSheet("QWidget{\n"
|
|
|
|
|
|
" border:0px;\n"
|
|
|
|
|
|
" background-color:rgb(200,200,200);\n"
|
|
|
|
|
|
"}\n");
|
|
|
|
|
|
m_pPosMarking->setMaximumWidth(3);
|
|
|
|
|
|
m_pPosMarking->setMinimumWidth(3);
|
|
|
|
|
|
m_pPosMarking->hide();
|
|
|
|
|
|
|
|
|
|
|
|
m_nCurrentIndex = -1;
|
|
|
|
|
|
m_pTabsContainerWidget = new QWidget(this);
|
|
|
|
|
|
m_pTabsContainerWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
|
|
|
|
|
m_pTabsContainerWidget->setObjectName("tabsContainerWidget");
|
|
|
|
|
|
m_pTabsLayout = new QBoxLayout(QBoxLayout::LeftToRight);
|
|
|
|
|
|
m_pTabsLayout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
|
m_pTabsLayout->setSpacing(0);
|
|
|
|
|
|
m_pTabsLayout->addStretch(1);
|
|
|
|
|
|
m_pTabsContainerWidget->setLayout(m_pTabsLayout);
|
|
|
|
|
|
setWidget(m_pTabsContainerWidget);
|
|
|
|
|
|
|
|
|
|
|
|
setFocusPolicy(Qt::NoFocus);
|
|
|
|
|
|
setAcceptDrops(true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CustomTabBar::~CustomTabBar()
|
|
|
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CustomTabBar::dragEnterEvent(QDragEnterEvent* event)
|
|
|
|
|
|
{
|
|
|
|
|
|
const QMimeData* mimeData = event->mimeData();
|
2024-11-07 12:08:56 +08:00
|
|
|
|
if( mimeData->hasFormat("dragData/customTab") )
|
2024-11-05 09:24:21 +08:00
|
|
|
|
{
|
|
|
|
|
|
event->acceptProposedAction();
|
2024-11-07 12:08:56 +08:00
|
|
|
|
//qDebug() << "dragEnterEvent-tabBar";
|
2024-11-05 09:24:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
event->ignore();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CustomTabBar::dragMoveEvent(QDragMoveEvent* event)
|
|
|
|
|
|
{
|
|
|
|
|
|
//qDebug() << "dragMoveEvent";
|
|
|
|
|
|
event->acceptProposedAction();
|
|
|
|
|
|
|
|
|
|
|
|
int toIndex = -1;
|
|
|
|
|
|
int lastWidgetIndex = m_pTabsLayout->count() - 2;
|
|
|
|
|
|
QWidget* lastWidget = m_pTabsLayout->itemAt(lastWidgetIndex)->widget();
|
|
|
|
|
|
if(lastWidget && event->position().x() > lastWidget->geometry().right()) //移到最后
|
|
|
|
|
|
toIndex = lastWidgetIndex;
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int i = 0; i < count(); ++i)
|
|
|
|
|
|
{
|
|
|
|
|
|
CustomTab* dropTab = tab(i);
|
|
|
|
|
|
if(!dropTab)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
QRect tabGeometry = dropTab->geometry();
|
|
|
|
|
|
if( !tabGeometry.contains(event->position().toPoint()) )
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
toIndex = m_pTabsLayout->indexOf(dropTab);
|
|
|
|
|
|
if(toIndex > 0 && m_pPosMarking->isVisible())
|
|
|
|
|
|
{
|
|
|
|
|
|
int nIndex = toIndex - 1;
|
|
|
|
|
|
if(m_pTabsLayout->indexOf(m_pPosMarking) == nIndex)//判断上一帧是否已经将posMarking放入到该tab之前
|
|
|
|
|
|
toIndex = -1;
|
|
|
|
|
|
else if(m_pTabsLayout->indexOf(m_pPosMarking) < toIndex)//在dropTab之前插入了posMarking会让dropTab的索引放生变化(+1)
|
|
|
|
|
|
toIndex -= 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-11-07 12:08:56 +08:00
|
|
|
|
//qDebug() << toIndex;
|
2024-11-05 09:24:21 +08:00
|
|
|
|
if(toIndex != -1)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_pPosMarking->show();
|
|
|
|
|
|
m_pTabsLayout->insertWidget(toIndex, m_pPosMarking);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CustomTabBar::dragLeaveEvent(QDragLeaveEvent* event)
|
|
|
|
|
|
{
|
2024-11-07 12:08:56 +08:00
|
|
|
|
//qDebug() << "dragLeaveEvent-tabBar";
|
|
|
|
|
|
if(m_pPosMarking->isVisible())
|
|
|
|
|
|
{
|
|
|
|
|
|
m_pPosMarking->hide();
|
|
|
|
|
|
m_pTabsLayout->removeWidget(m_pPosMarking);
|
|
|
|
|
|
}
|
2024-11-05 09:24:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CustomTabBar::dropEvent(QDropEvent* event)
|
|
|
|
|
|
{
|
2024-11-07 12:08:56 +08:00
|
|
|
|
//qDebug() << "dropEvent-tabBar";
|
|
|
|
|
|
event->setDropAction(Qt::MoveAction);
|
|
|
|
|
|
event->accept();
|
2024-11-05 09:24:21 +08:00
|
|
|
|
|
|
|
|
|
|
int toIndex = m_pTabsLayout->indexOf(m_pPosMarking);
|
|
|
|
|
|
m_pPosMarking->hide();
|
|
|
|
|
|
m_pTabsLayout->removeWidget(m_pPosMarking);
|
|
|
|
|
|
|
2024-11-07 12:08:56 +08:00
|
|
|
|
QByteArray itemData = event->mimeData()->data("dragData/customTab");
|
|
|
|
|
|
QDataStream dataStream(&itemData, QIODevice::ReadOnly);
|
|
|
|
|
|
QString strTabText = "";
|
|
|
|
|
|
QString strFromBar = "";
|
|
|
|
|
|
dataStream >> strTabText >> strFromBar;
|
2024-11-05 09:24:21 +08:00
|
|
|
|
|
2024-11-07 12:08:56 +08:00
|
|
|
|
if(strFromBar == objectName()) //同一组的tab,做移动操作
|
2024-11-05 09:24:21 +08:00
|
|
|
|
{
|
2024-11-07 12:08:56 +08:00
|
|
|
|
CustomTab* sourceObj = qobject_cast<CustomTab*>(event->source());
|
|
|
|
|
|
if(!sourceObj)
|
|
|
|
|
|
return;
|
|
|
|
|
|
int fromIndex = m_pTabsLayout->indexOf(sourceObj);
|
|
|
|
|
|
|
|
|
|
|
|
if(toIndex > fromIndex)//因为被移动的tab要先remove出来再insert,如果是向后移动,remove会引起索引的变化,所以要-1
|
|
|
|
|
|
toIndex -= 1;
|
|
|
|
|
|
|
|
|
|
|
|
if(toIndex != fromIndex) //移动
|
|
|
|
|
|
{
|
|
|
|
|
|
m_pTabsLayout->removeWidget(sourceObj);
|
|
|
|
|
|
m_pTabsLayout->insertWidget(toIndex, sourceObj);
|
|
|
|
|
|
emit tabMoved(fromIndex, toIndex);
|
|
|
|
|
|
}
|
|
|
|
|
|
//qDebug() << fromIndex << toIndex;
|
2024-11-05 09:24:21 +08:00
|
|
|
|
}
|
2024-11-07 12:08:56 +08:00
|
|
|
|
else
|
|
|
|
|
|
{
|
2024-11-05 09:24:21 +08:00
|
|
|
|
|
2024-11-07 12:08:56 +08:00
|
|
|
|
}
|
2024-11-05 09:24:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int CustomTabBar::count()
|
|
|
|
|
|
{
|
|
|
|
|
|
//含有一个stretch
|
|
|
|
|
|
return m_pTabsLayout->count() - 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-11-07 12:08:56 +08:00
|
|
|
|
void CustomTabBar::insertTab(int index, CustomTab* tab)
|
2024-11-05 09:24:21 +08:00
|
|
|
|
{
|
|
|
|
|
|
if(index < 0)
|
|
|
|
|
|
index = 0;
|
|
|
|
|
|
else if(index > count())
|
|
|
|
|
|
index = count();
|
|
|
|
|
|
|
|
|
|
|
|
m_pTabsLayout->insertWidget(index, tab);
|
2024-11-07 12:08:56 +08:00
|
|
|
|
ensureWidgetVisible(tab); //定位到可以显示该tab的位置
|
|
|
|
|
|
}
|
2024-11-05 09:24:21 +08:00
|
|
|
|
|
|
|
|
|
|
void CustomTabBar::addTab(CustomTab* tab)
|
|
|
|
|
|
{
|
2024-11-07 12:08:56 +08:00
|
|
|
|
insertTab(count(), tab);
|
2024-11-05 09:24:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
void CustomTabBar::removeTab(CustomTab* tab)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_pTabsLayout->removeWidget(tab);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CustomTab* CustomTabBar::tab(int index)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (index >= count() || index < 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
return qobject_cast<CustomTab*>(m_pTabsLayout->itemAt(index)->widget());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CustomTabBar::onTabClicked()
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|