add: Container Widget

This commit is contained in:
Simon Hardt
2022-03-06 22:03:12 +01:00
parent 33f79d9f92
commit 4c70f3440d
11 changed files with 288 additions and 13 deletions

View File

@@ -39,16 +39,16 @@ set(src
src/widgets/Widget.hpp
src/widgets/Widget.cpp
src/widgets/ContainerWidget.hpp
src/widgets/ContainerWidget.cpp
src/widgets/WidgetRegistry.hpp
src/widgets/WidgetRegistry.cpp
src/widgets/clock/Digital.hpp
src/widgets/clock/Digital.cpp
src/widgets/clock/Analog.hpp
src/widgets/clock/Analog.cpp
src/widgets/clock/Date.hpp
src/widgets/clock/Date.cpp
)

View File

@@ -32,13 +32,13 @@ namespace frame
if(mRoot)
{
mRenderTarget.Clear();
mRoot->setSize(mDisplay->getSize());
mRoot->Render(mRenderTarget);
if(mDisplay)
{
mDisplay->Display(mRenderTarget.getImage());
}
}
}
void ScreenManager::MainLoop()
{

View File

@@ -11,6 +11,7 @@ using namespace std::chrono_literals;
#include "font/FontRegistry.hpp"
//#include "render/RenderTarget.hpp"
//#include "widgets/clock/Analog.hpp"
#include "widgets/ContainerWidget.hpp"
#include "widgets/WidgetRegistry.hpp"
int main()
@@ -30,7 +31,14 @@ int main()
auto const& widgets = frame::Service::get<frame::widgets::WidgetRegistry>();
screen.setRoot(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(1, widgets->Create("Date"));
screen.setRoot(con);
screen.MainLoop();
}

View File

@@ -0,0 +1,34 @@
#include "ContainerWidget.hpp"
namespace frame::widgets
{
ContainerWidget::ContainerWidget(size_t slots)
{
widgets.resize(slots);
maxSlots = slots;
}
Widget::shared_ptr ContainerWidget::getSlot(size_t slot) const
{
if(slot >= maxSlots)
return nullptr;
return widgets[slot];
}
void ContainerWidget::setSlot(size_t slot, Widget::shared_ptr ptr)
{
widgets[slot] = ptr;
}
void ContainerWidget::UpdateWidgets()
{
for(auto& el : widgets)
{
if(el)
{
el->Update();
}
}
}
} // namespace frame::widgets

View File

@@ -0,0 +1,23 @@
#pragma once
#include "Widget.hpp"
#include <vector>
namespace frame::widgets
{
class ContainerWidget : public Widget
{
std::vector<Widget::shared_ptr> widgets;
size_t maxSlots = 0;
public:
ContainerWidget(size_t slots);
Widget::shared_ptr getSlot(size_t slot) const;
void setSlot(size_t slot, Widget::shared_ptr);
void UpdateWidgets();
};
} // namespace frame::widgets

View File

@@ -20,6 +20,11 @@ namespace frame::widgets
return std::make_shared<AnalogClock>();
}
AnalogClock::AnalogClock()
: ContainerWidget(2)
{
}
void AnalogClock::Update()
{
auto const now = std::chrono::system_clock::now();
@@ -30,6 +35,8 @@ namespace frame::widgets
setDirty();
last_time = min;
}
UpdateWidgets();
}
void AnalogClock::Render(render::RenderTarget& rt)
@@ -97,9 +104,54 @@ namespace frame::widgets
setClear();
// == Widgets ==
auto widget_center_1 = center;
widget_center_1.y -= radius / 2;
auto widget_center_2 = center;
widget_center_2.y += radius / 2;
auto const widget_height_h = radius / 4;
auto const widget_width_h = radius / 2;
Rect widget_box_1{widget_center_1.y - widget_height_h,
widget_center_1.x - widget_width_h,
widget_width_h * 2,
widget_height_h * 2};
Rect widget_box_2{widget_center_2.y - widget_height_h,
widget_center_2.x - widget_width_h,
widget_width_h * 2,
widget_height_h * 2};
// Top
rt.setInvert(true);
auto top = getSlot(0);
if(top)
{
top->setSize({widget_box_1.width, widget_box_1.height});
rt.pushViewport(widget_box_1);
top->Render(rt);
rt.popViewport();
}
auto bottom = getSlot(1);
if(bottom)
{
bottom->setSize({widget_box_2.width, widget_box_2.height});
rt.pushViewport(widget_box_2);
bottom->Render(rt);
rt.popViewport();
}
rt.setInvert(false);
// Text
auto font = font::GetFont("Fira Code");
/*auto font = font::GetFont("Fira Code");
if(!font)
return;
@@ -126,7 +178,7 @@ namespace frame::widgets
font_size,
AlignHorizontal::CENTER,
AlignVertical::CENTER);
rt.setInvert(false);
rt.setInvert(false);*/
}
} // namespace frame::widgets

