// 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 "ui/rp_widget.h" #include "base/object_ptr.h" #include #include namespace style { struct WindowTitle; } // namespace style namespace Ui { class IconButton; class AbstractButton; class PlainShadow; class RpWindow; namespace Platform { class TitleControls; enum class HitTestResult { None = 0, Client, Minimize, MaximizeRestore, Close, Caption, Top, TopRight, Right, BottomRight, Bottom, BottomLeft, Left, TopLeft, }; struct HitTestRequest { QPoint point; HitTestResult result = HitTestResult::Client; }; [[nodiscard]] bool SemiNativeSystemButtonProcessing(); void SetupSemiNativeSystemButtons( not_null controls, not_null window, rpl::lifetime &lifetime, Fn filter = nullptr); enum class TitleControl { Unknown, Minimize, Maximize, Close, }; class AbstractTitleButtons { public: [[nodiscard]] virtual object_ptr create( not_null parent, TitleControl control, const style::WindowTitle &st) = 0; virtual void updateState( bool active, bool maximized, const style::WindowTitle &st) = 0; virtual void notifySynteticOver(TitleControl control, bool over) = 0; }; class IconTitleButtons final : public AbstractTitleButtons { public: object_ptr create( not_null parent, TitleControl control, const style::WindowTitle &st) override; void updateState( bool active, bool maximized, const style::WindowTitle &st) override; void notifySynteticOver(TitleControl control, bool over) override { } private: QPointer _minimize; QPointer _maximizeRestore; QPointer _close; }; class TitleControls final { public: TitleControls( not_null parent, const style::WindowTitle &st, Fn maximize = nullptr); TitleControls( not_null parent, const style::WindowTitle &st, std::unique_ptr buttons, Fn maximize = nullptr); void setStyle(const style::WindowTitle &st); [[nodiscard]] not_null st() const; [[nodiscard]] QRect geometry() const; void setResizeEnabled(bool enabled); void raise(); [[nodiscard]] HitTestResult hitTest(QPoint point, int padding) const; void buttonOver(HitTestResult testResult); void buttonDown(HitTestResult testResult); using Control = TitleControl; struct Layout { std::vector left; std::vector right; }; private: [[nodiscard]] not_null parent() const; [[nodiscard]] not_null window() const; [[nodiscard]] AbstractButton *controlWidget(Control control) const; void init(Fn maximize); void subscribeToStateChanges(); void updateButtonsState(); void updateControlsPosition(); void updateControlsPositionBySide( const std::vector &controls, bool right); void handleWindowStateChanged(Qt::WindowState state = Qt::WindowNoState); not_null _st; const std::unique_ptr _buttons; object_ptr _minimize; object_ptr _maximizeRestore; object_ptr _close; bool _maximizedState = false; bool _activeState = false; bool _resizeEnabled = true; }; class DefaultTitleWidget : public RpWidget { public: explicit DefaultTitleWidget(not_null parent); [[nodiscard]] not_null st() const; [[nodiscard]] QRect controlsGeometry() const; void setText(const QString &text); void setStyle(const style::WindowTitle &st); void setResizeEnabled(bool enabled); protected: void paintEvent(QPaintEvent *e) override; void resizeEvent(QResizeEvent *e) override; void mousePressEvent(QMouseEvent *e) override; void mouseReleaseEvent(QMouseEvent *e) override; void mouseMoveEvent(QMouseEvent *e) override; void mouseDoubleClickEvent(QMouseEvent *e) override; private: TitleControls _controls; object_ptr _shadow; bool _mousePressed = false; }; struct SeparateTitleControls { SeparateTitleControls( QWidget *parent, const style::WindowTitle &st, Fn maximize); SeparateTitleControls( QWidget *parent, const style::WindowTitle &st, std::unique_ptr buttons, Fn maximize); RpWidget wrap; TitleControls controls; }; [[nodiscard]] auto SetupSeparateTitleControls( not_null window, const style::WindowTitle &st, Fn maximize = nullptr, rpl::producer controlsTop = nullptr) -> std::unique_ptr; [[nodiscard]] auto SetupSeparateTitleControls( not_null window, std::unique_ptr created, rpl::producer controlsTop = nullptr) -> std::unique_ptr; } // namespace Platform } // namespace Ui