// This file is part of Desktop App Toolkit, // a set of libraries for developing nice desktop applications. // // For license and copyright information please follow this link: // https://github.com/desktop-app/legal/blob/master/LEGAL // #pragma once #include "base/flags.h" #include "base/object_ptr.h" #include "ui/round_rect.h" namespace style { struct WindowTitle; struct TextStyle; } // namespace style namespace Ui { class RpWidget; class RpWindow; enum class WindowTitleHitTestFlag; using WindowTitleHitTestFlags = base::flags; namespace Platform { struct HitTestRequest; enum class HitTestResult; class DefaultTitleWidget; class BasicWindowHelper { public: explicit BasicWindowHelper(not_null window); virtual ~BasicWindowHelper() = default; [[nodiscard]] not_null window() const { return _window; } virtual void initInWindow(not_null window); [[nodiscard]] virtual not_null body(); [[nodiscard]] virtual QMargins frameMargins(); [[nodiscard]] virtual int additionalContentPadding() const; [[nodiscard]] virtual auto additionalContentPaddingValue() const -> rpl::producer; [[nodiscard]] virtual auto hitTestRequests() const -> rpl::producer>; [[nodiscard]] virtual auto systemButtonOver() const -> rpl::producer; [[nodiscard]] virtual auto systemButtonDown() const -> rpl::producer; virtual void overrideSystemButtonOver(HitTestResult button); virtual void overrideSystemButtonDown(HitTestResult button); virtual void setTitle(const QString &title); virtual void setTitleStyle(const style::WindowTitle &st); virtual void setNativeFrame(bool enabled); virtual void setMinimumSize(QSize size); virtual void setFixedSize(QSize size); virtual void setStaysOnTop(bool enabled); virtual void setGeometry(QRect rect); virtual void showFullScreen(); virtual void showNormal(); virtual void close(); virtual int manualRoundingRadius() const; void setBodyTitleArea(Fn testMethod); [[nodiscard]] virtual const style::TextStyle &titleTextStyle() const; protected: [[nodiscard]] WindowTitleHitTestFlags bodyTitleAreaHit( QPoint point) const { return _bodyTitleAreaTestMethod ? _bodyTitleAreaTestMethod(point) : WindowTitleHitTestFlag(); } [[nodiscard]] QMargins nativeFrameMargins() const; private: virtual void setupBodyTitleAreaEvents(); const not_null _window; Fn _bodyTitleAreaTestMethod; bool _mousePressed = false; }; class DefaultWindowHelper final : public QObject, public BasicWindowHelper { public: explicit DefaultWindowHelper(not_null window); not_null body() override; QMargins frameMargins() override; void setTitle(const QString &title) override; void setTitleStyle(const style::WindowTitle &st) override; void setNativeFrame(bool enabled) override; void setMinimumSize(QSize size) override; void setFixedSize(QSize size) override; void setGeometry(QRect rect) override; int manualRoundingRadius() const override; protected: bool eventFilter(QObject *obj, QEvent *e) override; private: void init(); void updateRoundingOverlay(); [[nodiscard]] bool hasShadow() const; [[nodiscard]] QMargins resizeArea() const; [[nodiscard]] Qt::Edges edgesFromPos(const QPoint &pos) const; void paintBorders(QPainter &p); void updateWindowMargins(); void updateCursor(Qt::Edges edges); [[nodiscard]] int titleHeight() const; [[nodiscard]] QMargins bodyPadding() const; const not_null _title; const not_null _body; RoundRect _roundRect; std::array _sides; std::array _corners; object_ptr _roundingOverlay = { nullptr }; bool _marginsSet = false; rpl::variable _windowState = Qt::WindowNoState; }; [[nodiscard]] std::unique_ptr CreateSpecialWindowHelper( not_null window); [[nodiscard]] inline std::unique_ptr CreateWindowHelper( not_null window) { if (auto special = CreateSpecialWindowHelper(window)) { return special; } return std::make_unique(window); } [[nodiscard]] bool NativeWindowFrameSupported(); } // namespace Platform } // namespace Ui