1 #ifndef DATA_SYNCTHINGICONS_H
2 #define DATA_SYNCTHINGICONS_H
3 
4 #include "./global.h"
5 
6 #include <QIcon>
7 #include <QSize>
8 
9 #include <vector>
10 
QT_FORWARD_DECLARE_CLASS(QColor)11 QT_FORWARD_DECLARE_CLASS(QColor)
12 
13 namespace Data {
14 
15 enum class StatusEmblem {
16     None,
17     Scanning,
18     Synchronizing,
19     Alert,
20     Paused,
21     Complete,
22     Add,
23 };
24 
25 struct LIB_SYNCTHING_MODEL_EXPORT StatusIconColorSet {
26     StatusIconColorSet(const QColor &backgroundStart, const QColor &backgroundEnd, const QColor &foreground);
27     StatusIconColorSet(QColor &&backgroundStart, QColor &&backgroundEnd, QColor &&foreground);
28     StatusIconColorSet(const QString &backgroundStart, const QString &backgroundEnd, const QString &foreground);
29 
30     QColor backgroundStart;
31     QColor backgroundEnd;
32     QColor foreground;
33 };
34 
35 inline StatusIconColorSet::StatusIconColorSet(const QColor &backgroundStart, const QColor &backgroundEnd, const QColor &foreground)
36     : backgroundStart(backgroundStart)
37     , backgroundEnd(backgroundEnd)
38     , foreground(foreground)
39 {
40 }
41 
42 inline StatusIconColorSet::StatusIconColorSet(QColor &&backgroundStart, QColor &&backgroundEnd, QColor &&foreground)
43     : backgroundStart(backgroundStart)
44     , backgroundEnd(backgroundEnd)
45     , foreground(foreground)
46 {
47 }
48 
49 inline StatusIconColorSet::StatusIconColorSet(const QString &backgroundStart, const QString &backgroundEnd, const QString &foreground)
50     : backgroundStart(backgroundStart)
51     , backgroundEnd(backgroundEnd)
52     , foreground(foreground)
53 {
54 }
55 
56 LIB_SYNCTHING_MODEL_EXPORT QByteArray makeSyncthingIcon(
57     const StatusIconColorSet &colors = StatusIconColorSet{ QStringLiteral("#26B6DB"), QStringLiteral("#0882C8"), QStringLiteral("#FFFFFF") },
58     StatusEmblem statusEmblem = StatusEmblem::None);
59 LIB_SYNCTHING_MODEL_EXPORT QPixmap renderSvgImage(const QString &path, const QSize &size = QSize(32, 32), int margin = 0);
60 LIB_SYNCTHING_MODEL_EXPORT QPixmap renderSvgImage(const QByteArray &contents, const QSize &size = QSize(32, 32), int margin = 0);
61 LIB_SYNCTHING_MODEL_EXPORT QByteArray loadFontAwesomeIcon(const QString &iconName, const QColor &color, bool solid = true);
62 
63 struct LIB_SYNCTHING_MODEL_EXPORT StatusIconSettings {
64     struct DarkTheme {
65     };
66     struct BrightTheme {
67     };
68 
69     explicit StatusIconSettings();
70     explicit StatusIconSettings(DarkTheme);
71     explicit StatusIconSettings(BrightTheme);
72     explicit StatusIconSettings(const QString &str);
73 
74     StatusIconColorSet defaultColor;
75     StatusIconColorSet errorColor;
76     StatusIconColorSet warningColor;
77     StatusIconColorSet idleColor;
78     StatusIconColorSet scanningColor;
79     StatusIconColorSet synchronizingColor;
80     StatusIconColorSet pausedColor;
81     StatusIconColorSet disconnectedColor;
82     QSize renderSize = QSize(32, 32);
83 
84     static constexpr auto distinguishableColorCount = 8;
85 
86     struct ColorMapping {
87         QString colorName;
88         StatusEmblem defaultEmblem;
89         StatusIconColorSet &setting;
90     };
91     std::vector<ColorMapping> colorMapping();
92     QString toString() const;
93 };
94 
95 struct LIB_SYNCTHING_MODEL_EXPORT StatusIcons {
96     StatusIcons();
97     StatusIcons(const StatusIconSettings &settings);
98     StatusIcons(const StatusIcons &other) = default;
99     StatusIcons &operator=(const StatusIcons &other) = default;
100     QIcon disconnected;
101     QIcon idling;
102     QIcon scanninig;
103     QIcon notify;
104     QIcon pause;
105     QIcon sync;
106     QIcon syncComplete;
107     QIcon error;
108     QIcon errorSync;
109     QIcon newItem;
110     bool isValid;
111 };
112 
113 inline StatusIcons::StatusIcons()
114     : isValid(false)
115 {
116 }
117 
118 struct LIB_SYNCTHING_MODEL_EXPORT FontAwesomeIcons {
119     FontAwesomeIcons(const QColor &color, const QSize &size, int margin);
120     QIcon hashtag;
121     QIcon folderOpen;
122     QIcon globe;
123     QIcon home;
124     QIcon shareAlt;
125     QIcon refresh;
126     QIcon clock;
127     QIcon exchangeAlt;
128     QIcon exclamationTriangle;
129     QIcon cogs;
130     QIcon link;
131     QIcon eye;
132     QIcon fileArchive;
133     QIcon folder;
134     QIcon certificate;
135     QIcon networkWired;
136     QIcon cloudDownloadAlt;
137     QIcon cloudUploadAlt;
138     QIcon tag;
139 };
140 
141 class LIB_SYNCTHING_MODEL_EXPORT IconManager : public QObject {
142     Q_OBJECT
143 public:
144     static IconManager &instance();
145 
146     void applySettings(const StatusIconSettings *statusIconSettings = nullptr, const StatusIconSettings *trayIconSettings = nullptr);
147     const StatusIcons &statusIcons() const;
148     const StatusIcons &trayIcons() const;
149     const FontAwesomeIcons &fontAwesomeIconsForLightTheme() const;
150     const FontAwesomeIcons &fontAwesomeIconsForDarkTheme() const;
151 
152 Q_SIGNALS:
153     void statusIconsChanged(const StatusIcons &newStatusIcons, const StatusIcons &newTrayIcons);
154 
155 private:
156     IconManager();
157 
158     StatusIcons m_statusIcons;
159     StatusIcons m_trayIcons;
160     FontAwesomeIcons m_fontAwesomeIconsForLightTheme;
161     FontAwesomeIcons m_fontAwesomeIconsForDarkTheme;
162 };
163 
164 inline void IconManager::applySettings(const StatusIconSettings *statusIconSettings, const StatusIconSettings *trayIconSettings)
165 {
166     if (statusIconSettings) {
167         m_statusIcons = StatusIcons(*statusIconSettings);
168     } else {
169         m_statusIcons = StatusIcons(StatusIconSettings());
170     }
171     if (trayIconSettings) {
172         m_trayIcons = StatusIcons(*trayIconSettings);
173     } else {
174         m_trayIcons = m_statusIcons;
175     }
176     emit statusIconsChanged(m_statusIcons, m_trayIcons);
177 }
178 
179 inline const StatusIcons &IconManager::statusIcons() const
180 {
181     return m_statusIcons;
182 }
183 
184 inline const StatusIcons &IconManager::trayIcons() const
185 {
186     return m_trayIcons;
187 }
188 
189 inline const FontAwesomeIcons &IconManager::fontAwesomeIconsForLightTheme() const
190 {
191     return m_fontAwesomeIconsForLightTheme;
192 }
193 
194 inline const FontAwesomeIcons &IconManager::fontAwesomeIconsForDarkTheme() const
195 {
196     return m_fontAwesomeIconsForDarkTheme;
197 }
198 
199 inline const StatusIcons &statusIcons()
200 {
201     return IconManager::instance().statusIcons();
202 }
203 
204 inline const StatusIcons &trayIcons()
205 {
206     return IconManager::instance().trayIcons();
207 }
208 
209 inline const FontAwesomeIcons &fontAwesomeIconsForLightTheme()
210 {
211     return IconManager::instance().fontAwesomeIconsForLightTheme();
212 }
213 
214 inline const FontAwesomeIcons &fontAwesomeIconsForDarkTheme()
215 {
216     return IconManager::instance().fontAwesomeIconsForDarkTheme();
217 }
218 
219 } // namespace Data
220 
221 #endif // DATA_SYNCTHINGICONS_H
222