Skip to content

Commit bc6ffcc

Browse files
author
Uwe Kindler
committed
Fixed update of floating widget window title, make disabled close button look nicer, fixed restoring of floating dock container, change save and restore functionality of dock area to save the current dock widget name instead of the current index to ensure that the right dock widget is active in an area if the number of dock widgets changes for some reasons (i.e. in plugin based applications)
1 parent a9246f7 commit bc6ffcc

9 files changed

+168
-70
lines changed

demo/main.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#include <windows.h>
2+
13
#include <MainWindow.h>
24
#include <QString>
35
#include <QFile>
@@ -35,6 +37,8 @@ void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QS
3537

3638
int main(int argc, char *argv[])
3739
{
40+
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
41+
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
3842
std::shared_ptr<int> b;
3943
QApplication a(argc, argv);
4044
a.setQuitOnLastWindowClosed(true);

src/DockAreaTitleBar.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <QMouseEvent>
2020
#include <QDebug>
2121
#include <QStyleOptionButton>
22+
#include <QPainter>
2223

2324
#include "FloatingDockContainer.h"
2425
#include "DockAreaWidget.h"
@@ -61,6 +62,8 @@ struct DockAreaTitleBarPrivate
6162
* Creates the internal TabBar
6263
*/
6364
void createTabBar();
65+
66+
QPixmap createTransparentPixmap(const QPixmap& Source);
6467
};// struct DockAreaTitleBarPrivate
6568

6669

@@ -73,6 +76,18 @@ DockAreaTitleBarPrivate::DockAreaTitleBarPrivate(CDockAreaTitleBar* _public) :
7376
}
7477

7578

79+
//============================================================================
80+
QPixmap DockAreaTitleBarPrivate::createTransparentPixmap(const QPixmap& Source)
81+
{
82+
QPixmap disabledPixmap(Source.size());
83+
disabledPixmap.fill(Qt::transparent);
84+
QPainter p(&disabledPixmap);
85+
p.setOpacity(0.25);
86+
p.drawPixmap(0, 0, Source);
87+
return disabledPixmap;
88+
}
89+
90+
7691
//============================================================================
7792
void DockAreaTitleBarPrivate::createButtons()
7893
{
@@ -94,8 +109,13 @@ void DockAreaTitleBarPrivate::createButtons()
94109
CloseButton = new tTileBarButton();
95110
CloseButton->setObjectName("closeButton");
96111
CloseButton->setAutoRaise(true);
97-
QIcon CloseIcon(":/ads/close-button.svg");
98-
CloseIcon.addFile(":/ads/close-button-disabled.svg", QSize(), QIcon::Disabled);
112+
113+
// The standard icons do does not look good on high DPI screens
114+
QIcon CloseIcon = _this->style()->standardIcon(QStyle::SP_TitleBarCloseButton);
115+
QPixmap normalPixmap = _this->style()->standardPixmap(QStyle::SP_TitleBarCloseButton, 0, CloseButton);
116+
QPixmap disabledPixmap = createTransparentPixmap(normalPixmap);
117+
CloseIcon.addPixmap(disabledPixmap, QIcon::Disabled);
118+
99119
CloseButton->setIcon(CloseIcon);
100120
CloseButton->setToolTip(QObject::tr("Close"));
101121
CloseButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);

src/DockAreaWidget.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ void CDockAreaWidget::insertDockWidget(int index, CDockWidget* DockWidget,
373373
void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget)
374374
{
375375
qDebug() << "CDockAreaWidget::removeDockWidget";
376+
std::cout << "CDockAreaWidget::removeDockWidget" << std::endl;
376377
auto NextOpenDockWidget = nextOpenDockWidget(DockWidget);
377378

378379
d->ContentsLayout->removeWidget(DockWidget);
@@ -398,7 +399,11 @@ void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget)
398399
}
399400

400401
d->updateTabBar();
401-
DockWidget->setDockArea(nullptr);
402+
auto TopLevelDockWidget = dockContainer()->topLevelDockWidget();
403+
if (TopLevelDockWidget)
404+
{
405+
TopLevelDockWidget->emitTopLevelChanged(true);
406+
}
402407

403408
#if (ADS_DEBUG_LEVEL > 0)
404409
CDockContainerWidget* DockContainer = dockContainer();

src/DockContainerWidget.cpp

