KDDockWidgets API Documentation 2.1
Loading...
Searching...
No Matches
DropIndicatorOverlay.cpp
Go to the documentation of this file.
1/*
2 This file is part of KDDockWidgets.
3
4 SPDX-FileCopyrightText: 2019 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
5 Author: Sérgio Martins <sergio.martins@kdab.com>
6
7 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
8
9 Contact KDAB at <info@kdab.com> for commercial licensing options.
10*/
11
13#include "core/DropIndicatorOverlay_p.h"
14#include "Config.h"
15#include "Platform.h"
16#include "ViewFactory.h"
17
18#include "core/DropArea.h"
19#include "core/Group.h"
20#include "core/Logging_p.h"
21#include "core/Controller_p.h"
22#include "core/WindowBeingDragged_p.h"
23
24#include "core/DragController_p.h"
25#include "core/DockRegistry_p.h"
26
27using namespace KDDockWidgets;
28using namespace KDDockWidgets::Core;
29
32 , d(new Private())
33 , m_dropArea(dropArea)
34{
35 setVisible(false);
36 view->setViewName(QStringLiteral("DropIndicatorOverlay"));
37
38 // Set transparent for mouse events so that topLevel->childAt() never returns the drop indicator
39 // overlay
41
42 d->dropIndicatorsInhibitedConnection = DockRegistry::self()->dptr()->dropIndicatorsInhibitedChanged.connect([this](bool inhibited) {
43 if (inhibited) {
45 } else {
46 // Re-add hover. Fastest way is simply faking a mouse move
47 if (auto state = object_cast<StateDragging *>(DragController::instance()->activeState())) {
48 state->handleMouseMove(Platform::instance()->cursorPos());
49 }
50 }
51 });
52}
53
54
56 : DropIndicatorOverlay(dropArea, Platform::instance()->createView(this, dropArea->view()))
57{
58}
59
64
66{
68 return;
69
71 if (is) {
73 view()->raise();
74 } else {
75 setHoveredGroup(nullptr);
76 }
77
80}
81
83{
84 return m_hoveredGroupRect;
85}
86
88{
89 if (group == m_hoveredGroup)
90 return;
91
92 if (WindowBeingDragged *wbd = DragController::instance()->windowBeingDragged()) {
93 if (wbd->isInWaylandDrag(group)) {
94 // With wayland, we don't detach the group before the mouse release.
95 // Instead, we start a QDrag, with this group as cursor QPixmap.
96 // Here we catch the case where we're dragging the pixmap onto the group
97 // where're already dragging. That's a no-op.
98 return;
99 }
100 }
101
102 if (m_hoveredGroup)
103 d->groupConnection = KDBindings::ScopedConnection();
104
105 m_hoveredGroup = group;
106 if (m_hoveredGroup) {
107 d->groupConnection = group->Controller::dptr()->aboutToBeDeleted.connect([this] { onGroupDestroyed(); });
108 setHoveredGroupRect(m_hoveredGroup->view()->geometry());
109 } else {
110 setHoveredGroupRect(Rect());
111 }
112
114 d->hoveredGroupChanged.emit(m_hoveredGroup);
116}
117
122
124{
125 return m_currentDropLocation;
126}
127
157
159{
160 if (dropLoc == DropLocation_None)
161 return false;
162
163 WindowBeingDragged *windowBeingDragged = DragController::instance()->windowBeingDragged();
164 if (!windowBeingDragged)
165 return false;
166
167 const Core::DockWidget::List source = windowBeingDragged->dockWidgets();
168 const Core::DockWidget::List target =
170
171 const bool isInner = dropLoc & DropLocation_Inner;
172 const bool isOutter = dropLoc & DropLocation_Outter;
173 if (isInner) {
174 if (!m_hoveredGroup)
175 return false;
176 } else if (isOutter) {
177 // If there's only 1 group in the layout, the outer indicators are redundant, as they do the
178 // same thing as the internal ones. But there might be another window obscuring our target,
179 // so it's useful to show the outer indicators in this case
180 const bool isTheOnlyGroup = m_hoveredGroup && m_hoveredGroup->isTheOnlyGroup();
181 if (isTheOnlyGroup
182 && !DockRegistry::self()->isProbablyObscured(m_hoveredGroup->view()->window(),
183 windowBeingDragged))
184 return false;
185 } else if (dropLoc == DropLocation_Center) {
187 return false;
188
189 // Only allow to dock to center if the affinities match
190 if (!DockRegistry::self()->affinitiesMatch(m_hoveredGroup->affinities(),
191 windowBeingDragged->affinities()))
192 return false;
193 } else {
194 KDDW_ERROR("Unknown drop indicator location={}", dropLoc);
195 return false;
196 }
197
198 if (auto dropIndicatorAllowedFunc = Config::self().dropIndicatorAllowedFunc()) {
199 DropArea *dropArea = DragController::instance()->dropAreaUnderCursor();
200 if (!dropIndicatorAllowedFunc(dropLoc, source, target, dropArea))
201 return false;
202 }
203
204 return true;
205}
206
207void DropIndicatorOverlay::onGroupDestroyed()
208{
209 setHoveredGroup(nullptr);
210}
211
212DropIndicatorOverlay::Private *DropIndicatorOverlay::dptr() const
213{
214 return d;
215}
216
220
222{
223 if (m_currentDropLocation != location) {
224 m_currentDropLocation = location;
225 d->currentDropLocationChanged.emit();
226 }
227}
228
230{
231 const DropLocation loc = hover_impl(globalPos);
233 return loc;
234}
235
236void DropIndicatorOverlay::setHoveredGroupRect(Rect rect)
237{
238 if (m_hoveredGroupRect != rect) {
239 m_hoveredGroupRect = rect;
240 d->hoveredGroupRectChanged.emit();
241 }
242}
243
249
254
Application-wide config to tune certain behaviours of the framework.
A ScopedConnection is a RAII-style way to make sure a Connection is disconnected.
Definition signal.h:533
static Config & self()
returns the singleton Config instance
Definition Config.cpp:88
View * view() const
Returns the view associated with this controller, if any.
bool is(ViewType) const
Returns whether this controller is of the specified type.
Vector< DockWidget * > List
virtual DropLocation hover_impl(Point globalPos)=0
KDDockWidgets::DropLocation hover(Point globalPos)
static KDDockWidgets::Location multisplitterLocationFor(DropLocation)
void removeHover()
Clears and hides drop indicators.
virtual bool dropIndicatorVisible(DropLocation) const
Returns whether the specified drop indicator should be visible.
DropIndicatorOverlay(DropArea *dropArea, View *view)
Vector< DockWidget * > dockWidgets() const
bool isDockable() const
Returns whether you can DND dock widgets over this group and tab into it.
Vector< QString > affinities() const
implements functions specific to a particular platform A platform can be for example qtwidgets,...
static Platform * instance()
Returns the platform singleton.
virtual Rect geometry() const =0
virtual void enableAttribute(Qt::WidgetAttribute, bool enable=true)=0
virtual std::shared_ptr< Core::Window > window() const =0
Returns the window this view is inside For the Qt frontend, this wraps a QWindow. Like QWidget::windo...
virtual void raise()=0
virtual void setViewName(const QString &)=0
Equivalent to Qt's QObject::objectName()
virtual void setGeometry(Rect)=0
static DockRegistry * self()
A MultiSplitter with support for drop indicators when hovering over.
ViewType
Each View type also has a specific Controller associated with, except for ViewType::None.
Definition Controller.h:26
Class to abstract QAction, so code still works with QtQuick and Flutter.
@ Location_OnTop
‍Left docking location
@ Location_OnRight
‍Top docking location
@ Location_OnBottom
‍Right docking location
DropLocation
Enum describing the different drop indicator types.
WA_TransparentForMouseEvents
A factory class for allowing the user to customize some internal widgets.

© Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/
KDDockWidgets
Advanced Dock Widget Framework for Qt
https://www.kdab.com/development-resources/qt-tools/kddockwidgets/
Generated by doxygen 1.9.8