mirror of
https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git
synced 2024-12-24 23:31:32 +08:00
Added support for make auto hide widget floating via double click or context menu
This commit is contained in:
parent
0b3c3f0123
commit
1c6d86e70f
@ -230,7 +230,7 @@ CAutoHideDockContainer::CAutoHideDockContainer(CDockWidget* DockWidget, SideBarL
|
||||
//============================================================================
|
||||
void CAutoHideDockContainer::updateSize()
|
||||
{
|
||||
std::cout << "CAutoHideDockContainer::updateSize()" << std::endl;
|
||||
qDebug() << "CAutoHideDockContainer::updateSize()";
|
||||
auto dockContainerParent = dockContainer();
|
||||
if (!dockContainerParent)
|
||||
{
|
||||
@ -239,6 +239,10 @@ void CAutoHideDockContainer::updateSize()
|
||||
|
||||
auto rect = dockContainerParent->contentRect();
|
||||
qDebug() << "dockContainerParent->contentRect() " << rect;
|
||||
qDebug() << "dockWidget()->rect()" << dockWidget()->rect();
|
||||
qDebug() << "dockAreaWidget()->rect(): " << dockAreaWidget()->rect();
|
||||
qDebug() << "CAutoHideDockContainer::isVisible " << this->isVisible();
|
||||
qDebug() << "CAutoHideDockContainer::rect " << this->rect();
|
||||
|
||||
switch (sideBarLocation())
|
||||
{
|
||||
@ -273,6 +277,9 @@ void CAutoHideDockContainer::updateSize()
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
qDebug() << "CAutoHideDockContainer::rect (after): " << this->rect();
|
||||
qDebug() << "dockAreaWidget()->rect(): " << dockAreaWidget()->rect();
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
@ -326,6 +333,7 @@ CDockWidget* CAutoHideDockContainer::dockWidget() const
|
||||
//============================================================================
|
||||
void CAutoHideDockContainer::addDockWidget(CDockWidget* DockWidget)
|
||||
{
|
||||
std::cout << "CAutoHideDockContainer::addDockWidget " << std::endl;
|
||||
if (d->DockWidget)
|
||||
{
|
||||
// Remove the old dock widget at this area
|
||||
@ -346,6 +354,10 @@ void CAutoHideDockContainer::addDockWidget(CDockWidget* DockWidget)
|
||||
}
|
||||
d->DockArea->addDockWidget(DockWidget);
|
||||
updateSize();
|
||||
// The dock area is not visible and will not update the size when updateSize()
|
||||
// is called for this auto hide container. Therefore we explicitely resize
|
||||
// it here. As soon as it will become visible, it will get the right size
|
||||
d->DockArea->resize(size());
|
||||
}
|
||||
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <QBoxLayout>
|
||||
#include <QApplication>
|
||||
#include <QElapsedTimer>
|
||||
#include <QMenu>
|
||||
|
||||
#include "AutoHideDockContainer.h"
|
||||
#include "AutoHideSideBar.h"
|
||||
@ -272,10 +273,65 @@ bool CAutoHideTab::event(QEvent* event)
|
||||
return Super::event(event);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
bool CAutoHideTab::iconOnly() const
|
||||
{
|
||||
return CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideSideBarsIconOnly) && !icon().isNull();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideTab::contextMenuEvent(QContextMenuEvent* ev)
|
||||
{
|
||||
ev->accept();
|
||||
//d->saveDragStartMousePosition(ev->globalPos());
|
||||
|
||||
const bool isFloatable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable);
|
||||
QAction* Action;
|
||||
QMenu Menu(this);
|
||||
|
||||
|
||||
Action = Menu.addAction(tr("Detach"), this, SLOT(setDockWidgetFloating()));
|
||||
Action->setEnabled(isFloatable);
|
||||
auto IsPinnable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetPinnable);
|
||||
Action->setEnabled(IsPinnable);
|
||||
|
||||
auto menu = Menu.addMenu(tr("Pin To..."));
|
||||
menu->setEnabled(IsPinnable);
|
||||
//d->createAutoHideToAction(tr("Top"), SideBarTop, menu);
|
||||
//d->createAutoHideToAction(tr("Left"), SideBarLeft, menu);
|
||||
//d->createAutoHideToAction(tr("Right"), SideBarRight, menu);
|
||||
//d->createAutoHideToAction(tr("Bottom"), SideBarBottom, menu);
|
||||
|
||||
/*Menu.addSeparator();
|
||||
Action = Menu.addAction(tr("Close"), this, SIGNAL(closeRequested()));
|
||||
Action->setEnabled(isClosable());
|
||||
if (d->DockArea->openDockWidgetsCount() > 1)
|
||||
{
|
||||
Action = Menu.addAction(tr("Close Others"), this, SIGNAL(closeOtherTabsRequested()));
|
||||
}*/
|
||||
Menu.exec(ev->globalPos());
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideTab::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
setDockWidgetFloating();
|
||||
}
|
||||
|
||||
Super::mouseDoubleClickEvent(event);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CAutoHideTab::setDockWidgetFloating()
|
||||
{
|
||||
dockWidget()->setFloating();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -65,11 +65,12 @@ private:
|
||||
friend class CDockContainerWidget;
|
||||
friend DockContainerWidgetPrivate;
|
||||
|
||||
|
||||
protected:
|
||||
void setSideBar(CAutoHideSideBar *SideTabBar);
|
||||
void removeFromSideBar();
|
||||
virtual bool event(QEvent* event) override;
|
||||
virtual void contextMenuEvent(QContextMenuEvent* ev) override;
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
|
||||
|
||||
public:
|
||||
using Super = CPushButton;
|
||||
@ -133,6 +134,12 @@ public:
|
||||
* not in a side bar
|
||||
*/
|
||||
CAutoHideSideBar* sideBar() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
/**
|
||||
* Set the dock widget floating, if it is floatable
|
||||
*/
|
||||
void setDockWidgetFloating();
|
||||
}; // class AutoHideTab
|
||||
}
|
||||
// namespace ads
|
||||
|
@ -260,6 +260,7 @@ void DockAreaTitleBarPrivate::createTabBar()
|
||||
//============================================================================
|
||||
IFloatingWidget* DockAreaTitleBarPrivate::makeAreaFloating(const QPoint& Offset, eDragState DragState)
|
||||
{
|
||||
qDebug() << "DockAreaTitleBarPrivate::makeAreaFloating " << DockArea->size();
|
||||
QSize Size = DockArea->size();
|
||||
this->DragState = DragState;
|
||||
bool CreateFloatingDockContainer = (DraggingFloatingWidget != DragState);
|
||||
@ -660,6 +661,7 @@ void CDockAreaTitleBar::mouseMoveEvent(QMouseEvent* ev)
|
||||
//============================================================================
|
||||
void CDockAreaTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
{
|
||||
std::cout << "CDockAreaTitleBar::mouseDoubleClickEvent" << std::endl;
|
||||
// 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
|
||||
@ -677,6 +679,26 @@ void CDockAreaTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaTitleBar::setAreaFloating()
|
||||
{
|
||||
// If this is the last dock area in a dock container it does not make
|
||||
// sense to move it to a new floating widget and leave this one
|
||||
// empty
|
||||
if (d->DockArea->dockContainer()->isFloating() && d->DockArea->dockContainer()->dockAreaCount() == 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
d->makeAreaFloating(mapFromGlobal(QCursor::pos()), DraggingInactive);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaTitleBar::contextMenuEvent(QContextMenuEvent* ev)
|
||||
{
|
||||
|
@ -163,6 +163,12 @@ public:
|
||||
*/
|
||||
QString titleBarButtonToolTip(TitleBarButton Button) const;
|
||||
|
||||
/**
|
||||
* Moves the dock area into its own floating widget if the area
|
||||
* DockWidgetFloatable flag is true
|
||||
*/
|
||||
void setAreaFloating();
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* This signal is emitted if a tab in the tab bar is clicked by the user
|
||||
|
@ -1442,6 +1442,13 @@ bool CDockAreaWidget::isTopLevelArea() const
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CDockAreaWidget::setFloating()
|
||||
{
|
||||
d->TitleBar->setAreaFloating();
|
||||
}
|
||||
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
//============================================================================
|
||||
bool CDockAreaWidget::event(QEvent *e)
|
||||
|
@ -414,6 +414,12 @@ public Q_SLOTS:
|
||||
*/
|
||||
void closeOtherAreas();
|
||||
|
||||
/**
|
||||
* Moves the dock area into its own floating widget if the area
|
||||
* DockWidgetFloatable flag is true
|
||||
*/
|
||||
void setFloating();
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* This signal is emitted when user clicks on a tab at an index.
|
||||
|
@ -475,7 +475,6 @@ DockWidgetArea CDockOverlay::dropAreaUnderCursor() const
|
||||
auto DockArea = qobject_cast<CDockAreaWidget*>(d->TargetWidget.data());
|
||||
if (!DockArea && CDockManager::autoHideConfigFlags().testFlag(CDockManager::AutoHideFeatureEnabled))
|
||||
{
|
||||
std::cout << d->Mode << " Find out side bar area " << std::endl;
|
||||
auto Rect = rect();
|
||||
const QPoint pos = mapFromGlobal(QCursor::pos());
|
||||
if (pos.x() < d->sideBarMouseZone(SideBarLeft))
|
||||
@ -488,7 +487,6 @@ DockWidgetArea CDockOverlay::dropAreaUnderCursor() const
|
||||
}
|
||||
else if (pos.y() < d->sideBarMouseZone(SideBarTop))
|
||||
{
|
||||
std::cout << d->Mode << " TopAutoHideArea " << std::endl;
|
||||
return TopAutoHideArea;
|
||||
}
|
||||
else if (pos.y() > (Rect.height() - d->sideBarMouseZone(SideBarBottom)))
|
||||
@ -534,14 +532,12 @@ DockWidgetArea CDockOverlay::visibleDropAreaUnderCursor() const
|
||||
//============================================================================
|
||||
DockWidgetArea CDockOverlay::showOverlay(QWidget* target)
|
||||
{
|
||||
std::cout << d->Mode << " CDockOverlay::showOverlay()" << target << " " << target->objectName().toStdString() << std::endl;
|
||||
if (d->TargetWidget == target)
|
||||
{
|
||||
// Hint: We could update geometry of overlay here.
|
||||
DockWidgetArea da = dropAreaUnderCursor();
|
||||
if (da != d->LastLocation)
|
||||
{
|
||||
std::cout << d->Mode << " repaint()" << std::endl;
|
||||
repaint();
|
||||
d->LastLocation = da;
|
||||
}
|
||||
@ -566,7 +562,6 @@ DockWidgetArea CDockOverlay::showOverlay(QWidget* target)
|
||||
//============================================================================
|
||||
void CDockOverlay::hideOverlay()
|
||||
{
|
||||
std::cout << d->Mode << " CDockOverlay::hideOverlay()" << std::endl;
|
||||
hide();
|
||||
d->TargetWidget.clear();
|
||||
d->LastLocation = InvalidDockWidgetArea;
|
||||
@ -578,7 +573,6 @@ void CDockOverlay::hideOverlay()
|
||||
void CDockOverlay::enableDropPreview(bool Enable)
|
||||
{
|
||||
d->DropPreviewEnabled = Enable;
|
||||
std::cout << d->Mode << " update() " << Enable << std::endl;
|
||||
update();
|
||||
}
|
||||
|
||||
@ -606,7 +600,6 @@ void CDockOverlay::paintEvent(QPaintEvent* event)
|
||||
double Factor = (CDockOverlay::ModeContainerOverlay == d->Mode) ?
|
||||
3 : 2;
|
||||
|
||||
std::cout << "CDockOverlay::paintEvent da: " << da << std::endl;
|
||||
switch (da)
|
||||
{
|
||||
case TopDockWidgetArea: r.setHeight(r.height() / Factor); break;
|
||||
|
@ -1021,7 +1021,15 @@ void CDockWidget::setFloating()
|
||||
{
|
||||
return;
|
||||
}
|
||||
d->TabWidget->detachDockWidget();
|
||||
|
||||
if (this->isAutoHide())
|
||||
{
|
||||
dockAreaWidget()->setFloating();
|
||||
}
|
||||
else
|
||||
{
|
||||
d->TabWidget->detachDockWidget();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -499,10 +499,8 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|
||||
return;
|
||||
}
|
||||
|
||||
if (DockManager->dockAreaOverlay()->dropAreaUnderCursor()
|
||||
!= InvalidDockWidgetArea
|
||||
|| DockManager->containerOverlay()->dropAreaUnderCursor()
|
||||
!= InvalidDockWidgetArea)
|
||||
if (DockManager->dockAreaOverlay()->dropAreaUnderCursor() != InvalidDockWidgetArea
|
||||
|| DockManager->containerOverlay()->dropAreaUnderCursor() != InvalidDockWidgetArea)
|
||||
{
|
||||
CDockOverlay *Overlay = DockManager->containerOverlay();
|
||||
if (!Overlay->dropOverlayRect().isValid())
|
||||
@ -510,21 +508,26 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|
||||
Overlay = DockManager->dockAreaOverlay();
|
||||
}
|
||||
|
||||
// Resize the floating widget to the size of the highlighted drop area
|
||||
// rectangle
|
||||
QRect Rect = Overlay->dropOverlayRect();
|
||||
int FrameWidth = (_this->frameSize().width() - _this->rect().width())
|
||||
/ 2;
|
||||
int TitleBarHeight = _this->frameSize().height()
|
||||
- _this->rect().height() - FrameWidth;
|
||||
if (Rect.isValid())
|
||||
// Do not resize if we drop into an autohide sidebar area to preserve
|
||||
// the dock area size for the initial size of the auto hide area
|
||||
if (!ads::internal::isSideBarArea(Overlay->dropAreaUnderCursor()))
|
||||
{
|
||||
QPoint TopLeft = Overlay->mapToGlobal(Rect.topLeft());
|
||||
TopLeft.ry() += TitleBarHeight;
|
||||
_this->setGeometry(
|
||||
QRect(TopLeft,
|
||||
QSize(Rect.width(), Rect.height() - TitleBarHeight)));
|
||||
QApplication::processEvents();
|
||||
// Resize the floating widget to the size of the highlighted drop area
|
||||
// rectangle
|
||||
QRect Rect = Overlay->dropOverlayRect();
|
||||
int FrameWidth = (_this->frameSize().width() - _this->rect().width())
|
||||
/ 2;
|
||||
int TitleBarHeight = _this->frameSize().height()
|
||||
- _this->rect().height() - FrameWidth;
|
||||
if (Rect.isValid())
|
||||
{
|
||||
QPoint TopLeft = Overlay->mapToGlobal(Rect.topLeft());
|
||||
TopLeft.ry() += TitleBarHeight;
|
||||
_this->setGeometry(
|
||||
QRect(TopLeft,
|
||||
QSize(Rect.width(), Rect.height() - TitleBarHeight)));
|
||||
QApplication::processEvents();
|
||||
}
|
||||
}
|
||||
DropContainer->dropFloatingWidget(_this, QCursor::pos());
|
||||
}
|
||||
@ -533,6 +536,7 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|
||||
DockManager->dockAreaOverlay()->hideOverlay();
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
void FloatingDockContainerPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user