Lines changed: 84 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -759,8 +759,7 @@ CDockContainerWidget::CDockContainerWidget(CDockManager* DockManager, QWidget *p
759759
QFrame(parent),
760760
d(new DockContainerWidgetPrivate(this))
761761
{
762-
d->isFloating = dynamic_cast<CFloatingDockContainer*>(parent) != 0;
763-
762+
d->isFloating = floatingWidget() != nullptr;
764763
d->DockManager = DockManager;
765764
if (DockManager != this)
766765
{
@@ -986,8 +985,9 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
986985
CDockAreaWidget* DockArea = dockAreaAt(TargetPos);
987986
auto dropArea = InvalidDockWidgetArea;
988987
auto ContainerDropArea = d->DockManager->containerOverlay()->dropAreaUnderCursor();
989-
CDockWidget* TopLevelDockWidget = FloatingWidget->hasTopLevelDockWidget() ?
990-
FloatingWidget->topLevelDockWidget() : nullptr;
988+
CDockWidget* FloatingTopLevelDockWidget = FloatingWidget->topLevelDockWidget();
989+
CDockWidget* TopLevelDockWidget = topLevelDockWidget();
990+
991991
if (DockArea)
992992
{
993993
auto dropOverlay = d->DockManager->dockAreaOverlay();
@@ -1017,12 +1017,19 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
10171017
}
10181018
}
10191019

1020-
// If we drop a floating widget with only one single dock widget, then we
1021-
// drop a top level widget that changes from floating to docked now
1020+
// If there was a top level widget before the drop, then it is not top
1021+
// level widget anymore
10221022
if (TopLevelDockWidget)
10231023
{
10241024
TopLevelDockWidget->emitTopLevelChanged(false);
10251025
}
1026+
1027+
// If we drop a floating widget with only one single dock widget, then we
1028+
// drop a top level widget that changes from floating to docked now
1029+
if (FloatingTopLevelDockWidget)
1030+
{
1031+
FloatingTopLevelDockWidget->emitTopLevelChanged(false);
1032+
}
10261033
}
10271034

10281035

@@ -1052,7 +1059,7 @@ void CDockContainerWidget::saveState(QXmlStreamWriter& s) const
10521059
s.writeAttribute("Floating", QString::number(isFloating() ? 1 : 0));
10531060
if (isFloating())
10541061
{
1055-
CFloatingDockContainer* FloatingWidget = internal::findParent<CFloatingDockContainer*>(this);
1062+
CFloatingDockContainer* FloatingWidget = floatingWidget();
10561063
QByteArray Geometry = FloatingWidget->saveGeometry();
10571064
s.writeTextElement("Geometry", Geometry.toHex(' '));
10581065
}
@@ -1091,7 +1098,7 @@ bool CDockContainerWidget::restoreState(QXmlStreamReader& s, bool Testing)
10911098

10921099
if (!Testing)
10931100
{
1094-
CFloatingDockContainer* FloatingWidget = internal::findParent<CFloatingDockContainer*>(this);
1101+
CFloatingDockContainer* FloatingWidget = floatingWidget();
10951102
FloatingWidget->restoreGeometry(Geometry);
10961103
}
10971104
}
@@ -1118,6 +1125,40 @@ bool CDockContainerWidget::restoreState(QXmlStreamReader& s, bool Testing)
11181125
d->RootSplitter = dynamic_cast<QSplitter*>(NewRootSplitter);
11191126
OldRoot->deleteLater();
11201127

1128+
// All dock widgets, that have not been processed in the restore state
1129+
// function are invisible to the user now and have no assigned dock area
1130+
// They do not belong to any dock container, until the user toggles the
1131+
// toggle view action the next time
1132+
for (auto DockWidget : dockWidgets())
1133+
{
1134+
if (DockWidget->property("dirty").toBool())
1135+
{
1136+
DockWidget->flagAsUnassigned();
1137+
}
1138+
else
1139+
{
1140+
DockWidget->toggleViewInternal(!DockWidget->property("closed").toBool());
1141+
}
1142+
}
1143+
1144+
// Finally we need to send the topLevelChanged() signals for all dock
1145+
// widgets if top level changed
1146+
CDockWidget* TopLevelDockWidget = topLevelDockWidget();
1147+
if (TopLevelDockWidget)
1148+
{
1149+
TopLevelDockWidget->emitTopLevelChanged(true);
1150+
}
1151+
else
1152+
{
1153+
for (auto DockArea : d->DockAreas)
1154+
{
1155+
for (auto DockWidget : DockArea->dockWidgets())
1156+
{
1157+
DockWidget->emitTopLevelChanged(false);
1158+
}
1159+
}
1160+
}
1161+
11211162
return true;
11221163
}
11231164

