|
| 1 | +//============================================================================ |
| 2 | +/// \file DockFocusController.cpp |
| 3 | +/// \author Uwe Kindler |
| 4 | +/// \date 05.06.2020 |
| 5 | +/// \brief Implementation of CDockFocusController class |
| 6 | +//============================================================================ |
| 7 | + |
| 8 | +//============================================================================ |
| 9 | +// INCLUDES |
| 10 | +//============================================================================ |
| 11 | +#include "DockFocusController.h" |
| 12 | + |
| 13 | +#include <algorithm> |
| 14 | +#include <iostream> |
| 15 | + |
| 16 | +#include <QPointer> |
| 17 | +#include <QApplication> |
| 18 | + |
| 19 | +#include "DockWidget.h" |
| 20 | +#include "DockAreaWidget.h" |
| 21 | +#include "DockWidgetTab.h" |
| 22 | +#include "DockContainerWidget.h" |
| 23 | +#include "FloatingDockContainer.h" |
| 24 | +#include "DockManager.h" |
| 25 | +#include "DockAreaTitleBar.h" |
| 26 | + |
| 27 | +namespace ads |
| 28 | +{ |
| 29 | +/** |
| 30 | + * Private data class of CDockFocusController class (pimpl) |
| 31 | + */ |
| 32 | +struct DockFocusControllerPrivate |
| 33 | +{ |
| 34 | + CDockFocusController *_this; |
| 35 | + QPointer<CDockWidget> FocusedDockWidget = nullptr; |
| 36 | + QPointer<CDockAreaWidget> FocusedArea = nullptr; |
| 37 | + CDockManager* DockManager; |
| 38 | + |
| 39 | + /** |
| 40 | + * Private data constructor |
| 41 | + */ |
| 42 | + DockFocusControllerPrivate(CDockFocusController *_public); |
| 43 | + |
| 44 | + /** |
| 45 | + * This function updates the focus style of the given dock widget and |
| 46 | + * the dock area that it belongs to |
| 47 | + */ |
| 48 | + void updateDockWidgetFocus(CDockWidget* DockWidget); |
| 49 | +}; |
| 50 | +// struct DockFocusControllerPrivate |
| 51 | + |
| 52 | + |
| 53 | +//=========================================================================== |
| 54 | +static void updateDockWidgetFocusStyle(CDockWidget* DockWidget, bool Focused) |
| 55 | +{ |
| 56 | + DockWidget->setProperty("focused", Focused); |
| 57 | + DockWidget->tabWidget()->setProperty("focused", Focused); |
| 58 | + DockWidget->tabWidget()->updateStyle(); |
| 59 | + internal::repolishStyle(DockWidget); |
| 60 | +} |
| 61 | + |
| 62 | + |
| 63 | +//=========================================================================== |
| 64 | +static void updateDockAreaFocusStyle(CDockAreaWidget* DockArea, bool Focused) |
| 65 | +{ |
| 66 | + DockArea->setProperty("focused", Focused); |
| 67 | + internal::repolishStyle(DockArea); |
| 68 | + internal::repolishStyle(DockArea->titleBar()); |
| 69 | +} |
| 70 | + |
| 71 | + |
| 72 | +//=========================================================================== |
| 73 | +#ifdef Q_OS_LINUX |
| 74 | +static void updateFloatingWidgetFocusStyle(CFloatingDockContainer* FloatingWidget, bool Focused) |
| 75 | +{ |
| 76 | + auto TitleBar = qobject_cast<CFloatingWidgetTitleBar*>(FloatingWidget->titleBarWidget()); |
| 77 | + if (!TitleBar) |
| 78 | + { |
| 79 | + return; |
| 80 | + } |
| 81 | + TitleBar->setProperty("focused", Focused); |
| 82 | + TitleBar->updateStyle(); |
| 83 | +} |
| 84 | +#endif |
| 85 | + |
| 86 | + |
| 87 | +//============================================================================ |
| 88 | +DockFocusControllerPrivate::DockFocusControllerPrivate( |
| 89 | + CDockFocusController *_public) : |
| 90 | + _this(_public) |
| 91 | +{ |
| 92 | + |
| 93 | +} |
| 94 | + |
| 95 | + |
| 96 | +//============================================================================ |
| 97 | +void DockFocusControllerPrivate::updateDockWidgetFocus(CDockWidget* DockWidget) |
| 98 | +{ |
| 99 | + CDockAreaWidget* NewFocusedDockArea = nullptr; |
| 100 | + if (FocusedDockWidget) |
| 101 | + { |
| 102 | + updateDockWidgetFocusStyle(FocusedDockWidget, false); |
| 103 | + } |
| 104 | + |
| 105 | + CDockWidget* old = FocusedDockWidget; |
| 106 | + if (DockWidget != FocusedDockWidget) |
| 107 | + { |
| 108 | + std::cout << "!!!!!!!!!!!! focusedDockWidgetChanged " << (FocusedDockWidget ? FocusedDockWidget->objectName().toStdString() : "-") |
| 109 | + << " -> " << (DockWidget ? DockWidget->objectName().toStdString() : "-") << std::endl; |
| 110 | + } |
| 111 | + FocusedDockWidget = DockWidget; |
| 112 | + updateDockWidgetFocusStyle(FocusedDockWidget, true); |
| 113 | + NewFocusedDockArea = FocusedDockWidget->dockAreaWidget(); |
| 114 | + if (NewFocusedDockArea && (FocusedArea != NewFocusedDockArea)) |
| 115 | + { |
| 116 | + if (FocusedArea) |
| 117 | + { |
| 118 | + std::cout << "FocusedArea" << std::endl; |
| 119 | + QObject::disconnect(FocusedArea, SIGNAL(viewToggled(bool)), _this, SLOT(onFocusedDockAreaViewToggled(bool))); |
| 120 | + updateDockAreaFocusStyle(FocusedArea, false); |
| 121 | + } |
| 122 | + |
| 123 | + FocusedArea = NewFocusedDockArea; |
| 124 | + updateDockAreaFocusStyle(FocusedArea, true); |
| 125 | + QObject::connect(FocusedArea, SIGNAL(viewToggled(bool)), _this, SLOT(onFocusedDockAreaViewToggled(bool))); |
| 126 | + } |
| 127 | + |
| 128 | + |
| 129 | + auto NewFloatingWidget = FocusedDockWidget->dockContainer()->floatingWidget(); |
| 130 | + if (NewFloatingWidget) |
| 131 | + { |
| 132 | + std::cout << "NewFloatingWidget->setProperty(FocusedDockWidget)" << std::endl; |
| 133 | + NewFloatingWidget->setProperty("FocusedDockWidget", QVariant::fromValue(DockWidget)); |
| 134 | + } |
| 135 | + |
| 136 | + |
| 137 | +#ifdef Q_OS_LINUX |
| 138 | + // This code is required for styling the floating widget titlebar for linux |
| 139 | + // depending on the current focus state |
| 140 | + if (FloatingWidget == NewFloatingWidget) |
| 141 | + { |
| 142 | + return; |
| 143 | + } |
| 144 | + |
| 145 | + if (FloatingWidget) |
| 146 | + { |
| 147 | + updateFloatingWidgetFocusStyle(FloatingWidget, false); |
| 148 | + } |
| 149 | + FloatingWidget = NewFloatingWidget; |
| 150 | + |
| 151 | + if (FloatingWidget) |
| 152 | + { |
| 153 | + updateFloatingWidgetFocusStyle(FloatingWidget, true); |
| 154 | + } |
| 155 | +#endif |
| 156 | + |
| 157 | + if (old != DockWidget) |
| 158 | + { |
| 159 | + emit DockManager->focusedDockWidgetChanged(old, DockWidget); |
| 160 | + } |
| 161 | +} |
| 162 | + |
| 163 | + |
| 164 | + |
| 165 | +//============================================================================ |
| 166 | +CDockFocusController::CDockFocusController(CDockManager* DockManager) : |
| 167 | + Super(DockManager), |
| 168 | + d(new DockFocusControllerPrivate(this)) |
| 169 | +{ |
| 170 | + d->DockManager = DockManager; |
| 171 | + connect(QApplication::instance(), SIGNAL(focusChanged(QWidget*, QWidget*)), |
| 172 | + this, SLOT(onApplicationFocusChanged(QWidget*, QWidget*))); |
| 173 | + connect(d->DockManager, SIGNAL(stateRestored()), SLOT(onStateRestored())); |
| 174 | +} |
| 175 | + |
| 176 | +//============================================================================ |
| 177 | +CDockFocusController::~CDockFocusController() |
| 178 | +{ |
| 179 | + delete d; |
| 180 | +} |
| 181 | + |
| 182 | + |
| 183 | +//=========================================================================== |
| 184 | +void CDockFocusController::onApplicationFocusChanged(QWidget* focusedOld, QWidget* focusedNow) |
| 185 | +{ |
| 186 | + if (d->DockManager->isRestoringState()) |
| 187 | + { |
| 188 | + return; |
| 189 | + } |
| 190 | + std::cout << "CDockManager::onFocusChanged" << std::endl; |
| 191 | + std::cout << "focusedNow " << focusedNow << std::endl; |
| 192 | + Q_UNUSED(focusedOld) |
| 193 | + if (!focusedNow) |
| 194 | + { |
| 195 | + return; |
| 196 | + } |
| 197 | + |
| 198 | + CDockWidget* DockWidget = nullptr; |
| 199 | + auto DockWidgetTab = qobject_cast<CDockWidgetTab*>(focusedNow); |
| 200 | + std::cout << "FocuseNow " << focusedNow->metaObject()->className() << std::endl; |
| 201 | + if (DockWidgetTab) |
| 202 | + { |
| 203 | + DockWidget = DockWidgetTab->dockWidget(); |
| 204 | + } |
| 205 | + else |
| 206 | + { |
| 207 | + DockWidget = internal::findParent<CDockWidget*>(focusedNow); |
| 208 | + } |
| 209 | + |
| 210 | +#ifdef Q_OS_LINUX |
| 211 | + if (!DockWidget) |
| 212 | + { |
| 213 | + return; |
| 214 | + } |
| 215 | +#else |
| 216 | + if (!DockWidget || DockWidget->tabWidget()->isHidden()) |
| 217 | + { |
| 218 | + std::cout << "!DockWidget || !DockWidget->tabWidget()->isVisible() " << (DockWidget ? DockWidget->objectName().toStdString() : "0") << std::endl; |
| 219 | + std::cout << "DockWidget->tabWidget()->isHidden() " << (DockWidget ? DockWidget->tabWidget()->isHidden() : false) << std::endl; |
| 220 | + return; |
| 221 | + } |
| 222 | +#endif |
| 223 | + |
| 224 | + std::cout << "CDockManager::onFocusChanged " << DockWidget->tabWidget()->text().toStdString() << std::endl; |
| 225 | + d->updateDockWidgetFocus(DockWidget); |
| 226 | +} |
| 227 | + |
| 228 | + |
| 229 | +//=========================================================================== |
| 230 | +void CDockFocusController::onFocusedDockAreaViewToggled(bool Open) |
| 231 | +{ |
| 232 | + if (d->DockManager->isRestoringState()) |
| 233 | + { |
| 234 | + return; |
| 235 | + } |
| 236 | + |
| 237 | + CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(sender()); |
| 238 | + if (!DockArea || Open) |
| 239 | + { |
| 240 | + return; |
| 241 | + } |
| 242 | + auto Container = DockArea->dockContainer(); |
| 243 | + auto OpenedDockAreas = Container->openedDockAreas(); |
| 244 | + if (OpenedDockAreas.isEmpty()) |
| 245 | + { |
| 246 | + return; |
| 247 | + } |
| 248 | + |
| 249 | + CDockManager::setWidgetFocus(OpenedDockAreas[0]->currentDockWidget()->tabWidget()); |
| 250 | +} |
| 251 | + |
| 252 | + |
| 253 | +//=========================================================================== |
| 254 | +void CDockFocusController::notifyWidgetOrAreaRelocation(QWidget* DroppedWidget) |
| 255 | +{ |
| 256 | + if (d->DockManager->isRestoringState()) |
| 257 | + { |
| 258 | + return; |
| 259 | + } |
| 260 | + std::cout << "\n\nCDockManager::notifyWidgetDrop" << std::endl; |
| 261 | + CDockWidget* DockWidget = qobject_cast<CDockWidget*>(DroppedWidget); |
| 262 | + if (DockWidget) |
| 263 | + { |
| 264 | + std::cout << "CDockManager::setWidgetFocus " << DockWidget->objectName().toStdString() << std::endl; |
| 265 | + CDockManager::setWidgetFocus(DockWidget->tabWidget()); |
| 266 | + return; |
| 267 | + } |
| 268 | + |
| 269 | + CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(DroppedWidget); |
| 270 | + if (!DockArea) |
| 271 | + { |
| 272 | + return; |
| 273 | + } |
| 274 | + |
| 275 | + DockWidget = DockArea->currentDockWidget(); |
| 276 | + CDockManager::setWidgetFocus(DockWidget->tabWidget()); |
| 277 | + std::cout << "\n\n" << std::endl; |
| 278 | +} |
| 279 | + |
| 280 | + |
| 281 | +//=========================================================================== |
| 282 | +void CDockFocusController::notifyFloatingWidgetDrop(CFloatingDockContainer* FloatingWidget) |
| 283 | +{ |
| 284 | + std::cout << "\n\nCDockManager::notifyFloatingWidgetDrop" << std::endl; |
| 285 | + if (!FloatingWidget || d->DockManager->isRestoringState()) |
| 286 | + { |
| 287 | + return; |
| 288 | + } |
| 289 | + |
| 290 | + auto vDockWidget = FloatingWidget->property("FocusedDockWidget"); |
| 291 | + if (!vDockWidget.isValid()) |
| 292 | + { |
| 293 | + return; |
| 294 | + } |
| 295 | + std::cout << "vDockWidget.isValid()" << std::endl; |
| 296 | + auto DockWidget = vDockWidget.value<CDockWidget*>(); |
| 297 | + if (DockWidget) |
| 298 | + { |
| 299 | + std::cout << "Dropped focus dock widget " << DockWidget->objectName().toStdString() << std::endl; |
| 300 | + DockWidget->dockAreaWidget()->setCurrentDockWidget(DockWidget); |
| 301 | + CDockManager::setWidgetFocus(DockWidget->tabWidget()); |
| 302 | + } |
| 303 | + std::cout << "\n\n" << std::endl; |
| 304 | +} |
| 305 | + |
| 306 | + |
| 307 | +//========================================================================== |
| 308 | +void CDockFocusController::onStateRestored() |
| 309 | +{ |
| 310 | + std::cout << "CDockFocusController::onStateRestored()" << std::endl; |
| 311 | + if (d->FocusedDockWidget) |
| 312 | + { |
| 313 | + updateDockWidgetFocusStyle(d->FocusedDockWidget, false); |
| 314 | + } |
| 315 | +} |
| 316 | + |
| 317 | +} // namespace ads |
| 318 | + |
| 319 | +//--------------------------------------------------------------------------- |
| 320 | +// EOF DockFocusController.cpp |
0 commit comments