2016-05-17 03:04:11 +12:00
|
|
|
#pragma once
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
#ifndef DOCKLAYOUT_H
|
|
|
|
#define DOCKLAYOUT_H
|
|
|
|
|
|
|
|
#include "tcommon.h"
|
|
|
|
|
|
|
|
#include <QWidget>
|
|
|
|
#include <QAction>
|
|
|
|
|
|
|
|
#include <deque>
|
|
|
|
#include <vector>
|
|
|
|
#include <QLayout>
|
|
|
|
#include <QFrame>
|
|
|
|
#include "docklayout.h"
|
|
|
|
|
|
|
|
#undef DVAPI
|
|
|
|
#undef DVVAR
|
|
|
|
#ifdef TOONZQT_EXPORTS
|
|
|
|
#define DVAPI DV_EXPORT_API
|
|
|
|
#define DVVAR DV_EXPORT_VAR
|
|
|
|
#else
|
|
|
|
#define DVAPI DV_IMPORT_API
|
|
|
|
#define DVVAR DV_IMPORT_VAR
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//-------------------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
// Forward Declarations
|
2016-03-19 06:57:51 +13:00
|
|
|
class DockLayout;
|
|
|
|
class DockWidget;
|
|
|
|
|
|
|
|
class DockPlaceholder;
|
|
|
|
class DockSeparator;
|
|
|
|
class DockDecoAllocator;
|
|
|
|
|
|
|
|
class Region;
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
//--------------------------
|
|
|
|
// Docking Lock Check
|
|
|
|
//--------------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
//! Singleton for docking system lock.
|
|
|
|
class DVAPI DockingCheck {
|
|
|
|
bool m_enabled;
|
|
|
|
QAction *m_toggle;
|
|
|
|
DockingCheck() : m_enabled(false), m_toggle(0) {}
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
static DockingCheck *instance();
|
|
|
|
void setToggle(QAction *toggle);
|
|
|
|
bool isEnabled() const { return m_enabled; }
|
|
|
|
void setIsEnabled(bool on);
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
//-------------------
|
|
|
|
// Dock Layout
|
|
|
|
//-------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
//! DockLayout inherits the abstract QLayout to provide a docking system for
|
|
|
|
//! widgets.
|
2016-03-19 06:57:51 +13:00
|
|
|
/*!
|
2016-06-15 18:43:10 +12:00
|
|
|
\b IMPORTANT NOTE: Observe that the addWidget() method expects only widgets of
|
|
|
|
type DockWidget, so any other
|
2016-03-19 06:57:51 +13:00
|
|
|
widget type added to this kind of Layout will cause a run-time error.
|
|
|
|
|
|
|
|
\sa DockWidget and DockSeparator classes.
|
|
|
|
*/
|
2016-06-29 18:17:12 +12:00
|
|
|
class DVAPI DockLayout final : public QLayout {
|
2016-06-15 18:43:10 +12:00
|
|
|
std::vector<QLayoutItem *> m_items;
|
|
|
|
std::deque<Region *> m_regions;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
DockWidget
|
|
|
|
*m_maximizedDock; // Let the layout know if there is a maximized widget
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
// Decoration-related allocator (separators)
|
|
|
|
DockDecoAllocator *m_decoAllocator;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
DockLayout();
|
|
|
|
virtual ~DockLayout();
|
|
|
|
|
|
|
|
// QLayout item handling (see Qt reference)
|
2016-06-19 20:06:29 +12:00
|
|
|
int count(void) const override;
|
|
|
|
void addItem(QLayoutItem *item) override;
|
|
|
|
QSize sizeHint() const override;
|
|
|
|
QSize minimumSize() const override;
|
|
|
|
QSize maximumSize() const override;
|
|
|
|
QLayoutItem *itemAt(int) const override;
|
2016-06-15 18:43:10 +12:00
|
|
|
QWidget *widgetAt(int) const;
|
2016-06-19 20:06:29 +12:00
|
|
|
QLayoutItem *takeAt(int) override;
|
|
|
|
void setGeometry(const QRect &rect) override;
|
2016-06-15 18:43:10 +12:00
|
|
|
|
2020-10-19 12:33:59 +13:00
|
|
|
void update(); // Re-applies partition found
|
|
|
|
void redistribute(bool allowFixedItems = true); // Calculates partition
|
2021-07-08 13:39:28 +12:00
|
|
|
void applyTransform(const QTransform &transform); // Applies transformation to
|
|
|
|
// known partition - Da
|
2016-06-15 18:43:10 +12:00
|
|
|
// rimuovere, non serve...
|
|
|
|
|
|
|
|
DockWidget *getMaximized() { return m_maximizedDock; }
|
|
|
|
void setMaximized(
|
|
|
|
DockWidget *item,
|
|
|
|
bool state = true); // Let DockLayout handle maximization requests
|
|
|
|
|
|
|
|
// Docking and undocking methods.
|
|
|
|
Region *dockItem(DockWidget *item, Region *r = 0, int idx = 0);
|
|
|
|
void dockItem(DockWidget *item, DockPlaceholder *place);
|
|
|
|
void dockItem(DockWidget *item, DockWidget *target, int regionSide);
|
|
|
|
bool undockItem(DockWidget *item);
|
|
|
|
void calculateDockPlaceholders(DockWidget *item);
|
|
|
|
|
|
|
|
// Query methods
|
|
|
|
Region *rootRegion() const {
|
|
|
|
return m_regions.size() ? m_regions.front() : 0;
|
|
|
|
}
|
|
|
|
const std::deque<Region *> ®ions() const { return m_regions; }
|
|
|
|
Region *region(int i) const { return m_regions[i]; }
|
|
|
|
Region *find(DockWidget *item) const;
|
|
|
|
QWidget *containerOf(QPoint point) const;
|
|
|
|
|
|
|
|
// Save and load DockLayout states
|
|
|
|
typedef std::pair<std::vector<QRect>, QString> State;
|
|
|
|
|
|
|
|
State saveState();
|
|
|
|
bool restoreState(const State &state);
|
|
|
|
|
|
|
|
// Decorations allocator
|
|
|
|
void setDecoAllocator(DockDecoAllocator *decoAllocator);
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
private:
|
2016-06-15 18:43:10 +12:00
|
|
|
void applyGeometry();
|
|
|
|
inline void updateSeparatorCursors();
|
|
|
|
Region *dockItemPrivate(DockWidget *item, Region *r, int idx);
|
|
|
|
|
|
|
|
// Insertion and removal check - called internally by dock/undockItem
|
|
|
|
bool isPossibleInsertion(DockWidget *item, Region *parentRegion,
|
|
|
|
int insertionIdx);
|
|
|
|
bool isPossibleRemoval(DockWidget *item, Region *parentRegion,
|
|
|
|
int removalIdx);
|
|
|
|
|
|
|
|
// Internal save function
|
|
|
|
void writeRegion(Region *r, QString &hierarchy);
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
//-----------------------
|
|
|
|
// Dock Widget
|
|
|
|
//-----------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
//! Dockable widgets are widget containers handled by DockLayout class.
|
2016-03-19 06:57:51 +13:00
|
|
|
/*!
|
|
|
|
DockLayouts accept only dock widgets of this class; so if you want to
|
|
|
|
place a given widget under this kind of layout, a DockWidget shell for
|
|
|
|
it must be allocated first. The following class implements base dock
|
|
|
|
widgets, with native floating decorations and no docked title bar.
|
|
|
|
It is encouraged to reimplement all the essential functions for custom aspect
|
|
|
|
and behaviour.
|
|
|
|
|
|
|
|
\sa DockLayout and DockPlaceholder classes.
|
|
|
|
*/
|
2017-03-15 17:32:57 +13:00
|
|
|
class DVAPI DockWidget : public QFrame {
|
2016-06-15 18:43:10 +12:00
|
|
|
friend class DockLayout; // DockLayout is granted access to placeholders'
|
|
|
|
// privates
|
|
|
|
friend class DockPlaceholder; // As above.
|
|
|
|
// friend Region; //Regions need access to m_saveIndex field.
|
2016-07-05 22:28:44 +12:00
|
|
|
public:
|
|
|
|
void maximizeDock();
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2020-04-24 16:02:45 +12:00
|
|
|
bool getCanFixWidth() { return m_canFixWidth; }
|
|
|
|
void setCanFixWidth(bool fixed) { m_canFixWidth = fixed; }
|
|
|
|
|
2016-03-19 06:57:51 +13:00
|
|
|
protected:
|
2016-06-15 18:43:10 +12:00
|
|
|
// Private attributes for dragging purposes
|
2020-06-29 15:02:28 +12:00
|
|
|
bool m_floating; // Whether this window is floating or docked
|
|
|
|
bool m_wasFloating;
|
2016-06-15 18:43:10 +12:00
|
|
|
bool m_dragging; // Whether this window is being dragged
|
|
|
|
bool m_undocking; // Still docked, but after a mouse button press on a title
|
|
|
|
// bar.
|
|
|
|
// NOTE: m_dragging ==> !m_undocking; m_dragging=>m_floating.
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
// Private infos for resizing purposes
|
|
|
|
bool m_resizing; // Whether this window is being resized
|
|
|
|
int m_marginType; // Type of resize to consider
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
// Maximization
|
|
|
|
bool m_maximized;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2020-04-25 07:35:04 +12:00
|
|
|
// Level Strip and Style Editor use a fixed width on
|
2020-04-24 16:02:45 +12:00
|
|
|
// window resize to minimize user frustration
|
|
|
|
// This variable is only used by Level Strip right now.
|
|
|
|
// This is only true if the level strip is vertical.
|
|
|
|
bool m_canFixWidth = false;
|
|
|
|
|
2016-03-19 06:57:51 +13:00
|
|
|
private:
|
2016-06-15 18:43:10 +12:00
|
|
|
QPoint m_dragInitialPos;
|
|
|
|
QPoint m_dragMouseInitialPos;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
// Widget and Layout links
|
|
|
|
DockLayout *m_parentLayout;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
// Decoration-related allocator (placeholders)
|
|
|
|
DockDecoAllocator *m_decoAllocator;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
int m_saveIndex;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
protected:
|
2016-06-15 18:43:10 +12:00
|
|
|
// Protected infos for docking purposes
|
|
|
|
std::vector<DockPlaceholder *> m_placeholders;
|
|
|
|
DockPlaceholder *m_selectedPlace;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
DockWidget(QWidget *parent = 0, Qt::WindowFlags flags = Qt::Tool);
|
|
|
|
virtual ~DockWidget();
|
|
|
|
|
|
|
|
// Returns the DockLayout owning \b this dock widget
|
|
|
|
DockLayout *parentLayout() const { return m_parentLayout; }
|
|
|
|
|
|
|
|
bool isFloating() const { return m_floating; }
|
2020-06-29 15:02:28 +12:00
|
|
|
bool wasFloating() const { return m_wasFloating; }
|
|
|
|
void clearWasFloating() { m_wasFloating = false; }
|
2016-06-15 18:43:10 +12:00
|
|
|
bool isMaximized() const { return m_maximized; }
|
|
|
|
|
|
|
|
// Query functions
|
|
|
|
QWidget *hoveredWidget(QMouseEvent *me);
|
|
|
|
DockPlaceholder *placeAdjacentTo(DockWidget *dockWidget, int boundary);
|
|
|
|
DockPlaceholder *placeOfSeparator(DockSeparator *);
|
|
|
|
const std::vector<DockPlaceholder *> &placeholders() const {
|
|
|
|
return m_placeholders;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Re-implementable functions for custom dock widgets.
|
|
|
|
|
|
|
|
//! Returns the minimum size of the dock widget when docked. This function
|
|
|
|
//! should be
|
|
|
|
//! reimlemented whenever minimum size changes between floating and docked
|
|
|
|
//! appearance.
|
|
|
|
virtual QSize getDockedMinimumSize() { return minimumSize(); }
|
|
|
|
|
|
|
|
//! Returns the maximum size of the dock widget when docked. This function
|
|
|
|
//! should be
|
|
|
|
//! reimlemented whenever minimum size changes between floating and docked
|
|
|
|
//! appearance.
|
|
|
|
virtual QSize getDockedMaximumSize() { return maximumSize(); }
|
|
|
|
|
|
|
|
//! This function is called in order to show the dock widget in its floating
|
|
|
|
//! status. No show() or update()
|
|
|
|
//! is needed in its body.
|
|
|
|
//! It can be reimplemented to build custom-styled dock widgets.
|
|
|
|
virtual void setFloatingAppearance() { setWindowFlags(Qt::Tool); }
|
|
|
|
|
|
|
|
//! This function is called in order to show the dock widget in its docked
|
|
|
|
//! status. No show() or update()
|
|
|
|
//! is needed in its body.
|
|
|
|
//! It can be reimplemented to build custom-styled dock widgets.
|
|
|
|
virtual void setDockedAppearance() {}
|
|
|
|
|
|
|
|
virtual bool isDragGrip(QPoint p);
|
|
|
|
virtual int isResizeGrip(QPoint) {
|
|
|
|
return 0; // Native deco widgets handle margins and resizes on their own
|
|
|
|
}
|
|
|
|
|
|
|
|
enum {
|
|
|
|
leftMargin = 0x1,
|
|
|
|
rightMargin = 0x2,
|
|
|
|
topMargin = 0x4,
|
|
|
|
bottomMargin = 0x8
|
|
|
|
};
|
|
|
|
|
|
|
|
// Placeholders-related methods
|
|
|
|
virtual void selectDockPlaceholder(QMouseEvent *me);
|
|
|
|
void clearDockPlaceholders();
|
|
|
|
|
|
|
|
// Decorations allocator
|
|
|
|
void setDecoAllocator(DockDecoAllocator *decoAllocator);
|
|
|
|
|
2021-07-08 13:39:28 +12:00
|
|
|
// reimplemented in FlipbookPanel
|
2016-06-15 18:43:10 +12:00
|
|
|
virtual void onDock(bool docked) {}
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
private:
|
2016-06-15 18:43:10 +12:00
|
|
|
// Event handling
|
|
|
|
// Basic events
|
2016-06-19 20:06:29 +12:00
|
|
|
bool event(QEvent *e) override;
|
|
|
|
void mousePressEvent(QMouseEvent *me) override;
|
|
|
|
void mouseReleaseEvent(QMouseEvent *me) override;
|
|
|
|
void mouseMoveEvent(QMouseEvent *me) override;
|
2016-06-15 18:43:10 +12:00
|
|
|
void hoverMoveEvent(QHoverEvent *he);
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
protected:
|
2016-06-15 18:43:10 +12:00
|
|
|
// Customizable events
|
2016-06-19 20:06:29 +12:00
|
|
|
void wheelEvent(QWheelEvent *we) override;
|
|
|
|
void mouseDoubleClickEvent(QMouseEvent *me) override;
|
2016-06-15 18:43:10 +12:00
|
|
|
virtual void windowTitleEvent(QEvent *) {}
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
//---------------------
|
|
|
|
// DockSeparator
|
|
|
|
//---------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
//! Separators are interposition widgets among docked DockWidgets of a
|
|
|
|
//! DockLayout.
|
2016-03-19 06:57:51 +13:00
|
|
|
/*!
|
2016-06-15 18:43:10 +12:00
|
|
|
A DockSeparator has the role of separating sister Regions; it is always owned
|
|
|
|
by a parent
|
|
|
|
Region and inherits its subdivision (here separation) direction. It also
|
|
|
|
provides basical
|
|
|
|
interaction with the user, allowing itself to be shifted along separation
|
|
|
|
direction until
|
2016-03-19 06:57:51 +13:00
|
|
|
geometric constraints are met.
|
2016-06-15 18:43:10 +12:00
|
|
|
DockSeparator class can be inherited to build custom separators - in that
|
|
|
|
case, a
|
|
|
|
heir of DockDecoAllocator class allocating the new separator class must be
|
|
|
|
assigned to
|
2016-03-19 06:57:51 +13:00
|
|
|
the DockLayout.
|
2016-06-15 18:43:10 +12:00
|
|
|
It is also possible to specify the Separators' thickness used in a DockLayout
|
|
|
|
through the
|
2016-03-19 06:57:51 +13:00
|
|
|
QLayout::setSpacing(int) method.
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
\b NOTE: Observe that Separators' geometry is owned by the DockLayout to which
|
|
|
|
it belongs; it
|
|
|
|
is discouraged (but not forbidden) to manually modify it. You may, for
|
|
|
|
example, modify the
|
2016-03-19 06:57:51 +13:00
|
|
|
geometry of a DockSeparator when dragging a dock widget over it.
|
2016-06-15 18:43:10 +12:00
|
|
|
In any case, the layout will automatically regenerate Separators' geometry at
|
|
|
|
each update of
|
2016-03-19 06:57:51 +13:00
|
|
|
the layout.
|
|
|
|
|
|
|
|
\sa DockLayout and DockWidget classes.
|
|
|
|
*/
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
class DockSeparator : public QWidget {
|
|
|
|
friend class DockLayout; // Layout updates each DockSeparator during
|
|
|
|
// DockLayout::applyGeometry()
|
2016-06-20 14:23:05 +12:00
|
|
|
friend class Region; // Region may update a DockSeparator's parent during
|
|
|
|
// removeItem()
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
DockLayout *m_owner;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
// Event-related infos
|
|
|
|
bool m_pressed;
|
|
|
|
QPoint m_oldOrigin;
|
|
|
|
QPoint m_oldPos;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
// Structural infos
|
|
|
|
Region *m_parentRegion;
|
|
|
|
int m_index;
|
|
|
|
bool m_orientation;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
// Constraint infos
|
|
|
|
double m_leftBound;
|
|
|
|
double m_rightBound;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
DockSeparator(DockLayout *owner, bool orientation, Region *parentRegion);
|
|
|
|
virtual ~DockSeparator() {}
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
// Structural getters
|
|
|
|
bool getOrientation() const { return m_orientation; }
|
|
|
|
Region *getParentRegion() const { return m_parentRegion; }
|
|
|
|
int getIndex() const { return m_index; }
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
// Public setters
|
|
|
|
void shift(int dx);
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
private:
|
2016-06-15 18:43:10 +12:00
|
|
|
void calculateBounds();
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-19 20:06:29 +12:00
|
|
|
void mousePressEvent(QMouseEvent *me) override;
|
|
|
|
void mouseReleaseEvent(QMouseEvent *me) override;
|
|
|
|
void mouseMoveEvent(QMouseEvent *me) override;
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
//---------------------------
|
|
|
|
// Dock Placeholder
|
|
|
|
//---------------------------
|
|
|
|
|
2021-07-08 13:39:28 +12:00
|
|
|
//! A dock placeholder contains the necessary information about a possible
|
2016-06-15 18:43:10 +12:00
|
|
|
//! docking solution.
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
/*!
|
|
|
|
Dock placeholders are top-level widgets used by a DockLayout to draw docking
|
|
|
|
solutions for a dragged DockWidget. They are actually generated when
|
|
|
|
dragging of a DockWidget begins: if it belongs to a parent DockLayout, docking
|
|
|
|
possibilities are calculated and stored into the layout.
|
2016-06-15 18:43:10 +12:00
|
|
|
Placeholders selection and activation depend on the dragged dock window and
|
|
|
|
therefore
|
2016-03-19 06:57:51 +13:00
|
|
|
are of its own responsibility.
|
2016-06-15 18:43:10 +12:00
|
|
|
You may, however, inherit this class to provide custom placeholders; in this
|
|
|
|
case,
|
|
|
|
a DockDecoAllocator class reimplementing allocation of placeholders must be
|
|
|
|
assigned to
|
2016-03-19 06:57:51 +13:00
|
|
|
the owner dock widget.
|
|
|
|
|
|
|
|
\sa DockLayout and DockWidget classes
|
|
|
|
*/
|
2016-06-15 18:43:10 +12:00
|
|
|
class DockPlaceholder : public QWidget {
|
|
|
|
friend class DockLayout; // DockLayout is granted access to placeholders'
|
|
|
|
// privates
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2021-07-08 13:39:28 +12:00
|
|
|
// Docking information - private
|
2016-06-15 18:43:10 +12:00
|
|
|
Region *m_region;
|
|
|
|
int m_idx;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2021-07-08 13:39:28 +12:00
|
|
|
// Docking information - public
|
2016-06-15 18:43:10 +12:00
|
|
|
int m_attributes;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
// Owner
|
|
|
|
DockSeparator *m_separator;
|
|
|
|
DockWidget *m_owner;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
DockPlaceholder(DockWidget *owner, Region *r, int idx, int attributes = 0);
|
|
|
|
virtual ~DockPlaceholder() {}
|
|
|
|
|
|
|
|
// Member access methods
|
|
|
|
|
|
|
|
//! Returns DockSeparator on which docking takes place (if any)
|
|
|
|
DockSeparator *getSeparator() const;
|
|
|
|
//! Returns dockWidget owner
|
|
|
|
DockWidget *getDockWidget() const { return m_owner; }
|
|
|
|
//! Returns Region owner
|
|
|
|
Region *getParentRegion() const { return m_region; }
|
|
|
|
//! Returns insertion index into parent region
|
|
|
|
int getInsertionIdx() const { return m_idx; }
|
|
|
|
|
|
|
|
enum {
|
|
|
|
left = 0,
|
|
|
|
right = 1,
|
|
|
|
top = 2,
|
|
|
|
bottom = 3,
|
|
|
|
sepHor = 4,
|
|
|
|
sepVert = 5,
|
|
|
|
root = 6
|
|
|
|
};
|
|
|
|
int getAttribute() const { return m_attributes; }
|
|
|
|
void setAttribute(int attribute) { m_attributes = attribute; }
|
|
|
|
|
|
|
|
// Geometry functions
|
|
|
|
QRect parentGeometry() const;
|
|
|
|
virtual void buildGeometry();
|
|
|
|
|
|
|
|
// Query functions
|
|
|
|
//! A root placeholder is passed only if no item is currently docked (special
|
|
|
|
//! case)
|
|
|
|
bool isRoot() const { return m_attributes == root; }
|
|
|
|
DockPlaceholder *parentPlaceholder();
|
|
|
|
DockPlaceholder *greatestPlaceholder();
|
|
|
|
DockPlaceholder *childPlaceholder(QPoint p);
|
|
|
|
DockPlaceholder *smallestPlaceholder(QPoint p);
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
private:
|
2016-06-15 18:43:10 +12:00
|
|
|
//! Let wheel events also be propagated to owner dock widget
|
2016-06-19 20:06:29 +12:00
|
|
|
void wheelEvent(QWheelEvent *we) override { m_owner->wheelEvent(we); }
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
//===========================================
|
|
|
|
|
|
|
|
//--------------------
|
|
|
|
// Class Region
|
|
|
|
//--------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
//! Regions represent any rectangular space inside a DockLayout.
|
|
|
|
//! Normally there is no reason to deal with Regions, unless you want to
|
|
|
|
//! build complex docking systems or manually dock widgets into your code.
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
/*!
|
|
|
|
Regions are rectangular areas of the DockLayout's contentsRect() which
|
|
|
|
can be either subdiveded into subRegions (all in a given \b subdivision
|
|
|
|
\b direction) or contain a DockWidget.
|
|
|
|
Every subRegion, if present, has opposite subdivision direction with
|
|
|
|
respect to parent one. In addition, regions possess lists of separators
|
|
|
|
and placeholders found along its subdivision direction.
|
2021-07-08 13:39:28 +12:00
|
|
|
Region information are owned by the DockLayout who allocates it; however,
|
2016-03-19 06:57:51 +13:00
|
|
|
they are read-only accessible by the user.
|
|
|
|
|
|
|
|
\sa DockLayout, DockWidget, DockSeparator and DockPlaceholder classes.
|
|
|
|
*/
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
class Region {
|
2016-06-20 14:23:05 +12:00
|
|
|
friend class DockLayout; // Layout is the main operating class over
|
|
|
|
// rectangular regions - need full access
|
2016-06-15 18:43:10 +12:00
|
|
|
friend class DockSeparator; // Separators need access to extremal sizes
|
|
|
|
// methods when moving themselves
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
DockLayout *m_owner;
|
|
|
|
DockWidget *m_item;
|
|
|
|
Region *m_parent;
|
|
|
|
std::deque<Region *> m_childList;
|
|
|
|
std::deque<DockSeparator *> m_separators;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
std::vector<DockPlaceholder *> m_placeholders;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
QRectF m_rect;
|
|
|
|
bool m_orientation;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
int m_minimumSize[2];
|
|
|
|
int m_maximumSize[2];
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
int m_saveIndex;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
Region(DockLayout *owner, DockWidget *item = 0)
|
|
|
|
: m_owner(owner), m_item(item), m_parent(0), m_orientation(0) {}
|
|
|
|
~Region();
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
enum { inf = 1000000 };
|
|
|
|
enum { horizontal = 0, vertical = 1 };
|
|
|
|
enum { left = 0x1, right = 0x2, top = 0x4, bottom = 0x8 };
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
// Getters - public
|
|
|
|
bool getOrientation() const { return m_orientation; }
|
|
|
|
QRectF getGeometry() const { return m_rect; }
|
|
|
|
QSizeF getSize() const { return QSizeF(m_rect.width(), m_rect.height()); }
|
|
|
|
Region *getParent() const { return m_parent; }
|
|
|
|
DockWidget *getItem() const { return m_item; }
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
const std::deque<Region *> &getChildList() const { return m_childList; }
|
|
|
|
Region *childRegion(int i) const { return m_childList[i]; }
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
const std::deque<DockSeparator *> &separators() const { return m_separators; }
|
|
|
|
DockSeparator *separator(int i) const { return m_separators[i]; }
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
std::vector<DockPlaceholder *> &placeholders() { return m_placeholders; }
|
|
|
|
DockPlaceholder *placeholder(int i) const { return m_placeholders[i]; }
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
unsigned int find(const Region *subRegion) const;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2020-10-06 09:15:45 +13:00
|
|
|
bool checkWidgetsToBeFixedWidth(std::vector<QWidget *> &widgets);
|
2020-09-28 11:20:03 +13:00
|
|
|
// This causes issues on maximize if the timeline is too tall.
|
|
|
|
// bool checkWidgetsToBeFixedHeight(std::vector<QWidget *> &widgets,
|
|
|
|
// bool &fromDocking);
|
2020-06-29 15:02:28 +12:00
|
|
|
|
2016-03-19 06:57:51 +13:00
|
|
|
private:
|
2016-06-15 18:43:10 +12:00
|
|
|
// Setters - private
|
|
|
|
void setOrientation(bool orientation) { m_orientation = orientation; }
|
|
|
|
void setGeometry(const QRectF &rect) { m_rect = rect; }
|
|
|
|
void setSize(const QSizeF &size) { m_rect.setSize(size); }
|
|
|
|
void setParent(Region *parent) { m_parent = parent; }
|
|
|
|
void setItem(DockWidget *item) { m_item = item; }
|
|
|
|
|
|
|
|
// Insertion and removal methods
|
|
|
|
void insertSubRegion(Region *subregion, int idx);
|
|
|
|
Region *insertItem(DockWidget *item, int idx);
|
|
|
|
void removeItem(DockWidget *item);
|
|
|
|
void insertSeparator(DockSeparator *sep);
|
|
|
|
void removeSeparator();
|
|
|
|
|
|
|
|
// Extremal region sizes
|
|
|
|
//! Returns cached occupied space in \b this region along given \b direction.
|
|
|
|
inline int getMaximumSize(bool direction) const {
|
|
|
|
return m_maximumSize[direction];
|
|
|
|
}
|
|
|
|
//! Returns cached occupied space in \b this region along given \b direction.
|
|
|
|
inline int getMinimumSize(bool direction) const {
|
|
|
|
return m_minimumSize[direction];
|
|
|
|
}
|
|
|
|
|
|
|
|
bool addItemSize(DockWidget *item);
|
|
|
|
bool subItemSize(DockWidget *item);
|
|
|
|
void calculateExtremalSizes();
|
|
|
|
int calculateMinimumSize(bool direction, bool recalcChildren);
|
|
|
|
int calculateMaximumSize(bool direction, bool recalcChildren);
|
|
|
|
|
|
|
|
// Redistribution function.
|
|
|
|
// The main feature of a Region consists of the redistribute() method, which
|
|
|
|
// extracts the optimal layout among the branching regions with \b this
|
|
|
|
// root. However, only the full redistribute() method in DockLayout is made
|
|
|
|
// public.
|
|
|
|
void redistribute();
|
|
|
|
void restoreGeometry();
|
|
|
|
// void updateSeparators();
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
//----------------------
|
|
|
|
// Dock Allocator
|
|
|
|
//----------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
//! DockDecoAllocator class handles the allocation of decoration elements used
|
|
|
|
//! by our dock manager.
|
2016-03-19 06:57:51 +13:00
|
|
|
/*!
|
|
|
|
In order to implement custom appearances for the docking system, it
|
|
|
|
is possible to customize both DockSeparator and DockPlaceholder classes. Since
|
|
|
|
allocation of such objects is handled internally by the docking system,
|
|
|
|
it is necessary to reimplement allocator functions whenever decoration
|
|
|
|
classes change.
|
|
|
|
In order to assign a DockDecoAllocator to a DockLayout or DockWidget, the
|
|
|
|
respective 'setDecoAllocator' methods are provided.
|
|
|
|
|
|
|
|
\sa DockLayout, DockWidget, DockSeparator and DockPlaceholder classes.
|
|
|
|
*/
|
2016-06-15 18:43:10 +12:00
|
|
|
class DockDecoAllocator {
|
|
|
|
friend class DockLayout;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
DockDecoAllocator() {}
|
|
|
|
virtual ~DockDecoAllocator() {}
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
// Customizabile allocators
|
|
|
|
virtual DockSeparator *newSeparator(DockLayout *owner, bool orientation,
|
|
|
|
Region *parentRegion);
|
|
|
|
virtual DockPlaceholder *newPlaceholder(DockWidget *owner, Region *r, int idx,
|
|
|
|
int attributes);
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
private:
|
2016-06-15 18:43:10 +12:00
|
|
|
DockPlaceholder *newPlaceBuilt(DockWidget *owner, Region *r, int idx,
|
|
|
|
int attributes);
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
#endif // SIMPLEQTTEST_H
|