3 Copyright (C) 2019 rubenwardy
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.
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.
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.
20 #include "client/tile.h" // ITextureSource
21 #include "irrlichttypes_extrabloated.h"
22 #include "util/string.h"
51 std::array<bool, NUM_PROPERTIES> property_set{};
52 std::array<std::string, NUM_PROPERTIES> properties;
55 static Property GetPropertyByName(const std::string &name)
57 if (name == "textcolor") {
59 } else if (name == "bgcolor") {
61 } else if (name == "bgcolor_hovered") {
62 return BGCOLOR_HOVERED;
63 } else if (name == "bgcolor_pressed") {
64 return BGCOLOR_PRESSED;
65 } else if (name == "noclip") {
67 } else if (name == "border") {
69 } else if (name == "bgimg") {
71 } else if (name == "bgimg_hovered") {
73 } else if (name == "bgimg_middle") {
75 } else if (name == "bgimg_pressed") {
77 } else if (name == "fgimg") {
79 } else if (name == "fgimg_hovered") {
81 } else if (name == "fgimg_pressed") {
83 } else if (name == "alpha") {
90 std::string get(Property prop, std::string def) const
92 const auto &val = properties[prop];
93 return val.empty() ? def : val;
96 void set(Property prop, const std::string &value)
98 properties[prop] = value;
99 property_set[prop] = true;
102 video::SColor getColor(Property prop, video::SColor def) const
104 const auto &val = properties[prop];
109 parseColorString(val, def, false, 0xFF);
113 video::SColor getColor(Property prop) const
115 const auto &val = properties[prop];
116 FATAL_ERROR_IF(val.empty(), "Unexpected missing property");
119 parseColorString(val, color, false, 0xFF);
123 irr::core::rect<s32> getRect(Property prop, irr::core::rect<s32> def) const
125 const auto &val = properties[prop];
129 irr::core::rect<s32> rect;
130 if (!parseRect(val, &rect))
136 irr::core::rect<s32> getRect(Property prop) const
138 const auto &val = properties[prop];
139 FATAL_ERROR_IF(val.empty(), "Unexpected missing property");
141 irr::core::rect<s32> rect;
142 parseRect(val, &rect);
146 video::ITexture *getTexture(Property prop, ISimpleTextureSource *tsrc,
147 video::ITexture *def) const
149 const auto &val = properties[prop];
154 video::ITexture *texture = tsrc->getTexture(val);
159 video::ITexture *getTexture(Property prop, ISimpleTextureSource *tsrc) const
161 const auto &val = properties[prop];
162 FATAL_ERROR_IF(val.empty(), "Unexpected missing property");
164 video::ITexture *texture = tsrc->getTexture(val);
169 bool getBool(Property prop, bool def) const
171 const auto &val = properties[prop];
179 inline bool isNotDefault(Property prop) const
181 return !properties[prop].empty();
184 inline bool hasProperty(Property prop) const { return property_set[prop]; }
186 StyleSpec &operator|=(const StyleSpec &other)
188 for (size_t i = 0; i < NUM_PROPERTIES; i++) {
189 auto prop = (Property)i;
190 if (other.hasProperty(prop)) {
191 set(prop, other.get(prop, ""));
198 StyleSpec operator|(const StyleSpec &other) const
200 StyleSpec newspec = *this;
206 bool parseRect(const std::string &value, irr::core::rect<s32> *parsed_rect) const
208 irr::core::rect<s32> rect;
209 std::vector<std::string> v_rect = split(value, ',');
211 if (v_rect.size() == 1) {
212 s32 x = stoi(v_rect[0]);
213 rect.UpperLeftCorner = irr::core::vector2di(x, x);
214 rect.LowerRightCorner = irr::core::vector2di(-x, -x);
215 } else if (v_rect.size() == 2) {
216 s32 x = stoi(v_rect[0]);
217 s32 y = stoi(v_rect[1]);
218 rect.UpperLeftCorner = irr::core::vector2di(x, y);
219 rect.LowerRightCorner = irr::core::vector2di(-x, -y);
220 // `-x` is interpreted as `w - x`
221 } else if (v_rect.size() == 4) {
222 rect.UpperLeftCorner = irr::core::vector2di(
223 stoi(v_rect[0]), stoi(v_rect[1]));
224 rect.LowerRightCorner = irr::core::vector2di(
225 stoi(v_rect[2]), stoi(v_rect[3]));
227 warningstream << "Invalid rectangle string format: \"" << value
228 << "\"" << std::endl;