mirror of
https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git
synced 2024-12-24 07:21:32 +08:00
Improved hide / show functionality of dock widgets
This commit is contained in:
parent
0d6f469a36
commit
b6ee26adc2
@ -26,7 +26,7 @@ static ads::CDockWidget* createLongTextLabelDockWidget(QMenu* ViewMenu)
|
||||
QLabel* l = new QLabel();
|
||||
l->setWordWrap(true);
|
||||
l->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
l->setText(QString("Lorem Ipsum ist ein einfacher Demo-Text für die Print- "
|
||||
l->setText(QString("Label %1 %2 - Lorem Ipsum ist ein einfacher Demo-Text für die Print- "
|
||||
"und Schriftindustrie. Lorem Ipsum ist in der Industrie bereits der "
|
||||
"Standard Demo-Text seit 1500, als ein unbekannter Schriftsteller eine "
|
||||
"Hand voll Wörter nahm und diese durcheinander warf um ein Musterbuch zu "
|
||||
@ -34,7 +34,9 @@ static ads::CDockWidget* createLongTextLabelDockWidget(QMenu* ViewMenu)
|
||||
"Spruch in die elektronische Schriftbearbeitung geschafft (bemerke, nahezu "
|
||||
"unverändert). Bekannt wurde es 1960, mit dem erscheinen von Letrase, "
|
||||
"welches Passagen von Lorem Ipsum enhielt, so wie Desktop Software wie "
|
||||
"Aldus PageMaker - ebenfalls mit Lorem Ipsum."));
|
||||
"Aldus PageMaker - ebenfalls mit Lorem Ipsum.")
|
||||
.arg(LabelCount)
|
||||
.arg(QTime::currentTime().toString("hh:mm:ss:zzz")));
|
||||
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Label %1").arg(LabelCount++));
|
||||
DockWidget->setWidget(l);
|
||||
|
@ -504,6 +504,18 @@ CDockWidget* CDockAreaWidget::currentDockWidget() const
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaWidget::setCurrentDockWidget(CDockWidget* DockWidget)
|
||||
{
|
||||
int Index = tabIndex(DockWidget);
|
||||
if (Index < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
setCurrentIndex(Index);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaWidget::setCurrentIndex(int index)
|
||||
{
|
||||
@ -530,6 +542,7 @@ void CDockAreaWidget::setCurrentIndex(int index)
|
||||
|
||||
if (i == index)
|
||||
{
|
||||
TitleWidget->show();
|
||||
TitleWidget->setActiveTab(true);
|
||||
d->TabsScrollArea->ensureWidgetVisible(TitleWidget);
|
||||
auto Features = TitleWidget->dockWidget()->features();
|
||||
@ -542,6 +555,7 @@ void CDockAreaWidget::setCurrentIndex(int index)
|
||||
}
|
||||
|
||||
d->ContentsLayout->setCurrentIndex(index);
|
||||
d->ContentsLayout->currentWidget()->show();
|
||||
emit currentChanged(index);
|
||||
}
|
||||
|
||||
@ -585,6 +599,22 @@ QList<CDockWidget*> CDockAreaWidget::dockWidgets() const
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
QList<CDockWidget*> CDockAreaWidget::openDockWidgets() const
|
||||
{
|
||||
QList<CDockWidget*> DockWidgetList;
|
||||
for (int i = 0; i < d->ContentsLayout->count(); ++i)
|
||||
{
|
||||
CDockWidget* DockWidget = dockWidget(i);
|
||||
if (!DockWidget->isClosed())
|
||||
{
|
||||
DockWidgetList.append(dockWidget(i));
|
||||
}
|
||||
}
|
||||
return DockWidgetList;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
int CDockAreaWidget::indexOfContentByTitlePos(const QPoint& p, QWidget* exclude) const
|
||||
{
|
||||
@ -665,6 +695,22 @@ void CDockAreaWidget::updateDockArea()
|
||||
d->updateTabBar();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaWidget::hideEvent(QHideEvent* event)
|
||||
{
|
||||
QFrame::hideEvent(event);
|
||||
emit visibilityChanged(isVisible());
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaWidget::showEvent(QShowEvent* event)
|
||||
{
|
||||
QFrame::showEvent(event);
|
||||
emit visibilityChanged(isVisible());
|
||||
}
|
||||
|
||||
} // namespace ads
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -56,6 +56,10 @@ private slots:
|
||||
void onTabsMenuActionTriggered(QAction* Action);
|
||||
void onCloseButtonClicked();
|
||||
|
||||
protected:
|
||||
virtual void hideEvent(QHideEvent *) override;
|
||||
virtual void showEvent(QShowEvent *) override;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Default Constructor
|
||||
@ -120,10 +124,16 @@ public:
|
||||
int indexOfContentByTitlePos(const QPoint& pos, QWidget* exclude = nullptr) const;
|
||||
|
||||
/**
|
||||
* Returns a list of all dock widgets in this dock area
|
||||
* Returns a list of all dock widgets in this dock area.
|
||||
* This list contains open and closed dock widgets.
|
||||
*/
|
||||
QList<CDockWidget*> dockWidgets() const;
|
||||
|
||||
/**
|
||||
* Returns a list of dock widgets that are not closed
|
||||
*/
|
||||
QList<CDockWidget*> openDockWidgets() const;
|
||||
|
||||
/**
|
||||
* Returns the number of dock widgets in this area
|
||||
*/
|
||||
@ -149,6 +159,11 @@ public:
|
||||
*/
|
||||
CDockWidget* currentDockWidget() const;
|
||||
|
||||
/**
|
||||
* Shows the tab with tghe given dock widget
|
||||
*/
|
||||
void setCurrentDockWidget(CDockWidget* DockWidget);
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* This sets the index position of the current tab page.
|
||||
@ -172,6 +187,14 @@ signals:
|
||||
* @param index
|
||||
*/
|
||||
void currentChanged(int index);
|
||||
|
||||
/**
|
||||
* This signal is emitted if a dock areas visibility changed.
|
||||
* The visibility changes, if the last dock widget in a dock area is closed
|
||||
* or if one dock widget in a dock area with only closed dock widgets
|
||||
* becomes visible
|
||||
*/
|
||||
void visibilityChanged(bool Visible);
|
||||
}; // class DockAreaWidget
|
||||
}
|
||||
// namespace ads
|
||||
|
@ -497,6 +497,7 @@ void CDockContainerWidget::removeDockArea(CDockAreaWidget* area)
|
||||
area->setParent(0);
|
||||
if (!(Splitter && Splitter->count() == 1))
|
||||
{
|
||||
emit dockAreasRemoved();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -586,6 +587,7 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace ads
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -52,6 +52,7 @@ class CDockContainerWidget : public QFrame
|
||||
private:
|
||||
DockContainerWidgetPrivate* d; ///< private data (pimpl)
|
||||
friend class DockContainerWidgetPrivate;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Handles activation events to update zOrderIndex
|
||||
|
@ -62,6 +62,7 @@ struct DockWidgetPrivate
|
||||
CDockManager* DockManager = nullptr;
|
||||
CDockAreaWidget* DockArea = nullptr;
|
||||
QAction* ToggleViewAction;
|
||||
bool Closed = false;
|
||||
struct CapturedState
|
||||
{
|
||||
QString DockTreePosition;
|
||||
@ -83,6 +84,16 @@ struct DockWidgetPrivate
|
||||
* Show dock widget
|
||||
*/
|
||||
void showDockWidget();
|
||||
|
||||
/**
|
||||
* Hides a parent splitter if all dock widgets in the splitter are closed
|
||||
*/
|
||||
void hideEmptyParentSplitter();
|
||||
|
||||
/**
|
||||
* Hides a dock area if all dock widgets in the area are closed
|
||||
*/
|
||||
void hideEmptyParentDockArea();
|
||||
};
|
||||
// struct DockWidgetPrivate
|
||||
|
||||
@ -131,32 +142,8 @@ void DockWidgetPrivate::capturedState()
|
||||
//============================================================================
|
||||
void DockWidgetPrivate::showDockWidget()
|
||||
{
|
||||
/*if (!CapturedState.DockContainer)
|
||||
{
|
||||
auto FloatingWidget = new CFloatingDockContainer(_this);
|
||||
FloatingWidget->setGeometry(CapturedState.GlobalGeometry);
|
||||
FloatingWidget->show();
|
||||
return;
|
||||
}
|
||||
|
||||
CDockContainerWidget* DockContainer = CapturedState.DockContainer.data();
|
||||
QStringList DockTree = this->CapturedState.DockTreePosition.split(' ');
|
||||
QSplitter* splitter = DockContainer->findChild<QSplitter*>(QString(), Qt::FindDirectChildrenOnly);
|
||||
|
||||
while (splitter)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
for (const auto& TreeItem : DockTree)
|
||||
{
|
||||
|
||||
}*/
|
||||
|
||||
std::cout << "DockWidgetPrivate::showDockWidget()" << std::endl;
|
||||
_this->show();
|
||||
DockArea->show();
|
||||
|
||||
DockArea->setCurrentIndex(DockArea->tabIndex(_this));
|
||||
QSplitter* Splitter = internal::findParent<QSplitter*>(_this);
|
||||
if (Splitter)
|
||||
{
|
||||
@ -165,6 +152,53 @@ void DockWidgetPrivate::showDockWidget()
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void DockWidgetPrivate::hideEmptyParentSplitter()
|
||||
{
|
||||
QSplitter* Splitter = internal::findParent<QSplitter*>(_this);
|
||||
if (!Splitter)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < Splitter->count(); ++i)
|
||||
{
|
||||
if (Splitter->widget(i)->isVisible())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Splitter->hide();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void DockWidgetPrivate::hideEmptyParentDockArea()
|
||||
{
|
||||
auto OpenDockWidgets = DockArea->openDockWidgets();
|
||||
if (OpenDockWidgets.count() > 1)
|
||||
{
|
||||
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
|
||||
{
|
||||
DockArea->hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
CDockWidget::CDockWidget(const QString &title, QWidget *parent) :
|
||||
QFrame(parent),
|
||||
@ -270,6 +304,13 @@ bool CDockWidget::isFloating() const
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool CDockWidget::isClosed() const
|
||||
{
|
||||
return d->Closed;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
QAction* CDockWidget::toggleViewAction() const
|
||||
{
|
||||
@ -280,28 +321,15 @@ QAction* CDockWidget::toggleViewAction() const
|
||||
//============================================================================
|
||||
void CDockWidget::toggleView(bool Open)
|
||||
{
|
||||
/*if ((d->DockArea != nullptr) == Open)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Open && d->DockArea)
|
||||
{
|
||||
hideDockWidget(true);
|
||||
}
|
||||
else if (Open && !d->DockArea)
|
||||
{
|
||||
d->showDockWidget();
|
||||
}*/
|
||||
|
||||
if (Open)
|
||||
{
|
||||
d->showDockWidget();
|
||||
}
|
||||
else
|
||||
{
|
||||
hideDockWidget(true);
|
||||
hideDockWidget();
|
||||
}
|
||||
d->Closed = !Open;
|
||||
}
|
||||
|
||||
|
||||
@ -315,59 +343,13 @@ void CDockWidget::setDockArea(CDockAreaWidget* DockArea)
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockWidget::hideDockWidget(bool RemoveFromDockArea)
|
||||
void CDockWidget::hideDockWidget()
|
||||
{
|
||||
/*d->capturedState();
|
||||
if (d->DockArea && RemoveFromDockArea)
|
||||
{
|
||||
d->DockArea->removeDockWidget(this);
|
||||
}
|
||||
this->setParent(d->DockManager);
|
||||
this->setDockArea(nullptr);
|
||||
// Remove title from dock area widget to prevent its deletion if dock
|
||||
// area is deleted
|
||||
d->TitleWidget->setParent(this);*/
|
||||
|
||||
std::cout << "CDockWidget::hideDockWidget" << std::endl;
|
||||
this->hide();
|
||||
CDockAreaWidget* DockArea = d->DockArea;
|
||||
d->ToggleViewAction->setChecked(false);
|
||||
d->TitleWidget->hide();
|
||||
CDockAreaWidget* DockArea = d->DockArea;
|
||||
for (int i = 0; i < DockArea->count(); ++i)
|
||||
{
|
||||
if (DockArea->dockWidget(i)->isVisible())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (DockArea->count() > 1)
|
||||
{
|
||||
if (DockArea->currentIndex() == (DockArea->count() - 1))
|
||||
{
|
||||
DockArea->setCurrentIndex(DockArea->currentIndex() - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
DockArea->setCurrentIndex(DockArea->currentIndex() + 1);
|
||||
}
|
||||
}
|
||||
QSplitter* Splitter = internal::findParent<QSplitter*>(this);
|
||||
if (!Splitter)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "DockWidgets " << Splitter->count() << std::endl;
|
||||
for (int i = 0; i < Splitter->count(); ++i)
|
||||
{
|
||||
if (Splitter->widget(i)->isVisible())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Splitter->hide();
|
||||
d->hideEmptyParentDockArea();
|
||||
d->hideEmptyParentSplitter();
|
||||
}
|
||||
|
||||
} // namespace ads
|
||||
|
@ -71,10 +71,8 @@ protected:
|
||||
|
||||
/**
|
||||
* Hide dock widget.
|
||||
* If RemoveFromDockArea is true, the dock widget will be properly removed
|
||||
* from dock area.
|
||||
*/
|
||||
void hideDockWidget(bool RemoveFromDockArea = true);
|
||||
void hideDockWidget();
|
||||
|
||||
public:
|
||||
enum DockWidgetFeature
|
||||
@ -157,6 +155,11 @@ public:
|
||||
*/
|
||||
bool isFloating() const;
|
||||
|
||||
/**
|
||||
* Returns true, if this dock widget is closed.
|
||||
*/
|
||||
bool isClosed() const;
|
||||
|
||||
/**
|
||||
* Returns a checkable action that can be used to show or close this dock widget.
|
||||
* The action's text is set to the dock widget's window title.
|
||||
|
@ -172,7 +172,7 @@ CFloatingDockContainer::CFloatingDockContainer(CDockManager* DockManager) :
|
||||
QWidget(DockManager, Qt::Window),
|
||||
d(new FloatingDockContainerPrivate(this))
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
//setAttribute(Qt::WA_DeleteOnClose);
|
||||
d->DockManager = DockManager;
|
||||
QBoxLayout* l = new QBoxLayout(QBoxLayout::TopToBottom);
|
||||
l->setContentsMargins(0, 0, 0, 0);
|
||||
@ -210,6 +210,7 @@ CFloatingDockContainer::CFloatingDockContainer(CDockWidget* DockWidget) :
|
||||
//============================================================================
|
||||
CFloatingDockContainer::~CFloatingDockContainer()
|
||||
{
|
||||
std::cout << "~CFloatingDockContainer" << std::endl;
|
||||
if (d->DockManager)
|
||||
{
|
||||
d->DockManager->removeFloatingWidget(this);
|
||||
@ -269,17 +270,21 @@ void CFloatingDockContainer::closeEvent(QCloseEvent *event)
|
||||
auto DockWidgets = dockContainer()->dockArea(i)->dockWidgets();
|
||||
for (auto DockWidget : DockWidgets)
|
||||
{
|
||||
DockWidget->hideDockWidget(false);
|
||||
DockWidget->hideDockWidget();
|
||||
}
|
||||
}
|
||||
QWidget::closeEvent(event);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Closing single tab" << std::endl;
|
||||
event->ignore();
|
||||
auto DockArea = dockContainer()->dockArea(0);
|
||||
DockArea->currentDockWidget()->hideDockWidget(true);
|
||||
DockArea->currentDockWidget()->hideDockWidget();
|
||||
// As long as there are open dock widgets, we do not close the floating
|
||||
// window
|
||||
if (DockArea->openDockWidgets().count())
|
||||
{
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user