2026-04-06 00:20:51 -05:00

235 lines
7.3 KiB
C++

/*
This file is part of KDDockWidgets.
SPDX-FileCopyrightText: 2020 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 "Controller.h"
#include "kddockwidgets/KDDockWidgets.h"
#include "kddockwidgets/docks_export.h"
#include "kddockwidgets/LayoutSaver.h"
#include "Group.h"
#include "kddockwidgets/QtCompat_p.h"
#include "kddockwidgets/core/Draggable_p.h"
QT_BEGIN_NAMESPACE
class QAbstractNativeEventFilter;
QT_END_NAMESPACE
namespace KDDockWidgets::Core {
class DropArea;
class Group;
class Layout;
class MainWindow;
class TitleBar;
class DOCKS_EXPORT FloatingWindow : public Controller, public Draggable
{
Q_OBJECT
public:
explicit FloatingWindow(
Rect suggestedGeometry, MainWindow *parent = nullptr,
FloatingWindowFlags requestedFlags = FloatingWindowFlag::FromGlobalConfig);
explicit FloatingWindow(Core::Group *group, Rect suggestedGeometry,
MainWindow *parent = nullptr);
virtual ~FloatingWindow() override;
bool deserialize(const LayoutSaver::FloatingWindow &);
LayoutSaver::FloatingWindow serialize() const;
// Draggable:
std::unique_ptr<WindowBeingDragged> makeWindow() override;
Core::DockWidget *singleDockWidget() const final;
bool isWindow() const override;
Vector<DockWidget *> dockWidgets() const;
Core::Group::List groups() const;
DropArea *dropArea() const;
int userType() const;
/// @brief Returns whether this window is a tool window
/// Tool windows don't usually appear in the task bar
bool isUtilityWindow() const;
static void ensureRectIsOnScreen(Rect &geometry);
#ifdef KDDW_FRONTEND_QT_WINDOWS
void setLastHitTest(int hitTest)
{
m_lastHitTest = hitTest;
}
#endif
/**
* @brief Returns the title bar.
*
* This TitleBar is hidden if we're using a native title bar.
*/
Core::TitleBar *titleBar() const
{
return m_titleBar;
}
/**
* @brief Equivalent to setGeometry(), but the value might be adjusted.
*
* For example, if the suggestedRect is bigger than max size, we'll make it smaller.
*
* @param preserveCenter, if true, then the center is preserved
*
*/
void setSuggestedGeometry(Rect suggestedRect,
SuggestedGeometryHints = SuggestedGeometryHint_None);
bool anyNonClosable() const;
bool anyNonDockable() const;
/**
* @brief checks if this FloatingWindow only has one group.
* If true it means there's no side-by-side dock widgets here. There's only 1 group.
* Note that despite having only 1 group it can still have multiple DockWidgets,
* as they can be tabbed into the single group.
* @return true if this FloatingWindow has a single group.
*/
bool hasSingleGroup() const;
/**
* @brief checks if this FloatingWindow only has one dockwidget.
* This is a more specific case than hasSingleGroup(), it implies not only a single group,
* but that group must only have 1 dock widget.
* @return true if this FloatingWindow only has one dockwidget.
*/
bool hasSingleDockWidget() const;
/// @brief If this floating window has only one Frame, it's returned, otherwise nullptr
Core::Group *singleFrame() const;
/**
* @brief Returns whether a deleteLater has already been issued
*/
bool beingDeleted() const;
/**
* @brief Equivalent to deleteLater() but sets beingDeleted() to true
*/
void scheduleDeleteLater();
/**
* @brief Returns the MultiSplitter
*/
Core::DropArea *multiSplitter() const;
/**
* @brief Returns the Layout
*/
Layout *layout() const;
/**
* @brief Returns whether @p globalPoint is inside the title bar (or, when there's no title-bar,
* the draggable empty area of a tab bar)
*/
bool isInDragArea(Point globalPoint) const;
bool isMDI() const override;
///@brief updates the title and the icon
void updateTitleAndIcon();
void updateTitleBarVisibility();
Vector<QString> affinities() const;
/**
* Returns the drag rect in global coordinates. This is usually the title bar rect.
* However, when using Config::Flag_HideTitleBarWhenTabsVisible it will be the tab bar
* background. Returns global coordinates.
*/
Rect dragRect() const;
///@brief Returns whether all dock widgets have the specified option set
bool allDockWidgetsHave(DockWidgetOption) const;
///@brief Returns whether at least one dock widget has the specified option set
bool anyDockWidgetsHas(DockWidgetOption) const;
///@brief Returns whether all dock widgets have the specified layout saver option set
bool allDockWidgetsHave(LayoutSaverOption) const;
///@brief Returns whether at least one dock widget has the specified layout saver option set
bool anyDockWidgetsHas(LayoutSaverOption) const;
/// @brief Adds the dock widget to the specified location
void addDockWidget(DockWidget *, KDDockWidgets::Location location, DockWidget *relativeTo,
const InitialOption & = {});
/// @brief Returns the MainWindow which is the transient parent of this FloatingWindow
/// Can be nullptr if you create dock widgets before the main window. Can also be some
/// arbitrary value if you have more than one main window.
MainWindow *mainWindow() const;
///@brief Returns the contents margins
Margins contentMargins() const;
// The state reported by QWidget is not always the same as what the
// window manager thinks, due to the async nature. This method
// returns the last state reported by the window manager itself.
WindowState lastWindowManagerState() const;
void setLastWindowManagerState(WindowState);
///@brief Allows the user app to specify which window flags to use, instead of KDDWs default
/// ones
/// Bugs caused by this won't be supported, as the amount of combinations that could go wrong
/// can be open ended
static Qt::WindowFlags s_windowFlagsOverride;
/// @brief Returns whether this floating window supports showing a minimize button
bool supportsMinimizeButton() const;
/// @brief Returns whether this floating window supports showing a maximize button
bool supportsMaximizeButton() const;
void maybeCreateResizeHandler();
/// Returns the per-floating window flags
FloatingWindowFlags floatingWindowFlags() const;
void focus(Qt::FocusReason reason);
class Private;
Private *dptr() const;
private:
Private *const d;
protected:
Core::TitleBar *const m_titleBar;
WindowState m_lastWindowManagerState = WindowState::None;
private:
KDDW_DELETE_COPY_CTOR(FloatingWindow)
Size maxSizeHint() const;
void onFrameCountChanged(int count);
void onVisibleFrameCountChanged(int count);
void onCloseEvent(CloseEvent *);
void updateSizeConstraints();
bool m_disableSetVisible = false;
bool m_deleteScheduled = false;
bool m_inDtor = false;
bool m_updatingTitleBarVisibility = false;
WindowState windowStateOverride() const;
#ifdef KDDW_FRONTEND_QT_WINDOWS
QAbstractNativeEventFilter *m_nchittestFilter = nullptr;
int m_lastHitTest = 0;
#endif
};
}