add: config ui
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user