add: Container Widget
This commit is contained in:
@@ -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
|
||||
|
||||
)
|
||||
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
34
frame/src/widgets/ContainerWidget.cpp
Normal file
34
frame/src/widgets/ContainerWidget.cpp
Normal 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
|
||||
23
frame/src/widgets/ContainerWidget.hpp
Normal file
23
frame/src/widgets/ContainerWidget.hpp
Normal 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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
54
frame/src/widgets/clock/Date.cpp
Normal file
54
frame/src/widgets/clock/Date.cpp
Normal 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
|
||||
22
frame/src/widgets/clock/Date.hpp
Normal file
22
frame/src/widgets/clock/Date.hpp
Normal 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user