Move KDBindings usage from View.h to View_p.h

KDBindings is implementation detail. User won't have to install
it, at this point.
This commit is contained in:
Sergio Martins
2022-06-18 12:15:42 +01:00
parent 9f1a9df621
commit 7017ce8396
19 changed files with 150 additions and 72 deletions

View File

@@ -10,7 +10,7 @@
*/
#include "View.h"
#include "private/View_p.h"
#include "private/multisplitter/Item_p.h"
#include "controllers/FloatingWindow.h"
@@ -35,7 +35,8 @@ static qint64 s_nextId = 1;
}
View::View(Controller *controller, Type type, QObject *thisObj)
: m_controller(controller)
: d(new Private())
, m_controller(controller)
, m_thisObj(thisObj)
, m_id(QString::number(KDDockWidgets::s_nextId++))
, m_type(type)
@@ -45,7 +46,7 @@ View::View(Controller *controller, Type type, QObject *thisObj)
View::~View()
{
m_inDtor = true;
beingDestroyed.emit();
d->beingDestroyed.emit();
if (!freed() && !is(Type::ViewWrapper)) {
// TODOm3
@@ -55,6 +56,8 @@ View::~View()
// and destroy its controller, which was the old behaviour.
delete m_controller;
}
delete d;
}
QString View::id() const
@@ -398,3 +401,9 @@ std::shared_ptr<Window> View::transientWindow() const
return {};
}
bool View::onResize(QSize newSize)
{
d->resized.emit(newSize);
return false;
}

View File

