Central Widget concept added

Adde option to set a dock widget as central widget. It influences resizing behavior of the splitters. The central widget will be stretched with the main window and remaing dock widgets and threir respective areas will be resized only vertically if docked left or right  and horizontaly if docked top or bottom
This commit is contained in:
hulswit 2020-08-20 16:36:02 +02:00
parent c44d0c87e3
commit 1a11e5ddcd
20 changed files with 629 additions and 29 deletions

View File

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

View File

@ -0,0 +1,26 @@
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
digitalclock.cpp
)
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,56 @@
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 += \
digitalclock.cpp \
main.cpp \
mainwindow.cpp
HEADERS += \
digitalclock.h \
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,27 @@
#include "digitalclock.h"
#include <QTime>
#include <QTimer>
CDigitalClock::CDigitalClock(QWidget *parent)
: QLCDNumber(parent)
{
setDigitCount(8);
setSegmentStyle(Filled);
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &CDigitalClock::showTime);
timer->start(1000);
showTime();
setWindowTitle(tr("Digital Clock"));
resize(150, 60);
}
void CDigitalClock::showTime()
{
QTime time = QTime::currentTime();
QString text = time.toString("hh:mm:ss");
display(text);
}

View File

@ -0,0 +1,17 @@
#ifndef DIGITALCLOCK_H
#define DIGITALCLOCK_H
#include <QLCDNumber>
class CDigitalClock : public QLCDNumber
{
Q_OBJECT
public:
CDigitalClock(QWidget *parent = nullptr);
private slots:
void showTime();
};
#endif // DIGITALCLOCK_H

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,237 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "digitalclock.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);
CentralDockWidget->setFeature(CDockWidget::DockWidgetClosable, false);
CentralDockWidget->setFeature(CDockWidget::DockWidgetMovable, false);
CentralDockWidget->setFeature(CDockWidget::DockWidgetFloatable, false);
auto* CentralDockArea = DockManager->setCentralWidget(CentralDockWidget);
CentralDockArea->setAllowedAreas(DockWidgetArea::OuterDockAreas);
CentralDockArea->setDockAreaFlag(CDockAreaWidget::eDockAreaFlag::HideSingleWidgetTitleBar, true);
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("Fixed height Dock 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->setResizeMode(CDockWidget::eResizeMode::ResizeHorizontal);
TimelineDockWidget->setFeature(CDockWidget::DockWidgetClosable, false);
TimelineDockWidget->setFeature(CDockWidget::DockWidgetMovable, false);
TimelineDockWidget->setFeature(CDockWidget::DockWidgetFloatable, false);
TimelineDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
TimelineDockWidget->setMinimumSize(QSize(50, 50));
TimelineDockWidget->setFixedHeight(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);
CDigitalClock* clock = new CDigitalClock(statusWidget);
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);
statusLayout->addWidget(clock);
CDockWidget* StatusDockWidget = new CDockWidget("Status");
StatusDockWidget->setWidget(statusWidget);
// StatusDockWidget->setResizeMode(CDockWidget::eResizeMode::ResizeHorizontal);
StatusDockWidget->setFeature(CDockWidget::DockWidgetClosable, false);
StatusDockWidget->setFeature(CDockWidget::DockWidgetMovable, false);
StatusDockWidget->setFeature(CDockWidget::DockWidgetFloatable, false);
StatusDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
StatusDockWidget->setMinimumSize(QSize(50, 50));
StatusDockWidget->setFixedHeight(50);
StatusDockArea = DockManager->addDockWidget(DockWidgetArea::BottomDockWidgetArea, StatusDockWidget);
StatusDockArea->setAllowedAreas(DockWidgetArea::OuterDockAreas);
StatusDockArea->setDockAreaFlag(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
SUBDIRS = \
centralwidget \
simple \
sidebar \
deleteonclose

View File

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

View File

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

View File

@ -322,6 +322,17 @@ public:
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: ------------------------------------------------------------
void onDockAreaViewToggled(bool Visible)
@ -421,7 +432,8 @@ void DockContainerWidgetPrivate::dropIntoContainer(CFloatingDockContainer* Float
QSplitter* NewSplitter = newSplitter(InsertParam.orientation());
QLayoutItem* li = Layout->replaceWidget(Splitter, NewSplitter);
NewSplitter->addWidget(Splitter);
Splitter = NewSplitter;
updateSplitterHandles(NewSplitter);
Splitter = NewSplitter;
delete li;
}
@ -430,19 +442,21 @@ void DockContainerWidgetPrivate::dropIntoContainer(CFloatingDockContainer* Float
if (FloatingSplitter->count() == 1)
{
insertWidgetIntoSplitter(Splitter, FloatingSplitter->widget(0), InsertParam.append());
}
updateSplitterHandles(Splitter);
}
else if (FloatingSplitter->orientation() == InsertParam.orientation())
{
int InsertIndex = InsertParam.append() ? Splitter->count() : 0;
while (FloatingSplitter->count())
{
Splitter->insertWidget(InsertIndex++, FloatingSplitter->widget(0));
}
}
updateSplitterHandles(Splitter);
}
}
else
{
insertWidgetIntoSplitter(Splitter, FloatingSplitter, InsertParam.append());
}
}
RootSplitter = Splitter;
addDockAreasToList(NewDockAreas);
@ -453,7 +467,7 @@ void DockContainerWidgetPrivate::dropIntoContainer(CFloatingDockContainer* Float
if (!Splitter->isVisible())
{
Splitter->show();
}
}
_this->dumpLayout();
}
@ -515,7 +529,8 @@ void DockContainerWidgetPrivate::dropIntoSection(CFloatingDockContainer* Floatin
QSplitter* Splitter = newSplitter(InsertParam.orientation());
Layout->replaceWidget(TargetArea, Splitter);
Splitter->addWidget(TargetArea);
TargetAreaSplitter = Splitter;
updateSplitterHandles(Splitter);
TargetAreaSplitter = Splitter;
}
int AreaIndex = TargetAreaSplitter->indexOf(TargetArea);
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)
{
TargetAreaSplitter->insertWidget(AreaIndex + InsertParam.insertOffset(), Widget);
}
updateSplitterHandles(TargetAreaSplitter);
}
else
{
AdjustSplitterSizes = (FloatingSplitter->count() == 1);
@ -537,8 +553,9 @@ void DockContainerWidgetPrivate::dropIntoSection(CFloatingDockContainer* Floatin
while (FloatingSplitter->count())
{
TargetAreaSplitter->insertWidget(InsertIndex++, FloatingSplitter->widget(0));
}
}
updateSplitterHandles(TargetAreaSplitter);
}
}
if (AdjustSplitterSizes)
{
@ -557,28 +574,32 @@ void DockContainerWidgetPrivate::dropIntoSection(CFloatingDockContainer* Floatin
if ((FloatingSplitter->orientation() != InsertParam.orientation()) && FloatingSplitter->count() > 1)
{
NewSplitter->addWidget(Widget);
}
updateSplitterHandles(NewSplitter);
}
else
{
AdjustSplitterSizes = (FloatingSplitter->count() == 1);
while (FloatingSplitter->count())
{
NewSplitter->addWidget(FloatingSplitter->widget(0));
}
}
updateSplitterHandles(NewSplitter);
}
}
// Save the sizes before insertion and restore it later to prevent
// shrinking of existing area
auto Sizes = TargetAreaSplitter->sizes();
insertWidgetIntoSplitter(NewSplitter, TargetArea, !InsertParam.append());
if (AdjustSplitterSizes)
updateSplitterHandles(NewSplitter);
if (AdjustSplitterSizes)
{
int Size = TargetAreaSize / 2;
NewSplitter->setSizes({Size, Size});
}
TargetAreaSplitter->insertWidget(AreaIndex, NewSplitter);
TargetAreaSplitter->setSizes(Sizes);
}
updateSplitterHandles(TargetAreaSplitter);
}
addDockAreasToList(NewDockAreas);
_this->dumpLayout();
@ -663,7 +684,8 @@ void DockContainerWidgetPrivate::moveToNewSection(QWidget* Widget, CDockAreaWidg
{
int TargetAreaSize = (InsertParam.orientation() == Qt::Horizontal) ? TargetArea->width() : TargetArea->height();
TargetAreaSplitter->insertWidget(AreaIndex + InsertParam.insertOffset(), NewDockArea);
int Size = (TargetAreaSize - TargetAreaSplitter->handleWidth()) / 2;
updateSplitterHandles(TargetAreaSplitter);
int Size = (TargetAreaSize - TargetAreaSplitter->handleWidth()) / 2;
Sizes[AreaIndex] = Size;
Sizes.insert(AreaIndex, Size);
}
@ -674,16 +696,54 @@ void DockContainerWidgetPrivate::moveToNewSection(QWidget* Widget, CDockAreaWidg
QSplitter* NewSplitter = newSplitter(InsertParam.orientation());
NewSplitter->addWidget(TargetArea);
insertWidgetIntoSplitter(NewSplitter, NewDockArea, InsertParam.append());
int Size = TargetAreaSize / 2;
updateSplitterHandles(NewSplitter);
int Size = TargetAreaSize / 2;
NewSplitter->setSizes({Size, Size});
TargetAreaSplitter->insertWidget(AreaIndex, NewSplitter);
}
updateSplitterHandles(TargetAreaSplitter);
}
TargetAreaSplitter->setSizes(Sizes);
addDockAreasToList({NewDockArea});
}
//============================================================================
void DockContainerWidgetPrivate::updateSplitterHandles( QSplitter* splitter )
{
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)
{
@ -892,6 +952,10 @@ bool DockContainerWidgetPrivate::restoreSplitter(CDockingStateReader& s,
Splitter->addWidget(ChildNode);
Visible |= ChildNode->isVisibleTo(Splitter);
}
if(!Testing)
{
updateSplitterHandles(Splitter);
}
if (Sizes.count() != WidgetCount)
{
@ -1069,7 +1133,8 @@ void DockContainerWidgetPrivate::addDockArea(CDockAreaWidget* NewDockArea, DockW
if (Splitter->orientation() == InsertParam.orientation())
{
insertWidgetIntoSplitter(Splitter, NewDockArea, InsertParam.append());
if (Splitter->isHidden())
updateSplitterHandles(Splitter);
if (Splitter->isHidden())
{
Splitter->show();
}
@ -1082,14 +1147,16 @@ void DockContainerWidgetPrivate::addDockArea(CDockAreaWidget* NewDockArea, DockW
QLayoutItem* li = Layout->replaceWidget(Splitter, NewSplitter);
NewSplitter->addWidget(Splitter);
NewSplitter->addWidget(NewDockArea);
delete li;
updateSplitterHandles(NewSplitter);
delete li;
}
else
{
NewSplitter->addWidget(NewDockArea);
QLayoutItem* li = Layout->replaceWidget(Splitter, NewSplitter);
NewSplitter->addWidget(Splitter);
delete li;
updateSplitterHandles(NewSplitter);
delete li;
}
RootSplitter = NewSplitter;
}
@ -1175,7 +1242,8 @@ CDockAreaWidget* DockContainerWidgetPrivate::addDockWidgetToDockArea(DockWidgetA
{
ADS_PRINT("TargetAreaSplitter->orientation() == InsertParam.orientation()");
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))
{
adjustSplitterSizesOnInsertion(TargetAreaSplitter);
@ -1188,11 +1256,14 @@ CDockAreaWidget* DockContainerWidgetPrivate::addDockWidgetToDockArea(DockWidgetA
auto TargetAreaSizes = TargetAreaSplitter->sizes();
QSplitter* NewSplitter = newSplitter(InsertParam.orientation());
NewSplitter->addWidget(TargetDockArea);
// updateSplitterHandles(NewSplitter);
insertWidgetIntoSplitter(NewSplitter, NewDockArea, InsertParam.append());
TargetAreaSplitter->insertWidget(index, NewSplitter);
if (CDockManager::testConfigFlag(CDockManager::EqualSplitOnInsertion))
{
updateSplitterHandles(NewSplitter);
TargetAreaSplitter->insertWidget(index, NewSplitter);
updateSplitterHandles(TargetAreaSplitter);
if (CDockManager::testConfigFlag(CDockManager::EqualSplitOnInsertion))
{
TargetAreaSplitter->setSizes(TargetAreaSizes);
adjustSplitterSizesOnInsertion(NewSplitter);
}
@ -1381,9 +1452,11 @@ void CDockContainerWidget::removeDockArea(CDockAreaWidget* area)
}
delete Splitter;
Splitter = nullptr;
emitAndExit:
CDockWidget* TopLevelWidget = topLevelDockWidget();
updateSplitterHandles(Splitter);
CDockWidget* TopLevelWidget = topLevelDockWidget();
// Updated the title bar visibility of the dock widget if there is only
// one single visible dock widget
@ -1732,6 +1805,13 @@ QList<CDockWidget*> CDockContainerWidget::dockWidgets() const
}
//============================================================================
void CDockContainerWidget::updateSplitterHandles(QSplitter* splitter)
{
d->updateSplitterHandles(splitter);
}
//============================================================================
CDockWidget::DockWidgetFeatures CDockContainerWidget::features() const
{

View File

@ -155,6 +155,12 @@ protected:
*/
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:
/**
* Default Constructor

View File

@ -108,6 +108,7 @@ struct DockManagerPrivate
bool RestoringState = false;
QVector<CFloatingDockContainer*> UninitializedFloatingWidgets;
CDockFocusController* FocusController = nullptr;
CDockWidget* CentralWidget = nullptr;
/**
* Private data constructor
@ -816,6 +817,23 @@ void CDockManager::loadPerspectives(QSettings& Settings)
Settings.endArray();
}
CDockWidget* CDockManager::centralWidget()
{
return d->CentralWidget;
}
//============================================================================
CDockAreaWidget* CDockManager::setCentralWidget(CDockWidget* widget)
{
if(d->CentralWidget)
{
addDockWidget(RightDockWidgetArea, d->CentralWidget);
}
d->CentralWidget = widget;
return addDockWidget(CenterDockWidgetArea, widget);
}
//============================================================================
QAction* CDockManager::addToggleViewActionToMenu(QAction* ToggleViewAction,
const QString& Group, const QIcon& GroupIcon)

View File

@ -378,7 +378,19 @@ public:
*/
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.
*/
CDockAreaWidget* setCentralWidget(CDockWidget* widget);
/**
* Adds a toggle view action to the the internal view menu.
* 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

View File

@ -102,6 +102,20 @@ QWidget* CDockSplitter::lastWidget() const
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
//---------------------------------------------------------------------------

View File

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

View File

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

View File

@ -360,6 +360,11 @@ public:
*/
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
* actions