1
0
mirror of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git synced 2025-03-16 02:59:51 +08:00

Merge branch 'Central-Widget' of https://github.com/hulswit/Qt-Advanced-Docking-System into hulswit-Central-Widget

This commit is contained in:
Uwe Kindler 2020-08-24 09:50:12 +02:00
commit d383ade03c
19 changed files with 587 additions and 29 deletions

1
.gitignore vendored
View File

@ -382,3 +382,4 @@ MigrationBackup/
FodyWeavers.xsd FodyWeavers.xsd
/ build / build
/Settings.ini /Settings.ini
.vscode/settings.json

View File

@ -2,4 +2,5 @@ cmake_minimum_required(VERSION 3.5)
project(QtADSExamples LANGUAGES CXX VERSION ${VERSION_SHORT}) project(QtADSExamples LANGUAGES CXX VERSION ${VERSION_SHORT})
add_subdirectory(simple) add_subdirectory(simple)
add_subdirectory(sidebar) add_subdirectory(sidebar)
add_subdirectory(deleteonclose) add_subdirectory(deleteonclose)
add_subdirectory(centralWidget)

View File

@ -0,0 +1,25 @@
cmake_minimum_required(VERSION 3.5)
project(ads_example_centralwidget VERSION ${VERSION_SHORT})
find_package(Qt5 5.5 COMPONENTS Core Gui Widgets REQUIRED)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(CentralWidgetExample WIN32
main.cpp
mainwindow.cpp
mainwindow.ui
)
target_include_directories(CentralWidgetExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
target_link_libraries(CentralWidgetExample PRIVATE qtadvanceddocking)
target_link_libraries(CentralWidgetExample PUBLIC Qt5::Core Qt5::Gui Qt5::Widgets)
set_target_properties(CentralWidgetExample PROPERTIES
AUTOMOC ON
AUTORCC ON
AUTOUIC ON
CXX_STANDARD 14
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF
VERSION ${VERSION_SHORT}
EXPORT_NAME "Qt Advanced Docking System Central Widget Example"
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/bin"
)

View File

@ -0,0 +1,54 @@
ADS_OUT_ROOT = $${OUT_PWD}/../..
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = CentralWidgetExample
DESTDIR = $${ADS_OUT_ROOT}/lib
TEMPLATE = app
CONFIG += c++14
CONFIG += debug_and_release
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
LIBS += -L$${ADS_OUT_ROOT}/lib
# Dependency: AdvancedDockingSystem (shared)
CONFIG(debug, debug|release){
win32 {
LIBS += -lqtadvanceddockingd
}
else:mac {
LIBS += -lqtadvanceddocking_debug
}
else {
LIBS += -lqtadvanceddocking
}
}
else{
LIBS += -lqtadvanceddocking
}
INCLUDEPATH += ../../src
DEPENDPATH += ../../src

View File

@ -0,0 +1,11 @@
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
CMainWindow w;
w.show();
return a.exec();
}

View File