@@ -1150,6 +1191,11 @@ CDockAreaWidget* CDockContainerWidget::lastAddedDockAreaWidget(DockWidgetArea ar
11501191
//============================================================================
11511192
bool CDockContainerWidget::hasTopLevelDockWidget() const
11521193
{
1194+
if (!isFloating())
1195+
{
1196+
return false;
1197+
}
1198+
11531199
auto DockAreas = openedDockAreas();
11541200
if (DockAreas.count() != 1)
11551201
{
@@ -1163,19 +1209,38 @@ bool CDockContainerWidget::hasTopLevelDockWidget() const
11631209
//============================================================================
11641210
CDockWidget* CDockContainerWidget::topLevelDockWidget() const
11651211
{
1166-
auto DockAreas = openedDockAreas();
1167-
if (DockAreas.count() != 1)
1212+
auto TopLevelDockArea = topLevelDockArea();
1213+
if (!TopLevelDockArea)
11681214
{
11691215
return nullptr;
11701216
}
11711217

1172-
auto DockWidgets = DockAreas[0]->openedDockWidgets();
1218+
auto DockWidgets = TopLevelDockArea->openedDockWidgets();
11731219
if (DockWidgets.count() != 1)
11741220
{
11751221
return nullptr;
11761222
}
11771223

11781224
return DockWidgets[0];
1225+
1226+
}
1227+
1228+
1229+
//============================================================================
1230+
CDockAreaWidget* CDockContainerWidget::topLevelDockArea() const
1231+
{
1232+
if (!isFloating())
1233+
{
1234+
return nullptr;
1235+
}
1236+
1237+
auto DockAreas = openedDockAreas();
1238+
if (DockAreas.count() != 1)
1239+
{
1240+
return nullptr;
1241+
}
1242+
1243+
return DockAreas[0];
11791244
}
11801245

11811246

@@ -1204,6 +1269,14 @@ CDockWidget::DockWidgetFeatures CDockContainerWidget::features() const
12041269
return Features;
12051270
}
12061271

1272+
1273+
//============================================================================
1274+
CFloatingDockContainer* CDockContainerWidget::floatingWidget() const
1275+
{
1276+
return internal::findParent<CFloatingDockContainer*>(this);
1277+
}
1278+
1279+
12071280
} // namespace ads
12081281

12091282
#include "moc_DockContainerWidget.cpp"

src/DockContainerWidget.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,11 @@ class ADS_EXPORT CDockContainerWidget : public QFrame
127127
*/
128128
CDockWidget* topLevelDockWidget() const;
129129

130+
/**
131+
* Returns the top level dock area.
132+
*/
133+
CDockAreaWidget* topLevelDockArea() const;
134+
130135
/**
131136
* This function returns a list of all dock widgets in this floating widget.
132137
* It may be possible, depending on the implementation, that dock widgets,
@@ -216,6 +221,13 @@ class ADS_EXPORT CDockContainerWidget : public QFrame
216221
*/
217222
CDockWidget::DockWidgetFeatures features() const;
218223

224+
/**
225+
* If this dock container is in a floating widget, this function returns
226+
* the floating widget.
227+
* Else, it returns a nullptr.
228+
*/
229+
CFloatingDockContainer* floatingWidget() const;
230+
219231
signals:
220232
/**
221233
* This signal is emitted if one or multiple dock areas has been added to

src/DockManager.cpp

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -141,16 +141,27 @@ bool DockManagerPrivate::restoreContainer(int Index, QXmlStreamReader& stream, b
141141
Index = 0;
142142
}
143143

144+
bool Result = false;
144145
if (Index >= Containers.count())
145146
{
146147
CFloatingDockContainer* FloatingWidget = new CFloatingDockContainer(_this);
147-
return FloatingWidget->restoreState(stream, Testing);
148+
Result = FloatingWidget->restoreState(stream, Testing);
148149
}
149150
else
150151
{
151152
qDebug() << "d->Containers[i]->restoreState ";
152-
return Containers[Index]->restoreState(stream, Testing);
153+
auto Container = Containers[Index];
154+
if (Container->isFloating())
155+
{
156+
Result = Container->floatingWidget()->restoreState(stream, Testing);
157+
}
158+
else
159+
{
160+
Result = Container->restoreState(stream, Testing);
161+
}
153162
}
163+
164+
return Result;
154165
}
155166

156167

@@ -242,23 +253,6 @@ bool DockManagerPrivate::restoreState(const QByteArray &state, int version)
242253
return false;
243254
}
244255

245-
// All dock widgets, that have not been processed in the restore state
246-
// function are invisible to the user now and have no assigned dock area
247-
// They do not belong to any dock container, until the user toggles the
248-
// toggle view action the next time
249-
for (auto DockWidget : DockWidgetsMap)
250-
{
251-
if (DockWidget->property("dirty").toBool())
252-
{
253-
DockWidget->flagAsUnassigned();
254-
}
255-
else
256-
{
257-
DockWidget->toggleViewInternal(!DockWidget->property("closed").toBool());
258-
}
259-
}
260-
261-
262256
// Now all dock areas are properly restored and we setup the index of
263257
// The dock areas because the previous toggleView() action has changed
264258
// the dock area index
@@ -281,7 +275,7 @@ bool DockManagerPrivate::restoreState(const QByteArray &state, int version)
281275

282276
// Finally we need to send the topLevelChanged() signals for all dock
283277
// widgets if top level changed
284-
for (auto DockContainer : Containers)
278+
/*for (auto DockContainer : Containers)
285279
{
286280
CDockWidget* TopLevelDockWidget = DockContainer->topLevelDockWidget();
287281
if (TopLevelDockWidget)
@@ -299,7 +293,7 @@ bool DockManagerPrivate::restoreState(const QByteArray &state, int version)
299293
}
300294
}
301295
}
302-
}
296+
}*/
303297

304298
return true;
305299
}

0 commit comments

Comments
 (0)