20#include <QAbstractScrollArea>
23#include <QXmlStreamWriter>
27class DockWidgetPrivate
30 struct WidgetFactory {
31 DockWidget::FactoryFunc createWidget;
32 DockWidget::WidgetInsertMode insertMode;
39 void showDockWidget();
40 void hideDockWidget();
41 void updateParentDockPanel();
43 void closeAutoHideDockWidgetsIfNeeded();
46 void setupScrollArea();
47 bool createWidgetFromFactory();
48 void setToolBarStyleFromDockWindow();
50 DockWindow *m_window =
nullptr;
51 QPointer<DockPanel> m_panel =
nullptr;
52 QBoxLayout *m_layout =
nullptr;
53 DockTab *m_tab =
nullptr;
54 DockWidget::DockWidgetFeatures m_features = DockWidget::DefaultDockWidgetFeatures;
55 QList<QAction *> m_titleBarActions;
56 QAction *m_toggleViewAction =
nullptr;
57 bool m_closed =
false;
58 bool m_isFloatingTopLevel =
false;
59 DockWidget::MinimumSizeHintMode m_minimumSizeHintMode = DockWidget::MinimumSizeHintFromDockWidget;
60 QWidget *m_widget =
nullptr;
61 QScrollArea *m_scrollArea =
nullptr;
62 QPointer<DockSideTab> m_sideTab;
63 DockWidget::ToolBarStyleSource m_toolBarStyleSource = DockWidget::ToolBarStyleFromDockWindow;
64 Qt::ToolButtonStyle m_toolBarStyleDocked = Qt::ToolButtonIconOnly;
65 Qt::ToolButtonStyle m_toolBarStyleFloating = Qt::ToolButtonTextUnderIcon;
66 QSize m_toolBarIconSizeDocked = QSize(16, 16);
67 QSize m_toolBarIconSizeFloating = QSize(24, 24);
68 QToolBar *m_toolBar =
nullptr;
69 WidgetFactory *m_factory =
nullptr;
72DockWidgetPrivate::DockWidgetPrivate()
76void DockWidgetPrivate::init()
80 m_layout =
new QBoxLayout(QBoxLayout::TopToBottom);
81 m_layout->setContentsMargins(0, 0, 0, 0);
82 m_layout->setSpacing(0);
83 q->setLayout(m_layout);
85 m_tab =
new DockTab(q);
88void DockWidgetPrivate::showDockWidget()
93 if (!m_widget && m_features.testFlag(DockWidget::DeleteContentOnClose)) {
94 if (!createWidgetFromFactory()) {
95 Q_ASSERT(m_features.testFlag(DockWidget::DeleteContentOnClose) &&
96 "DeleteContentOnClose flag was set, but the widget "
97 "factory is missing or it doesn't return a valid QWidget.");
103 DockFloatingContainer *floatingWidget =
new DockFloatingContainer(q);
105 floatingWidget->resize(m_widget ? m_widget->sizeHint() : q->sizeHint());
107 floatingWidget->show();
109 m_panel->setCurrentDockWidget(q);
110 m_panel->toggleView(
true);
112 auto splitter = m_panel->parentSplitter();
113 while (splitter && !splitter->isVisible() && !m_panel->isAutoHide()) {
115 splitter = internal::findParent<DockSplitter *>(splitter);
118 DockContainer *container = m_panel->dockContainer();
119 if (container->isFloating()) {
120 DockFloatingContainer *floatingWidget = internal::findParent<DockFloatingContainer *>(container);
121 floatingWidget->show();
126 if (container->openedDockWidgets().count() == 0 && m_panel->isAutoHide() && !m_window->isRestoringState()) {
127 m_panel->autoHideContainer()->moveContentsToParent();
132void DockWidgetPrivate::hideDockWidget()
135 updateParentDockPanel();
137 closeAutoHideDockWidgetsIfNeeded();
139 if (m_features.testFlag(DockWidget::DeleteContentOnClose)) {
141 m_scrollArea->takeWidget();
143 m_scrollArea =
nullptr;
145 m_widget->deleteLater();
155void DockWidgetPrivate::updateParentDockPanel()
161 if (m_panel->currentDockWidget() != q) {
164 auto nextDockWidget = m_panel->nextOpenDockWidget(q);
165 if (nextDockWidget) {
166 m_panel->setCurrentDockWidget(nextDockWidget);
168 m_panel->hideAreaWithNoVisibleContent();
176void DockWidgetPrivate::closeAutoHideDockWidgetsIfNeeded()
179 auto container = q->dockContainer();
184 if (q->dockWindow()->isRestoringState()) {
190 if ((container == q->dockWindow()) || !container->openedDockWidgets().isEmpty()) {
194 for (
auto autoHideWidget : container->autoHideWidgets()) {
195 auto dockWidget = autoHideWidget->dockWidget();
196 if (dockWidget == q) {
200 dockWidget->toggleView(
false);
204void DockWidgetPrivate::setupToolBar()
207 m_toolBar =
new QToolBar(q);
208 m_toolBar->setObjectName(
"dockWidgetToolBar");
209 m_layout->insertWidget(0, m_toolBar);
210 m_toolBar->setIconSize(QSize(16, 16));
211 m_toolBar->toggleViewAction()->setEnabled(
false);
212 m_toolBar->toggleViewAction()->setVisible(
false);
213 q->connect(q, SIGNAL(topLevelChanged(
bool)), SLOT(setToolbarFloatingStyle(
bool)));
219void DockWidgetPrivate::setupScrollArea()
222 m_scrollArea =
new QScrollArea(q);
223 m_scrollArea->setObjectName(
"dockWidgetScrollArea");
224 m_scrollArea->setWidgetResizable(
true);
225 m_layout->addWidget(m_scrollArea);
232bool DockWidgetPrivate::createWidgetFromFactory()
239 QWidget *w = m_factory->createWidget(q);
244 q->setWidget(w, m_factory->insertMode);
251void DockWidgetPrivate::setToolBarStyleFromDockWindow()
257 auto state = DockWidget::StateDocked;
258 q->setToolBarIconSize(m_window->dockWidgetToolBarIconSize(state), state);
259 q->setToolBarStyle(m_window->dockWidgetToolBarStyle(state), state);
260 state = DockWidget::StateFloating;
261 q->setToolBarIconSize(m_window->dockWidgetToolBarIconSize(state), state);
262 q->setToolBarStyle(m_window->dockWidgetToolBarStyle(state), state);
278DockWidget::DockWidget(
const QString &title, QWidget *parent)
284 setWindowTitle(title);
285 setObjectName(title);
290 d->m_toggleViewAction =
new QAction(title,
this);
291 d->m_toggleViewAction->setCheckable(
true);
292 connect(d->m_toggleViewAction, SIGNAL(triggered(
bool)),
this, SLOT(
toggleView(
bool)));
296 setFocusPolicy(Qt::ClickFocus);
317 auto scrollAreaWidget = qobject_cast<QAbstractScrollArea *>(w);
319 d->m_layout->addWidget(w);
320 if (scrollAreaWidget && scrollAreaWidget->viewport()) {
321 scrollAreaWidget->viewport()->setProperty(
"dockWidgetContent",
true);
324 d->setupScrollArea();
325 d->m_scrollArea->setWidget(w);
329 d->m_widget->setProperty(
"dockWidgetContent",
true);
348 QWidget *w =
nullptr;
349 if (d->m_scrollArea) {
350 d->m_layout->removeWidget(d->m_scrollArea);
351 w = d->m_scrollArea->takeWidget();
352 delete d->m_scrollArea;
353 d->m_scrollArea =
nullptr;
354 d->m_widget =
nullptr;
355 }
else if (d->m_widget) {
356 d->m_layout->removeWidget(d->m_widget);
358 d->m_widget =
nullptr;
362 w->setParent(
nullptr);
387 return d->m_features & ~d->m_window->globallyLockedDockWidgetFeatures();
389 return d->m_features;
424 d->m_tab->onDockWidgetFeaturesChanged();
426 panel->onDockWidgetFeaturesChanged();
448 return d->m_panel->dockContainer();
461 return container ? container->floatingWidget() :
nullptr;
500 if (!container->isFloating()) {
525 return Super::isFullScreen();
536 return d->m_panel && (d->m_panel->openDockWidgetsCount() > 1);
548 return d->m_panel && (d->m_panel->currentDockWidget() ==
this);
566 return d->m_toggleViewAction;
579 d->m_toggleViewAction->setParent(
nullptr);
580 delete d->m_toggleViewAction;
581 d->m_toggleViewAction = action;
582 d->m_toggleViewAction->setParent(
this);
583 connect(d->m_toggleViewAction, SIGNAL(triggered(
bool)),
this, SLOT(
toggleView(
bool)));
594 d->m_toggleViewAction->setCheckable(
true);
595 d->m_toggleViewAction->setIcon(QIcon());
597 d->m_toggleViewAction->setCheckable(
false);
598 d->m_toggleViewAction->setIcon(d->m_tab->icon());
608 QAction *action = d->m_toggleViewAction;
609 action->blockSignals(
true);
610 action->setChecked(checked);
611 action->blockSignals(
false);
617 return d->m_titleBarActions;
631 d->m_titleBarActions = actions;
640 return d->m_minimumSizeHintMode;
651 d->m_minimumSizeHintMode = mode;
658 return QSize(60, 40);
661 switch (d->m_minimumSizeHintMode) {
663 return QSize(60, 40);
665 return d->m_widget->minimumSizeHint();
667 return minimumSize();
669 return d->m_widget->minimumSize();
672 return d->m_widget->minimumSizeHint();
678 return d->m_tab->icon();
684 d->m_tab->setIcon(
icon);
687 d->m_sideTab->setIcon(
icon);
690 if (!d->m_toggleViewAction->isCheckable()) {
691 d->m_toggleViewAction->setIcon(
icon);
702 if (!d_ptr->m_toolBar) {
703 d_ptr->setupToolBar();
705 return d_ptr->m_toolBar;
721 d->m_layout->insertWidget(0, d->m_toolBar);
729 return d->m_toolBarStyleSource;
739 d->m_toolBarStyleSource = source;
741 d->setToolBarStyleFromDockWindow();
749 return d->m_toolBarStyleFloating;
751 return d->m_toolBarStyleDocked;
767 d->m_toolBarStyleFloating = style;
769 d->m_toolBarStyleDocked = style;
779 return d->m_toolBarIconSizeFloating;
781 return d->m_toolBarIconSizeDocked;
795 d->m_toolBarIconSizeFloating = iconSize;
797 d->m_toolBarIconSizeDocked = iconSize;
826 return !d->m_sideTab.isNull();
841 return d->m_panel->autoHideContainer();
869 d->m_factory =
new DockWidgetPrivate::WidgetFactory{createWidget, insertMode};
877 d->m_tab->setToolTip(
text);
879 if (d->m_toggleViewAction) {
880 d->m_toggleViewAction->setToolTip(
text);
883 d->m_panel->markTitleBarMenuOutdated();
895 QAction *a = qobject_cast<QAction *>(sender());
896 if (a == d->m_toggleViewAction && !d->m_toggleViewAction->isCheckable()) {
903 if (d->m_closed != !open) {
905 }
else if (open && d->m_panel && !container) {
909 if (open && container) {
910 container->collapseView(
false);
922 d->m_window->removeDockWidget(
this);
971 panel->setAutoHide(
false);
1003 d->m_panel->setCurrentDockWidget(
this);
1022 auto floatingWindow =
window();
1023 floatingWindow->raise();
1024 floatingWindow->activateWindow();
1044 Super::showFullScreen();
1057 Super::showNormal();
1074 d->m_tab->detachDockWidget();
1084 if (!d->m_toolBar) {
1088 auto iconSize = floating ? d->m_toolBarIconSizeFloating : d->m_toolBarIconSizeDocked;
1089 if (iconSize != d->m_toolBar->iconSize()) {
1090 d->m_toolBar->setIconSize(iconSize);
1093 auto buttonStyle = floating ? d->m_toolBarStyleFloating : d->m_toolBarStyleDocked;
1094 if (buttonStyle != d->m_toolBar->toolButtonStyle()) {
1095 d->m_toolBar->setToolButtonStyle(buttonStyle);
1111 d->setToolBarStyleFromDockWindow();
1125 d->m_toggleViewAction->setChecked(panel !=
nullptr && !this->
isClosed());
1141 if (topLevelDockWidget) {
1155 if (floating != d->m_isFloatingTopLevel) {
1156 d->m_isFloatingTopLevel = floating;
1171 d->m_closed = !open;
1173 d->showDockWidget();
1175 d->hideDockWidget();
1177 d->m_toggleViewAction->blockSignals(
true);
1178 d->m_toggleViewAction->setChecked(open);
1179 d->m_toggleViewAction->blockSignals(
false);
1181 d->m_panel->toggleDockWidgetView(
this, open);
1182 if (d->m_panel->isAutoHide()) {
1188 if (open && topLevelDockWidgetBefore) {
1199 if (floatingContainer) {
1229 floatingWidget->deleteLater();
1231 floatingWidget->hide();
1235 if (d->m_panel && d->m_panel->isAutoHide()) {
1236 d->m_panel->autoHideContainer()->cleanupAndDelete();
1259 setParent(d->m_window);
1262 tab()->setParent(
this);
1268 s.writeStartElement(
"Widget");
1269 s.writeAttribute(
"Name", objectName());
1270 s.writeAttribute(
"Closed", QString::number(d->m_closed ? 1 : 0));
1271 s.writeEndElement();
1280 switch (e->type()) {
1289 case QEvent::WindowTitleChange: {
1290 const auto title = windowTitle();
1292 d->m_tab->setText(title);
1295 d->m_sideTab->setText(title);
1297 if (d->m_toggleViewAction) {
1298 d->m_toggleViewAction->setText(title);
1301 d->m_panel->markTitleBarMenuOutdated();
1305 if (floatingWidget) {
1306 floatingWidget->updateWindowTitle();
1315 return Super::event(e);
Auto hide container for hosting an auto hide dock widget
Qx::DockSideBarArea sideBarArea() const
void moveToNewSideBarArea(Qx::DockSideBarArea area, int tabIndex=-1)
Removes the AutoHide container from the current side bar and adds it to the new side bar given in are...
Container that manages a number of dock panels with single dock widgets or tabyfied dock widgets in e...
DockWidget * topLevelDockWidget() const
If hasTopLevelDockWidget() returns true, this function returns the one and only visible dock widget.
DockAutoHideContainer * createAndSetupAutoHideContainer(Qx::DockSideBarArea area, DockWidget *w, int tabIndex=-1)
Creates and initializes a dockwidget auto hide container into the given area.
DockFloatingContainer * floatingWidget() const
If this dock container is in a floating widget, this function returns the floating widget.
This implements a floating widget that is a dock container that accepts docking of dock widgets like ...
QList< DockWidget * > dockWidgets() const
This function returns a list of all dock widget in this floating widget.
static bool testConfigFlag(ConfigFlag flag)
static bool testAutoHideConfigFlag(AutoHideFlag flag)
DockPanel manages multiple instances of DockWidgets.
void updateTitleBarVisibility()
Updates the dock panel layout and components visibility
A dock widget Side tab that shows a title or an icon.
The central dock window that maintains the complete docking system.
DockWidget * centralWidget() const
#define QXDOCK_SET_BGCOLOR(w)
void setFlag(T &flags, typename T::enum_type flag, bool on=true)
#define QX_INIT_PRIVATE(Class)
#define QX_DECLARE_PUBLIC(Class)
#define QX_FINI_PRIVATE()
#define QX_DOCK_END_NAMESPACE
#define QX_DOCK_BEGIN_NAMESPACE