Added mising DockFocusController files

This commit is contained in:
Uwe Kindler 2020-06-05 21:03:47 +02:00
parent f5c4b26aab
commit 2fc8bbe9c9
2 changed files with 403 additions and 0 deletions

320
src/DockFocusController.cpp Normal file
View File

@ -0,0 +1,320 @@
//============================================================================
/// \file DockFocusController.cpp
/// \author Uwe Kindler
/// \date 05.06.2020
/// \brief Implementation of CDockFocusController class
//============================================================================
//============================================================================
// INCLUDES
//============================================================================
#include "DockFocusController.h"
#include <algorithm>
#include <iostream>
#include <QPointer>
#include <QApplication>
#include "DockWidget.h"
#include "DockAreaWidget.h"
#include "DockWidgetTab.h"
#include "DockContainerWidget.h"
#include "FloatingDockContainer.h"
#include "DockManager.h"
#include "DockAreaTitleBar.h"
namespace ads
{
/**
* Private data class of CDockFocusController class (pimpl)
*/
struct DockFocusControllerPrivate
{
CDockFocusController *_this;
QPointer<CDockWidget> FocusedDockWidget = nullptr;
QPointer<CDockAreaWidget> FocusedArea = nullptr;
CDockManager* DockManager;
/**
* Private data constructor
*/
DockFocusControllerPrivate(CDockFocusController *_public);
/**
* This function updates the focus style of the given dock widget and
* the dock area that it belongs to
*/
void updateDockWidgetFocus(CDockWidget* DockWidget);
};
// struct DockFocusControllerPrivate
//===========================================================================
static void updateDockWidgetFocusStyle(CDockWidget* DockWidget, bool Focused)
{
DockWidget->setProperty("focused", Focused);
DockWidget->tabWidget()->setProperty("focused", Focused);
DockWidget->tabWidget()->updateStyle();
internal::repolishStyle(DockWidget);
}
//===========================================================================
static void updateDockAreaFocusStyle(CDockAreaWidget* DockArea, bool Focused)
{
DockArea->setProperty("focused", Focused);
internal::repolishStyle(DockArea);
internal::repolishStyle(DockArea->titleBar());
}
//===========================================================================
#ifdef Q_OS_LINUX
static void updateFloatingWidgetFocusStyle(CFloatingDockContainer* FloatingWidget, bool Focused)
{
auto TitleBar = qobject_cast<CFloatingWidgetTitleBar*>(FloatingWidget->titleBarWidget());
if (!TitleBar)
{
return;
}
TitleBar->setProperty("focused", Focused);
TitleBar->updateStyle();
}
#endif
//============================================================================
DockFocusControllerPrivate::DockFocusControllerPrivate(
CDockFocusController *_public) :
_this(_public)
{
}
//============================================================================
void DockFocusControllerPrivate::updateDockWidgetFocus(CDockWidget* DockWidget)
{
CDockAreaWidget* NewFocusedDockArea = nullptr;
if (FocusedDockWidget)
{
updateDockWidgetFocusStyle(FocusedDockWidget, false);
}
CDockWidget* old = FocusedDockWidget;
if (DockWidget != FocusedDockWidget)
{
std::cout << "!!!!!!!!!!!! focusedDockWidgetChanged " << (FocusedDockWidget ? FocusedDockWidget->objectName().toStdString() : "-")
<< " -> " << (DockWidget ? DockWidget->objectName().toStdString() : "-") << std::endl;
}
FocusedDockWidget = DockWidget;
updateDockWidgetFocusStyle(FocusedDockWidget, true);
NewFocusedDockArea = FocusedDockWidget->dockAreaWidget();
if (NewFocusedDockArea && (FocusedArea != NewFocusedDockArea))
{
if (FocusedArea)
{
std::cout << "FocusedArea" << std::endl;
QObject::disconnect(FocusedArea, SIGNAL(viewToggled(bool)), _this, SLOT(onFocusedDockAreaViewToggled(bool)));
updateDockAreaFocusStyle(FocusedArea, false);
}
FocusedArea = NewFocusedDockArea;
updateDockAreaFocusStyle(FocusedArea, true);
QObject::connect(FocusedArea, SIGNAL(viewToggled(bool)), _this, SLOT(onFocusedDockAreaViewToggled(bool)));
}
auto NewFloatingWidget = FocusedDockWidget->dockContainer()->floatingWidget();
if (NewFloatingWidget)
{
std::cout << "NewFloatingWidget->setProperty(FocusedDockWidget)" << std::endl;
NewFloatingWidget->setProperty("FocusedDockWidget", QVariant::fromValue(DockWidget));
}
#ifdef Q_OS_LINUX
// This code is required for styling the floating widget titlebar for linux
// depending on the current focus state
if (FloatingWidget == NewFloatingWidget)
{
return;
}
if (FloatingWidget)
{
updateFloatingWidgetFocusStyle(FloatingWidget, false);
}
FloatingWidget = NewFloatingWidget;
if (FloatingWidget)
{
updateFloatingWidgetFocusStyle(FloatingWidget, true);
}
#endif
if (old != DockWidget)
{
emit DockManager->focusedDockWidgetChanged(old, DockWidget);
}
}
//============================================================================
CDockFocusController::CDockFocusController(CDockManager* DockManager) :
Super(DockManager),
d(new DockFocusControllerPrivate(this))
{
d->DockManager = DockManager;
connect(QApplication::instance(), SIGNAL(focusChanged(QWidget*, QWidget*)),
this, SLOT(onApplicationFocusChanged(QWidget*, QWidget*)));
connect(d->DockManager, SIGNAL(stateRestored()), SLOT(onStateRestored()));
}
//============================================================================
CDockFocusController::~CDockFocusController()
{
delete d;
}
//===========================================================================
void CDockFocusController::onApplicationFocusChanged(QWidget* focusedOld, QWidget* focusedNow)
{
if (d->DockManager->isRestoringState())
{
return;
}
std::cout << "CDockManager::onFocusChanged" << std::endl;
std::cout << "focusedNow " << focusedNow << std::endl;
Q_UNUSED(focusedOld)
if (!focusedNow)
{
return;
}
CDockWidget* DockWidget = nullptr;
auto DockWidgetTab = qobject_cast<CDockWidgetTab*>(focusedNow);
std::cout << "FocuseNow " << focusedNow->metaObject()->className() << std::endl;
if (DockWidgetTab)
{
DockWidget = DockWidgetTab->dockWidget();
}
else
{
DockWidget = internal::findParent<CDockWidget*>(focusedNow);
}
#ifdef Q_OS_LINUX
if (!DockWidget)
{
return;
}
#else
if (!DockWidget || DockWidget->tabWidget()->isHidden())
{
std::cout << "!DockWidget || !DockWidget->tabWidget()->isVisible() " << (DockWidget ? DockWidget->objectName().toStdString() : "0") << std::endl;
std::cout << "DockWidget->tabWidget()->isHidden() " << (DockWidget ? DockWidget->tabWidget()->isHidden() : false) << std::endl;
return;
}
#endif
std::cout << "CDockManager::onFocusChanged " << DockWidget->tabWidget()->text().toStdString() << std::endl;
d->updateDockWidgetFocus(DockWidget);
}
//===========================================================================
void CDockFocusController::onFocusedDockAreaViewToggled(bool Open)
{
if (d->DockManager->isRestoringState())
{
return;
}
CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(sender());
if (!DockArea || Open)
{
return;
}
auto Container = DockArea->dockContainer();
auto OpenedDockAreas = Container->openedDockAreas();
if (OpenedDockAreas.isEmpty())
{
return;
}
CDockManager::setWidgetFocus(OpenedDockAreas[0]->currentDockWidget()->tabWidget());
}
//===========================================================================
void CDockFocusController::notifyWidgetOrAreaRelocation(QWidget* DroppedWidget)
{
if (d->DockManager->isRestoringState())
{
return;
}
std::cout << "\n\nCDockManager::notifyWidgetDrop" << std::endl;
CDockWidget* DockWidget = qobject_cast<CDockWidget*>(DroppedWidget);
if (DockWidget)
{
std::cout << "CDockManager::setWidgetFocus " << DockWidget->objectName().toStdString() << std::endl;
CDockManager::setWidgetFocus(DockWidget->tabWidget());
return;
}
CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(DroppedWidget);
if (!DockArea)
{
return;
}
DockWidget = DockArea->currentDockWidget();
CDockManager::setWidgetFocus(DockWidget->tabWidget());
std::cout << "\n\n" << std::endl;
}
//===========================================================================
void CDockFocusController::notifyFloatingWidgetDrop(CFloatingDockContainer* FloatingWidget)
{
std::cout << "\n\nCDockManager::notifyFloatingWidgetDrop" << std::endl;
if (!FloatingWidget || d->DockManager->isRestoringState())
{
return;
}
auto vDockWidget = FloatingWidget->property("FocusedDockWidget");
if (!vDockWidget.isValid())
{
return;
}
std::cout << "vDockWidget.isValid()" << std::endl;
auto DockWidget = vDockWidget.value<CDockWidget*>();
if (DockWidget)
{
std::cout << "Dropped focus dock widget " << DockWidget->objectName().toStdString() << std::endl;
DockWidget->dockAreaWidget()->setCurrentDockWidget(DockWidget);
CDockManager::setWidgetFocus(DockWidget->tabWidget());
}
std::cout << "\n\n" << std::endl;
}
//==========================================================================
void CDockFocusController::onStateRestored()
{
std::cout << "CDockFocusController::onStateRestored()" << std::endl;
if (d->FocusedDockWidget)
{
updateDockWidgetFocusStyle(d->FocusedDockWidget, false);
}
}
} // namespace ads
//---------------------------------------------------------------------------
// EOF DockFocusController.cpp

