212 lines
5.8 KiB
C++
212 lines
5.8 KiB
C++
#include "customTabBar.h"
|
||
#include "customTab.h"
|
||
#include "dashboardFrame.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_pFrame = nullptr;
|
||
|
||
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();
|
||
if( mimeData->hasFormat("dragData/customTab") )
|
||
{
|
||
event->acceptProposedAction();
|
||
//qDebug() << "dragEnterEvent-tabBar";
|
||
}
|
||
else
|
||
event->ignore();
|
||
}
|
||
|
||
void CustomTabBar::dragMoveEvent(QDragMoveEvent* event)
|
||
{
|
||
//qDebug() << "dragMoveEvent";
|
||
event->acceptProposedAction();
|
||
|
||
if(m_pTabsLayout->count() == 1) //没有tab
|
||
return;
|
||
|
||
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;
|
||
}
|
||
}
|
||
|
||
//qDebug() << toIndex;
|
||
if(toIndex != -1)
|
||
{
|
||
m_pPosMarking->show();
|
||
m_pTabsLayout->insertWidget(toIndex, m_pPosMarking);
|
||
}
|
||
}
|
||
|
||
void CustomTabBar::dragLeaveEvent(QDragLeaveEvent* event)
|
||
{
|
||
//qDebug() << "dragLeaveEvent-tabBar";
|
||
if(m_pPosMarking->isVisible())
|
||
{
|
||
m_pPosMarking->hide();
|
||
m_pTabsLayout->removeWidget(m_pPosMarking);
|
||
}
|
||
}
|
||
|
||
void CustomTabBar::dropEvent(QDropEvent* event)
|
||
{
|
||
//qDebug() << "dropEvent-tabBar";
|
||
event->setDropAction(Qt::MoveAction);
|
||
event->accept();
|
||
|
||
int toIndex = m_pTabsLayout->indexOf(m_pPosMarking);
|
||
m_pPosMarking->hide();
|
||
m_pTabsLayout->removeWidget(m_pPosMarking);
|
||
|
||
QByteArray itemData = event->mimeData()->data("dragData/customTab");
|
||
QDataStream dataStream(&itemData, QIODevice::ReadOnly);
|
||
QString strTabText = "";
|
||
QString strFromFrame = "";
|
||
dataStream >> strTabText >> strFromFrame;
|
||
|
||
if(!m_pFrame)
|
||
return;
|
||
|
||
if(strFromFrame == m_pFrame->objectName()) //同一组的tab,做移动操作
|
||
{
|
||
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;
|
||
}
|
||
else
|
||
{
|
||
DashboardFrame* fromFrame = m_pFrame->getDashboardFrame(strFromFrame);
|
||
if(fromFrame != m_pFrame && fromFrame != nullptr)
|
||
{
|
||
Dashboard* dashboard = fromFrame->takeDashboard(strTabText);
|
||
m_pFrame->insertDashboard(toIndex, dashboard);
|
||
}
|
||
}
|
||
}
|
||
|
||
void CustomTabBar::setFrame(DashboardFrame* frame)
|
||
{
|
||
m_pFrame = frame;
|
||
}
|
||
DashboardFrame* CustomTabBar::frame()
|
||
{
|
||
return m_pFrame;
|
||
}
|
||
|
||
int CustomTabBar::count()
|
||
{
|
||
//含有一个stretch
|
||
return m_pTabsLayout->count() - 1;
|
||
}
|
||
|
||
void CustomTabBar::insertTab(int index, CustomTab* tab)
|
||
{
|
||
if(index < 0)
|
||
index = 0;
|
||
else if(index > count())
|
||
index = count();
|
||
|
||
m_pTabsLayout->insertWidget(index, tab);
|
||
ensureWidgetVisible(tab); //定位到可以显示该tab的位置
|
||
}
|
||
|
||
void CustomTabBar::addTab(CustomTab* tab)
|
||
{
|
||
insertTab(count(), tab);
|
||
}
|
||
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()
|
||
{
|
||
|
||
}
|