Remove Mapgen V7 floatlands in preparation for new implementation (#9238)
[oweals/minetest.git] / src / gui / StyleSpec.h
1 /*
2 Minetest
3 Copyright (C) 2019 rubenwardy
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "client/tile.h" // ITextureSource
21 #include "irrlichttypes_extrabloated.h"
22 #include "util/string.h"
23 #include <array>
24
25 #pragma once
26
27 class StyleSpec
28 {
29 public:
30         enum Property
31         {
32                 TEXTCOLOR,
33                 BGCOLOR,
34                 BGCOLOR_HOVERED,
35                 BGCOLOR_PRESSED,
36                 NOCLIP,
37                 BORDER,
38                 BGIMG,
39                 BGIMG_HOVERED,
40                 BGIMG_PRESSED,
41                 FGIMG,
42                 FGIMG_HOVERED,
43                 FGIMG_PRESSED,
44                 ALPHA,
45                 NUM_PROPERTIES,
46                 NONE
47         };
48
49 private:
50         std::array<bool, NUM_PROPERTIES> property_set{};
51         std::array<std::string, NUM_PROPERTIES> properties;
52
53 public:
54         static Property GetPropertyByName(const std::string &name)
55         {
56                 if (name == "textcolor") {
57                         return TEXTCOLOR;
58                 } else if (name == "bgcolor") {
59                         return BGCOLOR;
60                 } else if (name == "bgcolor_hovered") {
61                         return BGCOLOR_HOVERED;
62                 } else if (name == "bgcolor_pressed") {
63                         return BGCOLOR_PRESSED;
64                 } else if (name == "noclip") {
65                         return NOCLIP;
66                 } else if (name == "border") {
67                         return BORDER;
68                 } else if (name == "bgimg") {
69                         return BGIMG;
70                 } else if (name == "bgimg_hovered") {
71                         return BGIMG_HOVERED;
72                 } else if (name == "bgimg_pressed") {
73                         return BGIMG_PRESSED;
74                 } else if (name == "fgimg") {
75                         return FGIMG;
76                 } else if (name == "fgimg_hovered") {
77                         return FGIMG_HOVERED;
78                 } else if (name == "fgimg_pressed") {
79                         return FGIMG_PRESSED;
80                 } else if (name == "alpha") {
81                         return ALPHA;
82                 } else {
83                         return NONE;
84                 }
85         }
86
87         std::string get(Property prop, std::string def) const
88         {
89                 const auto &val = properties[prop];
90                 return val.empty() ? def : val;
91         }
92
93         void set(Property prop, const std::string &value)
94         {
95                 properties[prop] = value;
96                 property_set[prop] = true;
97         }
98
99         video::SColor getColor(Property prop, video::SColor def) const
100         {
101                 const auto &val = properties[prop];
102                 if (val.empty()) {
103                         return def;
104                 }
105
106                 parseColorString(val, def, false, 0xFF);
107                 return def;
108         }
109
110         video::SColor getColor(Property prop) const
111         {
112                 const auto &val = properties[prop];
113                 FATAL_ERROR_IF(val.empty(), "Unexpected missing property");
114
115                 video::SColor color;
116                 parseColorString(val, color, false, 0xFF);
117                 return color;
118         }
119
120         video::ITexture *getTexture(Property prop, ISimpleTextureSource *tsrc,
121                         video::ITexture *def) const
122         {
123                 const auto &val = properties[prop];
124                 if (val.empty()) {
125                         return def;
126                 }
127
128                 video::ITexture *texture = tsrc->getTexture(val);
129
130                 return texture;
131         }
132
133         video::ITexture *getTexture(Property prop, ISimpleTextureSource *tsrc) const
134         {
135                 const auto &val = properties[prop];
136                 FATAL_ERROR_IF(val.empty(), "Unexpected missing property");
137
138                 video::ITexture *texture = tsrc->getTexture(val);
139
140                 return texture;
141         }
142
143         bool getBool(Property prop, bool def) const
144         {
145                 const auto &val = properties[prop];
146                 if (val.empty()) {
147                         return def;
148                 }
149
150                 return is_yes(val);
151         }
152
153         inline bool isNotDefault(Property prop) const
154         {
155                 return !properties[prop].empty();
156         }
157
158         inline bool hasProperty(Property prop) const { return property_set[prop]; }
159
160         StyleSpec &operator|=(const StyleSpec &other)
161         {
162                 for (size_t i = 0; i < NUM_PROPERTIES; i++) {
163                         auto prop = (Property)i;
164                         if (other.hasProperty(prop)) {
165                                 set(prop, other.get(prop, ""));
166                         }
167                 }
168
169                 return *this;
170         }
171
172         StyleSpec operator|(const StyleSpec &other) const
173         {
174                 StyleSpec newspec = *this;
175                 newspec |= other;
176                 return newspec;
177         }
178 };