245 lines
7.1 KiB
C++
245 lines
7.1 KiB
C++
/*
|
|
This file is part of KDDockWidgets.
|
|
|
|
SPDX-FileCopyrightText: 2020-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
|
Author: Sérgio Martins <sergio.martins@kdab.com>
|
|
|
|
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
|
|
|
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
* @brief A widget that supports an arbitrary number of splitters (called Separators) in any
|
|
* combination of vertical/horizontal.
|
|
*
|
|
* This is a widget wrapper around the multisplitter layout (Layouting::Item)
|
|
*
|
|
* @author Sérgio Martins \<sergio.martins@kdab.com\>
|
|
*/
|
|
|
|
#ifndef KDDOCKWIDGETS_LAYOUTWIDGET_P_H
|
|
#define KDDOCKWIDGETS_LAYOUTWIDGET_P_H
|
|
|
|
#pragma once
|
|
|
|
#include "View.h"
|
|
#include "kddockwidgets/docks_export.h"
|
|
#include "kddockwidgets/KDDockWidgets.h"
|
|
#include "kddockwidgets/LayoutSaver.h"
|
|
#include "kdbindings/signal.h"
|
|
|
|
#include <QList>
|
|
|
|
namespace Layouting {
|
|
class Item;
|
|
class ItemContainer;
|
|
class Separator;
|
|
}
|
|
|
|
namespace KDDockWidgets {
|
|
|
|
namespace Controllers {
|
|
class Frame;
|
|
class FloatingWindow;
|
|
class DockWidget;
|
|
class MainWindow;
|
|
}
|
|
|
|
namespace Controllers {
|
|
|
|
/**
|
|
* @brief The widget (QWidget or QQuickItem) which holds a layout of dock widgets.
|
|
*
|
|
* Usually this would simply be MultiSplitter, but we've introduced this base class to support
|
|
* different layouts, like MDI layouts, which are very different than traditional dock widget
|
|
* layouts.
|
|
*
|
|
* This class makes the bridge between the GUI world (QWidget) and Layouting::Item world.
|
|
* It's suitable to be set as a main window central widget for instance. The actual layouting is
|
|
* then done by the root Item.
|
|
*/
|
|
class DOCKS_EXPORT Layout : public Controller
|
|
{
|
|
public:
|
|
explicit Layout(Type, View *);
|
|
~Layout();
|
|
|
|
/// @brief Returns whether this layout is in a MainWindow
|
|
/// @param honourNesting If true, then we'll count DropAreas/MDIAreas which are nested into DropAreas/MDIAreas as inside the main window.
|
|
/// otherwise, only direct parenting is considered
|
|
bool isInMainWindow(bool honourNesting = false) const;
|
|
|
|
Controllers::MainWindow *mainWindow(bool honourNesting = false) const;
|
|
|
|
Controllers::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 layoutWidth() const
|
|
{
|
|
return layoutSize().width();
|
|
}
|
|
|
|
/**
|
|
* @brief returns the contents height.
|
|
* Usually it's the same height as the respective parent MultiSplitter.
|
|
*/
|
|
int layoutHeight() const
|
|
{
|
|
return layoutSize().height();
|
|
}
|
|
|
|
/**
|
|
* @brief Returns the size of the contents
|
|
*/
|
|
QSize layoutSize() 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(Controllers::DockWidget *dw, Layouting::Item *, int tabIndex);
|
|
|
|
/**
|
|
* @brief The list of items in this layout.
|
|
*/
|
|
const QVector<Layouting::Item *> items() const;
|
|
|
|
/**
|
|
* @brief Returns true if this layout contains the specified item.
|
|
*/
|
|
bool containsItem(const Layouting::Item *) const;
|
|
|
|
/**
|
|
* @brief Returns true if this layout contains the specified frame.
|
|
*/
|
|
bool containsFrame(const Controllers::Frame *) const;
|
|
|
|
/**
|
|
* @brief Returns the number of Item objects in this layout.
|
|
* This includes non-visible (placeholder) Items too.
|
|
* @sa visibleCount
|
|
*/
|
|
int count() const;
|
|
|
|
/**
|
|
* @brief Returns the number of visible Items in this layout.
|
|
* Which is @ref count minus @ref placeholderCount
|
|
* @sa count
|
|
*/
|
|
int visibleCount() const;
|
|
|
|
/**
|
|
* @brief Returns the number of placeholder items in this layout.
|
|
* This is the same as @ref count minus @ref visibleCount
|
|
* @sa count, visibleCount
|
|
*/
|
|
int placeholderCount() const;
|
|
|
|
/**
|
|
* @brief returns the Item that holds @p frame in this layout
|
|
*/
|
|
Layouting::Item *itemForFrame(const Controllers::Frame *frame) const;
|
|
|
|
/**
|
|
* @brief Returns this list of Frame objects contained in this layout
|
|
*/
|
|
QList<Controllers::Frame *> frames() const;
|
|
|
|
/// @brief Returns the list of dock widgets contained in this layout
|
|
QVector<Controllers::DockWidget *> dockWidgets() const;
|
|
|
|
/**
|
|
* @brief Removes an item from this MultiSplitter.
|
|
*/
|
|
void removeItem(Layouting::Item *item);
|
|
|
|
/**
|
|
* @brief Updates the min size of this layout.
|
|
*/
|
|
void updateSizeConstraints();
|
|
|
|
virtual bool deserialize(const LayoutSaver::MultiSplitter &);
|
|
LayoutSaver::MultiSplitter serialize() const;
|
|
|
|
Controllers::DropArea *asDropArea() const;
|
|
Controllers::MDILayout *asMDILayout() const;
|
|
|
|
/// @brief Emitted when the count of visible widgets changes
|
|
KDBindings::Signal<int> visibleWidgetCountChanged;
|
|
|
|
/// TODOm3: Better a signal, so that derived classes don't have to remember to call these
|
|
bool onResize(QSize newSize);
|
|
|
|
/// TODOm3: Remove
|
|
void viewAboutToBeDeleted();
|
|
|
|
protected:
|
|
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<Controllers::Frame *> &framesBeingAdded) const;
|
|
|
|
/**
|
|
* @brief returns the frames contained in @p frameOrMultiSplitter
|
|
* If frameOrMultiSplitter is a Frame, it returns a list of 1 element, with that frame
|
|
* If frameOrMultiSplitter is a MultiSplitter then it returns a list of all frames it contains
|
|
*/
|
|
QList<Controllers::Frame *> framesFrom(View *frameOrMultiSplitter) const;
|
|
|
|
private:
|
|
bool m_inResizeEvent = false;
|
|
Layouting::ItemContainer *m_rootItem = nullptr;
|
|
KDBindings::ConnectionHandle m_minSizeChangedHandler;
|
|
bool m_viewDeleted = false;
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|