Added access functions for the titlebar buttons

This commit is contained in:
Uwe Kindler 2018-11-03 20:51:02 +01:00
parent 0ac19ebdfb
commit 72ec61a043
12 changed files with 141 additions and 46 deletions

View File

@ -214,17 +214,25 @@ void CDockAreaTabBar::mouseDoubleClickEvent(QMouseEvent *event)
//============================================================================ //============================================================================
void CDockAreaTabBar::startFloating(const QPoint& Pos) CFloatingDockContainer* CDockAreaTabBar::makeAreaFloating(const QPoint& Pos)
{ {
QSize Size = d->DockArea->size(); QSize Size = d->DockArea->size();
CFloatingDockContainer* FloatingWidget = new CFloatingDockContainer(d->DockArea); CFloatingDockContainer* FloatingWidget = new CFloatingDockContainer(d->DockArea);
FloatingWidget->startFloating(Pos, Size); FloatingWidget->startFloating(Pos, Size);
d->FloatingWidget = FloatingWidget; auto TopLevelDockWidget = FloatingWidget->topLevelDockWidget();
auto TopLevelDockWidget = d->FloatingWidget->topLevelDockWidget();
if (TopLevelDockWidget) if (TopLevelDockWidget)
{ {
TopLevelDockWidget->emitTopLevelChanged(true); TopLevelDockWidget->emitTopLevelChanged(true);
} }
return FloatingWidget;
}
//============================================================================
void CDockAreaTabBar::startFloating(const QPoint& Pos)
{
d->FloatingWidget = makeAreaFloating(Pos);
} }

View File