View File

@@ -1,13 +1,13 @@
#pragma once
#include "../Widget.hpp"
#include "../ContainerWidget.hpp"
#include <chrono>
namespace frame::widgets
{
class AnalogClock : public Widget
class AnalogClock : public ContainerWidget
{
using Time = std::chrono::time_point<std::chrono::system_clock>;
@@ -16,6 +16,8 @@ namespace frame::widgets
public:
static Widget::shared_ptr Create();
AnalogClock();
void Update() override;
void Render(render::RenderTarget& rt) override;
};

View File

@@ -0,0 +1,54 @@
#include "Date.hpp"
REGISTER_WIDGET(frame::widgets::Date, "Date");
#include "../../font/FontRegistry.hpp"
#include <ctime>
#include <fmt/chrono.h>
#include <fmt/format.h>
namespace frame::widgets
{
Widget::shared_ptr Date::Create()
{
return std::make_shared<Date>();
}
void Date::Update()
{
auto const now = std::chrono::system_clock::now();
auto const min = std::chrono::floor<std::chrono::minutes>(now);
if(last_time != min)
{
setDirty();
last_time = min;
}
}
void Date::Render(render::RenderTarget& rt)
{
std::time_t t = std::chrono::system_clock::to_time_t(last_time);
auto const& size = getSize();
Rect draw{0, 0, size.x, size.y};
auto text = fmt::format("{:%d.%m.%Y}", fmt::localtime(t));
auto font = font::GetFont("Fira Code");
auto font_size = font->getOptimalSize(text, draw);
rt.DrawText(draw,
text,
*font,
font_size,
AlignHorizontal::CENTER,
AlignVertical::CENTER);
setClear();
}
} // namespace frame::widgets

View File

@@ -0,0 +1,22 @@
#pragma once
#include "../Widget.hpp"
#include "../WidgetRegistry.hpp"
#include <chrono>
namespace frame::widgets
{
class Date : public Widget
{
using Time = std::chrono::time_point<std::chrono::system_clock>;
Time last_time;
public:
static Widget::shared_ptr Create();
void Update() override;
void Render(render::RenderTarget& rt) override;
};
} // namespace frame::widgets

View File

@@ -0,0 +1,56 @@
#include "Digital.hpp"
REGISTER_WIDGET(frame::widgets::DigitalClock, "DigitalClock");
#include "../../font/FontRegistry.hpp"
#include <ctime>
#include <fmt/chrono.h>
#include <fmt/format.h>
namespace frame::widgets
{
Widget::shared_ptr DigitalClock::Create()
{
return std::make_shared<DigitalClock>();
}
void DigitalClock::Update()
{
auto const now = std::chrono::system_clock::now();
auto const min = std::chrono::floor<std::chrono::minutes>(now);
if(last_time != min)
{
setDirty();
last_time = min;
}
}
void DigitalClock::Render(render::RenderTarget& rt)
{
std::time_t t = std::chrono::system_clock::to_time_t(last_time);
auto c_time = std::localtime(&t);
auto const& size = getSize();
Rect draw{0, 0, size.x, size.y};
auto text =
fmt::format("{:0^2}:{:0^2}", c_time->tm_hour, c_time->tm_min);
auto font = font::GetFont("Fira Code");
auto font_size = font->getOptimalSize(text, draw);
rt.DrawText(draw,
text,
*font,
font_size,
AlignHorizontal::CENTER,
AlignVertical::CENTER);
setClear();
}
} // namespace frame::widgets

View File

@@ -0,0 +1,24 @@
#pragma once
#include <chrono>
#include "../Widget.hpp"
#include "../WidgetRegistry.hpp"
namespace frame::widgets
{
class DigitalClock : public Widget
{
using Time = std::chrono::time_point<std::chrono::system_clock>;
Time last_time;
public:
static Widget::shared_ptr Create();
void Update() override;
void Render(render::RenderTarget& rt) override;
};
} // namespace frame::widgets