add: config ui
This commit is contained in:
@@ -7,17 +7,36 @@
|
|||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
#define PROPERTY(str, member) str.member = j.value(#member, str.member)
|
#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()
|
Config Config::Load()
|
||||||
{
|
{
|
||||||
fs::path const config_path{"config.json"};
|
fs::path const config_path{"config.json"};
|
||||||
|
|
||||||
if(fs::is_regular_file(config_path))
|
if(fs::is_regular_file(config_path))
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
std::fstream file(config_path.string(), std::ios::in);
|
std::fstream file(config_path.string(), std::ios::in);
|
||||||
|
|
||||||
return json::parse(file);
|
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");
|
fmt::print("[INFO] Creating config file\n");
|
||||||
Config config;
|
Config config;
|
||||||
@@ -30,18 +49,29 @@ Config Config::Load()
|
|||||||
// == to json ==
|
// == to json ==
|
||||||
void to_json(json& j, Config const& c)
|
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)
|
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 ==
|
// == from json ==
|
||||||
void from_json(json const& j, Config& c)
|
void from_json(json const& j, Config& c)
|
||||||
{
|
{
|
||||||
PROPERTY(c, font);
|
PROPERTY(c, font);
|
||||||
|
PROPERTY(c, root);
|
||||||
}
|
}
|
||||||
|
|
||||||
void from_json(json const& j, FontConfig& fc)
|
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, base_path);
|
||||||
PROPERTY(fc, fonts);
|
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
|
#pragma once
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
@@ -12,15 +13,26 @@ struct FontConfig
|
|||||||
{"Fira Code", "FiraCode.json"}};
|
{"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
|
struct Config
|
||||||
{
|
{
|
||||||
FontConfig font{};
|
FontConfig font{};
|
||||||
|
WidgetConfig root{};
|
||||||
|
|
||||||
static Config Load();
|
static Config Load();
|
||||||
};
|
};
|
||||||
|
|
||||||
void to_json(json& j, Config const& c);
|
void to_json(json& j, Config const& c);
|
||||||
void to_json(json& j, FontConfig const& fc);
|
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, Config& c);
|
||||||
void from_json(json const& j, FontConfig& fc);
|
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>();
|
auto const& widgets = frame::Service::get<frame::widgets::WidgetRegistry>();
|
||||||
|
|
||||||
std::shared_ptr<frame::widgets::ContainerWidget> con =
|
// std::shared_ptr<frame::widgets::ContainerWidget> con =
|
||||||
std::static_pointer_cast<frame::widgets::ContainerWidget>(
|
// std::static_pointer_cast<frame::widgets::ContainerWidget>(
|
||||||
widgets->Create("AnalogClock"));
|
// 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.setRoot(con);
|
||||||
|
|
||||||
screen.MainLoop();
|
screen.MainLoop();
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#include "WidgetRegistry.hpp"
|
#include "WidgetRegistry.hpp"
|
||||||
|
|
||||||
|
#include "ContainerWidget.hpp"
|
||||||
|
|
||||||
namespace frame::widgets
|
namespace frame::widgets
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -19,4 +21,23 @@ namespace frame::widgets
|
|||||||
return it->second();
|
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
|
} // namespace frame::widgets
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "../Config.hpp"
|
||||||
#include "../ServiceLocator.hpp"
|
#include "../ServiceLocator.hpp"
|
||||||
#include "Widget.hpp"
|
#include "Widget.hpp"
|
||||||
|
|
||||||
@@ -14,7 +15,6 @@
|
|||||||
|
|
||||||
namespace frame::widgets
|
namespace frame::widgets
|
||||||
{
|
{
|
||||||
|
|
||||||
class WidgetRegistry : public IService
|
class WidgetRegistry : public IService
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -29,8 +29,15 @@ namespace frame::widgets
|
|||||||
bool Register(std::string_view name);
|
bool Register(std::string_view name);
|
||||||
|
|
||||||
Widget::shared_ptr Create(std::string_view name) const;
|
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>
|
template<class WIDGET>
|
||||||
bool WidgetRegistry::Register(std::string_view name)
|
bool WidgetRegistry::Register(std::string_view name)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user