add: Simple widget system

This commit is contained in:
Simon Hardt
2022-03-06 03:04:32 +01:00
parent e1e410561c
commit 243bf41e90
14 changed files with 430 additions and 8 deletions

View File

@@ -0,0 +1,56 @@
#include "Widget.hpp"
namespace frame::widgets
{
Widget::shared_ptr Widget::getParent() const
{
return mParent;
}
void Widget::setParent(week_ptr ptr)
{
mParent = ptr;
}
bool Widget::isDirty() const
{
return mDirty;
}
void Widget::setSize(Vector size)
{
mSize = size;
ComputeChildSize(size);
}
Vector const& Widget::getSize() const
{
return mSize;
}
void Widget::setPosition(Vector size)
{
mRelativePosition = size;
}
Vector Widget::getPosition() const
{
return mRelativePosition;
}
void Widget::setDirty()
{
mDirty = true;
if(mParent)
{
mParent->setDirty();
}
}
void Widget::setClear()
{
mDirty = false;
}
} // namespace frame::widgets

View File

@@ -0,0 +1,44 @@
#pragma once
#include "../Rect.hpp"
#include "../render/RenderTarget.hpp"
#include <memory>
namespace frame::widgets
{
class Widget
{
public:
using shared_ptr = std::shared_ptr<Widget>;
using week_ptr = std::shared_ptr<Widget>;
public:
virtual ~Widget() = default;
virtual void Update() = 0;
virtual void Render(render::RenderTarget& rt) = 0;
virtual void ComputeChildSize(Vector size){};
shared_ptr getParent() const;
void setParent(week_ptr ptr);
void setSize(Vector size);
Vector const& getSize() const;
void setPosition(Vector size);
Vector getPosition() const;
bool isDirty() const;
void setDirty();
void setClear();
private:
week_ptr mParent;
bool mDirty = true;
Vector mRelativePosition;
Vector mSize;
};
} // namespace frame::widgets

View File

@@ -0,0 +1,94 @@
#include "Analog.hpp"
#include <ctime>
#include <fmt/format.h>
constexpr double pi = 3.14159;
namespace frame::widgets
{
Widget::shared_ptr AnalogClock::Create()
{
return std::make_shared<AnalogClock>();
}
void AnalogClock::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 AnalogClock::Render(render::RenderTarget& rt)
{
auto const size = rt.getCurrentSize();
auto const min = std::min(size.height, size.width);
auto const radius = (min / 2) - 10;
auto const center = Vector{size.width / 2, size.height / 2};
rt.DrawCircle(center, radius, 4);
rt.DrawCircle(center, 6, 4);
auto step = 360 / 60;
for(int i = 0; i < 60; ++i)
{
double const x = std::cos(step * i * pi / 180.f);
double const y = std::sin(step * i * pi / 180.f);
auto lineLength = 10;
if(i % 5 == 0)
{
lineLength = 20;
if(i % 3 == 0)
{
lineLength = 50;
}
}
auto const fromCenter = radius - lineLength;
rt.DrawLine({int32_t(x * (radius - 1) + center.x),
int32_t(y * (radius - 1) + center.y)},
{int32_t(x * fromCenter + center.x),
int32_t(y * fromCenter + center.y)});
}
// pls c++ 20
std::time_t t = std::chrono::system_clock::to_time_t(last_time);
auto c_time = std::localtime(&t);
// Render Pointer Minute
auto const min_steps = 360 / 60;
auto const min_rad = (min_steps * c_time->tm_min - 90) * pi / 180.f;
rt.DrawLine(center,
{center.x + int32_t(std::cos(min_rad) * radius),
center.y + int32_t(std::sin(min_rad) * radius)});
// Render Pointer Hour
auto const hour_steps = 360 / 12;
auto hour_deg = (hour_steps * c_time->tm_hour - 90);
auto const normalied_min = (c_time->tm_min / 59.0);
hour_deg += int32_t(normalied_min * hour_steps);
auto const hour_rad = hour_deg * pi / 180.f;
rt.DrawLine(center,
{center.x + int32_t(std::cos(hour_rad) * radius * 0.6),
center.y + int32_t(std::sin(hour_rad) * radius * 0.6)});
setClear();
}
} // namespace frame::widgets

View File

@@ -0,0 +1,22 @@
#pragma once
#include "../Widget.hpp"
#include <chrono>
namespace frame::widgets
{
class AnalogClock : 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

View File