#include #include #include #include #include #include #include #include #include "json.hpp" #include "sdl_helpers.h" #include "Widgets/Widget.h" #include "Widgets/WidgetImage.h" #include "Widgets/WidgetRect.h" #include "Widgets/WidgetText.h" using std::cout; using std::endl; using std::map; using std::shared_ptr; using std::string; using std::unique_ptr; using std::vector; using nlohmann::json; void init_builders(map(*)(const json&)>& widget_builders) { widget_builders["image"] = &WidgetImage::builder; widget_builders["rect"] = &WidgetRect::builder; widget_builders["text"] = &WidgetText::builder; } int main(int argc, char **argv) { int result = 0; bool ok; int screen_width = 800; int screen_height = 480; string output_filename = "trmnl.png"; string cfg_filename = "config.json"; json cfg; SDL_Surface* main_surface = nullptr; vector widgets_cfg; vector> widgets; map(*)(const json&)> widget_builders; ok = init_sdl(); if (!ok) { return -1; } if (argc > 1) { cfg_filename = argv[1]; } // Read JSON CFG ok = read_config_json(cfg, cfg_filename); if (!ok) { result = -1; goto cleanup; } // Change screen size from JSON json_extract(cfg, "width", screen_width); json_extract(cfg, "height", screen_height); json_extract(cfg, "font", default_font_name); // Create surface main_surface = SDL_CreateRGBSurfaceWithFormat(0, screen_width, screen_height, 32, SDL_PIXELFORMAT_RGBA8888); if (nullptr == main_surface) { cout << "Could not allocate main surface" << endl; result = -1; goto cleanup; } init_builders(widget_builders); // Add Widgets From JSON if (cfg.contains("widgets") && cfg["widgets"].is_array()) { widgets_cfg = cfg["widgets"]; } for (const json& j : widgets_cfg) { string widget_name; json_extract(j, "name", widget_name); if (widget_name.empty()) { continue; } // Check if name exists in known builders if (0 == widget_builders.count(widget_name)) { cout << "Unknown widget '" << widget_name << "'. Skipping ..." << endl; continue; } // Construct and add widget to vector shared_ptr widget = widget_builders[widget_name](j); if (nullptr != widget) { widgets.push_back(widget); } } // Clear screen with white SDL_FillRect(main_surface, nullptr, SDL_MapRGBA(main_surface->format, 255, 255, 255, SDL_ALPHA_OPAQUE)); // Draw and apply all widgets for (shared_ptr& widget : widgets) { widget->draw(); SDL_Rect rect = widget->get_rect(); SDL_BlitSurface(widget->get_internal_surface(), nullptr, main_surface, &rect); } // Save image json_extract(cfg, "output", output_filename); IMG_SavePNG(main_surface, output_filename.c_str()); cleanup: widgets.clear(); clean_sdl(); return result; }