83
src/DockFocusController.h Normal file
View File

@ -0,0 +1,83 @@
#ifndef DockFocusControllerH
#define DockFocusControllerH
//============================================================================
/// \file DockFocusController.h
/// \author Uwe Kindler
/// \date 05.06.2020
/// \brief Declaration of CDockFocusController class
//============================================================================
//============================================================================
// INCLUDES
//============================================================================
#include <QObject>
#include "ads_globals.h"
#include "DockManager.h"
namespace ads
{
struct DockFocusControllerPrivate;
class CDockManager;
class CFloatingDockContainer;
/**
* Manages focus styling of dock widgets and handling of focus changes
*/
class ADS_EXPORT CDockFocusController : public QObject
{
Q_OBJECT
private:
DockFocusControllerPrivate* d; ///< private data (pimpl)
friend class DockFocusControllerPrivate;
private slots:
void onApplicationFocusChanged(QWidget *old, QWidget *now);
void onFocusedDockAreaViewToggled(bool Open);
void onStateRestored();
public:
using Super = QObject;
/**
* Default Constructor
*/
CDockFocusController(CDockManager* DockManager);
/**
* Virtual Destructor
*/
virtual ~CDockFocusController();
/**
* Helper function to set focus depending on the configuration of the
* FocusStyling flag
*/
template <class QWidgetPtr>
static void setWidgetFocus(QWidgetPtr widget)
{
if (!CDockManager::configFlags().testFlag(CDockManager::FocusStyling))
{
return;
}
widget->setFocus(Qt::OtherFocusReason);
}
/**
* A container needs to call this function if a widget has been dropped
* into it
*/
void notifyWidgetOrAreaRelocation(QWidget* RelocatedWidget);
/**
* This function is called, if a floating widget has been dropped into
* an new position.
* When this function is called, all dock widgets of the FloatingWidget
* are already inserted into its new position
*/
void notifyFloatingWidgetDrop(CFloatingDockContainer* FloatingWidget);
}; // class DockFocusController
}
// namespace ads
//-----------------------------------------------------------------------------
#endif // DockFocusControllerH