KDDockWidgets API Documentation  1.4
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Pages
ClassicIndicators.cpp
Go to the documentation of this file.
1 /*
2  This file is part of KDDockWidgets.
3 
4  SPDX-FileCopyrightText: 2019-2021 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 
12 #include "ClassicIndicators_p.h"
13 #include "Config.h"
14 #include "FrameworkWidgetFactory.h"
15 #include "ClassicIndicatorsWindow_p.h"
16 
17 #include "private/DropArea_p.h"
18 #include "private/DragController_p.h"
19 #include "private/Frame_p.h"
20 #include "private/Logging_p.h"
21 #include "private/DockRegistry_p.h"
22 #include "private/Utils_p.h"
23 
24 // #define KDDOCKWIDGETS_RUBBERBAND_IS_TOPLEVEL 1
25 
26 using namespace KDDockWidgets;
27 
28 static IndicatorWindow *createIndicatorWindow(ClassicIndicators *classicIndicators)
29 {
30  auto window = new IndicatorWindow(classicIndicators);
31  window->setObjectName(QStringLiteral("_docks_IndicatorWindow_Overlay"));
32 
33  return window;
34 }
35 
36 ClassicIndicators::ClassicIndicators(DropArea *dropArea)
37  : DropIndicatorOverlayInterface(dropArea) // Is parented on the drop-area, not a toplevel.
38  , m_rubberBand(Config::self().frameworkWidgetFactory()->createRubberBand(rubberBandIsTopLevel() ? nullptr : dropArea))
39  , m_indicatorWindow(createIndicatorWindow(this))
40 {
41  if (rubberBandIsTopLevel())
42  m_rubberBand->setWindowOpacity(0.5);
43 }
44 
45 ClassicIndicators::~ClassicIndicators()
46 {
47  delete m_indicatorWindow;
48 }
49 
50 DropIndicatorOverlayInterface::DropLocation ClassicIndicators::hover_impl(QPoint globalPos)
51 {
52  return m_indicatorWindow->hover(globalPos);
53 }
54 
55 QPoint ClassicIndicators::posForIndicator(DropIndicatorOverlayInterface::DropLocation loc) const
56 {
57  return m_indicatorWindow->posForIndicator(loc);
58 }
59 
60 bool ClassicIndicators::innerIndicatorsVisible() const
61 {
62  return m_innerIndicatorsVisible;
63 }
64 
65 bool ClassicIndicators::outterIndicatorsVisible() const
66 {
67  return m_outterIndicatorsVisible;
68 }
69 
70 bool ClassicIndicators::tabIndicatorVisible() const
71 {
72  return m_tabIndicatorVisible;
73 }
74 
75 bool ClassicIndicators::onResize(QSize)
76 {
77  m_indicatorWindow->resize(window()->size());
78  return false;
79 }
80 
81 void ClassicIndicators::updateVisibility()
82 {
83  if (isHovered()) {
84  m_indicatorWindow->updatePositions();
85  m_indicatorWindow->setVisible(true);
86  updateWindowPosition();
87  updateIndicatorsVisibility(true);
88  raiseIndicators();
89  } else {
90  m_rubberBand->setVisible(false);
91  m_indicatorWindow->setVisible(false);
92  updateIndicatorsVisibility(false);
93  }
94 }
95 
96 void ClassicIndicators::updateIndicatorsVisibility(bool visible)
97 {
98  const bool isTheOnlyFrame = m_hoveredFrame && m_hoveredFrame->isTheOnlyFrame();
99 
100  m_innerIndicatorsVisible = visible && m_hoveredFrame;
101 
102  WindowBeingDragged *windowBeingDragged = DragController::instance()->windowBeingDragged();
103 
104  // If there's only 1 frame in the layout, the outer indicators are redundant, as they do the same thing as the internal ones.
105  // But there might be another window obscuring our target, so it's useful to show the outer indicators in this case
106  m_outterIndicatorsVisible = visible && (!isTheOnlyFrame || DockRegistry::self()->isProbablyObscured(m_hoveredFrame->window()->windowHandle(), windowBeingDragged));
107 
108 
109  // Only allow to dock to center if the affinities match
110  auto tabbingAllowedFunc = Config::self().tabbingAllowedFunc();
111  m_tabIndicatorVisible = m_innerIndicatorsVisible && windowBeingDragged && DockRegistry::self()->affinitiesMatch(m_hoveredFrame->affinities(), windowBeingDragged->affinities());
112  if (m_tabIndicatorVisible && tabbingAllowedFunc) {
113  const DockWidgetBase::List source = windowBeingDragged->dockWidgets();
114  const DockWidgetBase::List target = m_hoveredFrame->dockWidgets();
115  m_tabIndicatorVisible = tabbingAllowedFunc(source, target);
116  }
117 
118  Q_EMIT innerIndicatorsVisibleChanged();
119  Q_EMIT outterIndicatorsVisibleChanged();
120  Q_EMIT tabIndicatorVisibleChanged();
121 }
122 
123 void ClassicIndicators::raiseIndicators()
124 {
125  m_indicatorWindow->raise();
126 }
127 
128 KDDockWidgets::Location locationToMultisplitterLocation(ClassicIndicators::DropLocation location)
129 {
130  switch (location) {
131  case DropIndicatorOverlayInterface::DropLocation_Left:
133  case DropIndicatorOverlayInterface::DropLocation_Top:
135  case DropIndicatorOverlayInterface::DropLocation_Right:
137  case DropIndicatorOverlayInterface::DropLocation_Bottom:
139  case DropIndicatorOverlayInterface::DropLocation_OutterLeft:
141  case DropIndicatorOverlayInterface::DropLocation_OutterTop:
143  case DropIndicatorOverlayInterface::DropLocation_OutterRight:
145  case DropIndicatorOverlayInterface::DropLocation_OutterBottom:
147  default:
149  }
150 }
151 
152 void ClassicIndicators::setDropLocation(ClassicIndicators::DropLocation location)
153 {
154  setCurrentDropLocation(location);
155 
156  if (location == DropLocation_None) {
157  m_rubberBand->setVisible(false);
158  return;
159  }
160 
161  if (location == DropLocation_Center) {
162  m_rubberBand->setGeometry(geometryForRubberband(m_hoveredFrame ? m_hoveredFrame->QWidgetAdapter::geometry() : rect()));
163  m_rubberBand->setVisible(true);
164  if (rubberBandIsTopLevel()) {
165  m_rubberBand->raise();
166  raiseIndicators();
167  }
168 
169  return;
170  }
171 
172  KDDockWidgets::Location multisplitterLocation = locationToMultisplitterLocation(location);
173  Frame *relativeToFrame = nullptr;
174 
175  switch (location) {
176  case DropLocation_Left:
177  case DropLocation_Top:
178  case DropLocation_Right:
179  case DropLocation_Bottom:
180  if (!m_hoveredFrame) {
181  qWarning() << "ClassicIndicators::setCurrentDropLocation: frame is null. location=" << location
182  << "; isHovered=" << isHovered()
183  << "; dropArea->widgets=" << m_dropArea->items();
184  Q_ASSERT(false);
185  return;
186  }
187  relativeToFrame = m_hoveredFrame;
188  break;
189  case DropLocation_OutterLeft:
190  case DropLocation_OutterTop:
191  case DropLocation_OutterRight:
192  case DropLocation_OutterBottom:
193  break;
194  default:
195  break;
196  }
197 
198  auto windowBeingDragged = DragController::instance()->windowBeingDragged();
199 
200  QRect rect = m_dropArea->rectForDrop(windowBeingDragged, multisplitterLocation,
201  m_dropArea->itemForFrame(relativeToFrame));
202 
203  m_rubberBand->setGeometry(geometryForRubberband(rect));
204  m_rubberBand->setVisible(true);
205  if (rubberBandIsTopLevel()) {
206  m_rubberBand->raise();
207  raiseIndicators();
208  }
209 }
210 
211 void ClassicIndicators::updateWindowPosition()
212 {
213  QRect rect = this->rect();
214  if (KDDockWidgets::isWindow(m_indicatorWindow)) {
215  // On all non-wayland platforms it's a top-level.
216  QPoint pos = mapToGlobal(QPoint(0, 0));
217  rect.moveTo(pos);
218  }
219  m_indicatorWindow->setGeometry(rect);
220 }
221 
222 bool ClassicIndicators::rubberBandIsTopLevel() const
223 {
224 #ifdef KDDOCKWIDGETS_RUBBERBAND_IS_TOPLEVEL
225  return true;
226 #else
227  return false;
228 #endif
229 }
230 
231 QRect ClassicIndicators::geometryForRubberband(QRect localRect) const
232 {
233  if (!rubberBandIsTopLevel())
234  return localRect;
235 
236  QPoint topLeftLocal = localRect.topLeft();
237  QPoint topLeftGlobal = m_dropArea->QWidgetAdapter::mapToGlobal(topLeftLocal);
238 
239  localRect.moveTopLeft(topLeftGlobal);
240 
241  return localRect;
242 }
QRect::moveTopLeft
void moveTopLeft(const QPoint &position)
QRect::topLeft
QPoint topLeft() const const
QRect
KDDockWidgets::Location_OnTop
@ Location_OnTop
Left docking location
Definition: KDDockWidgets.h:48
KDDockWidgets::Location
Location
Definition: KDDockWidgets.h:45
QSize
KDDockWidgets::Location_OnBottom
@ Location_OnBottom
Right docking location
Definition: KDDockWidgets.h:50
locationToMultisplitterLocation
KDDockWidgets::Location locationToMultisplitterLocation(ClassicIndicators::DropLocation location)
Definition: ClassicIndicators.cpp:128
KDDockWidgets::Location_OnLeft
@ Location_OnLeft
Definition: KDDockWidgets.h:47
KDDockWidgets::Config
Singleton to allow to choose certain behaviours of the framework.
Definition: Config.h:55
KDDockWidgets::Location_OnRight
@ Location_OnRight
Top docking location
Definition: KDDockWidgets.h:49
Config.h
Application-wide config to tune certain behaviours of the framework.
createIndicatorWindow
static IndicatorWindow * createIndicatorWindow(ClassicIndicators *classicIndicators)
Definition: ClassicIndicators.cpp:28
KDDockWidgets
Definition: Config.cpp:36
KDDockWidgets::Location_None
@ Location_None
Definition: KDDockWidgets.h:46
QRect::moveTo
void moveTo(int x, int y)
QVector
QPoint
FrameworkWidgetFactory.h
A factory class for allowing the user to customize some internal widgets.

© 2019-2021 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 on Mon Nov 15 2021 00:17:17 for KDDockWidgets API Documentation by doxygen 1.8.20