KDDockWidgets API Documentation  1.5
LayoutWidget.cpp
Go to the documentation of this file.
1 /*
2  This file is part of KDDockWidgets.
3 
4  SPDX-FileCopyrightText: 2020-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
5  Author: SĂ©rgio Martins <sergio.martins@kdab.com>
6 
7  SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
8 
9  Contact KDAB at <info@kdab.com> for commercial licensing options.
10 */
11 
12 #include "LayoutSaver_p.h"
13 #include "Config.h"
14 #include "DockWidgetBase_p.h"
15 #include "FloatingWindow_p.h"
16 #include "Frame_p.h"
17 #include "FrameworkWidgetFactory.h"
18 #include "MainWindowBase.h"
19 #include "Position_p.h"
20 
21 using namespace KDDockWidgets;
22 
23 
24 LayoutWidget::LayoutWidget(QWidgetOrQuick *parent)
25  : LayoutGuestWidget(parent)
26 {
27 }
28 
29 LayoutWidget::~LayoutWidget()
30 {
31  if (m_rootItem->hostWidget()->asQObject() == this)
32  delete m_rootItem;
33  DockRegistry::self()->unregisterLayout(this);
34 }
35 
36 bool LayoutWidget::isInMainWindow() const
37 {
38  return mainWindow() != nullptr;
39 }
40 
41 MainWindowBase *LayoutWidget::mainWindow() const
42 {
43  if (auto pw = QWidgetAdapter::parentWidget()) {
44  // Note that if pw is a FloatingWindow then pw->parentWidget() can be a MainWindow too, as
45  // it's parented
46  if (pw->objectName() == QLatin1String("MyCentralWidget"))
47  return qobject_cast<MainWindowBase *>(pw->parentWidget());
48 
49  if (auto mw = qobject_cast<MainWindowBase *>(pw))
50  return mw;
51  }
52 
53  return nullptr;
54 }
55 
56 FloatingWindow *LayoutWidget::floatingWindow() const
57 {
58  return qobject_cast<FloatingWindow *>(QWidgetAdapter::parentWidget());
59 }
60 
61 void LayoutWidget::setRootItem(Layouting::ItemContainer *root)
62 {
63  delete m_rootItem;
64  m_rootItem = root;
65  connect(m_rootItem, &Layouting::ItemContainer::numVisibleItemsChanged, this,
66  &MultiSplitter::visibleWidgetCountChanged);
67  connect(m_rootItem, &Layouting::ItemContainer::minSizeChanged, this,
68  [this] { setMinimumSize(layoutMinimumSize()); });
69 }
70 
71 QSize LayoutWidget::layoutMinimumSize() const
72 {
73  return m_rootItem->minSize();
74 }
75 
76 QSize LayoutWidget::layoutMaximumSizeHint() const
77 {
78  return m_rootItem->maxSizeHint();
79 }
80 
81 void LayoutWidget::setLayoutMinimumSize(QSize sz)
82 {
83  if (sz != m_rootItem->minSize()) {
84  setLayoutSize(size().expandedTo(m_rootItem->minSize())); // Increase size in case we need to
85  m_rootItem->setMinSize(sz);
86  }
87 }
88 
89 QSize LayoutWidget::size() const
90 {
91  return m_rootItem->size();
92 }
93 
94 void LayoutWidget::clearLayout()
95 {
96  m_rootItem->clear();
97 }
98 
99 bool LayoutWidget::checkSanity() const
100 {
101  return m_rootItem->checkSanity();
102 }
103 
104 void LayoutWidget::dumpLayout() const
105 {
106  m_rootItem->dumpLayout();
107 }
108 
109 void LayoutWidget::restorePlaceholder(DockWidgetBase *dw, Layouting::Item *item, int tabIndex)
110 {
111  if (item->isPlaceholder()) {
112  Frame *newFrame = Config::self().frameworkWidgetFactory()->createFrame(this);
113  item->restore(newFrame);
114  }
115 
116  auto frame = qobject_cast<Frame *>(item->guestAsQObject());
117  Q_ASSERT(frame);
118 
119  if (tabIndex != -1 && frame->dockWidgetCount() >= tabIndex) {
120  frame->insertWidget(dw, tabIndex);
121  } else {
122  frame->addWidget(dw);
123  }
124 
125  frame->QWidgetAdapter::setVisible(true);
126 }
127 
128 void LayoutWidget::unrefOldPlaceholders(const Frame::List &framesBeingAdded) const
129 {
130  for (Frame *frame : framesBeingAdded) {
131  for (DockWidgetBase *dw : frame->dockWidgets()) {
132  dw->d->lastPositions().removePlaceholders(this);
133  }
134  }
135 }
136 
137 void LayoutWidget::setLayoutSize(QSize size)
138 {
139  if (size != this->size()) {
140  m_rootItem->setSize_recursive(size);
141  if (!m_inResizeEvent && !LayoutSaver::restoreInProgress())
142  resize(size);
143  }
144 }
145 
146 const Layouting::Item::List LayoutWidget::items() const
147 {
148  return m_rootItem->items_recursive();
149 }
150 
151 bool LayoutWidget::containsItem(const Layouting::Item *item) const
152 {
153  return m_rootItem->contains_recursive(item);
154 }
155 
156 bool LayoutWidget::containsFrame(const Frame *frame) const
157 {
158  return itemForFrame(frame) != nullptr;
159 }
160 
161 int LayoutWidget::count() const
162 {
163  return m_rootItem->count_recursive();
164 }
165 
166 int LayoutWidget::visibleCount() const
167 {
168  return m_rootItem->visibleCount_recursive();
169 }
170 
171 int LayoutWidget::placeholderCount() const
172 {
173  return count() - visibleCount();
174 }
175 
176 Layouting::Item *LayoutWidget::itemForFrame(const Frame *frame) const
177 {
178  if (!frame)
179  return nullptr;
180 
181  return m_rootItem->itemForWidget(frame);
182 }
183 
184 DockWidgetBase::List LayoutWidget::dockWidgets() const
185 {
186  DockWidgetBase::List dockWidgets;
187  const Frame::List frames = this->frames();
188  for (Frame *frame : frames)
189  dockWidgets << frame->dockWidgets();
190 
191  return dockWidgets;
192 }
193 
194 Frame::List LayoutWidget::framesFrom(QWidgetOrQuick *frameOrMultiSplitter) const
195 {
196  if (auto frame = qobject_cast<Frame *>(frameOrMultiSplitter))
197  return { frame };
198 
199  if (auto msw = qobject_cast<MultiSplitter *>(frameOrMultiSplitter))
200  return msw->frames();
201 
202  return {};
203 }
204 
205 Frame::List LayoutWidget::frames() const
206 {
207  const Layouting::Item::List items = m_rootItem->items_recursive();
208 
209  Frame::List result;
210  result.reserve(items.size());
211 
212  for (Layouting::Item *item : items) {
213  if (auto f = static_cast<Frame *>(item->guestAsQObject()))
214  result.push_back(f);
215  }
216 
217  return result;
218 }
219 
220 void LayoutWidget::removeItem(Layouting::Item *item)
221 {
222  if (!item) {
223  qWarning() << Q_FUNC_INFO << "nullptr item";
224  return;
225  }
226 
227  item->parentContainer()->removeItem(item);
228 }
229 
230 void LayoutWidget::updateSizeConstraints()
231 {
232  const QSize newMinSize = m_rootItem->minSize();
233  qCDebug(sizing) << Q_FUNC_INFO << "Updating size constraints from" << minimumSize() << "to"
234  << newMinSize;
235 
236  setLayoutMinimumSize(newMinSize);
237 }
238 
239 bool LayoutWidget::deserialize(const LayoutSaver::MultiSplitter &l)
240 {
242  for (const LayoutSaver::Frame &frame : qAsConst(l.frames)) {
243  Frame *f = Frame::deserialize(frame);
244  Q_ASSERT(!frame.id.isEmpty());
245  frames.insert(frame.id, f);
246  }
247 
248  m_rootItem->fillFromVariantMap(l.layout, frames);
249 
250  updateSizeConstraints();
251 
252  // This qMin() isn't needed for QtWidgets (but harmless), but it's required for QtQuick
253  // as some sizing is async
254  const QSize newLayoutSize = QWidgetAdapter::size().expandedTo(m_rootItem->minSize());
255 
256  m_rootItem->setSize_recursive(newLayoutSize);
257 
258  return true;
259 }
260 
261 void LayoutWidget::onLayoutRequest()
262 {
263  updateSizeConstraints();
264 }
265 
266 bool LayoutWidget::onResize(QSize newSize)
267 {
268  QScopedValueRollback<bool> resizeGuard(m_inResizeEvent, true); // to avoid re-entrancy
269 
271  // don't resize anything while we're restoring the layout
272  setLayoutSize(newSize);
273  }
274 
275  return false; // So QWidget::resizeEvent is called
276 }
277 
278 LayoutSaver::MultiSplitter LayoutWidget::serialize() const
279 {
280  LayoutSaver::MultiSplitter l;
281  l.layout = m_rootItem->toVariantMap();
282  const Layouting::Item::List items = m_rootItem->items_recursive();
283  l.frames.reserve(items.size());
284  for (Layouting::Item *item : items) {
285  if (!item->isContainer()) {
286  if (auto frame = qobject_cast<Frame *>(item->guestAsQObject()))
287  l.frames.insert(frame->id(), frame->serialize());
288  }
289  }
290 
291  return l;
292 }
QWidget
QSize
QHash::insert
QHash::iterator insert(const Key &key, const T &value)
MainWindowBase.h
The MainWindow base-class that's shared between QtWidgets and QtQuick stack.
KDDockWidgets::LayoutSaver::restoreInProgress
static bool restoreInProgress()
returns whether a restore (restoreLayout) is in progress
Definition: LayoutSaver.cpp:419
KDDockWidgets::LayoutGuestWidget
LayoutGuestWidget is the type that Item will host.
Definition: QWidgetAdapter.h:76
KDDockWidgets::Config::frameworkWidgetFactory
FrameworkWidgetFactory * frameworkWidgetFactory() const
getter for the framework widget factory
Definition: Config.cpp:143
QLatin1String
KDDockWidgets::FrameworkWidgetFactory::createFrame
virtual Frame * createFrame(QWidgetOrQuick *parent=nullptr, FrameOptions options=FrameOption_None) const =0
Called internally by the framework to create a Frame class Override to provide your own Frame sub-cla...
QVector::reserve
void reserve(int size)
Config.h
Application-wide config to tune certain behaviours of the framework.
QSize::expandedTo
QSize expandedTo(const QSize &otherSize) const const
KDDockWidgets::DockWidgetBase
The DockWidget base-class. DockWidget and DockWidgetBase are only split in two so we can share some c...
Definition: DockWidgetBase.h:61
KDDockWidgets
Definition: Config.cpp:36
QScopedValueRollback
KDDockWidgets::MainWindowBase
The MainWindow base-class. MainWindow and MainWindowBase are only split in two so we can share some c...
Definition: MainWindowBase.h:56
QVector
QHash
KDDockWidgets::Config::self
static Config & self()
returns the singleton Config instance
Definition: Config.cpp:82
FrameworkWidgetFactory.h
A factory class for allowing the user to customize some internal widgets.

© 2019-2022 Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/
KDDockWidgets
Advanced Dock Widget Framework for Qt
https://www.kdab.com/development-resources/qt-tools/kddockwidgets/
Generated on Mon Mar 7 2022 02:01:20 for KDDockWidgets API Documentation by doxygen 1.8.20