@ -0,0 +1,226 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QWidgetAction>
#include <QLabel>
#include <QCalendarWidget>
#include <QTreeView>
#include <QFileSystemModel>
#include <QTableWidget>
#include <QHBoxLayout>
#include <QRadioButton>
#include <QPushButton>
#include <QInputDialog>
#include <QFileDialog>
#include <QSettings>
#include <QMessageBox>
#include "DockAreaWidget.h"
#include "DockAreaTitleBar.h"
#include "DockAreaTabBar.h"
#include "FloatingDockContainer.h"
#include "DockComponentsFactory.h"
using namespace ads;
const QString CMainWindow::kTableTopLayout = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<QtAdvancedDockingSystem Version=\"1\" UserVersion=\"0\" Containers=\"1\">"
"<Container Floating=\"0\">"
"<Splitter Orientation=\"-\" Count=\"3\">"
"<Area Tabs=\"1\" Current=\"Timeline\" AllowedAreas=\"f\" Flags=\"1\">"
"<Widget Name=\"Timeline\" Closed=\"0\" />"
"</Area>"
"<Splitter Orientation=\"|\" Count=\"3\">"
"<Splitter Orientation=\"-\" Count=\"2\">"
"<Area Tabs=\"1\" Current=\"File system\">"
"<Widget Name=\"File system\" Closed=\"0\"/>"
"</Area>"
"<Area Tabs=\"1\" Current=\"Table\">"
"<Widget Name=\"Table\" Closed=\"0\"/>"
"</Area>"
"<Sizes>344 272 </Sizes>"
"</Splitter>"
"<Area Tabs=\"1\" Current=\"\" AllowedAreas=\"f\" Flags=\"1\">"
"<Widget Name=\"CentralWidget\" Closed=\"0\"/>"
"</Area>"
"<Area Tabs=\"1\" Current=\"Properties\">"
"<Widget Name=\"Properties\" Closed=\"0\"/>"
"</Area>"
"<Sizes>258 758 258 </Sizes>"
"</Splitter>"
"<Area Tabs=\"1\" Current=\"Status\" AllowedAreas=\"f\" Flags=\"1\">"
"<Widget Name=\"Status\" Closed=\"0\"/>"
"</Area>"
"<Sizes>52 621 52 </Sizes>"
"</Splitter>"
"</Container>"
"</QtAdvancedDockingSystem>";
const QString CMainWindow::kTableBottomLayout = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<QtAdvancedDockingSystem Version=\"1\" UserVersion=\"0\" Containers=\"1\">"
"<Container Floating=\"0\">"
"<Splitter Orientation=\"-\" Count=\"3\">"
"<Splitter Orientation=\"|\" Count=\"3\">"
"<Area Tabs=\"2\" Current=\"Table\">"
"<Widget Name=\"Table\" Closed=\"0\"/>"
"<Widget Name=\"File system\" Closed=\"0\"/>"
"</Area>"
"<Area Tabs=\"1\" Current=\"\" AllowedAreas=\"f\" Flags=\"1\">"
"<Widget Name=\"CentralWidget\" Closed=\"0\"/>"
"</Area>"
"<Area Tabs=\"1\" Current=\"Properties\">"
"<Widget Name=\"Properties\" Closed=\"0\"/>"
"</Area>"
"<Sizes>258 758 258 </Sizes>"
"</Splitter>"
"<Area Tabs=\"1\" Current=\"Timeline\" AllowedAreas=\"f\" Flags=\"1\">"
"<Widget Name=\"Timeline\" Closed=\"0\"/>"
"</Area>"
"<Area Tabs=\"1\" Current=\"Status\" AllowedAreas=\"f\" Flags=\"1\">"
"<Widget Name=\"Status\" Closed=\"0\"/>"
"</Area>"
"<Sizes>621 52 52 </Sizes>"
"</Splitter>"
"</Container>"
"</QtAdvancedDockingSystem>";
CMainWindow::CMainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::CMainWindow)
{
ui->setupUi(this);
CDockManager::setConfigFlag(CDockManager::OpaqueSplitterResize, true);
CDockManager::setConfigFlag(CDockManager::XmlCompressionEnabled, false);
DockManager = new CDockManager(this);
QCalendarWidget* calendar = new QCalendarWidget();
CDockWidget* CentralDockWidget = new CDockWidget("CentralWidget");
CentralDockWidget->setWidget(calendar);
auto* CentralDockArea = DockManager->setCentralWidget(CentralDockWidget);
CentralDockArea->setAllowedAreas(DockWidgetArea::OuterDockAreas);
QTreeView* fileTree = new QTreeView();
fileTree->setFrameShape(QFrame::NoFrame);
QFileSystemModel* fileModel = new QFileSystemModel(fileTree);
fileModel->setRootPath(QDir::currentPath());
fileTree->setModel(fileModel);
CDockWidget* DataDockWidget = new CDockWidget("File system");
DataDockWidget->setWidget(fileTree);
DataDockWidget->resize(150, 250);
DataDockWidget->setMinimumSize(100, 250);
auto* fileArea = DockManager->addDockWidget(DockWidgetArea::LeftDockWidgetArea, DataDockWidget, CentralDockArea);
QTableWidget* table = new QTableWidget();
table->setColumnCount(3);
table->setRowCount(10);
CDockWidget* TableDockWidget = new CDockWidget("Table");
TableDockWidget->setWidget(table);
TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
TableDockWidget->resize(250, 150);
TableDockWidget->setMinimumSize(200,150);
DockManager->addDockWidget(DockWidgetArea::BottomDockWidgetArea, TableDockWidget, fileArea);
QTableWidget* propertiesTable = new QTableWidget();
table->setColumnCount(3);
table->setRowCount(10);
CDockWidget* PropertiesDockWidget = new CDockWidget("Properties");
PropertiesDockWidget->setWidget(propertiesTable);
PropertiesDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
PropertiesDockWidget->resize(250, 150);
PropertiesDockWidget->setMinimumSize(200,150);
DockManager->addDockWidget(DockWidgetArea::RightDockWidgetArea, PropertiesDockWidget, CentralDockArea);
QWidget* timeLineWidget = new QWidget();
QHBoxLayout* timelineLayout = new QHBoxLayout(timeLineWidget);
QRadioButton* radioDockTop = new QRadioButton("Top", timeLineWidget);
QRadioButton* radioDockBottom = new QRadioButton("Bottom", timeLineWidget);
radioDockTop->setChecked(true);
timelineLayout->addWidget(new QLabel("Test Widget."));
timelineLayout->addStretch(1);
timelineLayout->addWidget(new QLabel("Apply predefined perspective: ", this));
timelineLayout->addWidget(radioDockTop);
timelineLayout->addWidget(radioDockBottom);
TimelineDockWidget = new CDockWidget("Timeline");
TimelineDockWidget->setWidget(timeLineWidget);
TimelineDockWidget->setFeature(CDockWidget::DockWidgetClosable, false);
TimelineDockWidget->setFeature(CDockWidget::DockWidgetMovable, false);
TimelineDockWidget->setFeature(CDockWidget::DockWidgetFloatable, false);
TimelineDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
TimelineDockWidget->setMinimumSize(QSize(50, 50));
auto *TimelineDockArea = DockManager->addDockWidget(DockWidgetArea::TopDockWidgetArea, TimelineDockWidget);
TimelineDockArea->setDockAreaFlag(CDockAreaWidget::eDockAreaFlag::HideSingleWidgetTitleBar, true);
TimelineDockArea->setAllowedAreas(DockWidgetArea::OuterDockAreas);
connect(radioDockTop, &QRadioButton::toggled, [this](bool checked){
bool ok = true;
if(!checked)
{
ok = DockManager->restoreState(kTableBottomLayout.toUtf8());
}
else
{
ok = DockManager->restoreState(kTableTopLayout.toUtf8());
}
if(!ok)
{
QMessageBox msgBox;
msgBox.setText("Failed to apply perspective!");
msgBox.exec();
}
});
QWidget* statusWidget = new QWidget();
QHBoxLayout* statusLayout = new QHBoxLayout(statusWidget);
statusLayout->setSpacing(10);
statusLayout->addWidget(new QLabel("Status Bar"));
QPushButton* OpenPerspectiveButton = new QPushButton("Open Perspective", statusWidget);
connect(OpenPerspectiveButton, &QPushButton::clicked, [this](){
QString PerspectiveName = QFileDialog::getOpenFileName(this, "Open Perspective", "", "Perspective files (*.xml)");
if (PerspectiveName.isEmpty())
{
return;
}
QFile stateFile(PerspectiveName);
stateFile.open(QIODevice::ReadOnly);
QByteArray state = stateFile.readAll();
stateFile.close();
if(!DockManager->restoreState(state))
{
QMessageBox msgBox;
msgBox.setText("Failed to apply perspective " + stateFile.fileName());
msgBox.exec();
}
});
QPushButton* SavePerspectiveButton = new QPushButton("Create Perspective", statusWidget);
connect(SavePerspectiveButton, &QPushButton::clicked, [this](){
QString PerspectiveName = QInputDialog::getText(this, "Save Perspective", "Enter unique name:");
if (PerspectiveName.isEmpty())
{
return;
}
QByteArray state = DockManager->saveState();
QFile stateFile(PerspectiveName + ".xml");
stateFile.open(QIODevice::WriteOnly);
stateFile.write(state);
stateFile.close();
});
statusLayout->addWidget(OpenPerspectiveButton);
statusLayout->addWidget(SavePerspectiveButton);
statusLayout->addStretch(1);
CDockWidget* StatusDockWidget = new CDockWidget("Status");
StatusDockWidget->setWidget(statusWidget);
StatusDockWidget->setFeature(CDockWidget::DockWidgetClosable, false);
StatusDockWidget->setFeature(CDockWidget::DockWidgetMovable, false);
StatusDockWidget->setFeature(CDockWidget::DockWidgetFloatable, false);
StatusDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
StatusDockWidget->setMinimumSize(QSize(50, 50));
StatusDockArea = DockManager->addDockWidget(DockWidgetArea::BottomDockWidgetArea, StatusDockWidget);
StatusDockArea->setAllowedAreas(DockWidgetArea::OuterDockAreas);
StatusDockArea->setDockAreaFlag(ads::CDockAreaWidget::eDockAreaFlag::HideSingleWidgetTitleBar, true);
}
CMainWindow::~CMainWindow()
{
delete ui;
}