@ -36,6 +36,8 @@ namespace ads
class CDockAreaWidget; class CDockAreaWidget;
class CDockWidgetTab; class CDockWidgetTab;
struct DockAreaTabBarPrivate; struct DockAreaTabBarPrivate;
class CDockAreaTitleBar;
class CFloatingDockContainer;
/** /**
* Custom tabbar implementation for tab area that is shown on top of a * Custom tabbar implementation for tab area that is shown on top of a
@ -48,6 +50,7 @@ class CDockAreaTabBar : public QScrollArea
private: private:
DockAreaTabBarPrivate* d; ///< private data (pimpl) DockAreaTabBarPrivate* d; ///< private data (pimpl)
friend class DockAreaTabBarPrivate; friend class DockAreaTabBarPrivate;
friend class CDockAreaTitleBar;
private slots: private slots:
void onTabClicked(); void onTabClicked();
@ -81,6 +84,12 @@ protected:
*/ */
void startFloating(const QPoint& Pos); void startFloating(const QPoint& Pos);
/**
* Makes the dock area loating
*/
CFloatingDockContainer* makeAreaFloating(const QPoint& Pos);
public: public:
using Super = QScrollArea; using Super = QScrollArea;
/** /**

View File

@ -41,6 +41,7 @@ struct DockAreaTitleBarPrivate
{ {
CDockAreaTitleBar* _this; CDockAreaTitleBar* _this;
tTileBarButton* TabsMenuButton; tTileBarButton* TabsMenuButton;
tTileBarButton* UndockButton;
tTileBarButton* CloseButton; tTileBarButton* CloseButton;
QBoxLayout* TopLayout; QBoxLayout* TopLayout;
CDockAreaWidget* DockArea; CDockAreaWidget* DockArea;
@ -106,6 +107,15 @@ void DockAreaTitleBarPrivate::createButtons()
_this->connect(TabsMenuButton->menu(), SIGNAL(triggered(QAction*)), _this->connect(TabsMenuButton->menu(), SIGNAL(triggered(QAction*)),
SLOT(onTabsMenuActionTriggered(QAction*))); SLOT(onTabsMenuActionTriggered(QAction*)));
// Undock button
UndockButton = new tTileBarButton();
UndockButton->setObjectName("undockButton");
UndockButton->setAutoRaise(true);
UndockButton->setIcon(_this->style()->standardIcon(QStyle::SP_TitleBarNormalButton));
UndockButton->setMaximumWidth(UndockButton->iconSize().width());
TopLayout->addWidget(UndockButton, 0);
_this->connect(UndockButton, SIGNAL(clicked()), SLOT(onUndockButtonClicked()));
CloseButton = new tTileBarButton(); CloseButton = new tTileBarButton();
CloseButton->setObjectName("closeButton"); CloseButton->setObjectName("closeButton");
CloseButton->setAutoRaise(true); CloseButton->setAutoRaise(true);
@ -213,6 +223,14 @@ void CDockAreaTitleBar::onCloseButtonClicked()
} }
//============================================================================
void CDockAreaTitleBar::onUndockButtonClicked()
{
std::cout << "CDockAreaTitleBar::onUndockButtonClicked" << std::endl;
d->TabBar->makeAreaFloating(mapFromGlobal(QCursor::pos()));
}
//============================================================================ //============================================================================
void CDockAreaTitleBar::onTabsMenuActionTriggered(QAction* Action) void CDockAreaTitleBar::onTabsMenuActionTriggered(QAction* Action)
{ {
@ -230,6 +248,27 @@ void CDockAreaTitleBar::onCurrentTabChanged(int Index)
} }
//============================================================================
QAbstractButton* CDockAreaTitleBar::button(TitleBarButton which) const
{
switch (which)
{
case TitleBarButtonTabsMenu: return d->TabsMenuButton;
case TitleBarButtonUndock: return d->UndockButton;
case TitleBarButtonClose: return d->CloseButton;
default:
return nullptr;
}
}
//============================================================================
void CDockAreaTitleBar::setVisible(bool Visible)
{
Super::setVisible(Visible);
}
} // namespace ads } // namespace ads
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@ -32,6 +32,10 @@
//============================================================================ //============================================================================
#include <QFrame> #include <QFrame>
#include "ads_globals.h"
class QAbstractButton;
namespace ads namespace ads
{ {
class CDockAreaTabBar; class CDockAreaTabBar;
@ -52,6 +56,7 @@ private slots:
void markTabsMenuOutdated(); void markTabsMenuOutdated();
void onTabsMenuAboutToShow(); void onTabsMenuAboutToShow();
void onCloseButtonClicked(); void onCloseButtonClicked();
void onUndockButtonClicked();
void onTabsMenuActionTriggered(QAction* Action); void onTabsMenuActionTriggered(QAction* Action);
void onCurrentTabChanged(int Index); void onCurrentTabChanged(int Index);
@ -72,6 +77,13 @@ public:
*/ */
CDockAreaTabBar* tabBar() const; CDockAreaTabBar* tabBar() const;
/**
* Returns the button corresponding to the given title bar button identifier
*/
QAbstractButton* button(TitleBarButton which) const;
virtual void setVisible(bool Visible) override;
signals: signals:
/** /**
* This signal is emitted if a tab in the tab bar is clicked by the user * This signal is emitted if a tab in the tab bar is clicked by the user

View File

@ -258,7 +258,7 @@ struct DockAreaWidgetPrivate
* Updates the tab bar visibility depending on the number of dock widgets * Updates the tab bar visibility depending on the number of dock widgets
* in this area * in this area
*/ */
void updateTabBar(); void updateTitleBarVisibility();
/** /**
* Convenience function for tabbar access * Convenience function for tabbar access
@ -294,7 +294,7 @@ void DockAreaWidgetPrivate::createTitleBar()
//============================================================================ //============================================================================
void DockAreaWidgetPrivate::updateTabBar() void DockAreaWidgetPrivate::updateTitleBarVisibility()
{ {
CDockContainerWidget* Container = _this->dockContainer(); CDockContainerWidget* Container = _this->dockContainer();
if (!Container) if (!Container)
@ -358,7 +358,11 @@ void CDockAreaWidget::insertDockWidget(int index, CDockWidget* DockWidget,
d->ContentsLayout->insertWidget(index, DockWidget); d->ContentsLayout->insertWidget(index, DockWidget);
DockWidget->tabWidget()->setDockAreaWidget(this); DockWidget->tabWidget()->setDockAreaWidget(this);
auto TabWidget = DockWidget->tabWidget(); auto TabWidget = DockWidget->tabWidget();
// Inserting the tab will change the current index which in turn will
// make the tab widget visible in the slot
d->tabBar()->blockSignals(true);
d->tabBar()->insertTab(index, TabWidget); d->tabBar()->insertTab(index, TabWidget);
d->tabBar()->blockSignals(false);
TabWidget->setVisible(!DockWidget->isClosed()); TabWidget->setVisible(!DockWidget->isClosed());
DockWidget->setProperty(INDEX_PROPERTY, index); DockWidget->setProperty(INDEX_PROPERTY, index);
if (Activate) if (Activate)
@ -398,7 +402,7 @@ void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget)
hideAreaWithNoVisibleContent(); hideAreaWithNoVisibleContent();
} }
d->updateTabBar(); d->updateTitleBarVisibility();
auto TopLevelDockWidget = dockContainer()->topLevelDockWidget(); auto TopLevelDockWidget = dockContainer()->topLevelDockWidget();
if (TopLevelDockWidget) if (TopLevelDockWidget)
{ {
@ -415,6 +419,7 @@ void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget)
//============================================================================ //============================================================================
void CDockAreaWidget::hideAreaWithNoVisibleContent() void CDockAreaWidget::hideAreaWithNoVisibleContent()
{ {
std::cout << "CDockAreaWidget::hideAreaWithNoVisibleContent()" << std::endl;
this->toggleView(false); this->toggleView(false);
// Hide empty parent splitter // Hide empty parent splitter
@ -430,9 +435,21 @@ void CDockAreaWidget::hideAreaWithNoVisibleContent()
//Hide empty floating widget //Hide empty floating widget
CDockContainerWidget* Container = this->dockContainer(); CDockContainerWidget* Container = this->dockContainer();
if (Container->isFloating() && Container->openedDockAreas().isEmpty()) if (!Container->isFloating())
{
return;
}
d->updateTitleBarVisibility();
auto TopLevelWidget = Container->topLevelDockWidget();
auto FloatingWidget = Container->floatingWidget();
if (TopLevelWidget)
{
FloatingWidget->updateWindowTitle();
CDockWidget::emitTopLevelEventForWidget(TopLevelWidget, true);
}
else if (Container->openedDockAreas().isEmpty())
{ {
CFloatingDockContainer* FloatingWidget = internal::findParent<CFloatingDockContainer*>(Container);
FloatingWidget->hide(); FloatingWidget->hide();
} }
} }
@ -449,7 +466,13 @@ void CDockAreaWidget::onTabCloseRequested(int Index)
//============================================================================ //============================================================================
CDockWidget* CDockAreaWidget::currentDockWidget() const CDockWidget* CDockAreaWidget::currentDockWidget() const
{ {
return dockWidget(currentIndex()); int CurrentIndex = currentIndex();
if (CurrentIndex < 0)
{
return nullptr;
}
return dockWidget(CurrentIndex);
} }
@ -576,7 +599,7 @@ int CDockAreaWidget::dockWidgetsCount() const
//============================================================================ //============================================================================
CDockWidget* CDockAreaWidget::dockWidget(int Index) const CDockWidget* CDockAreaWidget::dockWidget(int Index) const
{ {
return dynamic_cast<CDockWidget*>(d->ContentsLayout->widget(Index)); return qobject_cast<CDockWidget*>(d->ContentsLayout->widget(Index));
} }
@ -610,7 +633,7 @@ void CDockAreaWidget::toggleDockWidgetView(CDockWidget* DockWidget, bool Open)
//============================================================================ //============================================================================
void CDockAreaWidget::updateTabBarVisibility() void CDockAreaWidget::updateTabBarVisibility()
{ {
d->updateTabBar(); d->updateTitleBarVisibility();
} }
@ -619,9 +642,11 @@ void CDockAreaWidget::saveState(QXmlStreamWriter& s) const
{ {
s.writeStartElement("DockAreaWidget"); s.writeStartElement("DockAreaWidget");
s.writeAttribute("Tabs", QString::number(d->ContentsLayout->count())); s.writeAttribute("Tabs", QString::number(d->ContentsLayout->count()));
s.writeAttribute("CurrentDockWidget", currentDockWidget()->objectName()); auto CurrentDockWidget = currentDockWidget();
QString Name = CurrentDockWidget ? CurrentDockWidget->objectName() : "";
s.writeAttribute("CurrentDockWidget", Name);
qDebug() << "CDockAreaWidget::saveState TabCount: " << d->ContentsLayout->count() qDebug() << "CDockAreaWidget::saveState TabCount: " << d->ContentsLayout->count()
<< " CurrentDockWidge: " << currentDockWidget()->objectName(); << " CurrentDockWidge: " << Name;
for (int i = 0; i < d->ContentsLayout->count(); ++i) for (int i = 0; i < d->ContentsLayout->count(); ++i)
{ {
dockWidget(i)->saveState(s); dockWidget(i)->saveState(s);
@ -675,6 +700,13 @@ void CDockAreaWidget::toggleView(bool Open)
setVisible(Open); setVisible(Open);
emit viewToggled(Open); emit viewToggled(Open);
} }
//============================================================================
QAbstractButton* CDockAreaWidget::titleBarButton(TitleBarButton which) const
{
return d->TitleBar->button(which);
}
} // namespace ads } // namespace ads
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@ -36,6 +36,7 @@
#include "DockWidget.h" #include "DockWidget.h"
class QXmlStreamWriter; class QXmlStreamWriter;
class QAbstractButton;
namespace ads namespace ads
{ {
@ -190,12 +191,14 @@ public:
CDockWidget* dockWidget(int Index) const; CDockWidget* dockWidget(int Index) const;
/** /**
* Returns the index of the current active dock widget * Returns the index of the current active dock widget or -1 if there
* are is no active dock widget (ie.e if all dock widgets are closed)
*/ */
int currentIndex() const; int currentIndex() const;
/** /**
* Returns the current active dock widget * Returns the current active dock widget or a nullptr if there is no
* active dock widget (i.e. if all dock widgets are closed)
*/ */
CDockWidget* currentDockWidget() const; CDockWidget* currentDockWidget() const;
@ -218,6 +221,12 @@ public:
*/ */
CDockWidget::DockWidgetFeatures features() const; CDockWidget::DockWidgetFeatures features() const;
/**
* Returns the title bar button corresponding to the given title bar
* button identifier
*/
QAbstractButton* titleBarButton(TitleBarButton which) const;
public slots: public slots:
/** /**
* This activates the tab for the given tab index. * This activates the tab for the given tab index.

View File

@ -528,10 +528,6 @@ bool DockContainerWidgetPrivate::restoreDockArea(QXmlStreamReader& s,
QString CurrentDockWidget = s.attributes().value("CurrentDockWidget").toString(); QString CurrentDockWidget = s.attributes().value("CurrentDockWidget").toString();
if (CurrentDockWidget.isEmpty())
{
return false;
}
qDebug() << "Restore NodeDockArea Tabs: " << Tabs << " CurrentDockWidget: " qDebug() << "Restore NodeDockArea Tabs: " << Tabs << " CurrentDockWidget: "
<< CurrentDockWidget; << CurrentDockWidget;

View File

@ -264,6 +264,11 @@ bool DockManagerPrivate::restoreState(const QByteArray &state, int version)
{ {
CDockAreaWidget* DockArea = DockContainer->dockArea(i); CDockAreaWidget* DockArea = DockContainer->dockArea(i);
QString DockWidgetName = DockArea->property("currentDockWidget").toString(); QString DockWidgetName = DockArea->property("currentDockWidget").toString();
if (DockWidgetName.isEmpty())
{
continue;
}
CDockWidget* DockWidget = _this->findDockWidget(DockWidgetName); CDockWidget* DockWidget = _this->findDockWidget(DockWidgetName);
if (!DockWidget->isClosed()) if (!DockWidget->isClosed())
{ {
@ -272,29 +277,6 @@ bool DockManagerPrivate::restoreState(const QByteArray &state, int version)
} }
} }
// Finally we need to send the topLevelChanged() signals for all dock
// widgets if top level changed
/*for (auto DockContainer : Containers)
{
CDockWidget* TopLevelDockWidget = DockContainer->topLevelDockWidget();
if (TopLevelDockWidget)
{
TopLevelDockWidget->emitTopLevelChanged(true);
}
else
{
for (int i = 0; i < DockContainer->dockAreaCount(); ++i)
{
auto DockArea = DockContainer->dockArea(i);
for (auto DockWidget : DockArea->dockWidgets())
{
DockWidget->emitTopLevelChanged(false);
}
}
}
}*/
return true; return true;
} }

