190 lines
6.7 KiB
C++
190 lines
6.7 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.
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
* @brief A MultiSplitter with support for drop indicators when hovering over.
|
|
*
|
|
* @author Sérgio Martins \<sergio.martins@kdab.com\>
|
|
*/
|
|
|
|
#ifndef KD_DROP_AREA_P_H
|
|
#define KD_DROP_AREA_P_H
|
|
#pragma once
|
|
|
|
#include "kddockwidgets/docks_export.h"
|
|
#include "kddockwidgets/KDDockWidgets.h"
|
|
#include "kddockwidgets/core/Layout.h"
|
|
|
|
class TestQtWidgets;
|
|
class TestDocks;
|
|
|
|
namespace KDDockWidgets {
|
|
|
|
namespace Core {
|
|
|
|
class Group;
|
|
class Draggable;
|
|
class DockWidget;
|
|
class Separator;
|
|
class DropIndicatorOverlay;
|
|
class LayoutingSeparator;
|
|
struct WindowBeingDragged;
|
|
|
|
/**
|
|
* MultiSplitter is simply a wrapper around Core::Item in which the hosted widgets are
|
|
* of class KDDockWidgets::Frame. The stuff in Core:: being agnostic and generic, not specific
|
|
* to KDDW.
|
|
*
|
|
* A MultiSplitter is like a QSplitter but supports mixing vertical and horizontal splitters in
|
|
* any combination.
|
|
*
|
|
* It supports adding a widget to the left/top/bottom/right of the whole MultiSplitter or adding
|
|
* relative to a single widget.
|
|
*/
|
|
|
|
class DOCKS_EXPORT DropArea : public Layout
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
explicit DropArea(View *parent, MainWindowOptions options, bool isMDIWrapper = false);
|
|
~DropArea();
|
|
|
|
void removeHover();
|
|
DropLocation hover(WindowBeingDragged *draggedWindow, Point globalPos);
|
|
///@brief Called when a user drops a widget via DND
|
|
bool drop(WindowBeingDragged *droppedWindow, Point globalPos);
|
|
Vector<Core::Group *> groups() const;
|
|
|
|
Core::Item *centralFrame() const;
|
|
DropIndicatorOverlay *dropIndicatorOverlay() const;
|
|
void addDockWidget(DockWidget *dw, KDDockWidgets::Location location, DockWidget *relativeTo,
|
|
const InitialOption &initialOption = {});
|
|
void _addDockWidget(DockWidget *dw, KDDockWidgets::Location location, Item *relativeTo,
|
|
const InitialOption &initialOption);
|
|
|
|
bool containsDockWidget(DockWidget *) const;
|
|
|
|
/// Returns whether this layout has a single dock widget which is floating
|
|
/// Implies it's in a FloatingWindow and that it has only one dock widget
|
|
bool hasSingleFloatingGroup() const;
|
|
|
|
/// Returns whether this drop area has only 1 group.
|
|
/// See further explanation in FloatingWindow::hasSingleGroup()
|
|
bool hasSingleGroup() const;
|
|
|
|
Vector<QString> affinities() const;
|
|
void layoutParentContainerEqually(DockWidget *);
|
|
|
|
/// When DockWidgetOption_MDINestable is used, docked MDI dock widgets will be wrapped inside
|
|
/// a DropArea, so they accept drops This DropArea is created implicitly while docking, and this
|
|
/// function will return true
|
|
bool isMDIWrapper() const;
|
|
|
|
/// Returns the helper dock widget for implementing DockWidgetOption_MDINestable.
|
|
Core::DockWidget *mdiDockWidgetWrapper() const;
|
|
|
|
static Core::Group *createCentralGroup(MainWindowOptions options);
|
|
|
|
/**
|
|
* @brief Adds a widget to this MultiSplitter.
|
|
*/
|
|
void addWidget(View *widget, KDDockWidgets::Location location,
|
|
Core::Item *relativeToItem = nullptr,
|
|
const InitialOption &option = DefaultSizeMode::Fair);
|
|
|
|
/**
|
|
* Adds an entire MultiSplitter into this layout. The donor MultiSplitter will be deleted
|
|
* after all its Frames are stolen. All added Frames will preserve their original layout, so,
|
|
* if widgetFoo was at the left of widgetBar when in the donor splitter, then it will still be
|
|
* at left of widgetBar when the whole splitter is dropped into this one.
|
|
*/
|
|
void addMultiSplitter(Core::DropArea *sourceMultiSplitter, KDDockWidgets::Location location,
|
|
Core::Group *relativeToGroup = nullptr,
|
|
const InitialOption &option = DefaultSizeMode::Fair);
|
|
|
|
/**
|
|
* Called by the indicators, so they draw the drop rubber band at the correct place.
|
|
* The rect for the rubberband when dropping a widget at the specified location.
|
|
* Excludes the Separator thickness, result is actually smaller than what needed. In other
|
|
* words, the result will be exactly the same as the geometry the widget will get.
|
|
*/
|
|
Rect rectForDrop(const WindowBeingDragged *wbd, KDDockWidgets::Location location,
|
|
const Core::Item *relativeTo) const;
|
|
|
|
bool deserialize(const LayoutSaver::MultiSplitter &) override;
|
|
|
|
///@brief returns the list of separators
|
|
Vector<Core::LayoutingSeparator *> separators() const;
|
|
|
|
/// @brief See docs for MainWindowBase::layoutEqually()
|
|
void layoutEqually();
|
|
|
|
/// @brief overload that just resizes widgets within a sub-tree
|
|
void layoutEqually(Core::ItemBoxContainer *);
|
|
|
|
/// @brief Returns the number of items layed-out horizontally or vertically
|
|
/// But honours nesting
|
|
int numSideBySide_recursive(Qt::Orientation) const;
|
|
|
|
Core::ItemBoxContainer *rootItem() const;
|
|
|
|
/// Returns the current drop location
|
|
/// The user needs to be dragging a window and be over a drop indicator, otherwise DropLocation_None is returned
|
|
DropLocation currentDropLocation() const;
|
|
|
|
Core::Group *centralGroup() const;
|
|
|
|
#if defined(DOCKS_DEVELOPER_MODE)
|
|
public:
|
|
#else
|
|
private:
|
|
#endif
|
|
KDDW_DELETE_COPY_CTOR(DropArea)
|
|
friend class Core::MainWindow;
|
|
friend class Core::Group;
|
|
friend class Core::FloatingWindow;
|
|
friend class DropIndicatorOverlay;
|
|
friend class AnimatedIndicators;
|
|
|
|
// For debug/hardening
|
|
bool validateInputs(View *widget, KDDockWidgets::Location location, const Core::Item *relativeToItem, const InitialOption &option) const;
|
|
|
|
void setRootItem(Core::ItemBoxContainer *);
|
|
|
|
/**
|
|
* @brief Like @ref availableLengthForDrop but just returns the total available width or height
|
|
* (depending on @p orientation) So no need to receive any location.
|
|
* @param orientation If Qt::Vertical then returns the available height. Width otherwise.
|
|
*/
|
|
int availableLengthForOrientation(Qt::Orientation orientation) const;
|
|
|
|
/**
|
|
* @brief Equivalent to @ref availableLengthForOrientation but returns for both orientations.
|
|
* width is for Qt::Vertical.
|
|
*/
|
|
Size availableSize() const;
|
|
|
|
template<typename T>
|
|
bool validateAffinity(T *, Core::Group *acceptingGroup = nullptr) const;
|
|
bool drop(WindowBeingDragged *draggedWindow, Core::Group *acceptingGroup, DropLocation);
|
|
bool drop(View *droppedwindow, KDDockWidgets::Location location, Core::Group *relativeTo);
|
|
Core::Group *groupContainingPos(Point globalPos) const;
|
|
void updateFloatingActions();
|
|
|
|
class Private;
|
|
Private *const d;
|
|
};
|
|
}
|
|
}
|
|
|
|
#endif
|