View File

@ -0,0 +1,32 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "DockManager.h"
#include "DockAreaWidget.h"
#include "DockWidget.h"
QT_BEGIN_NAMESPACE
namespace Ui { class CMainWindow; }
QT_END_NAMESPACE
class CMainWindow : public QMainWindow
{
Q_OBJECT
public:
CMainWindow(QWidget *parent = nullptr);
~CMainWindow();
private:
static const QString kTableTopLayout;
static const QString kTableBottomLayout;
Ui::CMainWindow *ui;
ads::CDockManager* DockManager;
ads::CDockAreaWidget* StatusDockArea;
ads::CDockWidget* TimelineDockWidget;
};
#endif // MAINWINDOW_H

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CMainWindow</class>
<widget class="QMainWindow" name="CMainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1284</width>
<height>757</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget"/>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1284</width>
<height>21</height>
</rect>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -1,6 +1,7 @@
TEMPLATE = subdirs TEMPLATE = subdirs
SUBDIRS = \ SUBDIRS = \
centralwidget \
simple \ simple \
sidebar \ sidebar \
deleteonclose deleteonclose

View File

@ -452,6 +452,7 @@ void CDockAreaWidget::insertDockWidget(int index, CDockWidget* DockWidget,
DockWidget->toggleViewInternal(true); DockWidget->toggleViewInternal(true);
} }
d->updateTitleBarButtonStates(); d->updateTitleBarButtonStates();
updateTitleBarVisibility();
} }
@ -966,6 +967,16 @@ CDockAreaTitleBar* CDockAreaWidget::titleBar() const
} }
//============================================================================
bool CDockAreaWidget::isCentralWidgetArea()
{
if(dockWidgetsCount()!=1)
return false;
return dockManager()->centralWidget()==dockWidgets()[0];
}
//============================================================================ //============================================================================
QSize CDockAreaWidget::minimumSizeHint() const QSize CDockAreaWidget::minimumSizeHint() const
{ {

View File

@ -154,7 +154,7 @@ public:
}; };
Q_DECLARE_FLAGS(DockAreaFlags, eDockAreaFlag) Q_DECLARE_FLAGS(DockAreaFlags, eDockAreaFlag)
/** /**
* Default Constructor * Default Constructor
*/ */
CDockAreaWidget(CDockManager* DockManager, CDockContainerWidget* parent); CDockAreaWidget(CDockManager* DockManager, CDockContainerWidget* parent);
@ -307,6 +307,11 @@ public:
*/ */
void setDockAreaFlag(eDockAreaFlag Flag, bool On); void setDockAreaFlag(eDockAreaFlag Flag, bool On);
/**
* Returns true if the area contains the central widget of it's manager.
*/
bool isCentralWidgetArea();
public slots: public slots:
/** /**
* This activates the tab for the given tab index. * This activates the tab for the given tab index.

View File

@ -322,6 +322,17 @@ public:
Splitter->setSizes(SplitterSizes); Splitter->setSizes(SplitterSizes);
} }
/**
* This finction forces the dock container widget to update handles of splitters
* based on resize modes of dock widgets aontained in the container.
*/
void updateSplitterHandles(QSplitter* splitter);
/**
* This function returns true if the area is not allowed to resize in the direstion
* of the splitter. Otherwise returns true.
*/
bool widgetResizesWithContainer(QWidget* widget);
// private slots: ------------------------------------------------------------ // private slots: ------------------------------------------------------------
void onDockAreaViewToggled(bool Visible) void onDockAreaViewToggled(bool Visible)
@ -421,7 +432,8 @@ void DockContainerWidgetPrivate::dropIntoContainer(CFloatingDockContainer* Float
QSplitter* NewSplitter = newSplitter(InsertParam.orientation()); QSplitter* NewSplitter = newSplitter(InsertParam.orientation());
QLayoutItem* li = Layout->replaceWidget(Splitter, NewSplitter); QLayoutItem* li = Layout->replaceWidget(Splitter, NewSplitter);
NewSplitter->addWidget(Splitter); NewSplitter->addWidget(Splitter);
Splitter = NewSplitter; updateSplitterHandles(NewSplitter);
Splitter = NewSplitter;
delete li; delete li;
} }
@ -430,19 +442,21 @@ void DockContainerWidgetPrivate::dropIntoContainer(CFloatingDockContainer* Float
if (FloatingSplitter->count() == 1) if (FloatingSplitter->count() == 1)
{ {
insertWidgetIntoSplitter(Splitter, FloatingSplitter->widget(0), InsertParam.append()); insertWidgetIntoSplitter(Splitter, FloatingSplitter->widget(0), InsertParam.append());
} updateSplitterHandles(Splitter);
}
else if (FloatingSplitter->orientation() == InsertParam.orientation()) else if (FloatingSplitter->orientation() == InsertParam.orientation())
{ {
int InsertIndex = InsertParam.append() ? Splitter->count() : 0; int InsertIndex = InsertParam.append() ? Splitter->count() : 0;
while (FloatingSplitter->count()) while (FloatingSplitter->count())
{ {
Splitter->insertWidget(InsertIndex++, FloatingSplitter->widget(0)); Splitter->insertWidget(InsertIndex++, FloatingSplitter->widget(0));
} updateSplitterHandles(Splitter);
} }
}
else else
{ {
insertWidgetIntoSplitter(Splitter, FloatingSplitter, InsertParam.append()); insertWidgetIntoSplitter(Splitter, FloatingSplitter, InsertParam.append());
} }
RootSplitter = Splitter; RootSplitter = Splitter;
addDockAreasToList(NewDockAreas); addDockAreasToList(NewDockAreas);
@ -453,7 +467,7 @@ void DockContainerWidgetPrivate::dropIntoContainer(CFloatingDockContainer* Float
if (!Splitter->isVisible()) if (!Splitter->isVisible())
{ {
Splitter->show(); Splitter->show();
} }
_this->dumpLayout(); _this->dumpLayout();
} }
@ -515,7 +529,8 @@ void DockContainerWidgetPrivate::dropIntoSection(CFloatingDockContainer* Floatin
QSplitter* Splitter = newSplitter(InsertParam.orientation()); QSplitter* Splitter = newSplitter(InsertParam.orientation());
Layout->replaceWidget(TargetArea, Splitter); Layout->replaceWidget(TargetArea, Splitter);
Splitter->addWidget(TargetArea); Splitter->addWidget(TargetArea);
TargetAreaSplitter = Splitter; updateSplitterHandles(Splitter);
TargetAreaSplitter = Splitter;
} }
int AreaIndex = TargetAreaSplitter->indexOf(TargetArea); int AreaIndex = TargetAreaSplitter->indexOf(TargetArea);
auto Widget = FloatingWidget->dockContainer()->findChild<QWidget*>(QString(), Qt::FindDirectChildrenOnly); auto Widget = FloatingWidget->dockContainer()->findChild<QWidget*>(QString(), Qt::FindDirectChildrenOnly);
@ -529,7 +544,8 @@ void DockContainerWidgetPrivate::dropIntoSection(CFloatingDockContainer* Floatin
if ((FloatingSplitter->orientation() != InsertParam.orientation()) && FloatingSplitter->count() > 1) if ((FloatingSplitter->orientation() != InsertParam.orientation()) && FloatingSplitter->count() > 1)
{ {
TargetAreaSplitter->insertWidget(AreaIndex + InsertParam.insertOffset(), Widget); TargetAreaSplitter->insertWidget(AreaIndex + InsertParam.insertOffset(), Widget);
} updateSplitterHandles(TargetAreaSplitter);
}
else else
{ {
AdjustSplitterSizes = (FloatingSplitter->count() == 1); AdjustSplitterSizes = (FloatingSplitter->count() == 1);
@ -537,8 +553,9 @@ void DockContainerWidgetPrivate::dropIntoSection(CFloatingDockContainer* Floatin
while (FloatingSplitter->count()) while (FloatingSplitter->count())
{ {
TargetAreaSplitter->insertWidget(InsertIndex++, FloatingSplitter->widget(0)); TargetAreaSplitter->insertWidget(InsertIndex++, FloatingSplitter->widget(0));
} updateSplitterHandles(TargetAreaSplitter);
} }
}
if (AdjustSplitterSizes) if (AdjustSplitterSizes)
{ {
@ -557,28 +574,32 @@ void DockContainerWidgetPrivate::dropIntoSection(CFloatingDockContainer* Floatin
if ((FloatingSplitter->orientation() != InsertParam.orientation()) && FloatingSplitter->count() > 1) if ((FloatingSplitter->orientation() != InsertParam.orientation()) && FloatingSplitter->count() > 1)
{ {
NewSplitter->addWidget(Widget); NewSplitter->addWidget(Widget);
} updateSplitterHandles(NewSplitter);
}
else else
{ {
AdjustSplitterSizes = (FloatingSplitter->count() == 1); AdjustSplitterSizes = (FloatingSplitter->count() == 1);
while (FloatingSplitter->count()) while (FloatingSplitter->count())
{ {
NewSplitter->addWidget(FloatingSplitter->widget(0)); NewSplitter->addWidget(FloatingSplitter->widget(0));
} updateSplitterHandles(NewSplitter);
} }
}
// Save the sizes before insertion and restore it later to prevent // Save the sizes before insertion and restore it later to prevent
// shrinking of existing area // shrinking of existing area
auto Sizes = TargetAreaSplitter->sizes(); auto Sizes = TargetAreaSplitter->sizes();
insertWidgetIntoSplitter(NewSplitter, TargetArea, !InsertParam.append()); insertWidgetIntoSplitter(NewSplitter, TargetArea, !InsertParam.append());
if (AdjustSplitterSizes) updateSplitterHandles(NewSplitter);
if (AdjustSplitterSizes)
{ {
int Size = TargetAreaSize / 2; int Size = TargetAreaSize / 2;
NewSplitter->setSizes({Size, Size}); NewSplitter->setSizes({Size, Size});
} }
TargetAreaSplitter->insertWidget(AreaIndex, NewSplitter); TargetAreaSplitter->insertWidget(AreaIndex, NewSplitter);
TargetAreaSplitter->setSizes(Sizes); TargetAreaSplitter->setSizes(Sizes);
} updateSplitterHandles(TargetAreaSplitter);
}
addDockAreasToList(NewDockAreas); addDockAreasToList(NewDockAreas);
_this->dumpLayout(); _this->dumpLayout();
@ -663,7 +684,8 @@ void DockContainerWidgetPrivate::moveToNewSection(QWidget* Widget, CDockAreaWidg
{ {
int TargetAreaSize = (InsertParam.orientation() == Qt::Horizontal) ? TargetArea->width() : TargetArea->height(); int TargetAreaSize = (InsertParam.orientation() == Qt::Horizontal) ? TargetArea->width() : TargetArea->height();
TargetAreaSplitter->insertWidget(AreaIndex + InsertParam.insertOffset(), NewDockArea); TargetAreaSplitter->insertWidget(AreaIndex + InsertParam.insertOffset(), NewDockArea);
int Size = (TargetAreaSize - TargetAreaSplitter->handleWidth()) / 2; updateSplitterHandles(TargetAreaSplitter);
int Size = (TargetAreaSize - TargetAreaSplitter->handleWidth()) / 2;
Sizes[AreaIndex] = Size; Sizes[AreaIndex] = Size;
Sizes.insert(AreaIndex, Size); Sizes.insert(AreaIndex, Size);
} }
@ -674,16 +696,57 @@ void DockContainerWidgetPrivate::moveToNewSection(QWidget* Widget, CDockAreaWidg
QSplitter* NewSplitter = newSplitter(InsertParam.orientation()); QSplitter* NewSplitter = newSplitter(InsertParam.orientation());
NewSplitter->addWidget(TargetArea); NewSplitter->addWidget(TargetArea);
insertWidgetIntoSplitter(NewSplitter, NewDockArea, InsertParam.append()); insertWidgetIntoSplitter(NewSplitter, NewDockArea, InsertParam.append());
int Size = TargetAreaSize / 2; updateSplitterHandles(NewSplitter);
int Size = TargetAreaSize / 2;
NewSplitter->setSizes({Size, Size}); NewSplitter->setSizes({Size, Size});
TargetAreaSplitter->insertWidget(AreaIndex, NewSplitter); TargetAreaSplitter->insertWidget(AreaIndex, NewSplitter);
} updateSplitterHandles(TargetAreaSplitter);
}
TargetAreaSplitter->setSizes(Sizes); TargetAreaSplitter->setSizes(Sizes);
addDockAreasToList({NewDockArea}); addDockAreasToList({NewDockArea});
} }
//============================================================================
void DockContainerWidgetPrivate::updateSplitterHandles( QSplitter* splitter )
{
if(DockManager->centralWidget())
{
if( splitter )
{
for( int index = 0; index < splitter->count(); index++ )
{
splitter->setStretchFactor(index, widgetResizesWithContainer(splitter->widget(index)) ? 1 : 0);
}
}
}
}
//============================================================================
bool DockContainerWidgetPrivate::widgetResizesWithContainer(QWidget* widget)
{
if(!DockManager->centralWidget())
return true;
CDockAreaWidget* Area = dynamic_cast< CDockAreaWidget* >( widget );
if(Area)
{
return Area->isCentralWidgetArea();
}
CDockSplitter* innerSplitter = dynamic_cast< CDockSplitter* >( widget );
if(innerSplitter)
{
return innerSplitter->resizeWithContainer();
}
return false;
}
//============================================================================ //============================================================================
void DockContainerWidgetPrivate::moveToContainer(QWidget* Widget, DockWidgetArea area) void DockContainerWidgetPrivate::moveToContainer(QWidget* Widget, DockWidgetArea area)
{ {
@ -892,6 +955,10 @@ bool DockContainerWidgetPrivate::restoreSplitter(CDockingStateReader& s,
Splitter->addWidget(ChildNode); Splitter->addWidget(ChildNode);
Visible |= ChildNode->isVisibleTo(Splitter); Visible |= ChildNode->isVisibleTo(Splitter);
} }
if(!Testing)
{
updateSplitterHandles(Splitter);
}
if (Sizes.count() != WidgetCount) if (Sizes.count() != WidgetCount)
{ {
@ -1069,7 +1136,8 @@ void DockContainerWidgetPrivate::addDockArea(CDockAreaWidget* NewDockArea, DockW
if (Splitter->orientation() == InsertParam.orientation()) if (Splitter->orientation() == InsertParam.orientation())
{ {
insertWidgetIntoSplitter(Splitter, NewDockArea, InsertParam.append()); insertWidgetIntoSplitter(Splitter, NewDockArea, InsertParam.append());
if (Splitter->isHidden()) updateSplitterHandles(Splitter);
if (Splitter->isHidden())
{ {
Splitter->show(); Splitter->show();
} }
@ -1082,14 +1150,16 @@ void DockContainerWidgetPrivate::addDockArea(CDockAreaWidget* NewDockArea, DockW
QLayoutItem* li = Layout->replaceWidget(Splitter, NewSplitter); QLayoutItem* li = Layout->replaceWidget(Splitter, NewSplitter);
NewSplitter->addWidget(Splitter); NewSplitter->addWidget(Splitter);
NewSplitter->addWidget(NewDockArea); NewSplitter->addWidget(NewDockArea);
delete li; updateSplitterHandles(NewSplitter);
delete li;
} }
else else
{ {
NewSplitter->addWidget(NewDockArea); NewSplitter->addWidget(NewDockArea);
QLayoutItem* li = Layout->replaceWidget(Splitter, NewSplitter); QLayoutItem* li = Layout->replaceWidget(Splitter, NewSplitter);
NewSplitter->addWidget(Splitter); NewSplitter->addWidget(Splitter);
delete li; updateSplitterHandles(NewSplitter);
delete li;
} }
RootSplitter = NewSplitter; RootSplitter = NewSplitter;
} }
@ -1175,7 +1245,8 @@ CDockAreaWidget* DockContainerWidgetPrivate::addDockWidgetToDockArea(DockWidgetA
{ {
ADS_PRINT("TargetAreaSplitter->orientation() == InsertParam.orientation()"); ADS_PRINT("TargetAreaSplitter->orientation() == InsertParam.orientation()");
TargetAreaSplitter->insertWidget(index + InsertParam.insertOffset(), NewDockArea); TargetAreaSplitter->insertWidget(index + InsertParam.insertOffset(), NewDockArea);
// do nothing, if flag is not enabled updateSplitterHandles(TargetAreaSplitter);
// do nothing, if flag is not enabled
if (CDockManager::testConfigFlag(CDockManager::EqualSplitOnInsertion)) if (CDockManager::testConfigFlag(CDockManager::EqualSplitOnInsertion))
{ {
adjustSplitterSizesOnInsertion(TargetAreaSplitter); adjustSplitterSizesOnInsertion(TargetAreaSplitter);
@ -1190,9 +1261,11 @@ CDockAreaWidget* DockContainerWidgetPrivate::addDockWidgetToDockArea(DockWidgetA
NewSplitter->addWidget(TargetDockArea); NewSplitter->addWidget(TargetDockArea);
insertWidgetIntoSplitter(NewSplitter, NewDockArea, InsertParam.append()); insertWidgetIntoSplitter(NewSplitter, NewDockArea, InsertParam.append());
TargetAreaSplitter->insertWidget(index, NewSplitter); updateSplitterHandles(NewSplitter);
if (CDockManager::testConfigFlag(CDockManager::EqualSplitOnInsertion)) TargetAreaSplitter->insertWidget(index, NewSplitter);
{ updateSplitterHandles(TargetAreaSplitter);
if (CDockManager::testConfigFlag(CDockManager::EqualSplitOnInsertion))
{
TargetAreaSplitter->setSizes(TargetAreaSizes); TargetAreaSplitter->setSizes(TargetAreaSizes);
adjustSplitterSizesOnInsertion(NewSplitter); adjustSplitterSizesOnInsertion(NewSplitter);
} }
@ -1381,9 +1454,11 @@ void CDockContainerWidget::removeDockArea(CDockAreaWidget* area)
} }
delete Splitter; delete Splitter;
Splitter = nullptr;
emitAndExit: emitAndExit:
CDockWidget* TopLevelWidget = topLevelDockWidget(); updateSplitterHandles(Splitter);
CDockWidget* TopLevelWidget = topLevelDockWidget();
// Updated the title bar visibility of the dock widget if there is only // Updated the title bar visibility of the dock widget if there is only
// one single visible dock widget // one single visible dock widget
@ -1732,6 +1807,13 @@ QList<CDockWidget*> CDockContainerWidget::dockWidgets() const
} }
//============================================================================
void CDockContainerWidget::updateSplitterHandles(QSplitter* splitter)
{
d->updateSplitterHandles(splitter);
}
//============================================================================ //============================================================================
CDockWidget::DockWidgetFeatures CDockContainerWidget::features() const CDockWidget::DockWidgetFeatures CDockContainerWidget::features() const
{ {

View File

@ -155,6 +155,12 @@ protected:
*/ */
QList<CDockWidget*> dockWidgets() const; QList<CDockWidget*> dockWidgets() const;
/**
* This finction forces the dock container widget to update handles of splitters
* based on resize modes of dock widgets aontained in the container.
*/
void updateSplitterHandles(QSplitter* splitter);
public: public:
/** /**
* Default Constructor * Default Constructor

View File

@ -108,6 +108,7 @@ struct DockManagerPrivate
bool RestoringState = false; bool RestoringState = false;
QVector<CFloatingDockContainer*> UninitializedFloatingWidgets; QVector<CFloatingDockContainer*> UninitializedFloatingWidgets;
CDockFocusController* FocusController = nullptr; CDockFocusController* FocusController = nullptr;
CDockWidget* CentralWidget = nullptr;
/** /**
* Private data constructor * Private data constructor
@ -406,6 +407,7 @@ bool DockManagerPrivate::restoreState(const QByteArray& State, int version)
return false; return false;
} }
CentralWidget = nullptr;
// Hide updates of floating widgets from use // Hide updates of floating widgets from use
hideFloatingWidgets(); hideFloatingWidgets();
markDockWidgetsDirty(); markDockWidgetsDirty();
@ -829,6 +831,33 @@ void CDockManager::loadPerspectives(QSettings& Settings)
Settings.endArray(); Settings.endArray();
} }
CDockWidget* CDockManager::centralWidget()
{
return d->CentralWidget;
}
//============================================================================
CDockAreaWidget* CDockManager::setCentralWidget(CDockWidget* widget, CDockWidget* oldCentralWidget, DockWidgetArea oldCentralWidgetArea)
{
oldCentralWidget = d->CentralWidget;
if(oldCentralWidget)
{
addDockWidget(oldCentralWidgetArea, oldCentralWidget);
}
if(widget)
{
widget->setFeature(CDockWidget::DockWidgetClosable, false);
widget->setFeature(CDockWidget::DockWidgetMovable, false);
widget->setFeature(CDockWidget::DockWidgetFloatable, false);
d->CentralWidget = widget;
CDockAreaWidget* CentralArea = addDockWidget(CenterDockWidgetArea, widget);
CentralArea->setDockAreaFlag(CDockAreaWidget::eDockAreaFlag::HideSingleWidgetTitleBar, true);
return CentralArea;
}
return nullptr;
}
//============================================================================ //============================================================================
QAction* CDockManager::addToggleViewActionToMenu(QAction* ToggleViewAction, QAction* CDockManager::addToggleViewActionToMenu(QAction* ToggleViewAction,
const QString& Group, const QIcon& GroupIcon) const QString& Group, const QIcon& GroupIcon)

View File

@ -378,7 +378,21 @@ public:
*/ */
void loadPerspectives(QSettings& Settings); void loadPerspectives(QSettings& Settings);
/** /**
* This function returns managers central widget or nullptr if no central widget is set.
*/
CDockWidget* centralWidget();
/**
* Adds dockwidget into the central area and marks it as central widget.
* If central widget is set, it will be the only dock widget
* that will resize with the dock container.
* If a central widget does exist, it will be docked to oldCentralWidgetArea
* and returned in oldCentralWidget.
*/
CDockAreaWidget* setCentralWidget(CDockWidget* widget, CDockWidget* oldCentralWidget = nullptr, DockWidgetArea oldCentralWidgetArea = DockWidgetArea::RightDockWidgetArea);
/**
* Adds a toggle view action to the the internal view menu. * Adds a toggle view action to the the internal view menu.
* You can either manage the insertion of the toggle view actions in your * You can either manage the insertion of the toggle view actions in your
* application or you can add the actions to the internal view menu and * application or you can add the actions to the internal view menu and

View File

@ -102,6 +102,20 @@ QWidget* CDockSplitter::lastWidget() const
return (count() > 0) ? widget(count() - 1) : nullptr; return (count() > 0) ? widget(count() - 1) : nullptr;
} }
//============================================================================
bool CDockSplitter::resizeWithContainer()
{
QList<CDockAreaWidget *> areas = findChildren<CDockAreaWidget *>();
for(int i=0; i<areas.size(); i++)
{
CDockAreaWidget* area = areas.at(i);
if(area->isCentralWidgetArea())
return true;
}
return false;
}
} // namespace ads } // namespace ads
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@ -71,6 +71,11 @@ public:
* Returns last widget of nullptr is splitter is empty * Returns last widget of nullptr is splitter is empty
*/ */
QWidget* lastWidget() const; QWidget* lastWidget() const;
/**
* Returns true if the splitter contains central widget of dock manager.
*/
bool resizeWithContainer();
}; // class CDockSplitter }; // class CDockSplitter
} // namespace ads } // namespace ads

View File

@ -463,6 +463,12 @@ void CDockWidget::setMinimumSizeHintMode(eMinimumSizeHintMode Mode)
} }
bool CDockWidget::isCentralWidget()
{
return dockManager()->centralWidget() == this;
}
//============================================================================ //============================================================================
void CDockWidget::toggleView(bool Open) void CDockWidget::toggleView(bool Open)
{ {

View File

@ -360,6 +360,11 @@ public:
*/ */
void setMinimumSizeHintMode(eMinimumSizeHintMode Mode); void setMinimumSizeHintMode(eMinimumSizeHintMode Mode);
/**
* Returns true if the dock wisget is set as central widget of it's dock manager
*/
bool isCentralWidget();
/** /**
* Sets the dock widget icon that is shown in tabs and in toggle view * Sets the dock widget icon that is shown in tabs and in toggle view
* actions * actions