add: config ui

This commit is contained in:
2022-10-16 04:48:46 +02:00
parent 2a0334ba4b
commit e6591ce9be
5 changed files with 91 additions and 12 deletions

View File

@@ -7,17 +7,36 @@
namespace fs = std::filesystem;
#define PROPERTY(str, member) str.member = j.value(#member, str.member)
#define PROPERTY_OPT(str, member, type) \
str.member = \
j.contains(#member) ? j[#member].get<type>() : std::optional<type>{};
#define OBJ(str, mem) \
{ \
# mem, str.mem \
}
Config Config::Load()
{
fs::path const config_path{"config.json"};
if(fs::is_regular_file(config_path))
{
try
{
std::fstream file(config_path.string(), std::ios::in);
return json::parse(file);
}
catch(std::exception const& e)
{
fmt::print("Error: {}\n", e.what());
// TODO: Create Error Display Widget
return {};
}
}
fmt::print("[INFO] Creating config file\n");
Config config;
@@ -30,18 +49,29 @@ Config Config::Load()
// == to json ==
void to_json(json& j, Config const& c)
{
j = {{"font", c.font}};
j = {OBJ(c, font), OBJ(c, root)};
}
void to_json(json& j, FontConfig const& fc)
{
j = {{"base_path", fc.base_path}, {"fonts", fc.fonts}};
j = {OBJ(fc, base_path), OBJ(fc, fonts)};
}
void to_json(json& j, WidgetConfig const& w)
{
j = {OBJ(w, name), OBJ(w, parameters), OBJ(w, widgets)};
if(w.slot)
{
j["slot"] = w.slot.value();
}
}
// == from json ==
void from_json(json const& j, Config& c)
{
PROPERTY(c, font);
PROPERTY(c, root);
}
void from_json(json const& j, FontConfig& fc)
@@ -49,3 +79,11 @@ void from_json(json const& j, FontConfig& fc)
PROPERTY(fc, base_path);
PROPERTY(fc, fonts);
}
void from_json(json const& j, WidgetConfig& w)
{
PROPERTY(w, name);
PROPERTY(w, parameters);
PROPERTY(w, widgets);
PROPERTY_OPT(w, slot, int);
}

View File

@@ -1,5 +1,6 @@
#pragma once
#include <nlohmann/json.hpp>
#include <optional>
#include <string>
#include <unordered_map>
@@ -12,15 +13,26 @@ struct FontConfig
{"Fira Code", "FiraCode.json"}};
};
struct WidgetConfig
{
std::string name = "DigitalClock";
std::unordered_map<std::string, json> parameters = {};
std::vector<WidgetConfig> widgets = {};
std::optional<int> slot = {};
};
struct Config
{
FontConfig font{};
WidgetConfig root{};
static Config Load();
};
void to_json(json& j, Config const& c);
void to_json(json& j, FontConfig const& fc);
void to_json(json& j, WidgetConfig const& w);
void from_json(json const& j, Config& c);
void from_json(json const& j, FontConfig& fc);
void from_json(json const& j, WidgetConfig& w);

View File

@@ -38,14 +38,15 @@ int main()
auto const& widgets = frame::Service::get<frame::widgets::WidgetRegistry>();
std::shared_ptr<frame::widgets::ContainerWidget> con =
std::static_pointer_cast<frame::widgets::ContainerWidget>(
widgets->Create("AnalogClock"));
// std::shared_ptr<frame::widgets::ContainerWidget> con =
// std::static_pointer_cast<frame::widgets::ContainerWidget>(
// widgets->Create("AnalogClock"));
con->setSlot(0, widgets->Create("DigitalClock"));
// con->setSlot(0, widgets->Create("DigitalClock"));
con->setSlot(1, widgets->Create("Date"));
// con->setSlot(1, widgets->Create("Date"));
auto con = frame::widgets::LocateRegistry().BuildFromConfig(config.root);
screen.setRoot(con);
screen.MainLoop();

View File

@@ -1,5 +1,7 @@
#include "WidgetRegistry.hpp"
#include "ContainerWidget.hpp"
namespace frame::widgets
{
@@ -19,4 +21,23 @@ namespace frame::widgets
return it->second();
}
Widget::shared_ptr WidgetRegistry::BuildFromConfig(WidgetConfig const& w)
{
fmt::print("INFO: Creating widget {} \n", w.name);
auto widget = Create(w.name);
auto container = std::dynamic_pointer_cast<ContainerWidget>(widget);
if(container)
{
int counter = 0;
for(auto const& el : w.widgets)
{
int slot = el.slot ? el.slot.value() : counter;
container->setSlot(slot, BuildFromConfig(el));
}
}
return widget;
}
} // namespace frame::widgets

View File

@@ -1,4 +1,5 @@
#pragma once
#include "../Config.hpp"
#include "../ServiceLocator.hpp"
#include "Widget.hpp"
@@ -14,7 +15,6 @@
namespace frame::widgets
{
class WidgetRegistry : public IService
{
@@ -29,8 +29,15 @@ namespace frame::widgets
bool Register(std::string_view name);
Widget::shared_ptr Create(std::string_view name) const;
Widget::shared_ptr BuildFromConfig(WidgetConfig const& w);
};
inline WidgetRegistry& LocateRegistry()
{
return *Service::get<frame::widgets::WidgetRegistry>();
}
template<class WIDGET>
bool WidgetRegistry::Register(std::string_view name)
{