@@ -19,8 +19,6 @@
#include <QRect>
#include <QObject>
#include "kdbindings/signal.h"
#include <memory>
namespace Layouting {
@@ -178,11 +176,7 @@ public:
virtual void setCursor(Qt::CursorShape) = 0;
virtual void setMouseTracking(bool) = 0;
virtual bool onResize(QSize newSize)
{
resized.emit(newSize);
return false;
}
virtual bool onResize(QSize newSize);
virtual bool onFocusInEvent(QFocusEvent *)
{
@@ -273,20 +267,12 @@ public:
Controller *firstParentOfType(KDDockWidgets::Type) const;
public:
/// @brief signal emitted once ~View starts
KDBindings::Signal<> beingDestroyed;
/// @brief signal emitted when something tried to close this view
KDBindings::Signal<QCloseEvent *> closeRequested;
/// @brief signal emitted when constraints change, for example min/max sizes
KDBindings::Signal<> layoutInvalidated;
/// @brief signal emitted when the view is resized
KDBindings::Signal<QSize> resized;
class Private;
Private *const d;
protected:
virtual void free_impl();
virtual void
free_impl();
Controller *const m_controller;
QObject *const m_thisObj;

View File

@@ -11,6 +11,7 @@
#include "ViewGuard.h"
#include "View.h"
#include "private/View_p.h"
using namespace KDDockWidgets;
@@ -81,7 +82,7 @@ void ViewGuard::setView(View *view)
v = view;
if (v) {
m_onDestroy = v->beingDestroyed.connect([this] {
m_onDestroy = v->d->beingDestroyed.connect([this] {
v = nullptr;
});
}

View File

@@ -17,6 +17,7 @@
#include "private/Position_p.h"
#include "ViewWrapper.h"
#include "Action.h"
#include "private/View_p.h"
#include <QCoreApplication>
#include <QString>
@@ -59,7 +60,7 @@ public:
void init()
{
updateTitle();
q->view()->closeRequested.connect([this](QCloseEvent *ev) {
q->view()->d->closeRequested.connect([this](QCloseEvent *ev) {
onCloseEvent(ev);
});
}

View File

@@ -28,6 +28,9 @@
#include "private/multisplitter/Item_p.h"
#include "View.h"
#include "private/View_p.h"
#include "kdbindings/signal.h"
#include <QCloseEvent>
#include <QScopedValueRollback>
@@ -45,6 +48,12 @@
using namespace KDDockWidgets;
using namespace KDDockWidgets::Controllers;
class FloatingWindow::Private
{
public:
KDBindings::ScopedConnection m_visibleWidgetCountConnection;
};
/** static */
Qt::WindowFlags FloatingWindow::s_windowFlagsOverride = {};
@@ -108,6 +117,7 @@ MainWindow *actualParent(MainWindow *candidate)
FloatingWindow::FloatingWindow(QRect suggestedGeometry, MainWindow *parent)
: Controller(Type::FloatingWindow, Config::self().viewFactory()->createFloatingWindow(this, actualParent(parent), windowFlagsToUse()))
, Draggable(view(), KDDockWidgets::usesNativeDraggingAndResizing()) // FloatingWindow is only draggable when using a native title bar. Otherwise the KDDockWidgets::TitleBar is the draggable
, d(new Private())
, m_dropArea(new DropArea(view(), MainWindowOption_None))
, m_titleBar(new Controllers::TitleBar(this))
{
@@ -137,17 +147,17 @@ FloatingWindow::FloatingWindow(QRect suggestedGeometry, MainWindow *parent)
updateTitleBarVisibility();
m_visibleWidgetCountConnection = m_dropArea->visibleWidgetCountChanged.connect([this](int count) {
d->m_visibleWidgetCountConnection = m_dropArea->visibleWidgetCountChanged.connect([this](int count) {
onFrameCountChanged(count);
numFramesChanged();
onVisibleFrameCountChanged(count);
});
view()->closeRequested.connect([this](QCloseEvent *ev) {
view()->d->closeRequested.connect([this](QCloseEvent *ev) {
onCloseEvent(ev);
});
view()->layoutInvalidated.connect([this] {
view()->d->layoutInvalidated.connect([this] {
updateSizeConstraints();
});
@@ -224,6 +234,7 @@ FloatingWindow::~FloatingWindow()
DockRegistry::self()->unregisterFloatingWindow(this);
delete m_titleBar;
delete d;
}
void FloatingWindow::maybeCreateResizeHandler()

View File

@@ -214,6 +214,10 @@ Q_SIGNALS:
void numFramesChanged();
void windowStateChanged(QWindowStateChangeEvent *);
private:
class Private;
Private *const d;
protected:
QPointer<DropArea> m_dropArea;
Controllers::TitleBar *const m_titleBar;
@@ -225,12 +229,12 @@ private:
void onVisibleFrameCountChanged(int count);
void onCloseEvent(QCloseEvent *);
void updateSizeConstraints();
bool m_disableSetVisible = false;
bool m_deleteScheduled = false;
bool m_inDtor = false;
bool m_updatingTitleBarVisibility = false;
QMetaObject::Connection m_layoutDestroyedConnection;
KDBindings::ScopedConnection m_visibleWidgetCountConnection;
QAbstractNativeEventFilter *m_nchittestFilter = nullptr;
Qt::WindowState windowStateOverride() const;
#ifdef Q_OS_WIN

View File

@@ -27,15 +27,19 @@
#include "controllers/Layout.h"
#include "controllers/MainWindow.h"
#include "private/Logging_p.h"
#include "private/Utils_p.h"
#include "DockRegistry.h"
#include "DockWidget_p.h"
#include "private/Logging_p.h"
#include "private/Utils_p.h"
#include "private/View_p.h"
#include "private/LayoutSaver_p.h"
#include "private/Position_p.h"
#include "private/WidgetResizeHandler_p.h"
#include "private/multisplitter/Item_p.h"
#include "kdbindings/signal.h"
#include <QCloseEvent>
#include <QTimer>
@@ -48,6 +52,12 @@ using namespace KDDockWidgets::Controllers;
namespace KDDockWidgets {
class Frame::Private
{
public:
KDBindings::ScopedConnection m_visibleWidgetCountChangedConnection;
};
static FrameOptions actualOptions(FrameOptions options)
{
if (Config::self().flags() & Config::Flag_AlwaysShowTabs)
@@ -71,6 +81,7 @@ static StackOptions tabWidgetOptions(FrameOptions options)
Frame::Frame(View *parent, FrameOptions options, int userType)
: Controller(Type::Frame, Config::self().viewFactory()->createFrame(this, parent))
, FocusScope(view())
, d(new Private())
, m_tabWidget(new Controllers::Stack(this, tabWidgetOptions(options)))
, m_titleBar(new Controllers::TitleBar(this))
, m_options(actualOptions(options))
@@ -85,7 +96,7 @@ Frame::Frame(View *parent, FrameOptions options, int userType)
setLayout(parent ? parent->asLayout() : nullptr);
view()->init();
view()->closeRequested.connect([this](QCloseEvent *ev) {
view()->d->closeRequested.connect([this](QCloseEvent *ev) {
onCloseEvent(ev);
});
@@ -108,6 +119,7 @@ Frame::~Frame()
setLayout(nullptr);
delete m_titleBar;
delete m_tabWidget;
delete d;
}
void Frame::onCloseEvent(QCloseEvent *e)
@@ -138,8 +150,8 @@ void Frame::setLayout(Layout *dt)
m_resizeHandler = new WidgetResizeHandler(/*topLevel=*/false, view());
// We keep the connect result so we don't dereference m_layout at shutdown
m_visibleWidgetCountChangedConnection->disconnect(); // TODOm3: Remove if tests pass. It's a KDBindings bug.
m_visibleWidgetCountChangedConnection = m_layout->visibleWidgetCountChanged.connect(&Frame::updateTitleBarVisibility, this);
d->m_visibleWidgetCountChangedConnection->disconnect(); // TODOm3: Remove if tests pass. It's a KDBindings bug.
d->m_visibleWidgetCountChangedConnection = m_layout->visibleWidgetCountChanged.connect(&Frame::updateTitleBarVisibility, this);
updateTitleBarVisibility();
if (wasInMainWindow != isInMainWindow())
Q_EMIT isInMainWindowChanged();

View File

@@ -347,6 +347,8 @@ public:
int nonContentsHeight() const;
private:
class Private;
Private *const d;
bool m_inCtor = true; // Needs to be initialized early, as pointed out by UBSAN
protected:
bool m_inDtor = false;
@@ -369,7 +371,6 @@ private:
bool m_updatingTitleBar = false;
bool m_beingDeleted = false;
int m_userType = 0;
KDBindings::ScopedConnection m_visibleWidgetCountChangedConnection;
};
}

View File

@@ -15,6 +15,7 @@
#include "Platform.h"
#include "kddockwidgets/ViewFactory.h"
#include "private/Utils_p.h"
#include "private/View_p.h"
#include "controllers/Layout.h"
#include "controllers/DropArea.h"
@@ -32,11 +33,11 @@ using namespace KDDockWidgets::Controllers;
Layout::Layout(Type type, View *view)
: Controller(type, view)
{
view->layoutInvalidated.connect([this] {
view->d->layoutInvalidated.connect([this] {
updateSizeConstraints();
});
view->resized.connect(&Layout::onResize, this);
view->d->resized.connect(&Layout::onResize, this);
}
Layout::~Layout()

33
src/private/View_p.h Normal file
View File

@@ -0,0 +1,33 @@
/*
This file is part of KDDockWidgets.
SPDX-FileCopyrightText: 2020-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
Author: Sérgio Martins <sergio.martins@kdab.com>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
Contact KDAB at <info@kdab.com> for commercial licensing options.
*/
#pragma once
#include "../View.h"
#include "kdbindings/signal.h"
namespace KDDockWidgets {
class View::Private
{
public:
/// @brief signal emitted once ~View starts
KDBindings::Signal<> beingDestroyed;
/// @brief signal emitted when something tried to close this view
KDBindings::Signal<QCloseEvent *> closeRequested;
/// @brief signal emitted when constraints change, for example min/max sizes
KDBindings::Signal<> layoutInvalidated;
/// @brief signal emitted when the view is resized
KDBindings::Signal<QSize> resized;
};
}

View File

@@ -17,6 +17,8 @@
#include "ItemFreeContainer_p.h"
#include "kdbindings/signal.h"
#include "Window.h"
#include "../View_p.h"
#include <QEvent>
#include <QDebug>
@@ -201,7 +203,7 @@ void Item::setGuestView(View *guest)
connect(newWidget, &QObject::destroyed, this, &Item::onWidgetDestroyed);
m_layoutInvalidatedConnection->disconnect();
m_layoutInvalidatedConnection = guest->layoutInvalidated.connect(&Item::onWidgetLayoutRequested, this);
m_layoutInvalidatedConnection = guest->d->layoutInvalidated.connect(&Item::onWidgetLayoutRequested, this);
if (m_sizingInfo.geometry.isEmpty()) {
// Use the widgets geometry, but ensure it's at least hardcodedMinimumSize

View File

@@ -15,6 +15,7 @@
#include "kddockwidgets/views/MainWindow_qtquick.h"
#include "kddockwidgets/controllers/MainWindow.h"
#include "Helpers_p.h"
#include "private/View_p.h"
#include <QGuiApplication>
#include <QQmlEngine>
@@ -109,7 +110,7 @@ View *Platform_qtquick::tests_createNonClosableView(View *parent)
CreateViewOptions opts;
opts.isVisible = true;
auto view = tests_createView(opts, parent);
view->closeRequested.connect([](QCloseEvent *ev) {
view->d->closeRequested.connect([](QCloseEvent *ev) {
ev->ignore();
});

View File

@@ -61,7 +61,7 @@ void Frame_qtquick::init()
this, SLOT(updateConstriants()));
connect(this, &View_qtquick::geometryUpdated, this, [this] {
layoutInvalidated.emit();
View::d->layoutInvalidated.emit();
});
/// QML interface connect, since controllers won't be QObjects for much longer:
@@ -100,7 +100,7 @@ void Frame_qtquick::updateConstriants()
setProperty("kddockwidgets_min_size", minSize());
setProperty("kddockwidgets_max_size", maximumSize());
layoutInvalidated.emit();
View::d->layoutInvalidated.emit();
}
void Frame_qtquick::removeWidget_impl(Controllers::DockWidget *dw)

View File

@@ -11,6 +11,7 @@
#include "View_qtquick.h"
#include "private/Utils_p.h"
#include "private/View_p.h"
#include "ViewWrapper_qtquick.h"
#include "private/multisplitter/Item_p.h"
#include "kddockwidgets/Window_qtquick.h"
@@ -230,7 +231,7 @@ void View_qtquick::move(int x, int y)
bool View_qtquick::event(QEvent *ev)
{
if (ev->type() == QEvent::Close)
closeRequested.emit(static_cast<QCloseEvent *>(ev));
View::d->closeRequested.emit(static_cast<QCloseEvent *>(ev));
return QQuickItem::event(ev);
}
@@ -268,7 +269,7 @@ bool View_qtquick::close(QQuickItem *item)
{
if (auto viewqtquick = qobject_cast<View_qtquick *>(item)) {
QCloseEvent ev;
viewqtquick->closeRequested.emit(&ev);
viewqtquick->View::d->closeRequested.emit(&ev);
if (ev.isAccepted()) {
viewqtquick->setVisible(false);
@@ -459,7 +460,7 @@ void View_qtquick::setMaximumSize(QSize sz)
if (maximumSize() != sz) {
setProperty("kddockwidgets_max_size", sz);
updateGeometry();
layoutInvalidated.emit();
View::d->layoutInvalidated.emit();
}
}
@@ -772,7 +773,7 @@ void View_qtquick::setMinimumSize(QSize sz)
if (minSize() != sz) {
setProperty("kddockwidgets_min_size", sz);
updateGeometry();
layoutInvalidated.emit();
View::d->layoutInvalidated.emit();
}
}

View File

@@ -20,6 +20,7 @@
#include "kddockwidgets/controllers/TabBar.h"
#include "kddockwidgets/controllers/TitleBar.h"
#include "Config.h"
#include "private/View_p.h"
#include <QPainter>
#include <QTabBar>
@@ -44,7 +45,7 @@ public:
if (m_frameWidget->inDtor())
return;
QVBoxLayout::invalidate();
m_frameWidget->layoutInvalidated.emit();
m_frameWidget->d->layoutInvalidated.emit();
}
Frame_qtwidgets *const m_frameWidget;

View File

@@ -17,6 +17,7 @@
#include "qtwidgets/views/DockWidget_qtwidgets.h"
#include "DockRegistry.h"
#include "Config.h"
#include "private/View_p.h"
#include <QMouseEvent>
#include <QTabBar>

View File

@@ -11,6 +11,7 @@
#include "View_qtwidgets.h"
#include "../Window_qtwidgets.h"
#include "private/View_p.h"
#include <QTabBar>
#include <QTabWidget>
@@ -75,6 +76,39 @@ std::shared_ptr<Window> View_qtwidgets<T>::window() const
return {};
}
template<class T>
void View_qtwidgets<T>::setMaximumSize(QSize sz)
{
if (sz != QWidget::maximumSize()) {
T::setMaximumSize(sz);
d->layoutInvalidated.emit();
}
}
template<class T>
bool View_qtwidgets<T>::event(QEvent *e)
{
if (e->type() == QEvent::LayoutRequest)
d->layoutInvalidated.emit();
return T::event(e);
}
template<class T>
void View_qtwidgets<T>::closeEvent(QCloseEvent *ev)
{
d->closeRequested.emit(ev);
}
template<class T>
void View_qtwidgets<T>::setMinimumSize(QSize sz)
{
if (sz != QWidget::minimumSize()) {
QWidget::setMinimumSize(sz);
d->layoutInvalidated.emit();
}
}
namespace KDDockWidgets::Views {
template class View_qtwidgets<QWidget>;
}

View File

@@ -71,13 +71,7 @@ public:
return Base::minimumSizeHint();
}
void setMinimumSize(QSize sz) override
{
if (sz != QWidget::minimumSize()) {
QWidget::setMinimumSize(sz);
layoutInvalidated.emit();
}
}
void setMinimumSize(QSize sz) override;
QSize maxSizeHint() const override
{
@@ -120,13 +114,7 @@ public:
Base::setGeometry(geo);
}
void setMaximumSize(QSize sz) override
{
if (sz != QWidget::maximumSize()) {
Base::setMaximumSize(sz);
layoutInvalidated.emit();
}
}
void setMaximumSize(QSize sz) override;
bool isVisible() const override
{
@@ -469,13 +457,8 @@ public:
}
protected:
bool event(QEvent *e) override
{
if (e->type() == QEvent::LayoutRequest)
layoutInvalidated.emit();
return Base::event(e);
}
bool event(QEvent *e) override;
void closeEvent(QCloseEvent *ev) override;
void resizeEvent(QResizeEvent *ev) override
{
@@ -483,11 +466,6 @@ protected:
Base::resizeEvent(ev);
}
void closeEvent(QCloseEvent *ev) override
{
closeRequested.emit(ev);
}
private:
Q_DISABLE_COPY(View_qtwidgets)
};

View File

@@ -10,6 +10,7 @@
*/
#include "main.h"
#include "private/View_p.h"
TEST_CASE("View::setParent()")
{
@@ -173,7 +174,7 @@ TEST_CASE("View::closeRequested")
auto rootView = createViewAndWindow({});
bool signalArrived = false;
KDBindings::ScopedConnection connection = rootView->closeRequested.connect([&signalArrived](QCloseEvent *ev) {
KDBindings::ScopedConnection connection = rootView->d->closeRequested.connect([&signalArrived](QCloseEvent *ev) {
signalArrived = true;
CHECK(ev->isAccepted());
});