Files
tessesbigscreen/include/bigscreen.hpp
2026-05-03 18:32:46 -05:00

254 lines
8.2 KiB
C++

#pragma once
#include <SDL2/SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <memory>
#include <mpv/client.h>
#include <mpv/render_gl.h>
#include <TessesFramework/TessesFramework.hpp>
namespace Tesses::BigScreen {
constexpr int GRID_STRETCH_SZ(int ammount)
{
return -ammount;
}
constexpr int GRID_STRETCH = GRID_STRETCH_SZ(1);
/*
--bg-dark: hsl(136 100% 0%);
--bg: hsl(133 100% 2%);
--bg-light: hsl(134 100% 4%);
--text: hsl(127 100% 90%);
--text-muted: hsl(128 34% 64%);
--highlight: hsl(144 100% 15%);
--border: hsl(133 100% 9%);
--border-muted: hsl(131 100% 4%);
--primary: hsl(134 57% 56%);
--secondary: hsl(301 74% 72%);
--danger: hsl(7 94% 66%);
--warning: hsl(53 100% 24%);
--success: hsl(163 100% 26%);
--info: hsl(217 100% 70%);
*/
constexpr SDL_Color COLOR_BGDARK = {.r = 0,.g=0,.b=0,.a=255};
constexpr SDL_Color COLOR_BG = {.r = 0,.g=10,.b=2,.a=255};
constexpr SDL_Color COLOR_BGLIGHT = {.r = 0,.g=20,.b=5,.a=255};
constexpr SDL_Color COLOR_TEXT = {.r = 204,.g=255,.b=210,.a=255};
constexpr SDL_Color COLOR_TEXTMUTED = {.r = 132,.g=194,.b=140,.a=255};
/* #004D1F*/
constexpr SDL_Color COLOR_HIGHLIGHT = {.r = 0,.g=77,.b=31,.a=255};
/* #002E0A */
constexpr SDL_Color COLOR_BORDER = {.r = 0,.g=46,.b=10,.a=255};
constexpr SDL_Color COLOR_BORDERMUTED = {.r = 0,.g=20,.b=4,.a=255};
constexpr SDL_Color COLOR_PRIMARY = {.r = 79,.g=207,.b=109,.a=255};
class BigScreenWindow;
enum class EventResult {
Ignored,
Handled,
ParentDo
};
enum class LastDirection {
North,
South,
East,
West
};
class Widget {
public:
std::weak_ptr<Widget> parent;
virtual EventResult Event(SDL_Event& event, SDL_Rect& rect) = 0;
virtual void Draw(SDL_Rect& rect)=0;
virtual std::shared_ptr<BigScreenWindow> GetRoot();
virtual ~Widget() = default;
virtual bool CanFocus();
virtual int MinHeight();
virtual int MinWidth();
};
class VGrid : public Widget, public std::enable_shared_from_this<VGrid>
{
std::vector<std::pair<std::shared_ptr<Widget>, int>> widgets;
public:
void AddChild(std::shared_ptr<Widget> widget, int height);
EventResult Event(SDL_Event& event,SDL_Rect& rect);
void Draw(SDL_Rect& rect);
~VGrid() = default;
int MinWidth();
int MinHeight();
};
class HGrid : public Widget, public std::enable_shared_from_this<HGrid>
{
std::vector<std::pair<std::shared_ptr<Widget>, int>> widgets;
public:
void AddChild(std::shared_ptr<Widget> widget, int width);
EventResult Event(SDL_Event& event,SDL_Rect& rect);
void Draw(SDL_Rect& rect);
~HGrid() = default;
int MinWidth();
int MinHeight();
};
class Text : public Widget
{
private:
std::string text;
SDL_Color color;
public:
Text(std::string text);
Text(std::string text, std::string color);
Text(std::string text, SDL_Color color);
bool CanFocus();
SDL_Color GetColor();
void SetColor(SDL_Color color);
void SetColor(std::string color);
std::string GetText();
void SetText(std::string text);
EventResult Event(SDL_Event& event,SDL_Rect& rect);
void Draw(SDL_Rect& rect);
int MinWidth();
int MinHeight();
};
class Button : public Widget, public std::enable_shared_from_this<Button>
{
private:
std::shared_ptr<Widget> child;
std::function<void(std::shared_ptr<Widget> w)> cb;
SDL_Color color;
public:
Button(std::string text, std::function<void(std::shared_ptr<Widget> parent)> cb);
Button(std::string text, std::string textColor, std::function<void(std::shared_ptr<Widget> parent)> cb);
Button(std::string text, std::string textColor, std::string backColor, std::function<void(std::shared_ptr<Widget> parent)> cb);
Button(std::string text, SDL_Color textColor, std::function<void(std::shared_ptr<Widget> parent)> cb);
Button(std::string text, SDL_Color textColor, SDL_Color backColor, std::function<void(std::shared_ptr<Widget> parent)> cb);
Button(std::shared_ptr<Widget> widget, std::function<void(std::shared_ptr<Widget> parent)> cb);
Button(std::shared_ptr<Widget> widget, std::string backColor, std::function<void(std::shared_ptr<Widget> parent)> cb);
Button(std::shared_ptr<Widget> widget, SDL_Color backColor, std::function<void(std::shared_ptr<Widget> parent)> cb);
void SetBackColor(SDL_Color color);
void SetBackColor(std::string color);
SDL_Color GetBackColor();
void SetWidget(std::shared_ptr<Widget> widget);
std::shared_ptr<Widget> GetWidget();
EventResult Event(SDL_Event& event,SDL_Rect& rect);
void Draw(SDL_Rect& rect);
~Button();
int MinWidth();
int MinHeight();
};
class FontCache
{
std::array<SDL_Texture*,96> font_chrs;
int mw,mh,ps;
void Load(SDL_Renderer* renderer,TTF_Font* font);
public:
FontCache(SDL_Renderer* renderer,TTF_Font* font);
FontCache(SDL_Renderer* renderer,std::string font,int sz);
FontCache(SDL_Renderer* renderer,const uint8_t* mem,size_t cnt,int sz);
FontCache(SDL_Renderer* renderer,const std::vector<uint8_t>& v,int sz);
FontCache(SDL_Renderer* renderer,int sz);
SDL_Texture* operator[](char c);
SDL_Texture* GetCharOfColor(char c, const SDL_Color& color);
int MaxWidth();
int MaxHeight();
int PointSize();
void CalculateSize(std::string text, int& x,int& y);
void Render(SDL_Renderer* renderer,int x,int y, std::string text, const SDL_Color& color);
~FontCache();
};
bool TryParseSDLColor(std::string str, SDL_Color& col);
class BigScreenWindow : public Widget, public std::enable_shared_from_this<BigScreenWindow> {
SDL_Window* window;
SDL_Renderer* renderer;
std::shared_ptr<Widget> page;
bool running=true;
Widget* current = nullptr;
std::shared_ptr<FontCache> fc;
SDL_Color color=COLOR_BGLIGHT;
public:
std::shared_ptr<FontCache> GetFont();
LastDirection dir=LastDirection::South;
void SetCurrent(Widget* widget);
bool IsCurrent(Widget* widget);
BigScreenWindow();
SDL_Window* GetWindow();
SDL_Renderer* GetRenderer();
EventResult Event(SDL_Event& event, SDL_Rect& rect);
void Draw(SDL_Rect& rect);
void Run();
~BigScreenWindow();
void SetWidget(std::shared_ptr<Widget> widget);
void DrawRectThick(SDL_Rect rect, int sz);
std::shared_ptr<BigScreenWindow> GetRoot();
void SetBackColor(SDL_Color color);
void SetBackColor(std::string color);
};
class VideoPlayerWidget : public Widget
{
private:
mpv_handle *mpv;
mpv_render_context *mpv_rd;
SDL_Texture* tex=NULL;
int tex_w = -1, tex_h = -1;
public:
mpv_handle* GetMPVHandle();
VideoPlayerWidget();
EventResult Event(SDL_Event& event,SDL_Rect& rect);
void Draw(SDL_Rect& rect);
void LoadFile(std::string file);
~VideoPlayerWidget();
};
class Clipper {
SDL_Rect theRect;
SDL_Renderer* renderer;
bool isClipped;
public:
Clipper(SDL_Renderer* renderer, SDL_Rect& myRect);
bool Clip(SDL_Rect rect);
~Clipper();
static void ClipRect(SDL_Rect& child, SDL_Rect& parent);
};
}