1 #pragma once 2 3 #include "widgets/BaseWidget.hpp" 4 5 #include <functional> 6 #include <pajlada/signals/signalholder.hpp> 7 #include "common/FlagsEnum.hpp" 8 9 class QHBoxLayout; 10 struct tagMSG; 11 typedef struct tagMSG MSG; 12 13 namespace chatterino { 14 15 class Button; 16 class EffectLabel; 17 class TitleBarButton; 18 enum class TitleBarButtonStyle; 19 20 class BaseWindow : public BaseWidget 21 { 22 Q_OBJECT 23 24 public: 25 enum Flags { 26 None = 0, 27 EnableCustomFrame = 1, 28 Frameless = 2, 29 TopMost = 4, 30 DisableCustomScaling = 8, 31 FramelessDraggable = 16, 32 DontFocus = 32, 33 Dialog = 64, 34 }; 35 36 enum ActionOnFocusLoss { Nothing, Delete, Close, Hide }; 37 38 explicit BaseWindow(FlagsEnum<Flags> flags_ = None, 39 QWidget *parent = nullptr); 40 ~BaseWindow() override; 41 42 void setInitialBounds(const QRect &bounds); 43 QRect getBounds(); 44 45 QWidget *getLayoutContainer(); 46 bool hasCustomWindowFrame(); 47 TitleBarButton *addTitleBarButton(const TitleBarButtonStyle &style, 48 std::function<void()> onClicked); 49 EffectLabel *addTitleBarLabel(std::function<void()> onClicked); 50 51 void setStayInScreenRect(bool value); 52 bool getStayInScreenRect() const; 53 54 void setActionOnFocusLoss(ActionOnFocusLoss value); 55 ActionOnFocusLoss getActionOnFocusLoss() const; 56 57 void moveTo(QWidget *widget, QPoint point, bool offset = true); 58 59 virtual float scale() const override; 60 float qtFontScale() const; 61 62 pajlada::Signals::NoArgSignal closing; 63 64 static bool supportsCustomWindowFrame(); 65 66 protected: 67 virtual bool nativeEvent(const QByteArray &eventType, void *message, 68 long *result) override; 69 virtual void scaleChangedEvent(float) override; 70 71 virtual void paintEvent(QPaintEvent *) override; 72 73 virtual void changeEvent(QEvent *) override; 74 virtual void leaveEvent(QEvent *) override; 75 virtual void resizeEvent(QResizeEvent *) override; 76 virtual void moveEvent(QMoveEvent *) override; 77 virtual void closeEvent(QCloseEvent *) override; 78 virtual void showEvent(QShowEvent *) override; 79 80 virtual void themeChangedEvent() override; 81 virtual bool event(QEvent *event) override; 82 virtual void wheelEvent(QWheelEvent *event) override; 83 84 void mousePressEvent(QMouseEvent *event) override; 85 void mouseReleaseEvent(QMouseEvent *event) override; 86 void mouseMoveEvent(QMouseEvent *event) override; 87 QPointF movingRelativePos; 88 bool moving{}; 89 90 void updateScale(); 91 92 boost::optional<QColor> overrideBackgroundColor_; 93 94 private: 95 void init(); 96 void moveIntoDesktopRect(QWidget *parent, QPoint point); 97 void calcButtonsSizes(); 98 void drawCustomWindowFrame(QPainter &painter); 99 void onFocusLost(); 100 101 bool handleDPICHANGED(MSG *msg); 102 bool handleSHOWWINDOW(MSG *msg); 103 bool handleNCCALCSIZE(MSG *msg, long *result); 104 bool handleSIZE(MSG *msg); 105 bool handleMOVE(MSG *msg); 106 bool handleNCHITTEST(MSG *msg, long *result); 107 108 bool enableCustomFrame_; 109 ActionOnFocusLoss actionOnFocusLoss_ = Nothing; 110 bool frameless_; 111 bool stayInScreenRect_ = false; 112 bool shown_ = false; 113 FlagsEnum<Flags> flags_; 114 float nativeScale_ = 1; 115 bool isResizeFixing_ = false; 116 117 struct { 118 QLayout *windowLayout = nullptr; 119 QHBoxLayout *titlebarBox = nullptr; 120 QWidget *titleLabel = nullptr; 121 TitleBarButton *minButton = nullptr; 122 TitleBarButton *maxButton = nullptr; 123 TitleBarButton *exitButton = nullptr; 124 QWidget *layoutBase = nullptr; 125 std::vector<Button *> buttons; 126 } ui_; 127 128 #ifdef USEWINSDK 129 QRect initalBounds_; 130 QRect currentBounds_; 131 QRect nextBounds_; 132 QTimer useNextBounds_; 133 bool isNotMinimizedOrMaximized_{}; 134 #endif 135 136 pajlada::Signals::SignalHolder connections_; 137 std::vector<pajlada::Signals::ScopedConnection> managedConnections_; 138 139 friend class BaseWidget; 140 }; 141 142 } // namespace chatterino 143