136 lines
2.7 KiB
C++
136 lines
2.7 KiB
C++
#include <SDL2/SDL.h>
|
|
#include <SDL2/SDL_ttf.h>
|
|
#include <SDL2/SDL_image.h>
|
|
|
|
#include <iostream>
|
|
#include <map>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "json.hpp"
|
|
|
|
#include "sdl_helpers.h"
|
|
#include "Widgets/Widget.h"
|
|
#include "Widgets/WidgetText.h"
|
|
|
|
using std::cout;
|
|
using std::endl;
|
|
using std::map;
|
|
using std::string;
|
|
using std::vector;
|
|
using nlohmann::json;
|
|
|
|
void init_builders(map<string, Widget*(*)(const json&)>& widget_builders)
|
|
{
|
|
widget_builders["text"] = &WidgetText::builder;
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
int result = 0;
|
|
bool ok;
|
|
|
|
int screen_width = 800;
|
|
int screen_height = 600;
|
|
string output_filename = "trmnl.png";
|
|
string cfg_filename = "config.json";
|
|
json cfg;
|
|
|
|
SDL_Surface* main_surface = nullptr;
|
|
|
|
vector<json> widgets_cfg;
|
|
vector<Widget*> widgets;
|
|
map<string, Widget*(*)(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
|
|
Widget* 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 (Widget* 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:
|
|
// Destroy All Widgets
|
|
for (Widget* widget : widgets)
|
|
{
|
|
delete widget;
|
|
}
|
|
widgets.clear();
|
|
|
|
clean_sdl();
|
|
return result;
|
|
}
|