115 using namespace std::string_view_literals;
117 toml::parse_result result = toml::parse_file(std::string_view(path));
120 "Failed to parse theme file... it's probably not valid TOML");
121 FUNC_WARN(
"error: {}", result.error().description());
125 toml::table table = result.table();
126 if (!table.contains(
"meta"sv) || !table.contains(
"colors"sv)) {
127 FUNC_WARN(
"Theme file is missing required fields (meta/colors)");
131 toml::table* meta = table.get(
"meta"sv)->as_table();
132 const char* name = meta->get(
"name")->as_string()->get().c_str();
133 const char* author = meta->get(
"author")->as_string()->get().c_str();
134 const char* uuid = meta->get(
"uuid")->as_string()->get().c_str();
138 auto* name_copy = (
char*)malloc(strlen(name) + 1);
139 auto* author_copy = (
char*)malloc(strlen(author) + 1);
140 auto* uuid_copy = (
char*)malloc(strlen(uuid) + 1);
142 if (!name_copy || !author_copy || !uuid_copy) {
149 FUNC_ERR(
"Memory allocation failed!");
153 strcpy(name_copy, name);
154 strcpy(author_copy, author);
155 strcpy(uuid_copy, uuid);
157 toml::table* colors = table.get(
"colors"sv)->as_table();
158 ImGuiStyle style = ImGui::GetStyle();
160 for (
const auto& [k, v] : *colors) {
167 parsed = std::stoi(std::string(k.str()));
169 FUNC_WARN(
"Invalid color key: {}", k.str());
173 if (parsed < 0 || parsed >= ImGuiCol_COUNT) {
174 FUNC_WARN(
"Invalid ImGui color index: {}", parsed);
178 toml::array arr = *v.as_array();
182 style.Colors[parsed] =
183 ImVec4(arr.get(0)->as_floating_point()->get(),
184 arr.get(1)->as_floating_point()->get(),
185 arr.get(2)->as_floating_point()->get(),
186 arr.get(3)->as_floating_point()->get());
189 if (table.contains(
"other"sv) && table.get(
"other"sv)->is_table()) {
190 toml::table* other = table.get(
"other"sv)->as_table();
192 auto read_number = [](
const toml::node* node,
double& out) {
196 if (
const auto* fp = node->as_floating_point()) {
200 if (
const auto* i = node->as_integer()) {
201 out =
static_cast<double>(i->get());
207 auto read_float = [&](std::string_view key,
float& out) {
209 if (read_number(other->get(key), tmp)) {
210 out =
static_cast<float>(tmp);
214 auto read_vec2 = [&](std::string_view key, ImVec2& out) {
215 const toml::node* node = other->get(key);
216 if (!node || !node->is_array()) {
219 const toml::array& arr = *node->as_array();
220 if (arr.size() != 2) {
225 if (!read_number(arr.get(0), x) ||
226 !read_number(arr.get(1), y)) {
229 out = ImVec2(
static_cast<float>(x),
static_cast<float>(y));
232 auto read_bool = [&](std::string_view key,
bool& out) {
233 const toml::node* node = other->get(key);
237 if (
const auto* b = node->as_boolean()) {
242 if (read_number(node, tmp)) {
247 auto read_enum = [&](std::string_view key,
auto& out) {
249 if (read_number(other->get(key), tmp)) {
250 using T = std::remove_reference_t<
decltype(out)>;
251 out =
static_cast<T
>(
static_cast<int>(tmp));
255 read_float(
"Alpha"sv, style.Alpha);
256 read_float(
"DisabledAlpha"sv, style.DisabledAlpha);
257 read_vec2(
"WindowPadding"sv, style.WindowPadding);
258 read_float(
"WindowRounding"sv, style.WindowRounding);
259 read_float(
"WindowBorderSize"sv, style.WindowBorderSize);
261 "WindowBorderHoverPadding"sv, style.WindowBorderHoverPadding);
262 read_vec2(
"WindowMinSize"sv, style.WindowMinSize);
263 read_vec2(
"WindowTitleAlign"sv, style.WindowTitleAlign);
265 "WindowMenuButtonPosition"sv, style.WindowMenuButtonPosition);
266 read_float(
"ChildRounding"sv, style.ChildRounding);
267 read_float(
"ChildBorderSize"sv, style.ChildBorderSize);
268 read_float(
"PopupRounding"sv, style.PopupRounding);
269 read_float(
"PopupBorderSize"sv, style.PopupBorderSize);
270 read_vec2(
"FramePadding"sv, style.FramePadding);
271 read_float(
"FrameRounding"sv, style.FrameRounding);
272 read_float(
"FrameBorderSize"sv, style.FrameBorderSize);
273 read_vec2(
"ItemSpacing"sv, style.ItemSpacing);
274 read_vec2(
"ItemInnerSpacing"sv, style.ItemInnerSpacing);
275 read_vec2(
"CellPadding"sv, style.CellPadding);
276 read_vec2(
"TouchExtraPadding"sv, style.TouchExtraPadding);
277 read_float(
"IndentSpacing"sv, style.IndentSpacing);
278 read_float(
"ColumnsMinSpacing"sv, style.ColumnsMinSpacing);
279 read_float(
"ScrollbarSize"sv, style.ScrollbarSize);
280 read_float(
"ScrollbarRounding"sv, style.ScrollbarRounding);
281 read_float(
"ScrollbarPadding"sv, style.ScrollbarPadding);
282 read_float(
"GrabMinSize"sv, style.GrabMinSize);
283 read_float(
"GrabRounding"sv, style.GrabRounding);
284 read_float(
"LogSliderDeadzone"sv, style.LogSliderDeadzone);
285 read_float(
"ImageRounding"sv, style.ImageRounding);
286 read_float(
"ImageBorderSize"sv, style.ImageBorderSize);
287 read_float(
"TabRounding"sv, style.TabRounding);
288 read_float(
"TabBorderSize"sv, style.TabBorderSize);
289 read_float(
"TabMinWidthBase"sv, style.TabMinWidthBase);
290 read_float(
"TabMinWidthShrink"sv, style.TabMinWidthShrink);
291 read_float(
"TabCloseButtonMinWidthSelected"sv,
292 style.TabCloseButtonMinWidthSelected);
293 read_float(
"TabCloseButtonMinWidthUnselected"sv,
294 style.TabCloseButtonMinWidthUnselected);
295 read_float(
"TabBarBorderSize"sv, style.TabBarBorderSize);
296 read_float(
"TabBarOverlineSize"sv, style.TabBarOverlineSize);
298 "TableAngledHeadersAngle"sv, style.TableAngledHeadersAngle);
299 read_vec2(
"TableAngledHeadersTextAlign"sv,
300 style.TableAngledHeadersTextAlign);
301 read_enum(
"TreeLinesFlags"sv, style.TreeLinesFlags);
302 read_float(
"TreeLinesSize"sv, style.TreeLinesSize);
303 read_float(
"TreeLinesRounding"sv, style.TreeLinesRounding);
305 "DragDropTargetRounding"sv, style.DragDropTargetRounding);
307 "DragDropTargetBorderSize"sv, style.DragDropTargetBorderSize);
308 read_float(
"DragDropTargetPadding"sv, style.DragDropTargetPadding);
309 read_float(
"ColorMarkerSize"sv, style.ColorMarkerSize);
310 read_enum(
"ColorButtonPosition"sv, style.ColorButtonPosition);
311 read_vec2(
"ButtonTextAlign"sv, style.ButtonTextAlign);
312 read_vec2(
"SelectableTextAlign"sv, style.SelectableTextAlign);
313 read_float(
"SeparatorSize"sv, style.SeparatorSize);
315 "SeparatorTextBorderSize"sv, style.SeparatorTextBorderSize);
316 read_vec2(
"SeparatorTextAlign"sv, style.SeparatorTextAlign);
317 read_vec2(
"SeparatorTextPadding"sv, style.SeparatorTextPadding);
318 read_vec2(
"DisplayWindowPadding"sv, style.DisplayWindowPadding);
319 read_vec2(
"DisplaySafeAreaPadding"sv, style.DisplaySafeAreaPadding);
321 "DockingNodeHasCloseButton"sv, style.DockingNodeHasCloseButton);
322 read_float(
"DockingSeparatorSize"sv, style.DockingSeparatorSize);
323 read_float(
"MouseCursorScale"sv, style.MouseCursorScale);
324 read_bool(
"AntiAliasedLines"sv, style.AntiAliasedLines);
325 read_bool(
"AntiAliasedLinesUseTex"sv, style.AntiAliasedLinesUseTex);
326 read_bool(
"AntiAliasedFill"sv, style.AntiAliasedFill);
327 read_float(
"CurveTessellationTol"sv, style.CurveTessellationTol);
328 read_float(
"CircleTessellationMaxError"sv,
329 style.CircleTessellationMaxError);
334 std::free(uuid_copy);