Move lots of methods from MultiSplitter to its base class
This commit is contained in:
@@ -9,7 +9,13 @@
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
#include "Config.h"
|
||||
#include "DockWidgetBase_p.h"
|
||||
#include "FloatingWindow_p.h"
|
||||
#include "FrameworkWidgetFactory.h"
|
||||
#include "LayoutWidget_p.h"
|
||||
#include "MainWindowBase.h"
|
||||
#include "Position_p.h"
|
||||
|
||||
using namespace KDDockWidgets;
|
||||
|
||||
@@ -22,3 +28,113 @@ LayoutWidget::LayoutWidget(QWidgetOrQuick *parent)
|
||||
LayoutWidget::~LayoutWidget()
|
||||
{
|
||||
}
|
||||
|
||||
bool LayoutWidget::isInMainWindow() const
|
||||
{
|
||||
return mainWindow() != nullptr;
|
||||
}
|
||||
|
||||
MainWindowBase *LayoutWidget::mainWindow() const
|
||||
{
|
||||
if (auto pw = QWidgetAdapter::parentWidget()) {
|
||||
// Note that if pw is a FloatingWindow then pw->parentWidget() can be a MainWindow too, as
|
||||
// it's parented
|
||||
if (pw->objectName() == QLatin1String("MyCentralWidget"))
|
||||
return qobject_cast<MainWindowBase *>(pw->parentWidget());
|
||||
|
||||
if (auto mw = qobject_cast<MainWindowBase *>(pw))
|
||||
return mw;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FloatingWindow *LayoutWidget::floatingWindow() const
|
||||
{
|
||||
return qobject_cast<FloatingWindow *>(QWidgetAdapter::parentWidget());
|
||||
}
|
||||
|
||||
void LayoutWidget::setRootItem(Layouting::ItemContainer *root)
|
||||
{
|
||||
delete m_rootItem;
|
||||
m_rootItem = root;
|
||||
connect(m_rootItem, &Layouting::ItemContainer::numVisibleItemsChanged, this,
|
||||
&MultiSplitter::visibleWidgetCountChanged);
|
||||
connect(m_rootItem, &Layouting::ItemContainer::minSizeChanged, this,
|
||||
[this] { setMinimumSize(layoutMinimumSize()); });
|
||||
}
|
||||
|
||||
QSize LayoutWidget::layoutMinimumSize() const
|
||||
{
|
||||
return m_rootItem->minSize();
|
||||
}
|
||||
|
||||
QSize LayoutWidget::layoutMaximumSizeHint() const
|
||||
{
|
||||
return m_rootItem->maxSizeHint();
|
||||
}
|
||||
|
||||
void LayoutWidget::setLayoutMinimumSize(QSize sz)
|
||||
{
|
||||
if (sz != m_rootItem->minSize()) {
|
||||
setLayoutSize(size().expandedTo(m_rootItem->minSize())); // Increase size in case we need to
|
||||
m_rootItem->setMinSize(sz);
|
||||
}
|
||||
}
|
||||
|
||||
QSize LayoutWidget::size() const
|
||||
{
|
||||
return m_rootItem->size();
|
||||
}
|
||||
|
||||
void LayoutWidget::clearLayout()
|
||||
{
|
||||
m_rootItem->clear();
|
||||
}
|
||||
|
||||
bool LayoutWidget::checkSanity() const
|
||||
{
|
||||
return m_rootItem->checkSanity();
|
||||
}
|
||||
|
||||
void LayoutWidget::dumpLayout() const
|
||||
{
|
||||
m_rootItem->dumpLayout();
|
||||
}
|
||||
|
||||
void LayoutWidget::restorePlaceholder(DockWidgetBase *dw, Layouting::Item *item, int tabIndex)
|
||||
{
|
||||
if (item->isPlaceholder()) {
|
||||
Frame *newFrame = Config::self().frameworkWidgetFactory()->createFrame(this);
|
||||
item->restore(newFrame);
|
||||
}
|
||||
|
||||
auto frame = qobject_cast<Frame *>(item->guestAsQObject());
|
||||
Q_ASSERT(frame);
|
||||
|
||||
if (tabIndex != -1 && frame->dockWidgetCount() >= tabIndex) {
|
||||
frame->insertWidget(dw, tabIndex);
|
||||
} else {
|
||||
frame->addWidget(dw);
|
||||
}
|
||||
|
||||
frame->QWidgetAdapter::setVisible(true);
|
||||
}
|
||||
|
||||
void LayoutWidget::unrefOldPlaceholders(const Frame::List &framesBeingAdded) const
|
||||
{
|
||||
for (Frame *frame : framesBeingAdded) {
|
||||
for (DockWidgetBase *dw : frame->dockWidgets()) {
|
||||
dw->d->lastPositions().removePlaceholders(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutWidget::setLayoutSize(QSize size)
|
||||
{
|
||||
if (size != this->size()) {
|
||||
m_rootItem->setSize_recursive(size);
|
||||
if (!m_inResizeEvent && !LayoutSaver::restoreInProgress())
|
||||
resize(size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,8 +28,21 @@
|
||||
#include "kddockwidgets/KDDockWidgets.h"
|
||||
#include "kddockwidgets/QWidgetAdapter.h"
|
||||
|
||||
#include <QList>
|
||||
|
||||
namespace Layouting {
|
||||
class Item;
|
||||
class Separator;
|
||||
class Widget_qwidget;
|
||||
}
|
||||
|
||||
namespace KDDockWidgets {
|
||||
|
||||
class MainWindowBase;
|
||||
class FloatingWindow;
|
||||
class Frame;
|
||||
class DockWidgetBase;
|
||||
|
||||
/**
|
||||
* @brief The widget (QWidget or QQuickItem) which holds a layout of dock widgets.
|
||||
*
|
||||
@@ -47,6 +60,92 @@ class DOCKS_EXPORT LayoutWidget : public LayoutGuestWidget
|
||||
public:
|
||||
explicit LayoutWidget(QWidgetOrQuick *parent = nullptr);
|
||||
~LayoutWidget() override;
|
||||
|
||||
bool isInMainWindow() const;
|
||||
MainWindowBase *mainWindow() const;
|
||||
FloatingWindow *floatingWindow() const;
|
||||
|
||||
/**
|
||||
* @brief returns the layout's minimum size
|
||||
* @ref setLayoutMinimumSize
|
||||
*/
|
||||
QSize layoutMinimumSize() const;
|
||||
|
||||
/**
|
||||
* @brief returns the layout's maximum size hint
|
||||
*/
|
||||
QSize layoutMaximumSizeHint() const;
|
||||
|
||||
/**
|
||||
* @brief returns the contents width.
|
||||
* Usually it's the same width as the respective parent MultiSplitter.
|
||||
*/
|
||||
int width() const
|
||||
{
|
||||
return size().width();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns the contents height.
|
||||
* Usually it's the same height as the respective parent MultiSplitter.
|
||||
*/
|
||||
int height() const
|
||||
{
|
||||
return size().height();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief getter for the size
|
||||
*/
|
||||
QSize size() const;
|
||||
|
||||
/// @brief Runs some sanity checks. Returns true if everything is OK
|
||||
bool checkSanity() const;
|
||||
|
||||
/// @brief clears the layout
|
||||
void clearLayout();
|
||||
|
||||
/// @brief dumps the layout to stderr
|
||||
void dumpLayout() const;
|
||||
|
||||
/**
|
||||
* @brief setter for the contents size
|
||||
* The "contents size" is just the size() of this layout. However, since resizing
|
||||
* QWidgets is async and we need it to be sync. As sometimes adding widgets will increase
|
||||
* the MultiSplitter size (due to widget's min-size constraints).
|
||||
*/
|
||||
void setLayoutSize(QSize);
|
||||
|
||||
|
||||
/// @brief restores the dockwidget @p dw to its previous position
|
||||
void restorePlaceholder(DockWidgetBase *dw, Layouting::Item *, int tabIndex);
|
||||
|
||||
protected:
|
||||
bool m_inResizeEvent = false;
|
||||
|
||||
void setRootItem(Layouting::ItemContainer *root);
|
||||
/**
|
||||
* @brief setter for the minimum size
|
||||
* @ref minimumSize
|
||||
*/
|
||||
void setLayoutMinimumSize(QSize);
|
||||
|
||||
/**
|
||||
* @brief Removes unneeded placeholder items when adding new frames.
|
||||
*
|
||||
* A floating frame A might have a placeholder in the main window (for example to remember its
|
||||
* position on the Left), but then the user might attach it to the right, so the left
|
||||
* placeholder is no longer need. Right before adding the frame to the right we remove the left
|
||||
* placeholder, otherwise it's unrefed while we're adding causing a segfault. So what this does
|
||||
* is making the unrefing happen a bit earlier.
|
||||
*/
|
||||
void unrefOldPlaceholders(const QList<Frame *> &framesBeingAdded) const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void visibleWidgetCountChanged(int count);
|
||||
|
||||
private:
|
||||
Layouting::ItemContainer *m_rootItem = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -78,30 +78,6 @@ bool MultiSplitter::onResize(QSize newSize)
|
||||
return false; // So QWidget::resizeEvent is called
|
||||
}
|
||||
|
||||
bool MultiSplitter::isInMainWindow() const
|
||||
{
|
||||
return mainWindow() != nullptr;
|
||||
}
|
||||
|
||||
MainWindowBase *MultiSplitter::mainWindow() const
|
||||
{
|
||||
if (auto pw = QWidgetAdapter::parentWidget()) {
|
||||
// Note that if pw is a FloatingWindow then pw->parentWidget() can be a MainWindow too, as it's parented
|
||||
if (pw->objectName() == QLatin1String("MyCentralWidget"))
|
||||
return qobject_cast<MainWindowBase*>(pw->parentWidget());
|
||||
|
||||
if (auto mw = qobject_cast<MainWindowBase*>(pw))
|
||||
return mw;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FloatingWindow *MultiSplitter::floatingWindow() const
|
||||
{
|
||||
return qobject_cast<FloatingWindow*>(QWidgetAdapter::parentWidget());
|
||||
}
|
||||
|
||||
bool MultiSplitter::validateInputs(QWidgetOrQuick *widget,
|
||||
Location location,
|
||||
const Frame *relativeToFrame, InitialOption option) const
|
||||
@@ -334,25 +310,6 @@ Frame::List MultiSplitter::frames() const
|
||||
return result;
|
||||
}
|
||||
|
||||
void MultiSplitter::restorePlaceholder(DockWidgetBase *dw, Layouting::Item *item, int tabIndex)
|
||||
{
|
||||
if (item->isPlaceholder()) {
|
||||
Frame *newFrame = Config::self().frameworkWidgetFactory()->createFrame(this);
|
||||
item->restore(newFrame);
|
||||
}
|
||||
|
||||
auto frame = qobject_cast<Frame*>(item->guestAsQObject());
|
||||
Q_ASSERT(frame);
|
||||
|
||||
if (tabIndex != -1 && frame->dockWidgetCount() >= tabIndex) {
|
||||
frame->insertWidget(dw, tabIndex);
|
||||
} else {
|
||||
frame->addWidget(dw);
|
||||
}
|
||||
|
||||
frame->QWidgetAdapter::setVisible(true);
|
||||
}
|
||||
|
||||
void MultiSplitter::layoutEqually()
|
||||
{
|
||||
layoutEqually(m_rootItem);
|
||||
@@ -367,70 +324,13 @@ void MultiSplitter::layoutEqually(Layouting::ItemBoxContainer *container)
|
||||
}
|
||||
}
|
||||
|
||||
void MultiSplitter::clearLayout()
|
||||
{
|
||||
m_rootItem->clear();
|
||||
}
|
||||
|
||||
bool MultiSplitter::checkSanity() const
|
||||
{
|
||||
return m_rootItem->checkSanity();
|
||||
}
|
||||
|
||||
void MultiSplitter::unrefOldPlaceholders(const Frame::List &framesBeingAdded) const
|
||||
{
|
||||
for (Frame *frame : framesBeingAdded) {
|
||||
for (DockWidgetBase *dw : frame->dockWidgets()) {
|
||||
dw->d->lastPositions().removePlaceholders(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MultiSplitter::dumpLayout() const
|
||||
{
|
||||
m_rootItem->dumpLayout();
|
||||
}
|
||||
|
||||
void MultiSplitter::setLayoutSize(QSize size)
|
||||
{
|
||||
if (size != this->size()) {
|
||||
m_rootItem->setSize_recursive(size);
|
||||
if (!m_inResizeEvent && !LayoutSaver::restoreInProgress())
|
||||
resize(size);
|
||||
}
|
||||
}
|
||||
|
||||
QSize MultiSplitter::layoutMinimumSize() const
|
||||
{
|
||||
return m_rootItem->minSize();
|
||||
}
|
||||
|
||||
QSize MultiSplitter::layoutMaximumSizeHint() const
|
||||
{
|
||||
return m_rootItem->maxSizeHint();
|
||||
}
|
||||
|
||||
QSize MultiSplitter::size() const { return m_rootItem->size(); }
|
||||
|
||||
void MultiSplitter::setLayoutMinimumSize(QSize sz)
|
||||
{
|
||||
if (sz != m_rootItem->minSize()) {
|
||||
setLayoutSize(size().expandedTo(m_rootItem->minSize())); // Increase size in case we need to
|
||||
m_rootItem->setMinSize(sz);
|
||||
}
|
||||
|
||||
qCDebug(sizing) << Q_FUNC_INFO << "minSize = " << m_rootItem->minSize();
|
||||
}
|
||||
|
||||
void MultiSplitter::setRootItem(Layouting::ItemBoxContainer *root)
|
||||
{
|
||||
delete m_rootItem;
|
||||
LayoutWidget::setRootItem(root);
|
||||
|
||||
m_rootItem = root;
|
||||
connect(m_rootItem, &Layouting::ItemBoxContainer::numVisibleItemsChanged,
|
||||
this, &MultiSplitter::visibleWidgetCountChanged);
|
||||
connect(m_rootItem, &Layouting::ItemBoxContainer::minSizeChanged, this, [this] {
|
||||
setMinimumSize(layoutMinimumSize());
|
||||
});
|
||||
connect(m_rootItem, &Layouting::ItemContainer::minSizeChanged, this,
|
||||
[this] { setMinimumSize(layoutMinimumSize()); });
|
||||
}
|
||||
|
||||
const Layouting::Item::List MultiSplitter::items() const
|
||||
|
||||
@@ -28,19 +28,10 @@
|
||||
#include "kddockwidgets/QWidgetAdapter.h"
|
||||
#include "kddockwidgets/docks_export.h"
|
||||
|
||||
namespace Layouting {
|
||||
class Item;
|
||||
class Separator;
|
||||
class Widget_qwidget;
|
||||
}
|
||||
|
||||
class TestDocks;
|
||||
|
||||
namespace KDDockWidgets {
|
||||
|
||||
class MainWindowBase;
|
||||
class FloatingWindow;
|
||||
class Frame;
|
||||
struct WindowBeingDragged;
|
||||
|
||||
/**
|
||||
@@ -60,9 +51,6 @@ class DOCKS_EXPORT MultiSplitter : public LayoutWidget
|
||||
public:
|
||||
explicit MultiSplitter(QWidgetOrQuick *parent = nullptr);
|
||||
~MultiSplitter() override;
|
||||
bool isInMainWindow() const;
|
||||
MainWindowBase* mainWindow() const;
|
||||
FloatingWindow* floatingWindow() const;
|
||||
|
||||
/**
|
||||
* @brief Adds a widget to this MultiSplitter.
|
||||
@@ -120,7 +108,7 @@ public:
|
||||
/**
|
||||
* @brief The list of items in this layout.
|
||||
*/
|
||||
const QVector<Layouting::Item*> items() const;
|
||||
const QVector<Layouting::Item *> items() const;
|
||||
|
||||
|
||||
/**
|
||||
@@ -143,48 +131,6 @@ public:
|
||||
*/
|
||||
void updateSizeConstraints();
|
||||
|
||||
/**
|
||||
* @brief setter for the contents size
|
||||
* The "contents size" is just the size() of this layout. However, since resizing
|
||||
* QWidgets is async and we need it to be sync. As sometimes adding widgets will increase
|
||||
* the MultiSplitter size (due to widget's min-size constraints).
|
||||
*/
|
||||
void setLayoutSize(QSize);
|
||||
|
||||
/**
|
||||
* @brief returns the contents width.
|
||||
* Usually it's the same width as the respective parent MultiSplitter.
|
||||
*/
|
||||
int width() const { return size().width(); }
|
||||
|
||||
/**
|
||||
* @brief returns the contents height.
|
||||
* Usually it's the same height as the respective parent MultiSplitter.
|
||||
*/
|
||||
int height() const { return size().height(); }
|
||||
|
||||
/**
|
||||
* @brief returns the layout's minimum size
|
||||
* @ref setLayoutMinimumSize
|
||||
*/
|
||||
QSize layoutMinimumSize() const;
|
||||
|
||||
/**
|
||||
* @brief returns the layout's maximum size hint
|
||||
*/
|
||||
QSize layoutMaximumSizeHint() const;
|
||||
|
||||
/**
|
||||
* @brief getter for the size
|
||||
*/
|
||||
QSize size() const;
|
||||
|
||||
/// @brief Runs some sanity checks. Returns true if everything is OK
|
||||
bool checkSanity() const;
|
||||
|
||||
/// @brief dumps the layout to stderr
|
||||
void dumpLayout() const;
|
||||
|
||||
/**
|
||||
* @brief returns the Item that holds @p frame in this layout
|
||||
*/
|
||||
@@ -198,27 +144,16 @@ public:
|
||||
/// @brief Returns the list of dock widgets contained in this layout
|
||||
QVector<DockWidgetBase*> dockWidgets() const;
|
||||
|
||||
/// @brief restores the dockwidget @p dw to its previous position
|
||||
void restorePlaceholder(DockWidgetBase *dw, Layouting::Item *, int tabIndex);
|
||||
|
||||
/// @brief See docs for MainWindowBase::layoutEqually()
|
||||
void layoutEqually();
|
||||
|
||||
/// @brief overload that just resizes widgets within a sub-tree
|
||||
void layoutEqually(Layouting::ItemBoxContainer *);
|
||||
|
||||
/// @brief clears the layout
|
||||
void clearLayout();
|
||||
|
||||
Q_SIGNALS:
|
||||
void visibleWidgetCountChanged(int count);
|
||||
|
||||
protected:
|
||||
void onLayoutRequest() override;
|
||||
bool onResize(QSize newSize) override;
|
||||
private:
|
||||
bool m_inResizeEvent = false;
|
||||
|
||||
friend class ::TestDocks;
|
||||
|
||||
/**
|
||||
@@ -234,21 +169,6 @@ private:
|
||||
bool validateInputs(QWidgetOrQuick *widget, KDDockWidgets::Location location,
|
||||
const Frame *relativeToFrame, InitialOption option) const;
|
||||
|
||||
/**
|
||||
* @brief Removes unneeded placeholder items when adding new frames.
|
||||
*
|
||||
* A floating frame A might have a placeholder in the main window (for example to remember its position on the Left),
|
||||
* but then the user might attach it to the right, so the left placeholder is no longer need.
|
||||
* Right before adding the frame to the right we remove the left placeholder, otherwise it's unrefed while we're adding
|
||||
* causing a segfault. So what this does is making the unrefing happen a bit earlier.
|
||||
*/
|
||||
void unrefOldPlaceholders(const QList<Frame*> &framesBeingAdded) const;
|
||||
|
||||
/**
|
||||
* @brief setter for the minimum size
|
||||
* @ref minimumSize
|
||||
*/
|
||||
void setLayoutMinimumSize(QSize);
|
||||
|
||||
void setRootItem(Layouting::ItemBoxContainer *);
|
||||
|
||||
|
||||
@@ -294,6 +294,8 @@ public:
|
||||
|
||||
QVector<int> pathFromRoot() const;
|
||||
|
||||
Q_REQUIRED_RESULT virtual bool checkSanity();
|
||||
|
||||
virtual QSize minSize() const;
|
||||
virtual QSize maxSizeHint() const;
|
||||
virtual void setSize_recursive(QSize newSize, ChildrenResizeStrategy strategy = ChildrenResizeStrategy::Percentage);
|
||||
@@ -321,7 +323,6 @@ protected:
|
||||
explicit Item(bool isContainer, Widget *hostWidget, ItemContainer *parent);
|
||||
void setParentContainer(ItemContainer *parent);
|
||||
void connectParent(ItemContainer *parent);
|
||||
Q_REQUIRED_RESULT virtual bool checkSanity();
|
||||
void setPos(QPoint);
|
||||
void setPos(int pos, Qt::Orientation);
|
||||
const ItemContainer *asContainer() const;
|
||||
@@ -384,10 +385,18 @@ public:
|
||||
bool contains_recursive(const Item *item) const;
|
||||
int visibleCount_recursive() const override;
|
||||
int count_recursive() const;
|
||||
virtual void clear() = 0;
|
||||
|
||||
protected:
|
||||
bool hasSingleVisibleItem() const;
|
||||
|
||||
Item::List m_children;
|
||||
|
||||
Q_SIGNALS:
|
||||
void itemsChanged();
|
||||
void numVisibleItemsChanged(int);
|
||||
void numItemsChanged();
|
||||
|
||||
private:
|
||||
struct Private;
|
||||
Private *const d;
|
||||
@@ -427,7 +436,7 @@ public:
|
||||
QRect suggestedDropRect(const Item *item, const Item *relativeTo, KDDockWidgets::Location) const;
|
||||
QVariantMap toVariantMap() const override;
|
||||
void fillFromVariantMap(const QVariantMap &map, const QHash<QString, Widget *> &widgets) override;
|
||||
void clear();
|
||||
void clear() override;
|
||||
Qt::Orientation orientation() const;
|
||||
bool isVertical() const;
|
||||
bool isHorizontal() const;
|
||||
@@ -516,10 +525,6 @@ private:
|
||||
bool test_suggestedRect();
|
||||
#endif
|
||||
|
||||
Q_SIGNALS:
|
||||
void itemsChanged();
|
||||
void numVisibleItemsChanged(int);
|
||||
void numItemsChanged();
|
||||
public:
|
||||
QVector<Layouting::Separator*> separators_recursive() const;
|
||||
QVector<Layouting::Separator*> separators() const;
|
||||
|
||||
Reference in New Issue
Block a user