forked from qt-creator/qt-creator
ADS: Integrate newest base repository commits
* Activate new ADS feature focus highlight * Remove resources.qrc and related *.svg files * Clean up new and existing source Base repository was merged until commit 3de877fe5635ff51a6d1205ca98aad85d204427f Merged changes from base repository include the following: * Fix wrong current index when removing a widget from DockAreaLayout * Fix invisible TabWidget for DockWidgets that are not part of a restored state * Enable ClickFocus for DockWidget to support focussing in case the content does not support it * Move focus related functionality into DockFocusController class * Add new DockManger config flag FocusStyling * Add support for focus styling of FloatingWidgetTitleBar * Improve focus handling when dropping a DockWidget * Improve highlighting focused DockWidget * Improve setting of DockWidgetTab focus * Add styling of focused DockWidget * Fix docking of floating widgets for macOS * Fix setting of DockingStateReader file version - use internal file version instead of user file version * Fix saveState() and restoreState() version handling to work like the function from QMainWindow * Fix escape key handling in native window event function if event WM_EXITSIZEMOVE occurs * Implement windows drag handling with native WM_ nonclient area messages * Fix showing DockArea when inserting a DockWidget in a hidden DockArea * Fix setting DockAreaTabBar index to prevent showing of tab 0 when inserting a DockWidget into an area with no current index tab * Fix wrong insertion order of DockWidget when dropping a floating widget to the left or top container drop area * Fix tab changes position when redocking it to the same position * Add nullptr check to fix potential nullptr access when closing a FloatingDockContainer * Fix single DockArea cannot be split * Fix visibility issue when adding dock widget after all other dock widgets have ben closed * Fix FloatingDragPreview flashing of hidden overlay when dragging the last visible DockWidget in non opaque docking mode * Fix FloatingDragPreview preventing dock widget from floating when dragging over another dock widget * Fix DockWidget::setWidget function to test for QAbstractScrollArea instead of QScrollArea. Now setWidget properly supports ItemViews like QTreeView or QTableView * Fix wrong display of center drop area when dragging over invisible dock area title bar * Fix bug that drop overlay sometimes was not visible when moving the drag preview over a floating window * Fix dropping of FloatingDragPreview into center of dock container with only one single visible dock area. If this happens the dropped dock widget needs to get tabified * Fix crash when trying to make a DockWidget floating in non-opaque mode if the DockWidget is not floatable * Fix DockWidgetTab to provide the right size when starting floating * Add DockWidget functions setAsCurrentTab, raise, isCurrentTab, isTabbed * Add new config flag HideSingleCentralWidgetTitleBar to enable a central single dock widget in the main dock container (dock manager) without titlebar * Fix DockContainerWidget::hasTopLevelDockWidget() and DockContainerWidget::topLevelDockArea() to work properly also for the main non floating dock container * Fix ElidingLabel to properly support Qt::ElideNone * Add setElideMode function to DockWidgetTab * Add setFullScreen(), setNormal() and isFullScreen() function to DockWidget * Fix takeWidget() function and fixed setWidget() function to handle case when there is already a content widget Task-number: QDS-2180 Change-Id: Ie30648ba329016c91fd19e9b4e12e31e47614b18 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
committed by
Henning Gründl
parent
e5d9cb3779
commit
a98c254c59
273
src/libs/advanceddockingsystem/dockfocuscontroller.cpp
Normal file
273
src/libs/advanceddockingsystem/dockfocuscontroller.cpp
Normal file
@@ -0,0 +1,273 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 Uwe Kindler
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or (at your option) any later version.
|
||||
** The licenses are as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.LGPLv21 included in the packaging
|
||||
** of this file. Please review the following information to ensure
|
||||
** the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "dockfocuscontroller.h"
|
||||
|
||||
#include "dockareawidget.h"
|
||||
#include "dockareatitlebar.h"
|
||||
#include "dockcontainerwidget.h"
|
||||
#include "dockmanager.h"
|
||||
#include "dockwidget.h"
|
||||
#include "dockwidgettab.h"
|
||||
#include "floatingdockcontainer.h"
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#include "linux/floatingwidgettitlebar.h"
|
||||
#endif
|
||||
|
||||
#include <QApplication>
|
||||
#include <QPointer>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
namespace ADS
|
||||
{
|
||||
/**
|
||||
* Private data class of CDockFocusController class (pimpl)
|
||||
*/
|
||||
class DockFocusControllerPrivate
|
||||
{
|
||||
public:
|
||||
DockFocusController *q;
|
||||
QPointer<DockWidget> m_focusedDockWidget = nullptr;
|
||||
QPointer<DockAreaWidget> m_focusedArea = nullptr;
|
||||
#ifdef Q_OS_LINUX
|
||||
QPointer<FloatingDockContainer> m_floatingWidget = nullptr;
|
||||
#endif
|
||||
DockManager *m_dockManager;
|
||||
|
||||
/**
|
||||
* Private data constructor
|
||||
*/
|
||||
DockFocusControllerPrivate(DockFocusController *parent);
|
||||
|
||||
/**
|
||||
* This function updates the focus style of the given dock widget and
|
||||
* the dock area that it belongs to
|
||||
*/
|
||||
void updateDockWidgetFocus(DockWidget *dockWidget);
|
||||
}; // class DockFocusControllerPrivate
|
||||
|
||||
static void updateDockWidgetFocusStyle(DockWidget *dockWidget, bool focused)
|
||||
{
|
||||
dockWidget->setProperty("focused", focused);
|
||||
dockWidget->tabWidget()->setProperty("focused", focused);
|
||||
dockWidget->tabWidget()->updateStyle();
|
||||
internal::repolishStyle(dockWidget);
|
||||
}
|
||||
|
||||
static void updateDockAreaFocusStyle(DockAreaWidget *dockArea, bool focused)
|
||||
{
|
||||
dockArea->setProperty("focused", focused);
|
||||
internal::repolishStyle(dockArea);
|
||||
internal::repolishStyle(dockArea->titleBar());
|
||||
}
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
static void updateFloatingWidgetFocusStyle(FloatingDockContainer *floatingWidget, bool focused)
|
||||
{
|
||||
auto titleBar = qobject_cast<FloatingWidgetTitleBar *>(floatingWidget->titleBarWidget());
|
||||
if (!titleBar)
|
||||
return;
|
||||
|
||||
titleBar->setProperty("focused", focused);
|
||||
titleBar->updateStyle();
|
||||
}
|
||||
#endif
|
||||
|
||||
DockFocusControllerPrivate::DockFocusControllerPrivate(DockFocusController *parent)
|
||||
: q(parent)
|
||||
{}
|
||||
|
||||
void DockFocusControllerPrivate::updateDockWidgetFocus(DockWidget *dockWidget)
|
||||
{
|
||||
DockAreaWidget *newFocusedDockArea = nullptr;
|
||||
if (m_focusedDockWidget)
|
||||
updateDockWidgetFocusStyle(m_focusedDockWidget, false);
|
||||
|
||||
DockWidget *old = m_focusedDockWidget;
|
||||
m_focusedDockWidget = dockWidget;
|
||||
updateDockWidgetFocusStyle(m_focusedDockWidget, true);
|
||||
newFocusedDockArea = m_focusedDockWidget->dockAreaWidget();
|
||||
if (newFocusedDockArea && (m_focusedArea != newFocusedDockArea))
|
||||
{
|
||||
if (m_focusedArea)
|
||||
{
|
||||
QObject::disconnect(m_focusedArea, &DockAreaWidget::viewToggled,
|
||||
q, &DockFocusController::onFocusedDockAreaViewToggled);
|
||||
updateDockAreaFocusStyle(m_focusedArea, false);
|
||||
}
|
||||
|
||||
m_focusedArea = newFocusedDockArea;
|
||||
updateDockAreaFocusStyle(m_focusedArea, true);
|
||||
QObject::connect(m_focusedArea, &DockAreaWidget::viewToggled,
|
||||
q, &DockFocusController::onFocusedDockAreaViewToggled);
|
||||
}
|
||||
|
||||
auto newFloatingWidget = m_focusedDockWidget->dockContainer()->floatingWidget();
|
||||
if (newFloatingWidget)
|
||||
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 (m_floatingWidget == newFloatingWidget)
|
||||
return;
|
||||
|
||||
if (m_floatingWidget)
|
||||
updateFloatingWidgetFocusStyle(m_floatingWidget, false);
|
||||
|
||||
m_floatingWidget = newFloatingWidget;
|
||||
|
||||
if (m_floatingWidget)
|
||||
updateFloatingWidgetFocusStyle(m_floatingWidget, true);
|
||||
#endif
|
||||
|
||||
if (old != dockWidget)
|
||||
emit m_dockManager->focusedDockWidgetChanged(old, dockWidget);
|
||||
}
|
||||
|
||||
DockFocusController::DockFocusController(DockManager *dockManager)
|
||||
: QObject(dockManager)
|
||||
, d(new DockFocusControllerPrivate(this))
|
||||
{
|
||||
d->m_dockManager = dockManager;
|
||||
connect(qApp, &QApplication::focusChanged,
|
||||
this, &DockFocusController::onApplicationFocusChanged);
|
||||
connect(d->m_dockManager, &DockManager::stateRestored,
|
||||
this, &DockFocusController::onStateRestored);
|
||||
}
|
||||
|
||||
DockFocusController::~DockFocusController()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
void DockFocusController::onApplicationFocusChanged(QWidget *focusedOld, QWidget *focusedNow)
|
||||
{
|
||||
if (d->m_dockManager->isRestoringState())
|
||||
return;
|
||||
|
||||
if (!focusedNow)
|
||||
return;
|
||||
|
||||
DockWidget *dockWidget = nullptr;
|
||||
auto dockWidgetTab = qobject_cast<DockWidgetTab *>(focusedNow);
|
||||
if (dockWidgetTab)
|
||||
dockWidget = dockWidgetTab->dockWidget();
|
||||
|
||||
if (!dockWidget)
|
||||
dockWidget = qobject_cast<DockWidget *>(focusedNow);
|
||||
|
||||
if (!dockWidget)
|
||||
dockWidget = internal::findParent<DockWidget *>(focusedNow);
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
if (!dockWidget)
|
||||
return;
|
||||
#else
|
||||
if (!dockWidget || dockWidget->tabWidget()->isHidden())
|
||||
return;
|
||||
#endif
|
||||
|
||||
d->updateDockWidgetFocus(dockWidget);
|
||||
}
|
||||
|
||||
void DockFocusController::setDockWidgetFocused(DockWidget *focusedNow)
|
||||
{
|
||||
d->updateDockWidgetFocus(focusedNow);
|
||||
}
|
||||
|
||||
void DockFocusController::onFocusedDockAreaViewToggled(bool open)
|
||||
{
|
||||
if (d->m_dockManager->isRestoringState())
|
||||
return;
|
||||
|
||||
DockAreaWidget* dockArea = qobject_cast<DockAreaWidget *>(sender());
|
||||
if (!dockArea || open)
|
||||
return;
|
||||
|
||||
auto container = dockArea->dockContainer();
|
||||
auto openedDockAreas = container->openedDockAreas();
|
||||
if (openedDockAreas.isEmpty())
|
||||
return;
|
||||
|
||||
DockManager::setWidgetFocus(openedDockAreas[0]->currentDockWidget()->tabWidget());
|
||||
}
|
||||
|
||||
void DockFocusController::notifyWidgetOrAreaRelocation(QWidget *droppedWidget)
|
||||
{
|
||||
if (d->m_dockManager->isRestoringState())
|
||||
return;
|
||||
|
||||
DockWidget *dockWidget = qobject_cast<DockWidget *>(droppedWidget);
|
||||
if (dockWidget)
|
||||
{
|
||||
DockManager::setWidgetFocus(dockWidget->tabWidget());
|
||||
return;
|
||||
}
|
||||
|
||||
DockAreaWidget* dockArea = qobject_cast<DockAreaWidget*>(droppedWidget);
|
||||
if (!dockArea)
|
||||
return;
|
||||
|
||||
dockWidget = dockArea->currentDockWidget();
|
||||
DockManager::setWidgetFocus(dockWidget->tabWidget());
|
||||
}
|
||||
|
||||
void DockFocusController::notifyFloatingWidgetDrop(FloatingDockContainer *floatingWidget)
|
||||
{
|
||||
if (!floatingWidget || d->m_dockManager->isRestoringState())
|
||||
return;
|
||||
|
||||
auto vDockWidget = floatingWidget->property("FocusedDockWidget");
|
||||
if (!vDockWidget.isValid())
|
||||
return;
|
||||
|
||||
auto dockWidget = vDockWidget.value<DockWidget *>();
|
||||
if (dockWidget) {
|
||||
dockWidget->dockAreaWidget()->setCurrentDockWidget(dockWidget);
|
||||
DockManager::setWidgetFocus(dockWidget->tabWidget());
|
||||
}
|
||||
}
|
||||
|
||||
void DockFocusController::onStateRestored()
|
||||
{
|
||||
if (d->m_focusedDockWidget)
|
||||
updateDockWidgetFocusStyle(d->m_focusedDockWidget, false);
|
||||
}
|
||||
|
||||
} // namespace ADS
|
||||
Reference in New Issue
Block a user