1 /*
2  * Strawberry Music Player
3  * This file was part of Clementine.
4  * Copyright 2010, David Sansome <me@davidsansome.com>
5  * Copyright 2019-2021, Jonas Kvinge <jonas@jkvinge.net>
6  *
7  * Strawberry is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * Strawberry is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with Strawberry.  If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef OSDPRETTY_H
23 #define OSDPRETTY_H
24 
25 #include "config.h"
26 
27 #include <QtGlobal>
28 #include <QObject>
29 #include <QWidget>
30 #include <QMap>
31 #include <QString>
32 #include <QImage>
33 #include <QPixmap>
34 #include <QColor>
35 #include <QFont>
36 #include <QPoint>
37 #include <QRect>
38 #include <QRgb>
39 
40 class QScreen;
41 class QTimer;
42 class QTimeLine;
43 class QEvent;
44 class QMouseEvent;
45 class QPaintEvent;
46 class QShowEvent;
47 class QEnterEvent;
48 
49 class Ui_OSDPretty;
50 
51 class OSDPretty : public QWidget {
52   Q_OBJECT
53 
54  public:
55   enum Mode {
56     Mode_Popup,
57     Mode_Draggable,
58   };
59 
60   explicit OSDPretty(Mode mode, QWidget *parent = nullptr);
61   ~OSDPretty() override;
62 
63   static const char *kSettingsGroup;
64 
65   static const int kDropShadowSize;
66   static const int kBorderRadius;
67   static const int kMaxIconSize;
68 
69   static const int kSnapProximity;
70 
71   static const QRgb kPresetBlue;
72   static const QRgb kPresetRed;
73 
74   bool IsTransparencyAvailable();
75 
76   void SetMessage(const QString &summary, const QString &message, const QImage &image);
77   void ShowMessage(const QString &summary, const QString &message, const QImage &image);
78 
79   // Popup duration in seconds.  Only used in Mode_Popup.
80   void set_popup_duration(const int msec);
81 
82   // These will get overwritten when ReloadSettings() is called
83   void set_foreground_color(const QRgb color);
84   void set_background_color(const QRgb color);
85   void set_background_opacity(const qreal opacity);
86   void set_font(const QFont &font);
87 
88   QRgb foreground_color() const { return foreground_color_.rgb(); }
89   QRgb background_color() const { return background_color_.rgb(); }
90   qreal background_opacity() const { return background_opacity_; }
91   QString popup_screen() const { return popup_screen_name_; }
92   QPoint popup_pos() const { return popup_pos_; }
93   QFont font() const { return font_; }
94   bool disable_duration() const { return disable_duration_; }
95   bool fading() const { return fading_enabled_; }
96 
97   // When the user has been moving the popup, use these to get its current position and screen.
98   // Note that these return invalid values if the popup is hidden.
99   QScreen *current_screen() const;
100   QScreen *current_screen(const QPoint pos) const;
101   QPoint current_pos() const;
102 
103   // QWidget
104   void setVisible(bool visible) override;
105 
106   bool toggle_mode() const { return toggle_mode_; }
107   void set_toggle_mode(const bool toggle_mode) { toggle_mode_ = toggle_mode; }
108 
109  signals:
110   void PositionChanged();
111 
112  public slots:
113   void ReloadSettings();
114 
115  protected:
116   void paintEvent(QPaintEvent *e) override;
117 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
118   void enterEvent(QEnterEvent*) override;
119 #else
120   void enterEvent(QEvent*) override;
121 #endif
122   void leaveEvent(QEvent*) override;
123   void mousePressEvent(QMouseEvent *e) override;
124   void showEvent(QShowEvent *e) override;
125   void mouseMoveEvent(QMouseEvent *e) override;
126   void mouseReleaseEvent(QMouseEvent *e) override;
127 
128  private:
129   void Reposition();
130   void Load();
131 
132   QRect BoxBorder() const;
133 
134  private slots:
135   void FaderValueChanged(const qreal value);
136   void FaderFinished();
137   void ScreenAdded(QScreen *screen);
138   void ScreenRemoved(QScreen *screen);
139 
140  private:
141   Ui_OSDPretty *ui_;
142 
143   Mode mode_;
144 
145   // Settings loaded from QSettings
146   QColor foreground_color_;
147   QColor background_color_;
148   qreal background_opacity_;
149   QString popup_screen_name_;
150   QPoint popup_pos_;
151   QScreen *popup_screen_;
152   QFont font_;
153   // The OSD is kept always on top until you click (no timer)
154   bool disable_duration_;
155 
156   // Cached pixmaps
157   QPixmap shadow_edge_[4];
158   QPixmap shadow_corner_[4];
159   QPixmap background_;
160 
161   // For dragging the OSD
162   QPoint original_window_pos_;
163   QPoint drag_start_pos_;
164 
165   // For timeout of notification
166   QTimer *timeout_;
167 
168   // For fading
169   bool fading_enabled_;
170   QTimeLine *fader_;
171 
172   // Toggling requested, we have to show or hide the OSD
173   bool toggle_mode_;
174 
175   QMap<QString, QScreen*> screens_;
176 
177 };
178 
179 #endif  // OSDPRETTY_H
180