Compare commits

..

31 Commits
2.4.0 ... 2.5.1

Author SHA1 Message Date
Uwe Kindler
64231d037d Fixed build for Qt5.5.1 2019-07-12 14:45:35 +02:00
githubuser0xFFFF
6eb869014e Merge pull request #38 from tatatupi/bugfix/linux_cmake
adding linux src files to CMake
2019-07-12 14:41:39 +02:00
Taiguara
a564ca5ce5 adding linux src files to CMake 2019-07-12 09:35:06 -03:00
githubuser0xFFFF
365b989364 Update README.md
Updated Linux documentation because linux_experimental branch has been merged into master
2019-07-12 11:05:12 +02:00
Uwe Kindler
a3baf7dcf6 Changes in eclipse project file 2019-07-12 10:51:21 +02:00
Uwe Kindler
538e690c22 Fixed warning for unused parameter in DockOverlay.cpp 2019-07-12 10:39:59 +02:00
Uwe Kindler
b1309da89a Some changes to fix build for windows 2019-07-12 10:37:14 +02:00
Uwe Kindler
d2f751ef87 Moved linux specific code into linux sub folder 2019-07-11 16:12:15 +02:00
Uwe Kindler
35c1b04c58 Merge branch 'refs/heads/master' into linux_experimental 2019-07-11 15:50:24 +02:00
Uwe Kindler
0de1a9ccae Properly implemented support for DockWidgetFloatable feature - now detaching a DockWidget or a DockAre that is not floatable is not possible (support for DockWidgetMovable feature is not implemented yet) 2019-07-11 15:12:39 +02:00
Uwe Kindler
c45327aafd Removed enum eXmlMode and added XmlAutoFormatting flag anc XmlCompressionEnabled flag to eConfigFlags. Added support for XML compression for the XML generated by the store function. If enabled then XML the generated XML is not human readable anymore but it needs less space when storing into settings file 2019-06-26 14:57:14 +02:00
Uwe Kindler
8853c751d6 Merge branch 'master' into linux_experimental 2019-06-04 13:40:20 +02:00
githubuser0xFFFF
e978a32a09 Merge pull request #32 from simulton/master
Feature: Remove docks
2019-06-04 13:32:15 +02:00
Joel Bodenmann
ca5683f5bf Merge pull request #1 from simulton/feature/remove_docks
Feature/remove docks
2019-05-17 21:40:36 +02:00
Tibo Clausen
c630a59afe Replace CDockWidget::releaseWidget() with CDockWidget::takeWidget() 2019-05-16 13:08:48 +01:00
Tibo Clausen
b9b8ff9c76 Add CDockWidget::releaseWidget() 2019-05-16 11:53:31 +01:00
Tibo Clausen
e2c5204d00 Clear LastAddedAreaCache when restoring 2019-05-15 16:13:55 +01:00
Tibo Clausen
5ee94d7602 Improve CDockManager::addDockWidgetTab() for dynamically added widgets 2019-05-15 14:30:32 +01:00
Tibo Clausen
69894f3f88 Remove area from LastAddedAreaCache 2019-05-15 14:20:08 +01:00
Tibo Clausen
641946bff5 Add CDockManager::removeDockWidget() 2019-05-15 13:47:58 +01:00
githubuser0xFFFF
27dd7a1b75 Update README.md 2019-05-15 10:14:22 +02:00
Uwe Kindler
5425f2b9e1 Added missing FloatingWidgetTitleBar.cpp and missing stylesheet file for linux 2019-05-15 09:12:22 +02:00
githubuser0xFFFF
4320e350c8 Update README.md 2019-05-14 16:03:47 +02:00
Uwe Kindler
8351aa11e7 Added linux screenshot 2019-05-14 15:42:47 +02:00
Uwe Kindler
e98fd5bcb3 Improved icons for all button, adjusted size of dock marker 2019-05-14 15:32:50 +02:00
Uwe Kindler
a012af2aac Created experimental linux branch with initial experimental linux
support
2019-05-14 14:09:10 +02:00
githubuser0xFFFF
df285dd385 Merge pull request #26 from gameraccoon/master
Fix compilation on linux using cmake
2019-05-13 09:02:43 +02:00
Uwe Kindler
a6ed4354a9 Implemented workaround for blurry icons in latest Qt versions 2019-05-10 11:33:26 +02:00
Uwe Kindler
1fccb943fe Fixed setWidget function of DockWidget to properly setup the internal scroll area 2019-05-10 10:32:06 +02:00
Pavel Grebnev
7bd3765fa7 Fix compilation on linux 2019-05-04 19:08:47 +03:00
Uwe Kindler
9b56ca08e1 Changes to work around new QT issues in non client area code that comes with the new Qt version 5.12.2 2019-03-22 13:57:17 +01:00
25 changed files with 737 additions and 121 deletions

View File

@@ -71,15 +71,6 @@
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope"/>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1119687795;cdt.managedbuild.toolchain.gnu.mingw.base.1119687795.1949777584;cdt.managedbuild.tool.gnu.cpp.compiler.mingw.base.1947822681;cdt.managedbuild.tool.gnu.cpp.compiler.input.1318830536">
<autodiscovery enabled="false" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1119687795;cdt.managedbuild.toolchain.gnu.mingw.base.1119687795.1949777584;cdt.managedbuild.tool.gnu.c.compiler.mingw.base.389117097;cdt.managedbuild.tool.gnu.c.compiler.input.1568363924">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
<buildTargets>
<target name="Build all" path=" build" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
@@ -356,4 +347,13 @@
</target>
</buildTargets>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1119687795;cdt.managedbuild.toolchain.gnu.mingw.base.1119687795.1949777584;cdt.managedbuild.tool.gnu.cpp.compiler.mingw.base.1947822681;cdt.managedbuild.tool.gnu.cpp.compiler.input.1318830536">
<autodiscovery enabled="false" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1119687795;cdt.managedbuild.toolchain.gnu.mingw.base.1119687795.1949777584;cdt.managedbuild.tool.gnu.c.compiler.mingw.base.389117097;cdt.managedbuild.tool.gnu.c.compiler.input.1568363924">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
</cproject>

View File

