mirror of
https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git
synced 2024-11-15 21:25:44 +08:00
Improved transparent docking
This commit is contained in:
parent
07f9c6d016
commit
2fe542c3ef
@ -322,7 +322,9 @@ CMainWindow::CMainWindow(QWidget *parent) :
|
|||||||
|
|
||||||
// uncomment the following line if you wand a fixed tab width that does
|
// uncomment the following line if you wand a fixed tab width that does
|
||||||
// not change if the visibility of the close button changes
|
// not change if the visibility of the close button changes
|
||||||
CDockManager::setConfigFlag(CDockManager::OpaqueUndocking, false);
|
//CDockManager::setConfigFlag(CDockManager::OpaqueUndocking, false);
|
||||||
|
//CDockManager::setConfigFlag(CDockManager::DragPreviewIsDynamic, false);
|
||||||
|
CDockManager::setConfigFlags(CDockManager::NonOpaqueWithWindowFrame);
|
||||||
|
|
||||||
// Now create the dock manager and its content
|
// Now create the dock manager and its content
|
||||||
d->DockManager = new CDockManager(this);
|
d->DockManager = new CDockManager(this);
|
||||||
|
@ -152,12 +152,24 @@ public:
|
|||||||
TabCloseButtonIsToolButton = 0x0040,//! If enabled the tab close buttons will be QToolButtons instead of QPushButtons - disabled by default
|
TabCloseButtonIsToolButton = 0x0040,//! If enabled the tab close buttons will be QToolButtons instead of QPushButtons - disabled by default
|
||||||
AllTabsHaveCloseButton = 0x0080, //!< if this flag is set, then all tabs that are closable show a close button
|
AllTabsHaveCloseButton = 0x0080, //!< if this flag is set, then all tabs that are closable show a close button
|
||||||
RetainTabSizeWhenCloseButtonHidden = 0x0100, //!< if this flag is set, the space for the close button is reserved even if the close button is not visible
|
RetainTabSizeWhenCloseButtonHidden = 0x0100, //!< if this flag is set, the space for the close button is reserved even if the close button is not visible
|
||||||
OpaqueUndocking = 0x0200,
|
OpaqueUndocking = 0x0200,///< If enabled, the widgets are immediately undocked into floating widgets, if disabled, only a draw preview is undocked and the real undocking is deferred until the mouse is released
|
||||||
|
DragPreviewIsDynamic = 0x0400,///< If opaque undocking is disabled, this flag defines the behavior of the drag preview window, if this flag is enabled, the preview will be adjusted dynamically to the drop area
|
||||||
|
DragPreviewShowsContentPixmap = 0x0800,///< If opaque undocking is disabled, the created drag preview window shows a copy of the content of the dock widget / dock are that is dragged
|
||||||
|
DragPreviewHasWindowFrame = 0x1000,///< If opaque undocking is disabled, then this flag configures if the drag preview is frameless or looks like a real window
|
||||||
DefaultConfig = ActiveTabHasCloseButton
|
DefaultConfig = ActiveTabHasCloseButton
|
||||||
| DockAreaHasCloseButton
|
| DockAreaHasCloseButton
|
||||||
| OpaqueSplitterResize
|
| OpaqueSplitterResize
|
||||||
| XmlCompressionEnabled
|
| XmlCompressionEnabled
|
||||||
| OpaqueUndocking, ///< the default configuration
|
| OpaqueUndocking, ///< the default configuration
|
||||||
|
DefaultNonOpaqueConfig = ActiveTabHasCloseButton
|
||||||
|
| DockAreaHasCloseButton
|
||||||
|
| XmlCompressionEnabled
|
||||||
|
| DragPreviewShowsContentPixmap, ///< the default configuration for non opaque operations
|
||||||
|
NonOpaqueWithWindowFrame = ActiveTabHasCloseButton
|
||||||
|
| DockAreaHasCloseButton
|
||||||
|
| XmlCompressionEnabled
|
||||||
|
| DragPreviewShowsContentPixmap
|
||||||
|
| DragPreviewHasWindowFrame ///< the default configuration for non opaque operations that show a real window with frame
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(ConfigFlags, eConfigFlag)
|
Q_DECLARE_FLAGS(ConfigFlags, eConfigFlag)
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ struct FloatingOverlayPrivate
|
|||||||
qreal WindowOpacity;
|
qreal WindowOpacity;
|
||||||
bool Hidden = false;
|
bool Hidden = false;
|
||||||
bool IgnoreMouseEvents = false;
|
bool IgnoreMouseEvents = false;
|
||||||
|
QPixmap ContentPreviewPixmap;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -99,7 +100,10 @@ void FloatingOverlayPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
|||||||
{
|
{
|
||||||
ContainerOverlay->hideOverlay();
|
ContainerOverlay->hideOverlay();
|
||||||
DockAreaOverlay->hideOverlay();
|
DockAreaOverlay->hideOverlay();
|
||||||
setHidden(false);
|
if (CDockManager::configFlags().testFlag(CDockManager::DragPreviewIsDynamic))
|
||||||
|
{
|
||||||
|
setHidden(false);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,7 +144,10 @@ void FloatingOverlayPrivate::updateDropOverlays(const QPoint &GlobalPos)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setHidden(DockDropArea != InvalidDockWidgetArea || ContainerDropArea != InvalidDockWidgetArea);
|
if (CDockManager::configFlags().testFlag(CDockManager::DragPreviewIsDynamic))
|
||||||
|
{
|
||||||
|
setHidden(DockDropArea != InvalidDockWidgetArea || ContainerDropArea != InvalidDockWidgetArea);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -153,21 +160,37 @@ FloatingOverlayPrivate::FloatingOverlayPrivate(CFloatingOverlay *_public) :
|
|||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
CFloatingOverlay::CFloatingOverlay(QWidget* Content, QWidget* parent) :
|
CFloatingOverlay::CFloatingOverlay(QWidget* Content, QWidget* parent) :
|
||||||
QFrame(parent),
|
QWidget(parent),
|
||||||
d(new FloatingOverlayPrivate(this))
|
d(new FloatingOverlayPrivate(this))
|
||||||
{
|
{
|
||||||
d->Content = Content;
|
d->Content = Content;
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
if (CDockManager::configFlags().testFlag(CDockManager::DragPreviewHasWindowFrame))
|
||||||
|
{
|
||||||
|
setWindowFlags(
|
||||||
|
Qt::Window | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
|
||||||
|
setAttribute(Qt::WA_NoSystemBackground);
|
||||||
|
setAttribute(Qt::WA_TranslucentBackground);
|
||||||
|
}
|
||||||
|
|
||||||
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
|
setWindowOpacity(0.6);
|
||||||
setWindowOpacity(1);
|
|
||||||
setWindowTitle("FloatingOverlay");
|
|
||||||
setAttribute(Qt::WA_NoSystemBackground);
|
|
||||||
setAttribute(Qt::WA_TranslucentBackground);
|
|
||||||
// We install an event filter to detect mouse release events because we
|
// We install an event filter to detect mouse release events because we
|
||||||
// do not receive mouse release event if the floating widget is behind
|
// do not receive mouse release event if the floating widget is behind
|
||||||
// the drop overlay cross
|
// the drop overlay cross
|
||||||
qApp->installEventFilter(this);
|
qApp->installEventFilter(this);
|
||||||
|
|
||||||
|
// Create a static image of the widget that should get undocked
|
||||||
|
// This is like some kind preview image like it is uses in drag and drop
|
||||||
|
// operations
|
||||||
|
if (CDockManager::configFlags().testFlag(CDockManager::DragPreviewShowsContentPixmap))
|
||||||
|
{
|
||||||
|
d->ContentPreviewPixmap = QPixmap(Content->size());
|
||||||
|
Content->render(&d->ContentPreviewPixmap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -181,6 +204,7 @@ CFloatingOverlay::CFloatingOverlay(CDockWidget* Content)
|
|||||||
d->ContentSourceArea = Content->dockAreaWidget();
|
d->ContentSourceArea = Content->dockAreaWidget();
|
||||||
d->ContenSourceContainer = Content->dockContainer();
|
d->ContenSourceContainer = Content->dockContainer();
|
||||||
}
|
}
|
||||||
|
setWindowTitle(Content->windowTitle());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -191,6 +215,7 @@ CFloatingOverlay::CFloatingOverlay(CDockAreaWidget* Content)
|
|||||||
d->DockManager = Content->dockManager();
|
d->DockManager = Content->dockManager();
|
||||||
d->ContentSourceArea = Content;
|
d->ContentSourceArea = Content;
|
||||||
d->ContenSourceContainer = Content->dockContainer();
|
d->ContenSourceContainer = Content->dockContainer();
|
||||||
|
setWindowTitle(Content->currentDockWidget()->windowTitle());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -241,7 +266,6 @@ bool CFloatingOverlay::eventFilter(QObject *watched, QEvent *event)
|
|||||||
if (event->type() == QEvent::MouseButtonRelease && !d->IgnoreMouseEvents)
|
if (event->type() == QEvent::MouseButtonRelease && !d->IgnoreMouseEvents)
|
||||||
{
|
{
|
||||||
ADS_PRINT("FloatingWidget::eventFilter QEvent::MouseButtonRelease");
|
ADS_PRINT("FloatingWidget::eventFilter QEvent::MouseButtonRelease");
|
||||||
std::cout << "CFloatingOverlay::eventFilter QEvent::MouseButtonRelease" << std::endl;
|
|
||||||
|
|
||||||
auto DockDropArea = d->DockManager->dockAreaOverlay()->dropAreaUnderCursor();
|
auto DockDropArea = d->DockManager->dockAreaOverlay()->dropAreaUnderCursor();
|
||||||
auto ContainerDropArea = d->DockManager->containerOverlay()->dropAreaUnderCursor();
|
auto ContainerDropArea = d->DockManager->containerOverlay()->dropAreaUnderCursor();
|
||||||
@ -265,16 +289,22 @@ bool CFloatingOverlay::eventFilter(QObject *watched, QEvent *event)
|
|||||||
}
|
}
|
||||||
FloatingWidget->setGeometry(this->geometry());
|
FloatingWidget->setGeometry(this->geometry());
|
||||||
FloatingWidget->show();
|
FloatingWidget->show();
|
||||||
QApplication::processEvents();
|
if (!CDockManager::configFlags().testFlag(CDockManager::DragPreviewHasWindowFrame))
|
||||||
int FrameHeight = FloatingWidget->frameGeometry().height() - FloatingWidget->geometry().height();
|
{
|
||||||
QRect FixedGeometry = this->geometry();
|
QApplication::processEvents();
|
||||||
FixedGeometry.adjust(0, FrameHeight, 0, 0);
|
int FrameHeight = FloatingWidget->frameGeometry().height() - FloatingWidget->geometry().height();
|
||||||
FloatingWidget->setGeometry(FixedGeometry);
|
QRect FixedGeometry = this->geometry();
|
||||||
|
FixedGeometry.adjust(0, FrameHeight, 0, 0);
|
||||||
|
FloatingWidget->setGeometry(FixedGeometry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->close();
|
this->close();
|
||||||
d->DockManager->containerOverlay()->hideOverlay();
|
d->DockManager->containerOverlay()->hideOverlay();
|
||||||
d->DockManager->dockAreaOverlay()->hideOverlay();
|
d->DockManager->dockAreaOverlay()->hideOverlay();
|
||||||
|
// Because we use the event filter, we receive multiple mouse release
|
||||||
|
// events. To prevent multiple code execution, we ignore all mouse
|
||||||
|
// events after the first mouse event
|
||||||
d->IgnoreMouseEvents = true;
|
d->IgnoreMouseEvents = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,25 +316,31 @@ bool CFloatingOverlay::eventFilter(QObject *watched, QEvent *event)
|
|||||||
void CFloatingOverlay::paintEvent(QPaintEvent* event)
|
void CFloatingOverlay::paintEvent(QPaintEvent* event)
|
||||||
{
|
{
|
||||||
Q_UNUSED(event);
|
Q_UNUSED(event);
|
||||||
|
|
||||||
if (d->Hidden)
|
if (d->Hidden)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect r = rect();
|
|
||||||
QPainter painter(this);
|
QPainter painter(this);
|
||||||
QColor Color = palette().color(QPalette::Active, QPalette::Highlight);
|
if (CDockManager::configFlags().testFlag(CDockManager::DragPreviewShowsContentPixmap))
|
||||||
QPen Pen = painter.pen();
|
{
|
||||||
Pen.setColor(Color.darker(120));
|
painter.drawPixmap(QPoint(0, 0), d->ContentPreviewPixmap);
|
||||||
Pen.setStyle(Qt::SolidLine);
|
}
|
||||||
Pen.setWidth(1);
|
|
||||||
Pen.setCosmetic(true);
|
if (!CDockManager::configFlags().testFlag(CDockManager::DragPreviewHasWindowFrame))
|
||||||
painter.setPen(Pen);
|
{
|
||||||
Color = Color.lighter(130);
|
QColor Color = palette().color(QPalette::Active, QPalette::Highlight);
|
||||||
Color.setAlpha(64);
|
QPen Pen = painter.pen();
|
||||||
painter.setBrush(Color);
|
Pen.setColor(Color.darker(120));
|
||||||
painter.drawRect(r.adjusted(0, 0, -1, -1));
|
Pen.setStyle(Qt::SolidLine);
|
||||||
|
Pen.setWidth(1);
|
||||||
|
Pen.setCosmetic(true);
|
||||||
|
painter.setPen(Pen);
|
||||||
|
Color = Color.lighter(130);
|
||||||
|
Color.setAlpha(64);
|
||||||
|
painter.setBrush(Color);
|
||||||
|
painter.drawRect(rect().adjusted(0, 0, -1, -1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
// INCLUDES
|
// INCLUDES
|
||||||
//============================================================================
|
//============================================================================
|
||||||
#include <QFrame>
|
#include <QWidget>
|
||||||
#include "FloatingDockContainer.h"
|
#include "FloatingDockContainer.h"
|
||||||
|
|
||||||
namespace ads
|
namespace ads
|
||||||
@ -23,7 +23,7 @@ struct FloatingOverlayPrivate;
|
|||||||
* A floating overlay is a temporary floating widget that is just used to
|
* A floating overlay is a temporary floating widget that is just used to
|
||||||
* indicate the floating widget movement
|
* indicate the floating widget movement
|
||||||
*/
|
*/
|
||||||
class CFloatingOverlay : public QFrame, public IFloatingWidget
|
class CFloatingOverlay : public QWidget, public IFloatingWidget
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
FloatingOverlayPrivate* d;
|
FloatingOverlayPrivate* d;
|
||||||
@ -40,7 +40,7 @@ protected:
|
|||||||
CFloatingOverlay(QWidget* Content, QWidget* parent);
|
CFloatingOverlay(QWidget* Content, QWidget* parent);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using Super = QRubberBand;
|
using Super = QWidget;
|
||||||
CFloatingOverlay(CDockWidget* Content);
|
CFloatingOverlay(CDockWidget* Content);
|
||||||
CFloatingOverlay(CDockAreaWidget* Content);
|
CFloatingOverlay(CDockAreaWidget* Content);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user