View File

@ -400,10 +400,7 @@ void CDockWidgetTab::mouseDoubleClickEvent(QMouseEvent *event)
//============================================================================ //============================================================================
void CDockWidgetTab::setVisible(bool visible) void CDockWidgetTab::setVisible(bool visible)
{ {
/*if (!visible) // Just here for debugging to insert debug output
{
qDebug() << "CDockWidgetTab::setVisible " << visible;
}*/
Super::setVisible(visible); Super::setVisible(visible);
} }

View File

@ -36,6 +36,7 @@
#include <QPointer> #include <QPointer>
#include <QAction> #include <QAction>
#include <QDebug> #include <QDebug>
#include <QAbstractButton>
#include "DockContainerWidget.h" #include "DockContainerWidget.h"
#include "DockAreaWidget.h" #include "DockAreaWidget.h"
@ -471,6 +472,7 @@ void CFloatingDockContainer::onDockAreasAddedOrRemoved()
if (TopLevelDockArea) if (TopLevelDockArea)
{ {
d->SingleDockArea = TopLevelDockArea; d->SingleDockArea = TopLevelDockArea;
d->SingleDockArea->titleBarButton(TitleBarButtonUndock)->setVisible(false);
this->setWindowTitle(d->SingleDockArea->currentDockWidget()->windowTitle()); this->setWindowTitle(d->SingleDockArea->currentDockWidget()->windowTitle());
connect(d->SingleDockArea, SIGNAL(currentChanged(int)), this, connect(d->SingleDockArea, SIGNAL(currentChanged(int)), this,
SLOT(onDockAreaCurrentChanged(int))); SLOT(onDockAreaCurrentChanged(int)));
@ -479,6 +481,7 @@ void CFloatingDockContainer::onDockAreasAddedOrRemoved()
{ {
if (d->SingleDockArea) if (d->SingleDockArea)
{ {
d->SingleDockArea->titleBarButton(TitleBarButtonUndock)->setVisible(true);
disconnect(d->SingleDockArea, SIGNAL(currentChanged(int)), this, disconnect(d->SingleDockArea, SIGNAL(currentChanged(int)), this,
SLOT(onDockAreaCurrentChanged(int))); SLOT(onDockAreaCurrentChanged(int)));
d->SingleDockArea = nullptr; d->SingleDockArea = nullptr;

View File

@ -69,6 +69,7 @@ private:
friend class CDockAreaTitleBar; friend class CDockAreaTitleBar;
friend struct DockAreaTitleBarPrivate; friend struct DockAreaTitleBarPrivate;
friend class CDockWidget; friend class CDockWidget;
friend class CDockAreaWidget;
private slots: private slots:
void onDockAreasAddedOrRemoved(); void onDockAreasAddedOrRemoved();

View File

@ -61,6 +61,13 @@ enum DockWidgetArea
Q_DECLARE_FLAGS(DockWidgetAreas, DockWidgetArea) Q_DECLARE_FLAGS(DockWidgetAreas, DockWidgetArea)
enum TitleBarButton
{
TitleBarButtonTabsMenu,
TitleBarButtonUndock,
TitleBarButtonClose
};
namespace internal namespace internal
{ {