mirror of
https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git
synced 2025-02-04 18:16:46 +08:00
Fixed docking into empty main dock container, fixed tab handling to properly show the right dock widget tab when removing a dock widget, fixed tab menu to only show visible tabs, tab menu is now dynamically created just befor menu is shown
This commit is contained in:
parent
72ee4a53df
commit
67199a81f4
@ -18,6 +18,7 @@
|
||||
#include "DockAreaWidget.h"
|
||||
#include "DockOverlay.h"
|
||||
#include "DockManager.h"
|
||||
#include "DockWidget.h"
|
||||
|
||||
namespace ads
|
||||
{
|
||||
@ -166,6 +167,10 @@ void CDockAreaTabBar::startFloating(const QPoint& Pos)
|
||||
CFloatingDockContainer* FloatingWidget = new CFloatingDockContainer(d->DockArea);
|
||||
FloatingWidget->startFloating(Pos, Size);
|
||||
d->FloatingWidget = FloatingWidget;
|
||||
if (d->FloatingWidget->hasSingleDockWidget())
|
||||
{
|
||||
emit d->FloatingWidget->firstDockWidget()->topLevelChanged(true);
|
||||
}
|
||||
}
|
||||
} // namespace ads
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include <QMenu>
|
||||
#include <QSplitter>
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QVector>
|
||||
|
||||
|
||||
#include "DockContainerWidget.h"
|
||||
@ -50,11 +51,14 @@
|
||||
#include "DockOverlay.h"
|
||||
#include "DockAreaTabBar.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
namespace ads
|
||||
{
|
||||
static const char* const INDEX_PROPERTY = "index";
|
||||
static const char* const ACTION_PROPERTY = "action";
|
||||
static const char* const DOCKWIDGET_PROPERTY = "dockwidget";
|
||||
static const int APPEND = -1;
|
||||
|
||||
|
||||
@ -75,6 +79,8 @@ struct DockAreaWidgetPrivate
|
||||
QPushButton* CloseButton;
|
||||
int TabsLayoutInitCount;
|
||||
CDockManager* DockManager = nullptr;
|
||||
QVector<CDockWidget*> OpenDockWidgets;
|
||||
bool MenuOutdated = true;
|
||||
|
||||
/**
|
||||
* Private data constructor
|
||||
@ -99,7 +105,7 @@ struct DockAreaWidgetPrivate
|
||||
*/
|
||||
CDockWidgetTab* titleWidgetAt(int index)
|
||||
{
|
||||
return dockWidgetAt(index)->titleBar();
|
||||
return dockWidgetAt(index)->tabWidget();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -130,6 +136,11 @@ struct DockAreaWidgetPrivate
|
||||
* Update the tabs menu if dock widget order changed or if dock widget has
|
||||
* been removed
|
||||
*/
|
||||
void markTabsMenuOutdated();
|
||||
|
||||
/**
|
||||
* Updates the tabs menu if it is outdated
|
||||
*/
|
||||
void updateTabsMenu();
|
||||
|
||||
/**
|
||||
@ -178,7 +189,9 @@ void DockAreaWidgetPrivate::createTabBar()
|
||||
TabsMenuButton->setFlat(true);
|
||||
TabsMenuButton->setIcon(_this->style()->standardIcon(QStyle::SP_TitleBarUnshadeButton));
|
||||
TabsMenuButton->setMaximumWidth(TabsMenuButton->iconSize().width());
|
||||
TabsMenuButton->setMenu(new QMenu(TabsMenuButton));
|
||||
QMenu* TabsMenu = new QMenu(TabsMenuButton);
|
||||
_this->connect(TabsMenu, SIGNAL(aboutToShow()), SLOT(onTabsMenuAboutToShow()));
|
||||
TabsMenuButton->setMenu(TabsMenu);
|
||||
TopLayout->addWidget(TabsMenuButton, 0);
|
||||
TabsMenuButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
_this->connect(TabsMenuButton->menu(), SIGNAL(triggered(QAction*)),
|
||||
@ -232,20 +245,39 @@ void DockAreaWidgetPrivate::addTabsMenuEntry(CDockWidget* DockWidget,
|
||||
{
|
||||
Action = menu->addAction(DockWidget->icon(), DockWidget->windowTitle());
|
||||
}
|
||||
Action->setProperty(DOCKWIDGET_PROPERTY, QVariant::fromValue(DockWidget));
|
||||
QVariant vAction = QVariant::fromValue(Action);
|
||||
DockWidget->setProperty(ACTION_PROPERTY, vAction);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void DockAreaWidgetPrivate::markTabsMenuOutdated()
|
||||
{
|
||||
MenuOutdated = true;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void DockAreaWidgetPrivate::updateTabsMenu()
|
||||
{
|
||||
if (!MenuOutdated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QMenu* menu = TabsMenuButton->menu();
|
||||
menu->clear();
|
||||
for (int i = 0; i < ContentsLayout->count(); ++i)
|
||||
{
|
||||
if (dockWidgetAt(i)->isClosed())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
addTabsMenuEntry(dockWidgetAt(i), APPEND, menu);
|
||||
}
|
||||
|
||||
MenuOutdated = false;
|
||||
}
|
||||
|
||||
|
||||
@ -313,17 +345,16 @@ void CDockAreaWidget::insertDockWidget(int index, CDockWidget* DockWidget,
|
||||
bool Activate)
|
||||
{
|
||||
d->ContentsLayout->insertWidget(index, DockWidget);
|
||||
DockWidget->titleBar()->setDockAreaWidget(this);
|
||||
auto TitleBar = DockWidget->titleBar();
|
||||
d->TabsLayout->insertWidget(index, TitleBar);
|
||||
TitleBar->show();
|
||||
connect(TitleBar, SIGNAL(clicked()), this, SLOT(onDockWidgetTitleClicked()));
|
||||
DockWidget->tabWidget()->setDockAreaWidget(this);
|
||||
auto TabWidget = DockWidget->tabWidget();
|
||||
d->TabsLayout->insertWidget(index, TabWidget);
|
||||
TabWidget->show();
|
||||
connect(TabWidget, SIGNAL(clicked()), this, SLOT(onDockWidgetTitleClicked()));
|
||||
DockWidget->setProperty(INDEX_PROPERTY, index);
|
||||
if (Activate)
|
||||
{
|
||||
setCurrentIndex(index);
|
||||
}
|
||||
d->addTabsMenuEntry(DockWidget, index);
|
||||
DockWidget->setDockArea(this);
|
||||
}
|
||||
|
||||
@ -332,13 +363,18 @@ void CDockAreaWidget::insertDockWidget(int index, CDockWidget* DockWidget,
|
||||
void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget)
|
||||
{
|
||||
qDebug() << "CDockAreaWidget::removeDockWidget";
|
||||
auto NextDockWidget = nextOpenDockWidget(DockWidget);
|
||||
|
||||
d->ContentsLayout->removeWidget(DockWidget);
|
||||
auto TitleBar = DockWidget->titleBar();
|
||||
auto TitleBar = DockWidget->tabWidget();
|
||||
TitleBar->hide();
|
||||
d->TabsLayout->removeWidget(TitleBar);
|
||||
disconnect(TitleBar, SIGNAL(clicked()), this, SLOT(onDockWidgetTitleClicked()));
|
||||
setCurrentIndex(d->ContentsLayout->currentIndex());
|
||||
d->updateTabsMenu();
|
||||
if (NextDockWidget)
|
||||
{
|
||||
setCurrentDockWidget(NextDockWidget);
|
||||
d->markTabsMenuOutdated();
|
||||
}
|
||||
|
||||
CDockContainerWidget* DockContainer = dockContainer();
|
||||
if (d->ContentsLayout->isEmpty())
|
||||
@ -550,7 +586,6 @@ void CDockAreaWidget::reorderDockWidget(int fromIndex, int toIndex)
|
||||
Menu->insertAction(Menu->actions().at(toIndex), TabsAction);
|
||||
}
|
||||
|
||||
|
||||
// now reorder contents and title bars
|
||||
QLayoutItem* liFrom = nullptr;
|
||||
liFrom = d->TabsLayout->takeAt(fromIndex);
|
||||
@ -561,11 +596,21 @@ void CDockAreaWidget::reorderDockWidget(int fromIndex, int toIndex)
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaWidget::toggleDockWidgetView(CDockWidget* DockWidget, bool Open)
|
||||
{
|
||||
Q_UNUSED(DockWidget);
|
||||
Q_UNUSED(Open);
|
||||
d->markTabsMenuOutdated();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaWidget::onTabsMenuActionTriggered(QAction* Action)
|
||||
{
|
||||
int Index = d->TabsMenuButton->menu()->actions().indexOf(Action);
|
||||
setCurrentIndex(Index);
|
||||
QVariant vDockWidget = Action->property(DOCKWIDGET_PROPERTY);
|
||||
CDockWidget* DockWidget = vDockWidget.value<CDockWidget*>();
|
||||
setCurrentDockWidget(DockWidget);
|
||||
}
|
||||
|
||||
|
||||
@ -591,6 +636,40 @@ void CDockAreaWidget::saveState(QXmlStreamWriter& s) const
|
||||
s.writeEndElement();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
CDockWidget* CDockAreaWidget::nextOpenDockWidget(CDockWidget* DockWidget) const
|
||||
{
|
||||
auto OpenDockWidgets = openedDockWidgets();
|
||||
if (OpenDockWidgets.count() > 1)
|
||||
{
|
||||
CDockWidget* NextDockWidget;
|
||||
if (OpenDockWidgets.last() == DockWidget)
|
||||
{
|
||||
NextDockWidget = OpenDockWidgets[OpenDockWidgets.count() - 2];
|
||||
}
|
||||
else
|
||||
{
|
||||
int NextIndex = OpenDockWidgets.indexOf(DockWidget) + 1;
|
||||
NextDockWidget = OpenDockWidgets[NextIndex];
|
||||
}
|
||||
|
||||
return NextDockWidget;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaWidget::onTabsMenuAboutToShow()
|
||||
{
|
||||
std::cout << "CDockAreaWidget::onTabsMenuAboutToShow()" << std::endl;
|
||||
d->updateTabsMenu();
|
||||
}
|
||||
|
||||
} // namespace ads
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -59,11 +59,14 @@ private:
|
||||
friend class CDockContainerWidget;
|
||||
friend class DockContainerWidgetPrivate;
|
||||
friend class CDockWidgetTab;
|
||||
friend struct DockWidgetPrivate;
|
||||
friend class CDockWidget;
|
||||
|
||||
private slots:
|
||||
void onDockWidgetTitleClicked();
|
||||
void onTabsMenuActionTriggered(QAction* Action);
|
||||
void onCloseButtonClicked();
|
||||
void onTabsMenuAboutToShow();
|
||||
|
||||
protected:
|
||||
/**
|
||||
@ -97,6 +100,18 @@ protected:
|
||||
*/
|
||||
void reorderDockWidget(int fromIndex, int toIndex);
|
||||
|
||||
/**
|
||||
* Called from dock widget if it is opened or closed
|
||||
*/
|
||||
void toggleDockWidgetView(CDockWidget* DockWidget, bool Open);
|
||||
|
||||
/**
|
||||
* This is a helper function to get the next open dock widget to activate
|
||||
* if the given DockWidget will be closed or removed.
|
||||
* The function returns the next widget that should be activated or
|
||||
* nullptr in case there are no more open widgets in this area.
|
||||
*/
|
||||
CDockWidget* nextOpenDockWidget(CDockWidget* DockWidget) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
@ -178,7 +193,9 @@ public:
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* This sets the index position of the current tab page.
|
||||
* This activates the tab for the given tab index.
|
||||
* If the dock widget for the given tab is not visible, the this function
|
||||
* call will make it visible.
|
||||
*/
|
||||
void setCurrentIndex(int index);
|
||||
|
||||
|
@ -54,6 +54,26 @@ namespace ads
|
||||
{
|
||||
static unsigned int zOrderCounter = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Converts dock area ID to an index for array access
|
||||
*/
|
||||
static int areaIdToIndex(DockWidgetArea area)
|
||||
{
|
||||
switch (area)
|
||||
{
|
||||
case LeftDockWidgetArea: return 0;
|
||||
case RightDockWidgetArea: return 1;
|
||||
case TopDockWidgetArea: return 2;
|
||||
case BottomDockWidgetArea: return 3;
|
||||
case CenterDockWidgetArea: return 4;
|
||||
default:
|
||||
return 4;
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to ease insertion of dock area into splitter
|
||||
*/
|
||||
@ -81,6 +101,7 @@ struct DockContainerWidgetPrivate
|
||||
QGridLayout* Layout = nullptr;
|
||||
QSplitter* RootSplitter;
|
||||
bool isFloating = false;
|
||||
CDockAreaWidget* LastAddedAreaCache[5]{0, 0, 0, 0, 0};
|
||||
|
||||
/**
|
||||
* Private data constructor
|
||||
@ -172,7 +193,6 @@ void DockContainerWidgetPrivate::dropIntoContainer(CFloatingDockContainer* Float
|
||||
auto InsertParam = internal::dockAreaInsertParameters(area);
|
||||
auto NewDockAreas = FloatingWidget->dockContainer()->findChildren<CDockAreaWidget*>(
|
||||
QString(), Qt::FindChildrenRecursively);
|
||||
CDockWidget* DockWidget = FloatingWidget->dockContainer()->findChild<CDockWidget*>();
|
||||
QSplitter* Splitter = RootSplitter;
|
||||
|
||||
if (DockAreas.count() <= 1)
|
||||
@ -209,9 +229,12 @@ void DockContainerWidgetPrivate::dropIntoContainer(CFloatingDockContainer* Float
|
||||
RootSplitter = Splitter;
|
||||
addDockAreasToList(NewDockAreas);
|
||||
FloatingWidget->deleteLater();
|
||||
if (DockWidget)
|
||||
// If we dropped the floating widget into the main dock container that does
|
||||
// not contain any dock widgets, then splitter is invisible and we need to
|
||||
// show it to display the docked widgets
|
||||
if (!Splitter->isVisible())
|
||||
{
|
||||
DockWidget->toggleView(true);
|
||||
Splitter->show();
|
||||
}
|
||||
_this->dumpLayout();
|
||||
}
|
||||
@ -503,6 +526,8 @@ bool DockContainerWidgetPrivate::restoreDockArea(QXmlStreamReader& s,
|
||||
qDebug() << "Dock Widget found - parent " << DockWidget->parent();
|
||||
DockArea->addDockWidget(DockWidget);
|
||||
|
||||
// We hide the DockArea here to prevent the short display (the flashing)
|
||||
// of the dock areas during application startup
|
||||
DockArea->hide();
|
||||
DockWidget->setToggleViewActionChecked(!Closed);
|
||||
DockWidget->setProperty("closed", Closed);
|
||||
@ -565,6 +590,7 @@ CDockAreaWidget* DockContainerWidgetPrivate::dockWidgetIntoContainer(DockWidgetA
|
||||
CDockAreaWidget* NewDockArea = new CDockAreaWidget(DockManager, _this);
|
||||
NewDockArea->addDockWidget(Dockwidget);
|
||||
addDockArea(NewDockArea, area);
|
||||
LastAddedAreaCache[areaIdToIndex(area)] = NewDockArea;
|
||||
return NewDockArea;
|
||||
}
|
||||
|
||||
@ -689,7 +715,6 @@ CDockContainerWidget::CDockContainerWidget(CDockManager* DockManager, QWidget *p
|
||||
{
|
||||
d->isFloating = dynamic_cast<CFloatingDockContainer*>(parent) != 0;
|
||||
|
||||
//setStyleSheet("background: green;");
|
||||
d->DockManager = DockManager;
|
||||
if (DockManager != this)
|
||||
{
|
||||
@ -905,6 +930,8 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
|
||||
CDockAreaWidget* DockArea = dockAreaAt(TargetPos);
|
||||
auto dropArea = InvalidDockWidgetArea;
|
||||
auto ContainerDropArea = d->DockManager->containerOverlay()->dropAreaUnderCursor();
|
||||
CDockWidget* TopLevelDockWidget = FloatingWidget->hasSingleDockWidget() ?
|
||||
FloatingWidget->firstDockWidget() : nullptr;
|
||||
if (DockArea)
|
||||
{
|
||||
auto dropOverlay = d->DockManager->dockAreaOverlay();
|
||||
@ -933,6 +960,13 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
|
||||
d->dropIntoContainer(FloatingWidget, dropArea);
|
||||
}
|
||||
}
|
||||
|
||||
// If we drop a floating widget with only one single dock widget, then we
|
||||
// drop a top level widget that changes from floating to docked now
|
||||
if (TopLevelDockWidget)
|
||||
{
|
||||
emit TopLevelDockWidget->topLevelChanged(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1047,6 +1081,13 @@ void CDockContainerWidget::dumpLayout()
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
CDockAreaWidget* CDockContainerWidget::lastAddedDockAreaWidget(DockWidgetArea area) const
|
||||
{
|
||||
return d->LastAddedAreaCache[areaIdToIndex(area)];
|
||||
}
|
||||
|
||||
|
||||
} // namespace ads
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -103,6 +103,13 @@ protected:
|
||||
*/
|
||||
bool restoreState(QXmlStreamReader& Stream, bool Testing);
|
||||
|
||||
/**
|
||||
* This function returns the last added dock area widget for the given
|
||||
* area identifier or 0 if no dock area widget has been added for the given
|
||||
* area
|
||||
*/
|
||||
CDockAreaWidget* lastAddedDockAreaWidget(DockWidgetArea area) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Default Constructor
|
||||
|
@ -361,7 +361,8 @@ bool CDockManager::restoreState(const QByteArray &state, int version)
|
||||
{
|
||||
CDockAreaWidget* DockArea = DockContainer->dockArea(i);
|
||||
int CurrentIndex = DockArea->property("currentIndex").toInt();
|
||||
if (CurrentIndex < DockArea->count() && DockArea->count() > 1 && CurrentIndex > -1)
|
||||
int OpenDockWidgetCount = DockArea->openedDockWidgets().count();
|
||||
if (CurrentIndex < OpenDockWidgetCount && OpenDockWidgetCount > 1 && CurrentIndex > -1)
|
||||
{
|
||||
DockArea->setCurrentIndex(CurrentIndex);
|
||||
}
|
||||
@ -382,6 +383,30 @@ CDockAreaWidget* CDockManager::addDockWidget(DockWidgetArea area,
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
CDockAreaWidget* CDockManager::addDockWidgetTab(DockWidgetArea area,
|
||||
CDockWidget* Dockwidget)
|
||||
{
|
||||
CDockAreaWidget* AreaWidget = lastAddedDockAreaWidget(area);
|
||||
if (AreaWidget)
|
||||
{
|
||||
return addDockWidget(ads::CenterDockWidgetArea, Dockwidget, AreaWidget);
|
||||
}
|
||||
else
|
||||
{
|
||||
return addDockWidget(area, Dockwidget, AreaWidget);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
CDockAreaWidget* CDockManager::addDockWidgetTabToArea(CDockWidget* Dockwidget,
|
||||
CDockAreaWidget* DockAreaWidget)
|
||||
{
|
||||
return addDockWidget(ads::CenterDockWidgetArea, Dockwidget, DockAreaWidget);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
CDockWidget* CDockManager::findDockWidget(const QString& ObjectName)
|
||||
{
|
||||
|
@ -128,6 +128,22 @@ public:
|
||||
CDockAreaWidget* addDockWidget(DockWidgetArea area, CDockWidget* Dockwidget,
|
||||
CDockAreaWidget* DockAreaWidget = nullptr);
|
||||
|
||||
/**
|
||||
* This function will add the given Dockwidget to the given dock area as
|
||||
* a new tab.
|
||||
* If no dock area widget exists for the given area identifier, a new
|
||||
* dock area widget is created.
|
||||
*/
|
||||
CDockAreaWidget* addDockWidgetTab(DockWidgetArea area,
|
||||
CDockWidget* Dockwidget);
|
||||
|
||||
/**
|
||||
* This function will add the given Dockwidget to the given DockAreaWidget
|
||||
* as a new tab.
|
||||
*/
|
||||
CDockAreaWidget* addDockWidgetTabToArea(CDockWidget* Dockwidget,
|
||||
CDockAreaWidget* DockAreaWidget);
|
||||
|
||||
/**
|
||||
* Searches for a registered doc widget with the given ObjectName
|
||||
* \return Return the found dock widget or nullptr if a dock widget with the
|
||||
|
@ -59,7 +59,7 @@ struct DockWidgetPrivate
|
||||
CDockWidget* _this;
|
||||
QBoxLayout* Layout;
|
||||
QWidget* Widget = nullptr;
|
||||
CDockWidgetTab* TitleWidget;
|
||||
CDockWidgetTab* TabWidget;
|
||||
CDockWidget::DockWidgetFeatures Features = CDockWidget::AllDockWidgetFeatures;
|
||||
CDockManager* DockManager = nullptr;
|
||||
CDockAreaWidget* DockArea = nullptr;
|
||||
@ -87,9 +87,11 @@ struct DockWidgetPrivate
|
||||
void hideEmptyParentSplitters();
|
||||
|
||||
/**
|
||||
* Hides a dock area if all dock widgets in the area are closed
|
||||
* Hides a dock area if all dock widgets in the area are closed.
|
||||
* This function updates the current selected tab and hides the parent
|
||||
* dock area if it is empty
|
||||
*/
|
||||
void hideEmptyParentDockArea();
|
||||
void updateParentDockArea();
|
||||
|
||||
/**
|
||||
* Hides a floating widget if all dock areas are empty - that means,
|
||||
@ -141,8 +143,8 @@ void DockWidgetPrivate::showDockWidget()
|
||||
//============================================================================
|
||||
void DockWidgetPrivate::hideDockWidget()
|
||||
{
|
||||
TitleWidget->hide();
|
||||
hideEmptyParentDockArea();
|
||||
TabWidget->hide();
|
||||
updateParentDockArea();
|
||||
hideEmptyParentSplitters();
|
||||
hideEmptyFloatingWidget();
|
||||
}
|
||||
@ -164,22 +166,11 @@ void DockWidgetPrivate::hideEmptyParentSplitters()
|
||||
|
||||
|
||||
//============================================================================
|
||||
void DockWidgetPrivate::hideEmptyParentDockArea()
|
||||
void DockWidgetPrivate::updateParentDockArea()
|
||||
{
|
||||
auto OpenDockWidgets = DockArea->openedDockWidgets();
|
||||
if (OpenDockWidgets.count() > 1)
|
||||
auto NextDockWidget = DockArea->nextOpenDockWidget(_this);
|
||||
if (NextDockWidget)
|
||||
{
|
||||
CDockWidget* NextDockWidget;
|
||||
if (OpenDockWidgets.last() == _this)
|
||||
{
|
||||
NextDockWidget = OpenDockWidgets[OpenDockWidgets.count() - 2];
|
||||
}
|
||||
else
|
||||
{
|
||||
int NextIndex = OpenDockWidgets.indexOf(_this) + 1;
|
||||
NextDockWidget = OpenDockWidgets[NextIndex];
|
||||
}
|
||||
|
||||
DockArea->setCurrentDockWidget(NextDockWidget);
|
||||
}
|
||||
else
|
||||
@ -213,7 +204,7 @@ CDockWidget::CDockWidget(const QString &title, QWidget *parent) :
|
||||
setWindowTitle(title);
|
||||
setObjectName(title);
|
||||
|
||||
d->TitleWidget = new CDockWidgetTab(this);
|
||||
d->TabWidget = new CDockWidgetTab(this);
|
||||
d->ToggleViewAction = new QAction(title);
|
||||
d->ToggleViewAction->setCheckable(true);
|
||||
connect(d->ToggleViewAction, SIGNAL(triggered(bool)), this,
|
||||
@ -262,9 +253,9 @@ QWidget* CDockWidget::widget() const
|
||||
|
||||
|
||||
//============================================================================
|
||||
CDockWidgetTab* CDockWidget::titleBar() const
|
||||
CDockWidgetTab* CDockWidget::tabWidget() const
|
||||
{
|
||||
return d->TitleWidget;
|
||||
return d->TabWidget;
|
||||
}
|
||||
|
||||
|
||||
@ -320,7 +311,39 @@ CDockAreaWidget* CDockWidget::dockAreaWidget() const
|
||||
//============================================================================
|
||||
bool CDockWidget::isFloating() const
|
||||
{
|
||||
return dockContainer() ? dockContainer()->isFloating() : false;
|
||||
if (!isInFloatingContainer())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dockContainer()->dockAreaCount() != 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dockContainer()->dockArea(0)->count() != 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool CDockWidget::isInFloatingContainer() const
|
||||
{
|
||||
if (!dockContainer())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!dockContainer()->isFloating())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -349,7 +372,7 @@ void CDockWidget::setToggleViewActionMode(eToggleViewActionMode Mode)
|
||||
else
|
||||
{
|
||||
d->ToggleViewAction->setCheckable(false);
|
||||
d->ToggleViewAction->setIcon(d->TitleWidget->icon());
|
||||
d->ToggleViewAction->setIcon(d->TabWidget->icon());
|
||||
}
|
||||
}
|
||||
|
||||
@ -375,6 +398,8 @@ void CDockWidget::toggleView(bool Open)
|
||||
d->ToggleViewAction->blockSignals(true);
|
||||
d->ToggleViewAction->setChecked(Open);
|
||||
d->ToggleViewAction->blockSignals(false);
|
||||
d->DockArea->toggleDockWidgetView(this, Open);
|
||||
|
||||
if (!Open)
|
||||
{
|
||||
emit closed();
|
||||
@ -406,7 +431,7 @@ void CDockWidget::flagAsUnassigned()
|
||||
{
|
||||
setParent(d->DockManager);
|
||||
setDockArea(nullptr);
|
||||
titleBar()->setParent(this);
|
||||
tabWidget()->setParent(this);
|
||||
}
|
||||
|
||||
|
||||
@ -424,7 +449,7 @@ bool CDockWidget::event(QEvent *e)
|
||||
//============================================================================
|
||||
void CDockWidget::setIcon(const QIcon& Icon)
|
||||
{
|
||||
d->TitleWidget->setIcon(Icon);
|
||||
d->TabWidget->setIcon(Icon);
|
||||
if (!d->ToggleViewAction->isCheckable())
|
||||
{
|
||||
d->ToggleViewAction->setIcon(Icon);
|
||||
@ -435,7 +460,7 @@ void CDockWidget::setIcon(const QIcon& Icon)
|
||||
//============================================================================
|
||||
QIcon CDockWidget::icon() const
|
||||
{
|
||||
return d->TitleWidget->icon();
|
||||
return d->TabWidget->icon();
|
||||
}
|
||||
|
||||
|
||||
|
@ -164,7 +164,7 @@ public:
|
||||
/**
|
||||
* Returns the title bar widget of this dock widget
|
||||
*/
|
||||
CDockWidgetTab* titleBar() const;
|
||||
CDockWidgetTab* tabWidget() const;
|
||||
|
||||
/**
|
||||
* Sets, whether the dock widget is movable, closable, and floatable.
|
||||
@ -193,7 +193,7 @@ public:
|
||||
|
||||
/**
|
||||
* Returns the dock container widget this dock area widget belongs to or 0
|
||||
* if this dock widget has nt been docked yet
|
||||
* if this dock widget has not been docked yet
|
||||
*/
|
||||
CDockContainerWidget* dockContainer() const;
|
||||
|
||||
@ -205,9 +205,19 @@ public:
|
||||
|
||||
/**
|
||||
* This property holds whether the dock widget is floating.
|
||||
* A dock widget is only floating, if it is the one and only widget inside
|
||||
* of a floating container. If there are more than one dock widget in a
|
||||
* floating container, the all dock widgets are docked and not floating.
|
||||
*/
|
||||
bool isFloating() const;
|
||||
|
||||
/**
|
||||
* This function returns true, if this dock widget is in a floating.
|
||||
* The function returns true, if the dock widget is floating and it also
|
||||
* returns true if it is docked inside of a floating container.
|
||||
*/
|
||||
bool isInFloatingContainer() const;
|
||||
|
||||
/**
|
||||
* Returns true, if this dock widget is closed.
|
||||
*/
|
||||
@ -266,6 +276,13 @@ signals:
|
||||
* changed
|
||||
*/
|
||||
void titleChanged(const QString& Title);
|
||||
|
||||
/**
|
||||
* This signal is emitted when the floating property changes.
|
||||
* The topLevel parameter is true if the dock widget is now floating;
|
||||
* otherwise it is false.
|
||||
*/
|
||||
void topLevelChanged(bool topLevel);
|
||||
}; // class DockWidget
|
||||
}
|
||||
// namespace ads
|
||||
|
@ -196,6 +196,7 @@ bool DockWidgetTabPrivate::startFloating()
|
||||
auto Overlay = DockWidget->dockManager()->containerOverlay();
|
||||
Overlay->setAllowedAreas(OuterDockAreas);
|
||||
this->FloatingWidget = FloatingWidget;
|
||||
emit DockWidget->topLevelChanged(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -481,6 +481,25 @@ bool CFloatingDockContainer::restoreState(QXmlStreamReader& Stream, bool Testing
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool CFloatingDockContainer::hasSingleDockWidget() const
|
||||
{
|
||||
if (d->DockContainer->dockAreaCount() != 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return d->DockContainer->dockArea(0)->count() == 1;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
CDockWidget* CFloatingDockContainer::firstDockWidget() const
|
||||
{
|
||||
return d->DockContainer->dockArea(0)->dockWidget(0);
|
||||
}
|
||||
|
||||
|
||||
} // namespace ads
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -132,6 +132,21 @@ public:
|
||||
* It can be closed, if all dock widgets in all dock areas can be closed
|
||||
*/
|
||||
bool isClosable() const;
|
||||
|
||||
/**
|
||||
* This function returns true, if this floating widget has only one single
|
||||
* dock widget in a single dock area.
|
||||
* The single dock widget is a real top level floating widget because no
|
||||
* other widgets are docked.
|
||||
*/
|
||||
bool hasSingleDockWidget() const;
|
||||
|
||||
/**
|
||||
* This function returns the first dock widget in the first dock area.
|
||||
* If the function hasSingleDockWidget() returns true, then this function
|
||||
* returns this single dock widget.
|
||||
*/
|
||||
CDockWidget* firstDockWidget() const;
|
||||
}; // class FloatingDockContainer
|
||||
}
|
||||
// namespace ads
|
||||
|
Loading…
Reference in New Issue
Block a user