forked from qt-creator/qt-creator
ADS: Integrate newest base repository commits
* Add drag and drop to auto hide Base repository was merged until commit 65600a4dcd072fd2773b661823816db6392c34eb Change-Id: I09dd6613869368d3cf0c701055a6972db915561d Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
committed by
Henning Gründl
parent
16ef838f23
commit
bb635325e7
@@ -63,6 +63,45 @@ DockInsertParam dockAreaInsertParameters(DockWidgetArea area)
|
||||
return DockInsertParam(Qt::Vertical, false);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
QPixmap transparentPixmap(source.size());
|
||||
|
@@ -47,14 +47,21 @@ 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 eTitleBarButton {
|
||||
TitleBarButtonTabsMenu,
|
||||
TitleBarButtonUndock,
|
||||
@@ -137,6 +144,21 @@ public:
|
||||
*/
|
||||
DockInsertParam 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 child of any widget of type T.
|
||||
|
@@ -90,6 +90,7 @@ struct AutoHideDockContainerPrivate
|
||||
ResizeHandle *m_resizeHandle = nullptr;
|
||||
QSize m_size; // creates invalid size
|
||||
QPointer<AutoHideTab> m_sideTab;
|
||||
QSize m_sizeCache;
|
||||
|
||||
/**
|
||||
* Private data constructor
|
||||
@@ -181,6 +182,7 @@ AutoHideDockContainer::AutoHideDockContainer(DockWidget *dockWidget,
|
||||
bool opaqueResize = DockManager::testConfigFlag(DockManager::OpaqueSplitterResize);
|
||||
d->m_resizeHandle->setOpaqueResize(opaqueResize);
|
||||
d->m_size = d->m_dockArea->size();
|
||||
d->m_sizeCache = dockWidget->size();
|
||||
|
||||
addDockWidget(dockWidget);
|
||||
parent->registerAutoHideWidget(this);
|
||||
@@ -228,6 +230,11 @@ void AutoHideDockContainer::updateSize()
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (orientation() == Qt::Horizontal)
|
||||
d->m_sizeCache.setHeight(this->height());
|
||||
else
|
||||
d->m_sizeCache.setWidth(this->width());
|
||||
}
|
||||
|
||||
AutoHideDockContainer::~AutoHideDockContainer()
|
||||
@@ -245,13 +252,13 @@ AutoHideDockContainer::~AutoHideDockContainer()
|
||||
delete d;
|
||||
}
|
||||
|
||||
AutoHideSideBar *AutoHideDockContainer::sideBar() const
|
||||
AutoHideSideBar *AutoHideDockContainer::autoHideSideBar() const
|
||||
{
|
||||
if (d->m_sideTab) {
|
||||
return d->m_sideTab->sideBar();
|
||||
} else {
|
||||
auto container = dockContainer();
|
||||
return container ? container->sideTabBar(d->m_sideTabBarArea) : nullptr;
|
||||
return container ? container->autoHideSideBar(d->m_sideTabBarArea) : nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,14 +284,18 @@ void AutoHideDockContainer::addDockWidget(DockWidget *dockWidget)
|
||||
DockAreaWidget *oldDockArea = dockWidget->dockAreaWidget();
|
||||
auto isRestoringState = dockWidget->dockManager()->isRestoringState();
|
||||
if (oldDockArea && !isRestoringState) {
|
||||
// The initial size should be a little bit bigger than the original dock
|
||||
// area size to prevent that the resize handle of this auto hid dock area
|
||||
// is near of the splitter of the old dock area.
|
||||
// The initial size should be a little bit bigger than the original dock area size to
|
||||
// prevent that the resize handle of this auto hid dock area is near of the splitter of
|
||||
// the old dock area.
|
||||
d->m_size = oldDockArea->size() + QSize(16, 16);
|
||||
oldDockArea->removeDockWidget(dockWidget);
|
||||
}
|
||||
d->m_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 explicitly resize it here. As soon as it will
|
||||
// become visible, it will get the right size
|
||||
d->m_dockArea->resize(size());
|
||||
}
|
||||
|
||||
SideBarLocation AutoHideDockContainer::sideBarLocation() const
|
||||
@@ -393,6 +404,39 @@ void AutoHideDockContainer::setSize(int size)
|
||||
updateSize();
|
||||
}
|
||||
|
||||
Qt::Orientation AutoHideDockContainer::orientation() const
|
||||
{
|
||||
return internal::isHorizontalSideBarLocation(d->m_sideTabBarArea) ? Qt::Horizontal
|
||||
: Qt::Vertical;
|
||||
}
|
||||
|
||||
void AutoHideDockContainer::resetToInitialDockWidgetSize()
|
||||
{
|
||||
if (orientation() == Qt::Horizontal)
|
||||
setSize(d->m_sizeCache.height());
|
||||
else
|
||||
setSize(d->m_sizeCache.width());
|
||||
}
|
||||
|
||||
void AutoHideDockContainer::moveToNewSideBarLocation(SideBarLocation newSideBarLocation, int index)
|
||||
{
|
||||
if (newSideBarLocation == sideBarLocation() && index == tabIndex())
|
||||
return;
|
||||
|
||||
auto oldOrientation = orientation();
|
||||
auto sideBar = dockContainer()->autoHideSideBar(newSideBarLocation);
|
||||
sideBar->addAutoHideWidget(this, index);
|
||||
// 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 stretched dock widget after insertion.
|
||||
if (sideBar->orientation() != oldOrientation)
|
||||
resetToInitialDockWidgetSize();
|
||||
}
|
||||
|
||||
int AutoHideDockContainer::tabIndex() const
|
||||
{
|
||||
return d->m_sideTab->tabIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the object given in ancestor is an ancestor of the object given in descendant
|
||||
*/
|
||||
|
@@ -66,7 +66,7 @@ public:
|
||||
/**
|
||||
* Get's the side tab bar
|
||||
*/
|
||||
AutoHideSideBar *sideBar() const;
|
||||
AutoHideSideBar *autoHideSideBar() const;
|
||||
|
||||
/**
|
||||
* Returns the side tab
|
||||
@@ -137,6 +137,32 @@ public:
|
||||
* Depending on the sidebar location this will set the width or height of this auto hide container.
|
||||
*/
|
||||
void setSize(int size);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
/**
|
||||
* 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 index = -1);
|
||||
|
||||
/**
|
||||
* Returns the index of this container in the sidebar.
|
||||
*/
|
||||
int tabIndex() const;
|
||||
};
|
||||
|
||||
} // namespace ADS
|
||||
|
@@ -147,6 +147,7 @@ void AutoHideSideBar::insertTab(int index, AutoHideTab *sideTab)
|
||||
{
|
||||
sideTab->setSideBar(this);
|
||||
sideTab->installEventFilter(this);
|
||||
// Default insertion is append
|
||||
if (index < 0)
|
||||
d->m_tabsLayout->insertWidget(d->m_tabsLayout->count() - 1, sideTab);
|
||||
else
|
||||
@@ -177,19 +178,28 @@ void AutoHideSideBar::removeAutoHideWidget(AutoHideDockContainer *autoHideWidget
|
||||
autoHideWidget->setParent(nullptr);
|
||||
}
|
||||
|
||||
void AutoHideSideBar::addAutoHideWidget(AutoHideDockContainer *autoHideWidget)
|
||||
void AutoHideSideBar::addAutoHideWidget(AutoHideDockContainer *autoHideWidget, int index)
|
||||
{
|
||||
auto sideBar = autoHideWidget->autoHideTab()->sideBar();
|
||||
if (sideBar == this)
|
||||
if (sideBar == this) {
|
||||
// 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() == index || (autoHideWidget->tabIndex() + 1) == index)
|
||||
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() < index)
|
||||
--index;
|
||||
}
|
||||
|
||||
if (sideBar)
|
||||
sideBar->removeAutoHideWidget(autoHideWidget);
|
||||
|
||||
autoHideWidget->setParent(d->m_containerWidget);
|
||||
autoHideWidget->setSideBarLocation(d->m_sideTabArea);
|
||||
d->m_containerWidget->registerAutoHideWidget(autoHideWidget);
|
||||
insertTab(-1, autoHideWidget->autoHideTab());
|
||||
insertTab(index, autoHideWidget->autoHideTab());
|
||||
}
|
||||
|
||||
void AutoHideSideBar::removeTab(AutoHideTab *sideTab)
|
||||
@@ -228,33 +238,73 @@ Qt::Orientation AutoHideSideBar::orientation() const
|
||||
return d->m_orientation;
|
||||
}
|
||||
|
||||
AutoHideTab *AutoHideSideBar::tabAt(int index) const
|
||||
AutoHideTab *AutoHideSideBar::tab(int index) const
|
||||
{
|
||||
return qobject_cast<AutoHideTab *>(d->m_tabsLayout->itemAt(index)->widget());
|
||||
}
|
||||
|
||||
int AutoHideSideBar::tabCount() const
|
||||
int AutoHideSideBar::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 AutoHideSideBar::tabInsertIndexAt(const QPoint &pos) const
|
||||
{
|
||||
int index = tabAt(pos);
|
||||
if (index == TabInvalidIndex)
|
||||
return TabDefaultInsertIndex;
|
||||
else
|
||||
return (index < 0) ? 0 : index;
|
||||
}
|
||||
|
||||
int AutoHideSideBar::indexOfTab(const AutoHideTab &autoHideTab) const
|
||||
{
|
||||
for (auto i = 0; i < count(); i++) {
|
||||
if (tab(i) == &autoHideTab)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int AutoHideSideBar::count() const
|
||||
{
|
||||
return d->m_tabsLayout->count() - 1;
|
||||
}
|
||||
|
||||
int AutoHideSideBar::visibleTabCount() const
|
||||
{
|
||||
int count = 0;
|
||||
int c = 0;
|
||||
auto parent = parentWidget();
|
||||
for (auto i = 0; i < tabCount(); i++) {
|
||||
if (tabAt(i)->isVisibleTo(parent))
|
||||
count++;
|
||||
for (auto i = 0; i < count(); i++) {
|
||||
if (tab(i)->isVisibleTo(parent))
|
||||
c++;
|
||||
}
|
||||
|
||||
return count;
|
||||
return c;
|
||||
}
|
||||
|
||||
bool AutoHideSideBar::hasVisibleTabs() const
|
||||
{
|
||||
auto parent = parentWidget();
|
||||
for (auto i = 0; i < tabCount(); i++) {
|
||||
if (tabAt(i)->isVisibleTo(parent))
|
||||
for (auto i = 0; i < count(); i++) {
|
||||
if (tab(i)->isVisibleTo(parent))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -268,19 +318,19 @@ SideBarLocation AutoHideSideBar::sideBarLocation() const
|
||||
|
||||
void AutoHideSideBar::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) {
|
||||
auto tab = tabAt(i);
|
||||
if (!tab)
|
||||
for (auto i = 0; i < count(); ++i) {
|
||||
auto currentTab = tab(i);
|
||||
if (!currentTab)
|
||||
continue;
|
||||
|
||||
tab->dockWidget()->autoHideDockContainer()->saveState(s);
|
||||
currentTab->dockWidget()->autoHideDockContainer()->saveState(s);
|
||||
}
|
||||
|
||||
s.writeEndElement();
|
||||
|
@@ -91,7 +91,7 @@ public:
|
||||
* Adds the given AutoHideWidget to this sidebar. If the AutoHideWidget is in another sidebar,
|
||||
* then it will be removed from this sidebar.
|
||||
*/
|
||||
void addAutoHideWidget(AutoHideDockContainer *autoHideWidget);
|
||||
void addAutoHideWidget(AutoHideDockContainer *autoHideWidget, int index = TabDefaultInsertIndex);
|
||||
|
||||
/**
|
||||
* Returns orientation of side tab.
|
||||
@@ -101,12 +101,29 @@ public:
|
||||
/**
|
||||
* Get the side tab widget at position, returns nullptr if it's out of bounds.
|
||||
*/
|
||||
AutoHideTab *tabAt(int index) const;
|
||||
AutoHideTab *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 AutoHideTab &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.
|
||||
|
@@ -6,14 +6,22 @@
|
||||
#include "ads_globals_p.h"
|
||||
#include "autohidedockcontainer.h"
|
||||
#include "autohidesidebar.h"
|
||||
#include "dockareawidget.h"
|
||||
#include "dockmanager.h"
|
||||
#include "dockoverlay.h"
|
||||
#include "dockwidget.h"
|
||||
#include "floatingdragpreview.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QBoxLayout>
|
||||
#include <QContextMenuEvent>
|
||||
#include <QElapsedTimer>
|
||||
#include <QMenu>
|
||||
|
||||
namespace ADS {
|
||||
|
||||
static const char *const g_locationProperty = "Location";
|
||||
|
||||
/**
|
||||
* Private data class of CDockWidgetTab class (pimpl)
|
||||
*/
|
||||
@@ -24,6 +32,12 @@ struct AutoHideTabPrivate
|
||||
AutoHideSideBar *m_sideBar = nullptr;
|
||||
Qt::Orientation m_orientation{Qt::Vertical};
|
||||
QElapsedTimer m_timeSinceHoverMousePress;
|
||||
bool m_mousePressed = false;
|
||||
eDragState m_dragState = DraggingInactive;
|
||||
QPoint m_globalDragStartMousePosition;
|
||||
QPoint m_dragStartMousePosition;
|
||||
AbstractFloatingWidget *m_floatingWidget = nullptr;
|
||||
Qt::Orientation m_dragStartOrientation;
|
||||
|
||||
/**
|
||||
* Private data constructor
|
||||
@@ -52,6 +66,48 @@ struct AutoHideTabPrivate
|
||||
if (container)
|
||||
container->handleAutoHideWidgetEvent(event, q);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, q, &AutoHideTab::onAutoHideToActionClicked);
|
||||
action->setEnabled(location != q->sideBarLocation());
|
||||
return action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test function for current drag state.
|
||||
*/
|
||||
bool isDraggingState(eDragState dragState) const { return m_dragState == dragState; }
|
||||
|
||||
/**
|
||||
* Saves the drag start position in global and local coordinates.
|
||||
*/
|
||||
void saveDragStartMousePosition(const QPoint &globalPos)
|
||||
{
|
||||
m_globalDragStartMousePosition = globalPos;
|
||||
m_dragStartMousePosition = q->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>
|
||||
AbstractFloatingWidget *createFloatingWidget(T *widget)
|
||||
{
|
||||
auto w = new FloatingDragPreview(widget);
|
||||
q->connect(w, &FloatingDragPreview::draggingCanceled, [=]() {
|
||||
m_dragState = DraggingInactive;
|
||||
});
|
||||
return w;
|
||||
}
|
||||
}; // struct DockWidgetTabPrivate
|
||||
|
||||
AutoHideTabPrivate::AutoHideTabPrivate(AutoHideTab *parent)
|
||||
@@ -71,25 +127,47 @@ void AutoHideTabPrivate::updateOrientation()
|
||||
}
|
||||
}
|
||||
|
||||
void AutoHideTab::setSideBar(AutoHideSideBar *sideTabBar)
|
||||
bool AutoHideTabPrivate::startFloating(eDragState draggingState)
|
||||
{
|
||||
d->m_sideBar = sideTabBar;
|
||||
if (d->m_sideBar)
|
||||
d->updateOrientation();
|
||||
auto dockArea = m_dockWidget->dockAreaWidget();
|
||||
qCInfo(adsLog) << Q_FUNC_INFO << "isFloating " << dockContainer()->isFloating();
|
||||
|
||||
m_dragState = draggingState;
|
||||
AbstractFloatingWidget *floatingWidget = nullptr;
|
||||
floatingWidget = createFloatingWidget(dockArea);
|
||||
auto size = dockArea->size();
|
||||
auto startPos = m_dragStartMousePosition;
|
||||
auto autoHideContainer = m_dockWidget->autoHideDockContainer();
|
||||
m_dragStartOrientation = autoHideContainer->orientation();
|
||||
|
||||
switch (m_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, q);
|
||||
auto dockManager = m_dockWidget->dockManager();
|
||||
auto overlay = dockManager->containerOverlay();
|
||||
overlay->setAllowedAreas(OuterDockAreas);
|
||||
m_floatingWidget = floatingWidget;
|
||||
qApp->postEvent(m_dockWidget, new QEvent((QEvent::Type) internal::g_dockedWidgetDragStartEvent));
|
||||
|
||||
AutoHideSideBar *AutoHideTab::sideBar() const
|
||||
{
|
||||
return d->m_sideBar;
|
||||
}
|
||||
|
||||
void AutoHideTab::removeFromSideBar()
|
||||
{
|
||||
if (d->m_sideBar == nullptr)
|
||||
return;
|
||||
|
||||
d->m_sideBar->removeTab(this);
|
||||
setSideBar(nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
AutoHideTab::AutoHideTab(QWidget *parent)
|
||||
@@ -164,6 +242,61 @@ void AutoHideTab::setDockWidget(DockWidget *dockWidget)
|
||||
setIcon(d->m_dockWidget->icon());
|
||||
setToolTip(dockWidget->windowTitle());
|
||||
}
|
||||
bool AutoHideTab::iconOnly() const
|
||||
{
|
||||
return DockManager::testAutoHideConfigFlag(DockManager::AutoHideSideBarsIconOnly)
|
||||
&& !icon().isNull();
|
||||
}
|
||||
|
||||
AutoHideSideBar *AutoHideTab::sideBar() const
|
||||
{
|
||||
return d->m_sideBar;
|
||||
}
|
||||
|
||||
int AutoHideTab::tabIndex() const
|
||||
{
|
||||
if (!d->m_sideBar)
|
||||
return -1;
|
||||
|
||||
return d->m_sideBar->indexOfTab(*this);
|
||||
}
|
||||
|
||||
void AutoHideTab::setDockWidgetFloating()
|
||||
{
|
||||
d->m_dockWidget->setFloating();
|
||||
}
|
||||
|
||||
void AutoHideTab::unpinDockWidget()
|
||||
{
|
||||
d->m_dockWidget->setAutoHide(false);
|
||||
}
|
||||
|
||||
void AutoHideTab::requestCloseDockWidget()
|
||||
{
|
||||
d->m_dockWidget->requestCloseDockWidget();
|
||||
}
|
||||
|
||||
void AutoHideTab::onAutoHideToActionClicked()
|
||||
{
|
||||
int location = sender()->property(g_locationProperty).toInt();
|
||||
d->m_dockWidget->setAutoHide(true, (SideBarLocation) location);
|
||||
}
|
||||
|
||||
void AutoHideTab::setSideBar(AutoHideSideBar *sideTabBar)
|
||||
{
|
||||
d->m_sideBar = sideTabBar;
|
||||
if (d->m_sideBar)
|
||||
d->updateOrientation();
|
||||
}
|
||||
|
||||
void AutoHideTab::removeFromSideBar()
|
||||
{
|
||||
if (d->m_sideBar == nullptr)
|
||||
return;
|
||||
|
||||
d->m_sideBar->removeTab(this);
|
||||
setSideBar(nullptr);
|
||||
}
|
||||
|
||||
bool AutoHideTab::event(QEvent *event)
|
||||
{
|
||||
@@ -194,10 +327,138 @@ bool AutoHideTab::event(QEvent *event)
|
||||
return Super::event(event);
|
||||
}
|
||||
|
||||
bool AutoHideTab::iconOnly() const
|
||||
void AutoHideTab::contextMenuEvent(QContextMenuEvent *event)
|
||||
{
|
||||
return DockManager::testAutoHideConfigFlag(DockManager::AutoHideSideBarsIconOnly)
|
||||
&& !icon().isNull();
|
||||
event->accept();
|
||||
d->saveDragStartMousePosition(event->globalPos());
|
||||
|
||||
const bool isFloatable = d->m_dockWidget->features().testFlag(DockWidget::DockWidgetFloatable);
|
||||
QMenu menu(this);
|
||||
|
||||
QAction *detachAction = menu.addAction(tr("Detach"));
|
||||
detachAction->connect(detachAction,
|
||||
&QAction::triggered,
|
||||
this,
|
||||
&AutoHideTab::setDockWidgetFloating);
|
||||
detachAction->setEnabled(isFloatable);
|
||||
|
||||
auto isPinnable = d->m_dockWidget->features().testFlag(DockWidget::DockWidgetPinnable);
|
||||
detachAction->setEnabled(isPinnable);
|
||||
|
||||
auto pinToMenu = menu.addMenu(tr("Pin To..."));
|
||||
pinToMenu->setEnabled(isPinnable);
|
||||
d->createAutoHideToAction(tr("Top"), SideBarTop, pinToMenu);
|
||||
d->createAutoHideToAction(tr("Left"), SideBarLeft, pinToMenu);
|
||||
d->createAutoHideToAction(tr("Right"), SideBarRight, pinToMenu);
|
||||
d->createAutoHideToAction(tr("Bottom"), SideBarBottom, pinToMenu);
|
||||
|
||||
QAction *unpinAction = menu.addAction(tr("Unpin (Dock)"));
|
||||
unpinAction->connect(unpinAction, &QAction::triggered, this, &AutoHideTab::unpinDockWidget);
|
||||
menu.addSeparator();
|
||||
QAction *closeAction = menu.addAction(tr("Close"));
|
||||
closeAction->connect(closeAction,
|
||||
&QAction::triggered,
|
||||
this,
|
||||
&AutoHideTab::requestCloseDockWidget);
|
||||
closeAction->setEnabled(d->m_dockWidget->features().testFlag(DockWidget::DockWidgetClosable));
|
||||
|
||||
menu.exec(event->globalPos());
|
||||
}
|
||||
|
||||
void AutoHideTab::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
// 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->m_timeSinceHoverMousePress.restart();
|
||||
d->forwardEventToDockContainer(event);
|
||||
} else if (d->m_timeSinceHoverMousePress.hasExpired(500)) {
|
||||
d->forwardEventToDockContainer(event);
|
||||
}
|
||||
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
event->accept();
|
||||
d->m_mousePressed = true;
|
||||
d->saveDragStartMousePosition(event->globalPosition().toPoint());
|
||||
d->m_dragState = DraggingMousePressed;
|
||||
}
|
||||
|
||||
Super::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void AutoHideTab::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
d->m_mousePressed = false;
|
||||
auto currentDragState = d->m_dragState;
|
||||
d->m_globalDragStartMousePosition = QPoint();
|
||||
d->m_dragStartMousePosition = QPoint();
|
||||
d->m_dragState = DraggingInactive;
|
||||
|
||||
switch (currentDragState) {
|
||||
case DraggingTab:
|
||||
// End of tab moving, emit signal
|
||||
//if (d->DockArea) {
|
||||
// event->accept();
|
||||
// Q_EMIT moved(internal::globalPositionOf(event));
|
||||
//}
|
||||
break;
|
||||
|
||||
case DraggingFloatingWidget:
|
||||
event->accept();
|
||||
d->m_floatingWidget->finishDragging();
|
||||
if (d->m_dockWidget->isAutoHide() && d->m_dragStartOrientation != orientation())
|
||||
d->m_dockWidget->autoHideDockContainer()->resetToInitialDockWidgetSize();
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break; // do nothing
|
||||
}
|
||||
}
|
||||
|
||||
Super::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void AutoHideTab::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if (!(event->buttons() & Qt::LeftButton) || d->isDraggingState(DraggingInactive)) {
|
||||
d->m_dragState = DraggingInactive;
|
||||
Super::mouseMoveEvent(event);
|
||||
return;
|
||||
}
|
||||
|
||||
// Move floating window
|
||||
if (d->isDraggingState(DraggingFloatingWidget)) {
|
||||
d->m_floatingWidget->moveFloating();
|
||||
Super::mouseMoveEvent(event);
|
||||
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(event->pos());
|
||||
bool mouseOutsideBar = (mappedPos.x() < 0) || (mappedPos.x() > parentWidget()->rect().right());
|
||||
// Maybe a fixed drag distance is better here ?
|
||||
int dragDistanceY = qAbs(d->m_globalDragStartMousePosition.y()
|
||||
- event->globalPosition().toPoint().y());
|
||||
if (dragDistanceY >= DockManager::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->m_dockWidget->features();
|
||||
if (Features.testFlag(DockWidget::DockWidgetFloatable)
|
||||
|| (Features.testFlag(DockWidget::DockWidgetMovable))) {
|
||||
d->startFloating();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Super::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
} // namespace ADS
|
||||
|
@@ -38,10 +38,16 @@ private:
|
||||
friend class DockContainerWidget;
|
||||
friend DockContainerWidgetPrivate;
|
||||
|
||||
void onAutoHideToActionClicked();
|
||||
|
||||
protected:
|
||||
void setSideBar(AutoHideSideBar *sideTabBar);
|
||||
void removeFromSideBar();
|
||||
virtual bool event(QEvent *event) override;
|
||||
virtual void contextMenuEvent(QContextMenuEvent *event) override;
|
||||
virtual void mousePressEvent(QMouseEvent *event) override;
|
||||
virtual void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
virtual void mouseMoveEvent(QMouseEvent *event) override;
|
||||
|
||||
public:
|
||||
using Super = PushButton;
|
||||
@@ -102,6 +108,26 @@ public:
|
||||
* Returns the side bar that contains this tab or a nullptr if the tab is not in a side bar.
|
||||
*/
|
||||
AutoHideSideBar *sideBar() const;
|
||||
|
||||
/**
|
||||
* Returns the index of this tab in the sideBar.
|
||||
*/
|
||||
int tabIndex() const;
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@@ -104,6 +104,75 @@ DockAreaTabBar::~DockAreaTabBar()
|
||||
delete d;
|
||||
}
|
||||
|
||||
void DockAreaTabBar::onTabClicked(DockWidgetTab *sourceTab)
|
||||
{
|
||||
const int index = d->m_tabsLayout->indexOf(sourceTab);
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
setCurrentIndex(index);
|
||||
emit tabBarClicked(index);
|
||||
}
|
||||
|
||||
void DockAreaTabBar::onTabCloseRequested(DockWidgetTab *sourceTab)
|
||||
{
|
||||
const int index = d->m_tabsLayout->indexOf(sourceTab);
|
||||
closeTab(index);
|
||||
}
|
||||
|
||||
void DockAreaTabBar::onCloseOtherTabsRequested(DockWidgetTab *sourceTab)
|
||||
{
|
||||
for (int i = 0; i < count(); ++i) {
|
||||
auto currentTab = tab(i);
|
||||
if (currentTab->isClosable() && !currentTab->isHidden() && currentTab != sourceTab) {
|
||||
// If the dock widget is deleted with the closeTab() call, its tab it will no longer
|
||||
// be in the layout, and thus the index needs to be updated to not skip any tabs.
|
||||
int offset = currentTab->dockWidget()->features().testFlag(
|
||||
DockWidget::DockWidgetDeleteOnClose)
|
||||
? 1
|
||||
: 0;
|
||||
closeTab(i);
|
||||
// If the the dock widget blocks closing, i.e. if the flag CustomCloseHandling is set,
|
||||
// and the dock widget is still open, then we do not need to correct the index.
|
||||
if (currentTab->dockWidget()->isClosed())
|
||||
i -= offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DockAreaTabBar::onTabWidgetMoved(DockWidgetTab *sourceTab, const QPoint &globalPosition)
|
||||
{
|
||||
const int fromIndex = d->m_tabsLayout->indexOf(sourceTab);
|
||||
auto mousePos = mapFromGlobal(globalPosition);
|
||||
mousePos.rx() = qMax(d->firstTab()->geometry().left(), mousePos.x());
|
||||
mousePos.rx() = qMin(d->lastTab()->geometry().right(), mousePos.x());
|
||||
int toIndex = -1;
|
||||
// Find tab under mouse
|
||||
for (int i = 0; i < count(); ++i) {
|
||||
DockWidgetTab *dropTab = tab(i);
|
||||
if (dropTab == sourceTab || !dropTab->isVisibleTo(this)
|
||||
|| !dropTab->geometry().contains(mousePos))
|
||||
continue;
|
||||
|
||||
toIndex = d->m_tabsLayout->indexOf(dropTab);
|
||||
if (toIndex == fromIndex)
|
||||
toIndex = -1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (toIndex > -1) {
|
||||
d->m_tabsLayout->removeWidget(sourceTab);
|
||||
d->m_tabsLayout->insertWidget(toIndex, sourceTab);
|
||||
qCInfo(adsLog) << "tabMoved from" << fromIndex << "to" << toIndex;
|
||||
emit tabMoved(fromIndex, toIndex);
|
||||
setCurrentIndex(toIndex);
|
||||
} else {
|
||||
// Ensure that the moved tab is reset to its start position
|
||||
d->m_tabsLayout->update();
|
||||
}
|
||||
}
|
||||
|
||||
void DockAreaTabBar::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
event->accept();
|
||||
@@ -114,23 +183,6 @@ void DockAreaTabBar::wheelEvent(QWheelEvent *event)
|
||||
horizontalScrollBar()->setValue(horizontalScrollBar()->value() - 20);
|
||||
}
|
||||
|
||||
void DockAreaTabBar::setCurrentIndex(int index)
|
||||
{
|
||||
if (index == d->m_currentIndex)
|
||||
return;
|
||||
|
||||
if (index < -1 || index > (count() - 1)) {
|
||||
qWarning() << Q_FUNC_INFO << "Invalid index" << index;
|
||||
return;
|
||||
}
|
||||
|
||||
emit currentChanging(index);
|
||||
d->m_currentIndex = index;
|
||||
d->updateTabs();
|
||||
updateGeometry();
|
||||
emit currentChanged(index);
|
||||
}
|
||||
|
||||
int DockAreaTabBar::count() const
|
||||
{
|
||||
// The tab bar contains a stretch item as last item
|
||||
@@ -226,42 +278,6 @@ DockWidgetTab *DockAreaTabBar::currentTab() const
|
||||
return qobject_cast<DockWidgetTab *>(d->m_tabsLayout->itemAt(d->m_currentIndex)->widget());
|
||||
}
|
||||
|
||||
void DockAreaTabBar::onTabClicked(DockWidgetTab *sourceTab)
|
||||
{
|
||||
const int index = d->m_tabsLayout->indexOf(sourceTab);
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
setCurrentIndex(index);
|
||||
emit tabBarClicked(index);
|
||||
}
|
||||
|
||||
void DockAreaTabBar::onTabCloseRequested(DockWidgetTab *sourceTab)
|
||||
{
|
||||
const int index = d->m_tabsLayout->indexOf(sourceTab);
|
||||
closeTab(index);
|
||||
}
|
||||
|
||||
void DockAreaTabBar::onCloseOtherTabsRequested(DockWidgetTab *sourceTab)
|
||||
{
|
||||
for (int i = 0; i < count(); ++i) {
|
||||
auto currentTab = tab(i);
|
||||
if (currentTab->isClosable() && !currentTab->isHidden() && currentTab != sourceTab) {
|
||||
// If the dock widget is deleted with the closeTab() call, its tab it will no longer
|
||||
// be in the layout, and thus the index needs to be updated to not skip any tabs.
|
||||
int offset = currentTab->dockWidget()->features().testFlag(
|
||||
DockWidget::DockWidgetDeleteOnClose)
|
||||
? 1
|
||||
: 0;
|
||||
closeTab(i);
|
||||
// If the the dock widget blocks closing, i.e. if the flag CustomCloseHandling is set,
|
||||
// and the dock widget is still open, then we do not need to correct the index.
|
||||
if (currentTab->dockWidget()->isClosed())
|
||||
i -= offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DockWidgetTab *DockAreaTabBar::tab(int index) const
|
||||
{
|
||||
if (index >= count() || index < 0)
|
||||
@@ -270,49 +286,29 @@ DockWidgetTab *DockAreaTabBar::tab(int index) const
|
||||
return qobject_cast<DockWidgetTab *>(d->m_tabsLayout->itemAt(index)->widget());
|
||||
}
|
||||
|
||||
void DockAreaTabBar::onTabWidgetMoved(DockWidgetTab *sourceTab, const QPoint &globalPosition)
|
||||
int DockAreaTabBar::tabAt(const QPoint &pos) const
|
||||
{
|
||||
const int fromIndex = d->m_tabsLayout->indexOf(sourceTab);
|
||||
auto mousePos = mapFromGlobal(globalPosition);
|
||||
mousePos.rx() = qMax(d->firstTab()->geometry().left(), mousePos.x());
|
||||
mousePos.rx() = qMin(d->lastTab()->geometry().right(), mousePos.x());
|
||||
int toIndex = -1;
|
||||
// Find tab under mouse
|
||||
if (!isVisible())
|
||||
return TabInvalidIndex;
|
||||
|
||||
if (pos.x() < tab(0)->geometry().x())
|
||||
return -1;
|
||||
|
||||
for (int i = 0; i < count(); ++i) {
|
||||
DockWidgetTab *dropTab = tab(i);
|
||||
if (dropTab == sourceTab || !dropTab->isVisibleTo(this)
|
||||
|| !dropTab->geometry().contains(mousePos))
|
||||
continue;
|
||||
|
||||
toIndex = d->m_tabsLayout->indexOf(dropTab);
|
||||
if (toIndex == fromIndex)
|
||||
toIndex = -1;
|
||||
|
||||
break;
|
||||
if (tab(i)->geometry().contains(pos))
|
||||
return i;
|
||||
}
|
||||
|
||||
if (toIndex > -1) {
|
||||
d->m_tabsLayout->removeWidget(sourceTab);
|
||||
d->m_tabsLayout->insertWidget(toIndex, sourceTab);
|
||||
qCInfo(adsLog) << "tabMoved from" << fromIndex << "to" << toIndex;
|
||||
emit tabMoved(fromIndex, toIndex);
|
||||
setCurrentIndex(toIndex);
|
||||
} else {
|
||||
// Ensure that the moved tab is reset to its start position
|
||||
d->m_tabsLayout->update();
|
||||
}
|
||||
return count();
|
||||
}
|
||||
|
||||
void DockAreaTabBar::closeTab(int index)
|
||||
int DockAreaTabBar::tabInsertIndexAt(const QPoint &pos) const
|
||||
{
|
||||
if (index < 0 || index >= count())
|
||||
return;
|
||||
|
||||
auto dockWidgetTab = tab(index);
|
||||
if (dockWidgetTab->isHidden())
|
||||
return;
|
||||
|
||||
emit tabCloseRequested(index);
|
||||
int index = tabAt(pos);
|
||||
if (index == TabInvalidIndex)
|
||||
return TabDefaultInsertIndex;
|
||||
else
|
||||
return (index < 0) ? 0 : index;
|
||||
}
|
||||
|
||||
bool DockAreaTabBar::eventFilter(QObject *watched, QEvent *event)
|
||||
@@ -362,4 +358,33 @@ QSize DockAreaTabBar::sizeHint() const
|
||||
return d->m_tabsContainerWidget->sizeHint();
|
||||
}
|
||||
|
||||
void DockAreaTabBar::setCurrentIndex(int index)
|
||||
{
|
||||
if (index == d->m_currentIndex)
|
||||
return;
|
||||
|
||||
if (index < -1 || index > (count() - 1)) {
|
||||
qWarning() << Q_FUNC_INFO << "Invalid index" << index;
|
||||
return;
|
||||
}
|
||||
|
||||
emit currentChanging(index);
|
||||
d->m_currentIndex = index;
|
||||
d->updateTabs();
|
||||
updateGeometry();
|
||||
emit currentChanged(index);
|
||||
}
|
||||
|
||||
void DockAreaTabBar::closeTab(int index)
|
||||
{
|
||||
if (index < 0 || index >= count())
|
||||
return;
|
||||
|
||||
auto dockWidgetTab = tab(index);
|
||||
if (dockWidgetTab->isHidden())
|
||||
return;
|
||||
|
||||
emit tabCloseRequested(index);
|
||||
}
|
||||
|
||||
} // namespace ADS
|
||||
|
@@ -86,6 +86,18 @@ public:
|
||||
*/
|
||||
DockWidgetTab *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
|
||||
*/
|
||||
|
@@ -44,10 +44,10 @@ class DockAreaTitleBarPrivate
|
||||
{
|
||||
public:
|
||||
DockAreaTitleBar *q;
|
||||
QPointer<TitleBarButtonType> m_tabsMenuButton;
|
||||
QPointer<TitleBarButtonType> m_autoHideButton;
|
||||
QPointer<TitleBarButtonType> m_undockButton;
|
||||
QPointer<TitleBarButtonType> m_closeButton;
|
||||
QPointer<TitleBarButton> m_tabsMenuButton;
|
||||
QPointer<TitleBarButton> m_autoHideButton;
|
||||
QPointer<TitleBarButton> m_undockButton;
|
||||
QPointer<TitleBarButton> m_closeButton;
|
||||
QBoxLayout *m_layout = nullptr;
|
||||
DockAreaWidget *m_dockArea = nullptr;
|
||||
DockAreaTabBar *m_tabBar = nullptr;
|
||||
@@ -306,9 +306,9 @@ void DockAreaTitleBarPrivate::startFloating(const QPoint &offset)
|
||||
qApp->postEvent(m_dockArea, new QEvent((QEvent::Type) internal::g_dockedWidgetDragStartEvent));
|
||||
}
|
||||
|
||||
TitleBarButton::TitleBarButton(bool visible, QWidget *parent)
|
||||
TitleBarButton::TitleBarButton(bool showInTitleBar, QWidget *parent)
|
||||
: TitleBarButtonType(parent)
|
||||
, m_visible(visible)
|
||||
, m_showInTitleBar(showInTitleBar)
|
||||
, m_hideWhenDisabled(
|
||||
DockAreaTitleBarPrivate::testConfigFlag(DockManager::DockAreaHideDisabledButtons))
|
||||
{
|
||||
@@ -317,8 +317,8 @@ TitleBarButton::TitleBarButton(bool visible, QWidget *parent)
|
||||
|
||||
void TitleBarButton::setVisible(bool visible)
|
||||
{
|
||||
// 'visible' can stay 'true' if and only if this button is configured to generaly visible:
|
||||
visible = visible && m_visible;
|
||||
// 'visible' can stay 'true' if and only if this button is configured to generally visible:
|
||||
visible = visible && m_showInTitleBar;
|
||||
|
||||
// 'visible' can stay 'true' unless: this button is configured to be invisible when it
|
||||
// is disabled and it is currently disabled:
|
||||
@@ -328,6 +328,14 @@ void TitleBarButton::setVisible(bool visible)
|
||||
Super::setVisible(visible);
|
||||
}
|
||||
|
||||
void TitleBarButton::setShowInTitleBar(bool show)
|
||||
{
|
||||
m_showInTitleBar = show;
|
||||
|
||||
if (!show)
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
bool TitleBarButton::event(QEvent *event)
|
||||
{
|
||||
if (QEvent::EnabledChange == event->type() && m_hideWhenDisabled) {
|
||||
@@ -524,7 +532,7 @@ void DockAreaTitleBar::onAutoHideToActionClicked()
|
||||
d->m_dockArea->toggleAutoHide((SideBarLocation) location);
|
||||
}
|
||||
|
||||
QAbstractButton *DockAreaTitleBar::button(eTitleBarButton which) const
|
||||
TitleBarButton *DockAreaTitleBar::button(eTitleBarButton which) const
|
||||
{
|
||||
switch (which) {
|
||||
case TitleBarButtonTabsMenu:
|
||||
@@ -733,4 +741,19 @@ QString DockAreaTitleBar::titleBarButtonToolTip(eTitleBarButton button) const
|
||||
return QString();
|
||||
}
|
||||
|
||||
void DockAreaTitleBar::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->m_dockArea->dockContainer();
|
||||
if (dockContainer->isFloating() && dockContainer->dockAreaCount() == 1
|
||||
&& !d->m_dockArea->isAutoHide())
|
||||
return;
|
||||
|
||||
if (!d->m_dockArea->features().testFlag(DockWidget::DockWidgetFloatable))
|
||||
return;
|
||||
|
||||
d->makeAreaFloating(mapFromGlobal(QCursor::pos()), DraggingInactive);
|
||||
}
|
||||
|
||||
} // namespace ADS
|
||||
|
@@ -30,17 +30,22 @@ using TitleBarButtonType = QToolButton;
|
||||
class TitleBarButton : public TitleBarButtonType
|
||||
{
|
||||
Q_OBJECT
|
||||
bool m_visible = true;
|
||||
bool m_showInTitleBar = true;
|
||||
bool m_hideWhenDisabled = false;
|
||||
public:
|
||||
using Super = TitleBarButtonType;
|
||||
TitleBarButton(bool visible = true, QWidget *parent = nullptr);
|
||||
TitleBarButton(bool showInTitleBar = true, QWidget *parent = nullptr);
|
||||
|
||||
/**
|
||||
* Adjust this visibility change request with our internal settings:
|
||||
*/
|
||||
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
|
||||
@@ -139,7 +144,7 @@ public:
|
||||
/**
|
||||
* Returns the button corresponding to the given title bar button identifier
|
||||
*/
|
||||
QAbstractButton *button(eTitleBarButton which) const;
|
||||
TitleBarButton *button(eTitleBarButton which) const;
|
||||
|
||||
/**
|
||||
* Returns the auto hide title label, used when the dock area is expanded and auto hidden
|
||||
@@ -181,6 +186,11 @@ public:
|
||||
*/
|
||||
QString titleBarButtonToolTip(eTitleBarButton button) const;
|
||||
|
||||
/**
|
||||
* Moves the dock area into its own floating widget if the area DockWidgetFloatable flag is true.
|
||||
*/
|
||||
void setAreaFloating();
|
||||
|
||||
signals:
|
||||
/**
|
||||
* This signal is emitted if a tab in the tab bar is clicked by the user
|
||||
|
@@ -374,6 +374,7 @@ void DockAreaWidget::setAutoHideDockContainer(AutoHideDockContainer *autoHideDoc
|
||||
d->m_autoHideDockContainer = autoHideDockContainer;
|
||||
updateAutoHideButtonCheckState();
|
||||
updateTitleBarButtonsToolTips();
|
||||
d->m_titleBar->button(TitleBarButtonAutoHide)->setShowInTitleBar(true);
|
||||
}
|
||||
|
||||
void DockAreaWidget::addDockWidget(DockWidget *dockWidget)
|
||||
@@ -504,12 +505,7 @@ void DockAreaWidget::hideAreaWithNoVisibleContent()
|
||||
void DockAreaWidget::onTabCloseRequested(int index)
|
||||
{
|
||||
qCInfo(adsLog) << Q_FUNC_INFO << "index" << index;
|
||||
auto *currentDockWidget = dockWidget(index);
|
||||
if (currentDockWidget->features().testFlag(DockWidget::DockWidgetDeleteOnClose)
|
||||
|| currentDockWidget->features().testFlag(DockWidget::CustomCloseHandling))
|
||||
currentDockWidget->closeDockWidgetInternal();
|
||||
else
|
||||
currentDockWidget->toggleView(false);
|
||||
dockWidget(index)->requestCloseDockWidget();
|
||||
}
|
||||
|
||||
DockWidget *DockAreaWidget::currentDockWidget() const
|
||||
@@ -1075,27 +1071,33 @@ SideBarLocation DockAreaWidget::calculateSideTabBarArea() const
|
||||
return sideTab;
|
||||
}
|
||||
|
||||
void DockAreaWidget::setAutoHide(bool enable, SideBarLocation location)
|
||||
void DockAreaWidget::setAutoHide(bool enable, SideBarLocation location, int tabIndex)
|
||||
{
|
||||
if (!isAutoHideFeatureEnabled())
|
||||
return;
|
||||
|
||||
if (!enable) {
|
||||
if (isAutoHide())
|
||||
autoHideDockContainer()->moveContentsToParent();
|
||||
d->m_autoHideDockContainer->moveContentsToParent();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// If this is already an auto hide container, then move it to new location.
|
||||
if (isAutoHide()) {
|
||||
d->m_autoHideDockContainer->moveToNewSideBarLocation(location, tabIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
auto area = (SideBarNone == location) ? calculateSideTabBarArea() : location;
|
||||
for (const auto DockWidget : openedDockWidgets()) {
|
||||
for (const auto dockWidget : openedDockWidgets()) {
|
||||
if (enable == isAutoHide())
|
||||
continue;
|
||||
|
||||
if (!DockWidget->features().testFlag(DockWidget::DockWidgetPinnable))
|
||||
if (!dockWidget->features().testFlag(DockWidget::DockWidgetPinnable))
|
||||
continue;
|
||||
|
||||
dockContainer()->createAndSetupAutoHideContainer(area, DockWidget);
|
||||
dockContainer()->createAndSetupAutoHideContainer(area, dockWidget, tabIndex++);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1112,6 +1114,11 @@ void DockAreaWidget::closeOtherAreas()
|
||||
dockContainer()->closeOtherAreas(this);
|
||||
}
|
||||
|
||||
void DockAreaWidget::setFloating()
|
||||
{
|
||||
d->m_titleBar->setAreaFloating();
|
||||
}
|
||||
|
||||
DockAreaTitleBar *DockAreaWidget::titleBar() const
|
||||
{
|
||||
return d->m_titleBar;
|
||||
|
@@ -369,7 +369,7 @@ public:
|
||||
* 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
|
||||
@@ -382,6 +382,11 @@ public:
|
||||
*/
|
||||
void closeOtherAreas();
|
||||
|
||||
/**
|
||||
* Moves the dock area into its own floating widget if the area DockWidgetFloatable flag is true.
|
||||
*/
|
||||
void setFloating();
|
||||
|
||||
signals:
|
||||
/**
|
||||
* This signal is emitted when user clicks on a tab at an index.
|
||||
|
@@ -84,7 +84,7 @@ public:
|
||||
QList<AutoHideDockContainer *> m_autoHideWidgets;
|
||||
QMap<SideBarLocation, AutoHideSideBar *> m_sideTabBarWidgets;
|
||||
QGridLayout *m_layout = nullptr;
|
||||
QSplitter *m_rootSplitter = nullptr;
|
||||
DockSplitter *m_rootSplitter = nullptr;
|
||||
bool m_isFloating = false;
|
||||
DockAreaWidget *m_lastAddedAreaCache[5];
|
||||
int m_visibleDockAreaCount = -1;
|
||||
@@ -122,34 +122,51 @@ public:
|
||||
*/
|
||||
void dropIntoContainer(FloatingDockContainer *floatingWidget, DockWidgetArea area);
|
||||
|
||||
/**
|
||||
* Drop floating widget into auto hide side bar
|
||||
*/
|
||||
void dropIntoAutoHideSideBar(FloatingDockContainer *floatingWidget, DockWidgetArea area);
|
||||
|
||||
/**
|
||||
* Creates a new tab for a widget dropped into the center of a section
|
||||
*/
|
||||
void dropIntoCenterOfSection(FloatingDockContainer *floatingWidget,
|
||||
DockAreaWidget *targetArea,
|
||||
int tabIndex);
|
||||
|
||||
/**
|
||||
* Drop floating widget into dock area
|
||||
*/
|
||||
void dropIntoSection(FloatingDockContainer *floatingWidget,
|
||||
DockAreaWidget *targetArea,
|
||||
DockWidgetArea area);
|
||||
DockWidgetArea area,
|
||||
int tabIndex = 0);
|
||||
|
||||
/**
|
||||
* Moves the dock widget or dock area given in Widget parameter to a
|
||||
* new dock widget area
|
||||
* Moves the dock widget or dock area given in Widget parameter to a new dock widget area.
|
||||
*/
|
||||
void moveToNewSection(QWidget *widget, DockAreaWidget *targetArea, DockWidgetArea area);
|
||||
void moveToNewSection(QWidget *widget,
|
||||
DockAreaWidget *targetArea,
|
||||
DockWidgetArea area,
|
||||
int tabIndex = 0);
|
||||
|
||||
/**
|
||||
* Moves the dock widget or dock area given in Widget parameter to a
|
||||
* a dock area in container
|
||||
* Moves the dock widget or dock area given in Widget parameter to a dock area in container.
|
||||
*/
|
||||
void moveToContainer(QWidget *widget, DockWidgetArea area);
|
||||
|
||||
/**
|
||||
* Creates a new tab for a widget dropped into the center of a section
|
||||
*/
|
||||
void dropIntoCenterOfSection(FloatingDockContainer *floatingWidget, DockAreaWidget *targetArea);
|
||||
void moveIntoCenterOfSection(QWidget *widget, DockAreaWidget *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, DockAreaWidget *targetArea);
|
||||
void moveToAutoHideSideBar(QWidget *widget,
|
||||
DockWidgetArea area,
|
||||
int tabIndex = TabDefaultInsertIndex);
|
||||
|
||||
/**
|
||||
* Adds new dock areas to the internal dock area list
|
||||
@@ -371,12 +388,12 @@ void DockContainerWidgetPrivate::dropIntoContainer(FloatingDockContainer *floati
|
||||
auto newDockAreas
|
||||
= floatingDockContainer->findChildren<DockAreaWidget *>(QString(),
|
||||
Qt::FindChildrenRecursively);
|
||||
QSplitter *splitter = m_rootSplitter;
|
||||
auto *splitter = m_rootSplitter;
|
||||
|
||||
if (m_dockAreas.count() <= 1) {
|
||||
splitter->setOrientation(insertParam.orientation());
|
||||
} else if (splitter->orientation() != insertParam.orientation()) {
|
||||
QSplitter *newSplitter = createSplitter(insertParam.orientation());
|
||||
auto *newSplitter = createSplitter(insertParam.orientation());
|
||||
QLayoutItem *layoutItem = m_layout->replaceWidget(splitter, newSplitter);
|
||||
newSplitter->addWidget(splitter);
|
||||
updateSplitterHandles(newSplitter);
|
||||
@@ -411,42 +428,58 @@ void DockContainerWidgetPrivate::dropIntoContainer(FloatingDockContainer *floati
|
||||
q->dumpLayout();
|
||||
}
|
||||
|
||||
void DockContainerWidgetPrivate::dropIntoAutoHideSideBar(FloatingDockContainer *floatingWidget,
|
||||
DockWidgetArea area)
|
||||
{
|
||||
auto sideBarLocation = internal::toSideBarLocation(area);
|
||||
auto newDockAreas = floatingWidget->findChildren<DockAreaWidget *>(QString(),
|
||||
Qt::FindChildrenRecursively);
|
||||
int tabIndex = m_dockManager->containerOverlay()->tabIndexUnderCursor();
|
||||
for (auto dockArea : newDockAreas) {
|
||||
auto dockWidgets = dockArea->dockWidgets();
|
||||
for (auto dockWidget : dockWidgets)
|
||||
q->createAndSetupAutoHideContainer(sideBarLocation, dockWidget, tabIndex++);
|
||||
}
|
||||
}
|
||||
|
||||
void DockContainerWidgetPrivate::dropIntoCenterOfSection(FloatingDockContainer *floatingWidget,
|
||||
DockAreaWidget *targetArea)
|
||||
DockAreaWidget *targetArea,
|
||||
int tabIndex)
|
||||
{
|
||||
DockContainerWidget *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
|
||||
// dock widget in the drop area.
|
||||
// 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 dock widget in the drop area.
|
||||
if (topLevelDockArea)
|
||||
newCurrentIndex = topLevelDockArea->currentIndex();
|
||||
|
||||
for (int i = 0; i < newDockWidgets.count(); ++i) {
|
||||
DockWidget *dockWidget = newDockWidgets[i];
|
||||
targetArea->insertDockWidget(tabIndex + i, dockWidget, false);
|
||||
targetArea->insertDockWidget(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.
|
||||
// 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.
|
||||
if (newCurrentIndex < 0 && !dockWidget->isClosed())
|
||||
newCurrentIndex = i;
|
||||
}
|
||||
targetArea->setCurrentIndex(newCurrentIndex);
|
||||
targetArea->setCurrentIndex(newCurrentIndex + tabIndex);
|
||||
targetArea->updateTitleBarVisibility();
|
||||
return;
|
||||
}
|
||||
|
||||
void DockContainerWidgetPrivate::dropIntoSection(FloatingDockContainer *floatingWidget,
|
||||
DockAreaWidget *targetArea,
|
||||
DockWidgetArea area)
|
||||
DockWidgetArea area,
|
||||
int tabIndex)
|
||||
{
|
||||
// Dropping into center means all dock widgets in the dropped floating
|
||||
// widget will become tabs of the drop area
|
||||
// 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;
|
||||
}
|
||||
|
||||
@@ -525,44 +558,15 @@ void DockContainerWidgetPrivate::dropIntoSection(FloatingDockContainer *floating
|
||||
q->dumpLayout();
|
||||
}
|
||||
|
||||
void DockContainerWidgetPrivate::moveIntoCenterOfSection(QWidget *widget, DockAreaWidget *targetArea)
|
||||
{
|
||||
auto droppedDockWidget = qobject_cast<DockWidget *>(widget);
|
||||
auto droppedArea = qobject_cast<DockAreaWidget *>(widget);
|
||||
|
||||
if (droppedDockWidget) {
|
||||
DockAreaWidget *oldDockArea = droppedDockWidget->dockAreaWidget();
|
||||
if (oldDockArea == targetArea)
|
||||
return;
|
||||
|
||||
if (oldDockArea)
|
||||
oldDockArea->removeDockWidget(droppedDockWidget);
|
||||
|
||||
targetArea->insertDockWidget(0, droppedDockWidget, true);
|
||||
} else {
|
||||
QList<DockWidget *> newDockWidgets = droppedArea->dockWidgets();
|
||||
int newCurrentIndex = droppedArea->currentIndex();
|
||||
for (int i = 0; i < newDockWidgets.count(); ++i) {
|
||||
DockWidget *dockWidget = newDockWidgets[i];
|
||||
targetArea->insertDockWidget(i, dockWidget, false);
|
||||
}
|
||||
targetArea->setCurrentIndex(newCurrentIndex);
|
||||
droppedArea->dockContainer()->removeDockArea(droppedArea);
|
||||
droppedArea->deleteLater();
|
||||
}
|
||||
|
||||
targetArea->updateTitleBarVisibility();
|
||||
return;
|
||||
}
|
||||
|
||||
void DockContainerWidgetPrivate::moveToNewSection(QWidget *widget,
|
||||
DockAreaWidget *targetArea,
|
||||
DockWidgetArea area)
|
||||
DockWidgetArea area,
|
||||
int tabIndex)
|
||||
{
|
||||
// Dropping into center means all dock widgets in the dropped floating
|
||||
// widget will become tabs of the drop area
|
||||
// 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;
|
||||
}
|
||||
|
||||
@@ -612,31 +616,6 @@ void DockContainerWidgetPrivate::moveToNewSection(QWidget *widget,
|
||||
addDockAreasToList({newDockArea});
|
||||
}
|
||||
|
||||
void DockContainerWidgetPrivate::updateSplitterHandles(QSplitter *splitter)
|
||||
{
|
||||
if (!m_dockManager->centralWidget() || !splitter)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < splitter->count(); ++i)
|
||||
splitter->setStretchFactor(i, widgetResizesWithContainer(splitter->widget(i)) ? 1 : 0);
|
||||
}
|
||||
|
||||
bool DockContainerWidgetPrivate::widgetResizesWithContainer(QWidget *widget)
|
||||
{
|
||||
if (!m_dockManager->centralWidget())
|
||||
return true;
|
||||
|
||||
auto area = qobject_cast<DockAreaWidget *>(widget);
|
||||
if (area)
|
||||
return area->isCentralWidgetArea();
|
||||
|
||||
auto innerSplitter = qobject_cast<DockSplitter *>(widget);
|
||||
if (innerSplitter)
|
||||
return innerSplitter->isResizingWithContainer();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DockContainerWidgetPrivate::moveToContainer(QWidget *widget, DockWidgetArea area)
|
||||
{
|
||||
DockWidget *droppedDockWidget = qobject_cast<DockWidget *>(widget);
|
||||
@@ -671,6 +650,92 @@ void DockContainerWidgetPrivate::moveToContainer(QWidget *widget, DockWidgetArea
|
||||
m_lastAddedAreaCache[areaIdToIndex(area)] = newDockArea;
|
||||
}
|
||||
|
||||
void DockContainerWidgetPrivate::moveIntoCenterOfSection(QWidget *widget,
|
||||
DockAreaWidget *targetArea,
|
||||
int tabIndex)
|
||||
{
|
||||
auto droppedDockWidget = qobject_cast<DockWidget *>(widget);
|
||||
auto droppedArea = qobject_cast<DockAreaWidget *>(widget);
|
||||
tabIndex = qMax(0, tabIndex);
|
||||
|
||||
if (droppedDockWidget) {
|
||||
DockAreaWidget *oldDockArea = droppedDockWidget->dockAreaWidget();
|
||||
if (oldDockArea == targetArea)
|
||||
return;
|
||||
|
||||
if (oldDockArea)
|
||||
oldDockArea->removeDockWidget(droppedDockWidget);
|
||||
|
||||
targetArea->insertDockWidget(tabIndex, droppedDockWidget, true);
|
||||
} else {
|
||||
QList<DockWidget *> newDockWidgets = droppedArea->dockWidgets();
|
||||
int newCurrentIndex = droppedArea->currentIndex();
|
||||
for (int i = 0; i < newDockWidgets.count(); ++i) {
|
||||
DockWidget *dockWidget = newDockWidgets[i];
|
||||
targetArea->insertDockWidget(tabIndex + i, dockWidget, false);
|
||||
}
|
||||
targetArea->setCurrentIndex(tabIndex + newCurrentIndex);
|
||||
droppedArea->dockContainer()->removeDockArea(droppedArea);
|
||||
droppedArea->deleteLater();
|
||||
}
|
||||
|
||||
targetArea->updateTitleBarVisibility();
|
||||
return;
|
||||
}
|
||||
|
||||
void DockContainerWidgetPrivate::moveToAutoHideSideBar(QWidget *widget,
|
||||
DockWidgetArea area,
|
||||
int tabIndex)
|
||||
{
|
||||
DockWidget *droppedDockWidget = qobject_cast<DockWidget *>(widget);
|
||||
DockAreaWidget *droppedDockArea = qobject_cast<DockAreaWidget *>(widget);
|
||||
auto sideBarLocation = internal::toSideBarLocation(area);
|
||||
|
||||
if (droppedDockWidget) {
|
||||
if (q == droppedDockWidget->dockContainer())
|
||||
droppedDockWidget->setAutoHide(true, sideBarLocation, tabIndex);
|
||||
else
|
||||
q->createAndSetupAutoHideContainer(sideBarLocation, droppedDockWidget, tabIndex);
|
||||
|
||||
} else {
|
||||
if (q == droppedDockArea->dockContainer()) {
|
||||
droppedDockArea->setAutoHide(true, sideBarLocation, tabIndex);
|
||||
} else {
|
||||
for (const auto dockWidget : droppedDockArea->openedDockWidgets()) {
|
||||
if (!dockWidget->features().testFlag(DockWidget::DockWidgetPinnable))
|
||||
continue;
|
||||
|
||||
q->createAndSetupAutoHideContainer(sideBarLocation, dockWidget, tabIndex++);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DockContainerWidgetPrivate::updateSplitterHandles(QSplitter *splitter)
|
||||
{
|
||||
if (!m_dockManager->centralWidget() || !splitter)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < splitter->count(); ++i)
|
||||
splitter->setStretchFactor(i, widgetResizesWithContainer(splitter->widget(i)) ? 1 : 0);
|
||||
}
|
||||
|
||||
bool DockContainerWidgetPrivate::widgetResizesWithContainer(QWidget *widget)
|
||||
{
|
||||
if (!m_dockManager->centralWidget())
|
||||
return true;
|
||||
|
||||
auto area = qobject_cast<DockAreaWidget *>(widget);
|
||||
if (area)
|
||||
return area->isCentralWidgetArea();
|
||||
|
||||
auto innerSplitter = qobject_cast<DockSplitter *>(widget);
|
||||
if (innerSplitter)
|
||||
return innerSplitter->isResizingWithContainer();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DockContainerWidgetPrivate::addDockAreasToList(const QList<DockAreaWidget *> newDockAreas)
|
||||
{
|
||||
const int countBefore = m_dockAreas.count();
|
||||
@@ -740,7 +805,7 @@ void DockContainerWidgetPrivate::saveChildNodesState(QXmlStreamWriter &stream, Q
|
||||
void DockContainerWidgetPrivate::saveAutoHideWidgetsState(QXmlStreamWriter &s)
|
||||
{
|
||||
for (const auto sideTabBar : m_sideTabBarWidgets.values()) {
|
||||
if (!sideTabBar->tabCount())
|
||||
if (!sideTabBar->count())
|
||||
continue;
|
||||
|
||||
sideTabBar->saveState(s);
|
||||
@@ -896,11 +961,11 @@ bool DockContainerWidgetPrivate::restoreSideBar(DockingStateReader &stateReader,
|
||||
if (!dockWidget || testing)
|
||||
continue;
|
||||
|
||||
auto sideBar = q->sideTabBar(area);
|
||||
auto sideBar = q->autoHideSideBar(area);
|
||||
AutoHideDockContainer *autoHideContainer;
|
||||
if (dockWidget->isAutoHide()) {
|
||||
autoHideContainer = dockWidget->autoHideDockContainer();
|
||||
if (autoHideContainer->sideBar() != sideBar)
|
||||
if (autoHideContainer->autoHideSideBar() != sideBar)
|
||||
sideBar->addAutoHideWidget(autoHideContainer);
|
||||
} else {
|
||||
autoHideContainer = sideBar->insertDockWidget(-1, dockWidget);
|
||||
@@ -931,7 +996,7 @@ void DockContainerWidgetPrivate::addDockArea(DockAreaWidget *newDockArea, DockWi
|
||||
if (m_dockAreas.count() <= 1)
|
||||
m_rootSplitter->setOrientation(insertParam.orientation());
|
||||
|
||||
QSplitter *splitter = m_rootSplitter;
|
||||
auto *splitter = m_rootSplitter;
|
||||
if (splitter->orientation() == insertParam.orientation()) {
|
||||
insertWidgetIntoSplitter(splitter, newDockArea, insertParam.append());
|
||||
updateSplitterHandles(splitter);
|
||||
@@ -939,7 +1004,7 @@ void DockContainerWidgetPrivate::addDockArea(DockAreaWidget *newDockArea, DockWi
|
||||
splitter->show();
|
||||
|
||||
} else {
|
||||
QSplitter *newSplitter = createSplitter(insertParam.orientation());
|
||||
auto *newSplitter = createSplitter(insertParam.orientation());
|
||||
if (insertParam.append()) {
|
||||
QLayoutItem *layoutItem = m_layout->replaceWidget(splitter, newSplitter);
|
||||
newSplitter->addWidget(splitter);
|
||||
@@ -1108,7 +1173,8 @@ DockAreaWidget *DockContainerWidget::addDockWidget(DockWidgetArea area,
|
||||
}
|
||||
|
||||
AutoHideDockContainer *DockContainerWidget::createAndSetupAutoHideContainer(SideBarLocation area,
|
||||
DockWidget *dockWidget)
|
||||
DockWidget *dockWidget,
|
||||
int tabIndex)
|
||||
{
|
||||
if (!DockManager::testAutoHideConfigFlag(DockManager::AutoHideFeatureEnabled)) {
|
||||
Q_ASSERT_X(false,
|
||||
@@ -1121,7 +1187,7 @@ AutoHideDockContainer *DockContainerWidget::createAndSetupAutoHideContainer(Side
|
||||
d->m_dockManager); // Auto hide Dock Container needs a valid dock manager
|
||||
}
|
||||
|
||||
return sideTabBar(area)->insertDockWidget(-1, dockWidget);
|
||||
return autoHideSideBar(area)->insertDockWidget(tabIndex, dockWidget);
|
||||
}
|
||||
|
||||
void DockContainerWidget::removeDockWidget(DockWidget *dockWidget)
|
||||
@@ -1210,7 +1276,7 @@ void DockContainerWidget::removeDockArea(DockAreaWidget *area)
|
||||
}
|
||||
|
||||
QWidget *widget = splitter->widget(0);
|
||||
QSplitter *childSplitter = qobject_cast<QSplitter *>(widget);
|
||||
auto *childSplitter = qobject_cast<DockSplitter *>(widget);
|
||||
// If the one and only content widget of the splitter is not a splitter
|
||||
// then we are finished
|
||||
if (!childSplitter) {
|
||||
@@ -1227,7 +1293,7 @@ void DockContainerWidget::removeDockArea(DockAreaWidget *area)
|
||||
qCInfo(adsLog) << "RootSplitter replaced by child splitter";
|
||||
} else if (splitter->count() == 1) {
|
||||
qCInfo(adsLog) << "Replacing splitter with content";
|
||||
QSplitter *parentSplitter = internal::findParent<QSplitter *>(splitter);
|
||||
auto *parentSplitter = internal::findParent<QSplitter *>(splitter);
|
||||
auto sizes = parentSplitter->sizes();
|
||||
QWidget *widget = splitter->widget(0);
|
||||
widget->setParent(this);
|
||||
@@ -1299,11 +1365,12 @@ void DockContainerWidget::dropFloatingWidget(FloatingDockContainer *floatingWidg
|
||||
qCInfo(adsLog) << Q_FUNC_INFO;
|
||||
DockWidget *singleDroppedDockWidget = floatingWidget->topLevelDockWidget();
|
||||
DockWidget *singleDockWidget = topLevelDockWidget();
|
||||
DockAreaWidget *dockArea = dockAreaAt(targetPosition);
|
||||
auto dropArea = InvalidDockWidgetArea;
|
||||
auto containerDropArea = d->m_dockManager->containerOverlay()->dropAreaUnderCursor();
|
||||
bool dropped = false;
|
||||
|
||||
DockAreaWidget *dockArea = dockAreaAt(targetPosition);
|
||||
// Mouse is over dock area
|
||||
if (dockArea) {
|
||||
auto dropOverlay = d->m_dockManager->dockAreaOverlay();
|
||||
dropOverlay->setAllowedAreas(dockArea->allowedAreas());
|
||||
@@ -1313,24 +1380,27 @@ void DockContainerWidget::dropFloatingWidget(FloatingDockContainer *floatingWidg
|
||||
|
||||
if (dropArea != InvalidDockWidgetArea) {
|
||||
qCInfo(adsLog) << "Dock Area Drop Content: " << dropArea;
|
||||
d->dropIntoSection(floatingWidget, dockArea, dropArea);
|
||||
int tabIndex = d->m_dockManager->dockAreaOverlay()->tabIndexUnderCursor();
|
||||
d->dropIntoSection(floatingWidget, dockArea, dropArea, tabIndex);
|
||||
dropped = true;
|
||||
}
|
||||
}
|
||||
|
||||
// mouse is over container
|
||||
if (InvalidDockWidgetArea == dropArea) {
|
||||
dropArea = containerDropArea;
|
||||
qCInfo(adsLog) << "Container Drop Content: " << dropArea;
|
||||
if (dropArea != InvalidDockWidgetArea) {
|
||||
d->dropIntoContainer(floatingWidget, dropArea);
|
||||
// Mouse is over container or auto hide side bar
|
||||
if (InvalidDockWidgetArea == dropArea && InvalidDockWidgetArea != containerDropArea) {
|
||||
qCInfo(adsLog) << "Container Drop Content: " << containerDropArea;
|
||||
|
||||
if (internal::isSideBarArea(containerDropArea))
|
||||
d->dropIntoAutoHideSideBar(floatingWidget, containerDropArea);
|
||||
else
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -1356,11 +1426,14 @@ void DockContainerWidget::dropFloatingWidget(FloatingDockContainer *floatingWidg
|
||||
|
||||
void DockContainerWidget::dropWidget(QWidget *widget,
|
||||
DockWidgetArea dropArea,
|
||||
DockAreaWidget *targetAreaWidget)
|
||||
DockAreaWidget *targetAreaWidget,
|
||||
int tabIndex)
|
||||
{
|
||||
DockWidget *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
|
||||
d->moveToContainer(widget, dropArea);
|
||||
|
||||
@@ -1466,7 +1539,7 @@ bool DockContainerWidget::restoreState(DockingStateReader &stateReader, bool tes
|
||||
|
||||
d->m_layout->replaceWidget(d->m_rootSplitter, newRootSplitter);
|
||||
QSplitter *oldRoot = d->m_rootSplitter;
|
||||
d->m_rootSplitter = qobject_cast<QSplitter *>(newRootSplitter);
|
||||
d->m_rootSplitter = qobject_cast<DockSplitter *>(newRootSplitter);
|
||||
oldRoot->deleteLater();
|
||||
|
||||
return true;
|
||||
@@ -1621,7 +1694,7 @@ void DockContainerWidget::closeOtherAreas(DockAreaWidget *keepOpenArea)
|
||||
}
|
||||
}
|
||||
|
||||
AutoHideSideBar *DockContainerWidget::sideTabBar(SideBarLocation area) const
|
||||
AutoHideSideBar *DockContainerWidget::autoHideSideBar(SideBarLocation area) const
|
||||
{
|
||||
return d->m_sideTabBarWidgets[area];
|
||||
}
|
||||
@@ -1639,7 +1712,17 @@ QRect DockContainerWidget::contentRectGlobal() const
|
||||
if (!d->m_rootSplitter)
|
||||
return QRect();
|
||||
|
||||
return internal::globalGeometry(d->m_rootSplitter);
|
||||
if (d->m_rootSplitter->hasVisibleContent()) {
|
||||
return d->m_rootSplitter->geometry();
|
||||
} else {
|
||||
auto contentRect = rect();
|
||||
contentRect.adjust(autoHideSideBar(SideBarLeft)->sizeHint().width(),
|
||||
autoHideSideBar(SideBarTop)->sizeHint().height(),
|
||||
-autoHideSideBar(SideBarRight)->sizeHint().width(),
|
||||
-autoHideSideBar(SideBarBottom)->sizeHint().height());
|
||||
|
||||
return contentRect;
|
||||
}
|
||||
}
|
||||
|
||||
DockManager *DockContainerWidget::dockManager() const
|
||||
|
@@ -74,7 +74,8 @@ protected:
|
||||
* Returns nullptr if you try and insert into an area where the configuration is not enabled
|
||||
*/
|
||||
AutoHideDockContainer *createAndSetupAutoHideContainer(SideBarLocation area,
|
||||
DockWidget *dockWidget);
|
||||
DockWidget *dockWidget,
|
||||
int tabIndex = -1);
|
||||
|
||||
/**
|
||||
* Helper function for creation of the root splitter
|
||||
@@ -98,7 +99,10 @@ protected:
|
||||
* a nullptr, then the DropArea indicates the drop area in the given
|
||||
* TargetAreaWidget
|
||||
*/
|
||||
void dropWidget(QWidget *widget, DockWidgetArea dropArea, DockAreaWidget *targetAreaWidget);
|
||||
void dropWidget(QWidget *widget,
|
||||
DockWidgetArea dropArea,
|
||||
DockAreaWidget *targetAreaWidget,
|
||||
int tabIndex = -1);
|
||||
|
||||
/**
|
||||
* Adds the given dock area to this container widget
|
||||
@@ -299,7 +303,7 @@ public:
|
||||
/**
|
||||
* Returns the side tab widget for the given area
|
||||
*/
|
||||
AutoHideSideBar *sideTabBar(SideBarLocation area) const;
|
||||
AutoHideSideBar *autoHideSideBar(SideBarLocation area) const;
|
||||
|
||||
/**
|
||||
* Access function for auto hide widgets
|
||||
|
@@ -48,6 +48,8 @@ struct DockAreaWidgetPrivate;
|
||||
class IconProvider;
|
||||
class DockFocusController;
|
||||
class AutoHideSideBar;
|
||||
class AutoHideTab;
|
||||
struct AutoHideTabPrivate;
|
||||
|
||||
inline constexpr QStringView workspaceFolderName{u"workspaces"};
|
||||
inline constexpr QStringView workspaceFileExtension{u"wrk"};
|
||||
@@ -84,6 +86,8 @@ private:
|
||||
friend class DockAreaTitleBar;
|
||||
friend class AutoHideDockContainer;
|
||||
friend AutoHideSideBar;
|
||||
friend AutoHideTab;
|
||||
friend AutoHideTabPrivate;
|
||||
|
||||
public:
|
||||
using Super = DockContainerWidget;
|
||||
@@ -182,8 +186,8 @@ public:
|
||||
= 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
|
||||
= AutoHideFeatureEnabled | DockAreaHasAutoHideButton
|
||||
| AutoHideCloseButtonCollapsesDock ///< the default configuration for left and right side bars
|
||||
};
|
||||
Q_DECLARE_FLAGS(AutoHideFlags, eAutoHideFlag)
|
||||
|
||||
|
@@ -3,8 +3,12 @@
|
||||
|
||||
#include "dockoverlay.h"
|
||||
|
||||
#include "autohidesidebar.h"
|
||||
#include "dockareatabbar.h"
|
||||
#include "dockareatitlebar.h"
|
||||
#include "dockareawidget.h"
|
||||
#include "dockcontainerwidget.h"
|
||||
#include "dockmanager.h"
|
||||
|
||||
#include <utils/hostosinfo.h>
|
||||
|
||||
@@ -25,6 +29,10 @@
|
||||
|
||||
namespace ADS {
|
||||
|
||||
static const int g_autoHideAreaWidth = 32;
|
||||
static const int g_autoHideAreaMouseZone = 8;
|
||||
static const int g_invalidTabIndex = -2;
|
||||
|
||||
/**
|
||||
* Private data class of DockOverlay
|
||||
*/
|
||||
@@ -39,6 +47,7 @@ public:
|
||||
bool m_dropPreviewEnabled = true;
|
||||
DockOverlay::eMode m_mode = DockOverlay::ModeDockAreaOverlay;
|
||||
QRect m_dropAreaRect;
|
||||
int m_tabIndex = g_invalidTabIndex;
|
||||
|
||||
/**
|
||||
* Private data constructor
|
||||
@@ -46,6 +55,16 @@ public:
|
||||
DockOverlayPrivate(DockOverlay *parent)
|
||||
: q(parent)
|
||||
{}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -132,7 +151,15 @@ public:
|
||||
label->setObjectName("DockWidgetAreaLabel");
|
||||
|
||||
const qreal metric = dropIndicatorWidth(label);
|
||||
const QSizeF size(metric, metric);
|
||||
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);
|
||||
}
|
||||
|
||||
label->setPixmap(createHighDpiDropIndicatorPixmap(size, dockWidgetArea, mode));
|
||||
label->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
|
||||
@@ -159,6 +186,11 @@ public:
|
||||
{
|
||||
const QColor borderColor = iconColor(DockOverlayCross::FrameColor);
|
||||
const QColor backgroundColor = iconColor(DockOverlayCross::WindowBackgroundColor);
|
||||
|
||||
QColor overlayColor = iconColor(DockOverlayCross::OverlayColor);
|
||||
if (overlayColor.alpha() == 255)
|
||||
overlayColor.setAlpha(64);
|
||||
|
||||
const double devicePixelRatio = q->window()->devicePixelRatioF();
|
||||
const QSizeF pixmapSize = size * devicePixelRatio;
|
||||
QPixmap pixmap(pixmapSize.toSize());
|
||||
@@ -223,19 +255,18 @@ public:
|
||||
}
|
||||
|
||||
const QSizeF baseSize = baseRect.size();
|
||||
if (DockOverlay::ModeContainerOverlay == mode && dockWidgetArea != CenterDockWidgetArea) {
|
||||
bool isOuterContainerArea = (DockOverlay::ModeContainerOverlay == mode)
|
||||
&& (dockWidgetArea != CenterDockWidgetArea)
|
||||
&& !internal::isSideBarArea(dockWidgetArea);
|
||||
if (isOuterContainerArea)
|
||||
baseRect = areaRect;
|
||||
}
|
||||
|
||||
painter.fillRect(baseRect, backgroundColor);
|
||||
|
||||
if (areaRect.isValid()) {
|
||||
pen = painter.pen();
|
||||
pen.setColor(borderColor);
|
||||
QColor color = iconColor(DockOverlayCross::OverlayColor);
|
||||
if (color.alpha() == 255) {
|
||||
color.setAlpha(64);
|
||||
}
|
||||
painter.setBrush(color);
|
||||
painter.setBrush(overlayColor);
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.drawRect(areaRect);
|
||||
|
||||
@@ -264,7 +295,7 @@ public:
|
||||
painter.restore();
|
||||
|
||||
// Draw arrow for outer container drop indicators
|
||||
if (DockOverlay::ModeContainerOverlay == mode && dockWidgetArea != CenterDockWidgetArea) {
|
||||
if (isOuterContainerArea) {
|
||||
QRectF arrowRect;
|
||||
arrowRect.setSize(baseSize);
|
||||
arrowRect.setWidth(arrowRect.width() / 4.6);
|
||||
@@ -302,6 +333,26 @@ public:
|
||||
}
|
||||
}; // class DockOverlayCrossPrivate
|
||||
|
||||
int DockOverlayPrivate::sideBarOverlaySize(SideBarLocation sideBarLocation)
|
||||
{
|
||||
auto container = qobject_cast<DockContainerWidget *>(m_targetWidget.data());
|
||||
auto sideBar = container->autoHideSideBar(sideBarLocation);
|
||||
if (!sideBar || !sideBar->isVisibleTo(container))
|
||||
return g_autoHideAreaWidth;
|
||||
else
|
||||
return (sideBar->orientation() == Qt::Horizontal) ? sideBar->height() : sideBar->width();
|
||||
}
|
||||
|
||||
int DockOverlayPrivate::sideBarMouseZone(SideBarLocation sideBarLocation)
|
||||
{
|
||||
auto container = qobject_cast<DockContainerWidget *>(m_targetWidget.data());
|
||||
auto sideBar = container->autoHideSideBar(sideBarLocation);
|
||||
if (!sideBar || !sideBar->isVisibleTo(container))
|
||||
return g_autoHideAreaMouseZone;
|
||||
else
|
||||
return (sideBar->orientation() == Qt::Horizontal) ? sideBar->height() : sideBar->width();
|
||||
}
|
||||
|
||||
DockOverlay::DockOverlay(QWidget *parent, eMode mode)
|
||||
: QFrame(parent)
|
||||
, d(new DockOverlayPrivate(this))
|
||||
@@ -338,6 +389,14 @@ void DockOverlay::setAllowedAreas(DockWidgetAreas areas)
|
||||
d->m_cross->reset();
|
||||
}
|
||||
|
||||
void DockOverlay::setAllowedArea(DockWidgetArea area, bool enable)
|
||||
{
|
||||
auto areasOld = d->m_allowedAreas;
|
||||
d->m_allowedAreas.setFlag(area, enable);
|
||||
if (areasOld != d->m_allowedAreas)
|
||||
d->m_cross->reset();
|
||||
}
|
||||
|
||||
DockWidgetAreas DockOverlay::allowedAreas() const
|
||||
{
|
||||
return d->m_allowedAreas;
|
||||
@@ -345,21 +404,62 @@ DockWidgetAreas DockOverlay::allowedAreas() const
|
||||
|
||||
DockWidgetArea DockOverlay::dropAreaUnderCursor() const
|
||||
{
|
||||
d->m_tabIndex = g_invalidTabIndex;
|
||||
if (!d->m_targetWidget)
|
||||
return InvalidDockWidgetArea;
|
||||
|
||||
DockWidgetArea result = d->m_cross->cursorLocation();
|
||||
if (result != InvalidDockWidgetArea)
|
||||
return result;
|
||||
|
||||
DockAreaWidget *dockArea = qobject_cast<DockAreaWidget *>(d->m_targetWidget.data());
|
||||
if (!dockArea)
|
||||
auto cursorPos = QCursor::pos();
|
||||
auto dockArea = qobject_cast<DockAreaWidget *>(d->m_targetWidget.data());
|
||||
if (!dockArea
|
||||
&& DockManager::autoHideConfigFlags().testFlag(DockManager::AutoHideFeatureEnabled)) {
|
||||
auto rectangle = rect();
|
||||
const QPoint pos = mapFromGlobal(QCursor::pos());
|
||||
if ((pos.x() < d->sideBarMouseZone(SideBarLeft))
|
||||
&& d->m_allowedAreas.testFlag(LeftAutoHideArea)) {
|
||||
result = LeftAutoHideArea;
|
||||
} else if (pos.x() > (rectangle.width() - d->sideBarMouseZone(SideBarRight))
|
||||
&& d->m_allowedAreas.testFlag(RightAutoHideArea)) {
|
||||
result = RightAutoHideArea;
|
||||
} else if (pos.y() < d->sideBarMouseZone(SideBarTop)
|
||||
&& d->m_allowedAreas.testFlag(TopAutoHideArea)) {
|
||||
result = TopAutoHideArea;
|
||||
} else if (pos.y() > (rectangle.height() - d->sideBarMouseZone(SideBarBottom))
|
||||
&& d->m_allowedAreas.testFlag(BottomAutoHideArea)) {
|
||||
result = BottomAutoHideArea;
|
||||
}
|
||||
|
||||
auto sideBarLocation = internal::toSideBarLocation(result);
|
||||
if (sideBarLocation != SideBarNone) {
|
||||
auto Container = qobject_cast<DockContainerWidget *>(d->m_targetWidget.data());
|
||||
auto SideBar = Container->autoHideSideBar(sideBarLocation);
|
||||
if (SideBar->isVisible()) {
|
||||
d->m_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->m_tabIndex = tabBar->tabInsertIndexAt(tabBar->mapFromGlobal(cursorPos));
|
||||
return CenterDockWidgetArea;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int DockOverlay::tabIndexUnderCursor() const
|
||||
{
|
||||
return d->m_tabIndex;
|
||||
}
|
||||
|
||||
DockWidgetArea DockOverlay::visibleDropAreaUnderCursor() const
|
||||
{
|
||||
if (isHidden() || !d->m_dropPreviewEnabled)
|
||||
@@ -416,6 +516,7 @@ bool DockOverlay::dropPreviewEnabled() const
|
||||
void DockOverlay::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
// Draw rect based on location
|
||||
if (!d->m_dropPreviewEnabled) {
|
||||
d->m_dropAreaRect = QRect();
|
||||
@@ -442,9 +543,22 @@ void DockOverlay::paintEvent(QPaintEvent *event)
|
||||
case CenterDockWidgetArea:
|
||||
rectangle = rect();
|
||||
break;
|
||||
case LeftAutoHideArea:
|
||||
rectangle.setWidth(d->sideBarOverlaySize(SideBarLeft));
|
||||
break;
|
||||
case RightAutoHideArea:
|
||||
rectangle.setX(rectangle.width() - d->sideBarOverlaySize(SideBarRight));
|
||||
break;
|
||||
case TopAutoHideArea:
|
||||
rectangle.setHeight(d->sideBarOverlaySize(SideBarTop));
|
||||
break;
|
||||
case BottomAutoHideArea:
|
||||
rectangle.setY(rectangle.height() - d->sideBarOverlaySize(SideBarBottom));
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
QPainter painter(this);
|
||||
QColor color = palette().color(QPalette::Active, QPalette::Highlight);
|
||||
QPen pen = painter.pen();
|
||||
|
@@ -52,11 +52,26 @@ public:
|
||||
*/
|
||||
DockWidgetAreas allowedAreas() const;
|
||||
|
||||
/**
|
||||
* Enable / disable a certain area
|
||||
*/
|
||||
void setAllowedArea(DockWidgetArea area, bool enable);
|
||||
|
||||
/**
|
||||
* Returns the drop area under the current cursor location
|
||||
*/
|
||||
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
|
||||
|
@@ -409,6 +409,11 @@ bool DockWidget::isAutoHide() const
|
||||
return !d->m_sideTabWidget.isNull();
|
||||
}
|
||||
|
||||
SideBarLocation DockWidget::autoHideLocation() const
|
||||
{
|
||||
return isAutoHide() ? autoHideDockContainer()->sideBarLocation() : SideBarNone;
|
||||
}
|
||||
|
||||
bool DockWidget::isFloating() const
|
||||
{
|
||||
if (!isInFloatingContainer())
|
||||
@@ -746,6 +751,9 @@ void DockWidget::setFloating()
|
||||
if (isClosed())
|
||||
return;
|
||||
|
||||
if (isAutoHide())
|
||||
dockAreaWidget()->setFloating();
|
||||
else
|
||||
d->m_tabWidget->detachDockWidget();
|
||||
}
|
||||
|
||||
@@ -764,6 +772,15 @@ void DockWidget::closeDockWidget()
|
||||
closeDockWidgetInternal(true);
|
||||
}
|
||||
|
||||
void DockWidget::requestCloseDockWidget()
|
||||
{
|
||||
if (features().testFlag(DockWidget::DockWidgetDeleteOnClose)
|
||||
|| features().testFlag(DockWidget::CustomCloseHandling))
|
||||
closeDockWidgetInternal(false);
|
||||
else
|
||||
toggleView(false);
|
||||
}
|
||||
|
||||
bool DockWidget::closeDockWidgetInternal(bool forceClose)
|
||||
{
|
||||
if (!forceClose)
|
||||
@@ -859,21 +876,24 @@ void DockWidget::raise()
|
||||
}
|
||||
}
|
||||
|
||||
void DockWidget::setAutoHide(bool enable, SideBarLocation location)
|
||||
void DockWidget::setAutoHide(bool enable, SideBarLocation location, int tabIndex)
|
||||
{
|
||||
if (!DockManager::testAutoHideConfigFlag(DockManager::AutoHideFeatureEnabled))
|
||||
return;
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -338,16 +338,20 @@ public:
|
||||
bool isAutoHide() const;
|
||||
|
||||
/**
|
||||
* Returns the auto hide dock container of this dock widget
|
||||
* or 0 if there is none
|
||||
* Returns the auto hide dock container of this dock widget or 0 if there is none.
|
||||
*/
|
||||
AutoHideDockContainer *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
|
||||
* of a floating container. If there are more than one dock widget in a
|
||||
* floating container, the all dock widgets are docked and not floating.
|
||||
* A dock widget is only floating, if it is the one and only widget inside of a floating
|
||||
* container. If there are more than one dock widget in a floating container, the all dock
|
||||
* widgets are docked and not floating.
|
||||
*/
|
||||
bool isFloating() const;
|
||||
|
||||
@@ -546,23 +550,28 @@ public: // reimplements QFrame
|
||||
*/
|
||||
void closeDockWidget();
|
||||
|
||||
/**
|
||||
* Request closing of the dock widget.
|
||||
* For DockWidget with default close handling, the function does the same like clodeDockWidget()
|
||||
* but if the flag 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
|
||||
* compatible to QDockWidget, this function also maximizes a floating
|
||||
* dock widget.
|
||||
* Normally this function only affects windows. To make the interface compatible to QDockWidget,
|
||||
* this function also maximizes a floating dock widget.
|
||||
*
|
||||
* \note Full-screen mode works fine under Windows, but has certain
|
||||
* problems (doe not work) under X (Linux). These problems are due to
|
||||
* limitations of the ICCCM protocol that specifies the communication
|
||||
* between X11 clients and the window manager. ICCCM simply does not
|
||||
* \note Full-screen mode works fine under Windows, but has certain problems (doe not work)
|
||||
* under X (Linux). These problems are due to limitations of the ICCCM protocol that specifies
|
||||
* the communication between X11 clients and the window manager. ICCCM simply does not
|
||||
* understand the concept of non-decorated full-screen windows.
|
||||
*/
|
||||
void showFullScreen();
|
||||
|
||||
/**
|
||||
* This function complements showFullScreen() to restore the widget
|
||||
* after it has been in full screen mode.
|
||||
* This function complements showFullScreen() to restore the widget after it has been in full
|
||||
* screen mode.
|
||||
*/
|
||||
void showNormal();
|
||||
|
||||
@@ -570,11 +579,10 @@ public: // reimplements QFrame
|
||||
* 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
|
||||
* current state.
|
||||
* Switches the dock widget to auto hide mode or vice versa depending on its current state.
|
||||
*/
|
||||
void toggleAutoHide(SideBarLocation location = SideBarNone);
|
||||
|
||||
|
@@ -58,7 +58,6 @@ public:
|
||||
TabButton *m_closeButton = nullptr;
|
||||
QPoint m_tabDragStartPosition;
|
||||
QSize m_iconSize;
|
||||
bool m_mousePressed = false;
|
||||
|
||||
/**
|
||||
* Private data constructor
|
||||
@@ -340,7 +339,6 @@ void DockWidgetTab::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
event->accept();
|
||||
d->m_mousePressed = true;
|
||||
d->saveDragStartMousePosition(event->globalPosition().toPoint());
|
||||
d->m_dragState = DraggingMousePressed;
|
||||
if (DockManager::testConfigFlag(DockManager::FocusHighlighting)) {
|
||||
@@ -356,7 +354,6 @@ void DockWidgetTab::mousePressEvent(QMouseEvent *event)
|
||||
void DockWidgetTab::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
d->m_mousePressed = false;
|
||||
auto currentDragState = d->m_dragState;
|
||||
d->m_globalDragStartMousePosition = QPoint();
|
||||
d->m_dragStartMousePosition = QPoint();
|
||||
|
@@ -167,11 +167,6 @@ public:
|
||||
*/
|
||||
void setIconSize(const QSize &size);
|
||||
|
||||
/**
|
||||
* Returns true, if the tab has been clicked and the mouse is currently pressed.
|
||||
*/
|
||||
bool mousePressed() const;
|
||||
|
||||
void setVisible(bool visible) override;
|
||||
|
||||
signals:
|
||||
|
@@ -455,6 +455,9 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|
||||
if (!overlay->dropOverlayRect().isValid())
|
||||
overlay = m_dockManager->dockAreaOverlay();
|
||||
|
||||
// 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 (!internal::isSideBarArea(overlay->dropAreaUnderCursor())) {
|
||||
// Resize the floating widget to the size of the highlighted drop area rectangle
|
||||
QRect rect = overlay->dropOverlayRect();
|
||||
int frameWidth = (q->frameSize().width() - q->rect().width()) / 2;
|
||||
@@ -465,6 +468,7 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|
||||
q->setGeometry(QRect(topLeft, QSize(rect.width(), rect.height() - titleBarHeight)));
|
||||
QApplication::processEvents();
|
||||
}
|
||||
}
|
||||
m_dropContainer->dropFloatingWidget(q, QCursor::pos());
|
||||
}
|
||||
|
||||
@@ -510,10 +514,23 @@ void FloatingDockContainerPrivate::updateDropOverlays(const QPoint &globalPositi
|
||||
}
|
||||
|
||||
int visibleDockAreas = topContainer->visibleDockAreaCount();
|
||||
containerOverlay->setAllowedAreas(visibleDockAreas > 1 ? OuterDockAreas : AllDockAreas);
|
||||
|
||||
DockWidgetAreas allowedContainerAreas = (visibleDockAreas > 1) ? OuterDockAreas : AllDockAreas;
|
||||
auto dockArea = topContainer->dockAreaAt(globalPosition);
|
||||
// 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 (m_dockContainer->features().testFlag(DockWidget::DockWidgetPinnable))
|
||||
allowedContainerAreas |= AutoHideDockAreas;
|
||||
|
||||
containerOverlay->setAllowedAreas(allowedContainerAreas);
|
||||
|
||||
DockWidgetArea containerArea = containerOverlay->showOverlay(topContainer);
|
||||
containerOverlay->enableDropPreview(containerArea != InvalidDockWidgetArea);
|
||||
auto dockArea = topContainer->dockAreaAt(globalPosition);
|
||||
if (dockArea && dockArea->isVisible() && visibleDockAreas > 0) {
|
||||
dockAreaOverlay->enableDropPreview(true);
|
||||
dockAreaOverlay->setAllowedAreas((visibleDockAreas == 1) ? NoDockWidgetArea
|
||||
|
@@ -4,6 +4,7 @@
|
||||
#include "floatingdragpreview.h"
|
||||
#include "ads_globals_p.h"
|
||||
|
||||
#include "ads_globals.h"
|
||||
#include "autohidedockcontainer.h"
|
||||
#include "dockareawidget.h"
|
||||
#include "dockcontainerwidget.h"
|
||||
@@ -31,6 +32,7 @@ class FloatingDragPreviewPrivate
|
||||
public:
|
||||
FloatingDragPreview *q;
|
||||
QWidget *m_content = nullptr;
|
||||
DockWidget::DockWidgetFeatures m_contentFeatures;
|
||||
DockAreaWidget *m_contentSourceArea = nullptr;
|
||||
QPoint m_dragStartMousePosition;
|
||||
DockManager *m_dockManager = nullptr;
|
||||
@@ -70,19 +72,35 @@ public:
|
||||
void createFloatingWidget();
|
||||
|
||||
/**
|
||||
* Returns true, if the content is floatable.
|
||||
* Returns true, if the content is floatable
|
||||
*/
|
||||
bool isContentFloatable() const
|
||||
{
|
||||
return m_contentFeatures.testFlag(DockWidget::DockWidgetFloatable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true, if the content is pinnable
|
||||
*/
|
||||
bool isContentPinnable() const
|
||||
{
|
||||
return m_contentFeatures.testFlag(DockWidget::DockWidgetPinnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content features
|
||||
*/
|
||||
DockWidget::DockWidgetFeatures contentFeatures() const
|
||||
{
|
||||
DockWidget *dockWidget = qobject_cast<DockWidget *>(m_content);
|
||||
if (dockWidget && dockWidget->features().testFlag(DockWidget::DockWidgetFloatable))
|
||||
return true;
|
||||
if (dockWidget)
|
||||
return dockWidget->features();
|
||||
|
||||
DockAreaWidget *dockArea = qobject_cast<DockAreaWidget *>(m_content);
|
||||
if (dockArea && dockArea->features().testFlag(DockWidget::DockWidgetFloatable))
|
||||
return true;
|
||||
if (dockArea)
|
||||
return dockArea->features();
|
||||
|
||||
return false;
|
||||
return DockWidget::DockWidgetFeatures();
|
||||
}
|
||||
}; // class FloatingDragPreviewPrivate
|
||||
|
||||
@@ -107,8 +125,6 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &globalPosition
|
||||
m_dropContainer = topContainer;
|
||||
auto containerOverlay = m_dockManager->containerOverlay();
|
||||
auto dockAreaOverlay = m_dockManager->dockAreaOverlay();
|
||||
auto dockDropArea = dockAreaOverlay->dropAreaUnderCursor();
|
||||
auto containerDropArea = containerOverlay->dropAreaUnderCursor();
|
||||
|
||||
if (!topContainer) {
|
||||
containerOverlay->hideOverlay();
|
||||
@@ -119,6 +135,9 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &globalPosition
|
||||
return;
|
||||
}
|
||||
|
||||
auto dockDropArea = dockAreaOverlay->dropAreaUnderCursor();
|
||||
auto containerDropArea = containerOverlay->dropAreaUnderCursor();
|
||||
|
||||
int visibleDockAreas = topContainer->visibleDockAreaCount();
|
||||
|
||||
// Include the overlay widget we're dragging as a visible widget
|
||||
@@ -126,8 +145,22 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &globalPosition
|
||||
if (dockAreaWidget && dockAreaWidget->isAutoHide())
|
||||
visibleDockAreas++;
|
||||
|
||||
containerOverlay->setAllowedAreas(visibleDockAreas > 1 ? OuterDockAreas : AllDockAreas);
|
||||
DockWidgetAreas allowedContainerAreas = (visibleDockAreas > 1) ? OuterDockAreas : AllDockAreas;
|
||||
|
||||
auto dockArea = topContainer->dockAreaAt(globalPosition);
|
||||
// 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 != m_contentSourceArea) {
|
||||
dockAreaOverlay->enableDropPreview(true);
|
||||
@@ -149,10 +182,10 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &globalPosition
|
||||
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.
|
||||
// the same position. Only auto hide area is allowed.
|
||||
if (visibleDockAreas == 1)
|
||||
containerOverlay->hideOverlay();
|
||||
else
|
||||
containerOverlay->setAllowedAreas(AutoHideDockAreas);
|
||||
|
||||
containerOverlay->showOverlay(topContainer);
|
||||
|
||||
if (dockArea == m_contentSourceArea && InvalidDockWidgetArea == containerDropArea)
|
||||
@@ -199,6 +232,7 @@ FloatingDragPreview::FloatingDragPreview(QWidget *content, QWidget *parent)
|
||||
, d(new FloatingDragPreviewPrivate(this))
|
||||
{
|
||||
d->m_content = content;
|
||||
d->m_contentFeatures = d->contentFeatures();
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
if (DockManager::testConfigFlag(DockManager::DragPreviewHasWindowFrame)) {
|
||||
setWindowFlags(Qt::Window | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint);
|
||||
@@ -288,22 +322,25 @@ void FloatingDragPreview::finishDragging()
|
||||
// Non floatable auto hide widgets should stay in its current auto hide state if they are
|
||||
// dragged into a floating window.
|
||||
if (validDropArea || d->isContentFloatable())
|
||||
cleanupAutoHideContainerWidget();
|
||||
cleanupAutoHideContainerWidget(containerDropArea);
|
||||
|
||||
if (!d->m_dropContainer) {
|
||||
d->createFloatingWidget();
|
||||
} else if (dockDropArea != InvalidDockWidgetArea) {
|
||||
d->m_dropContainer->dropWidget(d->m_content,
|
||||
dockDropArea,
|
||||
d->m_dropContainer->dockAreaAt(QCursor::pos()));
|
||||
d->m_dropContainer->dockAreaAt(QCursor::pos()),
|
||||
d->m_dockManager->dockAreaOverlay()->tabIndexUnderCursor());
|
||||
} else if (containerDropArea != InvalidDockWidgetArea) {
|
||||
// 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->m_dropContainer->visibleDockAreaCount() <= 1
|
||||
&& CenterDockWidgetArea == containerDropArea)
|
||||
d->m_dropContainer->dropWidget(d->m_content,
|
||||
d->m_dropContainer
|
||||
->dropWidget(d->m_content,
|
||||
containerDropArea,
|
||||
d->m_dropContainer->dockAreaAt(QCursor::pos()));
|
||||
d->m_dropContainer->dockAreaAt(QCursor::pos()),
|
||||
d->m_dockManager->containerOverlay()->tabIndexUnderCursor());
|
||||
else
|
||||
d->m_dropContainer->dropWidget(d->m_content, containerDropArea, nullptr);
|
||||
} else {
|
||||
@@ -315,15 +352,24 @@ void FloatingDragPreview::finishDragging()
|
||||
d->m_dockManager->dockAreaOverlay()->hideOverlay();
|
||||
}
|
||||
|
||||
void FloatingDragPreview::cleanupAutoHideContainerWidget()
|
||||
void FloatingDragPreview::cleanupAutoHideContainerWidget(DockWidgetArea containerDropArea)
|
||||
{
|
||||
auto droppedDockWidget = qobject_cast<DockWidget *>(d->m_content);
|
||||
if (droppedDockWidget && droppedDockWidget->autoHideDockContainer())
|
||||
droppedDockWidget->autoHideDockContainer()->cleanupAndDelete();
|
||||
|
||||
auto droppedArea = qobject_cast<DockAreaWidget *>(d->m_content);
|
||||
if (droppedArea && droppedArea->autoHideDockContainer())
|
||||
droppedArea->autoHideDockContainer()->cleanupAndDelete();
|
||||
|
||||
auto autoHideContainer = droppedDockWidget ? droppedDockWidget->autoHideDockContainer()
|
||||
: droppedArea->autoHideDockContainer();
|
||||
|
||||
if (!autoHideContainer)
|
||||
return;
|
||||
|
||||
// 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 (internal::isSideBarArea(containerDropArea)
|
||||
&& (d->m_dropContainer == autoHideContainer->dockContainer()))
|
||||
return;
|
||||
|
||||
autoHideContainer->cleanupAndDelete();
|
||||
}
|
||||
|
||||
void FloatingDragPreview::paintEvent(QPaintEvent *event)
|
||||
@@ -333,6 +379,7 @@ void FloatingDragPreview::paintEvent(QPaintEvent *event)
|
||||
return;
|
||||
|
||||
QPainter painter(this);
|
||||
painter.setOpacity(0.6);
|
||||
if (DockManager::testConfigFlag(DockManager::DragPreviewShowsContentPixmap))
|
||||
painter.drawPixmap(QPoint(0, 0), d->m_contentPreviewPixmap);
|
||||
|
||||
|
@@ -89,7 +89,7 @@ public: // implements AbstractFloatingWidget
|
||||
/**
|
||||
* Cleanup auto hide container if the dragged widget has one.
|
||||
*/
|
||||
void cleanupAutoHideContainerWidget();
|
||||
void cleanupAutoHideContainerWidget(DockWidgetArea containerDropArea);
|
||||
|
||||
signals:
|
||||
/**
|
||||
|
Reference in New Issue
Block a user