mirror of
https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git
synced 2024-11-15 13:15:43 +08:00
Merge remote-tracking branch 'remotes/origin/autohide_drag'
This commit is contained in:
commit
f00ef60fb3
70
README.md
70
README.md
@ -22,6 +22,70 @@ integrated development environments (IDEs) such as Visual Studio.
|
||||
|
||||
## New and Noteworthy
|
||||
|
||||
Release [4.1](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/releases/latest) significantly improves the Auto-Hide functionality and also brings improvements
|
||||
for Drag and Drop of dock widgets into dock area tabs. These are the highlights of the new version:
|
||||
|
||||
#### Drag & Drop to Auto-Hide
|
||||
|
||||
Now you can easily drag any dock widget or any floating widget to the
|
||||
borders of a window to pin it as a auto-hide tab in one of the 4 sidebars.
|
||||
If you drag a dock widget close the one of the four window borders, special
|
||||
drop overlays will be shown to indicate the drop area for auto-hide widgets:
|
||||
|
||||
![Auo-Hide drag to Sidebar](doc/AutoHide_Drag_to_Sidebar.gif)
|
||||
|
||||
Of course, this also works with dock areas:
|
||||
|
||||
![Auo-Hide drag Dock Area](doc/AutoHide_Drag_DockArea.gif)
|
||||
|
||||
If you drag a dock widget or dock area into a sidebar, then you even have
|
||||
control over where tabs are inserted. Simply drag your mouse over a specific
|
||||
auto-hide tab, and your dragged dock widget will be inserted before this tab.
|
||||
Drag to the sidebar area behind the last tab, and the dragged widget will be
|
||||
appended as last tab. In the following screen capture, the **Image Viewer 1** will
|
||||
be inserted before the **Table 0** Auto-Hide tab and the **Image Viewer 2**
|
||||
is appende behind the last tab:
|
||||
|
||||
![Auo-Hide tab insert order](doc/AutoHide_Tab_Insert_Order.gif)
|
||||
|
||||
#### Auto-Hide Tab Insertion Order
|
||||
|
||||
It is also possible to drag Auto-Hide tabs to a new auto-hide position.
|
||||
That means, you can drag them to a different border or sidebar:
|
||||
|
||||
![Auto-Hide change sidebar](doc/AutoHide_Change_Sidebar.gif)
|
||||
|
||||
#### Auto-Hide Tab Sorting
|
||||
|
||||
You can drag Auto-Hide tabs to a new position in the current sidebar
|
||||
to sort them:
|
||||
|
||||
![Auo-Hide sort tabs](doc/AutoHide_Sort_Tabs.gif)
|
||||
|
||||
#### Auto-Hide Drag to Float / Dock
|
||||
|
||||
But that is not all. You can also simply move Auto-Hide tabs to another
|
||||
floating widget or dock them via drag and drop:
|
||||
|
||||
![Auo-Hide drag to float or dock](doc/AutoHide_Drag_to_Float_or_Dock.gif)
|
||||
|
||||
#### Auto-Hide Context Menu
|
||||
|
||||
All Auto-Hide tabs now have a context menu, that provides all the functionality
|
||||
that you know from Dock widget tabs. With the **Pin To...** item from the
|
||||
context menu it is very easy to move an Auto-Hide tab to a different Auto-Hide
|
||||
sidebar:
|
||||
|
||||
![Auo-Hide context menu](doc/AutoHide_Context_Menu.png)
|
||||
|
||||
#### Dock Area Tab Insert Order
|
||||
|
||||
And last but not least the new version also improves the docking of widgets
|
||||
into the tabs of a Dock area. Just as with Auto-Hide tabs, you can now determine the position at which a tab is inserted by moving the mouse over an already existing tab (insertion before the tab) or behind the last tab
|
||||
(appending):
|
||||
|
||||
![Dock area tab insert order](doc/DockArea_Tab_Insertion_Order.gif)
|
||||
|
||||
The [release 4.0](https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/releases/latest)
|
||||
adds the following features:
|
||||
|
||||
@ -77,6 +141,12 @@ know it from Visual Studio.
|
||||
### Overview
|
||||
|
||||
- [New and Noteworthy](#new-and-noteworthy)
|
||||
- [Drag \& Drop to Auto-Hide](#drag--drop-to-auto-hide)
|
||||
- [Auto-Hide Tab Insertion Order](#auto-hide-tab-insertion-order)
|
||||
- [Auto-Hide Tab Sorting](#auto-hide-tab-sorting)
|
||||
- [Auto-Hide Drag to Float / Dock](#auto-hide-drag-to-float--dock)
|
||||
- [Auto-Hide Context Menu](#auto-hide-context-menu)
|
||||
- [Dock Area Tab Insert Order](#dock-area-tab-insert-order)
|
||||
- [Features](#features)
|
||||
- [Overview](#overview)
|
||||
- [Docking everywhere - no central widget](#docking-everywhere---no-central-widget)
|
||||
|
@ -448,8 +448,8 @@ void MainWindowPrivate::createContent()
|
||||
|
||||
// For this Special Dock Area we want to avoid dropping on the center of it (i.e. we don't want this widget to be ever tabbified):
|
||||
{
|
||||
SpecialDockArea->setAllowedAreas(ads::OuterDockAreas);
|
||||
//SpecialDockArea->setAllowedAreas({ads::LeftDockWidgetArea, ads::RightDockWidgetArea}); // just for testing
|
||||
//SpecialDockArea->setAllowedAreas(ads::OuterDockAreas);
|
||||
SpecialDockArea->setAllowedAreas({ads::LeftDockWidgetArea, ads::RightDockWidgetArea, ads::TopDockWidgetArea}); // just for testing
|
||||
}
|
||||
|
||||
DockWidget = createLongTextLabelDockWidget();
|
||||
@ -517,7 +517,9 @@ void MainWindowPrivate::createContent()
|
||||
|
||||
// Test dock area docking
|
||||
auto RighDockArea = DockManager->addDockWidget(ads::RightDockWidgetArea, createLongTextLabelDockWidget(), TopDockArea);
|
||||
DockManager->addDockWidget(ads::TopDockWidgetArea, createLongTextLabelDockWidget(), RighDockArea);
|
||||
DockWidget = createLongTextLabelDockWidget();
|
||||
DockWidget->setFeature(ads::CDockWidget::DockWidgetPinnable, false);
|
||||
DockManager->addDockWidget(ads::TopDockWidgetArea, DockWidget, RighDockArea);
|
||||
auto BottomDockArea = DockManager->addDockWidget(ads::BottomDockWidgetArea, createLongTextLabelDockWidget(), RighDockArea);
|
||||
DockManager->addDockWidget(ads::CenterDockWidgetArea, createLongTextLabelDockWidget(), RighDockArea);
|
||||
auto LabelDockWidget = createLongTextLabelDockWidget();
|
||||
|
@ -117,6 +117,7 @@ struct AutoHideDockContainerPrivate
|
||||
CResizeHandle* ResizeHandle = nullptr;
|
||||
QSize Size; // creates invalid size
|
||||
QPointer<CAutoHideTab> SideTab;
|
||||
QSize SizeCache;
|
||||
|
||||
/**
|
||||
* Private data constructor
|
||||
@ -215,6 +216,7 @@ CAutoHideDockContainer::CAutoHideDockContainer(CDockWidget* DockWidget, SideBarL
|
||||
bool OpaqueResize = CDockManager::testConfigFlag(CDockManager::OpaqueSplitterResize);
|
||||
d->ResizeHandle->setOpaqueResize(OpaqueResize);
|
||||
d->Size = d->DockArea->size();
|
||||
d->SizeCache = DockWidget->size();
|
||||
|
||||
addDockWidget(DockWidget);
|
||||
parent->registerAutoHideWidget(this);
|
||||
@ -237,7 +239,6 @@ void CAutoHideDockContainer::updateSize()
|
||||
}
|
||||
|
||||
auto rect = dockContainerParent->contentRect();
|
||||
|
||||
switch (sideBarLocation())
|
||||
{
|
||||
case SideBarLocation::SideBarTop:
|
||||
@ -271,6 +272,15 @@ void CAutoHideDockContainer::updateSize()
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (orientation() == Qt::Horizontal)
|
||||
{
|
||||
d->SizeCache.setHeight(this->height());
|
||||
}
|
||||
else
|
||||
{
|
||||
d->SizeCache.setWidth(this->width());
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
@ -294,7 +304,7 @@ CAutoHideDockContainer::~CAutoHideDockContainer()
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
CAutoHideSideBar* CAutoHideDockContainer::sideBar() const
|
||||
CAutoHideSideBar* CAutoHideDockContainer::autoHideSideBar() const
|
||||
{
|
||||
if (d->SideTab)
|
||||
{
|
||||
@ -303,7 +313,7 @@ CAutoHideSideBar* CAutoHideDockContainer::sideBar() const
|
||||
else
|
||||
{
|
||||
auto DockContainer = dockContainer();
|
||||
return DockContainer ? DockContainer->sideTabBar(d->SideTabBarArea) : nullptr;
|
||||
return DockContainer ? DockContainer->autoHideSideBar(d->SideTabBarArea) : nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -344,6 +354,10 @@ void CAutoHideDockContainer::addDockWidget(CDockWidget* DockWidget)
|
||||
}
|
||||
d->DockArea->addDockWidget(DockWidget);
|
||||
updateSize();
|
||||
// The dock area is not visible and will not update the size when updateSize()
|
||||
// is called for this auto hide container. Therefore we explicitely resize
|
||||
// it here. As soon as it will become visible, it will get the right size
|
||||
d->DockArea->resize(size());
|
||||
}
|
||||
|
||||
|
||||
@ -643,5 +657,56 @@ bool CAutoHideDockContainer::event(QEvent* event)
|
||||
return Super::event(event);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
Qt::Orientation CAutoHideDockContainer::orientation() const
|
||||
{
|
||||
return ads::internal::isHorizontalSideBarLocation(d->SideTabBarArea)
|
||||
? Qt::Horizontal : Qt::Vertical;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideDockContainer::resetToInitialDockWidgetSize()
|
||||
{
|
||||
if (orientation() == Qt::Horizontal)
|
||||
{
|
||||
setSize(d->SizeCache.height());
|
||||
}
|
||||
else
|
||||
{
|
||||
setSize(d->SizeCache.width());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideDockContainer::moveToNewSideBarLocation(SideBarLocation NewSideBarLocation,
|
||||
int TabIndex)
|
||||
{
|
||||
if (NewSideBarLocation == sideBarLocation() && TabIndex == this->tabIndex())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto OldOrientation = orientation();
|
||||
auto SideBar = dockContainer()->autoHideSideBar(NewSideBarLocation);
|
||||
SideBar->addAutoHideWidget(this, TabIndex);
|
||||
// If we move a horizontal auto hide container to a vertical position
|
||||
// then we resize it to the orginal dock widget size, to avoid
|
||||
// an extremely streched dock widget after insertion
|
||||
if (SideBar->orientation() != OldOrientation)
|
||||
{
|
||||
resetToInitialDockWidgetSize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
int CAutoHideDockContainer::tabIndex() const
|
||||
{
|
||||
return d->SideTab->tabIndex();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ public:
|
||||
/**
|
||||
* Get's the side tab bar
|
||||
*/
|
||||
CAutoHideSideBar* sideBar() const;
|
||||
CAutoHideSideBar* autoHideSideBar() const;
|
||||
|
||||
/**
|
||||
* Returns the side tab
|
||||
@ -105,6 +105,11 @@ public:
|
||||
*/
|
||||
CDockWidget* dockWidget() const;
|
||||
|
||||
/**
|
||||
* Returns the index of this container in the sidebar
|
||||
*/
|
||||
int tabIndex() const;
|
||||
|
||||
/**
|
||||
* Adds a dock widget and removes the previous dock widget
|
||||
*/
|
||||
@ -166,6 +171,30 @@ public:
|
||||
* of this auto hide container.
|
||||
*/
|
||||
void setSize(int Size);
|
||||
|
||||
/**
|
||||
* Resets the with or hight to the initial dock widget size dependinng on
|
||||
* the orientation.
|
||||
* If the orientation is Qt::Horizontal, then the height is reset to
|
||||
* the initial size and if orientation is Qt::Vertical, then the width is
|
||||
* reset to the initial size
|
||||
*/
|
||||
void resetToInitialDockWidgetSize();
|
||||
|
||||
/**
|
||||
* Returns orientation of this container.
|
||||
* Left and right containers have a Qt::Vertical orientation and top / bottom
|
||||
* containers have a Qt::Horizontal orientation.
|
||||
* The function returns the orientation of the corresponding auto hide
|
||||
* side bar.
|
||||
*/
|
||||
Qt::Orientation orientation() const;
|
||||
|
||||
/**
|
||||
* Removes the AutoHide container from the current side bar and adds
|
||||
* it to the new side bar given in SideBarLocation
|
||||
*/
|
||||
void moveToNewSideBarLocation(SideBarLocation SideBarLocation, int TabIndex = -1);
|
||||
};
|
||||
} // namespace ads
|
||||
|
||||
|
@ -196,6 +196,7 @@ void CAutoHideSideBar::insertTab(int Index, CAutoHideTab* SideTab)
|
||||
{
|
||||
SideTab->setSideBar(this);
|
||||
SideTab->installEventFilter(this);
|
||||
// Default insertion is append
|
||||
if (Index < 0)
|
||||
{
|
||||
d->TabsLayout->insertWidget(d->TabsLayout->count() - 1, SideTab);
|
||||
@ -233,12 +234,25 @@ void CAutoHideSideBar::removeAutoHideWidget(CAutoHideDockContainer* AutoHideWidg
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideSideBar::addAutoHideWidget(CAutoHideDockContainer* AutoHideWidget)
|
||||
void CAutoHideSideBar::addAutoHideWidget(CAutoHideDockContainer* AutoHideWidget,
|
||||
int TabIndex)
|
||||
{
|
||||
auto SideBar = AutoHideWidget->autoHideTab()->sideBar();
|
||||
if (SideBar == this)
|
||||
{
|
||||
return;
|
||||
// If we move to the same tab index or if we insert before the next
|
||||
// tab index, then we will end at the same tab position and can leave
|
||||
if (AutoHideWidget->tabIndex() == TabIndex || (AutoHideWidget->tabIndex() + 1) == TabIndex)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// We remove this auto hide widget from the sidebar in the code below
|
||||
// and therefore need to correct the TabIndex here
|
||||
if (AutoHideWidget->tabIndex() < TabIndex)
|
||||
{
|
||||
--TabIndex;
|
||||
}
|
||||
}
|
||||
|
||||
if (SideBar)
|
||||
@ -248,7 +262,7 @@ void CAutoHideSideBar::addAutoHideWidget(CAutoHideDockContainer* AutoHideWidget)
|
||||
AutoHideWidget->setParent(d->ContainerWidget);
|
||||
AutoHideWidget->setSideBarLocation(d->SideTabArea);
|
||||
d->ContainerWidget->registerAutoHideWidget(AutoHideWidget);
|
||||
insertTab(-1, AutoHideWidget->autoHideTab());
|
||||
insertTab(TabIndex, AutoHideWidget->autoHideTab());
|
||||
}
|
||||
|
||||
|
||||
@ -302,14 +316,14 @@ Qt::Orientation CAutoHideSideBar::orientation() const
|
||||
|
||||
|
||||
//============================================================================
|
||||
CAutoHideTab* CAutoHideSideBar::tabAt(int index) const
|
||||
CAutoHideTab* CAutoHideSideBar::tab(int index) const
|
||||
{
|
||||
return qobject_cast<CAutoHideTab*>(d->TabsLayout->itemAt(index)->widget());
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
int CAutoHideSideBar::tabCount() const
|
||||
int CAutoHideSideBar::count() const
|
||||
{
|
||||
return d->TabsLayout->count() - 1;
|
||||
}
|
||||
@ -318,17 +332,17 @@ int CAutoHideSideBar::tabCount() const
|
||||
//============================================================================
|
||||
int CAutoHideSideBar::visibleTabCount() const
|
||||
{
|
||||
int count = 0;
|
||||
int VisibleTabCount = 0;
|
||||
auto ParentWidget = parentWidget();
|
||||
for (auto i = 0; i < tabCount(); i++)
|
||||
for (auto i = 0; i < count(); i++)
|
||||
{
|
||||
if (tabAt(i)->isVisibleTo(ParentWidget))
|
||||
if (tab(i)->isVisibleTo(ParentWidget))
|
||||
{
|
||||
count++;
|
||||
VisibleTabCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
return VisibleTabCount;
|
||||
}
|
||||
|
||||
|
||||
@ -336,9 +350,9 @@ int CAutoHideSideBar::visibleTabCount() const
|
||||
bool CAutoHideSideBar::hasVisibleTabs() const
|
||||
{
|
||||
auto ParentWidget = parentWidget();
|
||||
for (auto i = 0; i < tabCount(); i++)
|
||||
for (auto i = 0; i < count(); i++)
|
||||
{
|
||||
if (tabAt(i)->isVisibleTo(ParentWidget))
|
||||
if (tab(i)->isVisibleTo(ParentWidget))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -348,6 +362,21 @@ bool CAutoHideSideBar::hasVisibleTabs() const
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
int CAutoHideSideBar::indexOfTab(const CAutoHideTab& Tab) const
|
||||
{
|
||||
for (auto i = 0; i < count(); i++)
|
||||
{
|
||||
if (tab(i) == &Tab)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
SideBarLocation CAutoHideSideBar::sideBarLocation() const
|
||||
{
|
||||
@ -358,18 +387,18 @@ SideBarLocation CAutoHideSideBar::sideBarLocation() const
|
||||
//============================================================================
|
||||
void CAutoHideSideBar::saveState(QXmlStreamWriter& s) const
|
||||
{
|
||||
if (!tabCount())
|
||||
if (!count())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
s.writeStartElement("SideBar");
|
||||
s.writeAttribute("Area", QString::number(sideBarLocation()));
|
||||
s.writeAttribute("Tabs", QString::number(tabCount()));
|
||||
s.writeAttribute("Tabs", QString::number(count()));
|
||||
|
||||
for (auto i = 0; i < tabCount(); ++i)
|
||||
for (auto i = 0; i < count(); ++i)
|
||||
{
|
||||
auto Tab = tabAt(i);
|
||||
auto Tab = tab(i);
|
||||
if (!Tab)
|
||||
{
|
||||
continue;
|
||||
@ -417,5 +446,56 @@ CDockContainerWidget* CAutoHideSideBar::dockContainer() const
|
||||
return d->ContainerWidget;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
int CAutoHideSideBar::tabAt(const QPoint& Pos) const
|
||||
{
|
||||
if (!isVisible())
|
||||
{
|
||||
return TabInvalidIndex;
|
||||
}
|
||||
|
||||
if (orientation() == Qt::Horizontal)
|
||||
{
|
||||
if (Pos.x() < tab(0)->geometry().x())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Pos.y() < tab(0)->geometry().y())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < count(); ++i)
|
||||
{
|
||||
if (tab(i)->geometry().contains(Pos))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return count();
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
int CAutoHideSideBar::tabInsertIndexAt(const QPoint& Pos) const
|
||||
{
|
||||
int Index = tabAt(Pos);
|
||||
if (Index == TabInvalidIndex)
|
||||
{
|
||||
return TabDefaultInsertIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (Index < 0) ? 0 : Index;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ads
|
||||
|
||||
|
@ -117,7 +117,7 @@ public:
|
||||
* If the AutoHideWidget is in another sidebar, then it will be removed
|
||||
* from this sidebar.
|
||||
*/
|
||||
void addAutoHideWidget(CAutoHideDockContainer* AutoHideWidget);
|
||||
void addAutoHideWidget(CAutoHideDockContainer* AutoHideWidget, int Index = TabDefaultInsertIndex);
|
||||
|
||||
/**
|
||||
* Returns orientation of side tab.
|
||||
@ -125,14 +125,32 @@ public:
|
||||
Qt::Orientation orientation() const;
|
||||
|
||||
/*
|
||||
* get the side tab widget at position, returns nullptr if it's out of bounds
|
||||
* Get the side tab widget at position, returns nullptr if it's out of bounds
|
||||
*/
|
||||
CAutoHideTab* tabAt(int index) const;
|
||||
CAutoHideTab* tab(int index) const;
|
||||
|
||||
/**
|
||||
* Returns the tab at the given position.
|
||||
* Returns -1 if the position is left of the first tab and count() if the
|
||||
* position is right of the last tab. Returns InvalidTabIndex (-2) to
|
||||
* indicate an invalid value.
|
||||
*/
|
||||
int tabAt(const QPoint& Pos) const;
|
||||
|
||||
/**
|
||||
* Returns the tab insertion index for the given mouse cursor position
|
||||
*/
|
||||
int tabInsertIndexAt(const QPoint& Pos) const;
|
||||
|
||||
/**
|
||||
* Returns the index of the given tab
|
||||
*/
|
||||
int indexOfTab(const CAutoHideTab& Tab) const;
|
||||
|
||||
/*
|
||||
* Gets the count of the tab widgets
|
||||
*/
|
||||
int tabCount() const;
|
||||
int count() const;
|
||||
|
||||
/**
|
||||
* Returns the number of visible tabs to its parent widget.
|
||||
|
@ -32,15 +32,20 @@
|
||||
#include <QBoxLayout>
|
||||
#include <QApplication>
|
||||
#include <QElapsedTimer>
|
||||
#include <QMenu>
|
||||
|
||||
#include "AutoHideDockContainer.h"
|
||||
#include "AutoHideSideBar.h"
|
||||
#include "DockAreaWidget.h"
|
||||
#include "DockManager.h"
|
||||
#include "DockWidget.h"
|
||||
#include "FloatingDragPreview.h"
|
||||
#include "DockOverlay.h"
|
||||
|
||||
namespace ads
|
||||
{
|
||||
static const char* const LocationProperty = "Location";
|
||||
|
||||
/**
|
||||
* Private data class of CDockWidgetTab class (pimpl)
|
||||
*/
|
||||
@ -51,6 +56,12 @@ struct AutoHideTabPrivate
|
||||
CAutoHideSideBar* SideBar = nullptr;
|
||||
Qt::Orientation Orientation{Qt::Vertical};
|
||||
QElapsedTimer TimeSinceHoverMousePress;
|
||||
bool MousePressed = false;
|
||||
eDragState DragState = DraggingInactive;
|
||||
QPoint GlobalDragStartMousePosition;
|
||||
QPoint DragStartMousePosition;
|
||||
IFloatingWidget* FloatingWidget = nullptr;
|
||||
Qt::Orientation DragStartOrientation;
|
||||
|
||||
/**
|
||||
* Private data constructor
|
||||
@ -82,6 +93,55 @@ struct AutoHideTabPrivate
|
||||
DockContainer->handleAutoHideWidgetEvent(event, _this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to create and initialize the menu entries for
|
||||
* the "Auto Hide Group To..." menu
|
||||
*/
|
||||
QAction* createAutoHideToAction(const QString& Title, SideBarLocation Location,
|
||||
QMenu* Menu)
|
||||
{
|
||||
auto Action = Menu->addAction(Title);
|
||||
Action->setProperty("Location", Location);
|
||||
QObject::connect(Action, &QAction::triggered, _this, &CAutoHideTab::onAutoHideToActionClicked);
|
||||
Action->setEnabled(Location != _this->sideBarLocation());
|
||||
return Action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test function for current drag state
|
||||
*/
|
||||
bool isDraggingState(eDragState dragState) const
|
||||
{
|
||||
return this->DragState == dragState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the drag start position in global and local coordinates
|
||||
*/
|
||||
void saveDragStartMousePosition(const QPoint& GlobalPos)
|
||||
{
|
||||
GlobalDragStartMousePosition = GlobalPos;
|
||||
DragStartMousePosition = _this->mapFromGlobal(GlobalPos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts floating of the dock widget that belongs to this title bar
|
||||
* Returns true, if floating has been started and false if floating
|
||||
* is not possible for any reason
|
||||
*/
|
||||
bool startFloating(eDragState DraggingState = DraggingFloatingWidget);
|
||||
|
||||
template <typename T>
|
||||
IFloatingWidget* createFloatingWidget(T* Widget)
|
||||
{
|
||||
auto w = new CFloatingDragPreview(Widget);
|
||||
_this->connect(w, &CFloatingDragPreview::draggingCanceled, [=]()
|
||||
{
|
||||
DragState = DraggingInactive;
|
||||
});
|
||||
return w;
|
||||
}
|
||||
}; // struct DockWidgetTabPrivate
|
||||
|
||||
|
||||
@ -110,6 +170,53 @@ void AutoHideTabPrivate::updateOrientation()
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool AutoHideTabPrivate::startFloating(eDragState DraggingState)
|
||||
{
|
||||
auto DockArea = DockWidget->dockAreaWidget();
|
||||
ADS_PRINT("isFloating " << dockContainer->isFloating());
|
||||
|
||||
ADS_PRINT("startFloating");
|
||||
DragState = DraggingState;
|
||||
IFloatingWidget* FloatingWidget = nullptr;
|
||||
FloatingWidget = createFloatingWidget(DockArea);
|
||||
auto Size = DockArea->size();
|
||||
auto StartPos = DragStartMousePosition;
|
||||
auto AutoHideContainer = DockWidget->autoHideDockContainer();
|
||||
DragStartOrientation = AutoHideContainer->orientation();
|
||||
switch (SideBar->sideBarLocation())
|
||||
{
|
||||
case SideBarLeft:
|
||||
StartPos.rx() = AutoHideContainer->rect().left() + 10;
|
||||
break;
|
||||
|
||||
case SideBarRight:
|
||||
StartPos.rx() = AutoHideContainer->rect().right() - 10;
|
||||
break;
|
||||
|
||||
case SideBarTop:
|
||||
StartPos.ry() = AutoHideContainer->rect().top() + 10;
|
||||
break;
|
||||
|
||||
case SideBarBottom:
|
||||
StartPos.ry() = AutoHideContainer->rect().bottom() - 10;
|
||||
break;
|
||||
|
||||
case SideBarNone:
|
||||
return false;
|
||||
}
|
||||
FloatingWidget->startFloating(StartPos, Size, DraggingFloatingWidget, _this);
|
||||
auto DockManager = DockWidget->dockManager();
|
||||
auto Overlay = DockManager->containerOverlay();
|
||||
Overlay->setAllowedAreas(OuterDockAreas);
|
||||
this->FloatingWidget = FloatingWidget;
|
||||
qApp->postEvent(DockWidget, new QEvent((QEvent::Type)internal::DockedWidgetDragStartEvent));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideTab::setSideBar(CAutoHideSideBar* SideTabBar)
|
||||
{
|
||||
@ -250,32 +357,205 @@ bool CAutoHideTab::event(QEvent* event)
|
||||
d->forwardEventToDockContainer(event);
|
||||
break;
|
||||
|
||||
case QEvent::MouseButtonPress:
|
||||
// If AutoHideShowOnMouseOver is active, then the showing is triggered
|
||||
// by a MousePressEvent sent to this tab. To prevent accidental hiding
|
||||
// of the tab by a mouse click, we wait at least 500 ms before we accept
|
||||
// the mouse click
|
||||
if (!event->spontaneous())
|
||||
{
|
||||
d->TimeSinceHoverMousePress.restart();
|
||||
d->forwardEventToDockContainer(event);
|
||||
}
|
||||
else if (d->TimeSinceHoverMousePress.hasExpired(500))
|
||||
{
|
||||
d->forwardEventToDockContainer(event);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Super::event(event);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool CAutoHideTab::iconOnly() const
|
||||
{
|
||||
return CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideSideBarsIconOnly) && !icon().isNull();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideTab::contextMenuEvent(QContextMenuEvent* ev)
|
||||
{
|
||||
ev->accept();
|
||||
d->saveDragStartMousePosition(ev->globalPos());
|
||||
|
||||
const bool isFloatable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable);
|
||||
QAction* Action;
|
||||
QMenu Menu(this);
|
||||
|
||||
Action = Menu.addAction(tr("Detach"), this, SLOT(setDockWidgetFloating()));
|
||||
Action->setEnabled(isFloatable);
|
||||
auto IsPinnable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetPinnable);
|
||||
Action->setEnabled(IsPinnable);
|
||||
|
||||
auto menu = Menu.addMenu(tr("Pin To..."));
|
||||
menu->setEnabled(IsPinnable);
|
||||
d->createAutoHideToAction(tr("Top"), SideBarTop, menu);
|
||||
d->createAutoHideToAction(tr("Left"), SideBarLeft, menu);
|
||||
d->createAutoHideToAction(tr("Right"), SideBarRight, menu);
|
||||
d->createAutoHideToAction(tr("Bottom"), SideBarBottom, menu);
|
||||
|
||||
Action = Menu.addAction(tr("Unpin (Dock)"), this, SLOT(unpinDockWidget()));
|
||||
Menu.addSeparator();
|
||||
Action = Menu.addAction(tr("Close"), this, SLOT(requestCloseDockWidget()));
|
||||
Action->setEnabled(d->DockWidget->features().testFlag(CDockWidget::DockWidgetClosable));
|
||||
|
||||
Menu.exec(ev->globalPos());
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideTab::setDockWidgetFloating()
|
||||
{
|
||||
d->DockWidget->setFloating();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideTab::unpinDockWidget()
|
||||
{
|
||||
d->DockWidget->setAutoHide(false);
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
void CAutoHideTab::onAutoHideToActionClicked()
|
||||
{
|
||||
int Location = sender()->property(LocationProperty).toInt();
|
||||
d->DockWidget->setAutoHide(true, (SideBarLocation)Location);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideTab::mousePressEvent(QMouseEvent* ev)
|
||||
{
|
||||
// If AutoHideShowOnMouseOver is active, then the showing is triggered
|
||||
// by a MousePressEvent sent to this tab. To prevent accidental hiding
|
||||
// of the tab by a mouse click, we wait at least 500 ms before we accept
|
||||
// the mouse click
|
||||
if (!ev->spontaneous())
|
||||
{
|
||||
d->TimeSinceHoverMousePress.restart();
|
||||
d->forwardEventToDockContainer(ev);
|
||||
}
|
||||
else if (d->TimeSinceHoverMousePress.hasExpired(500))
|
||||
{
|
||||
d->forwardEventToDockContainer(ev);
|
||||
}
|
||||
|
||||
if (ev->button() == Qt::LeftButton)
|
||||
{
|
||||
ev->accept();
|
||||
d->MousePressed = true;
|
||||
d->saveDragStartMousePosition(internal::globalPositionOf(ev));
|
||||
d->DragState = DraggingMousePressed;
|
||||
}
|
||||
Super::mousePressEvent(ev);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideTab::mouseReleaseEvent(QMouseEvent* ev)
|
||||
{
|
||||
if (ev->button() == Qt::LeftButton)
|
||||
{
|
||||
d->MousePressed = false;
|
||||
auto CurrentDragState = d->DragState;
|
||||
d->GlobalDragStartMousePosition = QPoint();
|
||||
d->DragStartMousePosition = QPoint();
|
||||
d->DragState = DraggingInactive;
|
||||
|
||||
switch (CurrentDragState)
|
||||
{
|
||||
case DraggingTab:
|
||||
// End of tab moving, emit signal
|
||||
/*if (d->DockArea)
|
||||
{
|
||||
ev->accept();
|
||||
Q_EMIT moved(internal::globalPositionOf(ev));
|
||||
}*/
|
||||
break;
|
||||
|
||||
case DraggingFloatingWidget:
|
||||
ev->accept();
|
||||
d->FloatingWidget->finishDragging();
|
||||
if (d->DockWidget->isAutoHide() && d->DragStartOrientation != orientation())
|
||||
{
|
||||
d->DockWidget->autoHideDockContainer()->resetToInitialDockWidgetSize();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break; // do nothing
|
||||
}
|
||||
}
|
||||
|
||||
Super::mouseReleaseEvent(ev);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideTab::mouseMoveEvent(QMouseEvent* ev)
|
||||
{
|
||||
if (!(ev->buttons() & Qt::LeftButton) || d->isDraggingState(DraggingInactive))
|
||||
{
|
||||
d->DragState = DraggingInactive;
|
||||
Super::mouseMoveEvent(ev);
|
||||
return;
|
||||
}
|
||||
|
||||
// move floating window
|
||||
if (d->isDraggingState(DraggingFloatingWidget))
|
||||
{
|
||||
d->FloatingWidget->moveFloating();
|
||||
Super::mouseMoveEvent(ev);
|
||||
return;
|
||||
}
|
||||
|
||||
// move tab
|
||||
if (d->isDraggingState(DraggingTab))
|
||||
{
|
||||
// Moving the tab is always allowed because it does not mean moving the
|
||||
// dock widget around
|
||||
//d->moveTab(ev);
|
||||
}
|
||||
|
||||
auto MappedPos = mapToParent(ev->pos());
|
||||
bool MouseOutsideBar = (MappedPos.x() < 0) || (MappedPos.x() > parentWidget()->rect().right());
|
||||
// Maybe a fixed drag distance is better here ?
|
||||
int DragDistanceY = qAbs(d->GlobalDragStartMousePosition.y() - internal::globalPositionOf(ev).y());
|
||||
if (DragDistanceY >= CDockManager::startDragDistance() || MouseOutsideBar)
|
||||
{
|
||||
// Floating is only allowed for widgets that are floatable
|
||||
// We can create the drag preview if the widget is movable.
|
||||
auto Features = d->DockWidget->features();
|
||||
if (Features.testFlag(CDockWidget::DockWidgetFloatable) || (Features.testFlag(CDockWidget::DockWidgetMovable)))
|
||||
{
|
||||
d->startFloating();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Super::mouseMoveEvent(ev);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideTab::requestCloseDockWidget()
|
||||
{
|
||||
d->DockWidget->requestCloseDockWidget();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
int CAutoHideTab::tabIndex() const
|
||||
{
|
||||
if (!d->SideBar)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return d->SideBar->indexOfTab(*this);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -65,11 +65,17 @@ private:
|
||||
friend class CDockContainerWidget;
|
||||
friend DockContainerWidgetPrivate;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onAutoHideToActionClicked();
|
||||
|
||||
protected:
|
||||
void setSideBar(CAutoHideSideBar *SideTabBar);
|
||||
void removeFromSideBar();
|
||||
virtual bool event(QEvent* event) override;
|
||||
virtual void contextMenuEvent(QContextMenuEvent* ev) override;
|
||||
virtual void mousePressEvent(QMouseEvent* ev) override;
|
||||
virtual void mouseReleaseEvent(QMouseEvent* ev) override;
|
||||
virtual void mouseMoveEvent(QMouseEvent* ev) override;
|
||||
|
||||
public:
|
||||
using Super = CPushButton;
|
||||
@ -133,6 +139,27 @@ public:
|
||||
* not in a side bar
|
||||
*/
|
||||
CAutoHideSideBar* sideBar() const;
|
||||
|
||||
/**
|
||||
* Returns the index of this tab in the sideBar
|
||||
*/
|
||||
int tabIndex() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
/**
|
||||
* Set the dock widget floating, if it is floatable
|
||||
*/
|
||||
void setDockWidgetFloating();
|
||||
|
||||
/**
|
||||
* Unpin and dock the auto hide widget
|
||||
*/
|
||||
void unpinDockWidget();
|
||||
|
||||
/**
|
||||
* Calls the requestCloseDockWidget() function for the assigned dock widget
|
||||
*/
|
||||
void requestCloseDockWidget();
|
||||
}; // class AutoHideTab
|
||||
}
|
||||
// namespace ads
|
||||
|
@ -504,6 +504,46 @@ QSize CDockAreaTabBar::sizeHint() const
|
||||
return d->TabsContainerWidget->sizeHint();
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
int CDockAreaTabBar::tabAt(const QPoint& Pos) const
|
||||
{
|
||||
if (!isVisible())
|
||||
{
|
||||
return TabInvalidIndex;
|
||||
}
|
||||
|
||||
if (Pos.x() < tab(0)->geometry().x())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count(); ++i)
|
||||
{
|
||||
if (tab(i)->geometry().contains(Pos))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return count();
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
int CDockAreaTabBar::tabInsertIndexAt(const QPoint& Pos) const
|
||||
{
|
||||
int Index = tabAt(Pos);
|
||||
if (Index == TabInvalidIndex)
|
||||
{
|
||||
return TabDefaultInsertIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (Index < 0) ? 0 : Index;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ads
|
||||
|
||||
|
||||
|
@ -113,6 +113,19 @@ public:
|
||||
*/
|
||||
CDockWidgetTab* tab(int Index) const;
|
||||
|
||||
/**
|
||||
* Returns the tab at the given position.
|
||||
* Returns -1 if the position is left of the first tab and count() if the
|
||||
* position is right of the last tab. Returns -2 to indicate an invalid
|
||||
* value.
|
||||
*/
|
||||
int tabAt(const QPoint& Pos) const;
|
||||
|
||||
/**
|
||||
* Returns the tab insertion index for the given mouse cursor position
|
||||
*/
|
||||
int tabInsertIndexAt(const QPoint& Pos) const;
|
||||
|
||||
/**
|
||||
* Filters the tab widget events
|
||||
*/
|
||||
|
@ -68,10 +68,10 @@ static const char* const LocationProperty = "Location";
|
||||
struct DockAreaTitleBarPrivate
|
||||
{
|
||||
CDockAreaTitleBar* _this;
|
||||
QPointer<tTitleBarButton> TabsMenuButton;
|
||||
QPointer<tTitleBarButton> AutoHideButton;
|
||||
QPointer<tTitleBarButton> UndockButton;
|
||||
QPointer<tTitleBarButton> CloseButton;
|
||||
QPointer<CTitleBarButton> TabsMenuButton;
|
||||
QPointer<CTitleBarButton> AutoHideButton;
|
||||
QPointer<CTitleBarButton> UndockButton;
|
||||
QPointer<CTitleBarButton> CloseButton;
|
||||
QBoxLayout* Layout;
|
||||
CDockAreaWidget* DockArea;
|
||||
CDockAreaTabBar* TabBar;
|
||||
@ -539,7 +539,7 @@ void CDockAreaTitleBar::onAutoHideToActionClicked()
|
||||
|
||||
|
||||
//============================================================================
|
||||
QAbstractButton* CDockAreaTitleBar::button(TitleBarButton which) const
|
||||
CTitleBarButton* CDockAreaTitleBar::button(TitleBarButton which) const
|
||||
{
|
||||
switch (which)
|
||||
{
|
||||
@ -677,6 +677,28 @@ void CDockAreaTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaTitleBar::setAreaFloating()
|
||||
{
|
||||
// If this is the last dock area in a dock container it does not make
|
||||
// sense to move it to a new floating widget and leave this one
|
||||
// empty.
|
||||
auto DockContainer = d->DockArea->dockContainer();
|
||||
if (DockContainer->isFloating() && DockContainer->dockAreaCount() == 1
|
||||
&& !d->DockArea->isAutoHide())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
d->makeAreaFloating(mapFromGlobal(QCursor::pos()), DraggingInactive);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaTitleBar::contextMenuEvent(QContextMenuEvent* ev)
|
||||
{
|
||||
@ -781,9 +803,9 @@ QString CDockAreaTitleBar::titleBarButtonToolTip(TitleBarButton Button) const
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
CTitleBarButton::CTitleBarButton(bool visible, QWidget* parent)
|
||||
CTitleBarButton::CTitleBarButton(bool showInTitleBar, QWidget* parent)
|
||||
: tTitleBarButton(parent),
|
||||
Visible(visible),
|
||||
ShowInTitleBar(showInTitleBar),
|
||||
HideWhenDisabled(CDockManager::testConfigFlag(CDockManager::DockAreaHideDisabledButtons))
|
||||
{
|
||||
setFocusPolicy(Qt::NoFocus);
|
||||
@ -793,7 +815,7 @@ CTitleBarButton::CTitleBarButton(bool visible, QWidget* parent)
|
||||
void CTitleBarButton::setVisible(bool visible)
|
||||
{
|
||||
// 'visible' can stay 'true' if and only if this button is configured to generaly visible:
|
||||
visible = visible && this->Visible;
|
||||
visible = visible && this->ShowInTitleBar;
|
||||
|
||||
// 'visible' can stay 'true' unless: this button is configured to be invisible when it is disabled and it is currently disabled:
|
||||
if (visible && HideWhenDisabled)
|
||||
@ -804,6 +826,18 @@ void CTitleBarButton::setVisible(bool visible)
|
||||
Super::setVisible(visible);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CTitleBarButton::setShowInTitleBar(bool Show)
|
||||
{
|
||||
this->ShowInTitleBar = Show;
|
||||
if (!Show)
|
||||
{
|
||||
setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool CTitleBarButton::event(QEvent *ev)
|
||||
{
|
||||
|
@ -30,6 +30,7 @@
|
||||
//============================================================================
|
||||
// INCLUDES
|
||||
//============================================================================
|
||||
#include <QToolButton>
|
||||
#include <QFrame>
|
||||
|
||||
#include "ads_globals.h"
|
||||
@ -43,6 +44,44 @@ class CDockAreaWidget;
|
||||
struct DockAreaTitleBarPrivate;
|
||||
class CElidingLabel;
|
||||
|
||||
using tTitleBarButton = QToolButton;
|
||||
|
||||
/**
|
||||
* Title bar button of a dock area that customizes tTitleBarButton appearance/behaviour
|
||||
* according to various config flags such as:
|
||||
* CDockManager::DockAreaHas_xxx_Button - if set to 'false' keeps the button always invisible
|
||||
* CDockManager::DockAreaHideDisabledButtons - if set to 'true' hides button when it is disabled
|
||||
*/
|
||||
class CTitleBarButton : public tTitleBarButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
bool ShowInTitleBar = true;
|
||||
bool HideWhenDisabled = false;
|
||||
|
||||
public:
|
||||
using Super = tTitleBarButton;
|
||||
CTitleBarButton(bool ShowInTitleBar = true, QWidget* parent = nullptr);
|
||||
|
||||
/**
|
||||
* Adjust this visibility change request with our internal settings:
|
||||
*/
|
||||
virtual void setVisible(bool visible) override;
|
||||
|
||||
/**
|
||||
* Configures, if the title bar button should be shown in title bar
|
||||
*/
|
||||
void setShowInTitleBar(bool Show);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Handle EnabledChanged signal to set button invisible if the configured
|
||||
*/
|
||||
bool event(QEvent *ev) override;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Title bar of a dock area.
|
||||
* The title bar contains a tabbar with all tabs for a dock widget group and
|
||||
@ -121,7 +160,7 @@ public:
|
||||
/**
|
||||
* Returns the button corresponding to the given title bar button identifier
|
||||
*/
|
||||
QAbstractButton* button(TitleBarButton which) const;
|
||||
CTitleBarButton* button(TitleBarButton which) const;
|
||||
|
||||
/**
|
||||
* Returns the auto hide title label, used when the dock area is expanded and auto hidden
|
||||
@ -163,6 +202,12 @@ public:
|
||||
*/
|
||||
QString titleBarButtonToolTip(TitleBarButton Button) const;
|
||||
|
||||
/**
|
||||
* Moves the dock area into its own floating widget if the area
|
||||
* DockWidgetFloatable flag is true
|
||||
*/
|
||||
void setAreaFloating();
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* This signal is emitted if a tab in the tab bar is clicked by the user
|
||||
|
@ -31,43 +31,12 @@
|
||||
// INCLUDES
|
||||
//============================================================================
|
||||
#include <QFrame>
|
||||
#include <QToolButton>
|
||||
|
||||
#include "ads_globals.h"
|
||||
|
||||
namespace ads
|
||||
{
|
||||
using tTitleBarButton = QToolButton;
|
||||
|
||||
/**
|
||||
* Title bar button of a dock area that customizes tTitleBarButton appearance/behaviour
|
||||
* according to various config flags such as:
|
||||
* CDockManager::DockAreaHas_xxx_Button - if set to 'false' keeps the button always invisible
|
||||
* CDockManager::DockAreaHideDisabledButtons - if set to 'true' hides button when it is disabled
|
||||
*/
|
||||
class CTitleBarButton : public tTitleBarButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
bool Visible = true;
|
||||
bool HideWhenDisabled = false;
|
||||
|
||||
public:
|
||||
using Super = tTitleBarButton;
|
||||
CTitleBarButton(bool visible = true, QWidget* parent = nullptr);
|
||||
|
||||
/**
|
||||
* Adjust this visibility change request with our internal settings:
|
||||
*/
|
||||
virtual void setVisible(bool visible) override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Handle EnabledChanged signal to set button invisible if the configured
|
||||
*/
|
||||
bool event(QEvent *ev) override;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
|
@ -467,6 +467,7 @@ void CDockAreaWidget::setAutoHideDockContainer(CAutoHideDockContainer* AutoHideD
|
||||
d->AutoHideDockContainer = AutoHideDockContainer;
|
||||
updateAutoHideButtonCheckState();
|
||||
updateTitleBarButtonsToolTips();
|
||||
d->TitleBar->button(TitleBarButtonAutoHide)->setShowInTitleBar(true);
|
||||
}
|
||||
|
||||
|
||||
@ -626,15 +627,7 @@ void CDockAreaWidget::hideAreaWithNoVisibleContent()
|
||||
void CDockAreaWidget::onTabCloseRequested(int Index)
|
||||
{
|
||||
ADS_PRINT("CDockAreaWidget::onTabCloseRequested " << Index);
|
||||
auto* DockWidget = dockWidget(Index);
|
||||
if (DockWidget->features().testFlag(CDockWidget::DockWidgetDeleteOnClose) || DockWidget->features().testFlag(CDockWidget::CustomCloseHandling))
|
||||
{
|
||||
DockWidget->closeDockWidgetInternal();
|
||||
}
|
||||
else
|
||||
{
|
||||
DockWidget->toggleView(false);
|
||||
}
|
||||
dockWidget(Index)->requestCloseDockWidget();
|
||||
}
|
||||
|
||||
|
||||
@ -1312,7 +1305,7 @@ SideBarLocation CDockAreaWidget::calculateSideTabBarArea() const
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaWidget::setAutoHide(bool Enable, SideBarLocation Location)
|
||||
void CDockAreaWidget::setAutoHide(bool Enable, SideBarLocation Location, int TabIndex)
|
||||
{
|
||||
if (!isAutoHideFeatureEnabled())
|
||||
{
|
||||
@ -1323,11 +1316,18 @@ void CDockAreaWidget::setAutoHide(bool Enable, SideBarLocation Location)
|
||||
{
|
||||
if (isAutoHide())
|
||||
{
|
||||
autoHideDockContainer()->moveContentsToParent();
|
||||
d->AutoHideDockContainer->moveContentsToParent();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If this is already an auto hide container, then move it to new location
|
||||
if (isAutoHide())
|
||||
{
|
||||
d->AutoHideDockContainer->moveToNewSideBarLocation(Location, TabIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
auto area = (SideBarNone == Location) ? calculateSideTabBarArea() : Location;
|
||||
for (const auto DockWidget : openedDockWidgets())
|
||||
{
|
||||
@ -1341,7 +1341,7 @@ void CDockAreaWidget::setAutoHide(bool Enable, SideBarLocation Location)
|
||||
continue;
|
||||
}
|
||||
|
||||
dockContainer()->createAndSetupAutoHideContainer(area, DockWidget);
|
||||
dockContainer()->createAndSetupAutoHideContainer(area, DockWidget, TabIndex++);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1442,6 +1442,13 @@ bool CDockAreaWidget::isTopLevelArea() const
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaWidget::setFloating()
|
||||
{
|
||||
d->TitleBar->setAreaFloating();
|
||||
}
|
||||
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
//============================================================================
|
||||
bool CDockAreaWidget::event(QEvent *e)
|
||||
|
@ -221,7 +221,6 @@ public:
|
||||
*/
|
||||
bool isAutoHide() const;
|
||||
|
||||
|
||||
/**
|
||||
* Sets the current auto hide dock container
|
||||
*/
|
||||
@ -401,7 +400,7 @@ public Q_SLOTS:
|
||||
* If the dock area is switched to auto hide mode, then all dock widgets
|
||||
* that are pinable will be added to the sidebar
|
||||
*/
|
||||
void setAutoHide(bool Enable, SideBarLocation Location = SideBarNone);
|
||||
void setAutoHide(bool Enable, SideBarLocation Location = SideBarNone, int TabIndex = -1);
|
||||
|
||||
/**
|
||||
* Switches the dock area to auto hide mode or vice versa depending on its
|
||||
@ -414,6 +413,12 @@ public Q_SLOTS:
|
||||
*/
|
||||
void closeOtherAreas();
|
||||
|
||||
/**
|
||||
* Moves the dock area into its own floating widget if the area
|
||||
* DockWidgetFloatable flag is true
|
||||
*/
|
||||
void setFloating();
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* This signal is emitted when user clicks on a tab at an index.
|
||||
|
@ -145,7 +145,7 @@ public:
|
||||
QList<CAutoHideDockContainer*> AutoHideWidgets;
|
||||
QMap<SideBarLocation, CAutoHideSideBar*> SideTabBarWidgets;
|
||||
QGridLayout* Layout = nullptr;
|
||||
QSplitter* RootSplitter = nullptr;
|
||||
CDockSplitter* RootSplitter = nullptr;
|
||||
bool isFloating = false;
|
||||
CDockAreaWidget* LastAddedAreaCache[5];
|
||||
int VisibleDockAreaCount = -1;
|
||||
@ -181,17 +181,29 @@ public:
|
||||
*/
|
||||
void dropIntoContainer(CFloatingDockContainer* FloatingWidget, DockWidgetArea area);
|
||||
|
||||
/**
|
||||
* Drop floating widget into auto hide side bar
|
||||
*/
|
||||
void dropIntoAutoHideSideBar(CFloatingDockContainer* FloatingWidget, DockWidgetArea area);
|
||||
|
||||
/**
|
||||
* Creates a new tab for a widget dropped into the center of a section
|
||||
*/
|
||||
void dropIntoCenterOfSection(CFloatingDockContainer* FloatingWidget,
|
||||
CDockAreaWidget* TargetArea, int TabIndex = 0);
|
||||
|
||||
/**
|
||||
* Drop floating widget into dock area
|
||||
*/
|
||||
void dropIntoSection(CFloatingDockContainer* FloatingWidget,
|
||||
CDockAreaWidget* TargetArea, DockWidgetArea area);
|
||||
CDockAreaWidget* TargetArea, DockWidgetArea area, int TabIndex = 0);
|
||||
|
||||
/**
|
||||
* Moves the dock widget or dock area given in Widget parameter to a
|
||||
* new dock widget area
|
||||
*/
|
||||
void moveToNewSection(QWidget* Widget, CDockAreaWidget* TargetArea, DockWidgetArea area);
|
||||
void moveToNewSection(QWidget* Widget, CDockAreaWidget* TargetArea, DockWidgetArea area,
|
||||
int TabIndex = 0);
|
||||
|
||||
/**
|
||||
* Moves the dock widget or dock area given in Widget parameter to a
|
||||
@ -202,13 +214,13 @@ public:
|
||||
/**
|
||||
* Creates a new tab for a widget dropped into the center of a section
|
||||
*/
|
||||
void dropIntoCenterOfSection(CFloatingDockContainer* FloatingWidget,
|
||||
CDockAreaWidget* TargetArea);
|
||||
void moveIntoCenterOfSection(QWidget* Widget, CDockAreaWidget* TargetArea, int TabIndex = 0);
|
||||
|
||||
/**
|
||||
* Creates a new tab for a widget dropped into the center of a section
|
||||
* Moves the dock widget or dock area given in Widget parameter to
|
||||
* a auto hide sidebar area
|
||||
*/
|
||||
void moveIntoCenterOfSection(QWidget* Widget, CDockAreaWidget* TargetArea);
|
||||
void moveToAutoHideSideBar(QWidget* Widget, DockWidgetArea area, int TabIndex = TabDefaultInsertIndex);
|
||||
|
||||
|
||||
/**
|
||||
@ -454,7 +466,7 @@ void DockContainerWidgetPrivate::dropIntoContainer(CFloatingDockContainer* Float
|
||||
CDockContainerWidget* FloatingDockContainer = FloatingWidget->dockContainer();
|
||||
auto NewDockAreas = FloatingDockContainer->findChildren<CDockAreaWidget*>(
|
||||
QString(), Qt::FindChildrenRecursively);
|
||||
QSplitter* Splitter = RootSplitter;
|
||||
auto Splitter = RootSplitter;
|
||||
|
||||
if (DockAreas.count() <= 1)
|
||||
{
|
||||
@ -462,7 +474,7 @@ void DockContainerWidgetPrivate::dropIntoContainer(CFloatingDockContainer* Float
|
||||
}
|
||||
else if (Splitter->orientation() != InsertParam.orientation())
|
||||
{
|
||||
QSplitter* NewSplitter = newSplitter(InsertParam.orientation());
|
||||
auto NewSplitter = newSplitter(InsertParam.orientation());
|
||||
QLayoutItem* li = Layout->replaceWidget(Splitter, NewSplitter);
|
||||
NewSplitter->addWidget(Splitter);
|
||||
updateSplitterHandles(NewSplitter);
|
||||
@ -505,14 +517,33 @@ void DockContainerWidgetPrivate::dropIntoContainer(CFloatingDockContainer* Float
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void DockContainerWidgetPrivate::dropIntoAutoHideSideBar(CFloatingDockContainer* FloatingWidget, DockWidgetArea area)
|
||||
{
|
||||
auto SideBarLocation = internal::toSideBarLocation(area);
|
||||
auto NewDockAreas = FloatingWidget->findChildren<CDockAreaWidget*>(
|
||||
QString(), Qt::FindChildrenRecursively);
|
||||
int TabIndex = DockManager->containerOverlay()->tabIndexUnderCursor();
|
||||
for (auto DockArea : NewDockAreas)
|
||||
{
|
||||
auto DockWidgets = DockArea->dockWidgets();
|
||||
for (auto DockWidget : DockWidgets)
|
||||
{
|
||||
_this->createAndSetupAutoHideContainer(SideBarLocation, DockWidget, TabIndex++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void DockContainerWidgetPrivate::dropIntoCenterOfSection(
|
||||
CFloatingDockContainer* FloatingWidget, CDockAreaWidget* TargetArea)
|
||||
CFloatingDockContainer* FloatingWidget, CDockAreaWidget* TargetArea, int TabIndex)
|
||||
{
|
||||
CDockContainerWidget* FloatingContainer = FloatingWidget->dockContainer();
|
||||
auto NewDockWidgets = FloatingContainer->dockWidgets();
|
||||
auto TopLevelDockArea = FloatingContainer->topLevelDockArea();
|
||||
int NewCurrentIndex = -1;
|
||||
TabIndex = qMax(0, TabIndex);
|
||||
|
||||
// If the floating widget contains only one single dock are, then the
|
||||
// current dock widget of the dock area will also be the future current
|
||||
@ -525,7 +556,7 @@ void DockContainerWidgetPrivate::dropIntoCenterOfSection(
|
||||
for (int i = 0; i < NewDockWidgets.count(); ++i)
|
||||
{
|
||||
CDockWidget* DockWidget = NewDockWidgets[i];
|
||||
TargetArea->insertDockWidget(i, DockWidget, false);
|
||||
TargetArea->insertDockWidget(TabIndex + i, DockWidget, false);
|
||||
// If the floating widget contains multiple visible dock areas, then we
|
||||
// simply pick the first visible open dock widget and make it
|
||||
// the current one.
|
||||
@ -534,7 +565,7 @@ void DockContainerWidgetPrivate::dropIntoCenterOfSection(
|
||||
NewCurrentIndex = i;
|
||||
}
|
||||
}
|
||||
TargetArea->setCurrentIndex(NewCurrentIndex);
|
||||
TargetArea->setCurrentIndex(NewCurrentIndex + TabIndex);
|
||||
TargetArea->updateTitleBarVisibility();
|
||||
return;
|
||||
}
|
||||
@ -542,13 +573,13 @@ void DockContainerWidgetPrivate::dropIntoCenterOfSection(
|
||||
|
||||
//============================================================================
|
||||
void DockContainerWidgetPrivate::dropIntoSection(CFloatingDockContainer* FloatingWidget,
|
||||
CDockAreaWidget* TargetArea, DockWidgetArea area)
|
||||
CDockAreaWidget* TargetArea, DockWidgetArea area, int TabIndex)
|
||||
{
|
||||
// Dropping into center means all dock widgets in the dropped floating
|
||||
// widget will become tabs of the drop area
|
||||
if (CenterDockWidgetArea == area)
|
||||
{
|
||||
dropIntoCenterOfSection(FloatingWidget, TargetArea);
|
||||
dropIntoCenterOfSection(FloatingWidget, TargetArea, TabIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -638,11 +669,13 @@ void DockContainerWidgetPrivate::dropIntoSection(CFloatingDockContainer* Floatin
|
||||
|
||||
|
||||
//============================================================================
|
||||
void DockContainerWidgetPrivate::moveIntoCenterOfSection(QWidget* Widget, CDockAreaWidget* TargetArea)
|
||||
void DockContainerWidgetPrivate::moveIntoCenterOfSection(QWidget* Widget, CDockAreaWidget* TargetArea,
|
||||
int TabIndex)
|
||||
{
|
||||
auto DroppedDockWidget = qobject_cast<CDockWidget*>(Widget);
|
||||
auto DroppedArea = qobject_cast<CDockAreaWidget*>(Widget);
|
||||
|
||||
TabIndex = qMax(0, TabIndex);
|
||||
if (DroppedDockWidget)
|
||||
{
|
||||
CDockAreaWidget* OldDockArea = DroppedDockWidget->dockAreaWidget();
|
||||
@ -655,7 +688,7 @@ void DockContainerWidgetPrivate::moveIntoCenterOfSection(QWidget* Widget, CDockA
|
||||
{
|
||||
OldDockArea->removeDockWidget(DroppedDockWidget);
|
||||
}
|
||||
TargetArea->insertDockWidget(0, DroppedDockWidget, true);
|
||||
TargetArea->insertDockWidget(TabIndex, DroppedDockWidget, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -664,9 +697,9 @@ void DockContainerWidgetPrivate::moveIntoCenterOfSection(QWidget* Widget, CDockA
|
||||
for (int i = 0; i < NewDockWidgets.count(); ++i)
|
||||
{
|
||||
CDockWidget* DockWidget = NewDockWidgets[i];
|
||||
TargetArea->insertDockWidget(i, DockWidget, false);
|
||||
TargetArea->insertDockWidget(TabIndex + i, DockWidget, false);
|
||||
}
|
||||
TargetArea->setCurrentIndex(NewCurrentIndex);
|
||||
TargetArea->setCurrentIndex(TabIndex + NewCurrentIndex);
|
||||
DroppedArea->dockContainer()->removeDockArea(DroppedArea);
|
||||
DroppedArea->deleteLater();
|
||||
}
|
||||
@ -677,13 +710,14 @@ void DockContainerWidgetPrivate::moveIntoCenterOfSection(QWidget* Widget, CDockA
|
||||
|
||||
|
||||
//============================================================================
|
||||
void DockContainerWidgetPrivate::moveToNewSection(QWidget* Widget, CDockAreaWidget* TargetArea, DockWidgetArea area)
|
||||
void DockContainerWidgetPrivate::moveToNewSection(QWidget* Widget, CDockAreaWidget* TargetArea, DockWidgetArea area,
|
||||
int TabIndex)
|
||||
{
|
||||
// Dropping into center means all dock widgets in the dropped floating
|
||||
// widget will become tabs of the drop area
|
||||
if (CenterDockWidgetArea == area)
|
||||
{
|
||||
moveIntoCenterOfSection(Widget, TargetArea);
|
||||
moveIntoCenterOfSection(Widget, TargetArea, TabIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -738,6 +772,48 @@ void DockContainerWidgetPrivate::moveToNewSection(QWidget* Widget, CDockAreaWidg
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void DockContainerWidgetPrivate::moveToAutoHideSideBar(QWidget* Widget, DockWidgetArea area, int TabIndex)
|
||||
{
|
||||
CDockWidget* DroppedDockWidget = qobject_cast<CDockWidget*>(Widget);
|
||||
CDockAreaWidget* DroppedDockArea = qobject_cast<CDockAreaWidget*>(Widget);
|
||||
auto SideBarLocation = internal::toSideBarLocation(area);
|
||||
|
||||
if (DroppedDockWidget)
|
||||
{
|
||||
if (_this == DroppedDockWidget->dockContainer())
|
||||
{
|
||||
DroppedDockWidget->setAutoHide(true, SideBarLocation, TabIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
_this->createAndSetupAutoHideContainer(SideBarLocation, DroppedDockWidget, TabIndex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_this == DroppedDockArea->dockContainer())
|
||||
{
|
||||
DroppedDockArea->setAutoHide(true, SideBarLocation, TabIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const auto DockWidget : DroppedDockArea->openedDockWidgets())
|
||||
{
|
||||
if (!DockWidget->features().testFlag(
|
||||
CDockWidget::DockWidgetPinnable))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
_this->createAndSetupAutoHideContainer(SideBarLocation,
|
||||
DockWidget, TabIndex++);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void DockContainerWidgetPrivate::updateSplitterHandles( QSplitter* splitter )
|
||||
{
|
||||
@ -908,7 +984,7 @@ void DockContainerWidgetPrivate::saveAutoHideWidgetsState(QXmlStreamWriter& s)
|
||||
{
|
||||
for (const auto sideTabBar : SideTabBarWidgets.values())
|
||||
{
|
||||
if (!sideTabBar->tabCount())
|
||||
if (!sideTabBar->count())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -1101,12 +1177,12 @@ bool DockContainerWidgetPrivate::restoreSideBar(CDockingStateReader& s,
|
||||
continue;
|
||||
}
|
||||
|
||||
auto SideBar = _this->sideTabBar(Area);
|
||||
auto SideBar = _this->autoHideSideBar(Area);
|
||||
CAutoHideDockContainer* AutoHideContainer;
|
||||
if (DockWidget->isAutoHide())
|
||||
{
|
||||
AutoHideContainer = DockWidget->autoHideDockContainer();
|
||||
if (AutoHideContainer->sideBar() != SideBar)
|
||||
if (AutoHideContainer->autoHideSideBar() != SideBar)
|
||||
{
|
||||
SideBar->addAutoHideWidget(AutoHideContainer);
|
||||
}
|
||||
@ -1193,7 +1269,7 @@ void DockContainerWidgetPrivate::addDockArea(CDockAreaWidget* NewDockArea, DockW
|
||||
}
|
||||
else
|
||||
{
|
||||
QSplitter* NewSplitter = newSplitter(InsertParam.orientation());
|
||||
auto NewSplitter = newSplitter(InsertParam.orientation());
|
||||
if (InsertParam.append())
|
||||
{
|
||||
QLayoutItem* li = Layout->replaceWidget(Splitter, NewSplitter);
|
||||
@ -1404,7 +1480,7 @@ CDockAreaWidget* CDockContainerWidget::addDockWidget(DockWidgetArea area, CDockW
|
||||
|
||||
//============================================================================
|
||||
CAutoHideDockContainer* CDockContainerWidget::createAndSetupAutoHideContainer(
|
||||
SideBarLocation area, CDockWidget* DockWidget)
|
||||
SideBarLocation area, CDockWidget* DockWidget, int TabIndex)
|
||||
{
|
||||
if (!CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideFeatureEnabled))
|
||||
{
|
||||
@ -1417,7 +1493,7 @@ CAutoHideDockContainer* CDockContainerWidget::createAndSetupAutoHideContainer(
|
||||
DockWidget->setDockManager(d->DockManager); // Auto hide Dock Container needs a valid dock manager
|
||||
}
|
||||
|
||||
return sideTabBar(area)->insertDockWidget(-1, DockWidget);
|
||||
return autoHideSideBar(area)->insertDockWidget(TabIndex, DockWidget);
|
||||
}
|
||||
|
||||
|
||||
@ -1528,7 +1604,7 @@ void CDockContainerWidget::removeDockArea(CDockAreaWidget* area)
|
||||
}
|
||||
|
||||
QWidget* widget = Splitter->widget(0);
|
||||
QSplitter* ChildSplitter = qobject_cast<QSplitter*>(widget);
|
||||
auto ChildSplitter = qobject_cast<CDockSplitter*>(widget);
|
||||
// If the one and only content widget of the splitter is not a splitter
|
||||
// then we are finished
|
||||
if (!ChildSplitter)
|
||||
@ -1629,11 +1705,12 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
|
||||
ADS_PRINT("CDockContainerWidget::dropFloatingWidget");
|
||||
CDockWidget* SingleDroppedDockWidget = FloatingWidget->topLevelDockWidget();
|
||||
CDockWidget* SingleDockWidget = topLevelDockWidget();
|
||||
CDockAreaWidget* DockArea = dockAreaAt(TargetPos);
|
||||
auto dropArea = InvalidDockWidgetArea;
|
||||
auto ContainerDropArea = d->DockManager->containerOverlay()->dropAreaUnderCursor();
|
||||
bool Dropped = false;
|
||||
|
||||
CDockAreaWidget* DockArea = dockAreaAt(TargetPos);
|
||||
// mouse is over dock area
|
||||
if (DockArea)
|
||||
{
|
||||
auto dropOverlay = d->DockManager->dockAreaOverlay();
|
||||
@ -1648,28 +1725,33 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
|
||||
if (dropArea != InvalidDockWidgetArea)
|
||||
{
|
||||
ADS_PRINT("Dock Area Drop Content: " << dropArea);
|
||||
d->dropIntoSection(FloatingWidget, DockArea, dropArea);
|
||||
int TabIndex = d->DockManager->dockAreaOverlay()->tabIndexUnderCursor();
|
||||
d->dropIntoSection(FloatingWidget, DockArea, dropArea, TabIndex);
|
||||
Dropped = true;
|
||||
}
|
||||
}
|
||||
|
||||
// mouse is over container
|
||||
if (InvalidDockWidgetArea == dropArea)
|
||||
// mouse is over container or auto hide side bar
|
||||
if (InvalidDockWidgetArea == dropArea && InvalidDockWidgetArea != ContainerDropArea)
|
||||
{
|
||||
dropArea = ContainerDropArea;
|
||||
ADS_PRINT("Container Drop Content: " << dropArea);
|
||||
if (dropArea != InvalidDockWidgetArea)
|
||||
{
|
||||
d->dropIntoContainer(FloatingWidget, dropArea);
|
||||
Dropped = true;
|
||||
}
|
||||
if (internal::isSideBarArea(ContainerDropArea))
|
||||
{
|
||||
ADS_PRINT("Container Drop Content: " << ContainerDropArea);
|
||||
d->dropIntoAutoHideSideBar(FloatingWidget, ContainerDropArea);
|
||||
}
|
||||
else
|
||||
{
|
||||
ADS_PRINT("Container Drop Content: " << ContainerDropArea);
|
||||
d->dropIntoContainer(FloatingWidget, ContainerDropArea);
|
||||
}
|
||||
Dropped = true;
|
||||
}
|
||||
|
||||
// Remove the auto hide widgets from the FloatingWidget and insert
|
||||
// them into this widget
|
||||
for (auto AutohideWidget : FloatingWidget->dockContainer()->autoHideWidgets())
|
||||
{
|
||||
auto SideBar = sideTabBar(AutohideWidget->sideBarLocation());
|
||||
auto SideBar = autoHideSideBar(AutohideWidget->sideBarLocation());
|
||||
SideBar->addAutoHideWidget(AutohideWidget);
|
||||
}
|
||||
|
||||
@ -1697,12 +1779,17 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockContainerWidget::dropWidget(QWidget* Widget, DockWidgetArea DropArea, CDockAreaWidget* TargetAreaWidget)
|
||||
void CDockContainerWidget::dropWidget(QWidget* Widget, DockWidgetArea DropArea, CDockAreaWidget* TargetAreaWidget,
|
||||
int TabIndex)
|
||||
{
|
||||
CDockWidget* SingleDockWidget = topLevelDockWidget();
|
||||
if (TargetAreaWidget)
|
||||
{
|
||||
d->moveToNewSection(Widget, TargetAreaWidget, DropArea);
|
||||
d->moveToNewSection(Widget, TargetAreaWidget, DropArea, TabIndex);
|
||||
}
|
||||
else if (internal::isSideBarArea(DropArea))
|
||||
{
|
||||
d->moveToAutoHideSideBar(Widget, DropArea, TabIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1846,8 +1933,8 @@ bool CDockContainerWidget::restoreState(CDockingStateReader& s, bool Testing)
|
||||
}
|
||||
|
||||
d->Layout->replaceWidget(d->RootSplitter, NewRootSplitter);
|
||||
QSplitter* OldRoot = d->RootSplitter;
|
||||
d->RootSplitter = qobject_cast<QSplitter*>(NewRootSplitter);
|
||||
auto OldRoot = d->RootSplitter;
|
||||
d->RootSplitter = qobject_cast<CDockSplitter*>(NewRootSplitter);
|
||||
OldRoot->deleteLater();
|
||||
|
||||
return true;
|
||||
@ -2051,7 +2138,7 @@ void CDockContainerWidget::closeOtherAreas(CDockAreaWidget* KeepOpenArea)
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
CAutoHideSideBar* CDockContainerWidget::sideTabBar(SideBarLocation area) const
|
||||
CAutoHideSideBar* CDockContainerWidget::autoHideSideBar(SideBarLocation area) const
|
||||
{
|
||||
return d->SideTabBarWidgets[area];
|
||||
}
|
||||
@ -2065,7 +2152,21 @@ QRect CDockContainerWidget::contentRect() const
|
||||
return QRect();
|
||||
}
|
||||
|
||||
return d->RootSplitter->geometry();
|
||||
if (d->RootSplitter->hasVisibleContent())
|
||||
{
|
||||
return d->RootSplitter->geometry();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto ContentRect = this->rect();
|
||||
ContentRect.adjust(
|
||||
autoHideSideBar(SideBarLeft)->sizeHint().width(),
|
||||
autoHideSideBar(SideBarTop)->sizeHint().height(),
|
||||
-autoHideSideBar(SideBarRight)->sizeHint().width(),
|
||||
-autoHideSideBar(SideBarBottom)->sizeHint().height());
|
||||
|
||||
return ContentRect;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -101,7 +101,14 @@ protected:
|
||||
* Initializing inserts the tabs into the side tab widget and hides it
|
||||
* Returns nullptr if you try and insert into an area where the configuration is not enabled
|
||||
*/
|
||||
CAutoHideDockContainer* createAndSetupAutoHideContainer(SideBarLocation area, CDockWidget* DockWidget);
|
||||
CAutoHideDockContainer* createAndSetupAutoHideContainer(SideBarLocation area, CDockWidget* DockWidget, int TabIndex = -1);
|
||||
|
||||
/**
|
||||
* The funtion does the same like createAndSetupAutoHideContainer() but checks
|
||||
* if the given DockWidget is pinnable. If it is not pinnable, the
|
||||
* function returns a nullptr.
|
||||
*/
|
||||
CAutoHideDockContainer* createAutoHideContainerIfPinnable(SideBarLocation area, CDockWidget* DockWidget);
|
||||
|
||||
/**
|
||||
* Helper function for creation of the root splitter
|
||||
@ -125,7 +132,8 @@ protected:
|
||||
* a nullptr, then the DropArea indicates the drop area in the given
|
||||
* TargetAreaWidget
|
||||
*/
|
||||
void dropWidget(QWidget* Widget, DockWidgetArea DropArea, CDockAreaWidget* TargetAreaWidget);
|
||||
void dropWidget(QWidget* Widget, DockWidgetArea DropArea, CDockAreaWidget* TargetAreaWidget,
|
||||
int TabIndex = -1);
|
||||
|
||||
/**
|
||||
* Adds the given dock area to this container widget
|
||||
@ -322,7 +330,7 @@ public:
|
||||
/**
|
||||
* Returns the side tab widget for the given area
|
||||
*/
|
||||
CAutoHideSideBar* sideTabBar(SideBarLocation area) const;
|
||||
CAutoHideSideBar* autoHideSideBar(SideBarLocation area) const;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -55,6 +55,8 @@ class CIconProvider;
|
||||
class CDockComponentsFactory;
|
||||
class CDockFocusController;
|
||||
class CAutoHideSideBar;
|
||||
class CAutoHideTab;
|
||||
struct AutoHideTabPrivate;
|
||||
|
||||
/**
|
||||
* The central dock manager that maintains the complete docking system.
|
||||
@ -87,6 +89,8 @@ private:
|
||||
friend class CDockAreaTitleBar;
|
||||
friend class CAutoHideDockContainer;
|
||||
friend CAutoHideSideBar;
|
||||
friend CAutoHideTab;
|
||||
friend AutoHideTabPrivate;
|
||||
|
||||
public Q_SLOTS:
|
||||
/**
|
||||
@ -248,7 +252,9 @@ public:
|
||||
AutoHideCloseButtonCollapsesDock = 0x40, ///< Close button of an auto hide container collapses the dock instead of hiding it completely
|
||||
|
||||
DefaultAutoHideConfig = AutoHideFeatureEnabled
|
||||
| DockAreaHasAutoHideButton ///< the default configuration for left and right side bars
|
||||
| DockAreaHasAutoHideButton
|
||||
| AutoHideCloseButtonCollapsesDock
|
||||
|
||||
};
|
||||
Q_DECLARE_FLAGS(AutoHideFlags, eAutoHideFlag)
|
||||
|
||||
|
@ -38,11 +38,18 @@
|
||||
|
||||
#include "DockAreaWidget.h"
|
||||
#include "DockAreaTitleBar.h"
|
||||
#include "DockContainerWidget.h"
|
||||
#include "AutoHideSideBar.h"
|
||||
#include "DockManager.h"
|
||||
#include "DockAreaTabBar.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace ads
|
||||
{
|
||||
static const int AutoHideAreaWidth = 32;
|
||||
static const int AutoHideAreaMouseZone = 8;
|
||||
static const int InvalidTabIndex = -2;
|
||||
|
||||
/**
|
||||
* Private data class of CDockOverlay
|
||||
@ -57,11 +64,23 @@ struct DockOverlayPrivate
|
||||
bool DropPreviewEnabled = true;
|
||||
CDockOverlay::eMode Mode = CDockOverlay::ModeDockAreaOverlay;
|
||||
QRect DropAreaRect;
|
||||
int TabIndex = InvalidTabIndex;
|
||||
|
||||
/**
|
||||
* Private data constructor
|
||||
*/
|
||||
DockOverlayPrivate(CDockOverlay* _public) : _this(_public) {}
|
||||
|
||||
/**
|
||||
* Returns the overlay width / height depending on the visibility
|
||||
* of the sidebar
|
||||
*/
|
||||
int sideBarOverlaySize(SideBarLocation sideBarLocation);
|
||||
|
||||
/**
|
||||
* The area where the mouse is considered in the sidebar
|
||||
*/
|
||||
int sideBarMouseZone(SideBarLocation sideBarLocation);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -155,8 +174,20 @@ struct DockOverlayCrossPrivate
|
||||
QLabel* l = new QLabel();
|
||||
l->setObjectName("DockWidgetAreaLabel");
|
||||
|
||||
const qreal metric = dropIndicatiorWidth(l);
|
||||
const QSizeF size(metric, metric);
|
||||
qreal metric = dropIndicatiorWidth(l);
|
||||
QSizeF size(metric, metric);
|
||||
if (internal::isSideBarArea(DockWidgetArea))
|
||||
{
|
||||
auto SideBarLocation = internal::toSideBarLocation(DockWidgetArea);
|
||||
if (internal::isHorizontalSideBarLocation(SideBarLocation))
|
||||
{
|
||||
size.setHeight(size.height() / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
size.setWidth(size.width() / 2);
|
||||
}
|
||||
}
|
||||
|
||||
l->setPixmap(createHighDpiDropIndicatorPixmap(size, DockWidgetArea, Mode));
|
||||
l->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
|
||||
@ -182,6 +213,11 @@ struct DockOverlayCrossPrivate
|
||||
{
|
||||
QColor borderColor = iconColor(CDockOverlayCross::FrameColor);
|
||||
QColor backgroundColor = iconColor(CDockOverlayCross::WindowBackgroundColor);
|
||||
QColor overlayColor = iconColor(CDockOverlayCross::OverlayColor);
|
||||
if (overlayColor.alpha() == 255)
|
||||
{
|
||||
overlayColor.setAlpha(64);
|
||||
}
|
||||
|
||||
#if QT_VERSION >= 0x050600
|
||||
double DevicePixelRatio = _this->window()->devicePixelRatioF();
|
||||
@ -239,22 +275,22 @@ struct DockOverlayCrossPrivate
|
||||
}
|
||||
|
||||
QSizeF baseSize = baseRect.size();
|
||||
if (CDockOverlay::ModeContainerOverlay == Mode && DockWidgetArea != CenterDockWidgetArea)
|
||||
bool IsOuterContainerArea = (CDockOverlay::ModeContainerOverlay == Mode)
|
||||
&& (DockWidgetArea != CenterDockWidgetArea)
|
||||
&& !internal::isSideBarArea(DockWidgetArea);
|
||||
|
||||
if (IsOuterContainerArea)
|
||||
{
|
||||
baseRect = areaRect;
|
||||
}
|
||||
|
||||
p.fillRect(baseRect, backgroundColor);
|
||||
|
||||
if (areaRect.isValid())
|
||||
{
|
||||
pen = p.pen();
|
||||
pen.setColor(borderColor);
|
||||
QColor Color = iconColor(CDockOverlayCross::OverlayColor);
|
||||
if (Color.alpha() == 255)
|
||||
{
|
||||
Color.setAlpha(64);
|
||||
}
|
||||
p.setBrush(Color);
|
||||
p.setBrush(overlayColor);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawRect(areaRect);
|
||||
|
||||
@ -267,6 +303,7 @@ struct DockOverlayCrossPrivate
|
||||
}
|
||||
p.restore();
|
||||
|
||||
|
||||
p.save();
|
||||
// Draw outer border
|
||||
pen = p.pen();
|
||||
@ -282,8 +319,9 @@ struct DockOverlayCrossPrivate
|
||||
p.drawRect(FrameRect);
|
||||
p.restore();
|
||||
|
||||
|
||||
// Draw arrow for outer container drop indicators
|
||||
if (CDockOverlay::ModeContainerOverlay == Mode && DockWidgetArea != CenterDockWidgetArea)
|
||||
if (IsOuterContainerArea)
|
||||
{
|
||||
QRectF ArrowRect;
|
||||
ArrowRect.setSize(baseSize);
|
||||
@ -326,6 +364,38 @@ struct DockOverlayCrossPrivate
|
||||
};
|
||||
|
||||
|
||||
//============================================================================
|
||||
int DockOverlayPrivate::sideBarOverlaySize(SideBarLocation sideBarLocation)
|
||||
{
|
||||
auto Container = qobject_cast<CDockContainerWidget*>(TargetWidget.data());
|
||||
auto SideBar = Container->autoHideSideBar(sideBarLocation);
|
||||
if (!SideBar || !SideBar->isVisibleTo(Container))
|
||||
{
|
||||
return AutoHideAreaWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (SideBar->orientation() == Qt::Horizontal) ? SideBar->height() : SideBar->width();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
int DockOverlayPrivate::sideBarMouseZone(SideBarLocation sideBarLocation)
|
||||
{
|
||||
auto Container = qobject_cast<CDockContainerWidget*>(TargetWidget.data());
|
||||
auto SideBar = Container->autoHideSideBar(sideBarLocation);
|
||||
if (!SideBar || !SideBar->isVisibleTo(Container))
|
||||
{
|
||||
return AutoHideAreaMouseZone;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (SideBar->orientation() == Qt::Horizontal) ? SideBar->height() : SideBar->width();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
CDockOverlay::CDockOverlay(QWidget* parent, eMode Mode) :
|
||||
QFrame(parent),
|
||||
@ -359,12 +429,26 @@ CDockOverlay::~CDockOverlay()
|
||||
void CDockOverlay::setAllowedAreas(DockWidgetAreas areas)
|
||||
{
|
||||
if (areas == d->AllowedAreas)
|
||||
{
|
||||
return;
|
||||
}
|
||||
d->AllowedAreas = areas;
|
||||
d->Cross->reset();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockOverlay::setAllowedArea(DockWidgetArea area, bool Enable)
|
||||
{
|
||||
auto AreasOld = d->AllowedAreas;
|
||||
d->AllowedAreas.setFlag(area, Enable);
|
||||
if (AreasOld != d->AllowedAreas)
|
||||
{
|
||||
d->Cross->reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
DockWidgetAreas CDockOverlay::allowedAreas() const
|
||||
{
|
||||
@ -375,22 +459,68 @@ DockWidgetAreas CDockOverlay::allowedAreas() const
|
||||
//============================================================================
|
||||
DockWidgetArea CDockOverlay::dropAreaUnderCursor() const
|
||||
{
|
||||
d->TabIndex = InvalidTabIndex;
|
||||
if (!d->TargetWidget)
|
||||
{
|
||||
return InvalidDockWidgetArea;
|
||||
}
|
||||
|
||||
DockWidgetArea Result = d->Cross->cursorLocation();
|
||||
if (Result != InvalidDockWidgetArea)
|
||||
{
|
||||
return Result;
|
||||
}
|
||||
|
||||
CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(d->TargetWidget.data());
|
||||
if (!DockArea)
|
||||
auto CursorPos = QCursor::pos();
|
||||
auto DockArea = qobject_cast<CDockAreaWidget*>(d->TargetWidget.data());
|
||||
if (!DockArea && CDockManager::autoHideConfigFlags().testFlag(CDockManager::AutoHideFeatureEnabled))
|
||||
{
|
||||
auto Rect = rect();
|
||||
const QPoint pos = mapFromGlobal(QCursor::pos());
|
||||
if ((pos.x() < d->sideBarMouseZone(SideBarLeft))
|
||||
&& d->AllowedAreas.testFlag(LeftAutoHideArea))
|
||||
{
|
||||
Result = LeftAutoHideArea;
|
||||
}
|
||||
else if (pos.x() > (Rect.width() - d->sideBarMouseZone(SideBarRight))
|
||||
&& d->AllowedAreas.testFlag(RightAutoHideArea))
|
||||
{
|
||||
Result = RightAutoHideArea;
|
||||
}
|
||||
else if (pos.y() < d->sideBarMouseZone(SideBarTop)
|
||||
&& d->AllowedAreas.testFlag(TopAutoHideArea))
|
||||
{
|
||||
Result = TopAutoHideArea;
|
||||
}
|
||||
else if (pos.y() > (Rect.height() - d->sideBarMouseZone(SideBarBottom))
|
||||
&& d->AllowedAreas.testFlag(BottomAutoHideArea))
|
||||
{
|
||||
Result = BottomAutoHideArea;
|
||||
}
|
||||
|
||||
auto SideBarLocation = ads::internal::toSideBarLocation(Result);
|
||||
if (SideBarLocation != SideBarNone)
|
||||
{
|
||||
auto Container = qobject_cast<CDockContainerWidget*>(d->TargetWidget.data());
|
||||
auto SideBar = Container->autoHideSideBar(SideBarLocation);
|
||||
if (SideBar->isVisible())
|
||||
{
|
||||
d->TabIndex = SideBar->tabInsertIndexAt(SideBar->mapFromGlobal(CursorPos));
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
else if (!DockArea)
|
||||
{
|
||||
return Result;
|
||||
}
|
||||
|
||||
if (DockArea->allowedAreas().testFlag(CenterDockWidgetArea)
|
||||
&& !DockArea->titleBar()->isHidden()
|
||||
&& DockArea->titleBarGeometry().contains(DockArea->mapFromGlobal(QCursor::pos())))
|
||||
&& DockArea->titleBarGeometry().contains(DockArea->mapFromGlobal(CursorPos)))
|
||||
{
|
||||
auto TabBar = DockArea->titleBar()->tabBar();
|
||||
d->TabIndex = TabBar->tabInsertIndexAt(TabBar->mapFromGlobal(CursorPos));
|
||||
return CenterDockWidgetArea;
|
||||
}
|
||||
|
||||
@ -398,6 +528,13 @@ DockWidgetArea CDockOverlay::dropAreaUnderCursor() const
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
int CDockOverlay::tabIndexUnderCursor() const
|
||||
{
|
||||
return d->TabIndex;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
DockWidgetArea CDockOverlay::visibleDropAreaUnderCursor() const
|
||||
{
|
||||
@ -471,6 +608,7 @@ bool CDockOverlay::dropPreviewEnabled() const
|
||||
void CDockOverlay::paintEvent(QPaintEvent* event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
|
||||
// Draw rect based on location
|
||||
if (!d->DropPreviewEnabled)
|
||||
{
|
||||
@ -490,8 +628,13 @@ void CDockOverlay::paintEvent(QPaintEvent* event)
|
||||
case BottomDockWidgetArea: r.setY(r.height() * (1 - 1 / Factor)); break;
|
||||
case LeftDockWidgetArea: r.setWidth(r.width() / Factor); break;
|
||||
case CenterDockWidgetArea: r = rect();break;
|
||||
case LeftAutoHideArea: r.setWidth(d->sideBarOverlaySize(SideBarLeft)); break;
|
||||
case RightAutoHideArea: r.setX(r.width() - d->sideBarOverlaySize(SideBarRight)); break;
|
||||
case TopAutoHideArea: r.setHeight(d->sideBarOverlaySize(SideBarTop)); break;
|
||||
case BottomAutoHideArea: r.setY(r.height() - d->sideBarOverlaySize(SideBarBottom)); break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
QPainter painter(this);
|
||||
QColor Color = palette().color(QPalette::Active, QPalette::Highlight);
|
||||
QPen Pen = painter.pen();
|
||||
@ -627,6 +770,7 @@ void CDockOverlayCross::setupOverlayCross(CDockOverlay::eMode Mode)
|
||||
areaWidgets.insert(BottomDockWidgetArea, d->createDropIndicatorWidget(BottomDockWidgetArea, Mode));
|
||||
areaWidgets.insert(LeftDockWidgetArea, d->createDropIndicatorWidget(LeftDockWidgetArea, Mode));
|
||||
areaWidgets.insert(CenterDockWidgetArea, d->createDropIndicatorWidget(CenterDockWidgetArea, Mode));
|
||||
|
||||
#if QT_VERSION >= 0x050600
|
||||
d->LastDevicePixelRatio = devicePixelRatioF();
|
||||
#else
|
||||
|
@ -72,6 +72,11 @@ public:
|
||||
*/
|
||||
void setAllowedAreas(DockWidgetAreas areas);
|
||||
|
||||
/**
|
||||
* Enable / disable a certain area
|
||||
*/
|
||||
void setAllowedArea(DockWidgetArea area, bool Enable);
|
||||
|
||||
/**
|
||||
* Returns flags with all allowed drop areas
|
||||
*/
|
||||
@ -82,6 +87,17 @@ public:
|
||||
*/
|
||||
DockWidgetArea dropAreaUnderCursor() const;
|
||||
|
||||
/**
|
||||
* If the drop area is the CenterDockWidgetArea or a sidebar area,
|
||||
* then this function returns the index of the tab under cursor.
|
||||
* Call this function after call to dropAreaUnderCursor() because this
|
||||
* function updates the tab index.
|
||||
* A value of -1 indicates a position before the first tab and a value of
|
||||
* tabCount() indicates a position behind the last tab.
|
||||
* A value of -2 indicates an valid value
|
||||
*/
|
||||
int tabIndexUnderCursor() const;
|
||||
|
||||
/**
|
||||
* This function returns the same like dropAreaUnderCursor() if this
|
||||
* overlay is not hidden and if drop preview is enabled and returns
|
||||
|
@ -555,6 +555,13 @@ bool CDockWidget::isAutoHide() const
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
SideBarLocation CDockWidget::autoHideLocation() const
|
||||
{
|
||||
return isAutoHide() ? autoHideDockContainer()->sideBarLocation() : SideBarNone;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool CDockWidget::isFloating() const
|
||||
{
|
||||
@ -1021,7 +1028,15 @@ void CDockWidget::setFloating()
|
||||
{
|
||||
return;
|
||||
}
|
||||
d->TabWidget->detachDockWidget();
|
||||
|
||||
if (this->isAutoHide())
|
||||
{
|
||||
dockAreaWidget()->setFloating();
|
||||
}
|
||||
else
|
||||
{
|
||||
d->TabWidget->detachDockWidget();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1044,6 +1059,22 @@ void CDockWidget::closeDockWidget()
|
||||
}
|
||||
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockWidget::requestCloseDockWidget()
|
||||
{
|
||||
if (features().testFlag(CDockWidget::DockWidgetDeleteOnClose)
|
||||
|| features().testFlag(CDockWidget::CustomCloseHandling))
|
||||
{
|
||||
closeDockWidgetInternal(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
toggleView(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool CDockWidget::closeDockWidgetInternal(bool ForceClose)
|
||||
{
|
||||
@ -1190,7 +1221,7 @@ void CDockWidget::raise()
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockWidget::setAutoHide(bool Enable, SideBarLocation Location)
|
||||
void CDockWidget::setAutoHide(bool Enable, SideBarLocation Location, int TabIndex)
|
||||
{
|
||||
if (!CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideFeatureEnabled))
|
||||
{
|
||||
@ -1198,20 +1229,25 @@ void CDockWidget::setAutoHide(bool Enable, SideBarLocation Location)
|
||||
}
|
||||
|
||||
// Do nothing if nothing changes
|
||||
if (Enable == isAutoHide())
|
||||
if (Enable == isAutoHide() && Location == autoHideLocation())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto DockArea = dockAreaWidget();
|
||||
|
||||
if (!Enable)
|
||||
{
|
||||
DockArea->setAutoHide(false);
|
||||
}
|
||||
else if (isAutoHide())
|
||||
{
|
||||
autoHideDockContainer()->moveToNewSideBarLocation(Location);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto area = (SideBarNone == Location) ? DockArea->calculateSideTabBarArea() : Location;
|
||||
dockContainer()->createAndSetupAutoHideContainer(area, this);
|
||||
dockContainer()->createAndSetupAutoHideContainer(area, this, TabIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -377,6 +377,12 @@ public:
|
||||
*/
|
||||
CAutoHideDockContainer* autoHideDockContainer() const;
|
||||
|
||||
/**
|
||||
* Returns the auto hide side bar location or SideBarNone if, this is not
|
||||
* an autohide dock widget
|
||||
*/
|
||||
SideBarLocation autoHideLocation() const;
|
||||
|
||||
/**
|
||||
* This property holds whether the dock widget is floating.
|
||||
* A dock widget is only floating, if it is the one and only widget inside
|
||||
@ -578,10 +584,19 @@ public Q_SLOTS:
|
||||
void deleteDockWidget();
|
||||
|
||||
/**
|
||||
* Closes the dock widget
|
||||
* Closes the dock widget.
|
||||
* The function forces closing of the dock widget even for CustomCloseHandling.
|
||||
*/
|
||||
void closeDockWidget();
|
||||
|
||||
/**
|
||||
* Request closing of the dock widget.
|
||||
* For DockWidget with default close handling, the function does the same
|
||||
* like clodeDockWidget() but if the flas CustomCloseHandling is set,
|
||||
* the function only emits the closeRequested() signal.
|
||||
*/
|
||||
void requestCloseDockWidget();
|
||||
|
||||
/**
|
||||
* Shows the widget in full-screen mode.
|
||||
* Normally this function only affects windows. To make the interface
|
||||
@ -606,7 +621,7 @@ public Q_SLOTS:
|
||||
* Sets the dock widget into auto hide mode if this feature is enabled
|
||||
* via CDockManager::setAutoHideFlags(CDockManager::AutoHideFeatureEnabled)
|
||||
*/
|
||||
void setAutoHide(bool Enable, SideBarLocation Location = SideBarNone);
|
||||
void setAutoHide(bool Enable, SideBarLocation Location = SideBarNone, int TabIndex = -1);
|
||||
|
||||
/**
|
||||
* Switches the dock widget to auto hide mode or vice versa depending on its
|
||||
|
@ -499,10 +499,8 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|
||||
return;
|
||||
}
|
||||
|
||||
if (DockManager->dockAreaOverlay()->dropAreaUnderCursor()
|
||||
!= InvalidDockWidgetArea
|
||||
|| DockManager->containerOverlay()->dropAreaUnderCursor()
|
||||
!= InvalidDockWidgetArea)
|
||||
if (DockManager->dockAreaOverlay()->dropAreaUnderCursor() != InvalidDockWidgetArea
|
||||
|| DockManager->containerOverlay()->dropAreaUnderCursor() != InvalidDockWidgetArea)
|
||||
{
|
||||
CDockOverlay *Overlay = DockManager->containerOverlay();
|
||||
if (!Overlay->dropOverlayRect().isValid())
|
||||
@ -510,21 +508,26 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|
||||
Overlay = DockManager->dockAreaOverlay();
|
||||
}
|
||||
|
||||
// Resize the floating widget to the size of the highlighted drop area
|
||||
// rectangle
|
||||
QRect Rect = Overlay->dropOverlayRect();
|
||||
int FrameWidth = (_this->frameSize().width() - _this->rect().width())
|
||||
/ 2;
|
||||
int TitleBarHeight = _this->frameSize().height()
|
||||
- _this->rect().height() - FrameWidth;
|
||||
if (Rect.isValid())
|
||||
// Do not resize if we drop into an autohide sidebar area to preserve
|
||||
// the dock area size for the initial size of the auto hide area
|
||||
if (!ads::internal::isSideBarArea(Overlay->dropAreaUnderCursor()))
|
||||
{
|
||||
QPoint TopLeft = Overlay->mapToGlobal(Rect.topLeft());
|
||||
TopLeft.ry() += TitleBarHeight;
|
||||
_this->setGeometry(
|
||||
QRect(TopLeft,
|
||||
QSize(Rect.width(), Rect.height() - TitleBarHeight)));
|
||||
QApplication::processEvents();
|
||||
// Resize the floating widget to the size of the highlighted drop area
|
||||
// rectangle
|
||||
QRect Rect = Overlay->dropOverlayRect();
|
||||
int FrameWidth = (_this->frameSize().width() - _this->rect().width())
|
||||
/ 2;
|
||||
int TitleBarHeight = _this->frameSize().height()
|
||||
- _this->rect().height() - FrameWidth;
|
||||
if (Rect.isValid())
|
||||
{
|
||||
QPoint TopLeft = Overlay->mapToGlobal(Rect.topLeft());
|
||||
TopLeft.ry() += TitleBarHeight;
|
||||
_this->setGeometry(
|
||||
QRect(TopLeft,
|
||||
QSize(Rect.width(), Rect.height() - TitleBarHeight)));
|
||||
QApplication::processEvents();
|
||||
}
|
||||
}
|
||||
DropContainer->dropFloatingWidget(_this, QCursor::pos());
|
||||
}
|
||||
@ -533,6 +536,7 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|
||||
DockManager->dockAreaOverlay()->hideOverlay();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void FloatingDockContainerPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
||||
{
|
||||
@ -586,11 +590,25 @@ void FloatingDockContainerPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
||||
}
|
||||
|
||||
int VisibleDockAreas = TopContainer->visibleDockAreaCount();
|
||||
ContainerOverlay->setAllowedAreas(
|
||||
VisibleDockAreas > 1 ? OuterDockAreas : AllDockAreas);
|
||||
DockWidgetAreas AllowedContainerAreas = (VisibleDockAreas > 1) ? OuterDockAreas : AllDockAreas;
|
||||
auto DockArea = TopContainer->dockAreaAt(GlobalPos);
|
||||
// If the dock container contains only one single DockArea, then we need
|
||||
// to respect the allowed areas - only the center area is relevant here because
|
||||
// all other allowed areas are from the container
|
||||
if (VisibleDockAreas == 1 && DockArea)
|
||||
{
|
||||
AllowedContainerAreas.setFlag(CenterDockWidgetArea, DockArea->allowedAreas().testFlag(CenterDockWidgetArea));
|
||||
}
|
||||
|
||||
if (DockContainer->features().testFlag(CDockWidget::DockWidgetPinnable))
|
||||
{
|
||||
AllowedContainerAreas |= AutoHideDockAreas;
|
||||
}
|
||||
|
||||
ContainerOverlay->setAllowedAreas(AllowedContainerAreas);
|
||||
|
||||
DockWidgetArea ContainerArea = ContainerOverlay->showOverlay(TopContainer);
|
||||
ContainerOverlay->enableDropPreview(ContainerArea != InvalidDockWidgetArea);
|
||||
auto DockArea = TopContainer->dockAreaAt(GlobalPos);
|
||||
if (DockArea && DockArea->isVisible() && VisibleDockAreas > 0)
|
||||
{
|
||||
DockAreaOverlay->enableDropPreview(true);
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "DockManager.h"
|
||||
#include "DockContainerWidget.h"
|
||||
#include "DockOverlay.h"
|
||||
#include "AutoHideDockContainer.h"
|
||||
#include "ads_globals.h"
|
||||
|
||||
namespace ads
|
||||
{
|
||||
@ -33,6 +35,7 @@ struct FloatingDragPreviewPrivate
|
||||
{
|
||||
CFloatingDragPreview *_this;
|
||||
QWidget* Content;
|
||||
CDockWidget::DockWidgetFeatures ContentFeatures;
|
||||
CDockAreaWidget* ContentSourceArea = nullptr;
|
||||
QPoint DragStartMousePosition;
|
||||
CDockManager* DockManager;
|
||||
@ -77,20 +80,36 @@ struct FloatingDragPreviewPrivate
|
||||
* Returns true, if the content is floatable
|
||||
*/
|
||||
bool isContentFloatable() const
|
||||
{
|
||||
return this->ContentFeatures.testFlag(CDockWidget::DockWidgetFloatable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true, if the content is pinnable
|
||||
*/
|
||||
bool isContentPinnable() const
|
||||
{
|
||||
return this->ContentFeatures.testFlag(CDockWidget::DockWidgetPinnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content features
|
||||
*/
|
||||
CDockWidget::DockWidgetFeatures contentFeatures() const
|
||||
{
|
||||
CDockWidget* DockWidget = qobject_cast<CDockWidget*>(Content);
|
||||
if (DockWidget && DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable))
|
||||
if (DockWidget)
|
||||
{
|
||||
return true;
|
||||
return DockWidget->features();
|
||||
}
|
||||
|
||||
CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(Content);
|
||||
if (DockArea && DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
|
||||
if (DockArea)
|
||||
{
|
||||
return true;
|
||||
return DockArea->features();
|
||||
}
|
||||
|
||||
return false;
|
||||
return CDockWidget::DockWidgetFeatures();
|
||||
}
|
||||
};
|
||||
// struct LedArrayPanelPrivate
|
||||
@ -126,8 +145,6 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
||||
DropContainer = TopContainer;
|
||||
auto ContainerOverlay = DockManager->containerOverlay();
|
||||
auto DockAreaOverlay = DockManager->dockAreaOverlay();
|
||||
auto DockDropArea = DockAreaOverlay->dropAreaUnderCursor();
|
||||
auto ContainerDropArea = ContainerOverlay->dropAreaUnderCursor();
|
||||
|
||||
if (!TopContainer)
|
||||
{
|
||||
@ -140,6 +157,9 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
||||
return;
|
||||
}
|
||||
|
||||
auto DockDropArea = DockAreaOverlay->dropAreaUnderCursor();
|
||||
auto ContainerDropArea = ContainerOverlay->dropAreaUnderCursor();
|
||||
|
||||
int VisibleDockAreas = TopContainer->visibleDockAreaCount();
|
||||
|
||||
// Include the overlay widget we're dragging as a visible widget
|
||||
@ -149,13 +169,27 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
||||
VisibleDockAreas++;
|
||||
}
|
||||
|
||||
ContainerOverlay->setAllowedAreas( VisibleDockAreas > 1 ? OuterDockAreas : AllDockAreas);
|
||||
DockWidgetAreas AllowedContainerAreas = (VisibleDockAreas > 1) ? OuterDockAreas : AllDockAreas;
|
||||
//ContainerOverlay->enableDropPreview(ContainerDropArea != InvalidDockWidgetArea);
|
||||
auto DockArea = TopContainer->dockAreaAt(GlobalPos);
|
||||
// If the dock container contains only one single DockArea, then we need
|
||||
// to respect the allowed areas - only the center area is relevant here because
|
||||
// all other allowed areas are from the container
|
||||
if (VisibleDockAreas == 1 && DockArea)
|
||||
{
|
||||
AllowedContainerAreas.setFlag(CenterDockWidgetArea, DockArea->allowedAreas().testFlag(CenterDockWidgetArea));
|
||||
}
|
||||
|
||||
if (isContentPinnable())
|
||||
{
|
||||
AllowedContainerAreas |= AutoHideDockAreas;
|
||||
}
|
||||
ContainerOverlay->setAllowedAreas(AllowedContainerAreas);
|
||||
ContainerOverlay->enableDropPreview(ContainerDropArea != InvalidDockWidgetArea);
|
||||
if (DockArea && DockArea->isVisible() && VisibleDockAreas >= 0 && DockArea != ContentSourceArea)
|
||||
{
|
||||
DockAreaOverlay->enableDropPreview(true);
|
||||
DockAreaOverlay->setAllowedAreas( (VisibleDockAreas == 1) ? NoDockWidgetArea : DockArea->allowedAreas());
|
||||
|
||||
DockWidgetArea Area = DockAreaOverlay->showOverlay(DockArea);
|
||||
|
||||
// A CenterDockWidgetArea for the dockAreaOverlay() indicates that
|
||||
@ -178,15 +212,13 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
||||
DockAreaOverlay->hideOverlay();
|
||||
// If there is only one single visible dock area in a container, then
|
||||
// it does not make sense to show a dock overlay because the dock area
|
||||
// would be removed and inserted at the same position
|
||||
// would be removed and inserted at the same position. Only auto hide
|
||||
// area is allowed
|
||||
if (VisibleDockAreas == 1)
|
||||
{
|
||||
ContainerOverlay->hideOverlay();
|
||||
}
|
||||
else
|
||||
{
|
||||
ContainerOverlay->showOverlay(TopContainer);
|
||||
ContainerOverlay->setAllowedAreas(AutoHideDockAreas);
|
||||
}
|
||||
ContainerOverlay->showOverlay(TopContainer);
|
||||
|
||||
|
||||
if (DockArea == ContentSourceArea && InvalidDockWidgetArea == ContainerDropArea)
|
||||
@ -249,6 +281,7 @@ CFloatingDragPreview::CFloatingDragPreview(QWidget* Content, QWidget* parent) :
|
||||
d(new FloatingDragPreviewPrivate(this))
|
||||
{
|
||||
d->Content = Content;
|
||||
d->ContentFeatures = d->contentFeatures();
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
if (CDockManager::testConfigFlag(CDockManager::DragPreviewHasWindowFrame))
|
||||
{
|
||||
@ -268,8 +301,6 @@ CFloatingDragPreview::CFloatingDragPreview(QWidget* Content, QWidget* parent) :
|
||||
setWindowFlags(Flags);
|
||||
#endif
|
||||
|
||||
setWindowOpacity(0.6);
|
||||
|
||||
// Create a static image of the widget that should get undocked
|
||||
// This is like some kind preview image like it is uses in drag and drop
|
||||
// operations
|
||||
@ -356,7 +387,7 @@ void CFloatingDragPreview::finishDragging()
|
||||
// state if they are dragged into a floating window
|
||||
if (ValidDropArea || d->isContentFloatable())
|
||||
{
|
||||
cleanupAutoHideContainerWidget();
|
||||
cleanupAutoHideContainerWidget(ContainerDropArea);
|
||||
}
|
||||
|
||||
if (!d->DropContainer)
|
||||
@ -365,20 +396,21 @@ void CFloatingDragPreview::finishDragging()
|
||||
}
|
||||
else if (DockDropArea != InvalidDockWidgetArea)
|
||||
{
|
||||
d->DropContainer->dropWidget(d->Content, DockDropArea, d->DropContainer->dockAreaAt(QCursor::pos()));
|
||||
d->DropContainer->dropWidget(d->Content, DockDropArea, d->DropContainer->dockAreaAt(QCursor::pos()),
|
||||
d->DockManager->dockAreaOverlay()->tabIndexUnderCursor());
|
||||
}
|
||||
else if (ContainerDropArea != InvalidDockWidgetArea)
|
||||
{
|
||||
CDockAreaWidget* DockArea = nullptr;
|
||||
// If there is only one single dock area, and we drop into the center
|
||||
// then we tabify the dropped widget into the only visible dock area
|
||||
if (d->DropContainer->visibleDockAreaCount() <= 1 && CenterDockWidgetArea == ContainerDropArea)
|
||||
{
|
||||
d->DropContainer->dropWidget(d->Content, ContainerDropArea, d->DropContainer->dockAreaAt(QCursor::pos()));
|
||||
}
|
||||
else
|
||||
{
|
||||
d->DropContainer->dropWidget(d->Content, ContainerDropArea, nullptr);
|
||||
DockArea = d->DropContainer->dockAreaAt(QCursor::pos());
|
||||
}
|
||||
|
||||
d->DropContainer->dropWidget(d->Content, ContainerDropArea, DockArea,
|
||||
d->DockManager->containerOverlay()->tabIndexUnderCursor());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -392,18 +424,29 @@ void CFloatingDragPreview::finishDragging()
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CFloatingDragPreview::cleanupAutoHideContainerWidget()
|
||||
void CFloatingDragPreview::cleanupAutoHideContainerWidget(DockWidgetArea ContainerDropArea)
|
||||
{
|
||||
auto DroppedDockWidget = qobject_cast<CDockWidget*>(d->Content);
|
||||
auto DroppedArea = qobject_cast<CDockAreaWidget*>(d->Content);
|
||||
if (DroppedDockWidget && DroppedDockWidget->autoHideDockContainer())
|
||||
auto AutoHideContainer = DroppedDockWidget
|
||||
? DroppedDockWidget->autoHideDockContainer()
|
||||
: DroppedArea->autoHideDockContainer();
|
||||
|
||||
if (!AutoHideContainer)
|
||||
{
|
||||
DroppedDockWidget->autoHideDockContainer()->cleanupAndDelete();
|
||||
return;
|
||||
}
|
||||
if (DroppedArea && DroppedArea->autoHideDockContainer())
|
||||
|
||||
// If the dropped widget is already an auto hide widget and if it is moved
|
||||
// to a new side bar location in the same container, then we do not need
|
||||
// to cleanup
|
||||
if (ads::internal::isSideBarArea(ContainerDropArea)
|
||||
&& (d->DropContainer == AutoHideContainer->dockContainer()))
|
||||
{
|
||||
DroppedArea->autoHideDockContainer()->cleanupAndDelete();
|
||||
return;
|
||||
}
|
||||
|
||||
AutoHideContainer->cleanupAndDelete();
|
||||
}
|
||||
|
||||
|
||||
@ -417,6 +460,7 @@ void CFloatingDragPreview::paintEvent(QPaintEvent* event)
|
||||
}
|
||||
|
||||
QPainter painter(this);
|
||||
painter.setOpacity(0.6);
|
||||
if (CDockManager::testConfigFlag(CDockManager::DragPreviewShowsContentPixmap))
|
||||
{
|
||||
painter.drawPixmap(QPoint(0, 0), d->ContentPreviewPixmap);
|
||||
|
@ -95,7 +95,7 @@ public: // implements IFloatingWidget -----------------------------------------
|
||||
/**
|
||||
* Cleanup auto hide container if the dragged widget has one
|
||||
*/
|
||||
void cleanupAutoHideContainerWidget();
|
||||
void cleanupAutoHideContainerWidget(DockWidgetArea ContainerDropArea);
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
|
@ -18,5 +18,7 @@
|
||||
<file>images/vs-pin-button.svg</file>
|
||||
<file>images/vs-pin-button-pinned.svg</file>
|
||||
<file>images/vs-pin-button-pinned-focused.svg</file>
|
||||
<file>images/vs-pin-button_45.svg</file>
|
||||
<file>images/pin-button-big.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -333,6 +333,47 @@ CDockInsertParam dockAreaInsertParameters(DockWidgetArea Area)
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
SideBarLocation toSideBarLocation(DockWidgetArea Area)
|
||||
{
|
||||
switch (Area)
|
||||
{
|
||||
case LeftAutoHideArea: return SideBarLeft;
|
||||
case RightAutoHideArea: return SideBarRight;
|
||||
case TopAutoHideArea: return SideBarTop;
|
||||
case BottomAutoHideArea: return SideBarBottom;
|
||||
default:
|
||||
return SideBarNone;
|
||||
}
|
||||
|
||||
return SideBarNone;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool isHorizontalSideBarLocation(SideBarLocation Location)
|
||||
{
|
||||
switch (Location)
|
||||
{
|
||||
case SideBarTop:
|
||||
case SideBarBottom: return true;
|
||||
case SideBarLeft:
|
||||
case SideBarRight: return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool isSideBarArea(DockWidgetArea Area)
|
||||
{
|
||||
return toSideBarLocation(Area) != SideBarNone;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
QPixmap createTransparentPixmap(const QPixmap& Source, qreal Opacity)
|
||||
{
|
||||
|
@ -82,14 +82,26 @@ enum DockWidgetArea
|
||||
TopDockWidgetArea = 0x04,
|
||||
BottomDockWidgetArea = 0x08,
|
||||
CenterDockWidgetArea = 0x10,
|
||||
LeftAutoHideArea = 0x20,
|
||||
RightAutoHideArea = 0x40,
|
||||
TopAutoHideArea = 0x80,
|
||||
BottomAutoHideArea = 0x100,
|
||||
|
||||
InvalidDockWidgetArea = NoDockWidgetArea,
|
||||
OuterDockAreas = TopDockWidgetArea | LeftDockWidgetArea | RightDockWidgetArea | BottomDockWidgetArea,
|
||||
AutoHideDockAreas = LeftAutoHideArea | RightAutoHideArea | TopAutoHideArea | BottomAutoHideArea,
|
||||
AllDockAreas = OuterDockAreas | CenterDockWidgetArea
|
||||
};
|
||||
Q_DECLARE_FLAGS(DockWidgetAreas, DockWidgetArea)
|
||||
|
||||
|
||||
enum eTabIndex
|
||||
{
|
||||
TabDefaultInsertIndex = -1,
|
||||
TabInvalidIndex = -2
|
||||
};
|
||||
|
||||
|
||||
enum TitleBarButton
|
||||
{
|
||||
TitleBarButtonTabsMenu,
|
||||
@ -194,6 +206,7 @@ void replaceSplitterWidget(QSplitter* Splitter, QWidget* From, QWidget* To);
|
||||
*/
|
||||
void hideEmptyParentSplitters(CDockSplitter* FirstParentSplitter);
|
||||
|
||||
|
||||
/**
|
||||
* Convenience class for QPair to provide better naming than first and
|
||||
* second
|
||||
@ -212,6 +225,25 @@ public:
|
||||
*/
|
||||
CDockInsertParam dockAreaInsertParameters(DockWidgetArea Area);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the SieBarLocation for the AutoHide dock widget areas
|
||||
*/
|
||||
SideBarLocation toSideBarLocation(DockWidgetArea Area);
|
||||
|
||||
|
||||
/**
|
||||
* Returns true for the top or bottom side bar ansd false for the
|
||||
* left and right side bar
|
||||
*/
|
||||
bool isHorizontalSideBarLocation(SideBarLocation Location);
|
||||
|
||||
|
||||
/**
|
||||
* Returns true, if the given dock area is a SideBar area
|
||||
*/
|
||||
bool isSideBarArea(DockWidgetArea Area);
|
||||
|
||||
/**
|
||||
* Searches for the parent widget of the given type.
|
||||
* Returns the parent widget of the given widget or 0 if the widget is not
|
||||
|
2
src/images/pin-button-big.svg
Normal file
2
src/images/pin-button-big.svg
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="16" height="16" enable-background="new 0 0 122.879 122.867" version="1.1" viewBox="0 0 16 16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><g transform="matrix(.12293 0 0 .12294 .39712 .49812)" fill="#ffffff" stroke="#000000" stroke-width="8.1347"><path d="m83.88 0.451 38.547 38.549c0.603 0.601 0.603 1.585 0 2.188l-13.128 13.125c-0.602 0.604-1.586 0.604-2.187 0l-3.732-3.73-17.303 17.3c3.882 14.621 0.095 30.857-11.37 42.32-0.266 0.268-0.535 0.529-0.808 0.787-1.004 0.955-0.843 0.949-1.813-0.021l-24.489-24.489-47.597 36.387 36.399-47.584-24.525-24.523c-0.978-0.98-0.896-0.826 0.066-1.837 0.24-0.251 0.485-0.503 0.734-0.753 11.463-11.463 27.702-15.253 42.322-11.37l17.301-17.3-3.733-3.732c-0.601-0.601-0.601-1.585 0-2.188l13.127-13.129c0.604-0.601 1.588-0.601 2.189 0z" clip-rule="evenodd" fill="#ffffff" fill-rule="evenodd" stroke="#000000" stroke-width="8.1347"/></g></svg>
|
After Width: | Height: | Size: 940 B |
2
src/images/vs-pin-button_45.svg
Normal file
2
src/images/vs-pin-button_45.svg
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="16" height="16" enable-background="new 0 0 122.879 122.867" version="1.1" viewBox="0 0 16 16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="m10.286-1.055e-6 -6.8571 6.8571-1.1429-1.1429-1.1429 1.1429 3.4286 3.4286-4.5714 4.5714 1.1429 1.1429 4.5714-4.5714 3.4286 3.4286 1.1429-1.1429-1.1429-1.1429 6.8571-6.8571-4.5714-4.5714zm0 2.2857 2.2857 2.2857-5.7143 5.7143-2.2857-2.2857z" fill="#000000"/></svg>
|
After Width: | Height: | Size: 473 B |
Loading…
Reference in New Issue
Block a user