forked from qt-creator/qt-creator
ADS: Integrate newest base repository commits
* Activate new ADS feature focus highlight * Remove resources.qrc and related *.svg files * Clean up new and existing source Base repository was merged until commit 3de877fe5635ff51a6d1205ca98aad85d204427f Merged changes from base repository include the following: * Fix wrong current index when removing a widget from DockAreaLayout * Fix invisible TabWidget for DockWidgets that are not part of a restored state * Enable ClickFocus for DockWidget to support focussing in case the content does not support it * Move focus related functionality into DockFocusController class * Add new DockManger config flag FocusStyling * Add support for focus styling of FloatingWidgetTitleBar * Improve focus handling when dropping a DockWidget * Improve highlighting focused DockWidget * Improve setting of DockWidgetTab focus * Add styling of focused DockWidget * Fix docking of floating widgets for macOS * Fix setting of DockingStateReader file version - use internal file version instead of user file version * Fix saveState() and restoreState() version handling to work like the function from QMainWindow * Fix escape key handling in native window event function if event WM_EXITSIZEMOVE occurs * Implement windows drag handling with native WM_ nonclient area messages * Fix showing DockArea when inserting a DockWidget in a hidden DockArea * Fix setting DockAreaTabBar index to prevent showing of tab 0 when inserting a DockWidget into an area with no current index tab * Fix wrong insertion order of DockWidget when dropping a floating widget to the left or top container drop area * Fix tab changes position when redocking it to the same position * Add nullptr check to fix potential nullptr access when closing a FloatingDockContainer * Fix single DockArea cannot be split * Fix visibility issue when adding dock widget after all other dock widgets have ben closed * Fix FloatingDragPreview flashing of hidden overlay when dragging the last visible DockWidget in non opaque docking mode * Fix FloatingDragPreview preventing dock widget from floating when dragging over another dock widget * Fix DockWidget::setWidget function to test for QAbstractScrollArea instead of QScrollArea. Now setWidget properly supports ItemViews like QTreeView or QTableView * Fix wrong display of center drop area when dragging over invisible dock area title bar * Fix bug that drop overlay sometimes was not visible when moving the drag preview over a floating window * Fix dropping of FloatingDragPreview into center of dock container with only one single visible dock area. If this happens the dropped dock widget needs to get tabified * Fix crash when trying to make a DockWidget floating in non-opaque mode if the DockWidget is not floatable * Fix DockWidgetTab to provide the right size when starting floating * Add DockWidget functions setAsCurrentTab, raise, isCurrentTab, isTabbed * Add new config flag HideSingleCentralWidgetTitleBar to enable a central single dock widget in the main dock container (dock manager) without titlebar * Fix DockContainerWidget::hasTopLevelDockWidget() and DockContainerWidget::topLevelDockArea() to work properly also for the main non floating dock container * Fix ElidingLabel to properly support Qt::ElideNone * Add setElideMode function to DockWidgetTab * Add setFullScreen(), setNormal() and isFullScreen() function to DockWidget * Fix takeWidget() function and fixed setWidget() function to handle case when there is already a content widget Task-number: QDS-2180 Change-Id: Ie30648ba329016c91fd19e9b4e12e31e47614b18 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
committed by
Henning Gründl
parent
e5d9cb3779
commit
a98c254c59
@@ -7,6 +7,7 @@ add_qtc_library(AdvancedDockingSystem
|
|||||||
dockareawidget.cpp dockareawidget.h
|
dockareawidget.cpp dockareawidget.h
|
||||||
dockcomponentsfactory.cpp dockcomponentsfactory.h
|
dockcomponentsfactory.cpp dockcomponentsfactory.h
|
||||||
dockcontainerwidget.cpp dockcontainerwidget.h
|
dockcontainerwidget.cpp dockcontainerwidget.h
|
||||||
|
dockfocuscontroller.cpp dockfocuscontroller.h
|
||||||
dockingstatereader.cpp dockingstatereader.h
|
dockingstatereader.cpp dockingstatereader.h
|
||||||
dockmanager.cpp dockmanager.h
|
dockmanager.cpp dockmanager.h
|
||||||
dockoverlay.cpp dockoverlay.h
|
dockoverlay.cpp dockoverlay.h
|
||||||
@@ -21,7 +22,6 @@ add_qtc_library(AdvancedDockingSystem
|
|||||||
workspacemodel.cpp workspacemodel.h
|
workspacemodel.cpp workspacemodel.h
|
||||||
workspaceview.cpp workspaceview.h
|
workspaceview.cpp workspaceview.h
|
||||||
workspacedialog.ui
|
workspacedialog.ui
|
||||||
resources.qrc
|
|
||||||
)
|
)
|
||||||
|
|
||||||
extend_qtc_library(AdvancedDockingSystem
|
extend_qtc_library(AdvancedDockingSystem
|
||||||
|
@@ -41,6 +41,7 @@
|
|||||||
|
|
||||||
#include <QAbstractButton>
|
#include <QAbstractButton>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
#include <QStyle>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
|
||||||
namespace ADS {
|
namespace ADS {
|
||||||
@@ -116,5 +117,25 @@ void setButtonIcon(QAbstractButton* button,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void repolishStyle(QWidget *widget, eRepolishChildOptions options)
|
||||||
|
{
|
||||||
|
if (!widget)
|
||||||
|
return;
|
||||||
|
|
||||||
|
widget->style()->unpolish(widget);
|
||||||
|
widget->style()->polish(widget);
|
||||||
|
|
||||||
|
if (RepolishIgnoreChildren == options)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QList<QWidget*> children = widget->findChildren<QWidget *>(QString(),
|
||||||
|
(RepolishDirectChildren == options) ? Qt::FindDirectChildrenOnly : Qt::FindChildrenRecursively);
|
||||||
|
for (auto w : children)
|
||||||
|
{
|
||||||
|
w->style()->unpolish(w);
|
||||||
|
w->style()->polish(w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace ADS
|
} // namespace ADS
|
||||||
|
@@ -72,8 +72,6 @@ QT_END_NAMESPACE
|
|||||||
|
|
||||||
namespace ADS {
|
namespace ADS {
|
||||||
|
|
||||||
enum eStateFileVersion { InitialVerison = 0, Version1 = 1, CurrentVersion = Version1 };
|
|
||||||
|
|
||||||
class DockSplitter;
|
class DockSplitter;
|
||||||
|
|
||||||
enum DockWidgetArea {
|
enum DockWidgetArea {
|
||||||
@@ -228,5 +226,18 @@ void setToolTip(QObjectPtr obj, const QString &tip)
|
|||||||
void setButtonIcon(QAbstractButton *button, QStyle::StandardPixmap standarPixmap,
|
void setButtonIcon(QAbstractButton *button, QStyle::StandardPixmap standarPixmap,
|
||||||
ADS::eIcon CustomIconId);
|
ADS::eIcon CustomIconId);
|
||||||
|
|
||||||
|
enum eRepolishChildOptions
|
||||||
|
{
|
||||||
|
RepolishIgnoreChildren,
|
||||||
|
RepolishDirectChildren,
|
||||||
|
RepolishChildrenRecursively
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls unpolish() / polish for the style of the given widget to update
|
||||||
|
* stylesheet if a property changes
|
||||||
|
*/
|
||||||
|
void repolishStyle(QWidget *widget, eRepolishChildOptions options = RepolishIgnoreChildren);
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace ADS
|
} // namespace ADS
|
||||||
|
@@ -5,9 +5,6 @@ shared {
|
|||||||
}
|
}
|
||||||
|
|
||||||
## Input
|
## Input
|
||||||
RESOURCES += \
|
|
||||||
resources.qrc
|
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
ads_globals.h \
|
ads_globals.h \
|
||||||
dockareatabbar.h \
|
dockareatabbar.h \
|
||||||
@@ -15,6 +12,7 @@ HEADERS += \
|
|||||||
dockareawidget.h \
|
dockareawidget.h \
|
||||||
dockcomponentsfactory.h \
|
dockcomponentsfactory.h \
|
||||||
dockcontainerwidget.h \
|
dockcontainerwidget.h \
|
||||||
|
dockfocuscontroller.h \
|
||||||
dockingstatereader.h \
|
dockingstatereader.h \
|
||||||
dockmanager.h \
|
dockmanager.h \
|
||||||
dockoverlay.h \
|
dockoverlay.h \
|
||||||
@@ -36,6 +34,7 @@ SOURCES += \
|
|||||||
dockareawidget.cpp \
|
dockareawidget.cpp \
|
||||||
dockcomponentsfactory.cpp \
|
dockcomponentsfactory.cpp \
|
||||||
dockcontainerwidget.cpp \
|
dockcontainerwidget.cpp \
|
||||||
|
dockfocuscontroller.cpp \
|
||||||
dockingstatereader.cpp \
|
dockingstatereader.cpp \
|
||||||
dockmanager.cpp \
|
dockmanager.cpp \
|
||||||
dockoverlay.cpp \
|
dockoverlay.cpp \
|
||||||
|
@@ -19,6 +19,7 @@ QtcLibrary {
|
|||||||
"dockareawidget.cpp", "dockareawidget.h",
|
"dockareawidget.cpp", "dockareawidget.h",
|
||||||
"dockcomponentsfactory.cpp", "dockcomponentsfactory.h",
|
"dockcomponentsfactory.cpp", "dockcomponentsfactory.h",
|
||||||
"dockcontainerwidget.cpp", "dockcontainerwidget.h",
|
"dockcontainerwidget.cpp", "dockcontainerwidget.h",
|
||||||
|
"dockfocuscontroller.cpp", "dockfocuscontroller.h",
|
||||||
"dockingstatereader.cpp", "dockingstatereader.h",
|
"dockingstatereader.cpp", "dockingstatereader.h",
|
||||||
"dockmanager.cpp", "dockmanager.h",
|
"dockmanager.cpp", "dockmanager.h",
|
||||||
"dockoverlay.cpp", "dockoverlay.h",
|
"dockoverlay.cpp", "dockoverlay.h",
|
||||||
@@ -32,8 +33,7 @@ QtcLibrary {
|
|||||||
"workspacedialog.cpp", "workspacedialog.h",
|
"workspacedialog.cpp", "workspacedialog.h",
|
||||||
"workspacemodel.cpp", "workspacemodel.h",
|
"workspacemodel.cpp", "workspacemodel.h",
|
||||||
"workspaceview.cpp", "workspaceview.h",
|
"workspaceview.cpp", "workspaceview.h",
|
||||||
"workspacedialog.ui",
|
"workspacedialog.ui"
|
||||||
"resources.qrc"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -140,12 +140,11 @@ namespace ADS
|
|||||||
{
|
{
|
||||||
event->accept();
|
event->accept();
|
||||||
const int direction = event->angleDelta().y();
|
const int direction = event->angleDelta().y();
|
||||||
if (direction < 0) {
|
if (direction < 0)
|
||||||
horizontalScrollBar()->setValue(horizontalScrollBar()->value() + 20);
|
horizontalScrollBar()->setValue(horizontalScrollBar()->value() + 20);
|
||||||
} else {
|
else
|
||||||
horizontalScrollBar()->setValue(horizontalScrollBar()->value() - 20);
|
horizontalScrollBar()->setValue(horizontalScrollBar()->value() - 20);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void DockAreaTabBar::setCurrentIndex(int index)
|
void DockAreaTabBar::setCurrentIndex(int index)
|
||||||
{
|
{
|
||||||
@@ -189,9 +188,11 @@ namespace ADS
|
|||||||
&DockAreaTabBar::elidedChanged);
|
&DockAreaTabBar::elidedChanged);
|
||||||
dockWidgetTab->installEventFilter(this);
|
dockWidgetTab->installEventFilter(this);
|
||||||
emit tabInserted(index);
|
emit tabInserted(index);
|
||||||
if (index <= d->m_currentIndex || d->m_currentIndex == -1) {
|
if (index <= d->m_currentIndex)
|
||||||
setCurrentIndex(d->m_currentIndex + 1);
|
setCurrentIndex(d->m_currentIndex + 1);
|
||||||
}
|
else if (d->m_currentIndex == -1)
|
||||||
|
setCurrentIndex(index);
|
||||||
|
|
||||||
updateGeometry();
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,11 +236,11 @@ namespace ADS
|
|||||||
dockWidgetTab->disconnect(this);
|
dockWidgetTab->disconnect(this);
|
||||||
dockWidgetTab->removeEventFilter(this);
|
dockWidgetTab->removeEventFilter(this);
|
||||||
qCInfo(adsLog) << "NewCurrentIndex " << newCurrentIndex;
|
qCInfo(adsLog) << "NewCurrentIndex " << newCurrentIndex;
|
||||||
if (newCurrentIndex != d->m_currentIndex) {
|
if (newCurrentIndex != d->m_currentIndex)
|
||||||
setCurrentIndex(newCurrentIndex);
|
setCurrentIndex(newCurrentIndex);
|
||||||
} else {
|
else
|
||||||
d->updateTabs();
|
d->updateTabs();
|
||||||
}
|
|
||||||
updateGeometry();
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,13 +248,12 @@ namespace ADS
|
|||||||
|
|
||||||
DockWidgetTab *DockAreaTabBar::currentTab() const
|
DockWidgetTab *DockAreaTabBar::currentTab() const
|
||||||
{
|
{
|
||||||
if (d->m_currentIndex < 0) {
|
if (d->m_currentIndex < 0)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
} else {
|
else
|
||||||
return qobject_cast<DockWidgetTab *>(
|
return qobject_cast<DockWidgetTab *>(
|
||||||
d->m_tabsLayout->itemAt(d->m_currentIndex)->widget());
|
d->m_tabsLayout->itemAt(d->m_currentIndex)->widget());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void DockAreaTabBar::onTabClicked()
|
void DockAreaTabBar::onTabClicked()
|
||||||
{
|
{
|
||||||
@@ -292,12 +292,11 @@ namespace ADS
|
|||||||
// If the the dock widget blocks closing, i.e. if the flag
|
// If the the dock widget blocks closing, i.e. if the flag
|
||||||
// CustomCloseHandling is set, and the dock widget is still open,
|
// CustomCloseHandling is set, and the dock widget is still open,
|
||||||
// then we do not need to correct the index
|
// then we do not need to correct the index
|
||||||
if (currentTab->dockWidget()->isClosed()) {
|
if (currentTab->dockWidget()->isClosed())
|
||||||
i -= offset;
|
i -= offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
DockWidgetTab *DockAreaTabBar::tab(int index) const
|
DockWidgetTab *DockAreaTabBar::tab(int index) const
|
||||||
{
|
{
|
||||||
|
@@ -103,10 +103,11 @@ namespace ADS
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the given config flag is set
|
* Returns true if the given config flag is set
|
||||||
|
* Convenience function to ease config flag testing
|
||||||
*/
|
*/
|
||||||
static bool testConfigFlag(DockManager::eConfigFlag flag)
|
static bool testConfigFlag(DockManager::eConfigFlag flag)
|
||||||
{
|
{
|
||||||
return DockManager::configFlags().testFlag(flag);
|
return DockManager::testConfigFlag(flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -159,7 +160,7 @@ namespace ADS
|
|||||||
|
|
||||||
// Undock button
|
// Undock button
|
||||||
m_undockButton = new TitleBarButton(testConfigFlag(DockManager::DockAreaHasUndockButton));
|
m_undockButton = new TitleBarButton(testConfigFlag(DockManager::DockAreaHasUndockButton));
|
||||||
m_undockButton->setObjectName("undockButton");
|
m_undockButton->setObjectName("detachGroupButton");
|
||||||
m_undockButton->setAutoRaise(true);
|
m_undockButton->setAutoRaise(true);
|
||||||
internal::setToolTip(m_undockButton, QObject::tr("Detach Group"));
|
internal::setToolTip(m_undockButton, QObject::tr("Detach Group"));
|
||||||
internal::setButtonIcon(m_undockButton,
|
internal::setButtonIcon(m_undockButton,
|
||||||
@@ -175,16 +176,16 @@ namespace ADS
|
|||||||
|
|
||||||
// Close button
|
// Close button
|
||||||
m_closeButton = new TitleBarButton(testConfigFlag(DockManager::DockAreaHasCloseButton));
|
m_closeButton = new TitleBarButton(testConfigFlag(DockManager::DockAreaHasCloseButton));
|
||||||
m_closeButton->setObjectName("closeButton");
|
m_closeButton->setObjectName("dockAreaCloseButton");
|
||||||
m_closeButton->setAutoRaise(true);
|
m_closeButton->setAutoRaise(true);
|
||||||
internal::setButtonIcon(m_closeButton,
|
internal::setButtonIcon(m_closeButton,
|
||||||
QStyle::SP_TitleBarCloseButton,
|
QStyle::SP_TitleBarCloseButton,
|
||||||
ADS::DockAreaCloseIcon);
|
ADS::DockAreaCloseIcon);
|
||||||
if (testConfigFlag(DockManager::DockAreaCloseButtonClosesTab)) {
|
if (testConfigFlag(DockManager::DockAreaCloseButtonClosesTab))
|
||||||
internal::setToolTip(m_closeButton, QObject::tr("Close Active Tab"));
|
internal::setToolTip(m_closeButton, QObject::tr("Close Active Tab"));
|
||||||
} else {
|
else
|
||||||
internal::setToolTip(m_closeButton, QObject::tr("Close Group"));
|
internal::setToolTip(m_closeButton, QObject::tr("Close Group"));
|
||||||
}
|
|
||||||
m_closeButton->setSizePolicy(sizePolicy);
|
m_closeButton->setSizePolicy(sizePolicy);
|
||||||
m_closeButton->setIconSize(iconSize);
|
m_closeButton->setIconSize(iconSize);
|
||||||
m_layout->addWidget(m_closeButton, 0);
|
m_layout->addWidget(m_closeButton, 0);
|
||||||
@@ -238,7 +239,7 @@ namespace ADS
|
|||||||
{
|
{
|
||||||
QSize size = m_dockArea->size();
|
QSize size = m_dockArea->size();
|
||||||
m_dragState = dragState;
|
m_dragState = dragState;
|
||||||
bool opaqueUndocking = DockManager::configFlags().testFlag(DockManager::OpaqueUndocking)
|
bool opaqueUndocking = DockManager::testConfigFlag(DockManager::OpaqueUndocking)
|
||||||
|| (DraggingFloatingWidget != dragState);
|
|| (DraggingFloatingWidget != dragState);
|
||||||
FloatingDockContainer *floatingDockContainer = nullptr;
|
FloatingDockContainer *floatingDockContainer = nullptr;
|
||||||
AbstractFloatingWidget *floatingWidget;
|
AbstractFloatingWidget *floatingWidget;
|
||||||
@@ -269,9 +270,9 @@ namespace ADS
|
|||||||
}
|
}
|
||||||
|
|
||||||
TitleBarButton::TitleBarButton(bool visible, QWidget *parent)
|
TitleBarButton::TitleBarButton(bool visible, QWidget *parent)
|
||||||
: TitleBarButtonType(parent),
|
: TitleBarButtonType(parent)
|
||||||
m_visible(visible),
|
, m_visible(visible)
|
||||||
m_hideWhenDisabled(DockAreaTitleBarPrivate::testConfigFlag(DockManager::DockAreaHideDisabledButtons))
|
, m_hideWhenDisabled(DockAreaTitleBarPrivate::testConfigFlag(DockManager::DockAreaHideDisabledButtons))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void TitleBarButton::setVisible(bool visible)
|
void TitleBarButton::setVisible(bool visible)
|
||||||
@@ -281,9 +282,8 @@ namespace ADS
|
|||||||
|
|
||||||
// 'visible' can stay 'true' unless: this button is configured to be invisible when it
|
// 'visible' can stay 'true' unless: this button is configured to be invisible when it
|
||||||
// is disabled and it is currently disabled:
|
// is disabled and it is currently disabled:
|
||||||
if (visible && m_hideWhenDisabled) {
|
if (visible && m_hideWhenDisabled)
|
||||||
visible = isEnabled();
|
visible = isEnabled();
|
||||||
}
|
|
||||||
|
|
||||||
Super::setVisible(visible);
|
Super::setVisible(visible);
|
||||||
}
|
}
|
||||||
@@ -360,9 +360,8 @@ namespace ADS
|
|||||||
|
|
||||||
void DockAreaTitleBar::onTabsMenuAboutToShow()
|
void DockAreaTitleBar::onTabsMenuAboutToShow()
|
||||||
{
|
{
|
||||||
if (!d->m_menuOutdated) {
|
if (!d->m_menuOutdated)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
QMenu *menu = d->m_tabsMenuButton->menu();
|
QMenu *menu = d->m_tabsMenuButton->menu();
|
||||||
menu->clear();
|
menu->clear();
|
||||||
@@ -382,19 +381,17 @@ namespace ADS
|
|||||||
void DockAreaTitleBar::onCloseButtonClicked()
|
void DockAreaTitleBar::onCloseButtonClicked()
|
||||||
{
|
{
|
||||||
qCInfo(adsLog) << Q_FUNC_INFO;
|
qCInfo(adsLog) << Q_FUNC_INFO;
|
||||||
if (d->testConfigFlag(DockManager::DockAreaCloseButtonClosesTab)) {
|
if (d->testConfigFlag(DockManager::DockAreaCloseButtonClosesTab))
|
||||||
d->m_tabBar->closeTab(d->m_tabBar->currentIndex());
|
d->m_tabBar->closeTab(d->m_tabBar->currentIndex());
|
||||||
} else {
|
else
|
||||||
d->m_dockArea->closeArea();
|
d->m_dockArea->closeArea();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void DockAreaTitleBar::onUndockButtonClicked()
|
void DockAreaTitleBar::onUndockButtonClicked()
|
||||||
{
|
{
|
||||||
if (d->m_dockArea->features().testFlag(DockWidget::DockWidgetFloatable)) {
|
if (d->m_dockArea->features().testFlag(DockWidget::DockWidgetFloatable))
|
||||||
d->makeAreaFloating(mapFromGlobal(QCursor::pos()), DraggingInactive);
|
d->makeAreaFloating(mapFromGlobal(QCursor::pos()), DraggingInactive);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void DockAreaTitleBar::onTabsMenuActionTriggered(QAction *action)
|
void DockAreaTitleBar::onTabsMenuActionTriggered(QAction *action)
|
||||||
{
|
{
|
||||||
@@ -470,6 +467,9 @@ namespace ADS
|
|||||||
event->accept();
|
event->accept();
|
||||||
d->m_dragStartMousePos = event->pos();
|
d->m_dragStartMousePos = event->pos();
|
||||||
d->m_dragState = DraggingMousePressed;
|
d->m_dragState = DraggingMousePressed;
|
||||||
|
if (DockManager::testConfigFlag(DockManager::FocusHighlighting))
|
||||||
|
d->m_tabBar->currentTab()->setFocus(Qt::OtherFocusReason);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Super::mousePressEvent(event);
|
Super::mousePressEvent(event);
|
||||||
@@ -505,7 +505,7 @@ namespace ADS
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is the last dock area in a dock container it does not make
|
// If this is the last dock area in a floating dock container it does not make
|
||||||
// sense to move it to a new floating widget and leave this one empty
|
// sense to move it to a new floating widget and leave this one empty
|
||||||
if (d->m_dockArea->dockContainer()->isFloating()
|
if (d->m_dockArea->dockContainer()->isFloating()
|
||||||
&& d->m_dockArea->dockContainer()->visibleDockAreaCount() == 1) {
|
&& d->m_dockArea->dockContainer()->visibleDockAreaCount() == 1) {
|
||||||
@@ -525,7 +525,7 @@ namespace ADS
|
|||||||
|
|
||||||
int dragDistance = (d->m_dragStartMousePos - event->pos()).manhattanLength();
|
int dragDistance = (d->m_dragStartMousePos - event->pos()).manhattanLength();
|
||||||
if (dragDistance >= DockManager::startDragDistance()) {
|
if (dragDistance >= DockManager::startDragDistance()) {
|
||||||
qCInfo(adsLog) << "TabsScrollArea::startFloating";
|
qCInfo(adsLog) << "DockAreaTitlBar::startFloating";
|
||||||
d->startFloating(d->m_dragStartMousePos);
|
d->startFloating(d->m_dragStartMousePos);
|
||||||
auto overlay = d->m_dockArea->dockManager()->containerOverlay();
|
auto overlay = d->m_dockArea->dockManager()->containerOverlay();
|
||||||
overlay->setAllowedAreas(OuterDockAreas);
|
overlay->setAllowedAreas(OuterDockAreas);
|
||||||
|
@@ -103,18 +103,17 @@ namespace ADS
|
|||||||
void insertWidget(int index, QWidget *widget)
|
void insertWidget(int index, QWidget *widget)
|
||||||
{
|
{
|
||||||
widget->setParent(nullptr);
|
widget->setParent(nullptr);
|
||||||
if (index < 0) {
|
if (index < 0)
|
||||||
index = m_widgets.count();
|
index = m_widgets.count();
|
||||||
}
|
|
||||||
m_widgets.insert(index, widget);
|
m_widgets.insert(index, widget);
|
||||||
if (m_currentIndex < 0) {
|
if (m_currentIndex < 0) {
|
||||||
setCurrentIndex(index);
|
setCurrentIndex(index);
|
||||||
} else {
|
} else {
|
||||||
if (index <= m_currentIndex) {
|
if (index <= m_currentIndex)
|
||||||
++m_currentIndex;
|
++m_currentIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the given widget from the layout
|
* Removes the given widget from the layout
|
||||||
@@ -123,11 +122,13 @@ namespace ADS
|
|||||||
{
|
{
|
||||||
if (currentWidget() == widget) {
|
if (currentWidget() == widget) {
|
||||||
auto layoutItem = m_parentLayout->takeAt(1);
|
auto layoutItem = m_parentLayout->takeAt(1);
|
||||||
if (layoutItem) {
|
if (layoutItem)
|
||||||
layoutItem->widget()->setParent(nullptr);
|
layoutItem->widget()->setParent(nullptr);
|
||||||
}
|
|
||||||
m_currentWidget = nullptr;
|
m_currentWidget = nullptr;
|
||||||
m_currentIndex = -1;
|
m_currentIndex = -1;
|
||||||
|
} else if (indexOf(widget) < m_currentIndex) {
|
||||||
|
--m_currentIndex;
|
||||||
}
|
}
|
||||||
m_widgets.removeOne(widget);
|
m_widgets.removeOne(widget);
|
||||||
}
|
}
|
||||||
@@ -144,9 +145,8 @@ namespace ADS
|
|||||||
{
|
{
|
||||||
QWidget *prev = currentWidget();
|
QWidget *prev = currentWidget();
|
||||||
QWidget *next = widget(index);
|
QWidget *next = widget(index);
|
||||||
if (!next || (next == prev && !m_currentWidget)) {
|
if (!next || (next == prev && !m_currentWidget))
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
bool reenableUpdates = false;
|
bool reenableUpdates = false;
|
||||||
QWidget *parent = m_parentLayout->parentWidget();
|
QWidget *parent = m_parentLayout->parentWidget();
|
||||||
@@ -156,23 +156,19 @@ namespace ADS
|
|||||||
parent->setUpdatesEnabled(false);
|
parent->setUpdatesEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
if (auto layoutItem = m_parentLayout->takeAt(1))
|
||||||
auto layoutItem = m_parentLayout->takeAt(1);
|
|
||||||
if (layoutItem) {
|
|
||||||
layoutItem->widget()->setParent(nullptr);
|
layoutItem->widget()->setParent(nullptr);
|
||||||
}
|
|
||||||
|
|
||||||
m_parentLayout->addWidget(next);
|
m_parentLayout->addWidget(next);
|
||||||
if (prev) {
|
if (prev)
|
||||||
prev->hide();
|
prev->hide();
|
||||||
}
|
|
||||||
m_currentIndex = index;
|
m_currentIndex = index;
|
||||||
m_currentWidget = next;
|
m_currentWidget = next;
|
||||||
|
|
||||||
if (reenableUpdates) {
|
if (reenableUpdates)
|
||||||
parent->setUpdatesEnabled(true);
|
parent->setUpdatesEnabled(true);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the index of the current active widget
|
* Returns the index of the current active widget
|
||||||
@@ -262,7 +258,7 @@ namespace ADS
|
|||||||
DockAreaTabBar *tabBar() const { return m_titleBar->tabBar(); }
|
DockAreaTabBar *tabBar() const { return m_titleBar->tabBar(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Udpates the enable state of the close and detach button
|
* Updates the enable state of the close and detach button
|
||||||
*/
|
*/
|
||||||
void updateTitleBarButtonStates();
|
void updateTitleBarButtonStates();
|
||||||
|
|
||||||
@@ -330,10 +326,9 @@ namespace ADS
|
|||||||
|
|
||||||
d->createTitleBar();
|
d->createTitleBar();
|
||||||
d->m_contentsLayout = new DockAreaLayout(d->m_layout);
|
d->m_contentsLayout = new DockAreaLayout(d->m_layout);
|
||||||
if (d->m_dockManager) {
|
if (d->m_dockManager)
|
||||||
emit d->m_dockManager->dockAreaCreated(this);
|
emit d->m_dockManager->dockAreaCreated(this);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
DockAreaWidget::~DockAreaWidget()
|
DockAreaWidget::~DockAreaWidget()
|
||||||
{
|
{
|
||||||
@@ -357,6 +352,7 @@ namespace ADS
|
|||||||
void DockAreaWidget::insertDockWidget(int index, DockWidget *dockWidget, bool activate)
|
void DockAreaWidget::insertDockWidget(int index, DockWidget *dockWidget, bool activate)
|
||||||
{
|
{
|
||||||
d->m_contentsLayout->insertWidget(index, dockWidget);
|
d->m_contentsLayout->insertWidget(index, dockWidget);
|
||||||
|
dockWidget->setDockArea(this);
|
||||||
dockWidget->tabWidget()->setDockAreaWidget(this);
|
dockWidget->tabWidget()->setDockAreaWidget(this);
|
||||||
auto tabWidget = dockWidget->tabWidget();
|
auto tabWidget = dockWidget->tabWidget();
|
||||||
// Inserting the tab will change the current index which in turn will
|
// Inserting the tab will change the current index which in turn will
|
||||||
@@ -370,10 +366,14 @@ namespace ADS
|
|||||||
dockWidget->minimumSizeHint().height()));
|
dockWidget->minimumSizeHint().height()));
|
||||||
d->m_minSizeHint.setWidth(qMax(d->m_minSizeHint.width(),
|
d->m_minSizeHint.setWidth(qMax(d->m_minSizeHint.width(),
|
||||||
dockWidget->minimumSizeHint().width()));
|
dockWidget->minimumSizeHint().width()));
|
||||||
if (activate) {
|
if (activate)
|
||||||
setCurrentIndex(index);
|
setCurrentIndex(index);
|
||||||
}
|
|
||||||
dockWidget->setDockArea(this);
|
// If this dock area is hidden, then we need to make it visible again
|
||||||
|
// by calling dockWidget->toggleViewInternal(true);
|
||||||
|
if (!this->isVisible() && d->m_contentsLayout->count() > 1 && !dockManager()->isRestoringState())
|
||||||
|
dockWidget->toggleViewInternal(true);
|
||||||
|
|
||||||
d->updateTitleBarButtonStates();
|
d->updateTitleBarButtonStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -389,7 +389,7 @@ namespace ADS
|
|||||||
DockContainerWidget *dockContainerWidget = dockContainer();
|
DockContainerWidget *dockContainerWidget = dockContainer();
|
||||||
if (nextOpen) {
|
if (nextOpen) {
|
||||||
setCurrentDockWidget(nextOpen);
|
setCurrentDockWidget(nextOpen);
|
||||||
} else if (d->m_contentsLayout->isEmpty() && dockContainerWidget->dockAreaCount() > 1) {
|
} else if (d->m_contentsLayout->isEmpty() && dockContainerWidget->dockAreaCount() >= 1) {
|
||||||
qCInfo(adsLog) << "Dock Area empty";
|
qCInfo(adsLog) << "Dock Area empty";
|
||||||
dockContainerWidget->removeDockArea(this);
|
dockContainerWidget->removeDockArea(this);
|
||||||
this->deleteLater();
|
this->deleteLater();
|
||||||
@@ -404,9 +404,8 @@ namespace ADS
|
|||||||
updateTitleBarVisibility();
|
updateTitleBarVisibility();
|
||||||
d->updateMinimumSizeHint();
|
d->updateMinimumSizeHint();
|
||||||
auto topLevelDockWidget = dockContainerWidget->topLevelDockWidget();
|
auto topLevelDockWidget = dockContainerWidget->topLevelDockWidget();
|
||||||
if (topLevelDockWidget) {
|
if (topLevelDockWidget)
|
||||||
topLevelDockWidget->emitTopLevelChanged(true);
|
topLevelDockWidget->emitTopLevelChanged(true);
|
||||||
}
|
|
||||||
|
|
||||||
#if (ADS_DEBUG_LEVEL > 0)
|
#if (ADS_DEBUG_LEVEL > 0)
|
||||||
dockContainerWidget->dumpLayout();
|
dockContainerWidget->dumpLayout();
|
||||||
@@ -423,17 +422,19 @@ namespace ADS
|
|||||||
|
|
||||||
//Hide empty floating widget
|
//Hide empty floating widget
|
||||||
DockContainerWidget *container = this->dockContainer();
|
DockContainerWidget *container = this->dockContainer();
|
||||||
if (!container->isFloating()) {
|
if (!container->isFloating()
|
||||||
|
&& DockManager::testConfigFlag(DockManager::HideSingleCentralWidgetTitleBar))
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
updateTitleBarVisibility();
|
updateTitleBarVisibility();
|
||||||
auto topLevelWidget = container->topLevelDockWidget();
|
auto topLevelWidget = container->topLevelDockWidget();
|
||||||
auto floatingWidget = container->floatingWidget();
|
auto floatingWidget = container->floatingWidget();
|
||||||
if (topLevelWidget) {
|
if (topLevelWidget) {
|
||||||
|
if (floatingWidget)
|
||||||
floatingWidget->updateWindowTitle();
|
floatingWidget->updateWindowTitle();
|
||||||
|
|
||||||
DockWidget::emitTopLevelEventForWidget(topLevelWidget, true);
|
DockWidget::emitTopLevelEventForWidget(topLevelWidget, true);
|
||||||
} else if (container->openedDockAreas().isEmpty()) {
|
} else if (container->openedDockAreas().isEmpty() && floatingWidget) {
|
||||||
floatingWidget->hide();
|
floatingWidget->hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -442,28 +443,25 @@ namespace ADS
|
|||||||
{
|
{
|
||||||
qCInfo(adsLog) << Q_FUNC_INFO << "index" << index;
|
qCInfo(adsLog) << Q_FUNC_INFO << "index" << index;
|
||||||
auto *currentDockWidget = dockWidget(index);
|
auto *currentDockWidget = dockWidget(index);
|
||||||
if (currentDockWidget->features().testFlag(DockWidget::DockWidgetDeleteOnClose)) {
|
if (currentDockWidget->features().testFlag(DockWidget::DockWidgetDeleteOnClose))
|
||||||
currentDockWidget->closeDockWidgetInternal();
|
currentDockWidget->closeDockWidgetInternal();
|
||||||
} else {
|
else
|
||||||
currentDockWidget->toggleView(false);
|
currentDockWidget->toggleView(false);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
DockWidget *DockAreaWidget::currentDockWidget() const
|
DockWidget *DockAreaWidget::currentDockWidget() const
|
||||||
{
|
{
|
||||||
int currentIdx = currentIndex();
|
int currentIdx = currentIndex();
|
||||||
if (currentIdx < 0) {
|
if (currentIdx < 0)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
return dockWidget(currentIdx);
|
return dockWidget(currentIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DockAreaWidget::setCurrentDockWidget(DockWidget *dockWidget)
|
void DockAreaWidget::setCurrentDockWidget(DockWidget *dockWidget)
|
||||||
{
|
{
|
||||||
if (dockManager()->isRestoringState()) {
|
if (dockManager()->isRestoringState())
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
internalSetCurrentDockWidget(dockWidget);
|
internalSetCurrentDockWidget(dockWidget);
|
||||||
}
|
}
|
||||||
@@ -471,9 +469,8 @@ namespace ADS
|
|||||||
void DockAreaWidget::internalSetCurrentDockWidget(DockWidget *dockWidget)
|
void DockAreaWidget::internalSetCurrentDockWidget(DockWidget *dockWidget)
|
||||||
{
|
{
|
||||||
int index = indexOf(dockWidget);
|
int index = indexOf(dockWidget);
|
||||||
if (index < 0) {
|
if (index < 0)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
setCurrentIndex(index);
|
setCurrentIndex(index);
|
||||||
}
|
}
|
||||||
@@ -488,9 +485,8 @@ namespace ADS
|
|||||||
|
|
||||||
auto cw = d->m_contentsLayout->currentWidget();
|
auto cw = d->m_contentsLayout->currentWidget();
|
||||||
auto nw = d->m_contentsLayout->widget(index);
|
auto nw = d->m_contentsLayout->widget(index);
|
||||||
if (cw == nw && !nw->isHidden()) {
|
if (cw == nw && !nw->isHidden())
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
emit currentChanging(index);
|
emit currentChanging(index);
|
||||||
currentTabBar->setCurrentIndex(index);
|
currentTabBar->setCurrentIndex(index);
|
||||||
@@ -513,9 +509,9 @@ namespace ADS
|
|||||||
QList<DockWidget *> DockAreaWidget::dockWidgets() const
|
QList<DockWidget *> DockAreaWidget::dockWidgets() const
|
||||||
{
|
{
|
||||||
QList<DockWidget *> dockWidgetList;
|
QList<DockWidget *> dockWidgetList;
|
||||||
for (int i = 0; i < d->m_contentsLayout->count(); ++i) {
|
for (int i = 0; i < d->m_contentsLayout->count(); ++i)
|
||||||
dockWidgetList.append(dockWidget(i));
|
dockWidgetList.append(dockWidget(i));
|
||||||
}
|
|
||||||
return dockWidgetList;
|
return dockWidgetList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -523,10 +519,9 @@ namespace ADS
|
|||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (int i = 0; i < d->m_contentsLayout->count(); ++i) {
|
for (int i = 0; i < d->m_contentsLayout->count(); ++i) {
|
||||||
if (!dockWidget(i)->isClosed()) {
|
if (!dockWidget(i)->isClosed())
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -535,20 +530,18 @@ namespace ADS
|
|||||||
QList<DockWidget *> dockWidgetList;
|
QList<DockWidget *> dockWidgetList;
|
||||||
for (int i = 0; i < d->m_contentsLayout->count(); ++i) {
|
for (int i = 0; i < d->m_contentsLayout->count(); ++i) {
|
||||||
DockWidget *currentDockWidget = dockWidget(i);
|
DockWidget *currentDockWidget = dockWidget(i);
|
||||||
if (!currentDockWidget->isClosed()) {
|
if (!currentDockWidget->isClosed())
|
||||||
dockWidgetList.append(dockWidget(i));
|
dockWidgetList.append(dockWidget(i));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return dockWidgetList;
|
return dockWidgetList;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DockAreaWidget::indexOfFirstOpenDockWidget() const
|
int DockAreaWidget::indexOfFirstOpenDockWidget() const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < d->m_contentsLayout->count(); ++i) {
|
for (int i = 0; i < d->m_contentsLayout->count(); ++i) {
|
||||||
if (!dockWidget(i)->isClosed()) {
|
if (!dockWidget(i)->isClosed())
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return - 1;
|
return - 1;
|
||||||
}
|
}
|
||||||
@@ -585,25 +578,24 @@ namespace ADS
|
|||||||
void DockAreaWidget::updateTitleBarVisibility()
|
void DockAreaWidget::updateTitleBarVisibility()
|
||||||
{
|
{
|
||||||
DockContainerWidget *container = dockContainer();
|
DockContainerWidget *container = dockContainer();
|
||||||
if (!container) {
|
if (!container)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (DockManager::configFlags().testFlag(DockManager::AlwaysShowTabs)) {
|
if (DockManager::testConfigFlag(DockManager::AlwaysShowTabs))
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (d->m_titleBar) {
|
if (d->m_titleBar) {
|
||||||
d->m_titleBar->setVisible(!container->isFloating() || !container->hasTopLevelDockWidget());
|
bool hidden = container->hasTopLevelDockWidget() && (container->isFloating()
|
||||||
|
|| DockManager::testConfigFlag(DockManager::HideSingleCentralWidgetTitleBar));
|
||||||
|
d->m_titleBar->setVisible(!hidden);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DockAreaWidget::markTitleBarMenuOutdated()
|
void DockAreaWidget::markTitleBarMenuOutdated()
|
||||||
{
|
{
|
||||||
if (d->m_titleBar) {
|
if (d->m_titleBar)
|
||||||
d->m_titleBar->markTabsMenuOutdated();
|
d->m_titleBar->markTabsMenuOutdated();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void DockAreaWidget::saveState(QXmlStreamWriter &stream) const
|
void DockAreaWidget::saveState(QXmlStreamWriter &stream) const
|
||||||
{
|
{
|
||||||
@@ -614,9 +606,9 @@ namespace ADS
|
|||||||
stream.writeAttribute("current", name);
|
stream.writeAttribute("current", name);
|
||||||
qCInfo(adsLog) << Q_FUNC_INFO << "TabCount: " << d->m_contentsLayout->count()
|
qCInfo(adsLog) << Q_FUNC_INFO << "TabCount: " << d->m_contentsLayout->count()
|
||||||
<< " Current: " << name;
|
<< " Current: " << name;
|
||||||
for (int i = 0; i < d->m_contentsLayout->count(); ++i) {
|
for (int i = 0; i < d->m_contentsLayout->count(); ++i)
|
||||||
dockWidget(i)->saveState(stream);
|
dockWidget(i)->saveState(stream);
|
||||||
}
|
|
||||||
stream.writeEndElement();
|
stream.writeEndElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -643,15 +635,15 @@ namespace ADS
|
|||||||
{
|
{
|
||||||
if (BitwiseAnd == mode) {
|
if (BitwiseAnd == mode) {
|
||||||
DockWidget::DockWidgetFeatures features(DockWidget::AllDockWidgetFeatures);
|
DockWidget::DockWidgetFeatures features(DockWidget::AllDockWidgetFeatures);
|
||||||
for (const auto dockWidget : dockWidgets()) {
|
for (const auto dockWidget : dockWidgets())
|
||||||
features &= dockWidget->features();
|
features &= dockWidget->features();
|
||||||
}
|
|
||||||
return features;
|
return features;
|
||||||
} else {
|
} else {
|
||||||
DockWidget::DockWidgetFeatures features(DockWidget::NoDockWidgetFeatures);
|
DockWidget::DockWidgetFeatures features(DockWidget::NoDockWidgetFeatures);
|
||||||
for (const auto dockWidget : dockWidgets()) {
|
for (const auto dockWidget : dockWidgets())
|
||||||
features |= dockWidget->features();
|
features |= dockWidget->features();
|
||||||
}
|
|
||||||
return features;
|
return features;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -666,10 +658,9 @@ namespace ADS
|
|||||||
void DockAreaWidget::setVisible(bool visible)
|
void DockAreaWidget::setVisible(bool visible)
|
||||||
{
|
{
|
||||||
Super::setVisible(visible);
|
Super::setVisible(visible);
|
||||||
if (d->m_updateTitleBarButtons) {
|
if (d->m_updateTitleBarButtons)
|
||||||
d->updateTitleBarButtonStates();
|
d->updateTitleBarButtonStates();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void DockAreaWidget::setAllowedAreas(DockWidgetAreas areas)
|
void DockAreaWidget::setAllowedAreas(DockWidgetAreas areas)
|
||||||
{
|
{
|
||||||
@@ -695,11 +686,10 @@ namespace ADS
|
|||||||
&& openDockWidgets[0]->features().testFlag(DockWidget::DockWidgetDeleteOnClose)) {
|
&& openDockWidgets[0]->features().testFlag(DockWidget::DockWidgetDeleteOnClose)) {
|
||||||
openDockWidgets[0]->closeDockWidgetInternal();
|
openDockWidgets[0]->closeDockWidgetInternal();
|
||||||
} else {
|
} else {
|
||||||
for (auto dockWidget : openedDockWidgets()) {
|
for (auto dockWidget : openedDockWidgets())
|
||||||
dockWidget->toggleView(false);
|
dockWidget->toggleView(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void DockAreaWidget::closeOtherAreas() { dockContainer()->closeOtherAreas(this); }
|
void DockAreaWidget::closeOtherAreas() { dockContainer()->closeOtherAreas(this); }
|
||||||
|
|
||||||
|
@@ -95,12 +95,11 @@ namespace ADS
|
|||||||
*/
|
*/
|
||||||
static void insertWidgetIntoSplitter(QSplitter *splitter, QWidget *widget, bool append)
|
static void insertWidgetIntoSplitter(QSplitter *splitter, QWidget *widget, bool append)
|
||||||
{
|
{
|
||||||
if (append) {
|
if (append)
|
||||||
splitter->addWidget(widget);
|
splitter->addWidget(widget);
|
||||||
} else {
|
else
|
||||||
splitter->insertWidget(0, widget);
|
splitter->insertWidget(0, widget);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private data class of DockContainerWidget class (pimpl)
|
* Private data class of DockContainerWidget class (pimpl)
|
||||||
@@ -128,12 +127,12 @@ namespace ADS
|
|||||||
* Adds dock widget to container and returns the dock area that contains
|
* Adds dock widget to container and returns the dock area that contains
|
||||||
* the inserted dock widget
|
* the inserted dock widget
|
||||||
*/
|
*/
|
||||||
DockAreaWidget *dockWidgetIntoContainer(DockWidgetArea area, DockWidget *dockWidget);
|
DockAreaWidget *addDockWidgetToContainer(DockWidgetArea area, DockWidget *dockWidget);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds dock widget to a existing DockWidgetArea
|
* Adds dock widget to a existing DockWidgetArea
|
||||||
*/
|
*/
|
||||||
DockAreaWidget *dockWidgetIntoDockArea(DockWidgetArea area,
|
DockAreaWidget *addDockWidgetToDockArea(DockWidgetArea area,
|
||||||
DockWidget *dockWidget,
|
DockWidget *dockWidget,
|
||||||
DockAreaWidget *targetDockArea);
|
DockAreaWidget *targetDockArea);
|
||||||
|
|
||||||
@@ -233,22 +232,20 @@ namespace ADS
|
|||||||
*/
|
*/
|
||||||
void initVisibleDockAreaCount()
|
void initVisibleDockAreaCount()
|
||||||
{
|
{
|
||||||
if (m_visibleDockAreaCount > -1) {
|
if (m_visibleDockAreaCount > -1)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
m_visibleDockAreaCount = 0;
|
m_visibleDockAreaCount = 0;
|
||||||
for (auto dockArea : m_dockAreas) {
|
for (auto dockArea : m_dockAreas)
|
||||||
m_visibleDockAreaCount += dockArea->isHidden() ? 0 : 1;
|
m_visibleDockAreaCount += dockArea->isHidden() ? 0 : 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Access function for the visible dock area counter
|
* Access function for the visible dock area counter
|
||||||
*/
|
*/
|
||||||
int visibleDockAreaCount()
|
int visibleDockAreaCount()
|
||||||
{
|
{
|
||||||
// Lazy initialization - we initialize the VisibleDockAreaCount variable
|
// Lazy initialization - we initialize the m_visibleDockAreaCount variable
|
||||||
// on first use
|
// on first use
|
||||||
initVisibleDockAreaCount();
|
initVisibleDockAreaCount();
|
||||||
return m_visibleDockAreaCount;
|
return m_visibleDockAreaCount;
|
||||||
@@ -278,12 +275,29 @@ namespace ADS
|
|||||||
DockSplitter *createSplitter(Qt::Orientation orientation, QWidget *parent = nullptr)
|
DockSplitter *createSplitter(Qt::Orientation orientation, QWidget *parent = nullptr)
|
||||||
{
|
{
|
||||||
auto *splitter = new DockSplitter(orientation, parent);
|
auto *splitter = new DockSplitter(orientation, parent);
|
||||||
splitter->setOpaqueResize(
|
splitter->setOpaqueResize(DockManager::testConfigFlag(DockManager::OpaqueSplitterResize));
|
||||||
DockManager::configFlags().testFlag(DockManager::OpaqueSplitterResize));
|
|
||||||
splitter->setChildrenCollapsible(false);
|
splitter->setChildrenCollapsible(false);
|
||||||
return splitter;
|
return splitter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures equal distribution of the sizes of a splitter if an dock widget
|
||||||
|
* is inserted from code
|
||||||
|
*/
|
||||||
|
void adjustSplitterSizesOnInsertion(QSplitter *splitter, qreal lastRatio = 1.0)
|
||||||
|
{
|
||||||
|
const int areaSize = (splitter->orientation() == Qt::Horizontal) ? splitter->width()
|
||||||
|
: splitter->height();
|
||||||
|
auto splitterSizes = splitter->sizes();
|
||||||
|
|
||||||
|
const qreal totalRatio = splitterSizes.size() - 1.0 + lastRatio;
|
||||||
|
for (int i = 0; i < splitterSizes.size() - 1; ++i)
|
||||||
|
splitterSizes[i] = areaSize / totalRatio;
|
||||||
|
|
||||||
|
splitterSizes.back() = areaSize * lastRatio / totalRatio;
|
||||||
|
splitter->setSizes(splitterSizes);
|
||||||
|
}
|
||||||
|
|
||||||
void onDockAreaViewToggled(bool visible)
|
void onDockAreaViewToggled(bool visible)
|
||||||
{
|
{
|
||||||
DockAreaWidget *dockArea = qobject_cast<DockAreaWidget *>(q->sender());
|
DockAreaWidget *dockArea = qobject_cast<DockAreaWidget *>(q->sender());
|
||||||
@@ -309,9 +323,8 @@ namespace ADS
|
|||||||
auto dropOverlay = m_dockManager->dockAreaOverlay();
|
auto dropOverlay = m_dockManager->dockAreaOverlay();
|
||||||
dropOverlay->setAllowedAreas(dockArea->allowedAreas());
|
dropOverlay->setAllowedAreas(dockArea->allowedAreas());
|
||||||
dropArea = dropOverlay->showOverlay(dockArea);
|
dropArea = dropOverlay->showOverlay(dockArea);
|
||||||
if (containerDropArea != InvalidDockWidgetArea && containerDropArea != dropArea) {
|
if (containerDropArea != InvalidDockWidgetArea && containerDropArea != dropArea)
|
||||||
dropArea = InvalidDockWidgetArea;
|
dropArea = InvalidDockWidgetArea;
|
||||||
}
|
|
||||||
|
|
||||||
if (dropArea != InvalidDockWidgetArea) {
|
if (dropArea != InvalidDockWidgetArea) {
|
||||||
qCInfo(adsLog) << "Dock Area Drop Content: " << dropArea;
|
qCInfo(adsLog) << "Dock Area Drop Content: " << dropArea;
|
||||||
@@ -323,10 +336,9 @@ namespace ADS
|
|||||||
if (InvalidDockWidgetArea == dropArea) {
|
if (InvalidDockWidgetArea == dropArea) {
|
||||||
dropArea = containerDropArea;
|
dropArea = containerDropArea;
|
||||||
qCInfo(adsLog) << "Container Drop Content: " << dropArea;
|
qCInfo(adsLog) << "Container Drop Content: " << dropArea;
|
||||||
if (dropArea != InvalidDockWidgetArea) {
|
if (dropArea != InvalidDockWidgetArea)
|
||||||
return DropModeIntoContainer;
|
return DropModeIntoContainer;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return DropModeInvalid;
|
return DropModeInvalid;
|
||||||
}
|
}
|
||||||
@@ -373,11 +385,9 @@ namespace ADS
|
|||||||
if (floatingSplitter->count() == 1) {
|
if (floatingSplitter->count() == 1) {
|
||||||
insertWidgetIntoSplitter(splitter, floatingSplitter->widget(0), insertParam.append());
|
insertWidgetIntoSplitter(splitter, floatingSplitter->widget(0), insertParam.append());
|
||||||
} else if (floatingSplitter->orientation() == insertParam.orientation()) {
|
} else if (floatingSplitter->orientation() == insertParam.orientation()) {
|
||||||
while (floatingSplitter->count()) {
|
int insertIndex = insertParam.append() ? splitter->count() : 0;
|
||||||
insertWidgetIntoSplitter(splitter,
|
while (floatingSplitter->count())
|
||||||
floatingSplitter->widget(0),
|
splitter->insertWidget(insertIndex++, floatingSplitter->widget(0));
|
||||||
insertParam.append());
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
insertWidgetIntoSplitter(splitter, floatingSplitter, insertParam.append());
|
insertWidgetIntoSplitter(splitter, floatingSplitter, insertParam.append());
|
||||||
}
|
}
|
||||||
@@ -388,9 +398,9 @@ namespace ADS
|
|||||||
// If we dropped the floating widget into the main dock container that does
|
// If we dropped the floating widget into the main dock container that does
|
||||||
// not contain any dock widgets, then splitter is invisible and we need to
|
// not contain any dock widgets, then splitter is invisible and we need to
|
||||||
// show it to display the docked widgets
|
// show it to display the docked widgets
|
||||||
if (!splitter->isVisible()) {
|
if (!splitter->isVisible())
|
||||||
splitter->show();
|
splitter->show();
|
||||||
}
|
|
||||||
q->dumpLayout();
|
q->dumpLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,9 +415,8 @@ namespace ADS
|
|||||||
// If the floating widget contains only one single dock are, then the
|
// 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
|
// current dock widget of the dock area will also be the future current
|
||||||
// dock widget in the drop area.
|
// dock widget in the drop area.
|
||||||
if (topLevelDockArea) {
|
if (topLevelDockArea)
|
||||||
newCurrentIndex = topLevelDockArea->currentIndex();
|
newCurrentIndex = topLevelDockArea->currentIndex();
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < newDockWidgets.count(); ++i) {
|
for (int i = 0; i < newDockWidgets.count(); ++i) {
|
||||||
DockWidget *dockWidget = newDockWidgets[i];
|
DockWidget *dockWidget = newDockWidgets[i];
|
||||||
@@ -415,10 +424,9 @@ namespace ADS
|
|||||||
// If the floating widget contains multiple visible dock areas, then we
|
// If the floating widget contains multiple visible dock areas, then we
|
||||||
// simply pick the first visible open dock widget and make it
|
// simply pick the first visible open dock widget and make it
|
||||||
// the current one.
|
// the current one.
|
||||||
if (newCurrentIndex < 0 && !dockWidget->isClosed()) {
|
if (newCurrentIndex < 0 && !dockWidget->isClosed())
|
||||||
newCurrentIndex = i;
|
newCurrentIndex = i;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
targetArea->setCurrentIndex(newCurrentIndex);
|
targetArea->setCurrentIndex(newCurrentIndex);
|
||||||
targetArea->updateTitleBarVisibility();
|
targetArea->updateTitleBarVisibility();
|
||||||
return;
|
return;
|
||||||
@@ -464,10 +472,9 @@ namespace ADS
|
|||||||
} else {
|
} else {
|
||||||
adjustSplitterSizes = (floatingSplitter->count() == 1);
|
adjustSplitterSizes = (floatingSplitter->count() == 1);
|
||||||
int insertIndex = areaIndex + insertParam.insertOffset();
|
int insertIndex = areaIndex + insertParam.insertOffset();
|
||||||
while (floatingSplitter->count()) {
|
while (floatingSplitter->count())
|
||||||
targetAreaSplitter->insertWidget(insertIndex++, floatingSplitter->widget(0));
|
targetAreaSplitter->insertWidget(insertIndex++, floatingSplitter->widget(0));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (adjustSplitterSizes) {
|
if (adjustSplitterSizes) {
|
||||||
int size = (targetAreaSize - targetAreaSplitter->handleWidth()) / 2;
|
int size = (targetAreaSize - targetAreaSplitter->handleWidth()) / 2;
|
||||||
@@ -516,9 +523,12 @@ namespace ADS
|
|||||||
|
|
||||||
if (droppedDockWidget) {
|
if (droppedDockWidget) {
|
||||||
DockAreaWidget *oldDockArea = droppedDockWidget->dockAreaWidget();
|
DockAreaWidget *oldDockArea = droppedDockWidget->dockAreaWidget();
|
||||||
if (oldDockArea) {
|
if (oldDockArea == targetArea)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (oldDockArea)
|
||||||
oldDockArea->removeDockWidget(droppedDockWidget);
|
oldDockArea->removeDockWidget(droppedDockWidget);
|
||||||
}
|
|
||||||
targetArea->insertDockWidget(0, droppedDockWidget, true);
|
targetArea->insertDockWidget(0, droppedDockWidget, true);
|
||||||
} else {
|
} else {
|
||||||
QList<DockWidget *> newDockWidgets = droppedArea->dockWidgets();
|
QList<DockWidget *> newDockWidgets = droppedArea->dockWidgets();
|
||||||
@@ -553,9 +563,9 @@ namespace ADS
|
|||||||
if (droppedDockWidget) {
|
if (droppedDockWidget) {
|
||||||
newDockArea = new DockAreaWidget(m_dockManager, q);
|
newDockArea = new DockAreaWidget(m_dockManager, q);
|
||||||
DockAreaWidget *oldDockArea = droppedDockWidget->dockAreaWidget();
|
DockAreaWidget *oldDockArea = droppedDockWidget->dockAreaWidget();
|
||||||
if (oldDockArea) {
|
if (oldDockArea)
|
||||||
oldDockArea->removeDockWidget(droppedDockWidget);
|
oldDockArea->removeDockWidget(droppedDockWidget);
|
||||||
}
|
|
||||||
newDockArea->addDockWidget(droppedDockWidget);
|
newDockArea->addDockWidget(droppedDockWidget);
|
||||||
} else {
|
} else {
|
||||||
droppedDockArea->dockContainer()->removeDockArea(droppedDockArea);
|
droppedDockArea->dockContainer()->removeDockArea(droppedDockArea);
|
||||||
@@ -564,25 +574,25 @@ namespace ADS
|
|||||||
|
|
||||||
auto insertParam = internal::dockAreaInsertParameters(area);
|
auto insertParam = internal::dockAreaInsertParameters(area);
|
||||||
QSplitter *targetAreaSplitter = internal::findParent<QSplitter *>(targetArea);
|
QSplitter *targetAreaSplitter = internal::findParent<QSplitter *>(targetArea);
|
||||||
int areaIndex = targetAreaSplitter->indexOf(targetArea);
|
const int areaIndex = targetAreaSplitter->indexOf(targetArea);
|
||||||
auto sizes = targetAreaSplitter->sizes();
|
auto sizes = targetAreaSplitter->sizes();
|
||||||
if (targetAreaSplitter->orientation() == insertParam.orientation()) {
|
if (targetAreaSplitter->orientation() == insertParam.orientation()) {
|
||||||
int targetAreaSize = (insertParam.orientation() == Qt::Horizontal)
|
const int targetAreaSize = (insertParam.orientation() == Qt::Horizontal)
|
||||||
? targetArea->width()
|
? targetArea->width()
|
||||||
: targetArea->height();
|
: targetArea->height();
|
||||||
targetAreaSplitter->insertWidget(areaIndex + insertParam.insertOffset(), newDockArea);
|
targetAreaSplitter->insertWidget(areaIndex + insertParam.insertOffset(), newDockArea);
|
||||||
int size = (targetAreaSize - targetAreaSplitter->handleWidth()) / 2;
|
const int size = (targetAreaSize - targetAreaSplitter->handleWidth()) / 2;
|
||||||
sizes[areaIndex] = size;
|
sizes[areaIndex] = size;
|
||||||
sizes.insert(areaIndex, size);
|
sizes.insert(areaIndex, size);
|
||||||
} else {
|
} else {
|
||||||
auto sizes = targetAreaSplitter->sizes();
|
auto sizes = targetAreaSplitter->sizes();
|
||||||
int targetAreaSize = (insertParam.orientation() == Qt::Horizontal)
|
const int targetAreaSize = (insertParam.orientation() == Qt::Horizontal)
|
||||||
? targetArea->width()
|
? targetArea->width()
|
||||||
: targetArea->height();
|
: targetArea->height();
|
||||||
QSplitter *newSplitter = createSplitter(insertParam.orientation());
|
QSplitter *newSplitter = createSplitter(insertParam.orientation());
|
||||||
newSplitter->addWidget(targetArea);
|
newSplitter->addWidget(targetArea);
|
||||||
insertWidgetIntoSplitter(newSplitter, newDockArea, insertParam.append());
|
insertWidgetIntoSplitter(newSplitter, newDockArea, insertParam.append());
|
||||||
int size = targetAreaSize / 2;
|
const int size = targetAreaSize / 2;
|
||||||
newSplitter->setSizes({size, size});
|
newSplitter->setSizes({size, size});
|
||||||
targetAreaSplitter->insertWidget(areaIndex, newSplitter);
|
targetAreaSplitter->insertWidget(areaIndex, newSplitter);
|
||||||
}
|
}
|
||||||
@@ -600,9 +610,9 @@ namespace ADS
|
|||||||
if (droppedDockWidget) {
|
if (droppedDockWidget) {
|
||||||
newDockArea = new DockAreaWidget(m_dockManager, q);
|
newDockArea = new DockAreaWidget(m_dockManager, q);
|
||||||
DockAreaWidget *oldDockArea = droppedDockWidget->dockAreaWidget();
|
DockAreaWidget *oldDockArea = droppedDockWidget->dockAreaWidget();
|
||||||
if (oldDockArea) {
|
if (oldDockArea)
|
||||||
oldDockArea->removeDockWidget(droppedDockWidget);
|
oldDockArea->removeDockWidget(droppedDockWidget);
|
||||||
}
|
|
||||||
newDockArea->addDockWidget(droppedDockWidget);
|
newDockArea->addDockWidget(droppedDockWidget);
|
||||||
} else {
|
} else {
|
||||||
// We check, if we insert the dropped widget into the same place that
|
// We check, if we insert the dropped widget into the same place that
|
||||||
@@ -627,8 +637,8 @@ namespace ADS
|
|||||||
|
|
||||||
void DockContainerWidgetPrivate::addDockAreasToList(const QList<DockAreaWidget *> newDockAreas)
|
void DockContainerWidgetPrivate::addDockAreasToList(const QList<DockAreaWidget *> newDockAreas)
|
||||||
{
|
{
|
||||||
int countBefore = m_dockAreas.count();
|
const int countBefore = m_dockAreas.count();
|
||||||
int newAreaCount = newDockAreas.count();
|
const int newAreaCount = newDockAreas.count();
|
||||||
appendDockAreas(newDockAreas);
|
appendDockAreas(newDockAreas);
|
||||||
// If the user dropped a floating widget that contains only one single
|
// If the user dropped a floating widget that contains only one single
|
||||||
// visible dock area, then its title bar button TitleBarButtonUndock is
|
// visible dock area, then its title bar button TitleBarButtonUndock is
|
||||||
@@ -640,13 +650,11 @@ namespace ADS
|
|||||||
|
|
||||||
// We need to ensure, that the dock area title bar is visible. The title bar
|
// We need to ensure, that the dock area title bar is visible. The title bar
|
||||||
// is invisible, if the dock are is a single dock area in a floating widget.
|
// is invisible, if the dock are is a single dock area in a floating widget.
|
||||||
if (1 == countBefore) {
|
if (1 == countBefore)
|
||||||
m_dockAreas.at(0)->updateTitleBarVisibility();
|
m_dockAreas.at(0)->updateTitleBarVisibility();
|
||||||
}
|
|
||||||
|
|
||||||
if (1 == newAreaCount) {
|
if (1 == newAreaCount)
|
||||||
m_dockAreas.last()->updateTitleBarVisibility();
|
m_dockAreas.last()->updateTitleBarVisibility();
|
||||||
}
|
|
||||||
|
|
||||||
emitDockAreasAdded();
|
emitDockAreasAdded();
|
||||||
}
|
}
|
||||||
@@ -674,25 +682,23 @@ namespace ADS
|
|||||||
stream.writeAttribute("count", QString::number(splitter->count()));
|
stream.writeAttribute("count", QString::number(splitter->count()));
|
||||||
qCInfo(adsLog) << "NodeSplitter orient: " << splitter->orientation()
|
qCInfo(adsLog) << "NodeSplitter orient: " << splitter->orientation()
|
||||||
<< " WidgetCont: " << splitter->count();
|
<< " WidgetCont: " << splitter->count();
|
||||||
for (int i = 0; i < splitter->count(); ++i) {
|
for (int i = 0; i < splitter->count(); ++i)
|
||||||
saveChildNodesState(stream, splitter->widget(i));
|
saveChildNodesState(stream, splitter->widget(i));
|
||||||
}
|
|
||||||
|
|
||||||
stream.writeStartElement("sizes");
|
stream.writeStartElement("sizes");
|
||||||
QStringList sizes;
|
QStringList sizes;
|
||||||
for (auto size : splitter->sizes()) {
|
for (auto size : splitter->sizes())
|
||||||
sizes.append(QString::number(size));
|
sizes.append(QString::number(size));
|
||||||
}
|
|
||||||
stream.writeCharacters(sizes.join(" "));
|
stream.writeCharacters(sizes.join(" "));
|
||||||
stream.writeEndElement();
|
stream.writeEndElement(); // sizes
|
||||||
stream.writeEndElement();
|
stream.writeEndElement(); // splitter
|
||||||
} else {
|
} else {
|
||||||
DockAreaWidget *dockArea = qobject_cast<DockAreaWidget *>(widget);
|
DockAreaWidget *dockArea = qobject_cast<DockAreaWidget *>(widget);
|
||||||
if (dockArea) {
|
if (dockArea)
|
||||||
dockArea->saveState(stream);
|
dockArea->saveState(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool DockContainerWidgetPrivate::restoreSplitter(DockingStateReader &stateReader,
|
bool DockContainerWidgetPrivate::restoreSplitter(DockingStateReader &stateReader,
|
||||||
QWidget *&createdWidget,
|
QWidget *&createdWidget,
|
||||||
@@ -701,22 +707,22 @@ namespace ADS
|
|||||||
QVariant orientationVar = QVariant(stateReader.attributes().value("orientation").toString());
|
QVariant orientationVar = QVariant(stateReader.attributes().value("orientation").toString());
|
||||||
|
|
||||||
// Check if the orientation string is convertable
|
// Check if the orientation string is convertable
|
||||||
if (!orientationVar.canConvert<Qt::Orientation>()) {
|
if (!orientationVar.canConvert<Qt::Orientation>())
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
Qt::Orientation orientation = orientationVar.value<Qt::Orientation>();
|
Qt::Orientation orientation = orientationVar.value<Qt::Orientation>();
|
||||||
|
|
||||||
bool ok;
|
bool ok;
|
||||||
int widgetCount = stateReader.attributes().value("count").toInt(&ok);
|
int widgetCount = stateReader.attributes().value("count").toInt(&ok);
|
||||||
if (!ok) {
|
if (!ok)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
qCInfo(adsLog) << "Restore NodeSplitter Orientation: " << orientation
|
qCInfo(adsLog) << "Restore NodeSplitter Orientation: " << orientation
|
||||||
<< " WidgetCount: " << widgetCount;
|
<< " WidgetCount: " << widgetCount;
|
||||||
QSplitter *splitter = nullptr;
|
QSplitter *splitter = nullptr;
|
||||||
if (!testing) {
|
if (!testing)
|
||||||
splitter = createSplitter(orientation);
|
splitter = createSplitter(orientation);
|
||||||
}
|
|
||||||
bool visible = false;
|
bool visible = false;
|
||||||
QList<int> sizes;
|
QList<int> sizes;
|
||||||
while (stateReader.readNextStartElement()) {
|
while (stateReader.readNextStartElement()) {
|
||||||
@@ -739,13 +745,11 @@ namespace ADS
|
|||||||
stateReader.skipCurrentElement();
|
stateReader.skipCurrentElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!result) {
|
if (!result)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (testing || !childNode) {
|
if (testing || !childNode)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
qCInfo(adsLog) << "ChildNode isVisible " << childNode->isVisible() << " isVisibleTo "
|
qCInfo(adsLog) << "ChildNode isVisible " << childNode->isVisible() << " isVisibleTo "
|
||||||
<< childNode->isVisibleTo(splitter);
|
<< childNode->isVisibleTo(splitter);
|
||||||
@@ -753,9 +757,8 @@ namespace ADS
|
|||||||
visible |= childNode->isVisibleTo(splitter);
|
visible |= childNode->isVisibleTo(splitter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sizes.count() != widgetCount) {
|
if (sizes.count() != widgetCount)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (!testing) {
|
if (!testing) {
|
||||||
if (!splitter->count()) {
|
if (!splitter->count()) {
|
||||||
@@ -782,22 +785,20 @@ namespace ADS
|
|||||||
#ifdef ADS_DEBUG_PRINT
|
#ifdef ADS_DEBUG_PRINT
|
||||||
bool ok;
|
bool ok;
|
||||||
int tabs = stateReader.attributes().value("tabs").toInt(&ok);
|
int tabs = stateReader.attributes().value("tabs").toInt(&ok);
|
||||||
if (!ok) {
|
if (!ok)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
qCInfo(adsLog) << "Restore NodeDockArea Tabs: " << tabs
|
qCInfo(adsLog) << "Restore NodeDockArea Tabs: " << tabs
|
||||||
<< " Current: " << currentDockWidget;
|
<< " Current: " << currentDockWidget;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DockAreaWidget *dockArea = nullptr;
|
DockAreaWidget *dockArea = nullptr;
|
||||||
if (!testing) {
|
if (!testing)
|
||||||
dockArea = new DockAreaWidget(m_dockManager, q);
|
dockArea = new DockAreaWidget(m_dockManager, q);
|
||||||
}
|
|
||||||
|
|
||||||
while (stateReader.readNextStartElement()) {
|
while (stateReader.readNextStartElement()) {
|
||||||
if (stateReader.name() != "widget") {
|
if (stateReader.name() != "widget")
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
auto objectName = stateReader.attributes().value("name");
|
auto objectName = stateReader.attributes().value("name");
|
||||||
if (objectName.isEmpty()) {
|
if (objectName.isEmpty()) {
|
||||||
@@ -806,16 +807,15 @@ namespace ADS
|
|||||||
}
|
}
|
||||||
|
|
||||||
QVariant closedVar = QVariant(stateReader.attributes().value("closed").toString());
|
QVariant closedVar = QVariant(stateReader.attributes().value("closed").toString());
|
||||||
if (!closedVar.canConvert<bool>()) {
|
if (!closedVar.canConvert<bool>())
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
bool closed = closedVar.value<bool>();
|
bool closed = closedVar.value<bool>();
|
||||||
|
|
||||||
stateReader.skipCurrentElement();
|
stateReader.skipCurrentElement();
|
||||||
DockWidget *dockWidget = m_dockManager->findDockWidget(objectName.toString());
|
DockWidget *dockWidget = m_dockManager->findDockWidget(objectName.toString());
|
||||||
if (!dockWidget || testing) {
|
if (!dockWidget || testing)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
qCInfo(adsLog) << "Dock Widget found - parent " << dockWidget->parent();
|
qCInfo(adsLog) << "Dock Widget found - parent " << dockWidget->parent();
|
||||||
// We hide the DockArea here to prevent the short display (the flashing)
|
// We hide the DockArea here to prevent the short display (the flashing)
|
||||||
@@ -828,9 +828,8 @@ namespace ADS
|
|||||||
dockWidget->setProperty(internal::dirtyProperty, false);
|
dockWidget->setProperty(internal::dirtyProperty, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (testing) {
|
if (testing)
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
if (!dockArea->dockWidgetsCount()) {
|
if (!dockArea->dockWidgetsCount()) {
|
||||||
delete dockArea;
|
delete dockArea;
|
||||||
@@ -865,7 +864,7 @@ namespace ADS
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DockAreaWidget *DockContainerWidgetPrivate::dockWidgetIntoContainer(DockWidgetArea area,
|
DockAreaWidget *DockContainerWidgetPrivate::addDockWidgetToContainer(DockWidgetArea area,
|
||||||
DockWidget *dockWidget)
|
DockWidget *dockWidget)
|
||||||
{
|
{
|
||||||
DockAreaWidget *newDockArea = new DockAreaWidget(m_dockManager, q);
|
DockAreaWidget *newDockArea = new DockAreaWidget(m_dockManager, q);
|
||||||
@@ -880,13 +879,15 @@ namespace ADS
|
|||||||
{
|
{
|
||||||
auto insertParam = internal::dockAreaInsertParameters(area);
|
auto insertParam = internal::dockAreaInsertParameters(area);
|
||||||
// As long as we have only one dock area in the splitter we can adjust its orientation
|
// As long as we have only one dock area in the splitter we can adjust its orientation
|
||||||
if (m_dockAreas.count() <= 1) {
|
if (m_dockAreas.count() <= 1)
|
||||||
m_rootSplitter->setOrientation(insertParam.orientation());
|
m_rootSplitter->setOrientation(insertParam.orientation());
|
||||||
}
|
|
||||||
|
|
||||||
QSplitter *splitter = m_rootSplitter;
|
QSplitter *splitter = m_rootSplitter;
|
||||||
if (splitter->orientation() == insertParam.orientation()) {
|
if (splitter->orientation() == insertParam.orientation()) {
|
||||||
insertWidgetIntoSplitter(splitter, newDockArea, insertParam.append());
|
insertWidgetIntoSplitter(splitter, newDockArea, insertParam.append());
|
||||||
|
if (splitter->isHidden())
|
||||||
|
splitter->show();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
QSplitter *newSplitter = createSplitter(insertParam.orientation());
|
QSplitter *newSplitter = createSplitter(insertParam.orientation());
|
||||||
if (insertParam.append()) {
|
if (insertParam.append()) {
|
||||||
@@ -924,14 +925,13 @@ namespace ADS
|
|||||||
<< (splitter->isHidden() ? " " : "v") << " "
|
<< (splitter->isHidden() ? " " : "v") << " "
|
||||||
<< QString::number(splitter->count()).toStdString() << std::endl;
|
<< QString::number(splitter->count()).toStdString() << std::endl;
|
||||||
#endif
|
#endif
|
||||||
for (int i = 0; i < splitter->count(); ++i) {
|
for (int i = 0; i < splitter->count(); ++i)
|
||||||
dumpRecursive(level + 1, splitter->widget(i));
|
dumpRecursive(level + 1, splitter->widget(i));
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
DockAreaWidget *dockArea = qobject_cast<DockAreaWidget *>(widget);
|
DockAreaWidget *dockArea = qobject_cast<DockAreaWidget *>(widget);
|
||||||
if (!dockArea) {
|
if (!dockArea)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
#ifdef ADS_DEBUG_PRINT
|
#ifdef ADS_DEBUG_PRINT
|
||||||
qDebug("%sDockArea", buf.data());
|
qDebug("%sDockArea", buf.data());
|
||||||
std::cout << buf.data() << (dockArea->isHidden() ? " " : "v")
|
std::cout << buf.data() << (dockArea->isHidden() ? " " : "v")
|
||||||
@@ -953,10 +953,9 @@ namespace ADS
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
DockAreaWidget *DockContainerWidgetPrivate::dockWidgetIntoDockArea(DockWidgetArea area,
|
DockAreaWidget *DockContainerWidgetPrivate::addDockWidgetToDockArea(DockWidgetArea area,
|
||||||
DockWidget *dockWidget,
|
DockWidget *dockWidget,
|
||||||
DockAreaWidget
|
DockAreaWidget *targetDockArea)
|
||||||
*targetDockArea)
|
|
||||||
{
|
{
|
||||||
if (CenterDockWidgetArea == area) {
|
if (CenterDockWidgetArea == area) {
|
||||||
targetDockArea->addDockWidget(dockWidget);
|
targetDockArea->addDockWidget(dockWidget);
|
||||||
@@ -973,12 +972,20 @@ namespace ADS
|
|||||||
if (targetAreaSplitter->orientation() == insertParam.orientation()) {
|
if (targetAreaSplitter->orientation() == insertParam.orientation()) {
|
||||||
qCInfo(adsLog) << "TargetAreaSplitter->orientation() == InsertParam.orientation()";
|
qCInfo(adsLog) << "TargetAreaSplitter->orientation() == InsertParam.orientation()";
|
||||||
targetAreaSplitter->insertWidget(index + insertParam.insertOffset(), newDockArea);
|
targetAreaSplitter->insertWidget(index + insertParam.insertOffset(), newDockArea);
|
||||||
|
// do nothing, if flag is not enabled
|
||||||
|
if (DockManager::testConfigFlag(DockManager::EqualSplitOnInsertion))
|
||||||
|
adjustSplitterSizesOnInsertion(targetAreaSplitter);
|
||||||
} else {
|
} else {
|
||||||
qCInfo(adsLog) << "TargetAreaSplitter->orientation() != InsertParam.orientation()";
|
qCInfo(adsLog) << "TargetAreaSplitter->orientation() != InsertParam.orientation()";
|
||||||
|
auto targetAreaSizes = targetAreaSplitter->sizes();
|
||||||
QSplitter *newSplitter = createSplitter(insertParam.orientation());
|
QSplitter *newSplitter = createSplitter(insertParam.orientation());
|
||||||
newSplitter->addWidget(targetDockArea);
|
newSplitter->addWidget(targetDockArea);
|
||||||
insertWidgetIntoSplitter(newSplitter, newDockArea, insertParam.append());
|
insertWidgetIntoSplitter(newSplitter, newDockArea, insertParam.append());
|
||||||
targetAreaSplitter->insertWidget(index, newSplitter);
|
targetAreaSplitter->insertWidget(index, newSplitter);
|
||||||
|
if (DockManager::testConfigFlag(DockManager::EqualSplitOnInsertion)) {
|
||||||
|
targetAreaSplitter->setSizes(targetAreaSizes);
|
||||||
|
adjustSplitterSizesOnInsertion(newSplitter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
appendDockAreas({newDockArea});
|
appendDockAreas({newDockArea});
|
||||||
@@ -1011,9 +1018,9 @@ namespace ADS
|
|||||||
|
|
||||||
DockContainerWidget::~DockContainerWidget()
|
DockContainerWidget::~DockContainerWidget()
|
||||||
{
|
{
|
||||||
if (d->m_dockManager) {
|
if (d->m_dockManager)
|
||||||
d->m_dockManager->removeDockContainer(this);
|
d->m_dockManager->removeDockContainer(this);
|
||||||
}
|
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1022,25 +1029,22 @@ namespace ADS
|
|||||||
DockAreaWidget *dockAreaWidget)
|
DockAreaWidget *dockAreaWidget)
|
||||||
{
|
{
|
||||||
DockAreaWidget *oldDockArea = dockWidget->dockAreaWidget();
|
DockAreaWidget *oldDockArea = dockWidget->dockAreaWidget();
|
||||||
if (oldDockArea) {
|
if (oldDockArea)
|
||||||
oldDockArea->removeDockWidget(dockWidget);
|
oldDockArea->removeDockWidget(dockWidget);
|
||||||
}
|
|
||||||
|
|
||||||
dockWidget->setDockManager(d->m_dockManager);
|
dockWidget->setDockManager(d->m_dockManager);
|
||||||
if (dockAreaWidget) {
|
if (dockAreaWidget)
|
||||||
return d->dockWidgetIntoDockArea(area, dockWidget, dockAreaWidget);
|
return d->addDockWidgetToDockArea(area, dockWidget, dockAreaWidget);
|
||||||
} else {
|
else
|
||||||
return d->dockWidgetIntoContainer(area, dockWidget);
|
return d->addDockWidgetToContainer(area, dockWidget);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DockContainerWidget::removeDockWidget(DockWidget * dockWidget)
|
void DockContainerWidget::removeDockWidget(DockWidget * dockWidget)
|
||||||
{
|
{
|
||||||
DockAreaWidget *area = dockWidget->dockAreaWidget();
|
DockAreaWidget *area = dockWidget->dockAreaWidget();
|
||||||
if (area) {
|
if (area)
|
||||||
area->removeDockWidget(dockWidget);
|
area->removeDockWidget(dockWidget);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int DockContainerWidget::zOrderIndex() const { return d->m_zOrderIndex; }
|
unsigned int DockContainerWidget::zOrderIndex() const { return d->m_zOrderIndex; }
|
||||||
|
|
||||||
@@ -1052,11 +1056,10 @@ namespace ADS
|
|||||||
bool DockContainerWidget::event(QEvent *event)
|
bool DockContainerWidget::event(QEvent *event)
|
||||||
{
|
{
|
||||||
bool result = QWidget::event(event);
|
bool result = QWidget::event(event);
|
||||||
if (event->type() == QEvent::WindowActivate) {
|
if (event->type() == QEvent::WindowActivate)
|
||||||
d->m_zOrderIndex = ++zOrderCounter;
|
d->m_zOrderIndex = ++zOrderCounter;
|
||||||
} else if (event->type() == QEvent::Show && !d->m_zOrderIndex) {
|
else if (event->type() == QEvent::Show && !d->m_zOrderIndex)
|
||||||
d->m_zOrderIndex = ++zOrderCounter;
|
d->m_zOrderIndex = ++zOrderCounter;
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -1064,9 +1067,8 @@ namespace ADS
|
|||||||
void DockContainerWidget::addDockArea(DockAreaWidget *dockAreaWidget, DockWidgetArea area)
|
void DockContainerWidget::addDockArea(DockAreaWidget *dockAreaWidget, DockWidgetArea area)
|
||||||
{
|
{
|
||||||
DockContainerWidget *container = dockAreaWidget->dockContainer();
|
DockContainerWidget *container = dockAreaWidget->dockContainer();
|
||||||
if (container && container != this) {
|
if (container && container != this)
|
||||||
container->removeDockArea(dockAreaWidget);
|
container->removeDockArea(dockAreaWidget);
|
||||||
}
|
|
||||||
|
|
||||||
d->addDockArea(dockAreaWidget, area);
|
d->addDockArea(dockAreaWidget, area);
|
||||||
}
|
}
|
||||||
@@ -1085,9 +1087,8 @@ namespace ADS
|
|||||||
|
|
||||||
// Remove this area from cached areas
|
// Remove this area from cached areas
|
||||||
const auto &cache = d->m_lastAddedAreaCache;
|
const auto &cache = d->m_lastAddedAreaCache;
|
||||||
if (auto p = std::find(cache, cache + sizeof(cache) / sizeof(cache[0]), area)) {
|
if (auto p = std::find(cache, cache + sizeof(cache) / sizeof(cache[0]), area))
|
||||||
d->m_lastAddedAreaCache[std::distance(cache, p)] = nullptr;
|
d->m_lastAddedAreaCache[std::distance(cache, p)] = nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
// If splitter has more than 1 widgets, we are finished and can leave
|
// If splitter has more than 1 widgets, we are finished and can leave
|
||||||
if (splitter->count() > 1) {
|
if (splitter->count() > 1) {
|
||||||
@@ -1149,10 +1150,9 @@ namespace ADS
|
|||||||
{
|
{
|
||||||
for (auto dockArea : d->m_dockAreas) {
|
for (auto dockArea : d->m_dockAreas) {
|
||||||
if (dockArea->isVisible()
|
if (dockArea->isVisible()
|
||||||
&& dockArea->rect().contains(dockArea->mapFromGlobal(globalPosition))) {
|
&& dockArea->rect().contains(dockArea->mapFromGlobal(globalPosition)))
|
||||||
return dockArea;
|
return dockArea;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -1169,9 +1169,8 @@ namespace ADS
|
|||||||
int DockContainerWidget::visibleDockAreaCount() const
|
int DockContainerWidget::visibleDockAreaCount() const
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
for (auto dockArea : d->m_dockAreas) {
|
for (auto dockArea : d->m_dockAreas)
|
||||||
result += dockArea->isHidden() ? 0 : 1;
|
result += dockArea->isHidden() ? 0 : 1;
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@@ -1195,9 +1194,8 @@ namespace ADS
|
|||||||
auto dropOverlay = d->m_dockManager->dockAreaOverlay();
|
auto dropOverlay = d->m_dockManager->dockAreaOverlay();
|
||||||
dropOverlay->setAllowedAreas(dockArea->allowedAreas());
|
dropOverlay->setAllowedAreas(dockArea->allowedAreas());
|
||||||
dropArea = dropOverlay->showOverlay(dockArea);
|
dropArea = dropOverlay->showOverlay(dockArea);
|
||||||
if (containerDropArea != InvalidDockWidgetArea && containerDropArea != dropArea) {
|
if (containerDropArea != InvalidDockWidgetArea && containerDropArea != dropArea)
|
||||||
dropArea = InvalidDockWidgetArea;
|
dropArea = InvalidDockWidgetArea;
|
||||||
}
|
|
||||||
|
|
||||||
if (dropArea != InvalidDockWidgetArea) {
|
if (dropArea != InvalidDockWidgetArea) {
|
||||||
qCInfo(adsLog) << "Dock Area Drop Content: " << dropArea;
|
qCInfo(adsLog) << "Dock Area Drop Content: " << dropArea;
|
||||||
@@ -1227,6 +1225,11 @@ namespace ADS
|
|||||||
// level widget anymore
|
// level widget anymore
|
||||||
DockWidget::emitTopLevelEventForWidget(singleDockWidget, false);
|
DockWidget::emitTopLevelEventForWidget(singleDockWidget, false);
|
||||||
}
|
}
|
||||||
|
window()->activateWindow();
|
||||||
|
if (singleDroppedDockWidget)
|
||||||
|
d->m_dockManager->notifyWidgetOrAreaRelocation(singleDroppedDockWidget);
|
||||||
|
|
||||||
|
d->m_dockManager->notifyFloatingWidgetDrop(floatingWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DockContainerWidget::dropWidget(QWidget *widget, DockWidgetArea dropArea, DockAreaWidget *targetAreaWidget)
|
void DockContainerWidget::dropWidget(QWidget *widget, DockWidgetArea dropArea, DockAreaWidget *targetAreaWidget)
|
||||||
@@ -1240,16 +1243,26 @@ namespace ADS
|
|||||||
// If there was a top level widget before the drop, then it is not top
|
// If there was a top level widget before the drop, then it is not top
|
||||||
// level widget anymore
|
// level widget anymore
|
||||||
DockWidget::emitTopLevelEventForWidget(singleDockWidget, false);
|
DockWidget::emitTopLevelEventForWidget(singleDockWidget, false);
|
||||||
|
DockWidget *dockWidget = qobject_cast<DockWidget *>(widget);
|
||||||
|
if (!dockWidget)
|
||||||
|
{
|
||||||
|
DockAreaWidget *dockArea = qobject_cast<DockAreaWidget *>(widget);
|
||||||
|
auto openDockWidgets = dockArea->openedDockWidgets();
|
||||||
|
if (openDockWidgets.count() == 1)
|
||||||
|
dockWidget = openDockWidgets[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
window()->activateWindow();
|
||||||
|
d->m_dockManager->notifyWidgetOrAreaRelocation(widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<DockAreaWidget *> DockContainerWidget::openedDockAreas() const
|
QList<DockAreaWidget *> DockContainerWidget::openedDockAreas() const
|
||||||
{
|
{
|
||||||
QList<DockAreaWidget *> result;
|
QList<DockAreaWidget *> result;
|
||||||
for (auto dockArea : d->m_dockAreas) {
|
for (auto dockArea : d->m_dockAreas) {
|
||||||
if (!dockArea->isHidden()) {
|
if (!dockArea->isHidden())
|
||||||
result.append(dockArea);
|
result.append(dockArea);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -1272,9 +1285,9 @@ namespace ADS
|
|||||||
bool DockContainerWidget::restoreState(DockingStateReader &stateReader, bool testing)
|
bool DockContainerWidget::restoreState(DockingStateReader &stateReader, bool testing)
|
||||||
{
|
{
|
||||||
QVariant floatingVar = QVariant(stateReader.attributes().value("floating").toString());
|
QVariant floatingVar = QVariant(stateReader.attributes().value("floating").toString());
|
||||||
if (!floatingVar.canConvert<bool>()) {
|
if (!floatingVar.canConvert<bool>())
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
bool isFloating = floatingVar.value<bool>();
|
bool isFloating = floatingVar.value<bool>();
|
||||||
qCInfo(adsLog) << "Restore DockContainerWidget Floating" << isFloating;
|
qCInfo(adsLog) << "Restore DockContainerWidget Floating" << isFloating;
|
||||||
|
|
||||||
@@ -1289,18 +1302,16 @@ namespace ADS
|
|||||||
|
|
||||||
if (isFloating) {
|
if (isFloating) {
|
||||||
qCInfo(adsLog) << "Restore floating widget";
|
qCInfo(adsLog) << "Restore floating widget";
|
||||||
if (!stateReader.readNextStartElement() || stateReader.name() != "geometry") {
|
if (!stateReader.readNextStartElement() || stateReader.name() != "geometry")
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray geometryString = stateReader
|
QByteArray geometryString = stateReader
|
||||||
.readElementText(
|
.readElementText(
|
||||||
DockingStateReader::ErrorOnUnexpectedElement)
|
DockingStateReader::ErrorOnUnexpectedElement)
|
||||||
.toLocal8Bit();
|
.toLocal8Bit();
|
||||||
QByteArray geometry = QByteArray::fromBase64(geometryString);
|
QByteArray geometry = QByteArray::fromBase64(geometryString);
|
||||||
if (geometry.isEmpty()) {
|
if (geometry.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (!testing) {
|
if (!testing) {
|
||||||
FloatingDockContainer *floatingDockContainer = floatingWidget();
|
FloatingDockContainer *floatingDockContainer = floatingWidget();
|
||||||
@@ -1308,19 +1319,16 @@ namespace ADS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!d->restoreChildNodes(stateReader, newRootSplitter, testing)) {
|
if (!d->restoreChildNodes(stateReader, newRootSplitter, testing))
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (testing) {
|
if (testing)
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
// If the root splitter is empty, rostoreChildNodes returns a 0 pointer
|
// If the root splitter is empty, rostoreChildNodes returns a 0 pointer
|
||||||
// and we need to create a new empty root splitter
|
// and we need to create a new empty root splitter
|
||||||
if (!newRootSplitter) {
|
if (!newRootSplitter)
|
||||||
newRootSplitter = d->createSplitter(Qt::Horizontal);
|
newRootSplitter = d->createSplitter(Qt::Horizontal);
|
||||||
}
|
|
||||||
|
|
||||||
d->m_layout->replaceWidget(d->m_rootSplitter, newRootSplitter);
|
d->m_layout->replaceWidget(d->m_rootSplitter, newRootSplitter);
|
||||||
QSplitter *oldRoot = d->m_rootSplitter;
|
QSplitter *oldRoot = d->m_rootSplitter;
|
||||||
@@ -1334,9 +1342,9 @@ namespace ADS
|
|||||||
|
|
||||||
void DockContainerWidget::createRootSplitter()
|
void DockContainerWidget::createRootSplitter()
|
||||||
{
|
{
|
||||||
if (d->m_rootSplitter) {
|
if (d->m_rootSplitter)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
d->m_rootSplitter = d->createSplitter(Qt::Horizontal);
|
d->m_rootSplitter = d->createSplitter(Qt::Horizontal);
|
||||||
d->m_layout->addWidget(d->m_rootSplitter);
|
d->m_layout->addWidget(d->m_rootSplitter);
|
||||||
}
|
}
|
||||||
@@ -1359,14 +1367,9 @@ namespace ADS
|
|||||||
|
|
||||||
bool DockContainerWidget::hasTopLevelDockWidget() const
|
bool DockContainerWidget::hasTopLevelDockWidget() const
|
||||||
{
|
{
|
||||||
if (!isFloating()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto dockAreas = openedDockAreas();
|
auto dockAreas = openedDockAreas();
|
||||||
if (dockAreas.count() != 1) {
|
if (dockAreas.count() != 1)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return dockAreas[0]->openDockWidgetsCount() == 1;
|
return dockAreas[0]->openDockWidgetsCount() == 1;
|
||||||
}
|
}
|
||||||
@@ -1374,28 +1377,21 @@ namespace ADS
|
|||||||
DockWidget *DockContainerWidget::topLevelDockWidget() const
|
DockWidget *DockContainerWidget::topLevelDockWidget() const
|
||||||
{
|
{
|
||||||
auto dockArea = topLevelDockArea();
|
auto dockArea = topLevelDockArea();
|
||||||
if (!dockArea) {
|
if (!dockArea)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
auto dockWidgets = dockArea->openedDockWidgets();
|
auto dockWidgets = dockArea->openedDockWidgets();
|
||||||
if (dockWidgets.count() != 1) {
|
if (dockWidgets.count() != 1)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
return dockWidgets[0];
|
return dockWidgets[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
DockAreaWidget *DockContainerWidget::topLevelDockArea() const
|
DockAreaWidget *DockContainerWidget::topLevelDockArea() const
|
||||||
{
|
{
|
||||||
if (!isFloating()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto dockAreas = openedDockAreas();
|
auto dockAreas = openedDockAreas();
|
||||||
if (dockAreas.count() != 1) {
|
if (dockAreas.count() != 1)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
return dockAreas[0];
|
return dockAreas[0];
|
||||||
}
|
}
|
||||||
@@ -1403,9 +1399,8 @@ namespace ADS
|
|||||||
QList<DockWidget *> DockContainerWidget::dockWidgets() const
|
QList<DockWidget *> DockContainerWidget::dockWidgets() const
|
||||||
{
|
{
|
||||||
QList<DockWidget *> result;
|
QList<DockWidget *> result;
|
||||||
for (const auto dockArea : d->m_dockAreas) {
|
for (const auto dockArea : d->m_dockAreas)
|
||||||
result.append(dockArea->dockWidgets());
|
result.append(dockArea->dockWidgets());
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -1413,9 +1408,8 @@ namespace ADS
|
|||||||
DockWidget::DockWidgetFeatures DockContainerWidget::features() const
|
DockWidget::DockWidgetFeatures DockContainerWidget::features() const
|
||||||
{
|
{
|
||||||
DockWidget::DockWidgetFeatures features(DockWidget::AllDockWidgetFeatures);
|
DockWidget::DockWidgetFeatures features(DockWidget::AllDockWidgetFeatures);
|
||||||
for (const auto dockArea : d->m_dockAreas) {
|
for (const auto dockArea : d->m_dockAreas)
|
||||||
features &= dockArea->features();
|
features &= dockArea->features();
|
||||||
}
|
|
||||||
|
|
||||||
return features;
|
return features;
|
||||||
}
|
}
|
||||||
@@ -1428,18 +1422,15 @@ namespace ADS
|
|||||||
void DockContainerWidget::closeOtherAreas(DockAreaWidget *keepOpenArea)
|
void DockContainerWidget::closeOtherAreas(DockAreaWidget *keepOpenArea)
|
||||||
{
|
{
|
||||||
for (const auto dockArea : d->m_dockAreas) {
|
for (const auto dockArea : d->m_dockAreas) {
|
||||||
if (dockArea == keepOpenArea) {
|
if (dockArea == keepOpenArea)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if (!dockArea->features(BitwiseAnd).testFlag(DockWidget::DockWidgetClosable)) {
|
if (!dockArea->features(BitwiseAnd).testFlag(DockWidget::DockWidgetClosable))
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
// We do not close areas with widgets with custom close handling
|
// We do not close areas with widgets with custom close handling
|
||||||
if (dockArea->features(BitwiseOr).testFlag(DockWidget::CustomCloseHandling)) {
|
if (dockArea->features(BitwiseOr).testFlag(DockWidget::CustomCloseHandling))
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
dockArea->closeArea();
|
dockArea->closeArea();
|
||||||
}
|
}
|
||||||
|
@@ -59,10 +59,10 @@ class FloatingDragPreviewPrivate;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Container that manages a number of dock areas with single dock widgets
|
* Container that manages a number of dock areas with single dock widgets
|
||||||
* or tabyfied dock widgets in each area.
|
* or tabified dock widgets in each area.
|
||||||
* Each window that support docking has a DockContainerWidget. That means
|
* Each window that support docking has a DockContainerWidget. That means
|
||||||
* the main application window and all floating windows contain
|
* the main application window and all floating windows contain a
|
||||||
* a DockContainerWidget.
|
* DockContainerWidget instance.
|
||||||
*/
|
*/
|
||||||
class ADS_EXPORT DockContainerWidget : public QFrame
|
class ADS_EXPORT DockContainerWidget : public QFrame
|
||||||
{
|
{
|
||||||
@@ -86,13 +86,11 @@ protected:
|
|||||||
*/
|
*/
|
||||||
bool event(QEvent *event) override;
|
bool event(QEvent *event) override;
|
||||||
|
|
||||||
public: // TODO temporary
|
|
||||||
/**
|
/**
|
||||||
* Access function for the internal root splitter
|
* Access function for the internal root splitter
|
||||||
*/
|
*/
|
||||||
QSplitter *rootSplitter() const;
|
QSplitter *rootSplitter() const;
|
||||||
|
|
||||||
protected:
|
|
||||||
/**
|
/**
|
||||||
* Helper function for creation of the root splitter
|
* Helper function for creation of the root splitter
|
||||||
*/
|
*/
|
||||||
|
273
src/libs/advanceddockingsystem/dockfocuscontroller.cpp
Normal file
273
src/libs/advanceddockingsystem/dockfocuscontroller.cpp
Normal file
@@ -0,0 +1,273 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 Uwe Kindler
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 or (at your option) any later version.
|
||||||
|
** The licenses are as published by the Free Software Foundation
|
||||||
|
** and appearing in the file LICENSE.LGPLv21 included in the packaging
|
||||||
|
** of this file. Please review the following information to ensure
|
||||||
|
** the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 or (at your option) any later version
|
||||||
|
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||||
|
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "dockfocuscontroller.h"
|
||||||
|
|
||||||
|
#include "dockareawidget.h"
|
||||||
|
#include "dockareatitlebar.h"
|
||||||
|
#include "dockcontainerwidget.h"
|
||||||
|
#include "dockmanager.h"
|
||||||
|
#include "dockwidget.h"
|
||||||
|
#include "dockwidgettab.h"
|
||||||
|
#include "floatingdockcontainer.h"
|
||||||
|
|
||||||
|
#ifdef Q_OS_LINUX
|
||||||
|
#include "linux/floatingwidgettitlebar.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QPointer>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace ADS
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Private data class of CDockFocusController class (pimpl)
|
||||||
|
*/
|
||||||
|
class DockFocusControllerPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DockFocusController *q;
|
||||||
|
QPointer<DockWidget> m_focusedDockWidget = nullptr;
|
||||||
|
QPointer<DockAreaWidget> m_focusedArea = nullptr;
|
||||||
|
#ifdef Q_OS_LINUX
|
||||||
|
QPointer<FloatingDockContainer> m_floatingWidget = nullptr;
|
||||||
|
#endif
|
||||||
|
DockManager *m_dockManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private data constructor
|
||||||
|
*/
|
||||||
|
DockFocusControllerPrivate(DockFocusController *parent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function updates the focus style of the given dock widget and
|
||||||
|
* the dock area that it belongs to
|
||||||
|
*/
|
||||||
|
void updateDockWidgetFocus(DockWidget *dockWidget);
|
||||||
|
}; // class DockFocusControllerPrivate
|
||||||
|
|
||||||
|
static void updateDockWidgetFocusStyle(DockWidget *dockWidget, bool focused)
|
||||||
|
{
|
||||||
|
dockWidget->setProperty("focused", focused);
|
||||||
|
dockWidget->tabWidget()->setProperty("focused", focused);
|
||||||
|
dockWidget->tabWidget()->updateStyle();
|
||||||
|
internal::repolishStyle(dockWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateDockAreaFocusStyle(DockAreaWidget *dockArea, bool focused)
|
||||||
|
{
|
||||||
|
dockArea->setProperty("focused", focused);
|
||||||
|
internal::repolishStyle(dockArea);
|
||||||
|
internal::repolishStyle(dockArea->titleBar());
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_LINUX
|
||||||
|
static void updateFloatingWidgetFocusStyle(FloatingDockContainer *floatingWidget, bool focused)
|
||||||
|
{
|
||||||
|
auto titleBar = qobject_cast<FloatingWidgetTitleBar *>(floatingWidget->titleBarWidget());
|
||||||
|
if (!titleBar)
|
||||||
|
return;
|
||||||
|
|
||||||
|
titleBar->setProperty("focused", focused);
|
||||||
|
titleBar->updateStyle();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DockFocusControllerPrivate::DockFocusControllerPrivate(DockFocusController *parent)
|
||||||
|
: q(parent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void DockFocusControllerPrivate::updateDockWidgetFocus(DockWidget *dockWidget)
|
||||||
|
{
|
||||||
|
DockAreaWidget *newFocusedDockArea = nullptr;
|
||||||
|
if (m_focusedDockWidget)
|
||||||
|
updateDockWidgetFocusStyle(m_focusedDockWidget, false);
|
||||||
|
|
||||||
|
DockWidget *old = m_focusedDockWidget;
|
||||||
|
m_focusedDockWidget = dockWidget;
|
||||||
|
updateDockWidgetFocusStyle(m_focusedDockWidget, true);
|
||||||
|
newFocusedDockArea = m_focusedDockWidget->dockAreaWidget();
|
||||||
|
if (newFocusedDockArea && (m_focusedArea != newFocusedDockArea))
|
||||||
|
{
|
||||||
|
if (m_focusedArea)
|
||||||
|
{
|
||||||
|
QObject::disconnect(m_focusedArea, &DockAreaWidget::viewToggled,
|
||||||
|
q, &DockFocusController::onFocusedDockAreaViewToggled);
|
||||||
|
updateDockAreaFocusStyle(m_focusedArea, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_focusedArea = newFocusedDockArea;
|
||||||
|
updateDockAreaFocusStyle(m_focusedArea, true);
|
||||||
|
QObject::connect(m_focusedArea, &DockAreaWidget::viewToggled,
|
||||||
|
q, &DockFocusController::onFocusedDockAreaViewToggled);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto newFloatingWidget = m_focusedDockWidget->dockContainer()->floatingWidget();
|
||||||
|
if (newFloatingWidget)
|
||||||
|
newFloatingWidget->setProperty("FocusedDockWidget", QVariant::fromValue(dockWidget));
|
||||||
|
|
||||||
|
#ifdef Q_OS_LINUX
|
||||||
|
// This code is required for styling the floating widget titlebar for linux
|
||||||
|
// depending on the current focus state
|
||||||
|
if (m_floatingWidget == newFloatingWidget)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_floatingWidget)
|
||||||
|
updateFloatingWidgetFocusStyle(m_floatingWidget, false);
|
||||||
|
|
||||||
|
m_floatingWidget = newFloatingWidget;
|
||||||
|
|
||||||
|
if (m_floatingWidget)
|
||||||
|
updateFloatingWidgetFocusStyle(m_floatingWidget, true);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (old != dockWidget)
|
||||||
|
emit m_dockManager->focusedDockWidgetChanged(old, dockWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
DockFocusController::DockFocusController(DockManager *dockManager)
|
||||||
|
: QObject(dockManager)
|
||||||
|
, d(new DockFocusControllerPrivate(this))
|
||||||
|
{
|
||||||
|
d->m_dockManager = dockManager;
|
||||||
|
connect(qApp, &QApplication::focusChanged,
|
||||||
|
this, &DockFocusController::onApplicationFocusChanged);
|
||||||
|
connect(d->m_dockManager, &DockManager::stateRestored,
|
||||||
|
this, &DockFocusController::onStateRestored);
|
||||||
|
}
|
||||||
|
|
||||||
|
DockFocusController::~DockFocusController()
|
||||||
|
{
|
||||||
|
delete d;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockFocusController::onApplicationFocusChanged(QWidget *focusedOld, QWidget *focusedNow)
|
||||||
|
{
|
||||||
|
if (d->m_dockManager->isRestoringState())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!focusedNow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
DockWidget *dockWidget = nullptr;
|
||||||
|
auto dockWidgetTab = qobject_cast<DockWidgetTab *>(focusedNow);
|
||||||
|
if (dockWidgetTab)
|
||||||
|
dockWidget = dockWidgetTab->dockWidget();
|
||||||
|
|
||||||
|
if (!dockWidget)
|
||||||
|
dockWidget = qobject_cast<DockWidget *>(focusedNow);
|
||||||
|
|
||||||
|
if (!dockWidget)
|
||||||
|
dockWidget = internal::findParent<DockWidget *>(focusedNow);
|
||||||
|
|
||||||
|
#ifdef Q_OS_LINUX
|
||||||
|
if (!dockWidget)
|
||||||
|
return;
|
||||||
|
#else
|
||||||
|
if (!dockWidget || dockWidget->tabWidget()->isHidden())
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
d->updateDockWidgetFocus(dockWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockFocusController::setDockWidgetFocused(DockWidget *focusedNow)
|
||||||
|
{
|
||||||
|
d->updateDockWidgetFocus(focusedNow);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockFocusController::onFocusedDockAreaViewToggled(bool open)
|
||||||
|
{
|
||||||
|
if (d->m_dockManager->isRestoringState())
|
||||||
|
return;
|
||||||
|
|
||||||
|
DockAreaWidget* dockArea = qobject_cast<DockAreaWidget *>(sender());
|
||||||
|
if (!dockArea || open)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto container = dockArea->dockContainer();
|
||||||
|
auto openedDockAreas = container->openedDockAreas();
|
||||||
|
if (openedDockAreas.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
DockManager::setWidgetFocus(openedDockAreas[0]->currentDockWidget()->tabWidget());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockFocusController::notifyWidgetOrAreaRelocation(QWidget *droppedWidget)
|
||||||
|
{
|
||||||
|
if (d->m_dockManager->isRestoringState())
|
||||||
|
return;
|
||||||
|
|
||||||
|
DockWidget *dockWidget = qobject_cast<DockWidget *>(droppedWidget);
|
||||||
|
if (dockWidget)
|
||||||
|
{
|
||||||
|
DockManager::setWidgetFocus(dockWidget->tabWidget());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DockAreaWidget* dockArea = qobject_cast<DockAreaWidget*>(droppedWidget);
|
||||||
|
if (!dockArea)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dockWidget = dockArea->currentDockWidget();
|
||||||
|
DockManager::setWidgetFocus(dockWidget->tabWidget());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockFocusController::notifyFloatingWidgetDrop(FloatingDockContainer *floatingWidget)
|
||||||
|
{
|
||||||
|
if (!floatingWidget || d->m_dockManager->isRestoringState())
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto vDockWidget = floatingWidget->property("FocusedDockWidget");
|
||||||
|
if (!vDockWidget.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto dockWidget = vDockWidget.value<DockWidget *>();
|
||||||
|
if (dockWidget) {
|
||||||
|
dockWidget->dockAreaWidget()->setCurrentDockWidget(dockWidget);
|
||||||
|
DockManager::setWidgetFocus(dockWidget->tabWidget());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockFocusController::onStateRestored()
|
||||||
|
{
|
||||||
|
if (d->m_focusedDockWidget)
|
||||||
|
updateDockWidgetFocusStyle(d->m_focusedDockWidget, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ADS
|
109
src/libs/advanceddockingsystem/dockfocuscontroller.h
Normal file
109
src/libs/advanceddockingsystem/dockfocuscontroller.h
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 Uwe Kindler
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 or (at your option) any later version.
|
||||||
|
** The licenses are as published by the Free Software Foundation
|
||||||
|
** and appearing in the file LICENSE.LGPLv21 included in the packaging
|
||||||
|
** of this file. Please review the following information to ensure
|
||||||
|
** the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 or (at your option) any later version
|
||||||
|
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||||
|
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ads_globals.h"
|
||||||
|
#include "dockmanager.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace ADS {
|
||||||
|
|
||||||
|
class DockFocusControllerPrivate;
|
||||||
|
class DockManager;
|
||||||
|
class FloatingDockContainer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages focus styling of dock widgets and handling of focus changes
|
||||||
|
*/
|
||||||
|
class ADS_EXPORT DockFocusController : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
DockFocusControllerPrivate* d; ///< private data (pimpl)
|
||||||
|
friend class DockFocusControllerPrivate;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onApplicationFocusChanged(QWidget *old, QWidget *now);
|
||||||
|
void onFocusedDockAreaViewToggled(bool open);
|
||||||
|
void onStateRestored();
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Default Constructor
|
||||||
|
*/
|
||||||
|
DockFocusController(DockManager *dockManager);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Virtual Destructor
|
||||||
|
*/
|
||||||
|
~DockFocusController() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to set focus depending on the configuration of the
|
||||||
|
* FocusStyling flag
|
||||||
|
*/
|
||||||
|
template <class QWidgetPtr>
|
||||||
|
static void setWidgetFocus(QWidgetPtr widget)
|
||||||
|
{
|
||||||
|
if (!DockManager::testConfigFlag(DockManager::FocusHighlighting))
|
||||||
|
return;
|
||||||
|
|
||||||
|
widget->setFocus(Qt::OtherFocusReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A container needs to call this function if a widget has been dropped
|
||||||
|
* into it
|
||||||
|
*/
|
||||||
|
void notifyWidgetOrAreaRelocation(QWidget *relocatedWidget);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is called, if a floating widget has been dropped into
|
||||||
|
* an new position.
|
||||||
|
* When this function is called, all dock widgets of the FloatingWidget
|
||||||
|
* are already inserted into its new position
|
||||||
|
*/
|
||||||
|
void notifyFloatingWidgetDrop(FloatingDockContainer *floatingWidget);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request a focus change to the given dock widget
|
||||||
|
*/
|
||||||
|
void setDockWidgetFocused(DockWidget *focusedNow);
|
||||||
|
}; // class DockFocusController
|
||||||
|
|
||||||
|
} // namespace ADS
|
@@ -36,7 +36,9 @@
|
|||||||
#include "dockmanager.h"
|
#include "dockmanager.h"
|
||||||
|
|
||||||
#include "ads_globals.h"
|
#include "ads_globals.h"
|
||||||
|
#include "dockareatitlebar.h"
|
||||||
#include "dockareawidget.h"
|
#include "dockareawidget.h"
|
||||||
|
#include "dockfocuscontroller.h"
|
||||||
#include "dockingstatereader.h"
|
#include "dockingstatereader.h"
|
||||||
#include "dockoverlay.h"
|
#include "dockoverlay.h"
|
||||||
#include "dockwidget.h"
|
#include "dockwidget.h"
|
||||||
@@ -72,6 +74,15 @@ static Q_LOGGING_CATEGORY(adsLog, "qtc.qmldesigner.advanceddockingsystem", QtWar
|
|||||||
|
|
||||||
namespace ADS
|
namespace ADS
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Internal file version in case the structure changes internally
|
||||||
|
*/
|
||||||
|
enum eStateFileVersion {
|
||||||
|
InitialVersion = 0, //!< InitialVersion
|
||||||
|
Version1 = 1, //!< Version1
|
||||||
|
CurrentVersion = Version1 //!< CurrentVersion
|
||||||
|
};
|
||||||
|
|
||||||
static DockManager::ConfigFlags g_staticConfigFlags = DockManager::DefaultNonOpaqueConfig;
|
static DockManager::ConfigFlags g_staticConfigFlags = DockManager::DefaultNonOpaqueConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -88,6 +99,7 @@ namespace ADS
|
|||||||
QMap<QString, DockWidget *> m_dockWidgetsMap;
|
QMap<QString, DockWidget *> m_dockWidgetsMap;
|
||||||
bool m_restoringState = false;
|
bool m_restoringState = false;
|
||||||
QVector<FloatingDockContainer *> m_uninitializedFloatingWidgets;
|
QVector<FloatingDockContainer *> m_uninitializedFloatingWidgets;
|
||||||
|
DockFocusController *m_focusController = nullptr;
|
||||||
|
|
||||||
QString m_workspaceName;
|
QString m_workspaceName;
|
||||||
bool m_workspaceListDirty = true;
|
bool m_workspaceListDirty = true;
|
||||||
@@ -159,12 +171,11 @@ namespace ADS
|
|||||||
} else {
|
} else {
|
||||||
qCInfo(adsLog) << "d->m_containers[i]->restoreState ";
|
qCInfo(adsLog) << "d->m_containers[i]->restoreState ";
|
||||||
auto container = m_containers[index];
|
auto container = m_containers[index];
|
||||||
if (container->isFloating()) {
|
if (container->isFloating())
|
||||||
result = container->floatingWidget()->restoreState(stream, testing);
|
result = container->floatingWidget()->restoreState(stream, testing);
|
||||||
} else {
|
else
|
||||||
result = container->restoreState(stream, testing);
|
result = container->restoreState(stream, testing);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -190,6 +201,17 @@ namespace ADS
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
stateReader.setFileVersion(v);
|
stateReader.setFileVersion(v);
|
||||||
|
|
||||||
|
qCInfo(adsLog) << stateReader.attributes().value("userVersion");
|
||||||
|
// Older files do not support UserVersion but we still want to load them so
|
||||||
|
// we first test if the attribute exists
|
||||||
|
if (!stateReader.attributes().value("userVersion").isEmpty())
|
||||||
|
{
|
||||||
|
v = stateReader.attributes().value("userVersion").toInt(&ok);
|
||||||
|
if (!ok || v != version)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool result = true;
|
bool result = true;
|
||||||
#ifdef ADS_DEBUG_PRINT
|
#ifdef ADS_DEBUG_PRINT
|
||||||
int dockContainers = stateReader.attributes().value("containers").toInt();
|
int dockContainers = stateReader.attributes().value("containers").toInt();
|
||||||
@@ -248,9 +270,8 @@ namespace ADS
|
|||||||
DockAreaWidget *dockArea = dockContainer->dockArea(i);
|
DockAreaWidget *dockArea = dockContainer->dockArea(i);
|
||||||
QString dockWidgetName = dockArea->property("currentDockWidget").toString();
|
QString dockWidgetName = dockArea->property("currentDockWidget").toString();
|
||||||
DockWidget *dockWidget = nullptr;
|
DockWidget *dockWidget = nullptr;
|
||||||
if (!dockWidgetName.isEmpty()) {
|
if (!dockWidgetName.isEmpty())
|
||||||
dockWidget = q->findDockWidget(dockWidgetName);
|
dockWidget = q->findDockWidget(dockWidgetName);
|
||||||
}
|
|
||||||
|
|
||||||
if (!dockWidget || dockWidget->isClosed()) {
|
if (!dockWidget || dockWidget->isClosed()) {
|
||||||
int index = dockArea->indexOfFirstOpenDockWidget();
|
int index = dockArea->indexOfFirstOpenDockWidget();
|
||||||
@@ -276,13 +297,12 @@ namespace ADS
|
|||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < dockContainer->dockAreaCount(); ++i) {
|
for (int i = 0; i < dockContainer->dockAreaCount(); ++i) {
|
||||||
auto dockArea = dockContainer->dockArea(i);
|
auto dockArea = dockContainer->dockArea(i);
|
||||||
for (auto dockWidget : dockArea->dockWidgets()) {
|
for (auto dockWidget : dockArea->dockWidgets())
|
||||||
dockWidget->emitTopLevelChanged(false);
|
dockWidget->emitTopLevelChanged(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool DockManagerPrivate::restoreState(const QByteArray &state, int version)
|
bool DockManagerPrivate::restoreState(const QByteArray &state, int version)
|
||||||
{
|
{
|
||||||
@@ -326,6 +346,9 @@ namespace ADS
|
|||||||
d->m_dockAreaOverlay = new DockOverlay(this, DockOverlay::ModeDockAreaOverlay);
|
d->m_dockAreaOverlay = new DockOverlay(this, DockOverlay::ModeDockAreaOverlay);
|
||||||
d->m_containerOverlay = new DockOverlay(this, DockOverlay::ModeContainerOverlay);
|
d->m_containerOverlay = new DockOverlay(this, DockOverlay::ModeContainerOverlay);
|
||||||
d->m_containers.append(this);
|
d->m_containers.append(this);
|
||||||
|
|
||||||
|
if (DockManager::configFlags().testFlag(DockManager::FocusHighlighting))
|
||||||
|
d->m_focusController = new DockFocusController(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
DockManager::~DockManager()
|
DockManager::~DockManager()
|
||||||
@@ -398,14 +421,13 @@ namespace ADS
|
|||||||
DockAreaWidget *DockManager::addDockWidgetTab(DockWidgetArea area, DockWidget *dockWidget)
|
DockAreaWidget *DockManager::addDockWidgetTab(DockWidgetArea area, DockWidget *dockWidget)
|
||||||
{
|
{
|
||||||
DockAreaWidget *areaWidget = lastAddedDockAreaWidget(area);
|
DockAreaWidget *areaWidget = lastAddedDockAreaWidget(area);
|
||||||
if (areaWidget) {
|
if (areaWidget)
|
||||||
return addDockWidget(ADS::CenterDockWidgetArea, dockWidget, areaWidget);
|
return addDockWidget(ADS::CenterDockWidgetArea, dockWidget, areaWidget);
|
||||||
} else if (!openedDockAreas().isEmpty()) {
|
else if (!openedDockAreas().isEmpty())
|
||||||
return addDockWidget(area, dockWidget, openedDockAreas().last());
|
return addDockWidget(area, dockWidget, openedDockAreas().last());
|
||||||
} else {
|
else
|
||||||
return addDockWidget(area, dockWidget, nullptr);
|
return addDockWidget(area, dockWidget, nullptr);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
DockAreaWidget *DockManager::addDockWidgetTabToArea(DockWidget *dockWidget,
|
DockAreaWidget *DockManager::addDockWidgetTabToArea(DockWidget *dockWidget,
|
||||||
DockAreaWidget *dockAreaWidget)
|
DockAreaWidget *dockAreaWidget)
|
||||||
@@ -423,11 +445,11 @@ namespace ADS
|
|||||||
dockWidget->setDockManager(this);
|
dockWidget->setDockManager(this);
|
||||||
FloatingDockContainer *floatingWidget = new FloatingDockContainer(dockWidget);
|
FloatingDockContainer *floatingWidget = new FloatingDockContainer(dockWidget);
|
||||||
floatingWidget->resize(dockWidget->size());
|
floatingWidget->resize(dockWidget->size());
|
||||||
if (isVisible()) {
|
if (isVisible())
|
||||||
floatingWidget->show();
|
floatingWidget->show();
|
||||||
} else {
|
else
|
||||||
d->m_uninitializedFloatingWidgets.append(floatingWidget);
|
d->m_uninitializedFloatingWidgets.append(floatingWidget);
|
||||||
}
|
|
||||||
return floatingWidget;
|
return floatingWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -450,10 +472,9 @@ namespace ADS
|
|||||||
|
|
||||||
void DockManager::removeDockContainer(DockContainerWidget *dockContainer)
|
void DockManager::removeDockContainer(DockContainerWidget *dockContainer)
|
||||||
{
|
{
|
||||||
if (this != dockContainer) {
|
if (this != dockContainer)
|
||||||
d->m_containers.removeAll(dockContainer);
|
d->m_containers.removeAll(dockContainer);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
DockOverlay *DockManager::containerOverlay() const { return d->m_containerOverlay; }
|
DockOverlay *DockManager::containerOverlay() const { return d->m_containerOverlay; }
|
||||||
|
|
||||||
@@ -479,7 +500,8 @@ namespace ADS
|
|||||||
stream.setAutoFormatting(configFlags.testFlag(XmlAutoFormattingEnabled));
|
stream.setAutoFormatting(configFlags.testFlag(XmlAutoFormattingEnabled));
|
||||||
stream.writeStartDocument();
|
stream.writeStartDocument();
|
||||||
stream.writeStartElement("QtAdvancedDockingSystem");
|
stream.writeStartElement("QtAdvancedDockingSystem");
|
||||||
stream.writeAttribute("version", QString::number(version));
|
stream.writeAttribute("version", QString::number(CurrentVersion));
|
||||||
|
stream.writeAttribute("userVersion", QString::number(version));
|
||||||
stream.writeAttribute("containers", QString::number(d->m_containers.count()));
|
stream.writeAttribute("containers", QString::number(d->m_containers.count()));
|
||||||
for (auto container : d->m_containers)
|
for (auto container : d->m_containers)
|
||||||
container->saveState(stream);
|
container->saveState(stream);
|
||||||
@@ -512,10 +534,10 @@ namespace ADS
|
|||||||
emit restoringState();
|
emit restoringState();
|
||||||
bool result = d->restoreState(state, version);
|
bool result = d->restoreState(state, version);
|
||||||
d->m_restoringState = false;
|
d->m_restoringState = false;
|
||||||
emit stateRestored();
|
|
||||||
if (!isHidden)
|
if (!isHidden)
|
||||||
show();
|
show();
|
||||||
|
|
||||||
|
emit stateRestored();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -574,15 +596,14 @@ namespace ADS
|
|||||||
emit aboutToSaveWorkspace();
|
emit aboutToSaveWorkspace();
|
||||||
|
|
||||||
bool result = write(activeWorkspace(), saveState(), parentWidget());
|
bool result = write(activeWorkspace(), saveState(), parentWidget());
|
||||||
if (result) {
|
if (result)
|
||||||
d->m_workspaceDateTimes.insert(activeWorkspace(), QDateTime::currentDateTime());
|
d->m_workspaceDateTimes.insert(activeWorkspace(), QDateTime::currentDateTime());
|
||||||
} else {
|
else
|
||||||
QMessageBox::warning(parentWidget(),
|
QMessageBox::warning(parentWidget(),
|
||||||
tr("Cannot Save Workspace"),
|
tr("Cannot Save Workspace"),
|
||||||
tr("Could not save workspace to file %1")
|
tr("Could not save workspace to file %1")
|
||||||
.arg(workspaceNameToFilePath(d->m_workspaceName)
|
.arg(workspaceNameToFilePath(d->m_workspaceName)
|
||||||
.toUserOutput()));
|
.toUserOutput()));
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -638,10 +659,9 @@ namespace ADS
|
|||||||
= workspacePresetsDir.entryInfoList(QStringList() << QLatin1Char('*') + m_fileExt,
|
= workspacePresetsDir.entryInfoList(QStringList() << QLatin1Char('*') + m_fileExt,
|
||||||
QDir::NoFilter,
|
QDir::NoFilter,
|
||||||
QDir::Time);
|
QDir::Time);
|
||||||
for (const QFileInfo &fileInfo : workspacePresetsFiles) {
|
for (const QFileInfo &fileInfo : workspacePresetsFiles)
|
||||||
d->m_workspacePresets.insert(fileNameToWorkspaceName(fileInfo.completeBaseName()));
|
d->m_workspacePresets.insert(fileNameToWorkspaceName(fileInfo.completeBaseName()));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return d->m_workspacePresets;
|
return d->m_workspacePresets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -819,8 +839,10 @@ namespace ADS
|
|||||||
{
|
{
|
||||||
if (!cloneWorkspace(original, newName))
|
if (!cloneWorkspace(original, newName))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (original == activeWorkspace())
|
if (original == activeWorkspace())
|
||||||
openWorkspace(newName);
|
openWorkspace(newName);
|
||||||
|
|
||||||
return deleteWorkspace(original);
|
return deleteWorkspace(original);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1002,10 +1024,10 @@ namespace ADS
|
|||||||
QFile file(filePath);
|
QFile file(filePath);
|
||||||
|
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
if (!file.copy(workspaceDir.filePath(fileName))) {
|
if (!file.copy(workspaceDir.filePath(fileName)))
|
||||||
qCInfo(adsLog) << QString("Could not copy '%1' to '%2' error: %3").arg(
|
qCInfo(adsLog) << QString("Could not copy '%1' to '%2' error: %3").arg(
|
||||||
filePath, workspaceDir.filePath(fileName), file.errorString());
|
filePath, workspaceDir.filePath(fileName), file.errorString());
|
||||||
}
|
|
||||||
d->m_workspaceListDirty = true;
|
d->m_workspaceListDirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1020,4 +1042,22 @@ namespace ADS
|
|||||||
d->m_settings->setValue(Constants::STARTUP_WORKSPACE_SETTINGS_KEY, activeWorkspace());
|
d->m_settings->setValue(Constants::STARTUP_WORKSPACE_SETTINGS_KEY, activeWorkspace());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DockManager::notifyWidgetOrAreaRelocation(QWidget *droppedWidget)
|
||||||
|
{
|
||||||
|
if (d->m_focusController)
|
||||||
|
d->m_focusController->notifyWidgetOrAreaRelocation(droppedWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockManager::notifyFloatingWidgetDrop(FloatingDockContainer *floatingWidget)
|
||||||
|
{
|
||||||
|
if (d->m_focusController)
|
||||||
|
d->m_focusController->notifyFloatingWidgetDrop(floatingWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockManager::setDockWidgetFocused(DockWidget *dockWidget)
|
||||||
|
{
|
||||||
|
if (d->m_focusController)
|
||||||
|
d->m_focusController->setDockWidgetFocused(dockWidget);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ADS
|
} // namespace ADS
|
||||||
|
@@ -142,6 +142,32 @@ protected:
|
|||||||
*/
|
*/
|
||||||
DockOverlay *dockAreaOverlay() const;
|
DockOverlay *dockAreaOverlay() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A container needs to call this function if a widget has been dropped
|
||||||
|
* into it
|
||||||
|
*/
|
||||||
|
void notifyWidgetOrAreaRelocation(QWidget *droppedWidget);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is called, if a floating widget has been dropped into
|
||||||
|
* an new position.
|
||||||
|
* When this function is called, all dock widgets of the FloatingWidget
|
||||||
|
* are already inserted into its new position
|
||||||
|
*/
|
||||||
|
void notifyFloatingWidgetDrop(FloatingDockContainer *floatingWidget);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is called, if the given DockWidget has been relocated from
|
||||||
|
* the old container ContainerOld to the new container DockWidget->dockContainer()
|
||||||
|
*/
|
||||||
|
void notifyDockWidgetRelocation(DockWidget *dockWidget, DockContainerWidget *containerOld);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is called, if the given DockAreahas been relocated from
|
||||||
|
* the old container ContainerOld to the new container DockArea->dockContainer()
|
||||||
|
*/
|
||||||
|
void notifyDockAreaRelocation(DockAreaWidget *dockArea, DockContainerWidget *containerOld);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the floating widgets that has been created floating
|
* Show the floating widgets that has been created floating
|
||||||
*/
|
*/
|
||||||
@@ -190,11 +216,18 @@ public:
|
|||||||
DockAreaHideDisabledButtons
|
DockAreaHideDisabledButtons
|
||||||
= 0x10000, //!< If the flag is set disabled dock area buttons will not appear on the tollbar at all (enabling them will bring them back)
|
= 0x10000, //!< If the flag is set disabled dock area buttons will not appear on the tollbar at all (enabling them will bring them back)
|
||||||
DockAreaDynamicTabsMenuButtonVisibility
|
DockAreaDynamicTabsMenuButtonVisibility
|
||||||
= 0x20000, //!< If the flag is set dock area will disable a tabs menu button when there is only one tab in the area
|
= 0x20000, //!< If the flag is set, the tabs menu button will be shown only when it is required - that means, if the tabs are elided. If the tabs are not elided, it is hidden
|
||||||
FloatingContainerHasWidgetTitle
|
FloatingContainerHasWidgetTitle
|
||||||
= 0x40000,
|
= 0x40000, //!< If set, the Floating Widget window title reflects the title of the current dock widget otherwise it displays application name as window title
|
||||||
FloatingContainerHasWidgetIcon
|
FloatingContainerHasWidgetIcon
|
||||||
= 0x80000,
|
= 0x80000, //!< If set, the Floating Widget icon reflects the icon of the current dock widget otherwise it displays application icon
|
||||||
|
HideSingleCentralWidgetTitleBar
|
||||||
|
= 0x100000, //!< If there is only one single visible dock widget in the main dock container (the dock manager) and if this flag is set, then the titlebar of this dock widget will be hidden
|
||||||
|
//!< this only makes sense for non draggable and non floatable widgets and enables the creation of some kind of "central" widget
|
||||||
|
FocusHighlighting
|
||||||
|
= 0x200000, //!< enables styling of focused dock widget tabs or floating widget titlebar
|
||||||
|
EqualSplitOnInsertion
|
||||||
|
= 0x400000, ///!< if enabled, the space is equally distributed to all widgets in a splitter
|
||||||
|
|
||||||
DefaultDockAreaButtons = DockAreaHasCloseButton
|
DefaultDockAreaButtons = DockAreaHasCloseButton
|
||||||
| DockAreaHasUndockButton
|
| DockAreaHasUndockButton
|
||||||
@@ -267,6 +300,19 @@ public:
|
|||||||
*/
|
*/
|
||||||
static int startDragDistance();
|
static int startDragDistance();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to set focus depending on the configuration of the
|
||||||
|
* FocusStyling flag
|
||||||
|
*/
|
||||||
|
template <class QWidgetPtr>
|
||||||
|
static void setWidgetFocus(QWidgetPtr widget)
|
||||||
|
{
|
||||||
|
if (!DockManager::testConfigFlag(DockManager::FocusHighlighting))
|
||||||
|
return;
|
||||||
|
|
||||||
|
widget->setFocus(Qt::OtherFocusReason);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the QtCreator settings.
|
* Set the QtCreator settings.
|
||||||
*/
|
*/
|
||||||
@@ -358,8 +404,12 @@ public:
|
|||||||
* If auto formatting is enabled, the output is intended and line wrapped.
|
* If auto formatting is enabled, the output is intended and line wrapped.
|
||||||
* The XmlMode XmlAutoFormattingDisabled is better if you would like to have
|
* The XmlMode XmlAutoFormattingDisabled is better if you would like to have
|
||||||
* a more compact XML output - i.e. for storage in ini files.
|
* a more compact XML output - i.e. for storage in ini files.
|
||||||
|
* The version number is stored as part of the data.
|
||||||
|
* To restore the saved state, pass the return value and version number
|
||||||
|
* to restoreState().
|
||||||
|
* \see restoreState()
|
||||||
*/
|
*/
|
||||||
QByteArray saveState(int version = Version1) const;
|
QByteArray saveState(int version = 0) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restores the state of this dockmanagers dockwidgets.
|
* Restores the state of this dockmanagers dockwidgets.
|
||||||
@@ -367,8 +417,9 @@ public:
|
|||||||
* not match, the dockmanager's state is left unchanged, and this function
|
* not match, the dockmanager's state is left unchanged, and this function
|
||||||
* returns false; otherwise, the state is restored, and this function
|
* returns false; otherwise, the state is restored, and this function
|
||||||
* returns true.
|
* returns true.
|
||||||
|
* \see saveState()
|
||||||
*/
|
*/
|
||||||
bool restoreState(const QByteArray &state, int version = Version1);
|
bool restoreState(const QByteArray &state, int version = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function returns true between the restoringState() and
|
* This function returns true between the restoringState() and
|
||||||
@@ -376,6 +427,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool isRestoringState() const;
|
bool isRestoringState() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request a focus change to the given dock widget.
|
||||||
|
* This function only has an effect, if the flag CDockManager::FocusStyling
|
||||||
|
* is enabled
|
||||||
|
*/
|
||||||
|
void setDockWidgetFocused(DockWidget *dockWidget);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/**
|
/**
|
||||||
* This signal is emitted if the list of workspaces changed.
|
* This signal is emitted if the list of workspaces changed.
|
||||||
@@ -444,6 +502,13 @@ signals:
|
|||||||
*/
|
*/
|
||||||
void dockWidgetRemoved(DockWidget *dockWidget);
|
void dockWidgetRemoved(DockWidget *dockWidget);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This signal is emitted if the focused dock widget changed.
|
||||||
|
* Both old and now can be nullptr.
|
||||||
|
* The focused dock widget is the one that is highlighted in the GUI
|
||||||
|
*/
|
||||||
|
void focusedDockWidgetChanged(DockWidget *old, DockWidget *now);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void showWorkspaceMananger();
|
void showWorkspaceMananger();
|
||||||
|
|
||||||
|
@@ -36,6 +36,7 @@
|
|||||||
#include "dockoverlay.h"
|
#include "dockoverlay.h"
|
||||||
|
|
||||||
#include "dockareawidget.h"
|
#include "dockareawidget.h"
|
||||||
|
#include "dockareatitlebar.h"
|
||||||
|
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
|
|
||||||
@@ -151,12 +152,10 @@ namespace ADS {
|
|||||||
*/
|
*/
|
||||||
qreal dropIndicatiorWidth(QLabel *label) const
|
qreal dropIndicatiorWidth(QLabel *label) const
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_LINUX
|
if (Utils::HostOsInfo::isLinuxHost())
|
||||||
Q_UNUSED(label)
|
|
||||||
return 40;
|
return 40;
|
||||||
#else
|
else
|
||||||
return static_cast<qreal>(label->fontMetrics().height()) * 3.f;
|
return static_cast<qreal>(label->fontMetrics().height()) * 3.f;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *createDropIndicatorWidget(DockWidgetArea dockWidgetArea, DockOverlay::eMode mode)
|
QWidget *createDropIndicatorWidget(DockWidgetArea dockWidgetArea, DockOverlay::eMode mode)
|
||||||
@@ -190,10 +189,10 @@ namespace ADS {
|
|||||||
DockWidgetArea dockWidgetArea,
|
DockWidgetArea dockWidgetArea,
|
||||||
DockOverlay::eMode mode)
|
DockOverlay::eMode mode)
|
||||||
{
|
{
|
||||||
QColor borderColor = iconColor(DockOverlayCross::FrameColor);
|
const QColor borderColor = iconColor(DockOverlayCross::FrameColor);
|
||||||
QColor backgroundColor = iconColor(DockOverlayCross::WindowBackgroundColor);
|
const QColor backgroundColor = iconColor(DockOverlayCross::WindowBackgroundColor);
|
||||||
double devicePixelRatio = q->window()->devicePixelRatioF();
|
const double devicePixelRatio = q->window()->devicePixelRatioF();
|
||||||
QSizeF pixmapSize = size * devicePixelRatio;
|
const QSizeF pixmapSize = size * devicePixelRatio;
|
||||||
QPixmap pixmap(pixmapSize.toSize());
|
QPixmap pixmap(pixmapSize.toSize());
|
||||||
pixmap.fill(QColor(0, 0, 0, 0));
|
pixmap.fill(QColor(0, 0, 0, 0));
|
||||||
|
|
||||||
@@ -259,7 +258,7 @@ namespace ADS {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSizeF baseSize = baseRect.size();
|
const QSizeF baseSize = baseRect.size();
|
||||||
if (DockOverlay::ModeContainerOverlay == mode && dockWidgetArea != CenterDockWidgetArea) {
|
if (DockOverlay::ModeContainerOverlay == mode && dockWidgetArea != CenterDockWidgetArea) {
|
||||||
baseRect = areaRect;
|
baseRect = areaRect;
|
||||||
}
|
}
|
||||||
@@ -296,7 +295,7 @@ namespace ADS {
|
|||||||
|
|
||||||
// draw window title bar
|
// draw window title bar
|
||||||
painter.setBrush(borderColor);
|
painter.setBrush(borderColor);
|
||||||
QRectF frameRect(baseRect.topLeft(), QSizeF(baseRect.width(), baseSize.height() / 10));
|
const QRectF frameRect(baseRect.topLeft(), QSizeF(baseRect.width(), baseSize.height() / 10));
|
||||||
painter.drawRect(frameRect);
|
painter.drawRect(frameRect);
|
||||||
painter.restore();
|
painter.restore();
|
||||||
|
|
||||||
@@ -370,6 +369,7 @@ namespace ADS {
|
|||||||
{
|
{
|
||||||
if (areas == d->m_allowedAreas)
|
if (areas == d->m_allowedAreas)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
d->m_allowedAreas = areas;
|
d->m_allowedAreas = areas;
|
||||||
d->m_cross->reset();
|
d->m_cross->reset();
|
||||||
}
|
}
|
||||||
@@ -382,19 +382,17 @@ namespace ADS {
|
|||||||
DockWidgetArea DockOverlay::dropAreaUnderCursor() const
|
DockWidgetArea DockOverlay::dropAreaUnderCursor() const
|
||||||
{
|
{
|
||||||
DockWidgetArea result = d->m_cross->cursorLocation();
|
DockWidgetArea result = d->m_cross->cursorLocation();
|
||||||
if (result != InvalidDockWidgetArea) {
|
if (result != InvalidDockWidgetArea)
|
||||||
return result;
|
return result;
|
||||||
}
|
|
||||||
|
|
||||||
DockAreaWidget *dockArea = qobject_cast<DockAreaWidget *>(d->m_targetWidget.data());
|
DockAreaWidget *dockArea = qobject_cast<DockAreaWidget *>(d->m_targetWidget.data());
|
||||||
if (!dockArea) {
|
if (!dockArea)
|
||||||
return result;
|
return result;
|
||||||
}
|
|
||||||
|
|
||||||
if (dockArea->allowedAreas().testFlag(CenterDockWidgetArea)
|
if (dockArea->allowedAreas().testFlag(CenterDockWidgetArea)
|
||||||
&& dockArea->titleBarGeometry().contains(dockArea->mapFromGlobal(QCursor::pos()))) {
|
&& !dockArea->titleBar()->isHidden()
|
||||||
|
&& dockArea->titleBarGeometry().contains(dockArea->mapFromGlobal(QCursor::pos())))
|
||||||
return CenterDockWidgetArea;
|
return CenterDockWidgetArea;
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -518,9 +516,9 @@ namespace ADS {
|
|||||||
bool DockOverlay::event(QEvent *event)
|
bool DockOverlay::event(QEvent *event)
|
||||||
{
|
{
|
||||||
bool result = Super::event(event);
|
bool result = Super::event(event);
|
||||||
if (event->type() == QEvent::Polish) {
|
if (event->type() == QEvent::Polish)
|
||||||
d->m_cross->setupOverlayCross(d->m_mode);
|
d->m_cross->setupOverlayCross(d->m_mode);
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -622,13 +620,12 @@ namespace ADS {
|
|||||||
|
|
||||||
void DockOverlayCross::updateOverlayIcons()
|
void DockOverlayCross::updateOverlayIcons()
|
||||||
{
|
{
|
||||||
if (windowHandle()->devicePixelRatio() == d->m_lastDevicePixelRatio) { // TODO
|
if (windowHandle()->devicePixelRatio() == d->m_lastDevicePixelRatio) // TODO
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
for (auto Widget : d->m_dropIndicatorWidgets) {
|
for (auto widget : d->m_dropIndicatorWidgets)
|
||||||
d->updateDropIndicatorIcon(Widget);
|
d->updateDropIndicatorIcon(widget);
|
||||||
}
|
|
||||||
d->m_lastDevicePixelRatio = devicePixelRatioF();
|
d->m_lastDevicePixelRatio = devicePixelRatioF();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -661,7 +658,7 @@ namespace ADS {
|
|||||||
for (constIt = areas.begin(); constIt != areas.end(); ++constIt) {
|
for (constIt = areas.begin(); constIt != areas.end(); ++constIt) {
|
||||||
const DockWidgetArea area = constIt.key();
|
const DockWidgetArea area = constIt.key();
|
||||||
QWidget *widget = constIt.value();
|
QWidget *widget = constIt.value();
|
||||||
QPoint position = d->areaGridPosition(area);
|
const QPoint position = d->areaGridPosition(area);
|
||||||
d->m_gridLayout->addWidget(widget,
|
d->m_gridLayout->addWidget(widget,
|
||||||
position.x(),
|
position.x(),
|
||||||
position.y(),
|
position.y(),
|
||||||
@@ -717,9 +714,9 @@ namespace ADS {
|
|||||||
|
|
||||||
void DockOverlayCross::showEvent(QShowEvent *)
|
void DockOverlayCross::showEvent(QShowEvent *)
|
||||||
{
|
{
|
||||||
if (d->m_updateRequired) {
|
if (d->m_updateRequired)
|
||||||
setupOverlayCross(d->m_mode);
|
setupOverlayCross(d->m_mode);
|
||||||
}
|
|
||||||
this->updatePosition();
|
this->updatePosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -744,14 +741,13 @@ namespace ADS {
|
|||||||
|
|
||||||
// Update visibility of area widgets based on allowedAreas.
|
// Update visibility of area widgets based on allowedAreas.
|
||||||
for (auto area : allAreas) {
|
for (auto area : allAreas) {
|
||||||
QPoint position = d->areaGridPosition(area);
|
const QPoint position = d->areaGridPosition(area);
|
||||||
QLayoutItem *item = d->m_gridLayout->itemAtPosition(position.x(), position.y());
|
QLayoutItem *item = d->m_gridLayout->itemAtPosition(position.x(), position.y());
|
||||||
QWidget *widget = nullptr;
|
QWidget *widget = nullptr;
|
||||||
if (item && (widget = item->widget()) != nullptr) {
|
if (item && (widget = item->widget()) != nullptr)
|
||||||
widget->setVisible(allowedAreas.testFlag(area));
|
widget->setVisible(allowedAreas.testFlag(area));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void DockOverlayCross::setIconColors(const QString &colors)
|
void DockOverlayCross::setIconColors(const QString &colors)
|
||||||
{
|
{
|
||||||
@@ -766,9 +762,9 @@ namespace ADS {
|
|||||||
for (const auto &colorListEntry : colorList) {
|
for (const auto &colorListEntry : colorList) {
|
||||||
auto componentColor = colorListEntry.split('=', QString::SkipEmptyParts);
|
auto componentColor = colorListEntry.split('=', QString::SkipEmptyParts);
|
||||||
int component = colorCompenentStringMap.value(componentColor[0], -1);
|
int component = colorCompenentStringMap.value(componentColor[0], -1);
|
||||||
if (component < 0) {
|
if (component < 0)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
d->m_iconColors[component] = QColor(componentColor[1]);
|
d->m_iconColors[component] = QColor(componentColor[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -55,6 +55,7 @@
|
|||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <QToolBar>
|
#include <QToolBar>
|
||||||
#include <QXmlStreamWriter>
|
#include <QXmlStreamWriter>
|
||||||
|
#include <QWindow>
|
||||||
|
|
||||||
static Q_LOGGING_CATEGORY(adsLog, "qtc.qmldesigner.advanceddockingsystem", QtWarningMsg)
|
static Q_LOGGING_CATEGORY(adsLog, "qtc.qmldesigner.advanceddockingsystem", QtWarningMsg)
|
||||||
|
|
||||||
@@ -127,6 +128,7 @@ namespace ADS
|
|||||||
if (!m_dockArea) {
|
if (!m_dockArea) {
|
||||||
FloatingDockContainer *floatingWidget = new FloatingDockContainer(q);
|
FloatingDockContainer *floatingWidget = new FloatingDockContainer(q);
|
||||||
floatingWidget->resize(q->size());
|
floatingWidget->resize(q->size());
|
||||||
|
m_tabWidget->show();
|
||||||
floatingWidget->show();
|
floatingWidget->show();
|
||||||
} else {
|
} else {
|
||||||
m_dockArea->setCurrentDockWidget(q);
|
m_dockArea->setCurrentDockWidget(q);
|
||||||
@@ -204,6 +206,9 @@ namespace ADS
|
|||||||
d->m_toggleViewAction->setCheckable(true);
|
d->m_toggleViewAction->setCheckable(true);
|
||||||
connect(d->m_toggleViewAction, &QAction::triggered, this, &DockWidget::toggleView);
|
connect(d->m_toggleViewAction, &QAction::triggered, this, &DockWidget::toggleView);
|
||||||
setToolbarFloatingStyle(false);
|
setToolbarFloatingStyle(false);
|
||||||
|
|
||||||
|
if (DockManager::testConfigFlag(DockManager::FocusHighlighting))
|
||||||
|
setFocusPolicy(Qt::ClickFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
DockWidget::~DockWidget()
|
DockWidget::~DockWidget()
|
||||||
@@ -222,7 +227,10 @@ namespace ADS
|
|||||||
|
|
||||||
void DockWidget::setWidget(QWidget *widget, eInsertMode insertMode)
|
void DockWidget::setWidget(QWidget *widget, eInsertMode insertMode)
|
||||||
{
|
{
|
||||||
QScrollArea *scrollAreaWidget = qobject_cast<QScrollArea *>(widget);
|
if (d->m_widget)
|
||||||
|
takeWidget();
|
||||||
|
|
||||||
|
auto scrollAreaWidget = qobject_cast<QAbstractScrollArea *>(widget);
|
||||||
if (scrollAreaWidget || ForceNoScrollArea == insertMode) {
|
if (scrollAreaWidget || ForceNoScrollArea == insertMode) {
|
||||||
d->m_layout->addWidget(widget);
|
d->m_layout->addWidget(widget);
|
||||||
if (scrollAreaWidget && scrollAreaWidget->viewport())
|
if (scrollAreaWidget && scrollAreaWidget->viewport())
|
||||||
@@ -238,11 +246,23 @@ namespace ADS
|
|||||||
|
|
||||||
QWidget *DockWidget::takeWidget()
|
QWidget *DockWidget::takeWidget()
|
||||||
{
|
{
|
||||||
// TODO Shouldn't m_widget being set to nullptr?!
|
QWidget *w = nullptr;
|
||||||
d->m_scrollArea->takeWidget();
|
if (d->m_scrollArea) {
|
||||||
|
d->m_layout->removeWidget(d->m_scrollArea);
|
||||||
|
w = d->m_scrollArea->takeWidget();
|
||||||
|
delete d->m_scrollArea;
|
||||||
|
d->m_scrollArea = nullptr;
|
||||||
|
d->m_widget = nullptr;
|
||||||
|
} else if (d->m_widget) {
|
||||||
d->m_layout->removeWidget(d->m_widget);
|
d->m_layout->removeWidget(d->m_widget);
|
||||||
d->m_widget->setParent(nullptr);
|
w = d->m_widget;
|
||||||
return d->m_widget;
|
d->m_widget = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (w)
|
||||||
|
w->setParent(nullptr);
|
||||||
|
|
||||||
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *DockWidget::widget() const { return d->m_widget; }
|
QWidget *DockWidget::widget() const { return d->m_widget; }
|
||||||
@@ -251,9 +271,9 @@ namespace ADS
|
|||||||
|
|
||||||
void DockWidget::setFeatures(DockWidgetFeatures features)
|
void DockWidget::setFeatures(DockWidgetFeatures features)
|
||||||
{
|
{
|
||||||
if (d->m_features == features) {
|
if (d->m_features == features)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
d->m_features = features;
|
d->m_features = features;
|
||||||
emit featuresChanged(d->m_features);
|
emit featuresChanged(d->m_features);
|
||||||
d->m_tabWidget->onDockWidgetFeaturesChanged();
|
d->m_tabWidget->onDockWidgetFeaturesChanged();
|
||||||
@@ -274,12 +294,11 @@ namespace ADS
|
|||||||
|
|
||||||
DockContainerWidget *DockWidget::dockContainer() const
|
DockContainerWidget *DockWidget::dockContainer() const
|
||||||
{
|
{
|
||||||
if (d->m_dockArea) {
|
if (d->m_dockArea)
|
||||||
return d->m_dockArea->dockContainer();
|
return d->m_dockArea->dockContainer();
|
||||||
} else {
|
else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
DockAreaWidget *DockWidget::dockAreaWidget() const { return d->m_dockArea; }
|
DockAreaWidget *DockWidget::dockAreaWidget() const { return d->m_dockArea; }
|
||||||
|
|
||||||
@@ -347,11 +366,11 @@ namespace ADS
|
|||||||
? beforeDockContainerWidget->topLevelDockWidget()
|
? beforeDockContainerWidget->topLevelDockWidget()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
|
|
||||||
if (open) {
|
if (open)
|
||||||
d->showDockWidget();
|
d->showDockWidget();
|
||||||
} else {
|
else
|
||||||
d->hideDockWidget();
|
d->hideDockWidget();
|
||||||
}
|
|
||||||
d->m_closed = !open;
|
d->m_closed = !open;
|
||||||
//d->m_toggleViewAction->blockSignals(true);
|
//d->m_toggleViewAction->blockSignals(true);
|
||||||
d->m_toggleViewAction->setChecked(open);
|
d->m_toggleViewAction->setChecked(open);
|
||||||
@@ -617,4 +636,58 @@ namespace ADS
|
|||||||
return d->m_titleBarActions;
|
return d->m_titleBarActions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DockWidget::showFullScreen()
|
||||||
|
{
|
||||||
|
if (isFloating())
|
||||||
|
dockContainer()->floatingWidget()->showFullScreen();
|
||||||
|
else
|
||||||
|
Super::showFullScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockWidget::showNormal()
|
||||||
|
{
|
||||||
|
if (isFloating())
|
||||||
|
dockContainer()->floatingWidget()->showNormal();
|
||||||
|
else
|
||||||
|
Super::showNormal();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DockWidget::isFullScreen() const
|
||||||
|
{
|
||||||
|
if (isFloating())
|
||||||
|
return dockContainer()->floatingWidget()->isFullScreen();
|
||||||
|
else
|
||||||
|
return Super::isFullScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockWidget::setAsCurrentTab()
|
||||||
|
{
|
||||||
|
if (d->m_dockArea && !isClosed())
|
||||||
|
d->m_dockArea->setCurrentDockWidget(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DockWidget::isTabbed() const
|
||||||
|
{
|
||||||
|
return d->m_dockArea && (d->m_dockArea->openDockWidgetsCount() > 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DockWidget::isCurrentTab() const
|
||||||
|
{
|
||||||
|
return d->m_dockArea && (d->m_dockArea->currentDockWidget() == this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockWidget::raise()
|
||||||
|
{
|
||||||
|
if (isClosed())
|
||||||
|
return;
|
||||||
|
|
||||||
|
setAsCurrentTab();
|
||||||
|
if (isInFloatingContainer())
|
||||||
|
{
|
||||||
|
auto floatingWindow = window();
|
||||||
|
floatingWindow->raise();
|
||||||
|
floatingWindow->activateWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ADS
|
} // namespace ADS
|
||||||
|
@@ -152,8 +152,8 @@ public:
|
|||||||
using Super = QFrame;
|
using Super = QFrame;
|
||||||
|
|
||||||
enum DockWidgetFeature {
|
enum DockWidgetFeature {
|
||||||
DockWidgetClosable = 0x01,
|
DockWidgetClosable = 0x01,///< dock widget has a close button
|
||||||
DockWidgetMovable = 0x02,///< this feature is not properly implemented yet and is ignored
|
DockWidgetMovable = 0x02,///< dock widget is movable and can be moved to a new position in the current dock container
|
||||||
DockWidgetFloatable = 0x04,
|
DockWidgetFloatable = 0x04,
|
||||||
DockWidgetDeleteOnClose = 0x08, ///< deletes the dock widget when it is closed
|
DockWidgetDeleteOnClose = 0x08, ///< deletes the dock widget when it is closed
|
||||||
CustomCloseHandling = 0x10,
|
CustomCloseHandling = 0x10,
|
||||||
@@ -435,6 +435,26 @@ public:
|
|||||||
void setTabToolTip(const QString &text);
|
void setTabToolTip(const QString &text);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the dock widget is floating and if the floating dock
|
||||||
|
* container is full screen
|
||||||
|
*/
|
||||||
|
bool isFullScreen() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this dock widget is in a dock area, that contains at
|
||||||
|
* least 2 opened dock widgets
|
||||||
|
*/
|
||||||
|
bool isTabbed() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this dock widget is the current one in the dock
|
||||||
|
* area widget that contains it.
|
||||||
|
* If the dock widget is the only opened dock widget in a dock area,
|
||||||
|
* the true is returned
|
||||||
|
*/
|
||||||
|
bool isCurrentTab() const;
|
||||||
|
|
||||||
public: // reimplements QFrame
|
public: // reimplements QFrame
|
||||||
/**
|
/**
|
||||||
* Emits titleChanged signal if title change event occurs
|
* Emits titleChanged signal if title change event occurs
|
||||||
@@ -447,6 +467,23 @@ public: // reimplements QFrame
|
|||||||
*/
|
*/
|
||||||
void toggleView(bool open = true);
|
void toggleView(bool open = true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes this dock widget the current tab in its dock area.
|
||||||
|
* The function only has an effect, if the dock widget is open. A call
|
||||||
|
* to this function will not toggle the view, so if it is closed,
|
||||||
|
* nothing will happen
|
||||||
|
*/
|
||||||
|
void setAsCurrentTab();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Brings the dock widget to the front
|
||||||
|
* This means:
|
||||||
|
* - If the dock widget is tabbed with other dock widgets but its tab is not current, it's made current.
|
||||||
|
* - If the dock widget is floating, QWindow::raise() is called.
|
||||||
|
* This only applies if the dock widget is already open. If closed, does nothing.
|
||||||
|
*/
|
||||||
|
void raise();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function will make a docked widget floating
|
* This function will make a docked widget floating
|
||||||
*/
|
*/
|
||||||
@@ -463,6 +500,26 @@ public: // reimplements QFrame
|
|||||||
*/
|
*/
|
||||||
void closeDockWidget();
|
void closeDockWidget();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* \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.
|
||||||
|
*/
|
||||||
|
void showNormal();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/**
|
/**
|
||||||
* This signal is emitted if the dock widget is opened or closed
|
* This signal is emitted if the dock widget is opened or closed
|
||||||
|
@@ -116,7 +116,7 @@ namespace ADS
|
|||||||
*/
|
*/
|
||||||
bool testConfigFlag(DockManager::eConfigFlag flag) const
|
bool testConfigFlag(DockManager::eConfigFlag flag) const
|
||||||
{
|
{
|
||||||
return DockManager::configFlags().testFlag(flag);
|
return DockManager::testConfigFlag(flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -232,18 +232,20 @@ namespace ADS
|
|||||||
|
|
||||||
qCInfo(adsLog) << "startFloating";
|
qCInfo(adsLog) << "startFloating";
|
||||||
m_dragState = draggingState;
|
m_dragState = draggingState;
|
||||||
QSize size = m_dockArea->size();
|
|
||||||
AbstractFloatingWidget *floatingWidget = nullptr;
|
AbstractFloatingWidget *floatingWidget = nullptr;
|
||||||
bool opaqueUndocking = DockManager::configFlags().testFlag(DockManager::OpaqueUndocking)
|
bool opaqueUndocking = DockManager::testConfigFlag(DockManager::OpaqueUndocking)
|
||||||
|| (DraggingFloatingWidget != draggingState);
|
|| (DraggingFloatingWidget != draggingState);
|
||||||
|
|
||||||
// If section widget has multiple tabs, we take only one tab
|
// If section widget has multiple tabs, we take only one tab
|
||||||
// If it has only one single tab, we can move the complete
|
// If it has only one single tab, we can move the complete
|
||||||
// dock area into floating widget
|
// dock area into floating widget
|
||||||
|
QSize size;
|
||||||
if (m_dockArea->dockWidgetsCount() > 1) {
|
if (m_dockArea->dockWidgetsCount() > 1) {
|
||||||
floatingWidget = createFloatingWidget(m_dockWidget, opaqueUndocking);
|
floatingWidget = createFloatingWidget(m_dockWidget, opaqueUndocking);
|
||||||
|
size = m_dockWidget->size();
|
||||||
} else {
|
} else {
|
||||||
floatingWidget = createFloatingWidget(m_dockArea, opaqueUndocking);
|
floatingWidget = createFloatingWidget(m_dockArea, opaqueUndocking);
|
||||||
|
size = m_dockArea->size();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DraggingFloatingWidget == draggingState) {
|
if (DraggingFloatingWidget == draggingState) {
|
||||||
@@ -265,6 +267,8 @@ namespace ADS
|
|||||||
setAttribute(Qt::WA_NoMousePropagation, true);
|
setAttribute(Qt::WA_NoMousePropagation, true);
|
||||||
d->m_dockWidget = dockWidget;
|
d->m_dockWidget = dockWidget;
|
||||||
d->createLayout();
|
d->createLayout();
|
||||||
|
if (DockManager::testConfigFlag(DockManager::FocusHighlighting))
|
||||||
|
setFocusPolicy(Qt::ClickFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
DockWidgetTab::~DockWidgetTab()
|
DockWidgetTab::~DockWidgetTab()
|
||||||
@@ -358,9 +362,9 @@ namespace ADS
|
|||||||
// If we undock, we need to restore the initial position of this
|
// If we undock, we need to restore the initial position of this
|
||||||
// tab because it looks strange if it remains on its dragged position
|
// tab because it looks strange if it remains on its dragged position
|
||||||
if (d->isDraggingState(DraggingTab)
|
if (d->isDraggingState(DraggingTab)
|
||||||
&& !DockManager::configFlags().testFlag(DockManager::OpaqueUndocking)) {
|
&& !DockManager::testConfigFlag(DockManager::OpaqueUndocking))
|
||||||
parentWidget()->layout()->update();
|
parentWidget()->layout()->update();
|
||||||
}
|
|
||||||
d->startFloating();
|
d->startFloating();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -370,9 +374,9 @@ namespace ADS
|
|||||||
{
|
{
|
||||||
// If we start dragging the tab, we save its initial position to
|
// If we start dragging the tab, we save its initial position to
|
||||||
// restore it later
|
// restore it later
|
||||||
if (DraggingTab != d->m_dragState) {
|
if (DraggingTab != d->m_dragState)
|
||||||
d->m_tabDragStartPosition = this->pos();
|
d->m_tabDragStartPosition = this->pos();
|
||||||
}
|
|
||||||
d->m_dragState = DraggingTab;
|
d->m_dragState = DraggingTab;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -383,9 +387,8 @@ namespace ADS
|
|||||||
void DockWidgetTab::contextMenuEvent(QContextMenuEvent *event)
|
void DockWidgetTab::contextMenuEvent(QContextMenuEvent *event)
|
||||||
{
|
{
|
||||||
event->accept();
|
event->accept();
|
||||||
if (d->isDraggingState(DraggingFloatingWidget)) {
|
if (d->isDraggingState(DraggingFloatingWidget))
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
d->saveDragStartMousePosition(event->globalPos());
|
d->saveDragStartMousePosition(event->globalPos());
|
||||||
QMenu menu(this);
|
QMenu menu(this);
|
||||||
@@ -413,16 +416,27 @@ namespace ADS
|
|||||||
bool allTabsHaveCloseButton = d->testConfigFlag(DockManager::AllTabsHaveCloseButton);
|
bool allTabsHaveCloseButton = d->testConfigFlag(DockManager::AllTabsHaveCloseButton);
|
||||||
bool tabHasCloseButton = (activeTabHasCloseButton && active) | allTabsHaveCloseButton;
|
bool tabHasCloseButton = (activeTabHasCloseButton && active) | allTabsHaveCloseButton;
|
||||||
d->m_closeButton->setVisible(dockWidgetClosable && tabHasCloseButton);
|
d->m_closeButton->setVisible(dockWidgetClosable && tabHasCloseButton);
|
||||||
|
|
||||||
|
// Focus related stuff
|
||||||
|
if (DockManager::testConfigFlag(DockManager::FocusHighlighting)
|
||||||
|
&& !d->m_dockWidget->dockManager()->isRestoringState()) {
|
||||||
|
bool updateFocusStyle = false;
|
||||||
|
if (active && !hasFocus()) {
|
||||||
|
setFocus(Qt::OtherFocusReason);
|
||||||
|
updateFocusStyle = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (d->m_isActiveTab == active) {
|
if (d->m_isActiveTab == active) {
|
||||||
|
if (updateFocusStyle)
|
||||||
|
updateStyle();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (d->m_isActiveTab == active) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
d->m_isActiveTab = active;
|
d->m_isActiveTab = active;
|
||||||
|
updateStyle();
|
||||||
style()->unpolish(this);
|
|
||||||
style()->polish(this);
|
|
||||||
d->m_titleLabel->style()->unpolish(d->m_titleLabel);
|
|
||||||
d->m_titleLabel->style()->polish(d->m_titleLabel);
|
|
||||||
update();
|
update();
|
||||||
updateGeometry();
|
updateGeometry();
|
||||||
|
|
||||||
@@ -438,9 +452,8 @@ namespace ADS
|
|||||||
void DockWidgetTab::setIcon(const QIcon &icon)
|
void DockWidgetTab::setIcon(const QIcon &icon)
|
||||||
{
|
{
|
||||||
QBoxLayout *boxLayout = qobject_cast<QBoxLayout *>(layout());
|
QBoxLayout *boxLayout = qobject_cast<QBoxLayout *>(layout());
|
||||||
if (!d->m_iconLabel && icon.isNull()) {
|
if (!d->m_iconLabel && icon.isNull())
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (!d->m_iconLabel) {
|
if (!d->m_iconLabel) {
|
||||||
d->m_iconLabel = new QLabel();
|
d->m_iconLabel = new QLabel();
|
||||||
@@ -499,9 +512,9 @@ namespace ADS
|
|||||||
|
|
||||||
void DockWidgetTab::detachDockWidget()
|
void DockWidgetTab::detachDockWidget()
|
||||||
{
|
{
|
||||||
if (!d->m_dockWidget->features().testFlag(DockWidget::DockWidgetFloatable)) {
|
if (!d->m_dockWidget->features().testFlag(DockWidget::DockWidgetFloatable))
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
d->saveDragStartMousePosition(QCursor::pos());
|
d->saveDragStartMousePosition(QCursor::pos());
|
||||||
d->startFloating(DraggingInactive);
|
d->startFloating(DraggingInactive);
|
||||||
}
|
}
|
||||||
@@ -527,4 +540,14 @@ namespace ADS
|
|||||||
d->m_closeButton->setSizePolicy(sizePolicy);
|
d->m_closeButton->setSizePolicy(sizePolicy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DockWidgetTab::setElideMode(Qt::TextElideMode mode)
|
||||||
|
{
|
||||||
|
d->m_titleLabel->setElideMode(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockWidgetTab::updateStyle()
|
||||||
|
{
|
||||||
|
internal::repolishStyle(this, internal::RepolishDirectChildren);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ADS
|
} // namespace ADS
|
||||||
|
@@ -59,6 +59,7 @@ private:
|
|||||||
DockWidgetTabPrivate *d; ///< private data (pimpl)
|
DockWidgetTabPrivate *d; ///< private data (pimpl)
|
||||||
friend class DockWidgetTabPrivate;
|
friend class DockWidgetTabPrivate;
|
||||||
friend class DockWidget;
|
friend class DockWidget;
|
||||||
|
friend class DockManager;
|
||||||
void onDockWidgetFeaturesChanged();
|
void onDockWidgetFeaturesChanged();
|
||||||
void detachDockWidget();
|
void detachDockWidget();
|
||||||
|
|
||||||
@@ -150,6 +151,16 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool event(QEvent *event) override;
|
bool event(QEvent *event) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the text elide mode
|
||||||
|
*/
|
||||||
|
void setElideMode(Qt::TextElideMode mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update stylesheet style if a property changes
|
||||||
|
*/
|
||||||
|
void updateStyle();
|
||||||
|
|
||||||
void setVisible(bool visible) override;
|
void setVisible(bool visible) override;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@@ -115,9 +115,8 @@ namespace ADS {
|
|||||||
void ElidingLabel::mouseReleaseEvent(QMouseEvent *event)
|
void ElidingLabel::mouseReleaseEvent(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
Super::mouseReleaseEvent(event);
|
Super::mouseReleaseEvent(event);
|
||||||
if (event->button() != Qt::LeftButton) {
|
if (event->button() != Qt::LeftButton)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
emit clicked();
|
emit clicked();
|
||||||
}
|
}
|
||||||
@@ -131,17 +130,17 @@ namespace ADS {
|
|||||||
|
|
||||||
void ElidingLabel::resizeEvent(QResizeEvent *event)
|
void ElidingLabel::resizeEvent(QResizeEvent *event)
|
||||||
{
|
{
|
||||||
if (!d->isModeElideNone()) {
|
if (!d->isModeElideNone())
|
||||||
d->elideText(event->size().width());
|
d->elideText(event->size().width());
|
||||||
}
|
|
||||||
Super::resizeEvent(event);
|
Super::resizeEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize ElidingLabel::minimumSizeHint() const
|
QSize ElidingLabel::minimumSizeHint() const
|
||||||
{
|
{
|
||||||
if (pixmap() != nullptr || d->isModeElideNone()) {
|
if (pixmap() != nullptr || d->isModeElideNone())
|
||||||
return QLabel::minimumSizeHint();
|
return QLabel::minimumSizeHint();
|
||||||
}
|
|
||||||
const QFontMetrics &fm = fontMetrics();
|
const QFontMetrics &fm = fontMetrics();
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
|
||||||
QSize size(fm.horizontalAdvance(d->m_text.left(2) + "…"), fm.height());
|
QSize size(fm.horizontalAdvance(d->m_text.left(2) + "…"), fm.height());
|
||||||
@@ -153,9 +152,9 @@ namespace ADS {
|
|||||||
|
|
||||||
QSize ElidingLabel::sizeHint() const
|
QSize ElidingLabel::sizeHint() const
|
||||||
{
|
{
|
||||||
if (pixmap() != nullptr || d->isModeElideNone()) {
|
if (pixmap() != nullptr || d->isModeElideNone())
|
||||||
return QLabel::sizeHint();
|
return QLabel::sizeHint();
|
||||||
}
|
|
||||||
const QFontMetrics &fm = fontMetrics();
|
const QFontMetrics &fm = fontMetrics();
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
|
||||||
QSize size(fm.horizontalAdvance(d->m_text), QLabel::sizeHint().height());
|
QSize size(fm.horizontalAdvance(d->m_text), QLabel::sizeHint().height());
|
||||||
@@ -167,10 +166,10 @@ namespace ADS {
|
|||||||
|
|
||||||
void ElidingLabel::setText(const QString &text)
|
void ElidingLabel::setText(const QString &text)
|
||||||
{
|
{
|
||||||
|
d->m_text = text;
|
||||||
if (d->isModeElideNone()) {
|
if (d->isModeElideNone()) {
|
||||||
Super::setText(text);
|
Super::setText(text);
|
||||||
} else {
|
} else {
|
||||||
d->m_text = text;
|
|
||||||
internal::setToolTip(this, text);
|
internal::setToolTip(this, text);
|
||||||
d->elideText(this->size().width());
|
d->elideText(this->size().width());
|
||||||
}
|
}
|
||||||
|
@@ -41,6 +41,12 @@
|
|||||||
#include "dockoverlay.h"
|
#include "dockoverlay.h"
|
||||||
#include "dockwidget.h"
|
#include "dockwidget.h"
|
||||||
#include "linux/floatingwidgettitlebar.h"
|
#include "linux/floatingwidgettitlebar.h"
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
#include <windows.h>
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma comment(lib, "User32.lib")
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <QAbstractButton>
|
#include <QAbstractButton>
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
@@ -56,6 +62,303 @@ static Q_LOGGING_CATEGORY(adsLog, "qtc.qmldesigner.advanceddockingsystem", QtWar
|
|||||||
|
|
||||||
namespace ADS
|
namespace ADS
|
||||||
{
|
{
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
#if 0 // set to 1 if you need this function for debugging
|
||||||
|
/**
|
||||||
|
* Just for debugging to convert windows message identifiers to strings
|
||||||
|
*/
|
||||||
|
static const char* windowsMessageString(int messageId)
|
||||||
|
{
|
||||||
|
switch (messageId)
|
||||||
|
{
|
||||||
|
case 0: return "WM_NULL";
|
||||||
|
case 1: return "WM_CREATE";
|
||||||
|
case 2: return "WM_DESTROY";
|
||||||
|
case 3: return "WM_MOVE";
|
||||||
|
case 5: return "WM_SIZE";
|
||||||
|
case 6: return "WM_ACTIVATE";
|
||||||
|
case 7: return "WM_SETFOCUS";
|
||||||
|
case 8: return "WM_KILLFOCUS";
|
||||||
|
case 10: return "WM_ENABLE";
|
||||||
|
case 11: return "WM_SETREDRAW";
|
||||||
|
case 12: return "WM_SETTEXT";
|
||||||
|
case 13: return "WM_GETTEXT";
|
||||||
|
case 14: return "WM_GETTEXTLENGTH";
|
||||||
|
case 15: return "WM_PAINT";
|
||||||
|
case 16: return "WM_CLOSE";
|
||||||
|
case 17: return "WM_QUERYENDSESSION";
|
||||||
|
case 18: return "WM_QUIT";
|
||||||
|
case 19: return "WM_QUERYOPEN";
|
||||||
|
case 20: return "WM_ERASEBKGND";
|
||||||
|
case 21: return "WM_SYSCOLORCHANGE";
|
||||||
|
case 22: return "WM_ENDSESSION";
|
||||||
|
case 24: return "WM_SHOWWINDOW";
|
||||||
|
case 25: return "WM_CTLCOLOR";
|
||||||
|
case 26: return "WM_WININICHANGE";
|
||||||
|
case 27: return "WM_DEVMODECHANGE";
|
||||||
|
case 28: return "WM_ACTIVATEAPP";
|
||||||
|
case 29: return "WM_FONTCHANGE";
|
||||||
|
case 30: return "WM_TIMECHANGE";
|
||||||
|
case 31: return "WM_CANCELMODE";
|
||||||
|
case 32: return "WM_SETCURSOR";
|
||||||
|
case 33: return "WM_MOUSEACTIVATE";
|
||||||
|
case 34: return "WM_CHILDACTIVATE";
|
||||||
|
case 35: return "WM_QUEUESYNC";
|
||||||
|
case 36: return "WM_GETMINMAXINFO";
|
||||||
|
case 38: return "WM_PAINTICON";
|
||||||
|
case 39: return "WM_ICONERASEBKGND";
|
||||||
|
case 40: return "WM_NEXTDLGCTL";
|
||||||
|
case 42: return "WM_SPOOLERSTATUS";
|
||||||
|
case 43: return "WM_DRAWITEM";
|
||||||
|
case 44: return "WM_MEASUREITEM";
|
||||||
|
case 45: return "WM_DELETEITEM";
|
||||||
|
case 46: return "WM_VKEYTOITEM";
|
||||||
|
case 47: return "WM_CHARTOITEM";
|
||||||
|
case 48: return "WM_SETFONT";
|
||||||
|
case 49: return "WM_GETFONT";
|
||||||
|
case 50: return "WM_SETHOTKEY";
|
||||||
|
case 51: return "WM_GETHOTKEY";
|
||||||
|
case 55: return "WM_QUERYDRAGICON";
|
||||||
|
case 57: return "WM_COMPAREITEM";
|
||||||
|
case 61: return "WM_GETOBJECT";
|
||||||
|
case 65: return "WM_COMPACTING";
|
||||||
|
case 68: return "WM_COMMNOTIFY";
|
||||||
|
case 70: return "WM_WINDOWPOSCHANGING";
|
||||||
|
case 71: return "WM_WINDOWPOSCHANGED";
|
||||||
|
case 72: return "WM_POWER";
|
||||||
|
case 73: return "WM_COPYGLOBALDATA";
|
||||||
|
case 74: return "WM_COPYDATA";
|
||||||
|
case 75: return "WM_CANCELJOURNAL";
|
||||||
|
case 78: return "WM_NOTIFY";
|
||||||
|
case 80: return "WM_INPUTLANGCHANGEREQUEST";
|
||||||
|
case 81: return "WM_INPUTLANGCHANGE";
|
||||||
|
case 82: return "WM_TCARD";
|
||||||
|
case 83: return "WM_HELP";
|
||||||
|
case 84: return "WM_USERCHANGED";
|
||||||
|
case 85: return "WM_NOTIFYFORMAT";
|
||||||
|
case 123: return "WM_CONTEXTMENU";
|
||||||
|
case 124: return "WM_STYLECHANGING";
|
||||||
|
case 125: return "WM_STYLECHANGED";
|
||||||
|
case 126: return "WM_DISPLAYCHANGE";
|
||||||
|
case 127: return "WM_GETICON";
|
||||||
|
case 128: return "WM_SETICON";
|
||||||
|
case 129: return "WM_NCCREATE";
|
||||||
|
case 130: return "WM_NCDESTROY";
|
||||||
|
case 131: return "WM_NCCALCSIZE";
|
||||||
|
case 132: return "WM_NCHITTEST";
|
||||||
|
case 133: return "WM_NCPAINT";
|
||||||
|
case 134: return "WM_NCACTIVATE";
|
||||||
|
case 135: return "WM_GETDLGCODE";
|
||||||
|
case 136: return "WM_SYNCPAINT";
|
||||||
|
case 160: return "WM_NCMOUSEMOVE";
|
||||||
|
case 161: return "WM_NCLBUTTONDOWN";
|
||||||
|
case 162: return "WM_NCLBUTTONUP";
|
||||||
|
case 163: return "WM_NCLBUTTONDBLCLK";
|
||||||
|
case 164: return "WM_NCRBUTTONDOWN";
|
||||||
|
case 165: return "WM_NCRBUTTONUP";
|
||||||
|
case 166: return "WM_NCRBUTTONDBLCLK";
|
||||||
|
case 167: return "WM_NCMBUTTONDOWN";
|
||||||
|
case 168: return "WM_NCMBUTTONUP";
|
||||||
|
case 169: return "WM_NCMBUTTONDBLCLK";
|
||||||
|
case 171: return "WM_NCXBUTTONDOWN";
|
||||||
|
case 172: return "WM_NCXBUTTONUP";
|
||||||
|
case 173: return "WM_NCXBUTTONDBLCLK";
|
||||||
|
case 176: return "EM_GETSEL";
|
||||||
|
case 177: return "EM_SETSEL";
|
||||||
|
case 178: return "EM_GETRECT";
|
||||||
|
case 179: return "EM_SETRECT";
|
||||||
|
case 180: return "EM_SETRECTNP";
|
||||||
|
case 181: return "EM_SCROLL";
|
||||||
|
case 182: return "EM_LINESCROLL";
|
||||||
|
case 183: return "EM_SCROLLCARET";
|
||||||
|
case 185: return "EM_GETMODIFY";
|
||||||
|
case 187: return "EM_SETMODIFY";
|
||||||
|
case 188: return "EM_GETLINECOUNT";
|
||||||
|
case 189: return "EM_LINEINDEX";
|
||||||
|
case 190: return "EM_SETHANDLE";
|
||||||
|
case 191: return "EM_GETHANDLE";
|
||||||
|
case 192: return "EM_GETTHUMB";
|
||||||
|
case 193: return "EM_LINELENGTH";
|
||||||
|
case 194: return "EM_REPLACESEL";
|
||||||
|
case 195: return "EM_SETFONT";
|
||||||
|
case 196: return "EM_GETLINE";
|
||||||
|
case 197: return "EM_LIMITTEXT / EM_SETLIMITTEXT";
|
||||||
|
case 198: return "EM_CANUNDO";
|
||||||
|
case 199: return "EM_UNDO";
|
||||||
|
case 200: return "EM_FMTLINES";
|
||||||
|
case 201: return "EM_LINEFROMCHAR";
|
||||||
|
case 202: return "EM_SETWORDBREAK";
|
||||||
|
case 203: return "EM_SETTABSTOPS";
|
||||||
|
case 204: return "EM_SETPASSWORDCHAR";
|
||||||
|
case 205: return "EM_EMPTYUNDOBUFFER";
|
||||||
|
case 206: return "EM_GETFIRSTVISIBLELINE";
|
||||||
|
case 207: return "EM_SETREADONLY";
|
||||||
|
case 209: return "EM_SETWORDBREAKPROC / EM_GETWORDBREAKPROC";
|
||||||
|
case 210: return "EM_GETPASSWORDCHAR";
|
||||||
|
case 211: return "EM_SETMARGINS";
|
||||||
|
case 212: return "EM_GETMARGINS";
|
||||||
|
case 213: return "EM_GETLIMITTEXT";
|
||||||
|
case 214: return "EM_POSFROMCHAR";
|
||||||
|
case 215: return "EM_CHARFROMPOS";
|
||||||
|
case 216: return "EM_SETIMESTATUS";
|
||||||
|
case 217: return "EM_GETIMESTATUS";
|
||||||
|
case 224: return "SBM_SETPOS";
|
||||||
|
case 225: return "SBM_GETPOS";
|
||||||
|
case 226: return "SBM_SETRANGE";
|
||||||
|
case 227: return "SBM_GETRANGE";
|
||||||
|
case 228: return "SBM_ENABLE_ARROWS";
|
||||||
|
case 230: return "SBM_SETRANGEREDRAW";
|
||||||
|
case 233: return "SBM_SETSCROLLINFO";
|
||||||
|
case 234: return "SBM_GETSCROLLINFO";
|
||||||
|
case 235: return "SBM_GETSCROLLBARINFO";
|
||||||
|
case 240: return "BM_GETCHECK";
|
||||||
|
case 241: return "BM_SETCHECK";
|
||||||
|
case 242: return "BM_GETSTATE";
|
||||||
|
case 243: return "BM_SETSTATE";
|
||||||
|
case 244: return "BM_SETSTYLE";
|
||||||
|
case 245: return "BM_CLICK";
|
||||||
|
case 246: return "BM_GETIMAGE";
|
||||||
|
case 247: return "BM_SETIMAGE";
|
||||||
|
case 248: return "BM_SETDONTCLICK";
|
||||||
|
case 255: return "WM_INPUT";
|
||||||
|
case 256: return "WM_KEYDOWN";
|
||||||
|
case 257: return "WM_KEYUP";
|
||||||
|
case 258: return "WM_CHAR";
|
||||||
|
case 259: return "WM_DEADCHAR";
|
||||||
|
case 260: return "WM_SYSKEYDOWN";
|
||||||
|
case 261: return "WM_SYSKEYUP";
|
||||||
|
case 262: return "WM_SYSCHAR";
|
||||||
|
case 263: return "WM_SYSDEADCHAR";
|
||||||
|
case 265: return "WM_UNICHAR / WM_WNT_CONVERTREQUESTEX";
|
||||||
|
case 266: return "WM_CONVERTREQUEST";
|
||||||
|
case 267: return "WM_CONVERTRESULT";
|
||||||
|
case 268: return "WM_INTERIM";
|
||||||
|
case 269: return "WM_IME_STARTCOMPOSITION";
|
||||||
|
case 270: return "WM_IME_ENDCOMPOSITION";
|
||||||
|
case 272: return "WM_INITDIALOG";
|
||||||
|
case 273: return "WM_COMMAND";
|
||||||
|
case 274: return "WM_SYSCOMMAND";
|
||||||
|
case 275: return "WM_TIMER";
|
||||||
|
case 276: return "WM_HSCROLL";
|
||||||
|
case 277: return "WM_VSCROLL";
|
||||||
|
case 278: return "WM_INITMENU";
|
||||||
|
case 279: return "WM_INITMENUPOPUP";
|
||||||
|
case 280: return "WM_SYSTIMER";
|
||||||
|
case 287: return "WM_MENUSELECT";
|
||||||
|
case 288: return "WM_MENUCHAR";
|
||||||
|
case 289: return "WM_ENTERIDLE";
|
||||||
|
case 290: return "WM_MENURBUTTONUP";
|
||||||
|
case 291: return "WM_MENUDRAG";
|
||||||
|
case 292: return "WM_MENUGETOBJECT";
|
||||||
|
case 293: return "WM_UNINITMENUPOPUP";
|
||||||
|
case 294: return "WM_MENUCOMMAND";
|
||||||
|
case 295: return "WM_CHANGEUISTATE";
|
||||||
|
case 296: return "WM_UPDATEUISTATE";
|
||||||
|
case 297: return "WM_QUERYUISTATE";
|
||||||
|
case 306: return "WM_CTLCOLORMSGBOX";
|
||||||
|
case 307: return "WM_CTLCOLOREDIT";
|
||||||
|
case 308: return "WM_CTLCOLORLISTBOX";
|
||||||
|
case 309: return "WM_CTLCOLORBTN";
|
||||||
|
case 310: return "WM_CTLCOLORDLG";
|
||||||
|
case 311: return "WM_CTLCOLORSCROLLBAR";
|
||||||
|
case 312: return "WM_CTLCOLORSTATIC";
|
||||||
|
case 512: return "WM_MOUSEMOVE";
|
||||||
|
case 513: return "WM_LBUTTONDOWN";
|
||||||
|
case 514: return "WM_LBUTTONUP";
|
||||||
|
case 515: return "WM_LBUTTONDBLCLK";
|
||||||
|
case 516: return "WM_RBUTTONDOWN";
|
||||||
|
case 517: return "WM_RBUTTONUP";
|
||||||
|
case 518: return "WM_RBUTTONDBLCLK";
|
||||||
|
case 519: return "WM_MBUTTONDOWN";
|
||||||
|
case 520: return "WM_MBUTTONUP";
|
||||||
|
case 521: return "WM_MBUTTONDBLCLK";
|
||||||
|
case 522: return "WM_MOUSEWHEEL";
|
||||||
|
case 523: return "WM_XBUTTONDOWN";
|
||||||
|
case 524: return "WM_XBUTTONUP";
|
||||||
|
case 525: return "WM_XBUTTONDBLCLK";
|
||||||
|
case 528: return "WM_PARENTNOTIFY";
|
||||||
|
case 529: return "WM_ENTERMENULOOP";
|
||||||
|
case 530: return "WM_EXITMENULOOP";
|
||||||
|
case 531: return "WM_NEXTMENU";
|
||||||
|
case 532: return "WM_SIZING";
|
||||||
|
case 533: return "WM_CAPTURECHANGED";
|
||||||
|
case 534: return "WM_MOVING";
|
||||||
|
case 536: return "WM_POWERBROADCAST";
|
||||||
|
case 537: return "WM_DEVICECHANGE";
|
||||||
|
case 544: return "WM_MDICREATE";
|
||||||
|
case 545: return "WM_MDIDESTROY";
|
||||||
|
case 546: return "WM_MDIACTIVATE";
|
||||||
|
case 547: return "WM_MDIRESTORE";
|
||||||
|
case 548: return "WM_MDINEXT";
|
||||||
|
case 549: return "WM_MDIMAXIMIZE";
|
||||||
|
case 550: return "WM_MDITILE";
|
||||||
|
case 551: return "WM_MDICASCADE";
|
||||||
|
case 552: return "WM_MDIICONARRANGE";
|
||||||
|
case 553: return "WM_MDIGETACTIVE";
|
||||||
|
case 560: return "WM_MDISETMENU";
|
||||||
|
case 561: return "WM_ENTERSIZEMOVE";
|
||||||
|
case 562: return "WM_EXITSIZEMOVE";
|
||||||
|
case 563: return "WM_DROPFILES";
|
||||||
|
case 564: return "WM_MDIREFRESHMENU";
|
||||||
|
case 640: return "WM_IME_REPORT";
|
||||||
|
case 641: return "WM_IME_SETCONTEXT";
|
||||||
|
case 642: return "WM_IME_NOTIFY";
|
||||||
|
case 643: return "WM_IME_CONTROL";
|
||||||
|
case 644: return "WM_IME_COMPOSITIONFULL";
|
||||||
|
case 645: return "WM_IME_SELECT";
|
||||||
|
case 646: return "WM_IME_CHAR";
|
||||||
|
case 648: return "WM_IME_REQUEST";
|
||||||
|
case 656: return "WM_IME_KEYDOWN";
|
||||||
|
case 657: return "WM_IME_KEYUP";
|
||||||
|
case 672: return "WM_NCMOUSEHOVER";
|
||||||
|
case 673: return "WM_MOUSEHOVER";
|
||||||
|
case 674: return "WM_NCMOUSELEAVE";
|
||||||
|
case 675: return "WM_MOUSELEAVE";
|
||||||
|
case 768: return "WM_CUT";
|
||||||
|
case 769: return "WM_COPY";
|
||||||
|
case 770: return "WM_PASTE";
|
||||||
|
case 771: return "WM_CLEAR";
|
||||||
|
case 772: return "WM_UNDO";
|
||||||
|
case 773: return "WM_RENDERFORMAT";
|
||||||
|
case 774: return "WM_RENDERALLFORMATS";
|
||||||
|
case 775: return "WM_DESTROYCLIPBOARD";
|
||||||
|
case 776: return "WM_DRAWCLIPBOARD";
|
||||||
|
case 777: return "WM_PAINTCLIPBOARD";
|
||||||
|
case 778: return "WM_VSCROLLCLIPBOARD";
|
||||||
|
case 779: return "WM_SIZECLIPBOARD";
|
||||||
|
case 780: return "WM_ASKCBFORMATNAME";
|
||||||
|
case 781: return "WM_CHANGECBCHAIN";
|
||||||
|
case 782: return "WM_HSCROLLCLIPBOARD";
|
||||||
|
case 783: return "WM_QUERYNEWPALETTE";
|
||||||
|
case 784: return "WM_PALETTEISCHANGING";
|
||||||
|
case 785: return "WM_PALETTECHANGED";
|
||||||
|
case 786: return "WM_HOTKEY";
|
||||||
|
case 791: return "WM_PRINT";
|
||||||
|
case 792: return "WM_PRINTCLIENT";
|
||||||
|
case 793: return "WM_APPCOMMAND";
|
||||||
|
case 856: return "WM_HANDHELDFIRST";
|
||||||
|
case 863: return "WM_HANDHELDLAST";
|
||||||
|
case 864: return "WM_AFXFIRST";
|
||||||
|
case 895: return "WM_AFXLAST";
|
||||||
|
case 896: return "WM_PENWINFIRST";
|
||||||
|
case 897: return "WM_RCRESULT";
|
||||||
|
case 898: return "WM_HOOKRCRESULT";
|
||||||
|
case 899: return "WM_GLOBALRCCHANGE / WM_PENMISCINFO";
|
||||||
|
case 900: return "WM_SKB";
|
||||||
|
case 901: return "WM_HEDITCTL / WM_PENCTL";
|
||||||
|
case 902: return "WM_PENMISC";
|
||||||
|
case 903: return "WM_CTLINIT";
|
||||||
|
case 904: return "WM_PENEVENT";
|
||||||
|
case 911: return "WM_PENWINLAST";
|
||||||
|
default:
|
||||||
|
return "unknown WM_ message";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "unknown WM_ message";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
AbstractFloatingWidget::~AbstractFloatingWidget() = default;
|
AbstractFloatingWidget::~AbstractFloatingWidget() = default;
|
||||||
|
|
||||||
static unsigned int zOrderCounter = 0;
|
static unsigned int zOrderCounter = 0;
|
||||||
@@ -74,8 +377,9 @@ namespace ADS
|
|||||||
DockContainerWidget *m_dropContainer = nullptr;
|
DockContainerWidget *m_dropContainer = nullptr;
|
||||||
DockAreaWidget *m_singleDockArea = nullptr;
|
DockAreaWidget *m_singleDockArea = nullptr;
|
||||||
QPoint m_dragStartPos;
|
QPoint m_dragStartPos;
|
||||||
QWidget *m_mouseEventHandler = nullptr;
|
bool m_hiding = false;
|
||||||
FloatingWidgetTitleBar *m_titleBar = nullptr;
|
QWidget *m_mouseEventHandler = nullptr; // linux only
|
||||||
|
FloatingWidgetTitleBar *m_titleBar = nullptr; // linux only
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private data constructor
|
* Private data constructor
|
||||||
@@ -90,7 +394,7 @@ namespace ADS
|
|||||||
*/
|
*/
|
||||||
static bool testConfigFlag(DockManager::eConfigFlag flag)
|
static bool testConfigFlag(DockManager::eConfigFlag flag)
|
||||||
{
|
{
|
||||||
return DockManager::configFlags().testFlag(flag);
|
return DockManager::testConfigFlag(flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -146,11 +450,11 @@ namespace ADS
|
|||||||
|
|
||||||
if (m_dockManager->dockAreaOverlay()->dropAreaUnderCursor() != InvalidDockWidgetArea
|
if (m_dockManager->dockAreaOverlay()->dropAreaUnderCursor() != InvalidDockWidgetArea
|
||||||
|| m_dockManager->containerOverlay()->dropAreaUnderCursor() != InvalidDockWidgetArea) {
|
|| m_dockManager->containerOverlay()->dropAreaUnderCursor() != InvalidDockWidgetArea) {
|
||||||
// Resize the floating widget to the size of the highlighted drop area rectangle
|
|
||||||
DockOverlay *overlay = m_dockManager->containerOverlay();
|
DockOverlay *overlay = m_dockManager->containerOverlay();
|
||||||
if (!overlay->dropOverlayRect().isValid())
|
if (!overlay->dropOverlayRect().isValid())
|
||||||
overlay = m_dockManager->dockAreaOverlay();
|
overlay = m_dockManager->dockAreaOverlay();
|
||||||
|
|
||||||
|
// Resize the floating widget to the size of the highlighted drop area rectangle
|
||||||
QRect rect = overlay->dropOverlayRect();
|
QRect rect = overlay->dropOverlayRect();
|
||||||
int frameWidth = (q->frameSize().width() - q->rect().width()) / 2;
|
int frameWidth = (q->frameSize().width() - q->rect().width()) / 2;
|
||||||
int titleBarHeight = q->frameSize().height() - q->rect().height() - frameWidth;
|
int titleBarHeight = q->frameSize().height() - q->rect().height() - frameWidth;
|
||||||
@@ -272,24 +576,26 @@ namespace ADS
|
|||||||
: FloatingDockContainer(dockArea->dockManager())
|
: FloatingDockContainer(dockArea->dockManager())
|
||||||
{
|
{
|
||||||
d->m_dockContainer->addDockArea(dockArea);
|
d->m_dockContainer->addDockArea(dockArea);
|
||||||
if (Utils::HostOsInfo::isLinuxHost())
|
#ifdef Q_OS_LINUX
|
||||||
d->m_titleBar->enableCloseButton(isClosable());
|
d->m_titleBar->enableCloseButton(isClosable());
|
||||||
|
#endif
|
||||||
auto dw = topLevelDockWidget();
|
if (auto dw = topLevelDockWidget())
|
||||||
if (dw)
|
|
||||||
dw->emitTopLevelChanged(true);
|
dw->emitTopLevelChanged(true);
|
||||||
|
|
||||||
|
d->m_dockManager->notifyWidgetOrAreaRelocation(dockArea);
|
||||||
}
|
}
|
||||||
|
|
||||||
FloatingDockContainer::FloatingDockContainer(DockWidget *dockWidget)
|
FloatingDockContainer::FloatingDockContainer(DockWidget *dockWidget)
|
||||||
: FloatingDockContainer(dockWidget->dockManager())
|
: FloatingDockContainer(dockWidget->dockManager())
|
||||||
{
|
{
|
||||||
d->m_dockContainer->addDockWidget(CenterDockWidgetArea, dockWidget);
|
d->m_dockContainer->addDockWidget(CenterDockWidgetArea, dockWidget);
|
||||||
if (Utils::HostOsInfo::isLinuxHost())
|
#ifdef Q_OS_LINUX
|
||||||
d->m_titleBar->enableCloseButton(isClosable());
|
d->m_titleBar->enableCloseButton(isClosable());
|
||||||
|
#endif
|
||||||
auto dw = topLevelDockWidget();
|
if (auto dw = topLevelDockWidget())
|
||||||
if (dw)
|
|
||||||
dw->emitTopLevelChanged(true);
|
dw->emitTopLevelChanged(true);
|
||||||
|
|
||||||
|
d->m_dockManager->notifyWidgetOrAreaRelocation(dockWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
FloatingDockContainer::~FloatingDockContainer()
|
FloatingDockContainer::~FloatingDockContainer()
|
||||||
@@ -313,33 +619,56 @@ namespace ADS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FloatingDockContainer::moveEvent(QMoveEvent *event)
|
#ifdef Q_OS_WIN
|
||||||
|
bool FloatingDockContainer::nativeEvent(const QByteArray &eventType, void *message, long *result)
|
||||||
{
|
{
|
||||||
QWidget::moveEvent(event);
|
QWidget::nativeEvent(eventType, message, result);
|
||||||
switch (d->m_draggingState) {
|
MSG *msg = static_cast<MSG *>(message);
|
||||||
case DraggingMousePressed:
|
switch (msg->message)
|
||||||
// TODO Is checking for windows only sufficient or has macOS also problems?
|
{
|
||||||
if (Utils::HostOsInfo::isWindowsHost())
|
case WM_MOVING:
|
||||||
QApplication::instance()->installEventFilter(this);
|
{
|
||||||
|
if (d->isState(DraggingFloatingWidget))
|
||||||
|
d->updateDropOverlays(QCursor::pos());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_NCLBUTTONDOWN:
|
||||||
|
if (msg->wParam == HTCAPTION && d->isState(DraggingInactive))
|
||||||
|
{
|
||||||
|
qCInfo(adsLog) << Q_FUNC_INFO << "WM_NCLBUTTONDOWN" << eventType;
|
||||||
|
d->m_dragStartPos = pos();
|
||||||
|
d->setState(DraggingMousePressed);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_NCLBUTTONDBLCLK:
|
||||||
|
d->setState(DraggingInactive);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_ENTERSIZEMOVE:
|
||||||
|
if (d->isState(DraggingMousePressed))
|
||||||
|
{
|
||||||
|
qCInfo(adsLog) << Q_FUNC_INFO << "WM_ENTERSIZEMOVE" << eventType;
|
||||||
d->setState(DraggingFloatingWidget);
|
d->setState(DraggingFloatingWidget);
|
||||||
d->updateDropOverlays(QCursor::pos());
|
d->updateDropOverlays(QCursor::pos());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DraggingFloatingWidget:
|
case WM_EXITSIZEMOVE:
|
||||||
d->updateDropOverlays(QCursor::pos());
|
if (d->isState(DraggingFloatingWidget))
|
||||||
if (Utils::HostOsInfo::isMacHost()) {
|
{
|
||||||
// In macOS when hiding the DockAreaOverlay the application would set
|
qCInfo(adsLog) << Q_FUNC_INFO << "WM_EXITSIZEMOVE" << eventType;
|
||||||
// the main window as the active window for some reason. This fixes
|
if (GetAsyncKeyState(VK_ESCAPE) & 0x8000)
|
||||||
// that by resetting the active window to the floating widget after
|
d->handleEscapeKey();
|
||||||
// updating the overlays.
|
else
|
||||||
QApplication::setActiveWindow(this);
|
d->titleMouseReleaseEvent();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void FloatingDockContainer::closeEvent(QCloseEvent *event)
|
void FloatingDockContainer::closeEvent(QCloseEvent *event)
|
||||||
{
|
{
|
||||||
@@ -368,112 +697,21 @@ namespace ADS
|
|||||||
if (d->m_dockManager->isRestoringState())
|
if (d->m_dockManager->isRestoringState())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
d->m_hiding = true;
|
||||||
for (auto dockArea : d->m_dockContainer->openedDockAreas()) {
|
for (auto dockArea : d->m_dockContainer->openedDockAreas()) {
|
||||||
for (auto dockWidget : dockArea->openedDockWidgets())
|
for (auto dockWidget : dockArea->openedDockWidgets())
|
||||||
dockWidget->toggleView(false);
|
dockWidget->toggleView(false);
|
||||||
}
|
}
|
||||||
|
d->m_hiding = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FloatingDockContainer::showEvent(QShowEvent *event) { Super::showEvent(event); }
|
void FloatingDockContainer::showEvent(QShowEvent *event)
|
||||||
|
|
||||||
bool FloatingDockContainer::event(QEvent *event)
|
|
||||||
{
|
{
|
||||||
switch (d->m_draggingState) {
|
Super::showEvent(event);
|
||||||
case DraggingInactive: {
|
#ifdef Q_OS_LINUX
|
||||||
// Normally we would check here, if the left mouse button is pressed.
|
if (DockManager::testConfigFlag(DockManager::FocusHighlighting))
|
||||||
// But from QT version 5.12.2 on the mouse events from
|
window()->activateWindow();
|
||||||
// QEvent::NonClientAreaMouseButtonPress return the wrong mouse button
|
|
||||||
// The event always returns Qt::RightButton even if the left button is clicked.
|
|
||||||
// It is really great to work around the whole NonClientMouseArea bugs
|
|
||||||
|
|
||||||
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 2))
|
|
||||||
if (event->type() == QEvent::NonClientAreaMouseButtonPress
|
|
||||||
/*&& QGuiApplication::mouseButtons().testFlag(Qt::LeftButton)*/)
|
|
||||||
#else
|
|
||||||
if (event->type() == QEvent::NonClientAreaMouseButtonPress
|
|
||||||
&& QGuiApplication::mouseButtons().testFlag(Qt::LeftButton))
|
|
||||||
#endif
|
#endif
|
||||||
{
|
|
||||||
qCInfo(adsLog) << Q_FUNC_INFO << "QEvent::NonClientAreaMouseButtonPress"
|
|
||||||
<< event->type();
|
|
||||||
d->m_dragStartPos = pos();
|
|
||||||
d->setState(DraggingMousePressed);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case DraggingMousePressed:
|
|
||||||
switch (event->type()) {
|
|
||||||
case QEvent::NonClientAreaMouseButtonDblClick:
|
|
||||||
qCInfo(adsLog) << Q_FUNC_INFO << "QEvent::NonClientAreaMouseButtonDblClick";
|
|
||||||
d->setState(DraggingInactive);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QEvent::Resize:
|
|
||||||
// If the first event after the mouse press is a resize event, then
|
|
||||||
// the user resizes the window instead of dragging it around.
|
|
||||||
// But there is one exception. If the window is maximized,
|
|
||||||
// then dragging the window via title bar will cause the widget to
|
|
||||||
// leave the maximized state. This in turn will trigger a resize event.
|
|
||||||
// To know, if the resize event was triggered by user via moving a
|
|
||||||
// corner of the window frame or if it was caused by a windows state
|
|
||||||
// change, we check, if we are not in maximized state.
|
|
||||||
if (!isMaximized()) {
|
|
||||||
d->setState(DraggingInactive);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DraggingFloatingWidget:
|
|
||||||
if (event->type() == QEvent::NonClientAreaMouseButtonRelease) {
|
|
||||||
qCInfo(adsLog) << Q_FUNC_INFO << "QEvent::NonClientAreaMouseButtonRelease";
|
|
||||||
d->titleMouseReleaseEvent();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if (ADS_DEBUG_LEVEL > 0)
|
|
||||||
qDebug() << "FloatingDockContainer::event " << event->type();
|
|
||||||
#endif
|
|
||||||
return QWidget::event(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FloatingDockContainer::eventFilter(QObject *watched, QEvent *event)
|
|
||||||
{
|
|
||||||
Q_UNUSED(watched);
|
|
||||||
// I have not found a way to detect non client area key press events to
|
|
||||||
// handle escape key presses. On Windows, if the escape key is pressed while
|
|
||||||
// dragging around a widget, the widget position is reset to its start position
|
|
||||||
// which in turn generates a QEvent::NonClientAreaMouseButtonRelease event
|
|
||||||
// if the mouse is outside of the widget after the move to its initial position
|
|
||||||
// or a QEvent::MouseButtonRelease event, if the mouse is inside of the widget
|
|
||||||
// after the position has been reset.
|
|
||||||
// So we can install an event filter on the application to get these events
|
|
||||||
// here to properly cancel dragging and hide the overlays.
|
|
||||||
// If we are in DraggingFloatingWidget state, it means the widget
|
|
||||||
// has been dragged already but if the position is the same like
|
|
||||||
// the start position, then this is an indication that the escape
|
|
||||||
// key has been pressed.
|
|
||||||
if (event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::NonClientAreaMouseButtonRelease)
|
|
||||||
{
|
|
||||||
qCInfo(adsLog) << Q_FUNC_INFO << "QEvent::MouseButtonRelease or QEvent::NonClientAreaMouseButtonRelease"
|
|
||||||
<< "d->m_draggingState " << d->m_draggingState;
|
|
||||||
QApplication::instance()->removeEventFilter(this);
|
|
||||||
if (d->m_dragStartPos == pos())
|
|
||||||
{
|
|
||||||
d->handleEscapeKey();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FloatingDockContainer::startFloating(const QPoint &dragStartMousePos,
|
void FloatingDockContainer::startFloating(const QPoint &dragStartMousePos,
|
||||||
@@ -481,29 +719,52 @@ namespace ADS
|
|||||||
eDragState dragState,
|
eDragState dragState,
|
||||||
QWidget *mouseEventHandler)
|
QWidget *mouseEventHandler)
|
||||||
{
|
{
|
||||||
|
#ifndef Q_OS_LINUX
|
||||||
|
Q_UNUSED(mouseEventHandler)
|
||||||
|
#endif
|
||||||
resize(size);
|
resize(size);
|
||||||
d->setState(dragState);
|
d->setState(dragState);
|
||||||
d->m_dragStartMousePosition = dragStartMousePos;
|
d->m_dragStartMousePosition = dragStartMousePos;
|
||||||
|
|
||||||
if (Utils::HostOsInfo::isLinuxHost()) {
|
#ifdef Q_OS_LINUX
|
||||||
if (DraggingFloatingWidget == dragState) {
|
if (DraggingFloatingWidget == dragState) {
|
||||||
setAttribute(Qt::WA_X11NetWmWindowTypeDock, true);
|
setAttribute(Qt::WA_X11NetWmWindowTypeDock, true);
|
||||||
d->m_mouseEventHandler = mouseEventHandler;
|
d->m_mouseEventHandler = mouseEventHandler;
|
||||||
if (d->m_mouseEventHandler) {
|
if (d->m_mouseEventHandler)
|
||||||
d->m_mouseEventHandler->grabMouse();
|
d->m_mouseEventHandler->grabMouse();
|
||||||
}
|
}
|
||||||
}
|
#endif
|
||||||
}
|
|
||||||
moveFloating();
|
moveFloating();
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FloatingDockContainer::moveFloating()
|
void FloatingDockContainer::moveFloating()
|
||||||
{
|
{
|
||||||
int borderSize = (frameSize().width() - size().width()) / 2;
|
const int borderSize = (frameSize().width() - size().width()) / 2;
|
||||||
const QPoint moveToPos = QCursor::pos() - d->m_dragStartMousePosition
|
const QPoint moveToPos = QCursor::pos() - d->m_dragStartMousePosition
|
||||||
- QPoint(borderSize, 0);
|
- QPoint(borderSize, 0);
|
||||||
move(moveToPos);
|
move(moveToPos);
|
||||||
|
|
||||||
|
switch (d->m_draggingState)
|
||||||
|
{
|
||||||
|
case DraggingMousePressed:
|
||||||
|
d->setState(DraggingFloatingWidget);
|
||||||
|
d->updateDropOverlays(QCursor::pos());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DraggingFloatingWidget:
|
||||||
|
d->updateDropOverlays(QCursor::pos());
|
||||||
|
// On macOS when hiding the DockAreaOverlay the application would set
|
||||||
|
// the main window as the active window for some reason. This fixes
|
||||||
|
// that by resetting the active window to the floating widget after
|
||||||
|
// updating the overlays.
|
||||||
|
if (Utils::HostOsInfo::isMacHost())
|
||||||
|
QApplication::setActiveWindow(this);
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FloatingDockContainer::isClosable() const
|
bool FloatingDockContainer::isClosable() const
|
||||||
@@ -538,9 +799,13 @@ namespace ADS
|
|||||||
|
|
||||||
void FloatingDockContainer::updateWindowTitle()
|
void FloatingDockContainer::updateWindowTitle()
|
||||||
{
|
{
|
||||||
auto topLevelDockArea = d->m_dockContainer->topLevelDockArea();
|
// If this floating container will be hidden, then updating the window
|
||||||
if (topLevelDockArea) {
|
// title is not required anymore
|
||||||
DockWidget *currentWidget = topLevelDockArea->currentDockWidget();
|
if (d->m_hiding)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (auto topLevelDockArea = d->m_dockContainer->topLevelDockArea()) {
|
||||||
|
if (DockWidget *currentWidget = topLevelDockArea->currentDockWidget())
|
||||||
d->reflectCurrentWidget(currentWidget);
|
d->reflectCurrentWidget(currentWidget);
|
||||||
} else {
|
} else {
|
||||||
d->setWindowTitle(QApplication::applicationDisplayName());
|
d->setWindowTitle(QApplication::applicationDisplayName());
|
||||||
@@ -557,9 +822,8 @@ namespace ADS
|
|||||||
|
|
||||||
bool FloatingDockContainer::restoreState(DockingStateReader &stream, bool testing)
|
bool FloatingDockContainer::restoreState(DockingStateReader &stream, bool testing)
|
||||||
{
|
{
|
||||||
if (!d->m_dockContainer->restoreState(stream, testing)) {
|
if (!d->m_dockContainer->restoreState(stream, testing))
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
onDockAreasAddedOrRemoved();
|
onDockAreasAddedOrRemoved();
|
||||||
return true;
|
return true;
|
||||||
@@ -584,7 +848,7 @@ namespace ADS
|
|||||||
{
|
{
|
||||||
qCInfo(adsLog) << Q_FUNC_INFO;
|
qCInfo(adsLog) << Q_FUNC_INFO;
|
||||||
|
|
||||||
if (Utils::HostOsInfo::isLinuxHost()) {
|
#ifdef Q_OS_LINUX
|
||||||
setAttribute(Qt::WA_X11NetWmWindowTypeDock, false);
|
setAttribute(Qt::WA_X11NetWmWindowTypeDock, false);
|
||||||
setWindowOpacity(1);
|
setWindowOpacity(1);
|
||||||
activateWindow();
|
activateWindow();
|
||||||
@@ -592,8 +856,105 @@ namespace ADS
|
|||||||
d->m_mouseEventHandler->releaseMouse();
|
d->m_mouseEventHandler->releaseMouse();
|
||||||
d->m_mouseEventHandler = nullptr;
|
d->m_mouseEventHandler = nullptr;
|
||||||
}
|
}
|
||||||
}
|
#endif
|
||||||
d->titleMouseReleaseEvent();
|
d->titleMouseReleaseEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_MACOS
|
||||||
|
bool FloatingDockContainer::event(QEvent *event)
|
||||||
|
{
|
||||||
|
switch (d->m_draggingState)
|
||||||
|
{
|
||||||
|
case DraggingInactive:
|
||||||
|
{
|
||||||
|
// Normally we would check here, if the left mouse button is pressed.
|
||||||
|
// But from QT version 5.12.2 on the mouse events from
|
||||||
|
// QEvent::NonClientAreaMouseButtonPress return the wrong mouse button
|
||||||
|
// The event always returns Qt::RightButton even if the left button
|
||||||
|
// is clicked.
|
||||||
|
// It is really great to work around the whole NonClientMouseArea
|
||||||
|
// bugs
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 2))
|
||||||
|
if (event->type() == QEvent::NonClientAreaMouseButtonPress
|
||||||
|
/*&& QGuiApplication::mouseButtons().testFlag(Qt::LeftButton)*/)
|
||||||
|
#else
|
||||||
|
if (event->type() == QEvent::NonClientAreaMouseButtonPress
|
||||||
|
&& QGuiApplication::mouseButtons().testFlag(Qt::LeftButton))
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
qCInfo(adsLog) << Q_FUNC_INFO << "QEvent::NonClientAreaMouseButtonPress"
|
||||||
|
<< event->type();
|
||||||
|
d->m_dragStartPos = pos();
|
||||||
|
d->setState(DraggingMousePressed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DraggingMousePressed:
|
||||||
|
switch (event->type())
|
||||||
|
{
|
||||||
|
case QEvent::NonClientAreaMouseButtonDblClick:
|
||||||
|
qCInfo(adsLog) << Q_FUNC_INFO << "QEvent::NonClientAreaMouseButtonDblClick";
|
||||||
|
d->setState(DraggingInactive);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QEvent::Resize:
|
||||||
|
// If the first event after the mouse press is a resize event, then
|
||||||
|
// the user resizes the window instead of dragging it around.
|
||||||
|
// But there is one exception. If the window is maximized,
|
||||||
|
// then dragging the window via title bar will cause the widget to
|
||||||
|
// leave the maximized state. This in turn will trigger a resize event.
|
||||||
|
// To know, if the resize event was triggered by user via moving a
|
||||||
|
// corner of the window frame or if it was caused by a windows state
|
||||||
|
// change, we check, if we are not in maximized state.
|
||||||
|
if (!isMaximized())
|
||||||
|
d->setState(DraggingInactive);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DraggingFloatingWidget:
|
||||||
|
if (event->type() == QEvent::NonClientAreaMouseButtonRelease)
|
||||||
|
{
|
||||||
|
qCInfo(adsLog) << Q_FUNC_INFO << "QEvent::NonClientAreaMouseButtonRelease";
|
||||||
|
d->titleMouseReleaseEvent();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (ADS_DEBUG_LEVEL > 0)
|
||||||
|
qDebug() << Q_FUNC_INFO << event->type();
|
||||||
|
#endif
|
||||||
|
return QWidget::event(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FloatingDockContainer::moveEvent(QMoveEvent *event)
|
||||||
|
{
|
||||||
|
QWidget::moveEvent(event);
|
||||||
|
switch (d->m_draggingState)
|
||||||
|
{
|
||||||
|
case DraggingMousePressed:
|
||||||
|
d->setState(DraggingFloatingWidget);
|
||||||
|
d->updateDropOverlays(QCursor::pos());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DraggingFloatingWidget:
|
||||||
|
d->updateDropOverlays(QCursor::pos());
|
||||||
|
// On macOS when hiding the DockAreaOverlay the application would set
|
||||||
|
// the main window as the active window for some reason. This fixes
|
||||||
|
// that by resetting the active window to the floating widget after
|
||||||
|
// updating the overlays.
|
||||||
|
QApplication::setActiveWindow(this);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
} // namespace ADS
|
} // namespace ADS
|
||||||
|
@@ -183,12 +183,21 @@ protected:
|
|||||||
|
|
||||||
protected: // reimplements QWidget
|
protected: // reimplements QWidget
|
||||||
void changeEvent(QEvent *event) override;
|
void changeEvent(QEvent *event) override;
|
||||||
void moveEvent(QMoveEvent *event) override;
|
|
||||||
bool event(QEvent *event) override;
|
|
||||||
void closeEvent(QCloseEvent *event) override;
|
void closeEvent(QCloseEvent *event) override;
|
||||||
void hideEvent(QHideEvent *event) override;
|
void hideEvent(QHideEvent *event) override;
|
||||||
void showEvent(QShowEvent *event) override;
|
void showEvent(QShowEvent *event) override;
|
||||||
bool eventFilter(QObject *watched, QEvent *event) override;
|
|
||||||
|
#ifdef Q_OS_MACOS
|
||||||
|
virtual bool event(QEvent *event) override;
|
||||||
|
virtual void moveEvent(QMoveEvent *event) override;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
/**
|
||||||
|
* Native event filter for handling WM_MOVING messages on Windows
|
||||||
|
*/
|
||||||
|
bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using Super = QWidget;
|
using Super = QWidget;
|
||||||
|
@@ -62,7 +62,6 @@ namespace ADS
|
|||||||
FloatingDragPreview *q;
|
FloatingDragPreview *q;
|
||||||
QWidget *m_content = nullptr;
|
QWidget *m_content = nullptr;
|
||||||
DockAreaWidget *m_contentSourceArea = nullptr;
|
DockAreaWidget *m_contentSourceArea = nullptr;
|
||||||
DockContainerWidget *m_contenSourceContainer = nullptr;
|
|
||||||
QPoint m_dragStartMousePosition;
|
QPoint m_dragStartMousePosition;
|
||||||
DockManager *m_dockManager = nullptr;
|
DockManager *m_dockManager = nullptr;
|
||||||
DockContainerWidget *m_dropContainer = nullptr;
|
DockContainerWidget *m_dropContainer = nullptr;
|
||||||
@@ -93,6 +92,12 @@ namespace ADS
|
|||||||
m_dockManager->dockAreaOverlay()->hideOverlay();
|
m_dockManager->dockAreaOverlay()->hideOverlay();
|
||||||
q->close();
|
q->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the real floating widget in case the mouse is released outside
|
||||||
|
* outside of any drop area
|
||||||
|
*/
|
||||||
|
void createFloatingWidget();
|
||||||
}; // class FloatingDragPreviewPrivate
|
}; // class FloatingDragPreviewPrivate
|
||||||
|
|
||||||
void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &globalPosition)
|
void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &globalPosition)
|
||||||
@@ -106,7 +111,7 @@ namespace ADS
|
|||||||
if (!containerWidget->isVisible())
|
if (!containerWidget->isVisible())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
QPoint mappedPosition = containerWidget->mapFromGlobal(globalPosition);
|
const QPoint mappedPosition = containerWidget->mapFromGlobal(globalPosition);
|
||||||
if (containerWidget->rect().contains(mappedPosition)) {
|
if (containerWidget->rect().contains(mappedPosition)) {
|
||||||
if (!topContainer || containerWidget->isInFrontOf(topContainer))
|
if (!topContainer || containerWidget->isInFrontOf(topContainer))
|
||||||
topContainer = containerWidget;
|
topContainer = containerWidget;
|
||||||
@@ -122,18 +127,16 @@ namespace ADS
|
|||||||
if (!topContainer) {
|
if (!topContainer) {
|
||||||
containerOverlay->hideOverlay();
|
containerOverlay->hideOverlay();
|
||||||
dockAreaOverlay->hideOverlay();
|
dockAreaOverlay->hideOverlay();
|
||||||
if (DockManager::configFlags().testFlag(DockManager::DragPreviewIsDynamic))
|
if (DockManager::testConfigFlag(DockManager::DragPreviewIsDynamic))
|
||||||
setHidden(false);
|
setHidden(false);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int visibleDockAreas = topContainer->visibleDockAreaCount();
|
const int visibleDockAreas = topContainer->visibleDockAreaCount();
|
||||||
containerOverlay->setAllowedAreas(visibleDockAreas > 1 ? OuterDockAreas : AllDockAreas);
|
containerOverlay->setAllowedAreas(visibleDockAreas > 1 ? OuterDockAreas : AllDockAreas);
|
||||||
DockWidgetArea containerArea = containerOverlay->showOverlay(topContainer);
|
|
||||||
containerOverlay->enableDropPreview(containerArea != InvalidDockWidgetArea);
|
|
||||||
auto dockArea = topContainer->dockAreaAt(globalPosition);
|
auto dockArea = topContainer->dockAreaAt(globalPosition);
|
||||||
if (dockArea && dockArea->isVisible() && visibleDockAreas > 0
|
if (dockArea && dockArea->isVisible() && visibleDockAreas >= 0
|
||||||
&& dockArea != m_contentSourceArea) {
|
&& dockArea != m_contentSourceArea) {
|
||||||
dockAreaOverlay->enableDropPreview(true);
|
dockAreaOverlay->enableDropPreview(true);
|
||||||
dockAreaOverlay->setAllowedAreas((visibleDockAreas == 1) ? NoDockWidgetArea
|
dockAreaOverlay->setAllowedAreas((visibleDockAreas == 1) ? NoDockWidgetArea
|
||||||
@@ -143,25 +146,28 @@ namespace ADS
|
|||||||
// A CenterDockWidgetArea for the dockAreaOverlay() indicates that the mouse is in the
|
// A CenterDockWidgetArea for the dockAreaOverlay() indicates that the mouse is in the
|
||||||
// title bar. If the ContainerArea is valid then we ignore the dock area of the
|
// title bar. If the ContainerArea is valid then we ignore the dock area of the
|
||||||
// dockAreaOverlay() and disable the drop preview
|
// dockAreaOverlay() and disable the drop preview
|
||||||
if ((area == CenterDockWidgetArea) && (containerArea != InvalidDockWidgetArea)) {
|
if ((area == CenterDockWidgetArea) && (containerDropArea != InvalidDockWidgetArea)) {
|
||||||
dockAreaOverlay->enableDropPreview(false);
|
dockAreaOverlay->enableDropPreview(false);
|
||||||
containerOverlay->enableDropPreview(true);
|
containerOverlay->enableDropPreview(true);
|
||||||
} else {
|
} else {
|
||||||
containerOverlay->enableDropPreview(InvalidDockWidgetArea == area);
|
containerOverlay->enableDropPreview(InvalidDockWidgetArea == area);
|
||||||
}
|
}
|
||||||
|
containerOverlay->showOverlay(topContainer);
|
||||||
} else {
|
} else {
|
||||||
dockAreaOverlay->hideOverlay();
|
dockAreaOverlay->hideOverlay();
|
||||||
// If there is only one single visible dock area in a container, then
|
// 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
|
// it does not make sense to show a dock overlay because the dock area
|
||||||
// would be removed and inserted at the same position
|
// would be removed and inserted at the same position
|
||||||
if (visibleDockAreas <= 1)
|
if (visibleDockAreas <= 1)
|
||||||
containerOverlay->hide();
|
containerOverlay->hideOverlay();
|
||||||
|
else
|
||||||
|
containerOverlay->showOverlay(topContainer);
|
||||||
|
|
||||||
if (dockArea == m_contentSourceArea && InvalidDockWidgetArea == containerDropArea)
|
if (dockArea == m_contentSourceArea && InvalidDockWidgetArea == containerDropArea)
|
||||||
m_dropContainer = nullptr;
|
m_dropContainer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DockManager::configFlags().testFlag(DockManager::DragPreviewIsDynamic)) {
|
if (DockManager::testConfigFlag(DockManager::DragPreviewIsDynamic)) {
|
||||||
setHidden(dockDropArea != InvalidDockWidgetArea
|
setHidden(dockDropArea != InvalidDockWidgetArea
|
||||||
|| containerDropArea != InvalidDockWidgetArea);
|
|| containerDropArea != InvalidDockWidgetArea);
|
||||||
}
|
}
|
||||||
@@ -171,13 +177,38 @@ namespace ADS
|
|||||||
: q(parent)
|
: q(parent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
void FloatingDragPreviewPrivate::createFloatingWidget()
|
||||||
|
{
|
||||||
|
DockWidget *dockWidget = qobject_cast<DockWidget *>(m_content);
|
||||||
|
DockAreaWidget *dockArea = qobject_cast<DockAreaWidget *>(m_content);
|
||||||
|
|
||||||
|
FloatingDockContainer *floatingWidget = nullptr;
|
||||||
|
|
||||||
|
if (dockWidget && dockWidget->features().testFlag(DockWidget::DockWidgetFloatable))
|
||||||
|
floatingWidget = new FloatingDockContainer(dockWidget);
|
||||||
|
else if (dockArea && dockArea->features().testFlag(DockWidget::DockWidgetFloatable))
|
||||||
|
floatingWidget = new FloatingDockContainer(dockArea);
|
||||||
|
|
||||||
|
if (floatingWidget) {
|
||||||
|
floatingWidget->setGeometry(q->geometry());
|
||||||
|
floatingWidget->show();
|
||||||
|
if (!DockManager::testConfigFlag(DockManager::DragPreviewHasWindowFrame)) {
|
||||||
|
QApplication::processEvents();
|
||||||
|
int frameHeight = floatingWidget->frameGeometry().height() - floatingWidget->geometry().height();
|
||||||
|
QRect fixedGeometry = q->geometry();
|
||||||
|
fixedGeometry.adjust(0, frameHeight, 0, 0);
|
||||||
|
floatingWidget->setGeometry(fixedGeometry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FloatingDragPreview::FloatingDragPreview(QWidget *content, QWidget *parent)
|
FloatingDragPreview::FloatingDragPreview(QWidget *content, QWidget *parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
, d(new FloatingDragPreviewPrivate(this))
|
, d(new FloatingDragPreviewPrivate(this))
|
||||||
{
|
{
|
||||||
d->m_content = content;
|
d->m_content = content;
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
if (DockManager::configFlags().testFlag(DockManager::DragPreviewHasWindowFrame)) {
|
if (DockManager::testConfigFlag(DockManager::DragPreviewHasWindowFrame)) {
|
||||||
setWindowFlags(Qt::Window | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint);
|
setWindowFlags(Qt::Window | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint);
|
||||||
} else {
|
} else {
|
||||||
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
|
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
|
||||||
@@ -195,7 +226,7 @@ namespace ADS
|
|||||||
|
|
||||||
// Create a static image of the widget that should get undocked
|
// 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
|
// This is like some kind preview image like it is uses in drag and drop operations
|
||||||
if (DockManager::configFlags().testFlag(DockManager::DragPreviewShowsContentPixmap)) {
|
if (DockManager::testConfigFlag(DockManager::DragPreviewShowsContentPixmap)) {
|
||||||
d->m_contentPreviewPixmap = QPixmap(content->size());
|
d->m_contentPreviewPixmap = QPixmap(content->size());
|
||||||
content->render(&d->m_contentPreviewPixmap);
|
content->render(&d->m_contentPreviewPixmap);
|
||||||
}
|
}
|
||||||
@@ -213,10 +244,9 @@ namespace ADS
|
|||||||
content->dockManager()) // TODO static_cast?
|
content->dockManager()) // TODO static_cast?
|
||||||
{
|
{
|
||||||
d->m_dockManager = content->dockManager();
|
d->m_dockManager = content->dockManager();
|
||||||
if (content->dockAreaWidget()->openDockWidgetsCount() == 1) {
|
if (content->dockAreaWidget()->openDockWidgetsCount() == 1)
|
||||||
d->m_contentSourceArea = content->dockAreaWidget();
|
d->m_contentSourceArea = content->dockAreaWidget();
|
||||||
d->m_contenSourceContainer = content->dockContainer();
|
|
||||||
}
|
|
||||||
setWindowTitle(content->windowTitle());
|
setWindowTitle(content->windowTitle());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,7 +256,6 @@ namespace ADS
|
|||||||
{
|
{
|
||||||
d->m_dockManager = content->dockManager();
|
d->m_dockManager = content->dockManager();
|
||||||
d->m_contentSourceArea = content;
|
d->m_contentSourceArea = content;
|
||||||
d->m_contenSourceContainer = content->dockContainer();
|
|
||||||
setWindowTitle(content->currentDockWidget()->windowTitle());
|
setWindowTitle(content->currentDockWidget()->windowTitle());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,10 +263,11 @@ namespace ADS
|
|||||||
|
|
||||||
void FloatingDragPreview::moveFloating()
|
void FloatingDragPreview::moveFloating()
|
||||||
{
|
{
|
||||||
int borderSize = (frameSize().width() - size().width()) / 2;
|
const int borderSize = (frameSize().width() - size().width()) / 2;
|
||||||
const QPoint moveToPos = QCursor::pos() - d->m_dragStartMousePosition
|
const QPoint moveToPos = QCursor::pos() - d->m_dragStartMousePosition
|
||||||
- QPoint(borderSize, 0);
|
- QPoint(borderSize, 0);
|
||||||
move(moveToPos);
|
move(moveToPos);
|
||||||
|
d->updateDropOverlays(QCursor::pos());
|
||||||
}
|
}
|
||||||
|
|
||||||
void FloatingDragPreview::startFloating(const QPoint &dragStartMousePos,
|
void FloatingDragPreview::startFloating(const QPoint &dragStartMousePos,
|
||||||
@@ -253,46 +283,24 @@ namespace ADS
|
|||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FloatingDragPreview::moveEvent(QMoveEvent *event)
|
|
||||||
{
|
|
||||||
QWidget::moveEvent(event);
|
|
||||||
d->updateDropOverlays(QCursor::pos());
|
|
||||||
}
|
|
||||||
|
|
||||||
void FloatingDragPreview::finishDragging()
|
void FloatingDragPreview::finishDragging()
|
||||||
{
|
{
|
||||||
qCInfo(adsLog) << Q_FUNC_INFO;
|
qCInfo(adsLog) << Q_FUNC_INFO;
|
||||||
auto dockDropArea = d->m_dockManager->dockAreaOverlay()->visibleDropAreaUnderCursor();
|
auto dockDropArea = d->m_dockManager->dockAreaOverlay()->visibleDropAreaUnderCursor();
|
||||||
auto containerDropArea = d->m_dockManager->containerOverlay()->visibleDropAreaUnderCursor();
|
auto containerDropArea = d->m_dockManager->containerOverlay()->visibleDropAreaUnderCursor();
|
||||||
if (d->m_dropContainer && (dockDropArea != InvalidDockWidgetArea)) {
|
if (!d->m_dropContainer) {
|
||||||
d->m_dropContainer->dropWidget(d->m_content,
|
d->createFloatingWidget();
|
||||||
dockDropArea,
|
} else if (dockDropArea != InvalidDockWidgetArea) {
|
||||||
d->m_dropContainer->dockAreaAt(QCursor::pos()));
|
d->m_dropContainer->dropWidget(d->m_content, dockDropArea, d->m_dropContainer->dockAreaAt(QCursor::pos()));
|
||||||
} else if (d->m_dropContainer && (containerDropArea != InvalidDockWidgetArea)) {
|
} 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, containerDropArea, d->m_dropContainer->dockAreaAt(QCursor::pos()));
|
||||||
|
else
|
||||||
d->m_dropContainer->dropWidget(d->m_content, containerDropArea, nullptr);
|
d->m_dropContainer->dropWidget(d->m_content, containerDropArea, nullptr);
|
||||||
} else {
|
} else {
|
||||||
DockWidget *dockWidget = qobject_cast<DockWidget *>(d->m_content);
|
d->createFloatingWidget();
|
||||||
FloatingDockContainer *floatingWidget = nullptr;
|
|
||||||
|
|
||||||
if (dockWidget && dockWidget->features().testFlag(DockWidget::DockWidgetFloatable)) {
|
|
||||||
floatingWidget = new FloatingDockContainer(dockWidget);
|
|
||||||
} else {
|
|
||||||
DockAreaWidget *dockArea = qobject_cast<DockAreaWidget *>(d->m_content);
|
|
||||||
if (dockArea->features().testFlag(DockWidget::DockWidgetFloatable))
|
|
||||||
floatingWidget = new FloatingDockContainer(dockArea);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (floatingWidget) {
|
|
||||||
floatingWidget->setGeometry(this->geometry());
|
|
||||||
floatingWidget->show();
|
|
||||||
if (!DockManager::configFlags().testFlag(DockManager::DragPreviewHasWindowFrame)) {
|
|
||||||
QApplication::processEvents();
|
|
||||||
int frameHeight = floatingWidget->frameGeometry().height() - floatingWidget->geometry().height();
|
|
||||||
QRect fixedGeometry = this->geometry();
|
|
||||||
fixedGeometry.adjust(0, frameHeight, 0, 0);
|
|
||||||
floatingWidget->setGeometry(fixedGeometry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this->close();
|
this->close();
|
||||||
@@ -307,11 +315,11 @@ namespace ADS
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
QPainter painter(this);
|
QPainter painter(this);
|
||||||
if (DockManager::configFlags().testFlag(DockManager::DragPreviewShowsContentPixmap))
|
if (DockManager::testConfigFlag(DockManager::DragPreviewShowsContentPixmap))
|
||||||
painter.drawPixmap(QPoint(0, 0), d->m_contentPreviewPixmap);
|
painter.drawPixmap(QPoint(0, 0), d->m_contentPreviewPixmap);
|
||||||
|
|
||||||
// If we do not have a window frame then we paint a QRubberBand like frameless window
|
// If we do not have a window frame then we paint a QRubberBand like frameless window
|
||||||
if (!DockManager::configFlags().testFlag(DockManager::DragPreviewHasWindowFrame)) {
|
if (!DockManager::testConfigFlag(DockManager::DragPreviewHasWindowFrame)) {
|
||||||
QColor color = palette().color(QPalette::Active, QPalette::Highlight);
|
QColor color = palette().color(QPalette::Active, QPalette::Highlight);
|
||||||
QPen pen = painter.pen();
|
QPen pen = painter.pen();
|
||||||
pen.setColor(color.darker(120));
|
pen.setColor(color.darker(120));
|
||||||
|
@@ -64,11 +64,6 @@ private:
|
|||||||
void onApplicationStateChanged(Qt::ApplicationState state);
|
void onApplicationStateChanged(Qt::ApplicationState state);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
|
||||||
* Updates the drop overlays
|
|
||||||
*/
|
|
||||||
void moveEvent(QMoveEvent *event) override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cares about painting the
|
* Cares about painting the
|
||||||
*/
|
*/
|
||||||
|
@@ -1,122 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
version="1.1"
|
|
||||||
id="Capa_1"
|
|
||||||
x="0px"
|
|
||||||
y="0px"
|
|
||||||
width="512"
|
|
||||||
height="512"
|
|
||||||
viewBox="0 0 512 512"
|
|
||||||
xml:space="preserve"
|
|
||||||
sodipodi:docname="close-button-disabled.svg"
|
|
||||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"><metadata
|
|
||||||
id="metadata897"><rdf:RDF><cc:Work
|
|
||||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
|
||||||
id="defs895" /><sodipodi:namedview
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1"
|
|
||||||
objecttolerance="10"
|
|
||||||
gridtolerance="10"
|
|
||||||
guidetolerance="10"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1017"
|
|
||||||
id="namedview893"
|
|
||||||
showgrid="false"
|
|
||||||
fit-margin-top="0"
|
|
||||||
fit-margin-left="0"
|
|
||||||
fit-margin-right="0"
|
|
||||||
fit-margin-bottom="0"
|
|
||||||
inkscape:zoom="0.85862966"
|
|
||||||
inkscape:cx="345.29142"
|
|
||||||
inkscape:cy="32.731258"
|
|
||||||
inkscape:window-x="-8"
|
|
||||||
inkscape:window-y="-8"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="Capa_1" />
|
|
||||||
<g
|
|
||||||
id="g860"
|
|
||||||
transform="matrix(0.71708683,0,0,0.71708683,128,128)"
|
|
||||||
style="stroke:none;stroke-opacity:1;fill:#000000;fill-opacity:0.50196081">
|
|
||||||
<g
|
|
||||||
id="close"
|
|
||||||
style="stroke:none;stroke-opacity:1;fill:#000000;fill-opacity:0.50196081">
|
|
||||||
<polygon
|
|
||||||
points="357,321.3 214.2,178.5 357,35.7 321.3,0 178.5,142.8 35.7,0 0,35.7 142.8,178.5 0,321.3 35.7,357 178.5,214.2 321.3,357 "
|
|
||||||
id="polygon857"
|
|
||||||
style="stroke:none;stroke-opacity:1;fill:#000000;fill-opacity:0.50196081" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g862"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g864"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g866"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g868"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g870"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g872"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g874"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g876"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g878"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g880"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g882"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g884"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g886"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g888"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g890"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 2.9 KiB |
@@ -1,119 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
version="1.1"
|
|
||||||
id="Capa_1"
|
|
||||||
x="0px"
|
|
||||||
y="0px"
|
|
||||||
width="512"
|
|
||||||
height="512"
|
|
||||||
viewBox="0 0 512 512"
|
|
||||||
xml:space="preserve"
|
|
||||||
sodipodi:docname="close-button.svg"
|
|
||||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"><metadata
|
|
||||||
id="metadata897"><rdf:RDF><cc:Work
|
|
||||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
|
||||||
id="defs895" /><sodipodi:namedview
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1"
|
|
||||||
objecttolerance="10"
|
|
||||||
gridtolerance="10"
|
|
||||||
guidetolerance="10"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1017"
|
|
||||||
id="namedview893"
|
|
||||||
showgrid="false"
|
|
||||||
fit-margin-top="0"
|
|
||||||
fit-margin-left="0"
|
|
||||||
fit-margin-right="0"
|
|
||||||
fit-margin-bottom="0"
|
|
||||||
inkscape:zoom="0.85862966"
|
|
||||||
inkscape:cx="345.29142"
|
|
||||||
inkscape:cy="32.731258"
|
|
||||||
inkscape:window-x="-8"
|
|
||||||
inkscape:window-y="-8"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="Capa_1" />
|
|
||||||
<g
|
|
||||||
id="g860"
|
|
||||||
transform="matrix(0.71708683,0,0,0.71708683,128,128)">
|
|
||||||
<g
|
|
||||||
id="close">
|
|
||||||
<polygon
|
|
||||||
points="357,321.3 214.2,178.5 357,35.7 321.3,0 178.5,142.8 35.7,0 0,35.7 142.8,178.5 0,321.3 35.7,357 178.5,214.2 321.3,357 "
|
|
||||||
id="polygon857" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g862"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g864"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g866"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g868"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g870"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g872"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g874"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g876"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g878"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g880"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g882"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g884"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g886"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g888"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g890"
|
|
||||||
transform="translate(0,155)">
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 2.7 KiB |
@@ -41,7 +41,7 @@
|
|||||||
namespace ADS {
|
namespace ADS {
|
||||||
|
|
||||||
using TabLabelType = ElidingLabel;
|
using TabLabelType = ElidingLabel;
|
||||||
using CloseButtonType = QPushButton;
|
using CloseButtonType = QToolButton;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Private data class of public interface CFloatingWidgetTitleBar
|
* @brief Private data class of public interface CFloatingWidgetTitleBar
|
||||||
@@ -76,7 +76,7 @@ void FloatingWidgetTitleBarPrivate::createLayout()
|
|||||||
|
|
||||||
m_closeButton = new CloseButtonType();
|
m_closeButton = new CloseButtonType();
|
||||||
m_closeButton->setObjectName("floatingTitleCloseButton");
|
m_closeButton->setObjectName("floatingTitleCloseButton");
|
||||||
m_closeButton->setFlat(true);
|
m_closeButton->setAutoRaise(true);
|
||||||
internal::setButtonIcon(m_closeButton,
|
internal::setButtonIcon(m_closeButton,
|
||||||
QStyle::SP_TitleBarCloseButton,
|
QStyle::SP_TitleBarCloseButton,
|
||||||
ADS::FloatingWidgetCloseIcon);
|
ADS::FloatingWidgetCloseIcon);
|
||||||
@@ -106,7 +106,7 @@ void FloatingWidgetTitleBarPrivate::createLayout()
|
|||||||
}
|
}
|
||||||
|
|
||||||
FloatingWidgetTitleBar::FloatingWidgetTitleBar(FloatingDockContainer *parent)
|
FloatingWidgetTitleBar::FloatingWidgetTitleBar(FloatingDockContainer *parent)
|
||||||
: QWidget(parent)
|
: QFrame(parent)
|
||||||
, d(new FloatingWidgetTitleBarPrivate(this))
|
, d(new FloatingWidgetTitleBarPrivate(this))
|
||||||
{
|
{
|
||||||
d->m_floatingWidget = parent;
|
d->m_floatingWidget = parent;
|
||||||
@@ -131,9 +131,9 @@ void FloatingWidgetTitleBar::mousePressEvent(QMouseEvent *event)
|
|||||||
void FloatingWidgetTitleBar::mouseReleaseEvent(QMouseEvent *event)
|
void FloatingWidgetTitleBar::mouseReleaseEvent(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
d->m_dragState = DraggingInactive;
|
d->m_dragState = DraggingInactive;
|
||||||
if (d->m_floatingWidget) {
|
if (d->m_floatingWidget)
|
||||||
d->m_floatingWidget->finishDragging();
|
d->m_floatingWidget->finishDragging();
|
||||||
}
|
|
||||||
Super::mouseReleaseEvent(event);
|
Super::mouseReleaseEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,4 +164,9 @@ void FloatingWidgetTitleBar::setTitle(const QString &text)
|
|||||||
d->m_titleLabel->setText(text);
|
d->m_titleLabel->setText(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FloatingWidgetTitleBar::updateStyle()
|
||||||
|
{
|
||||||
|
internal::repolishStyle(this, internal::RepolishDirectChildren);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ADS
|
} // namespace ADS
|
||||||
|
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QFrame>
|
||||||
|
|
||||||
namespace ADS {
|
namespace ADS {
|
||||||
|
|
||||||
@@ -34,12 +34,12 @@ class FloatingWidgetTitleBarPrivate;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Titlebar for floating widgets to capture non client are mouse events.
|
* Titlebar for floating widgets to capture non client are mouse events.
|
||||||
* Linux does not support NonClieantArea mouse events like
|
* Linux does not support NonClientArea mouse events like
|
||||||
* QEvent::NonClientAreaMouseButtonPress. Because these events are required
|
* QEvent::NonClientAreaMouseButtonPress. Because these events are required
|
||||||
* for the docking system to work properly, we use our own titlebar here to
|
* for the docking system to work properly, we use our own titlebar here to
|
||||||
* capture the required mouse events.
|
* capture the required mouse events.
|
||||||
*/
|
*/
|
||||||
class FloatingWidgetTitleBar : public QWidget
|
class FloatingWidgetTitleBar : public QFrame
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
@@ -69,6 +69,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
void setTitle(const QString &text);
|
void setTitle(const QString &text);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update stylesheet style if a property changes
|
||||||
|
*/
|
||||||
|
void updateStyle();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/**
|
/**
|
||||||
* This signal is emitted, if the close button is clicked.
|
* This signal is emitted, if the close button is clicked.
|
||||||
|
@@ -1,6 +0,0 @@
|
|||||||
<RCC>
|
|
||||||
<qresource prefix="/ads">
|
|
||||||
<file>images/close-button.svg</file>
|
|
||||||
<file>images/close-button-disabled.svg</file>
|
|
||||||
</qresource>
|
|
||||||
</RCC>
|
|
@@ -59,9 +59,15 @@ ADS--DockWidget
|
|||||||
border-width: 0;
|
border-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ADS--DockAreaTitleBar{ background-color: creatorTheme.BackgroundColorDark; }
|
ADS--DockAreaTitleBar
|
||||||
|
{
|
||||||
|
background-color: creatorTheme.BackgroundColorDark;
|
||||||
|
}
|
||||||
|
|
||||||
QWidget#tabsContainerWidget { background-color: creatorTheme.BackgroundColorDark; }
|
QWidget#tabsContainerWidget
|
||||||
|
{
|
||||||
|
background-color: creatorTheme.BackgroundColorDark;
|
||||||
|
}
|
||||||
|
|
||||||
ADS--TitleBarButton
|
ADS--TitleBarButton
|
||||||
{
|
{
|
||||||
@@ -126,3 +132,33 @@ QScrollBar::sub-page {
|
|||||||
height: 0px;
|
height: 0px;
|
||||||
width: 0px;
|
width: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Focus related styling */
|
||||||
|
ADS--DockWidgetTab[focused="true"] {
|
||||||
|
background: creatorTheme.DSinteraction;
|
||||||
|
border-color: creatorTheme.DSinteraction;
|
||||||
|
}
|
||||||
|
|
||||||
|
ADS--DockWidgetTab[focused="true"] > #tabCloseButton:hover {
|
||||||
|
background: rgba(255, 255, 255, 48);
|
||||||
|
}
|
||||||
|
|
||||||
|
ADS--DockWidgetTab[focused="true"] > #tabCloseButton:pressed {
|
||||||
|
background: rgba(255, 255, 255, 92);
|
||||||
|
}
|
||||||
|
|
||||||
|
ADS--DockWidgetTab[focused="true"] QLabel {
|
||||||
|
color: palette(creatorTheme.QmlDesigner_TabDark);
|
||||||
|
}
|
||||||
|
|
||||||
|
ADS--DockAreaTitleBar {
|
||||||
|
background: transparent;
|
||||||
|
border-bottom: 2px solid creatorTheme.QmlDesigner_TabLight;
|
||||||
|
padding-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ADS--DockAreaWidget[focused="true"] ADS--DockAreaTitleBar {
|
||||||
|
background: transparent;
|
||||||
|
border-bottom: 2px solid creatorTheme.DSinteraction;
|
||||||
|
padding-bottom: 0px;
|
||||||
|
}
|
||||||
|
@@ -228,8 +228,9 @@ void DesignModeWidget::setup()
|
|||||||
|
|
||||||
auto settings = Core::ICore::settings(QSettings::UserScope);
|
auto settings = Core::ICore::settings(QSettings::UserScope);
|
||||||
|
|
||||||
|
ADS::DockManager::setConfigFlags(ADS::DockManager::DefaultNonOpaqueConfig);
|
||||||
|
ADS::DockManager::setConfigFlag(ADS::DockManager::FocusHighlighting, true);
|
||||||
m_dockManager = new ADS::DockManager(this);
|
m_dockManager = new ADS::DockManager(this);
|
||||||
m_dockManager->setConfigFlags(ADS::DockManager::DefaultNonOpaqueConfig);
|
|
||||||
m_dockManager->setSettings(settings);
|
m_dockManager->setSettings(settings);
|
||||||
m_dockManager->setWorkspacePresetsPath(Core::ICore::resourcePath() + QLatin1String("/qmldesigner/workspacePresets/"));
|
m_dockManager->setWorkspacePresetsPath(Core::ICore::resourcePath() + QLatin1String("/qmldesigner/workspacePresets/"));
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user