@@ -40,6 +40,7 @@ set(ads_SRCS
src/ElidingLabel.cpp
src/FloatingDockContainer.cpp
src/ads.qrc
src/linux/FloatingWidgetTitleBar.cpp
)
set(ads_INSTALL_INCLUDE
src/ads_globals.h
@@ -54,6 +55,7 @@ set(ads_INSTALL_INCLUDE
src/DockWidgetTab.h
src/ElidingLabel.h
src/FloatingDockContainer.h
src/linux/FloatingWidgetTitleBar.h
)
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4")
set(ads_PlatformDir "x86")

View File

@@ -1,6 +1,7 @@
# Advanced Docking System for Qt
[![Build Status](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System.svg?branch=master)](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System)
[![Build status](https://ci.appveyor.com/api/projects/status/qcfb3cy932jw9mpy/branch/master?svg=true)](https://ci.appveyor.com/project/githubuser0xFFFF/qt-advanced-docking-system/branch/master)
[![License: LGPL v2.1](https://img.shields.io/badge/License-LGPL%20v2.1-blue.svg)](gnu-lgpl-v2.1.md)
@@ -60,9 +61,22 @@ main window layout.
![Perspective](doc/perspectives_dark.png)
## Tested Compatible Environments
- Windows 10 [![Build status](https://ci.appveyor.com/api/projects/status/qcfb3cy932jw9mpy/branch/master?svg=true)](https://ci.appveyor.com/project/githubuser0xFFFF/qt-advanced-docking-system/branch/master)
- Ubuntu [![Build Status](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System.svg?branch=master)](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System)
- macOS [![Build Status](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System.svg?branch=master)](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System)
### Windows
Windows 10 [![Build status](https://ci.appveyor.com/api/projects/status/qcfb3cy932jw9mpy/branch/master?svg=true)](https://ci.appveyor.com/project/githubuser0xFFFF/qt-advanced-docking-system/branch/master)
The library was developed on and for Windows. It is used in a commercial Windows application and is therefore constantly tested.
### macOS
macOS [![Build Status](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System.svg?branch=master)](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System)
The application can be compiled for macOS. A user reported, that the library works on macOS. If have not tested it.
### Linux
Ubuntu [![Build Status](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System.svg?branch=master)](https://travis-ci.org/githubuser0xFFFF/Qt-Advanced-Docking-System)
The application can be compiled for Linux and has been developed and tested with **Kubuntu 18.04**.
![Advanced Docking on Linux](doc/linux_kubuntu_1804.png)
## Build
Open the `ads.pro` with QtCreator and start the build, that's it.
@@ -144,5 +158,6 @@ MainWindow::~MainWindow()
- Manuel Freiholz
## License information
[![License: LGPL v2.1](https://img.shields.io/badge/License-LGPL%20v2.1-blue.svg)](gnu-lgpl-v2.1.md)
This project uses the [LGPLv2.1 license](gnu-lgpl-v2.1.md)

View File

@@ -23,7 +23,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(ads_demo_SRCS
main.cpp
MainWindow.cpp
MainWindow.ui
mainwindow.ui
main.qrc
)
add_executable(AdvancedDockingSystemDemo WIN32 ${ads_demo_SRCS})

View File

@@ -88,6 +88,32 @@ static ads::CDockWidget* createLongTextLabelDockWidget(QMenu* ViewMenu)
}
/**
* Function returns a features string with closable (c), movable (m) and floatable (f)
* features. i.e. The following string is for a not closable but movable and floatable
* widget: c- m+ f+
*/
static QString featuresString(ads::CDockWidget* DockWidget)
{
auto f = DockWidget->features();
return QString("c%1 m%2 f%3")
.arg(f.testFlag(ads::CDockWidget::DockWidgetClosable) ? "+" : "-")
.arg(f.testFlag(ads::CDockWidget::DockWidgetMovable) ? "+" : "-")
.arg(f.testFlag(ads::CDockWidget::DockWidgetFloatable) ? "+" : "-");
}
/**
* Appends the string returned by featuresString() to the window title of
* the given DockWidget
*/
static void appendFeaturStringToWindowTitle(ads::CDockWidget* DockWidget)
{
DockWidget->setWindowTitle(DockWidget->windowTitle()
+ QString(" (%1)").arg(featuresString(DockWidget)));
}
//============================================================================
static ads::CDockWidget* createCalendarDockWidget(QMenu* ViewMenu)
{
@@ -110,7 +136,8 @@ static ads::CDockWidget* createFileSystemTreeDockWidget(QMenu* ViewMenu)
QFileSystemModel* m = new QFileSystemModel(w);
m->setRootPath(QDir::currentPath());
w->setModel(m);
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Filesystem %1").arg(FileSystemCount++));
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Filesystem %1")
.arg(FileSystemCount++));
DockWidget->setWidget(w);
ViewMenu->addAction(DockWidget->toggleViewAction());
return DockWidget;
@@ -185,6 +212,8 @@ void MainWindowPrivate::createContent()
ToolBar->addAction(ui.actionSaveState);
ToolBar->addAction(ui.actionRestoreState);
FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetMovable, false);
FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetFloatable, false);
appendFeaturStringToWindowTitle(FileSystemWidget);
auto TopDockArea = DockManager->addDockWidget(ads::TopDockWidgetArea, FileSystemWidget);
DockWidget = createCalendarDockWidget(ViewMenu);
DockWidget->setFeature(ads::CDockWidget::DockWidgetClosable, false);
@@ -282,7 +311,7 @@ CMainWindow::CMainWindow(QWidget *parent) :
d->createContent();
// Default window geometry
resize(800, 600);
resize(1280, 720);
d->restoreState();
d->restorePerspectives();

BIN
doc/linux_kubuntu_1804.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

View File

@@ -205,6 +205,13 @@ void CDockAreaTabBar::mouseMoveEvent(QMouseEvent* ev)
return;
}
// If one single dock widget in this area is not floatable then the whole
// area is not floatable
if (!d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
{
return;
}
int DragDistance = (d->DragStartMousePos - ev->pos()).manhattanLength();
if (DragDistance >= CDockManager::startDragDistance())
{
@@ -228,6 +235,11 @@ void CDockAreaTabBar::mouseDoubleClickEvent(QMouseEvent *event)
{
return;
}
if (!d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
{
return;
}
makeAreaFloating(event->pos(), DraggingInactive);
}
@@ -238,7 +250,7 @@ CFloatingDockContainer* CDockAreaTabBar::makeAreaFloating(const QPoint& Offset,
{
QSize Size = d->DockArea->size();
CFloatingDockContainer* FloatingWidget = new CFloatingDockContainer(d->DockArea);
FloatingWidget->startFloating(Offset, Size, DragState);
FloatingWidget->startFloating(Offset, Size, DragState, nullptr);
auto TopLevelDockWidget = FloatingWidget->topLevelDockWidget();
if (TopLevelDockWidget)
{

View File

@@ -97,6 +97,23 @@ struct DockAreaTitleBarPrivate
{
return DockArea->dockManager()->configFlags().testFlag(Flag);
}
/**
* Helper class to set title bar button icons depending on operating system
* and to avoid duplicated code
*/
void setTitleBarButtonIcon(tTileBarButton* Button, QStyle::StandardPixmap StandarPixmap)
{
#ifdef Q_OS_LINUX
Button->setIcon(_this->style()->standardIcon(StandarPixmap));
#else
QIcon Icon;
QPixmap normalPixmap = _this->style()->standardPixmap(StandarPixmap, 0, Button);
Icon.addPixmap(internal::createTransparentPixmap(normalPixmap, 0.25), QIcon::Disabled);
Icon.addPixmap(normalPixmap, QIcon::Normal);
Button->setIcon(Icon);
#endif
}
};// struct DockAreaTitleBarPrivate
@@ -112,12 +129,12 @@ DockAreaTitleBarPrivate::DockAreaTitleBarPrivate(CDockAreaTitleBar* _public) :
//============================================================================
void DockAreaTitleBarPrivate::createButtons()
{
// Tabs menu button
TabsMenuButton = new tTileBarButton();
TabsMenuButton->setObjectName("tabsMenuButton");
TabsMenuButton->setAutoRaise(true);
TabsMenuButton->setPopupMode(QToolButton::InstantPopup);
TabsMenuButton->setIcon(_this->style()->standardIcon(QStyle::SP_TitleBarUnshadeButton));
setTitleBarButtonIcon(TabsMenuButton, QStyle::SP_TitleBarUnshadeButton);
QMenu* TabsMenu = new QMenu(TabsMenuButton);
#ifndef QT_NO_TOOLTIP
TabsMenu->setToolTipsVisible(true);
@@ -132,6 +149,7 @@ void DockAreaTitleBarPrivate::createButtons()
_this->connect(TabsMenuButton->menu(), SIGNAL(triggered(QAction*)),
SLOT(onTabsMenuActionTriggered(QAction*)));
// Undock button
UndockButton = new tTileBarButton();
UndockButton->setObjectName("undockButton");
@@ -139,22 +157,17 @@ void DockAreaTitleBarPrivate::createButtons()
#ifndef QT_NO_TOOLTIP
UndockButton->setToolTip(QObject::tr("Detach Group"));
#endif
UndockButton->setIcon(_this->style()->standardIcon(QStyle::SP_TitleBarNormalButton));
UndockButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
setTitleBarButtonIcon(UndockButton, QStyle::SP_TitleBarNormalButton);
UndockButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
TopLayout->addWidget(UndockButton, 0);
_this->connect(UndockButton, SIGNAL(clicked()), SLOT(onUndockButtonClicked()));
// Close button
CloseButton = new tTileBarButton();
CloseButton->setObjectName("closeButton");
CloseButton->setAutoRaise(true);
// The standard icons do not look good on high DPI screens
QIcon CloseIcon = _this->style()->standardIcon(QStyle::SP_TitleBarCloseButton);
QPixmap normalPixmap = _this->style()->standardPixmap(QStyle::SP_TitleBarCloseButton, 0, CloseButton);
QPixmap disabledPixmap = internal::createTransparentPixmap(normalPixmap, 0.25);
CloseIcon.addPixmap(disabledPixmap, QIcon::Disabled);
CloseButton->setIcon(CloseIcon);
setTitleBarButtonIcon(CloseButton, QStyle::SP_TitleBarCloseButton);
#ifndef QT_NO_TOOLTIP
if (testConfigFlag(CDockManager::DockAreaCloseButtonClosesTab))
{
@@ -166,6 +179,7 @@ void DockAreaTitleBarPrivate::createButtons()
}
#endif
CloseButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
CloseButton->setIconSize(QSize(16, 16));
TopLayout->addWidget(CloseButton, 0);
_this->connect(CloseButton, SIGNAL(clicked()), SLOT(onCloseButtonClicked()));
}
@@ -277,7 +291,10 @@ void CDockAreaTitleBar::onCloseButtonClicked()
//============================================================================
void CDockAreaTitleBar::onUndockButtonClicked()
{
d->TabBar->makeAreaFloating(mapFromGlobal(QCursor::pos()), DraggingInactive);
if (d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
{
d->TabBar->makeAreaFloating(mapFromGlobal(QCursor::pos()), DraggingInactive);
}
}
@@ -332,9 +349,10 @@ void CDockAreaTitleBar::setVisible(bool Visible)
void CDockAreaTitleBar::showContextMenu(const QPoint& pos)
{
QMenu Menu(this);
Menu.addAction(tr("Detach Area"), this, SLOT(onUndockButtonClicked()));
auto Action = Menu.addAction(tr("Detach Area"), this, SLOT(onUndockButtonClicked()));
Action->setEnabled(d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable));
Menu.addSeparator();
auto Action = Menu.addAction(tr("Close Area"), this, SLOT(onCloseButtonClicked()));
Action = Menu.addAction(tr("Close Area"), this, SLOT(onCloseButtonClicked()));
Action->setEnabled(d->DockArea->features().testFlag(CDockWidget::DockWidgetClosable));
Menu.addAction(tr("Close Other Areas"), d->DockArea, SLOT(closeOtherAreas()));
Menu.exec(mapToGlobal(pos));

View File

@@ -241,7 +241,7 @@ struct DockAreaWidgetPrivate
DockAreaLayout* ContentsLayout = nullptr;
CDockAreaTitleBar* TitleBar = nullptr;
CDockManager* DockManager = nullptr;
bool UpdateCloseButton = false;
bool UpdateTitleBarButtons = false;
/**
* Private data constructor
@@ -295,9 +295,9 @@ struct DockAreaWidgetPrivate
}
/**
* Udpates the enable state of the close button
* Udpates the enable state of the close and detach button
*/
void updateCloseButtonState();
void updateTitleBarButtonStates();
};
// struct DockAreaWidgetPrivate
@@ -322,17 +322,19 @@ void DockAreaWidgetPrivate::createTitleBar()
//============================================================================
void DockAreaWidgetPrivate::updateCloseButtonState()
void DockAreaWidgetPrivate::updateTitleBarButtonStates()
{
if (_this->isHidden())
{
UpdateCloseButton = true;
UpdateTitleBarButtons = true;
return;
}
TitleBar->button(TitleBarButtonClose)->setEnabled(
_this->features().testFlag(CDockWidget::DockWidgetClosable));
UpdateCloseButton = false;
TitleBar->button(TitleBarButtonUndock)->setEnabled(
_this->features().testFlag(CDockWidget::DockWidgetFloatable));
UpdateTitleBarButtons = false;
}
@@ -400,7 +402,7 @@ void CDockAreaWidget::insertDockWidget(int index, CDockWidget* DockWidget,
setCurrentIndex(index);
}
DockWidget->setDockArea(this);
d->updateCloseButtonState();
d->updateTitleBarButtonStates();
}
@@ -414,14 +416,15 @@ void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget)
auto TabWidget = DockWidget->tabWidget();
TabWidget->hide();
d->tabBar()->removeTab(TabWidget);
CDockContainerWidget* DockContainer = dockContainer();
if (NextOpenDockWidget)
{
setCurrentDockWidget(NextOpenDockWidget);
}
else if (d->ContentsLayout->isEmpty())
else if (d->ContentsLayout->isEmpty() && DockContainer->dockAreaCount() > 1)
{
qDebug() << "Dock Area empty";
dockContainer()->removeDockArea(this);
DockContainer->removeDockArea(this);
this->deleteLater();
}
else
@@ -432,16 +435,15 @@ void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget)
hideAreaWithNoVisibleContent();
}
d->updateCloseButtonState();
d->updateTitleBarButtonStates();
updateTitleBarVisibility();
auto TopLevelDockWidget = dockContainer()->topLevelDockWidget();
auto TopLevelDockWidget = DockContainer->topLevelDockWidget();
if (TopLevelDockWidget)
{
TopLevelDockWidget->emitTopLevelChanged(true);
}
#if (ADS_DEBUG_LEVEL > 0)
CDockContainerWidget* DockContainer = dockContainer();
DockContainer->dumpLayout();
#endif
}
@@ -765,9 +767,9 @@ void CDockAreaWidget::toggleView(bool Open)
void CDockAreaWidget::setVisible(bool Visible)
{
Super::setVisible(Visible);
if (d->UpdateCloseButton)
if (d->UpdateTitleBarButtons)
{
d->updateCloseButtonState();
d->updateTitleBarButtonStates();
}
}

View File

@@ -998,6 +998,15 @@ CDockAreaWidget* CDockContainerWidget::addDockWidget(DockWidgetArea area, CDockW
}
}
//============================================================================
void CDockContainerWidget::removeDockWidget(CDockWidget* Dockwidget)
{
CDockAreaWidget* Area = Dockwidget->dockAreaWidget();
if (Area)
{
Area->removeDockWidget(Dockwidget);
}
}
//============================================================================
unsigned int CDockContainerWidget::zOrderIndex() const
@@ -1057,6 +1066,12 @@ void CDockContainerWidget::removeDockArea(CDockAreaWidget* area)
area->setParent(nullptr);
internal::hideEmptyParentSplitters(Splitter);
// Remove this area from cached areas
const auto& cache = d->LastAddedAreaCache;
if (auto p = std::find(cache, cache+sizeof(cache)/sizeof(cache[0]), area)) {
d->LastAddedAreaCache[std::distance(cache, p)] = nullptr;
}
// If splitter has more than 1 widgets, we are finished and can leave
if (Splitter->count() > 1)
{
@@ -1274,6 +1289,7 @@ bool CDockContainerWidget::restoreState(QXmlStreamReader& s, bool Testing)
{
d->VisibleDockAreaCount = -1;// invalidate the dock area count
d->DockAreas.clear();
std::fill(std::begin(d->LastAddedAreaCache),std::end(d->LastAddedAreaCache), nullptr);
}
if (IsFloating)

View File

@@ -166,6 +166,11 @@ public:
CDockAreaWidget* addDockWidget(DockWidgetArea area, CDockWidget* Dockwidget,
CDockAreaWidget* DockAreaWidget = nullptr);
/**
* Removes dockwidget
*/
void removeDockWidget(CDockWidget* Dockwidget);
/**
* Returns the current zOrderIndex
*/

View File

@@ -145,7 +145,11 @@ DockManagerPrivate::DockManagerPrivate(CDockManager* _public) :
void DockManagerPrivate::loadStylesheet()
{
QString Result;
#ifdef Q_OS_LINUX
QFile StyleSheetFile(":ads/stylesheets/default_linux.css");
#else
QFile StyleSheetFile(":ads/stylesheets/default.css");
#endif
StyleSheetFile.open(QIODevice::ReadOnly);
QTextStream StyleSheetStream(&StyleSheetFile);
Result = StyleSheetStream.readAll();
@@ -336,8 +340,9 @@ void DockManagerPrivate::emitTopLevelEvents()
//============================================================================
bool DockManagerPrivate::restoreState(const QByteArray &state, int version)
bool DockManagerPrivate::restoreState(const QByteArray& State, int version)
{
QByteArray state = State.startsWith("<?xml") ? State : qUncompress(State);
if (!checkFormat(state, version))
{
qDebug() << "checkFormat: Error checking format!!!!!!!";
@@ -489,11 +494,11 @@ unsigned int CDockManager::zOrderIndex() const
//============================================================================
QByteArray CDockManager::saveState(eXmlMode XmlMode, int version) const
QByteArray CDockManager::saveState(int version) const
{
QByteArray xmldata;
QXmlStreamWriter s(&xmldata);
s.setAutoFormatting(XmlAutoFormattingEnabled == XmlMode);
s.setAutoFormatting(d->ConfigFlags.testFlag(XmlAutoFormattingEnabled));
s.writeStartDocument();
s.writeStartElement("QtAdvancedDockingSystem");
s.writeAttribute("Version", QString::number(version));
@@ -506,7 +511,7 @@ QByteArray CDockManager::saveState(eXmlMode XmlMode, int version) const
s.writeEndElement();
s.writeEndDocument();
return xmldata;
return d->ConfigFlags.testFlag(XmlCompressionEnabled) ? qCompress(xmldata, 9) : xmldata;
}
@@ -565,9 +570,13 @@ CDockAreaWidget* CDockManager::addDockWidgetTab(DockWidgetArea area,
{
return addDockWidget(ads::CenterDockWidgetArea, Dockwidget, AreaWidget);
}
else if (!openedDockAreas().isEmpty())
{
return addDockWidget(area, Dockwidget, openedDockAreas().last());
}
else
{
return addDockWidget(area, Dockwidget, AreaWidget);
return addDockWidget(area, Dockwidget, nullptr);
}
}
@@ -586,6 +595,12 @@ CDockWidget* CDockManager::findDockWidget(const QString& ObjectName) const
return d->DockWidgetsMap.value(ObjectName, nullptr);
}
//============================================================================
void CDockManager::removeDockWidget(CDockWidget* Dockwidget)
{
d->DockWidgetsMap.remove(Dockwidget->objectName());
CDockContainerWidget::removeDockWidget(Dockwidget);
}
//============================================================================
QMap<QString, CDockWidget*> CDockManager::dockWidgetsMap() const

View File

@@ -51,7 +51,9 @@ struct DockWidgetTabPrivate;
struct DockAreaWidgetPrivate;
/**
* The central dock manager that maintains the complete docking system
* The central dock manager that maintains the complete docking system.
* With the configuration flags you can globally control the functionality
* of the docking system.
**/
class ADS_EXPORT CDockManager : public CDockContainerWidget
{
@@ -108,12 +110,6 @@ public:
MenuAlphabeticallySorted
};
enum eXmlMode
{
XmlAutoFormattingDisabled,
XmlAutoFormattingEnabled
};
/**
* These global configuration flags configure some global dock manager
* settings.
@@ -124,7 +120,9 @@ public:
DockAreaHasCloseButton = 0x02, //!< If the flag is set each dock area has a close button
DockAreaCloseButtonClosesTab = 0x04,//!< If the flag is set, the dock area close button closes the active tab, if not set, it closes the complete cock area
OpaqueSplitterResize = 0x08, //!< See QSplitter::setOpaqueResize() documentation
DefaultConfig = ActiveTabHasCloseButton | DockAreaHasCloseButton | OpaqueSplitterResize, ///< the default configuration
XmlAutoFormattingEnabled = 0x10,//!< If enabled, the XML writer automatically adds line-breaks and indentation to empty sections between elements (ignorable whitespace).
XmlCompressionEnabled = 0x20,//!< If enabled, the XML output will be compressed and is not human readable anymore
DefaultConfig = ActiveTabHasCloseButton | DockAreaHasCloseButton | OpaqueSplitterResize | XmlCompressionEnabled, ///< the default configuration
};
Q_DECLARE_FLAGS(ConfigFlags, eConfigFlag)
@@ -192,6 +190,11 @@ public:
*/
CDockWidget* findDockWidget(const QString& ObjectName) const;
/**
* Remove the given Dock from the dock manager
*/
void removeDockWidget(CDockWidget* Dockwidget);
/**
* This function returns a readable reference to the internal dock
* widgets map so that it is possible to iterate over all dock widgets
@@ -223,7 +226,7 @@ public:
* The XmlMode XmlAutoFormattingDisabled is better if you would like to have
* a more compact XML output - i.e. for storage in ini files.
*/
QByteArray saveState(eXmlMode XmlMode = XmlAutoFormattingDisabled, int version = 0) const;
QByteArray saveState(int version = 0) const;
/**
* Restores the state of this dockmanagers dockwidgets.

View File

@@ -132,6 +132,21 @@ struct DockOverlayCrossPrivate
return Color;
}
//============================================================================
/**
* Helper function that returns the drop indicator width depending on the
* operating system
*/
qreal dropIndicatiorWidth(QLabel* l) const
{
#ifdef Q_OS_LINUX
Q_UNUSED(l)
return 40;
#else
return static_cast<qreal>(l->fontMetrics().height()) * 3.f;
#endif
}
//============================================================================
QWidget* createDropIndicatorWidget(DockWidgetArea DockWidgetArea,
@@ -140,7 +155,7 @@ struct DockOverlayCrossPrivate
QLabel* l = new QLabel();
l->setObjectName("DockWidgetAreaLabel");
const qreal metric = static_cast<qreal>(l->fontMetrics().height()) * 3.f;
const qreal metric = dropIndicatiorWidth(l);
const QSizeF size(metric, metric);
l->setPixmap(createHighDpiDropIndicatorPixmap(size, DockWidgetArea, Mode));
@@ -154,7 +169,7 @@ struct DockOverlayCrossPrivate
void updateDropIndicatorIcon(QWidget* DropIndicatorWidget)
{
QLabel* l = qobject_cast<QLabel*>(DropIndicatorWidget);
const qreal metric = static_cast<qreal>(l->fontMetrics().height()) * 3.f;
const qreal metric = dropIndicatiorWidth(l);
const QSizeF size(metric, metric);
int Area = l->property("dockWidgetArea").toInt();

View File

@@ -243,21 +243,35 @@ void CDockWidget::setToggleViewActionChecked(bool Checked)
void CDockWidget::setWidget(QWidget* widget, eInsertMode InsertMode)
{
QScrollArea* ScrollAreaWidget = qobject_cast<QScrollArea*>(widget);
if (ScrollAreaWidget || ForceNoScrollArea != InsertMode)
if (ScrollAreaWidget || ForceNoScrollArea == InsertMode)
{
d->Layout->addWidget(widget);
if (ScrollAreaWidget && ScrollAreaWidget->viewport())
{
ScrollAreaWidget->viewport()->setProperty("dockWidgetContent", true);
}
}
else
{
d->setupScrollArea();
d->ScrollArea->setWidget(widget);
}
else
{
d->Layout->addWidget(widget);
}
d->Widget = widget;
d->Widget->setProperty("dockWidgetContent", true);
}
//============================================================================
QWidget* CDockWidget::takeWidget()
{
d->ScrollArea->takeWidget();
d->Layout->removeWidget(d->Widget);
d->Widget->setParent(nullptr);
return d->Widget;
}
//============================================================================
QWidget* CDockWidget::widget() const
{

View File

@@ -141,7 +141,7 @@ public:
enum DockWidgetFeature
{
DockWidgetClosable = 0x01,
DockWidgetMovable = 0x02,
DockWidgetMovable = 0x02,///< this feature is not properly implemented yet and is ignored
DockWidgetFloatable = 0x04,
AllDockWidgetFeatures = DockWidgetClosable | DockWidgetMovable | DockWidgetFloatable,
NoDockWidgetFeatures = 0x00
@@ -238,6 +238,11 @@ public:
*/
void setWidget(QWidget* widget, eInsertMode InsertMode = AutoScrollArea);
/**
* Remove the widget from the dock and give ownership back to the caller
*/
QWidget* takeWidget();
/**
* Returns the widget for the dock widget. This function returns zero if
* the widget has not been set.

View File

@@ -146,12 +146,13 @@ void DockWidgetTabPrivate::createLayout()
CloseButton = new tCloseButton();
CloseButton->setObjectName("tabCloseButton");
// The standard icons do does not look good on high DPI screens
QIcon CloseIcon = _this->style()->standardIcon(QStyle::SP_TitleBarCloseButton);
QIcon CloseIcon;
QPixmap normalPixmap = _this->style()->standardPixmap(QStyle::SP_TitleBarCloseButton, 0, CloseButton);
QPixmap disabledPixmap = internal::createTransparentPixmap(normalPixmap, 0.25);
CloseIcon.addPixmap(disabledPixmap, QIcon::Disabled);
CloseIcon.addPixmap(normalPixmap, QIcon::Normal);
CloseIcon.addPixmap(internal::createTransparentPixmap(normalPixmap, 0.25), QIcon::Disabled);
CloseButton->setIcon(CloseIcon);
CloseButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
CloseButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
CloseButton->setVisible(false);
#ifndef QT_NO_TOOLTIP
CloseButton->setToolTip(QObject::tr("Close Tab"));
@@ -223,7 +224,7 @@ bool DockWidgetTabPrivate::startFloating(eDragState DraggingState)
if (DraggingFloatingWidget == DraggingState)
{
FloatingWidget->startDragging(DragStartMousePosition, Size);
FloatingWidget->startDragging(DragStartMousePosition, Size, _this);
auto Overlay = DockWidget->dockManager()->containerOverlay();
Overlay->setAllowedAreas(OuterDockAreas);
this->FloatingWidget = FloatingWidget;
@@ -327,7 +328,7 @@ void CDockWidgetTab::mouseMoveEvent(QMouseEvent* ev)
}
// Floating is only allowed for widgets that are movable
if (d->DockWidget->features().testFlag(CDockWidget::DockWidgetMovable))
if (d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable))
{
d->startFloating();
}
@@ -351,9 +352,10 @@ void CDockWidgetTab::contextMenuEvent(QContextMenuEvent* ev)
d->DragStartMousePosition = ev->pos();
QMenu Menu(this);
Menu.addAction(tr("Detach"), this, SLOT(onDetachActionTriggered()));
auto Action = Menu.addAction(tr("Detach"), this, SLOT(onDetachActionTriggered()));
Action->setEnabled(d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable));
Menu.addSeparator();
auto Action = Menu.addAction(tr("Close"), this, SIGNAL(closeRequested()));
Action = Menu.addAction(tr("Close"), this, SIGNAL(closeRequested()));
Action->setEnabled(isClosable());
Menu.addAction(tr("Close Others"), this, SIGNAL(closeOtherTabsRequested()));
Menu.exec(mapToGlobal(ev->pos()));
@@ -468,7 +470,8 @@ void CDockWidgetTab::mouseDoubleClickEvent(QMouseEvent *event)
// If this is the last dock area in a dock container it does not make
// sense to move it to a new floating widget and leave this one
// empty
if (!d->DockArea->dockContainer()->isFloating() || d->DockArea->dockWidgetsCount() > 1)
if ((!d->DockArea->dockContainer()->isFloating() || d->DockArea->dockWidgetsCount() > 1)
&& d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable))
{
d->DragStartMousePosition = event->pos();
d->startFloating(DraggingInactive);
@@ -504,13 +507,15 @@ bool CDockWidgetTab::isClosable() const
//===========================================================================
void CDockWidgetTab::onDetachActionTriggered()
{
if (!d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable))
{
return;
}
d->DragStartMousePosition = mapFromGlobal(QCursor::pos());
d->startFloating(DraggingInactive);
}
//============================================================================
bool CDockWidgetTab::event(QEvent *e)
{

View File

@@ -45,7 +45,11 @@
#include "DockWidget.h"
#include "DockOverlay.h"
#include <iostream>
#ifdef Q_OS_LINUX
#include "linux/FloatingWidgetTitleBar.h"
#include <xcb/xcb.h>
#endif
namespace ads
{
@@ -63,6 +67,10 @@ struct FloatingDockContainerPrivate
QPoint DragStartMousePosition;
CDockContainerWidget* DropContainer = nullptr;
CDockAreaWidget* SingleDockArea = nullptr;
#ifdef Q_OS_LINUX
QWidget* MouseEventHandler = nullptr;
CFloatingWidgetTitleBar* TitleBar = nullptr;
#endif
/**
* Private data constructor
@@ -84,6 +92,15 @@ struct FloatingDockContainerPrivate
{
DraggingState = StateId;
}
void setWindowTitle(const QString& Text)
{
#ifdef Q_OS_LINUX
TitleBar->setTitle(Text);
#else
_this->setWindowTitle(Text);
#endif
}
};
// struct FloatingDockContainerPrivate
@@ -216,26 +233,38 @@ void FloatingDockContainerPrivate::updateDropOverlays(const QPoint& GlobalPos)
//============================================================================
CFloatingDockContainer::CFloatingDockContainer(CDockManager* DockManager) :
QWidget(DockManager, Qt::Window),
tFloatingWidgetBase(DockManager),
d(new FloatingDockContainerPrivate(this))
{
setWindowFlags(Qt::Window | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint);
d->DockManager = DockManager;
d->DockManager = DockManager;
d->DockContainer = new CDockContainerWidget(DockManager, this);
connect(d->DockContainer, SIGNAL(dockAreasAdded()), this, SLOT(onDockAreasAddedOrRemoved()));
connect(d->DockContainer, SIGNAL(dockAreasRemoved()), this, SLOT(onDockAreasAddedOrRemoved()));
#ifdef Q_OS_LINUX
d->TitleBar = new CFloatingWidgetTitleBar(this);
setWindowFlags(windowFlags() | Qt::Tool);
QDockWidget::setWidget(d->DockContainer);
QDockWidget::setFloating(true);
QDockWidget::setFeatures(QDockWidget::AllDockWidgetFeatures);
setTitleBarWidget(d->TitleBar);
connect(d->TitleBar, SIGNAL(closeRequested()), SLOT(close()));
#else
setWindowFlags(Qt::Window | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint);
QBoxLayout* l = new QBoxLayout(QBoxLayout::TopToBottom);
l->setContentsMargins(0, 0, 0, 0);
l->setSpacing(0);
setLayout(l);
l->addWidget(d->DockContainer);
#endif
d->DockContainer = new CDockContainerWidget(DockManager, this);
connect(d->DockContainer, SIGNAL(dockAreasAdded()), this, SLOT(onDockAreasAddedOrRemoved()));
connect(d->DockContainer, SIGNAL(dockAreasRemoved()), this, SLOT(onDockAreasAddedOrRemoved()));
l->addWidget(d->DockContainer);
DockManager->registerFloatingWidget(this);
// We install an event filter to detect mouse release events because we
// do not receive mouse release event if the floating widget is behind
// the drop overlay cross
qApp->installEventFilter(this);
qApp->installEventFilter(this);
}
@@ -244,14 +273,20 @@ CFloatingDockContainer::CFloatingDockContainer(CDockAreaWidget* DockArea) :
CFloatingDockContainer(DockArea->dockManager())
{
d->DockContainer->addDockArea(DockArea);
#ifdef Q_OS_LINUX
d->TitleBar->enableCloseButton(isClosable());
#endif
}
//============================================================================
CFloatingDockContainer::CFloatingDockContainer(CDockWidget* DockWidget) :
CFloatingDockContainer(DockWidget->dockManager())
CFloatingDockContainer(DockWidget->dockManager())
{
d->DockContainer->addDockWidget(CenterDockWidgetArea, DockWidget);
d->DockContainer->addDockWidget(CenterDockWidgetArea, DockWidget);
#ifdef Q_OS_LINUX
d->TitleBar->enableCloseButton(isClosable());
#endif
}
//============================================================================
@@ -290,7 +325,7 @@ void CFloatingDockContainer::changeEvent(QEvent *event)
void CFloatingDockContainer::moveEvent(QMoveEvent *event)
{
QWidget::moveEvent(event);
switch (d->DraggingState)
switch (d->DraggingState)
{
case DraggingMousePressed:
d->setState(DraggingFloatingWidget);
@@ -302,7 +337,7 @@ void CFloatingDockContainer::moveEvent(QMoveEvent *event)
break;
default:
break;
}
}
}
@@ -320,11 +355,18 @@ void CFloatingDockContainer::closeEvent(QCloseEvent *event)
// https://bugreports.qt.io/browse/QTBUG-73295
// The following code is a workaround for Qt versions > 5.9.2 that seems
// to work
#if (QT_VERSION > 0x050902)
// Starting from Qt version 5.12.2 this seems to work again. But
// now the QEvent::NonClientAreaMouseButtonPress function returns always
// Qt::RightButton even if the left button was pressed
#ifndef Q_OS_LINUX
#if (QT_VERSION > QT_VERSION_CHECK(5, 9, 2) && QT_VERSION < QT_VERSION_CHECK(5, 12, 2))
event->ignore();
this->hide();
#else
Super::closeEvent(event);
#endif
#else // Q_OS_LINUX
Super::closeEvent(event);
#endif
}
else
@@ -352,13 +394,6 @@ void CFloatingDockContainer::hideEvent(QHideEvent *event)
void CFloatingDockContainer::showEvent(QShowEvent *event)
{
Super::showEvent(event);
/*for (auto DockArea : d->DockContainer->openedDockAreas())
{
for (auto DockWidget : DockArea->openedDockWidgets())
{
DockWidget->setToggleViewActionChecked(true);
}
}*/
}
@@ -368,11 +403,28 @@ bool CFloatingDockContainer::event(QEvent *e)
switch (d->DraggingState)
{
case DraggingInactive:
if (e->type() == QEvent::NonClientAreaMouseButtonPress && QGuiApplication::mouseButtons() == Qt::LeftButton)
{
// 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 (e->type() == QEvent::NonClientAreaMouseButtonPress /*&& QGuiApplication::mouseButtons().testFlag(Qt::LeftButton)*/)
{
qDebug() << "FloatingWidget::event Event::NonClientAreaMouseButtonPress" << e->type();
d->setState(DraggingMousePressed);
}
#else
if (e->type() == QEvent::NonClientAreaMouseButtonPress && QGuiApplication::mouseButtons().testFlag(Qt::LeftButton))
{
qDebug() << "FloatingWidget::event Event::NonClientAreaMouseButtonPress" << e->type();
d->setState(DraggingMousePressed);
}
#endif
}
break;
case DraggingMousePressed:
@@ -425,12 +477,13 @@ bool CFloatingDockContainer::event(QEvent *e)
//============================================================================
bool CFloatingDockContainer::eventFilter(QObject *watched, QEvent *event)
{
Q_UNUSED(watched);
if (event->type() == QEvent::MouseButtonRelease && d->isState(DraggingFloatingWidget))
Q_UNUSED(watched);
if (event->type() == QEvent::MouseButtonRelease && d->isState(DraggingFloatingWidget))
{
qDebug() << "FloatingWidget::eventFilter QEvent::MouseButtonRelease";
finishDragging();
d->titleMouseReleaseEvent();
}
}
return false;
}
@@ -438,11 +491,26 @@ bool CFloatingDockContainer::eventFilter(QObject *watched, QEvent *event)
//============================================================================
void CFloatingDockContainer::startFloating(const QPoint& DragStartMousePos, const QSize& Size,
eDragState DragState)
eDragState DragState, QWidget* MouseEventHandler)
{
#ifndef Q_OS_LINUX
Q_UNUSED(MouseEventHandler)
#endif
resize(Size);
d->setState(DragState);
d->DragStartMousePosition = DragStartMousePos;
#ifdef Q_OS_LINUX
if (DraggingFloatingWidget == DragState)
{
setAttribute(Qt::WA_X11NetWmWindowTypeDock, true);
setWindowOpacity(0.6);
d->MouseEventHandler = MouseEventHandler;
if (d->MouseEventHandler)
{
d->MouseEventHandler->grabMouse();
}
}
#endif
moveFloating();
show();
@@ -454,7 +522,7 @@ void CFloatingDockContainer::moveFloating()
{
int BorderSize = (frameSize().width() - size().width()) / 2;
const QPoint moveToPos = QCursor::pos() - d->DragStartMousePosition - QPoint(BorderSize, 0);
move(moveToPos);
move(moveToPos);
}
@@ -473,7 +541,7 @@ void CFloatingDockContainer::onDockAreasAddedOrRemoved()
if (TopLevelDockArea)
{
d->SingleDockArea = TopLevelDockArea;
this->setWindowTitle(d->SingleDockArea->currentDockWidget()->windowTitle());
d->setWindowTitle(d->SingleDockArea->currentDockWidget()->windowTitle());
connect(d->SingleDockArea, SIGNAL(currentChanged(int)), this,
SLOT(onDockAreaCurrentChanged(int)));
}
@@ -485,7 +553,7 @@ void CFloatingDockContainer::onDockAreasAddedOrRemoved()
SLOT(onDockAreaCurrentChanged(int)));
d->SingleDockArea = nullptr;
}
this->setWindowTitle(qApp->applicationDisplayName());
d->setWindowTitle(qApp->applicationDisplayName());
}
}
@@ -496,11 +564,11 @@ void CFloatingDockContainer::updateWindowTitle()
auto TopLevelDockArea = d->DockContainer->topLevelDockArea();
if (TopLevelDockArea)
{
this->setWindowTitle(TopLevelDockArea->currentDockWidget()->windowTitle());
d->setWindowTitle(TopLevelDockArea->currentDockWidget()->windowTitle());
}
else
{
this->setWindowTitle(qApp->applicationDisplayName());
d->setWindowTitle(qApp->applicationDisplayName());
}
}
@@ -509,7 +577,7 @@ void CFloatingDockContainer::updateWindowTitle()
void CFloatingDockContainer::onDockAreaCurrentChanged(int Index)
{
Q_UNUSED(Index);
this->setWindowTitle(d->SingleDockArea->currentDockWidget()->windowTitle());
d->setWindowTitle(d->SingleDockArea->currentDockWidget()->windowTitle());
}
@@ -547,6 +615,24 @@ QList<CDockWidget*> CFloatingDockContainer::dockWidgets() const
}
//============================================================================
void CFloatingDockContainer::finishDragging()
{
qDebug() << "CFloatingDockContainer::finishDragging";
#ifdef Q_OS_LINUX
setAttribute(Qt::WA_X11NetWmWindowTypeDock, false);
setWindowOpacity(1);
activateWindow();
if (d->MouseEventHandler)
{
d->MouseEventHandler->releaseMouse();
d->MouseEventHandler = nullptr;
}
#endif
}
} // namespace ads
//---------------------------------------------------------------------------

View File

@@ -29,10 +29,16 @@
//============================================================================
// INCLUDES
//============================================================================
#include <QWidget>
#include "ads_globals.h"
#ifdef Q_OS_LINUX
#include <QDockWidget>
#define tFloatingWidgetBase QDockWidget
#else
#include <QWidget>
#define tFloatingWidgetBase QWidget
#endif
class QXmlStreamReader;
namespace ads
@@ -49,13 +55,14 @@ class CDockWidgetTab;
struct DockWidgetTabPrivate;
class CDockAreaTitleBar;
struct DockAreaTitleBarPrivate;
class CFloatingWidgetTitleBar;
/**
* This implements a floating widget that is a dock container that accepts
* docking of dock widgets like the main window and that can be docked into
* another dock container
*/
class ADS_EXPORT CFloatingDockContainer : public QWidget
class ADS_EXPORT CFloatingDockContainer : public tFloatingWidgetBase
{
Q_OBJECT
private:
@@ -70,6 +77,7 @@ private:
friend struct DockAreaTitleBarPrivate;
friend class CDockWidget;
friend class CDockAreaWidget;
friend class CFloatingWidgetTitleBar;
private slots:
void onDockAreasAddedOrRemoved();
@@ -82,23 +90,30 @@ protected:
* depending on the start position given in Pos parameter
*/
void startFloating(const QPoint& DragStartMousePos, const QSize& Size,
eDragState DragState);
eDragState DragState, QWidget* MouseEventHandler);
/**
* Call this function to start dragging the floating widget
*/
void startDragging(const QPoint& DragStartMousePos, const QSize& Size)
void startDragging(const QPoint& DragStartMousePos, const QSize& Size,
QWidget* MouseEventHandler)
{
startFloating(DragStartMousePos, Size, DraggingFloatingWidget);
startFloating(DragStartMousePos, Size, DraggingFloatingWidget, MouseEventHandler);
}
/**
* Call this function if you explecitely want to signal that dragging has
* finished
*/
void finishDragging();
/**
* Call this function if you just want to initialize the position
* and size of the floating widget
*/
void initFloatingGeometry(const QPoint& DragStartMousePos, const QSize& Size)
{
startFloating(DragStartMousePos, Size, DraggingInactive);
startFloating(DragStartMousePos, Size, DraggingInactive, nullptr);
}
/**

View File

@@ -3,5 +3,6 @@
<file>stylesheets/default.css</file>
<file>images/close-button.svg</file>
<file>images/close-button-disabled.svg</file>
<file>stylesheets/default_linux.css</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,187 @@
/*******************************************************************************
** Qt Advanced Docking System
** Copyright (C) 2017 Uwe Kindler
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with this library; If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
//============================================================================
/// \file FloatingWidgetTitleBar.cpp
/// \author Uwe Kindler
/// \date 13.05.2019
/// \brief Implementation of CFloatingWidgetTitleBar class
//============================================================================
//============================================================================
// INCLUDES
//============================================================================
#include "FloatingWidgetTitleBar.h"
#include <iostream>
#include <QHBoxLayout>
#include <QPushButton>
#include <QToolButton>
#include <QPixmap>
#include <QStyle>
#include <QMouseEvent>
#include "ads_globals.h"
#include "ElidingLabel.h"
#include "FloatingDockContainer.h"
namespace ads
{
using tTabLabel = CElidingLabel;
using tCloseButton = QPushButton;
/**
* @brief Private data class of public interface CFloatingWidgetTitleBar
*/
struct FloatingWidgetTitleBarPrivate
{
CFloatingWidgetTitleBar* _this; ///< public interface class
QLabel* IconLabel = nullptr;
tTabLabel* TitleLabel;
tCloseButton* CloseButton = nullptr;
CFloatingDockContainer* FloatingWidget = nullptr;
eDragState DragState = DraggingInactive;
FloatingWidgetTitleBarPrivate(CFloatingWidgetTitleBar* _public) : _this(_public) {}
/**
* Creates the complete layout including all controls
*/
void createLayout();
};
//============================================================================
void FloatingWidgetTitleBarPrivate::createLayout()
{
TitleLabel = new tTabLabel();
TitleLabel->setElideMode(Qt::ElideRight);
TitleLabel->setText("DockWidget->windowTitle()");
TitleLabel->setObjectName("floatingTitleLabel");
TitleLabel->setAlignment(Qt::AlignLeft);
CloseButton = new tCloseButton();
CloseButton->setObjectName("floatingTitleCloseButton");
CloseButton->setFlat(true);
//CloseButton->setAutoRaise(true);
// The standard icons do does not look good on high DPI screens
QIcon CloseIcon;
QPixmap normalPixmap = _this->style()->standardPixmap(QStyle::SP_TitleBarCloseButton, 0, CloseButton);
CloseIcon.addPixmap(normalPixmap, QIcon::Normal);
CloseIcon.addPixmap(internal::createTransparentPixmap(normalPixmap, 0.25), QIcon::Disabled);
CloseButton->setIcon(_this->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
CloseButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
CloseButton->setVisible(true);
CloseButton->setFocusPolicy(Qt::NoFocus);
_this->connect(CloseButton, SIGNAL(clicked()), SIGNAL(closeRequested()));
QFontMetrics fm(TitleLabel->font());
int Spacing = qRound(fm.height() / 4.0);
// Fill the layout
QBoxLayout* Layout = new QBoxLayout(QBoxLayout::LeftToRight);
Layout->setContentsMargins(6,0,0,0);
Layout->setSpacing(0);
_this->setLayout(Layout);
Layout->addWidget(TitleLabel, 1);
Layout->addSpacing(Spacing);
Layout->addWidget(CloseButton);
Layout->setAlignment(Qt::AlignCenter);
TitleLabel->setVisible(true);
}
//============================================================================
CFloatingWidgetTitleBar::CFloatingWidgetTitleBar(CFloatingDockContainer *parent)
: QWidget(parent),
d(new FloatingWidgetTitleBarPrivate(this))
{
d->FloatingWidget = parent;
d->createLayout();
}
//============================================================================
CFloatingWidgetTitleBar::~CFloatingWidgetTitleBar()
{
delete d;
}
//============================================================================
void CFloatingWidgetTitleBar::mousePressEvent(QMouseEvent* ev)
{
if (ev->button() == Qt::LeftButton)
{
d->DragState = DraggingFloatingWidget;
d->FloatingWidget->startDragging(ev->pos(), d->FloatingWidget->size(), this);
return;
}
Super::mousePressEvent(ev);
}
//============================================================================
void CFloatingWidgetTitleBar::mouseReleaseEvent(QMouseEvent* ev)
{
d->DragState = DraggingInactive;
Super::mouseReleaseEvent(ev);
}
//============================================================================
void CFloatingWidgetTitleBar::mouseMoveEvent(QMouseEvent* ev)
{
if (!(ev->buttons() & Qt::LeftButton) || DraggingInactive == d->DragState)
{
d->DragState = DraggingInactive;
Super::mouseMoveEvent(ev);
return;
}
// move floating window
if (DraggingFloatingWidget == d->DragState)
{
d->FloatingWidget->moveFloating();
Super::mouseMoveEvent(ev);
return;
}
Super::mouseMoveEvent(ev);
}
//============================================================================
void CFloatingWidgetTitleBar::enableCloseButton(bool Enable)
{
d->CloseButton->setEnabled(Enable);
}
//============================================================================
void CFloatingWidgetTitleBar::setTitle(const QString& Text)
{
d->TitleLabel->setText(Text);
}
} // namespace ads

View File

@@ -0,0 +1,68 @@
#ifndef FLOATINGWIDGETTITLEBAR_H
#define FLOATINGWIDGETTITLEBAR_H
/*******************************************************************************
** Qt Advanced Docking System
** Copyright (C) 2017 Uwe Kindler
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with this library; If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
//============================================================================
/// \file FloatingWidgetTitleBar.h
/// \author Uwe Kindler
/// \date 13.05.2019
/// \brief Declaration of CFloatingWidgetTitleBar class
//============================================================================
//============================================================================
// INCLUDES
//============================================================================
#include <QWidget>
namespace ads
{
class CFloatingDockContainer;
struct FloatingWidgetTitleBarPrivate;
class CFloatingWidgetTitleBar : public QWidget
{
Q_OBJECT
private:
FloatingWidgetTitleBarPrivate* d; ///< private data (pimpl)
protected:
virtual void mousePressEvent(QMouseEvent* ev) override;
virtual void mouseReleaseEvent(QMouseEvent* ev) override;
virtual void mouseMoveEvent(QMouseEvent* ev) override;
public:
using Super = QWidget;
explicit CFloatingWidgetTitleBar (CFloatingDockContainer *parent = nullptr);
/**
* Virtual Destructor
*/
virtual ~CFloatingWidgetTitleBar();
void enableCloseButton(bool Enable);
void setTitle(const QString& Text);
signals:
void closeRequested();
};
} // namespace ads
#endif // FLOATINGWIDGETTITLEBAR_H

View File

@@ -41,9 +41,8 @@ HEADERS += \
DockSplitter.h \
DockAreaTitleBar.h \
ElidingLabel.h
SOURCES += \
ads_globals.cpp \
DockAreaWidget.cpp \
@@ -58,6 +57,12 @@ SOURCES += \
DockAreaTitleBar.cpp \
ElidingLabel.cpp
unix {
HEADERS += linux/FloatingWidgetTitleBar.h
SOURCES += linux/FloatingWidgetTitleBar.cpp
}
isEmpty(PREFIX){
PREFIX=..\installed
warning("Install Prefix not set")
@@ -66,3 +71,5 @@ headers.path=$$PREFIX/include
headers.files=$$HEADERS
target.path=$$PREFIX/lib
INSTALLS += headers target
DISTFILES +=

View File

@@ -63,7 +63,7 @@ ads--CDockWidget
#closeButton,
#undockButton
{
padding: 0 -2px;
padding: 0px -2px;
}

View File

@@ -0,0 +1,96 @@
/*
* Default style sheet on Windows Platforms
* Note: Always use CSS-classes with and without "ads--" namespace to support Qt4 & Qt5
*/
ads--CDockContainerWidget
{
background: palette(dark);
}
ads--CDockContainerWidget QSplitter::handle
{
background: palette(dark);
}
ads--CDockAreaWidget
{
background: palette(window);
border: 1px solid white;
}
ads--CDockAreaWidget #tabsMenuButton::menu-indicator
{
image: none;
}
ads--CDockWidgetTab
{
background: palette(window);
border-color: palette(light);
border-style: solid;
border-width: 0 1px 0 0;
padding: 0 0px;
}
ads--CDockWidgetTab[activeTab="true"]
{
background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:0.5, stop:0 palette(window), stop:1 palette(light));
/*background: palette(highlight);*/
}
ads--CDockWidgetTab QLabel
{
color: palette(dark);
}
ads--CDockWidgetTab[activeTab="true"] QLabel
{
color: palette(foreground);
}
ads--CDockWidget
{
background: palette(light);
border-color: palette(light);
border-style: solid;
border-width: 1px 0 0 0;
}
#tabsMenuButton,
#closeButton,
#undockButton
{
padding: 0px -2px;
}
QScrollArea#dockWidgetScrollArea
{
padding: 0px;
border: none;
}
#tabCloseButton
{
margin-top: 2px;
background: none;
border: none;
padding: 0px -2px;
}
#tabCloseButton:hover
{
border: 1px solid rgba(0, 0, 0, 32);
background: rgba(0, 0, 0, 16);
}
#tabCloseButton:pressed
{
background: rgba(0, 0, 0, 32);
}