/* This file is part of KDDockWidgets. SPDX-FileCopyrightText: 2020 Klarälvdalens Datakonsult AB, a KDAB Group company Author: Sérgio Martins SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only Contact KDAB at 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 makeWindow() override; Core::DockWidget *singleDockWidget() const final; bool isWindow() const override; Vector 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 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 }; }