Smallcase folders part 1

This commit is contained in:
2025-12-29 13:39:40 +00:00
parent ae48f96fe8
commit 8bef59f793
84 changed files with 40 additions and 35 deletions
+7
View File
@@ -0,0 +1,7 @@
message(STATUS "··Configuring UI")
add_subdirectory(bar)
add_subdirectory(text)
add_subdirectory(header)
add_subdirectory(hostblock)
add_subdirectory(theme)
+61
View File
@@ -0,0 +1,61 @@
#include "Display/UI/Bar/Bar.h"
#include <algorithm>
namespace display::ui::bar
{
Bar::Bar(int width, int height, Orientation orientation, Style style)
: width(width), height(height), orientation(orientation), style(style)
{
}
void Bar::draw(display::graphics::Framebuffer &framebuffer, int x, int y, float value)
{
value = std::clamp(value, 0.0f, 1.0f);
// 1. Рисуем фон
framebuffer.fillRect(x, y, width, height, style.background);
// 2. Рисуем заполнение
display::graphics::Color fillColor = valueToColor(value);
if (orientation == Orientation::Horizontal)
{
int fillWidth = static_cast<int>(width * value);
framebuffer.fillRect(x, y, fillWidth, height, fillColor);
}
else // Vertical
{
int fillHeight = static_cast<int>(height * value);
framebuffer.fillRect(x, y + (height - fillHeight), width, fillHeight, fillColor);
}
// 3. Рисуем рамку
if (style.drawBorder)
{
// можно добавить метод drawRect в Framebuffer
framebuffer.drawRect(x, y, width, height, style.border);
}
}
display::graphics::Color Bar::valueToColor(float value)
{
value = std::clamp(value, 0.0f, 1.0f);
if (value <= 0.5f)
{
float t = value / 0.5f;
return display::graphics::Color{
static_cast<uint8_t>(t * 255), // R: 0 → 255
180, // G: остаётся 180
0 // B
};
}
else
{
float t = (value - 0.5f) / 0.5f;
return display::graphics::Color{
255, // R: остаётся 255
static_cast<uint8_t>(180 * (1.0f - t)), // G: 180 → 0
0};
}
}
} // namespace display::ui::bar
+26
View File
@@ -0,0 +1,26 @@
#pragma once
#include "Display/Graphics/Framebuffer.h"
#include "Display/Graphics/Color.h"
#include "Display/UI/Bar/Orientation.h"
#include "Display/UI/Bar/Style.h"
namespace display::ui::bar
{
class Bar
{
public:
Bar(int width, int height, Orientation orientation = Orientation::Horizontal, Style style = {});
void draw(display::graphics::Framebuffer &framebuffer,
int x, int y,
float value); // 0.0 .. 1.0
private:
int width;
int height;
Orientation orientation;
Style style;
display::graphics::Color valueToColor(float value);
};
} // namespace display::ui::bar
+17
View File
@@ -0,0 +1,17 @@
message(STATUS "···Configuring Bar")
add_library(DisplayUIBar
Bar.cpp
)
add_library(display::ui::Bar ALIAS DisplayUIBar)
target_link_libraries(DisplayUIBar
PUBLIC
Display::Graphics
)
target_include_directories(DisplayUIBar
PUBLIC
${INCLUDE_BASE_DIR}
)
+10
View File
@@ -0,0 +1,10 @@
#pragma once
namespace display::ui::bar
{
enum class Orientation
{
Horizontal,
Vertical
};
} // namespace display::ui::bar
+27
View File
@@ -0,0 +1,27 @@
#pragma once
#include "Display/Graphics/Color.h"
#include "Display/UI/Theme/Theme.h"
namespace display::ui::bar
{
struct Style
{
display::graphics::Color background;
display::graphics::Color fill;
display::graphics::Color border;
bool drawBorder;
Style(
display::graphics::Color background = display::ui::theme::bar::BACKGROUND,
display::graphics::Color fill = display::ui::theme::bar::FILL,
display::graphics::Color border = display::ui::theme::bar::BORDER,
bool drawBorder = true)
: background(background),
fill(fill),
border(border),
drawBorder(true)
{
}
};
} // namespace display::ui::bar
+18
View File
@@ -0,0 +1,18 @@
message(STATUS "···Configuring Header")
add_library(DisplayUIHeader
Header.cpp
)
add_library(display::ui::Header ALIAS DisplayUIHeader)
target_link_libraries(DisplayUIHeader
PUBLIC
Display::Graphics
display::ui::Text
)
target_include_directories(DisplayUIHeader
PUBLIC
${INCLUDE_BASE_DIR}
)
+58
View File
@@ -0,0 +1,58 @@
#include "Display/UI/Header/Header.h"
#include <algorithm>
#include <chrono>
#include <ctime>
#include <iomanip>
#include <sstream>
#include "Display/UI/Bar/Orientation.h"
#include "Display/UI/Bar/Style.h"
#include "Display/UI/Theme/Theme.h"
#include "Display/Graphics/Color.h"
namespace display::ui::header
{
Header::Header()
{
}
void Header::draw(
display::graphics::Framebuffer &fb,
display::ui::text::Renderer &text,
int x, int y)
{
// ===== Block background =====
fb.fillRect(x, y, HEADER_WIDTH, HEADER_HEIGHT, display::ui::theme::header::BACKGROUND);
fb.drawRect(x, y, HEADER_WIDTH, HEADER_HEIGHT, display::ui::theme::header::BORDER);
int cursorY = y + PADDING;
text.drawTextOutlined(
fb,
x + PADDING + 120 - 2,
cursorY + 8,
getCurrentDateTime(),
display::ui::theme::text::TEXT,
display::ui::theme::text::OUTLINE,
display::ui::text::Font{std::string(HEADER_FONT_NAME.begin(), HEADER_FONT_NAME.end()), HEADER_FONT_SIZE});
}
std::string Header::getCurrentDateTime()
{
auto now = std::chrono::system_clock::now();
std::time_t t = std::chrono::system_clock::to_time_t(now);
std::tm tm{};
localtime_r(&t, &tm);
std::ostringstream oss;
oss << std::setfill('0')
<< std::setw(2) << tm.tm_mday << '/'
<< std::setw(2) << tm.tm_mon + 1 << '/'
<< tm.tm_year + 1900 << ' '
<< std::setw(2) << tm.tm_hour << ':'
<< std::setw(2) << tm.tm_min << ':'
<< std::setw(2) << tm.tm_sec;
return oss.str();
}
}
+36
View File
@@ -0,0 +1,36 @@
#pragma once
#include <string>
#include <vector>
#include "Display/Graphics/Framebuffer.h"
#include "Display/Graphics/Color.h"
#include "Display/UI/Text/Renderer.h"
namespace display::ui::header
{
// ===== Layout =====
constexpr int HEADER_WIDTH = 240; // 116
constexpr int HEADER_HEIGHT = 16; // 116
constexpr int PADDING = 4; // 4
constexpr std::string_view HEADER_FONT_NAME = "Pixel10";
constexpr int HEADER_FONT_SIZE = 14; // 12
class Header
{
public:
Header();
static constexpr int width() { return HEADER_WIDTH; }
static constexpr int height() { return HEADER_HEIGHT; }
void draw(
display::graphics::Framebuffer &fb,
display::ui::text::Renderer &text,
int x, int y);
private:
std::string getCurrentDateTime();
};
}
+19
View File
@@ -0,0 +1,19 @@
message(STATUS "···Configuring HostBlock")
add_library(DisplayUIHostBlock
HostBlock.cpp
)
add_library(display::ui::HostBlock ALIAS DisplayUIHostBlock)
target_link_libraries(DisplayUIHostBlock
PUBLIC
Display::Graphics
display::ui::Text
display::ui::Bar
)
target_include_directories(DisplayUIHostBlock
PUBLIC
${INCLUDE_BASE_DIR}
)
+146
View File
@@ -0,0 +1,146 @@
#include "Display/UI/HostBlock/HostBlock.h"
#include <algorithm>
#include "Display/UI/Bar/Orientation.h"
#include "Display/UI/Bar/Style.h"
#include "Display/UI/Theme/Theme.h"
#include "Display/Graphics/Color.h"
#include "Display/UI/Text/Helpers.h"
namespace display::ui::hostblock
{
HostBlock::HostBlock()
: cpuBar(
CPU_BAR_WIDTH,
CPU_BAR_HEIGHT,
display::ui::bar::Orientation::Vertical,
display::ui::bar::Style{display::graphics::Color{40, 40, 40}, display::graphics::Color{0, 180, 0}, display::graphics::Color{80, 80, 80}, true}),
memBar(
BLOCK_WIDTH - PADDING * 2,
MEM_BAR_HEIGHT,
display::ui::bar::Orientation::Horizontal,
display::ui::bar::Style{display::graphics::Color{40, 40, 40}, display::graphics::Color{0, 120, 200}, display::graphics::Color{80, 80, 80}, true})
{
}
void HostBlock::draw(
display::graphics::Framebuffer &fb,
display::ui::text::Renderer &text,
int x, int y,
const std::string &hostname,
const metrics::Host &metrics)
{
// ===== Block background =====
fb.fillRect(x, y, BLOCK_WIDTH, BLOCK_HEIGHT, display::ui::theme::hostblock::BACKGROUND);
fb.drawRect(x, y, BLOCK_WIDTH, BLOCK_HEIGHT, display::ui::theme::hostblock::BORDER);
int cursorY = y + PADDING;
// ===== Header =====
fb.fillRect(
x + PADDING,
cursorY,
BLOCK_WIDTH - PADDING * 2,
HEADER_HEIGHT,
display::ui::theme::hostblock::HEADER);
text.drawTextOutlined(
fb,
x + PADDING + 2,
cursorY + HEADER_HEIGHT - 3,
hostname,
display::ui::theme::text::TEXT,
display::ui::theme::text::OUTLINE,
// display::ui::text::Font{"LiberationSans-Regular", HEADER_FONT_SIZE});
// display::ui::text::Font{"PixelFive-Regular", 5});
display::ui::text::Font{std::string(HEADER_FONT_NAME.begin(), HEADER_FONT_NAME.end()), HEADER_FONT_SIZE});
cursorY += HEADER_HEIGHT + SECTION_GAP;
// ===== CPU bars =====
int cpuCount = std::min<int>(metrics.cpu.coreLoads.size(),
CPU_MAX_PER_ROW * CPU_ROWS);
for (int i = 0; i < cpuCount; ++i)
{
int row = i / CPU_MAX_PER_ROW;
int col = i % CPU_MAX_PER_ROW;
int bx = x + PADDING +
col * (CPU_BAR_WIDTH + CPU_BAR_GAP);
int by = cursorY +
row * (CPU_BAR_HEIGHT + CPU_BAR_GAP);
float value = std::clamp(metrics.cpu.coreLoads[i] / 100.0f, 0.0f, 1.0f);
cpuBar.draw(fb, bx, by, value);
}
cursorY += CPU_ROWS * CPU_BAR_HEIGHT +
(CPU_ROWS - 1) * CPU_BAR_GAP +
SECTION_GAP;
// ===== Memory bar =====
float memValue, swapValue = 0.0f;
if (metrics.memory.mem_total > 0)
memValue = metrics.memory.mem_used / metrics.memory.mem_total;
memBar.draw(
fb,
x + PADDING,
cursorY,
std::clamp(memValue, 0.0f, 1.0f));
text.drawTextOutlined(fb,
x + MEM_BAR_TEXT_PADDING_X,
cursorY + 8,
"M: " + display::ui::text::formatFloat(metrics.memory.mem_used / 1073741824) + "/" + display::ui::text::formatFloat(metrics.memory.mem_total / 1073741824),
display::ui::theme::text::TEXT,
display::ui::theme::text::OUTLINE,
display::ui::text::Font{"PixelFive-Regular", 5});
cursorY += MEM_BAR_HEIGHT + SECTION_GAP;
if (metrics.memory.swap_total > 0)
{
swapValue = metrics.memory.swap_used / metrics.memory.swap_total;
memBar.draw(
fb,
x + PADDING,
cursorY,
std::clamp(swapValue, 0.0f, 1.0f));
text.drawTextOutlined(fb,
x + MEM_BAR_TEXT_PADDING_X,
cursorY + 8,
"S: " + display::ui::text::formatFloat(metrics.memory.swap_used / 1073741824) + "/" + display::ui::text::formatFloat(metrics.memory.swap_total / 1073741824),
display::ui::theme::text::TEXT,
display::ui::theme::text::OUTLINE,
display::ui::text::Font{"PixelFive-Regular", 5});
cursorY += MEM_BAR_HEIGHT + SECTION_GAP;
}
// ===== Disk bar =====
int diskCount = metrics.disks.size();
for (int i = 0; i < diskCount; ++i)
{
int by = cursorY +
i * (MEM_BAR_HEIGHT + SECTION_GAP);
float value = std::clamp(metrics.disks[i].used / metrics.disks[i].total, 0.0f, 1.0f);
memBar.draw(fb, x + PADDING, by, value);
text.drawTextOutlined(fb,
x + MEM_BAR_TEXT_PADDING_X,
by + 8,
metrics.disks[i].name + ": " + display::ui::text::formatFloat(metrics.disks[i].used / 1073741824) + "/" + display::ui::text::formatFloat(metrics.disks[i].total / 1073741824),
display::ui::theme::text::TEXT,
display::ui::theme::text::OUTLINE,
display::ui::text::Font{"PixelFive-Regular", 5});
}
}
}
+54
View File
@@ -0,0 +1,54 @@
#pragma once
#include <string>
#include <vector>
#include "Display/Graphics/Framebuffer.h"
#include "Display/Graphics/Color.h"
#include "Display/UI/Text/Renderer.h"
#include "Display/UI/Bar/Bar.h"
#include "Metrics/Host.h"
namespace display::ui::hostblock
{
// ===== Layout =====
constexpr int BLOCK_WIDTH = 118; // 118
constexpr int BLOCK_HEIGHT = 146; // 146
constexpr int PADDING = 5; // 5
constexpr int HEADER_HEIGHT = 12; // 12
constexpr std::string_view HEADER_FONT_NAME = "PixelFive-Regular";
constexpr int HEADER_FONT_SIZE = 5; // 10
constexpr int SECTION_GAP = 4; // 4
// ===== CPU bars =====
constexpr int CPU_BAR_WIDTH = 10; // 10
constexpr int CPU_BAR_GAP = 4; // 4
constexpr int CPU_BAR_HEIGHT = 16; // 16
constexpr int CPU_MAX_PER_ROW = 8; // 8
constexpr int CPU_ROWS = 2; // 2
// ===== Memory bar =====
constexpr int MEM_BAR_HEIGHT = 11; // 8
constexpr int MEM_BAR_TEXT_PADDING_X = PADDING + 3;
class HostBlock
{
public:
HostBlock();
static constexpr int width() { return BLOCK_WIDTH; }
static constexpr int height() { return BLOCK_HEIGHT; }
void draw(
display::graphics::Framebuffer &fb,
display::ui::text::Renderer &text,
int x, int y,
const std::string &hostname,
const metrics::Host &metrics);
private:
display::ui::bar::Bar cpuBar;
display::ui::bar::Bar memBar;
};
}
+26
View File
@@ -0,0 +1,26 @@
message(STATUS "···Configuring Text")
add_library(DisplayUIText
Fonts.cpp
Helpers.cpp
Renderer.cpp
)
add_library(display::ui::Text ALIAS DisplayUIText)
find_package(Freetype REQUIRED)
target_link_libraries(DisplayUIText
PRIVATE
Display::Graphics
Helpers::All
${FREETYPE_LIBRARIES}
)
# include-root общий
target_include_directories(DisplayUIText
PUBLIC
${INCLUDE_BASE_DIR}
${FREETYPE_INCLUDE_DIRS}
)
+24
View File
@@ -0,0 +1,24 @@
#pragma once
#include <string>
namespace display::ui::text
{
struct Font
{
std::string name;
int size; // размер шрифта
bool operator==(const Font &other) const
{
return name == other.name && size == other.size;
}
};
struct FontHash
{
std::size_t operator()(const Font &k) const
{
return std::hash<std::string>()(k.name) ^ std::hash<int>()(k.size);
}
};
} // namespace display::ui::text
+119
View File
@@ -0,0 +1,119 @@
#include "Display/UI/Text/Fonts.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#include <stdexcept>
#include <iostream>
#include <filesystem>
#include "Helpers/Paths.h"
namespace display::ui::text
{
struct Fonts::Library
{
FT_Library library = nullptr;
};
struct Fonts::Face
{
FT_Face face = nullptr;
};
Fonts::Fonts()
: library(std::make_unique<Library>())
{
if (FT_Init_FreeType(&library->library))
throw std::runtime_error("FT_Init_FreeType failed");
loadAllFonts();
}
Fonts::~Fonts()
{
for (auto &[k, v] : fonts)
if (v->face)
FT_Done_Face(v->face);
if (library->library)
FT_Done_FreeType(library->library);
}
void Fonts::loadAllFonts()
{
loadFonts("/usr/share/fonts/truetype");
loadFonts(helpers::initPaths().exeDir);
}
void Fonts::loadFonts(const std::string &path)
{
if (std::filesystem::exists(path))
{
for (auto &p : std::filesystem::recursive_directory_iterator(path))
{
if (p.path().extension() == ".ttf" || p.path().extension() == ".otf")
{
std::string path = p.path().string();
std::string filename = p.path().stem().string();
// Можно сразу создавать Fonts для стандартных размеров, например: 10,12,14,16,18,24
for (int sz : {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 24, 36, 72})
{
Font key{filename, sz};
std::unique_ptr<Face> face = std::make_unique<Face>();
if (FT_New_Face(library->library, path.c_str(), 0, &face->face))
throw std::runtime_error("FT_New_Face failed");
FT_Set_Pixel_Sizes(face->face, 0, sz);
fonts.emplace(key, std::move(face));
}
}
}
}
}
const Glyph &Fonts::getGlyph(char ch, const Font &font)
{
GlyphKey key{ch, font};
auto gph = glyphs.find(key);
if (gph != glyphs.end())
return gph->second;
auto fnt = fonts.find(font);
if (fnt == fonts.end())
{
// Если нет, можно использовать какой-нибудь дефолтный шрифт
fnt = fonts.begin();
}
FT_Face face = fnt->second->face;
if (!face)
throw std::runtime_error("Fonts not initialized!");
if (FT_Load_Char(face, ch, FT_LOAD_RENDER | FT_LOAD_TARGET_MONO))
throw std::runtime_error("FT_Load_Char failed");
FT_GlyphSlot g = face->glyph;
Glyph glyph;
glyph.width = g->bitmap.width;
glyph.height = g->bitmap.rows;
glyph.bearingX = g->bitmap_left;
glyph.bearingY = g->bitmap_top;
glyph.advance = g->advance.x >> 6;
// glyph.buffer.assign(g->bitmap.buffer, g->bitmap.buffer + g->bitmap.width * g->bitmap.rows);
glyph.buffer.resize(glyph.width * glyph.height, 0);
const FT_Bitmap &bm = g->bitmap;
for (int y = 0; y < bm.rows; ++y)
{
for (int x = 0; x < bm.width; ++x)
{
int byteIndex = y * bm.pitch + x / 8;
int bitIndex = 7 - (x % 8);
uint8_t bit = (bm.buffer[byteIndex] >> bitIndex) & 1;
glyph.buffer[y * bm.width + x] = bit ? 255 : 0;
}
}
return glyphs.emplace(key, std::move(glyph)).first->second;
}
} // namespace display::ui::text
+28
View File
@@ -0,0 +1,28 @@
#pragma once
#include <memory>
#include <string>
#include <unordered_map>
#include "Display/UI/Text/Font.h"
#include "Display/UI/Text/Glyph.h"
#include "Display/UI/Text/GlyphKey.h"
namespace display::ui::text
{
class Fonts
{
public:
Fonts();
~Fonts();
const Glyph &getGlyph(char ch, const Font &key);
private:
struct Library;
struct Face;
std::unique_ptr<Library> library;
std::unordered_map<Font, std::unique_ptr<Face>, FontHash> fonts;
std::unordered_map<GlyphKey, Glyph, GlyphKeyHash> glyphs;
void loadAllFonts();
void loadFonts(const std::string &path);
};
} // namespace display::ui::text
+15
View File
@@ -0,0 +1,15 @@
#include <cstdint>
#include <vector>
namespace display::ui::text
{
struct Glyph
{
int width;
int height;
int bearingX;
int bearingY;
int advance;
std::vector<uint8_t> buffer; // grayscale bitmap
};
} // namespace display::ui::text
+28
View File
@@ -0,0 +1,28 @@
#pragma once
#include <string>
#include "Font.h"
namespace display::ui::text
{
struct GlyphKey
{
char ch;
Font font;
bool operator==(const GlyphKey &other) const
{
return ch == other.ch && font == other.font;
}
};
struct GlyphKeyHash
{
std::size_t operator()(const GlyphKey &k) const
{
std::size_t h1 = std::hash<char>()(k.ch);
std::size_t h2 = FontHash{}(k.font);
return h1 ^ (h2 << 1);
}
};
} // namespace display::ui::text
+20
View File
@@ -0,0 +1,20 @@
#include "Display/UI/Text/Helpers.h"
#include <cstdio>
namespace display::ui::text
{
std::string formatFloat(float value, int decimals)
{
char buffer[64];
std::snprintf(buffer, sizeof(buffer), "%.*f", decimals, value);
return std::string(buffer);
}
std::string formatDouble(double value, int decimals)
{
char buffer[64];
std::snprintf(buffer, sizeof(buffer), "%.*f", decimals, value);
return std::string(buffer);
}
} // namespace display::ui::text
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#include <string>
namespace display::ui::text
{
std::string formatFloat(float value, int decimals = 1);
std::string formatDouble(double value, int decimals = 1);
} // namespace display::ui::text
+86
View File
@@ -0,0 +1,86 @@
#include "Display/UI/Text/Renderer.h"
#include "Display/UI/Text/UTFDecoder.h"
#include <iostream>
namespace display::ui::text
{
void Renderer::drawText(display::graphics::Framebuffer &fb, int x, int y,
const std::string &text, const display::graphics::Color &color, const Font &font)
{
int penX = x;
int baseline = y;
for (char ch : text)
{
const Glyph &g = fonts.getGlyph(ch, font);
for (int row = 0; row < g.height; ++row)
{
int py = baseline - g.bearingY + row;
for (int col = 0; col < g.width; ++col)
{
int px = penX + col + g.bearingX;
uint8_t alpha = g.buffer[row * g.width + col];
if (!alpha)
continue;
display::graphics::Color bg = fb.getPixel(px, py);
display::graphics::Color out;
out.r = (alpha * color.r + (255 - alpha) * bg.r) / 255;
out.g = (alpha * color.g + (255 - alpha) * bg.g) / 255;
out.b = (alpha * color.b + (255 - alpha) * bg.b) / 255;
fb.setPixel(px, py, out);
}
}
penX += g.advance;
}
}
void Renderer::drawTextOutlined(display::graphics::Framebuffer &fb,
int x, int y,
const std::string &text,
const display::graphics::Color &colorText,
const display::graphics::Color &colorOutline,
const Font &font)
{
// outline
for (int dx = -1; dx <= 1; ++dx)
for (int dy = -1; dy <= 1; ++dy)
if (dx != 0 || dy != 0)
drawText(fb, x + dx, y + dy, text, colorOutline, font);
// main text
drawText(fb, x, y, text, colorText, font);
}
/* int Renderer::measureWidth(const std::string &text)
{
int width = 0;
for (char ch : text)
{
const Glyph &g = glyphCache.getGlyph(ch, face);
width += g.advance;
}
return width;
}
int Renderer::measureHeight(const std::string &text)
{
int height = 0;
for (char ch : text)
{
const Glyph &g = glyphCache.getGlyph(ch, face);
int glyphHeight = g.height - g.bearingY + g.bearingY; // можно уточнить по высоте глифа
if (glyphHeight > height)
height = glyphHeight;
}
return height;
}
*/
} // namespace display::ui::text
+27
View File
@@ -0,0 +1,27 @@
#pragma once
#include "Display/Graphics/Framebuffer.h"
#include "Display/UI/Text/Fonts.h"
#include "Display/UI/Text/Font.h"
#include "Display/Graphics/Color.h"
#include <string>
#include <unordered_map>
namespace display::ui::text
{
class Renderer
{
public:
void drawText(display::graphics::Framebuffer &fb, int x, int y, const std::string &text, const display::graphics::Color &color = display::graphics::Color{255, 255, 255}, const Font &font = {"LiberationSans-Regular", 12});
void drawTextOutlined(display::graphics::Framebuffer &fb, int x, int y, const std::string &text, const display::graphics::Color &colorText = display::graphics::Color{255, 255, 255}, const display::graphics::Color &colorOutline = display::graphics::Color{0, 0, 0}, const Font &font = {"LiberationSans-Regular", 12});
// int measureWidth(const std::string &text);
// int measureHeight(const std::string &text);
private:
Fonts fonts;
};
} // namespace display::ui::text
+39
View File
@@ -0,0 +1,39 @@
#pragma once
#include <string_view>
#include <cstdint>
namespace display::ui::text
{
inline bool utf8Next(std::string_view &s, uint32_t &codepoint)
{
if (s.empty())
return false;
uint8_t c = s[0];
if ((c & 0x80) == 0)
{
codepoint = c;
s.remove_prefix(1);
}
else if ((c & 0xE0) == 0xC0)
{
codepoint = ((c & 0x1F) << 6) | (s[1] & 0x3F);
s.remove_prefix(2);
}
else if ((c & 0xF0) == 0xE0)
{
codepoint = ((c & 0x0F) << 12) |
((s[1] & 0x3F) << 6) |
(s[2] & 0x3F);
s.remove_prefix(3);
}
else
{
return false;
}
return true;
}
} // namespace display::ui::text
+15
View File
@@ -0,0 +1,15 @@
message(STATUS "···Configuring Theme")
add_library(Theme INTERFACE)
add_library(display::ui::Theme ALIAS Theme)
target_link_libraries(Theme
INTERFACE
Display::Graphics
)
target_include_directories(Theme
INTERFACE
${INCLUDE_BASE_DIR}
)
+35
View File
@@ -0,0 +1,35 @@
#pragma once
#include "Display/Graphics/Color.h"
namespace display::ui::theme
{
namespace text
{
const display::graphics::Color TEXT{220, 220, 220};
const display::graphics::Color OUTLINE{20, 20, 20};
} // namespace text
namespace header
{
// ===== Header =====
const display::graphics::Color BACKGROUND{20, 20, 20};
const display::graphics::Color BORDER{60, 60, 60};
const display::graphics::Color HEADER{30, 30, 30};
} // namespace header
namespace hostblock
{
// ===== HostBlock =====
const display::graphics::Color BACKGROUND{20, 20, 20};
const display::graphics::Color BORDER{60, 60, 60};
const display::graphics::Color HEADER{30, 30, 30};
} // namespace hostblock
namespace bar
{
const display::graphics::Color BACKGROUND{30, 30, 30};
const display::graphics::Color FILL{0, 180, 0};
const display::graphics::Color BORDER{80, 80, 80};
} // namespace bar
} // namespace display::ui::theme