634 lines
22 KiB
C++
634 lines
22 KiB
C++
/*
|
|
This file is part of KDDockWidgets.
|
|
|
|
SPDX-FileCopyrightText: 2019 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.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "kddockwidgets/docks_export.h"
|
|
#include "kddockwidgets/KDDockWidgets.h"
|
|
|
|
#include "kdbindings/signal.h"
|
|
#include "nlohmann/json.hpp"
|
|
|
|
#include <memory>
|
|
#include <unordered_map>
|
|
|
|
namespace KDDockWidgets {
|
|
|
|
namespace Core {
|
|
class View;
|
|
class ItemContainer;
|
|
class ItemBoxContainer;
|
|
class Item;
|
|
struct LengthOnSide;
|
|
|
|
class LayoutingHost;
|
|
class LayoutingGuest;
|
|
class LayoutingSeparator;
|
|
typedef void (*DumpScreenInfoFunc)();
|
|
typedef LayoutingSeparator *(*CreateSeparatorFunc)(Core::LayoutingHost *host, Qt::Orientation, Core::ItemBoxContainer *);
|
|
|
|
enum Side {
|
|
Side1,
|
|
Side2
|
|
};
|
|
|
|
enum class GrowthStrategy {
|
|
BothSidesEqually,
|
|
Side1Only,
|
|
Side2Only
|
|
};
|
|
|
|
enum class SeparatorOption {
|
|
None = 0,
|
|
LazyResize
|
|
};
|
|
Q_DECLARE_FLAGS(SeparatorOptions, SeparatorOption)
|
|
|
|
enum class ChildrenResizeStrategy {
|
|
Percentage, ///< Resizes the container in a way that all children will keep occupying the same
|
|
///< percentage
|
|
Side1SeparatorMove, ///< When resizing a container, it takes/adds space from Side1 children
|
|
///< first
|
|
Side2SeparatorMove, ///< When resizing a container, it takes/adds space from Side2 children first
|
|
GiveDropAreaWithCentralFrameAllExtra ///< When resizing a container, it gives all extra space to a drop area with central frame fix, otherwise same as Percentage
|
|
};
|
|
|
|
enum LayoutBorderLocation {
|
|
LayoutBorderLocation_None = 0,
|
|
LayoutBorderLocation_North = 1,
|
|
LayoutBorderLocation_East = 2,
|
|
LayoutBorderLocation_West = 4,
|
|
LayoutBorderLocation_South = 8,
|
|
LayoutBorderLocation_All = LayoutBorderLocation_North | LayoutBorderLocation_East
|
|
| LayoutBorderLocation_West | LayoutBorderLocation_South,
|
|
LayoutBorderLocation_Verticals = LayoutBorderLocation_West | LayoutBorderLocation_East,
|
|
LayoutBorderLocation_Horizontals = LayoutBorderLocation_North | LayoutBorderLocation_South,
|
|
};
|
|
Q_DECLARE_FLAGS(LayoutBorderLocations, LayoutBorderLocation)
|
|
|
|
inline int pos(Point p, Qt::Orientation o)
|
|
{
|
|
return o == Qt::Vertical ? p.y() : p.x();
|
|
}
|
|
|
|
inline int length(Size sz, Qt::Orientation o)
|
|
{
|
|
return o == Qt::Vertical ? sz.height() : sz.width();
|
|
}
|
|
|
|
struct DOCKS_EXPORT SizingInfo
|
|
{
|
|
SizingInfo();
|
|
|
|
Size size() const
|
|
{
|
|
return geometry.size();
|
|
}
|
|
|
|
void setSize(Size sz)
|
|
{
|
|
geometry.setSize(sz);
|
|
}
|
|
|
|
int length(Qt::Orientation o) const
|
|
{
|
|
return Core::length(size(), o);
|
|
}
|
|
|
|
int minLength(Qt::Orientation o) const
|
|
{
|
|
return Core::length(minSize, o);
|
|
}
|
|
|
|
int maxLengthHint(Qt::Orientation o) const;
|
|
int availableLength(Qt::Orientation o) const;
|
|
int missingLength(Qt::Orientation o) const;
|
|
|
|
Point pos() const
|
|
{
|
|
return geometry.topLeft();
|
|
}
|
|
|
|
int position(Qt::Orientation o) const
|
|
{
|
|
return Core::pos(pos(), o);
|
|
}
|
|
|
|
int edge(Qt::Orientation o) const
|
|
{
|
|
return o == Qt::Vertical ? geometry.bottom() : geometry.right();
|
|
}
|
|
|
|
void setLength(int l, Qt::Orientation o)
|
|
{
|
|
if (o == Qt::Vertical) {
|
|
geometry.setHeight(l);
|
|
} else {
|
|
geometry.setWidth(l);
|
|
}
|
|
}
|
|
|
|
void incrementLength(int byAmount, Qt::Orientation o)
|
|
{
|
|
setLength(length(o) + byAmount, o);
|
|
}
|
|
|
|
void setOppositeLength(int l, Qt::Orientation o);
|
|
|
|
void setPos(int p, Qt::Orientation o)
|
|
{
|
|
if (o == Qt::Vertical)
|
|
geometry.moveTop(p);
|
|
else
|
|
geometry.moveLeft(p);
|
|
}
|
|
|
|
bool isNull() const
|
|
{
|
|
return geometry.isNull();
|
|
}
|
|
|
|
void setGeometry(Rect geo)
|
|
{
|
|
geometry = geo;
|
|
}
|
|
|
|
int availableToGrow(Qt::Orientation o) const
|
|
{
|
|
return maxLengthHint(o) - length(o);
|
|
}
|
|
|
|
int neededToShrink(Qt::Orientation o) const;
|
|
|
|
bool isPastMax(Qt::Orientation o) const
|
|
{
|
|
return availableToGrow(o) >= 0;
|
|
}
|
|
|
|
typedef Vector<SizingInfo> List;
|
|
Rect geometry;
|
|
Size minSize;
|
|
Size maxSizeHint;
|
|
double percentageWithinParent = 0.0;
|
|
bool isBeingInserted = false;
|
|
};
|
|
|
|
class DOCKS_EXPORT Item : public Core::Object
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
typedef Vector<Item *> List;
|
|
|
|
explicit Item(KDDockWidgets::Core::LayoutingHost *hostWidget, ItemContainer *parent = nullptr);
|
|
~Item() override;
|
|
|
|
/// @brief returns whether this item is a root container
|
|
bool isRoot() const;
|
|
|
|
///@brief Returns whether the item is touching the layout's borders.
|
|
/// Returns Location_None if it's not touching a border.
|
|
LayoutBorderLocations adjacentLayoutBorders() const;
|
|
|
|
virtual int visibleCount_recursive() const;
|
|
|
|
/**
|
|
* @brief No widget can have a minimum size smaller than this, regardless of their minimum size.
|
|
*/
|
|
static Size hardcodedMinimumSize;
|
|
static Size hardcodedMaximumSize;
|
|
|
|
/// The width of a vertical separator, or height of horizontal one
|
|
/// Usually 5px
|
|
static int separatorThickness;
|
|
|
|
/// The spacing between dock widgets
|
|
/// This is by default, the separatorThickness, as the separator is between dockwidgets.
|
|
/// If set to a value smaller than separatorThickness, then the separators will overlap on top
|
|
/// of the dockwidgets, which can be useful in certain styles.
|
|
static int layoutSpacing;
|
|
|
|
int x() const;
|
|
int y() const;
|
|
int width() const;
|
|
int height() const;
|
|
Size size() const;
|
|
void setSize(Size);
|
|
|
|
/// Unlike setSize(), which just stores data, requestResize() asks the parent container
|
|
/// to resize this item and all its neighbours. This is convenience API for users wanting
|
|
/// to programmatically resize a dock widget. Not really used by the usual layouting.
|
|
/// API semantics work like QRect::adjust(), positive values always increase size.
|
|
void requestResize(int left, int top, int right, int bottom);
|
|
|
|
Point pos() const;
|
|
int pos(Qt::Orientation) const;
|
|
Rect geometry() const;
|
|
Rect rect() const;
|
|
bool isContainer() const;
|
|
ItemContainer *parentContainer() const;
|
|
|
|
/// Returns the parent container, but casted to ItemBoxContainer
|
|
ItemBoxContainer *parentBoxContainer() const;
|
|
|
|
int indexInAncestor(ItemContainer *, bool visibleOnly = true) const;
|
|
|
|
/// Returns the 1st ancestor container that has the desired orientation
|
|
/// Example:
|
|
/// - ItemBoxContainer(Vertical)
|
|
/// -- ItemBoxContainer(Horizontal)
|
|
/// --- Item // Passing this item to ancestorBoxContainerWithOrientation(Qt::Vertical) would
|
|
/// skip the direct parent and return the verticl one.
|
|
ItemBoxContainer *ancestorBoxContainerWithOrientation(Qt::Orientation) const;
|
|
|
|
void setMinSize(Size);
|
|
void setMaxSizeHint(Size);
|
|
bool isPlaceholder() const;
|
|
void setGeometry(Rect rect);
|
|
ItemBoxContainer *root() const;
|
|
Rect mapToRoot(Rect) const;
|
|
Point mapToRoot(Point) const;
|
|
int mapToRoot(int p, Qt::Orientation) const;
|
|
Point mapFromRoot(Point) const;
|
|
Rect mapFromRoot(Rect) const;
|
|
Point mapFromParent(Point) const;
|
|
int mapFromRoot(int p, Qt::Orientation) const;
|
|
|
|
LayoutingHost *host() const;
|
|
LayoutingGuest *guest() const;
|
|
|
|
void setGuest(LayoutingGuest *);
|
|
|
|
void ref();
|
|
void unref();
|
|
int refCount() const;
|
|
void turnIntoPlaceholder();
|
|
|
|
int minLength(Qt::Orientation) const;
|
|
int maxLengthHint(Qt::Orientation) const;
|
|
|
|
void restore(LayoutingGuest *);
|
|
|
|
Vector<int> pathFromRoot() const;
|
|
|
|
Q_REQUIRED_RESULT virtual bool checkSanity();
|
|
bool isMDI() const;
|
|
virtual bool inSetSize() const;
|
|
|
|
static bool s_silenceSanityChecks;
|
|
|
|
Item *outermostNeighbor(Location, bool visibleOnly = true) const;
|
|
Item *outermostNeighbor(Side, Qt::Orientation, bool visibleOnly) const;
|
|
|
|
virtual Size minSize() const;
|
|
virtual Size maxSizeHint() const;
|
|
virtual void
|
|
setSize_recursive(Size newSize,
|
|
ChildrenResizeStrategy strategy = ChildrenResizeStrategy::Percentage);
|
|
virtual bool isVisible(bool excludeBeingInserted = false) const;
|
|
virtual void setGeometry_recursive(Rect rect);
|
|
virtual void dumpLayout(int level = 0, bool printSeparators = true);
|
|
virtual void setHost(KDDockWidgets::Core::LayoutingHost *);
|
|
virtual void to_json(nlohmann::json &) const;
|
|
|
|
virtual void fillFromJson(const nlohmann::json &,
|
|
const std::unordered_map<QString, LayoutingGuest *> &);
|
|
|
|
static Item *createFromJson(LayoutingHost *hostWidget, ItemContainer *parent,
|
|
const nlohmann::json &,
|
|
const std::unordered_map<QString, LayoutingGuest *> &);
|
|
|
|
static void setDumpScreenInfoFunc(DumpScreenInfoFunc);
|
|
static void setCreateSeparatorFunc(CreateSeparatorFunc);
|
|
|
|
KDBindings::Signal<> geometryChanged;
|
|
KDBindings::Signal<> xChanged;
|
|
KDBindings::Signal<> yChanged;
|
|
KDBindings::Signal<> widthChanged;
|
|
KDBindings::Signal<> heightChanged;
|
|
KDBindings::Signal<Core::Item *, bool> visibleChanged;
|
|
KDBindings::Signal<Core::Item *> minSizeChanged;
|
|
KDBindings::Signal<Core::Item *> maxSizeChanged;
|
|
/// signal emitted when ~Item starts
|
|
KDBindings::Signal<> aboutToBeDeleted;
|
|
KDBindings::Signal<> deleted;
|
|
|
|
public:
|
|
explicit Item(bool isContainer, KDDockWidgets::Core::LayoutingHost *hostWidget, ItemContainer *parent);
|
|
void setParentContainer(ItemContainer *parent);
|
|
void connectParent(ItemContainer *parent);
|
|
void setPos(Point);
|
|
void setPos(int pos, Qt::Orientation);
|
|
const ItemContainer *asContainer() const;
|
|
ItemContainer *asContainer();
|
|
ItemBoxContainer *asBoxContainer();
|
|
void setLength(int length, Qt::Orientation);
|
|
virtual void setLength_recursive(int length, Qt::Orientation);
|
|
int length(Qt::Orientation) const;
|
|
int availableLength(Qt::Orientation) const;
|
|
Size missingSize() const;
|
|
virtual void updateWidgetGeometries();
|
|
virtual void setIsVisible(bool);
|
|
bool isBeingInserted() const;
|
|
void setBeingInserted(bool);
|
|
|
|
SizingInfo m_sizingInfo;
|
|
const bool m_isContainer;
|
|
ItemContainer *m_parent = nullptr;
|
|
bool m_isSettingGuest = false;
|
|
bool m_inDtor = false;
|
|
private Q_SLOTS:
|
|
void onWidgetLayoutRequested();
|
|
|
|
private:
|
|
friend class ItemContainer;
|
|
friend class ItemBoxContainer;
|
|
friend class ItemFreeContainer;
|
|
int m_refCount = 0;
|
|
void onGuestDestroyed();
|
|
bool m_isVisible = false;
|
|
bool m_inSetSize = false;
|
|
LayoutingHost *m_host = nullptr;
|
|
LayoutingGuest *m_guest = nullptr;
|
|
static DumpScreenInfoFunc s_dumpScreenInfoFunc;
|
|
static CreateSeparatorFunc s_createSeparatorFunc;
|
|
|
|
KDBindings::ConnectionHandle m_parentChangedConnection;
|
|
KDBindings::ConnectionHandle m_minSizeChangedHandle;
|
|
KDBindings::ConnectionHandle m_visibleChangedHandle;
|
|
KDBindings::ScopedConnection m_layoutInvalidatedConnection;
|
|
KDBindings::ScopedConnection m_guestDestroyedConnection;
|
|
};
|
|
|
|
/// @brief And Item which can contain other Items
|
|
class DOCKS_EXPORT ItemContainer : public Item
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
explicit ItemContainer(LayoutingHost *hostWidget, ItemContainer *parent);
|
|
explicit ItemContainer(LayoutingHost *hostWidget);
|
|
~ItemContainer();
|
|
|
|
virtual void removeItem(Item *, bool hardRemove = true) = 0;
|
|
virtual void restore(Item *child) = 0;
|
|
virtual void onChildMinSizeChanged(Item *child) = 0;
|
|
virtual void onChildVisibleChanged(Item *child, bool visible) = 0;
|
|
|
|
int numVisibleChildren() const;
|
|
int numChildren() const;
|
|
bool hasChildren() const;
|
|
bool hasVisibleChildren(bool excludeBeingInserted = false) const;
|
|
List childItems() const;
|
|
int indexOfChild(const Item *child) const;
|
|
bool isEmpty() const;
|
|
bool contains(const Item *item) const;
|
|
Item *itemForView(const LayoutingGuest *) const;
|
|
Item::List visibleChildren(bool includeBeingInserted = false) const;
|
|
Item::List items_recursive() const;
|
|
bool contains_recursive(const Item *item) const;
|
|
int visibleCount_recursive() const override;
|
|
int count_recursive() const;
|
|
virtual void clear() = 0;
|
|
bool inSetSize() const override;
|
|
|
|
public:
|
|
KDBindings::Signal<> itemsChanged;
|
|
KDBindings::Signal<> numItemsChanged;
|
|
KDBindings::Signal<int> numVisibleItemsChanged;
|
|
|
|
protected:
|
|
bool hasSingleVisibleItem() const;
|
|
Item::List m_children;
|
|
|
|
private:
|
|
struct Private;
|
|
Private *const d;
|
|
};
|
|
|
|
/// @brief A container for items which can either be vertical or horizontal
|
|
///
|
|
/// Similar analogy to QBoxLayout
|
|
class DOCKS_EXPORT ItemBoxContainer : public ItemContainer
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
explicit ItemBoxContainer(LayoutingHost *hostWidget, ItemContainer *parent);
|
|
explicit ItemBoxContainer(LayoutingHost *hostWidget);
|
|
~ItemBoxContainer();
|
|
void insertItem(Item *item, int index,
|
|
const KDDockWidgets::InitialOption &option = KDDockWidgets::DefaultSizeMode::Fair);
|
|
void insertItem(Item *item, KDDockWidgets::Location, const KDDockWidgets::InitialOption & = {});
|
|
|
|
static void
|
|
insertItemRelativeTo(Item *item, Item *relativeTo, KDDockWidgets::Location,
|
|
const KDDockWidgets::InitialOption & = KDDockWidgets::DefaultSizeMode::Fair);
|
|
|
|
void requestSeparatorMove(LayoutingSeparator *separator, int delta);
|
|
int minPosForSeparator(LayoutingSeparator *, bool honourMax = true) const;
|
|
int maxPosForSeparator(LayoutingSeparator *, bool honourMax = true) const;
|
|
int minPosForSeparator_global(LayoutingSeparator *,
|
|
bool honourMax = true) const;
|
|
int maxPosForSeparator_global(LayoutingSeparator *,
|
|
bool honourMax = true) const;
|
|
void requestEqualSize(LayoutingSeparator *separator);
|
|
void layoutEqually();
|
|
void layoutEqually_recursive();
|
|
void removeItem(Item *, bool hardRemove = true) override;
|
|
Size minSize() const override;
|
|
Size maxSizeHint() const override;
|
|
Size availableSize() const;
|
|
bool percentagesAreSane() const;
|
|
Q_REQUIRED_RESULT bool checkSanity() override;
|
|
void dumpLayout(int level = 0, bool printSeparators = true) override;
|
|
void setSize_recursive(
|
|
Size newSize,
|
|
ChildrenResizeStrategy strategy = ChildrenResizeStrategy::Percentage) override;
|
|
bool hostSupportsHonouringLayoutMinSize() const;
|
|
Rect suggestedDropRect(const Item *item, const Item *relativeTo,
|
|
KDDockWidgets::Location) const;
|
|
void to_json(nlohmann::json &) const override;
|
|
void fillFromJson(const nlohmann::json &,
|
|
const std::unordered_map<QString, LayoutingGuest *> &) override;
|
|
void clear() override;
|
|
Qt::Orientation orientation() const;
|
|
bool isVertical() const;
|
|
bool isHorizontal() const;
|
|
int length() const;
|
|
bool hasOrientation() const;
|
|
bool isOverflowing() const;
|
|
bool isDeserializing() const;
|
|
|
|
/// @brief Returns the number of visible items layed-out horizontally or vertically
|
|
/// But honours nesting
|
|
int numSideBySide_recursive(Qt::Orientation) const;
|
|
|
|
int availableLength() const;
|
|
LengthOnSide lengthOnSide(const SizingInfo::List &sizes, int fromIndex, Side,
|
|
Qt::Orientation) const;
|
|
int neighboursLengthFor(const Item *item, Side, Qt::Orientation) const;
|
|
int neighboursLengthFor_recursive(const Item *item, Side, Qt::Orientation) const;
|
|
int neighboursMinLengthFor(const Item *item, Side, Qt::Orientation) const;
|
|
int neighboursMaxLengthFor(const Item *item, Side, Qt::Orientation) const;
|
|
int availableToSqueezeOnSide(const Item *child, Side) const;
|
|
int availableToGrowOnSide(const Item *child, Side) const;
|
|
int availableToSqueezeOnSide_recursive(const Item *child, Side, Qt::Orientation) const;
|
|
int availableToGrowOnSide_recursive(const Item *child, Side, Qt::Orientation) const;
|
|
|
|
private:
|
|
int indexOfVisibleChild(const Item *) const;
|
|
void restore(Item *) override;
|
|
void restoreChild(Item *, bool forceRestoreContainer,
|
|
NeighbourSqueezeStrategy neighbourSqueezeStrategy);
|
|
|
|
void setGeometry_recursive(Rect rect) override;
|
|
|
|
ItemBoxContainer *convertChildToContainer(Item *leaf, const InitialOption &);
|
|
bool hasOrientationFor(KDDockWidgets::Location) const;
|
|
int usableLength() const;
|
|
void setChildren(const Item::List &children, Qt::Orientation o);
|
|
void setOrientation(Qt::Orientation);
|
|
void updateChildPercentages();
|
|
void updateChildPercentages_recursive();
|
|
void updateWidgetGeometries() override;
|
|
int oppositeLength() const;
|
|
|
|
void layoutEqually(SizingInfo::List &sizes);
|
|
|
|
///@brief Grows the side1Neighbour to the right and the side2Neighbour to the left
|
|
/// So they occupy the empty space that's between them (or bottom/top if Qt::Vertical).
|
|
/// This is useful when an Item is removed. Its neighbours will occupy its space.
|
|
/// side1Neighbour or side2Neighbour are allowed to be null, in which case the non-null one
|
|
/// will occupy the entire space.
|
|
void growNeighbours(Item *side1Neighbour, Item *side2Neighbour);
|
|
|
|
///@brief grows an item by @p amount. It calculates how much to grow on side1 and on side2
|
|
/// Then calls growItem(item, side1Growth, side2Growth) which will effectively grow it,
|
|
/// and shrink the neighbours which are donating the size.
|
|
void growItem(Item *, int amount, GrowthStrategy,
|
|
NeighbourSqueezeStrategy neighbourSqueezeStrategy,
|
|
bool accountForNewSeparator = false,
|
|
ChildrenResizeStrategy = ChildrenResizeStrategy::Percentage);
|
|
void growItem(int index, SizingInfo::List &sizes, int missing, GrowthStrategy,
|
|
NeighbourSqueezeStrategy neighbourSqueezeStrategy,
|
|
bool accountForNewSeparator = false);
|
|
|
|
///@brief Shrinks the neighbours of the item at @p index
|
|
///
|
|
/// The neighbours at the left/top of the item, will be shrunk by @p side1Amount, while the
|
|
/// items at right/bottom will be shrunk by @p side2Amount. Squeezes all the neighbours (not
|
|
/// just the immediate ones).
|
|
void shrinkNeighbours(int index, SizingInfo::List &sizes, int side1Amount, int side2Amount,
|
|
NeighbourSqueezeStrategy);
|
|
|
|
Item *visibleNeighbourFor(const Item *item, Side side) const;
|
|
|
|
void onChildMinSizeChanged(Item *child) override;
|
|
void onChildVisibleChanged(Item *child, bool visible) override;
|
|
void updateSizeConstraints();
|
|
SizingInfo::List sizes(bool ignoreBeingInserted = false) const;
|
|
Vector<int> calculateSqueezes(SizingInfo::List::const_iterator begin,
|
|
SizingInfo::List::const_iterator end, int needed,
|
|
NeighbourSqueezeStrategy, bool reversed = false) const;
|
|
Rect suggestedDropRectFallback(const Item *item, const Item *relativeTo,
|
|
KDDockWidgets::Location) const;
|
|
Item *itemAt(Point p) const;
|
|
Item *itemAt_recursive(Point p) const;
|
|
void setHost(KDDockWidgets::Core::LayoutingHost *) override;
|
|
void setIsVisible(bool) override;
|
|
bool isVisible(bool excludeBeingInserted = false) const override;
|
|
void setLength_recursive(int length, Qt::Orientation) override;
|
|
void applyGeometries(const SizingInfo::List &sizes,
|
|
ChildrenResizeStrategy = ChildrenResizeStrategy::Percentage);
|
|
void applyPositions(const SizingInfo::List &sizes);
|
|
|
|
int indexOf(LayoutingSeparator *) const;
|
|
bool isInSimplify() const;
|
|
|
|
public:
|
|
Vector<LayoutingSeparator *> separators_recursive() const;
|
|
Vector<LayoutingSeparator *> separators() const;
|
|
|
|
/// Returns the separator for the specified child on the specified child
|
|
/// Example:
|
|
/// - If this layout is horizontal, and side is Side1, then the left separator is returned.
|
|
/// - If this layout is horizontal, and side is Side2, then the right separator is returned.
|
|
/// - top, bottom if vertical layout.
|
|
/// @sa adjacentSeparatorForChild
|
|
LayoutingSeparator *separatorForChild(Item *child, Side side) const;
|
|
|
|
/// Returns the separator for the specified child on the specified child
|
|
/// Example:
|
|
/// - If this layout is horizontal, and side is Side1, then the top separator is returned.
|
|
/// - If this layout is horizontal, and side is Side2, then the bottom separator is returned.
|
|
/// - left, right if vertical layout.
|
|
/// @sa separatorForChild
|
|
LayoutingSeparator *adjacentSeparatorForChild(Item *child, Side side) const;
|
|
|
|
#ifdef DOCKS_DEVELOPER_MODE
|
|
bool
|
|
test_suggestedRect();
|
|
void relayoutIfNeeded();
|
|
#endif
|
|
|
|
#ifdef DOCKS_DEVELOPER_MODE
|
|
public:
|
|
#else
|
|
private:
|
|
#endif
|
|
void simplify();
|
|
|
|
/// Puts the items in their respective places. i.e. lays them sequentially, spaced by 5px (separator thickness)
|
|
/// does not resize.
|
|
void positionItems();
|
|
void positionItems_recursive();
|
|
void positionItems(SizingInfo::List &sizes);
|
|
|
|
static bool s_inhibitSimplify;
|
|
friend class Core::Item;
|
|
struct Private;
|
|
Private *const d;
|
|
};
|
|
|
|
/// QtQuick triggers a lot of resizes due to bindings being updated individually
|
|
/// Only check sanity at the end of an operation, and not each time a binding gets evaluated
|
|
/// Tests will fail with a warning if anything is wrong.
|
|
struct AtomicSanityChecks
|
|
{
|
|
AtomicSanityChecks(Item *root)
|
|
: m_oldValue(Item::s_silenceSanityChecks)
|
|
, m_root(root)
|
|
{
|
|
Item::s_silenceSanityChecks = true;
|
|
}
|
|
|
|
~AtomicSanityChecks()
|
|
{
|
|
Item::s_silenceSanityChecks = m_oldValue;
|
|
#ifdef DOCKS_DEVELOPER_MODE
|
|
if (m_root) {
|
|
const bool result = m_root->checkSanity();
|
|
KDDW_UNUSED(result);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
const bool m_oldValue;
|
|
Item *const m_root;
|
|
KDDW_DELETE_COPY_CTOR(AtomicSanityChecks)
|
|
};
|
|
|
|
DOCKS_EXPORT void from_json(const nlohmann::json &, SizingInfo &);
|
|
DOCKS_EXPORT void to_json(nlohmann::json &, const SizingInfo &);
|
|
DOCKS_EXPORT void to_json(nlohmann::json &, Item *);
|
|
|
|
} // Core
|
|
|
|
} // KDDockWidgets
|