1 /*
2  *  The ManaPlus Client
3  *  Copyright (C) 2008  The Legend of Mazzeroth Development Team
4  *  Copyright (C) 2009  Aethyra Development Team
5  *  Copyright (C) 2009  The Mana World Development Team
6  *  Copyright (C) 2009-2010  The Mana Developers
7  *  Copyright (C) 2011-2019  The ManaPlus Developers
8  *  Copyright (C) 2019-2021  Andrei Karas
9  *
10  *  This file is part of The ManaPlus Client.
11  *
12  *  This program is free software; you can redistribute it and/or modify
13  *  it under the terms of the GNU General Public License as published by
14  *  the Free Software Foundation; either version 2 of the License, or
15  *  any later version.
16  *
17  *  This program is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public License
23  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
24  */
25 
26 #ifndef GUI_THEME_H
27 #define GUI_THEME_H
28 
29 #include "logger.h"
30 
31 #include "enums/gui/progresscolorid.h"
32 #include "enums/gui/themecolorid.h"
33 
34 #include "listeners/configlistener.h"
35 
36 #include "gui/palette.h"
37 
38 #include "utils/stringvector.h"
39 
40 #include "localconsts.h"
41 
42 class DyePalette;
43 class Image;
44 class ImageRect;
45 class ImageSet;
46 class Skin;
47 class Theme;
48 
49 struct ThemeInfo;
50 
51 extern Theme *theme;
52 
53 class Theme final : public Palette,
54                     public ConfigListener
55 {
56     public:
57         Theme();
58 
59         ~Theme() override final;
60 
61         A_DELETE_COPY(Theme)
62 
63         static void prepareThemePath();
64 
65         static void selectSkin();
66 
getThemePath()67         static std::string getThemePath() A_WARN_UNUSED
68         { return mThemePath; }
69 
getThemeName()70         static std::string getThemeName() A_WARN_UNUSED
71         { return mThemeName; }
72 
73         static void fillSkinsList(StringVect &list);
74 
75         static void fillFontsList(StringVect &list);
76 
77         static void fillSoundsList(StringVect &list);
78 
79         /**
80          * Returns the patch to the given gui resource relative to the theme
81          * or, if it isn't in the theme, relative to 'graphics/gui'.
82          */
83         static std::string resolveThemePath(const std::string &path)
84                                             A_WARN_UNUSED;
85 
86         static Image *getImageFromTheme(const std::string &path) A_WARN_UNUSED;
87 
88         static ImageSet *getImageSetFromTheme(const std::string &path,
89                                               const int w,
90                                               const int h) A_WARN_UNUSED;
91 
92         static ImageSet *getImageSetFromThemeXml(const std::string &name,
93                                           const std::string &name2,
94                                           const int w,
95                                           const int h)A_WARN_UNUSED;
96 
97         static Color getProgressColor(const ProgressColorIdT type,
98                                       const float progress) A_WARN_UNUSED;
99 
100         /**
101          * Loads a skin.
102          */
103         Skin *load(const std::string &filename,
104                    const std::string &filename2,
105                    const bool full,
106                    const std::string &restrict defaultPath) A_WARN_UNUSED;
107 
108         Skin *loadSkinRect(ImageRect &image,
109                            const std::string &name,
110                            const std::string &name2,
111                            const int start,
112                            const int end) A_WARN_UNUSED;
113 
114         void unload(Skin *const skin);
115 
116         /**
117          * Updates the alpha values of all of the skins.
118          */
119         void updateAlpha();
120 
121         /**
122          * Get the minimum opacity allowed to skins.
123          */
getMinimumOpacity()124         float getMinimumOpacity() const noexcept2 A_WARN_UNUSED
125         { return mMinimumOpacity; }
126 
127         /**
128          * Gets the color associated with the type. Sets the alpha channel
129          * before returning.
130          *
131          * @param type the color type requested
132          * @param alpha alpha channel to use
133          *
134          * @return the requested color
135          */
getColor(const ThemeColorIdT type,const unsigned int alpha)136         inline const Color &getColor(const ThemeColorIdT type,
137                                      const unsigned int alpha) A_WARN_UNUSED
138         {
139             if (CAST_SIZE(type) >= mColors.size())
140             {
141                 logger->log("incorrect color request type: %d from %u",
142                     CAST_S32(type),
143                     CAST_U32(mColors.size()));
144                 Color *const col = &mColors[CAST_SIZE(
145                     ThemeColorId::BROWSERBOX)].color;
146                 col->a = alpha;
147                 return *col;
148             }
149             else
150             {
151                 Color *const col = &mColors[CAST_SIZE(type)].color;
152                 col->a = alpha;
153                 return *col;
154             }
155         }
156 
157         ThemeColorIdT getIdByChar(const signed char c,
158                                   bool &valid) const A_WARN_UNUSED;
159 
160         /**
161          * Set the minimum opacity allowed to skins.
162          * Set a negative value to free the minimum allowed.
163          */
164         void setMinimumOpacity(const float minimumOpacity);
165 
166         void optionChanged(const std::string &name) override final;
167 
168         void loadRect(ImageRect &image,
169                       const std::string &name,
170                       const std::string &name2,
171                       const int start,
172                       const int end);
173 
174         static void unloadRect(const ImageRect &rect,
175                                const int start,
176                                const int end);
177 
178         static Image *getImageFromThemeXml(const std::string &name,
179                                            const std::string &name2)
180                                            A_WARN_UNUSED;
181 
182         static ThemeInfo *loadInfo(const std::string &themeName) A_WARN_UNUSED;
183 
184     private:
185         Skin *readSkin(const std::string &filename0,
186                        const bool full) A_WARN_UNUSED;
187 
188         // Map containing all window skins
189         typedef std::map<std::string, Skin*> Skins;
190         typedef Skins::iterator SkinIterator;
191 
192         Skins mSkins;
193 
194         static std::string mThemePath;
195         static std::string mThemeName;
196         static std::string mScreenDensity;
197 
198         static bool tryThemePath(const std::string &themePath) A_WARN_UNUSED;
199 
200         void loadColors(std::string file);
201 
202         /**
203          * Tells if the current skins opacity
204          * should not get less than the given value
205          */
206         float mMinimumOpacity;
207 
208         typedef STD_VECTOR<DyePalette*> ProgressColors;
209         ProgressColors mProgressColors;
210 };
211 
212 #endif  // GUI_THEME_H
213