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