1 | // Aseprite Code Generator |
2 | // Copyright (c) 2015-2017 David Capello |
3 | // |
4 | // This file is released under the terms of the MIT license. |
5 | // Read LICENSE.txt for more information. |
6 | |
7 | #include "gen/theme_class.h" |
8 | |
9 | #include "base/string.h" |
10 | #include "gen/common.h" |
11 | |
12 | #include <cstring> |
13 | #include <iostream> |
14 | #include <vector> |
15 | |
16 | void gen_theme_class(TiXmlDocument* doc, const std::string& inputFn) |
17 | { |
18 | std::vector<std::string> dimensions; |
19 | std::vector<std::string> colors; |
20 | std::vector<std::string> parts; |
21 | std::vector<std::string> cursors; |
22 | std::vector<std::string> styles; |
23 | |
24 | TiXmlHandle handle(doc); |
25 | TiXmlElement* elem = handle |
26 | .FirstChild("theme" ) |
27 | .FirstChild("dimensions" ) |
28 | .FirstChild("dim" ).ToElement(); |
29 | while (elem) { |
30 | const char* id = elem->Attribute("id" ); |
31 | dimensions.push_back(id); |
32 | elem = elem->NextSiblingElement(); |
33 | } |
34 | |
35 | elem = handle |
36 | .FirstChild("theme" ) |
37 | .FirstChild("colors" ) |
38 | .FirstChild("color" ).ToElement(); |
39 | while (elem) { |
40 | const char* id = elem->Attribute("id" ); |
41 | colors.push_back(id); |
42 | elem = elem->NextSiblingElement(); |
43 | } |
44 | |
45 | elem = handle |
46 | .FirstChild("theme" ) |
47 | .FirstChild("parts" ) |
48 | .FirstChild("part" ).ToElement(); |
49 | while (elem) { |
50 | const char* id = elem->Attribute("id" ); |
51 | if (std::strncmp(id, "cursor_" , 7) == 0) { |
52 | cursors.push_back(std::string(id).substr(7)); |
53 | } |
54 | else if (!std::strchr(id, ':')) |
55 | parts.push_back(id); |
56 | elem = elem->NextSiblingElement(); |
57 | } |
58 | |
59 | elem = handle |
60 | .FirstChild("theme" ) |
61 | .FirstChild("styles" ) |
62 | .FirstChild("style" ).ToElement(); |
63 | while (elem) { |
64 | const char* id = elem->Attribute("id" ); |
65 | styles.push_back(id); |
66 | elem = elem->NextSiblingElement(); |
67 | } |
68 | |
69 | std::cout |
70 | << "// Don't modify, generated file from " << inputFn << "\n" |
71 | << "\n" |
72 | << "#ifndef GENERATED_THEME_H_INCLUDED\n" |
73 | << "#define GENERATED_THEME_H_INCLUDED\n" |
74 | << "#pragma once\n" |
75 | << "\n" |
76 | << "namespace app {\n" |
77 | << "namespace gen {\n" |
78 | << "\n" |
79 | << " template<typename T>\n" |
80 | << " class ThemeFile {\n" |
81 | << " public:\n" |
82 | << "\n" ; |
83 | |
84 | // Dimensions sub class |
85 | std::cout |
86 | << " class Dimensions {\n" |
87 | << " template<typename> friend class ThemeFile;\n" |
88 | << " public:\n" ; |
89 | for (auto dimension : dimensions) { |
90 | std::string id = convert_xmlid_to_cppid(dimension, false); |
91 | std::cout |
92 | << " int " << id << "() const { return m_" << id << "; }\n" ; |
93 | } |
94 | std::cout |
95 | << " private:\n" ; |
96 | for (auto dimension : dimensions) { |
97 | std::string id = convert_xmlid_to_cppid(dimension, false); |
98 | std::cout |
99 | << " int m_" << id << ";\n" ; |
100 | } |
101 | std::cout |
102 | << " };\n" ; |
103 | |
104 | // Colors sub class |
105 | std::cout |
106 | << " class Colors {\n" |
107 | << " template<typename> friend class ThemeFile;\n" |
108 | << " public:\n" ; |
109 | for (auto color : colors) { |
110 | std::string id = convert_xmlid_to_cppid(color, false); |
111 | std::cout |
112 | << " gfx::Color " << id << "() const { return m_" << id << "; }\n" ; |
113 | } |
114 | std::cout |
115 | << " private:\n" ; |
116 | for (auto color : colors) { |
117 | std::string id = convert_xmlid_to_cppid(color, false); |
118 | std::cout |
119 | << " gfx::Color m_" << id << ";\n" ; |
120 | } |
121 | std::cout |
122 | << " };\n" ; |
123 | |
124 | // Parts sub class |
125 | std::cout |
126 | << " class Parts {\n" |
127 | << " template<typename> friend class ThemeFile;\n" |
128 | << " public:\n" ; |
129 | for (auto part : parts) { |
130 | std::string id = convert_xmlid_to_cppid(part, false); |
131 | std::cout |
132 | << " const skin::SkinPartPtr& " << id << "() const { return m_" << id << "; }\n" ; |
133 | } |
134 | std::cout |
135 | << " private:\n" ; |
136 | for (auto part : parts) { |
137 | std::string id = convert_xmlid_to_cppid(part, false); |
138 | std::cout |
139 | << " skin::SkinPartPtr m_" << id << ";\n" ; |
140 | } |
141 | std::cout |
142 | << " };\n" ; |
143 | |
144 | // Cursors sub class |
145 | std::cout |
146 | << " class Cursors {\n" |
147 | << " template<typename> friend class ThemeFile;\n" |
148 | << " public:\n" ; |
149 | for (auto cursor : cursors) { |
150 | std::string id = convert_xmlid_to_cppid(cursor, false); |
151 | std::cout |
152 | << " const ui::Cursor* " << id << "() const { return m_" << id << "; }\n" ; |
153 | } |
154 | std::cout |
155 | << " private:\n" ; |
156 | for (auto cursor : cursors) { |
157 | std::string id = convert_xmlid_to_cppid(cursor, false); |
158 | std::cout |
159 | << " ui::Cursor* m_" << id << ";\n" ; |
160 | } |
161 | std::cout |
162 | << " };\n" ; |
163 | |
164 | // Styles sub class |
165 | std::cout |
166 | << "\n" |
167 | << " class Styles {\n" |
168 | << " template<typename> friend class ThemeFile;\n" |
169 | << " public:\n" ; |
170 | for (auto style : styles) { |
171 | std::string id = convert_xmlid_to_cppid(style, false); |
172 | std::cout |
173 | << " ui::Style* " << id << "() const { return m_" << id << "; }\n" ; |
174 | } |
175 | std::cout |
176 | << " private:\n" ; |
177 | for (auto style : styles) { |
178 | std::string id = convert_xmlid_to_cppid(style, false); |
179 | std::cout |
180 | << " ui::Style* m_" << id << ";\n" ; |
181 | } |
182 | std::cout |
183 | << " };\n" ; |
184 | |
185 | std::cout |
186 | << "\n" |
187 | << " Dimensions dimensions;\n" |
188 | << " Colors colors;\n" |
189 | << " Parts parts;\n" |
190 | << " Cursors cursors;\n" |
191 | << " Styles styles;\n" |
192 | << "\n" |
193 | << " protected:\n" |
194 | << " void updateInternals() {\n" ; |
195 | for (auto dimension : dimensions) { |
196 | std::string id = convert_xmlid_to_cppid(dimension, false); |
197 | std::cout << " byId(dimensions.m_" << id |
198 | << ", \"" << dimension << "\");\n" ; |
199 | } |
200 | for (auto color : colors) { |
201 | std::string id = convert_xmlid_to_cppid(color, false); |
202 | std::cout << " byId(colors.m_" << id |
203 | << ", \"" << color << "\");\n" ; |
204 | } |
205 | for (auto part : parts) { |
206 | std::string id = convert_xmlid_to_cppid(part, false); |
207 | std::cout << " byId(parts.m_" << id |
208 | << ", \"" << part << "\");\n" ; |
209 | } |
210 | for (auto cursor : cursors) { |
211 | std::string id = convert_xmlid_to_cppid(cursor, false); |
212 | std::cout << " byId(cursors.m_" << id |
213 | << ", \"" << cursor << "\");\n" ; |
214 | } |
215 | for (auto style : styles) { |
216 | std::string id = convert_xmlid_to_cppid(style, false); |
217 | std::cout << " byId(styles.m_" << id |
218 | << ", \"" << style << "\");\n" ; |
219 | } |
220 | std::cout |
221 | << " }\n" |
222 | << "\n" |
223 | << " private:\n" |
224 | << " void byId(int& dimension, const std::string& id) {\n" |
225 | << " dimension = static_cast<T*>(this)->getDimensionById(id);\n" |
226 | << " }\n" |
227 | << " void byId(gfx::Color& color, const std::string& id) {\n" |
228 | << " color = static_cast<T*>(this)->getColorById(id);\n" |
229 | << " }\n" |
230 | << " void byId(skin::SkinPartPtr& part, const std::string& id) {\n" |
231 | << " part = static_cast<T*>(this)->getPartById(id);\n" |
232 | << " }\n" |
233 | << " void byId(ui::Cursor*& cursor, const std::string& id) {\n" |
234 | << " cursor = static_cast<T*>(this)->getCursorById(id);\n" |
235 | << " }\n" |
236 | << " void byId(ui::Style*& style, const std::string& id) {\n" |
237 | << " style = static_cast<T*>(this)->getStyleById(id);\n" |
238 | << " }\n" ; |
239 | |
240 | std::cout |
241 | << " };\n" |
242 | << "\n" |
243 | << "} // namespace gen\n" |
244 | << "} // namespace app\n" |
245 | << "\n" |
246 | << "#endif\n" ; |
247 | } |
248 | |