add: Simple widget system
This commit is contained in:
56
frame/src/widgets/Widget.cpp
Normal file
56
frame/src/widgets/Widget.cpp
Normal 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
|
||||
44
frame/src/widgets/Widget.hpp
Normal file
44
frame/src/widgets/Widget.hpp
Normal 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
|
||||
94
frame/src/widgets/clock/Analog.cpp
Normal file
94
frame/src/widgets/clock/Analog.cpp
Normal 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
|
||||
22
frame/src/widgets/clock/Analog.hpp
Normal file
22
frame/src/widgets/clock/Analog.hpp
Normal 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
|
||||
0
frame/src/widgets/clock/Digital.cpp
Normal file
0
frame/src/widgets/clock/Digital.cpp
Normal file
0
frame/src/widgets/clock/Digital.hpp
Normal file
0
frame/src/widgets/clock/Digital.hpp
Normal file
Reference in New Issue
Block a user