231 lines
10 KiB
C++
231 lines
10 KiB
C++
#include "display/ui/hostblock/HostBlock.h"
|
|
|
|
#include <algorithm>
|
|
#include <chrono>
|
|
|
|
#include "display/ui/bar/Orientation.h"
|
|
#include "display/ui/bar/Style.h"
|
|
#include "display/ui/theme/Theme.h"
|
|
#include "display/ui/text/Helpers.h"
|
|
#include "display/graphics/Color.h"
|
|
|
|
namespace display::ui::hostblock
|
|
{
|
|
HostBlock::HostBlock(config::server::StyleConfig &config)
|
|
: config(config),
|
|
cpuBar(
|
|
config.hostblock.cpu.width,
|
|
config.hostblock.cpu.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}),
|
|
cpuTempBar(
|
|
config.hostblock.cpu.temperature.width,
|
|
config.hostblock.cpu.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(
|
|
config.hostblock.width - config.hostblock.padding * 2,
|
|
config.hostblock.memory.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)
|
|
{
|
|
bool online = std::chrono::high_resolution_clock::now() - metrics.packetTimepoint < std::chrono::seconds(5);
|
|
|
|
// ===== Block background =====
|
|
fb.fillRect(x, y, config.hostblock.width, config.hostblock.height, display::ui::theme::hostblock::BACKGROUND);
|
|
fb.drawRect(x, y, config.hostblock.width, config.hostblock.height, display::ui::theme::hostblock::BORDER);
|
|
|
|
int cursorY = y + config.hostblock.padding;
|
|
|
|
// ===== Header =====
|
|
fb.fillRect(
|
|
x + config.hostblock.padding,
|
|
cursorY,
|
|
config.hostblock.width - config.hostblock.padding * 2,
|
|
config.hostblock.header.height,
|
|
online ? display::ui::theme::hostblock::HEADER : display::graphics::Red());
|
|
|
|
text.drawTextOutlined(
|
|
fb,
|
|
x + config.hostblock.padding + 2,
|
|
cursorY + config.hostblock.header.height - 1,
|
|
hostname,
|
|
display::ui::theme::text::TEXT,
|
|
display::ui::theme::text::OUTLINE,
|
|
display::ui::text::Font{config.hostblock.header.font.name, config.hostblock.header.font.size});
|
|
|
|
cursorY += config.hostblock.header.height + config.hostblock.gap;
|
|
|
|
// ===== CPU bars =====
|
|
int cpuCount = std::min<int>(metrics.cpu.coreLoads.size(),
|
|
config.hostblock.cpu.max_per_row * config.hostblock.cpu.rows);
|
|
|
|
for (int i = 0; i < cpuCount; ++i)
|
|
{
|
|
int row = i / config.hostblock.cpu.max_per_row;
|
|
int col = i % config.hostblock.cpu.max_per_row;
|
|
|
|
int bx = x + config.hostblock.padding +
|
|
col * (config.hostblock.cpu.width + config.hostblock.cpu.temperature.width - 1 + config.hostblock.cpu.gap_h);
|
|
|
|
int by = cursorY +
|
|
row * (config.hostblock.cpu.height + config.hostblock.cpu.gap_v);
|
|
|
|
float value = std::clamp(metrics.cpu.coreLoads[i] / 100.0f, 0.0f, 1.0f);
|
|
|
|
cpuBar.draw(fb, bx, by, value, 0, online);
|
|
|
|
value = std::clamp((metrics.cpu.coreTemps[i].current - config.hostblock.cpu.temperature.min) / ((metrics.cpu.coreTemps[i].max == 0 ? static_cast<float>(config.hostblock.cpu.temperature.max) : metrics.cpu.coreTemps[i].max) - config.hostblock.cpu.temperature.min), 0.0f, 1.0f);
|
|
|
|
cpuTempBar.draw(fb, bx + config.hostblock.cpu.width - 1, by, value, 0, online);
|
|
}
|
|
|
|
cursorY += config.hostblock.cpu.rows * config.hostblock.cpu.height +
|
|
(config.hostblock.cpu.rows - 1) * config.hostblock.cpu.gap_v +
|
|
config.hostblock.gap;
|
|
|
|
// ===== Memory bar =====
|
|
float memValue, swapValue = 0.0f, hugepagesValue = 0.0f;
|
|
if (metrics.memory.memory.total > 0)
|
|
memValue = static_cast<float>(metrics.memory.memory.used) / static_cast<float>(metrics.memory.memory.total);
|
|
if (metrics.memory.hugepages.total > 0)
|
|
hugepagesValue = static_cast<float>(metrics.memory.hugepages.total) / static_cast<float>(metrics.memory.memory.total);
|
|
|
|
memBar.draw(
|
|
fb,
|
|
x + config.hostblock.padding,
|
|
cursorY,
|
|
std::clamp(memValue, 0.0f, 1.0f), std::clamp(hugepagesValue, 0.0f, 1.0f), online);
|
|
text.drawTextOutlined(fb,
|
|
x + config.hostblock.memory.font.padding,
|
|
cursorY + 8,
|
|
"MEM: " + display::ui::text::formatFloat(static_cast<float>(metrics.memory.memory.used) / 1073741824) + "/" + display::ui::text::formatFloat(static_cast<float>(metrics.memory.memory.total) / 1073741824),
|
|
display::ui::theme::text::TEXT,
|
|
display::ui::theme::text::OUTLINE,
|
|
display::ui::text::Font{config.hostblock.memory.font.name, config.hostblock.memory.font.size});
|
|
|
|
cursorY += config.hostblock.memory.height + config.hostblock.memory.gap;
|
|
|
|
if (metrics.memory.swap.total > 0)
|
|
{
|
|
swapValue = static_cast<float>(metrics.memory.swap.used) / static_cast<float>(metrics.memory.swap.total);
|
|
|
|
memBar.draw(
|
|
fb,
|
|
x + config.hostblock.padding,
|
|
cursorY,
|
|
std::clamp(swapValue, 0.0f, 1.0f), 0, online);
|
|
|
|
text.drawTextOutlined(fb,
|
|
x + config.hostblock.memory.font.padding,
|
|
cursorY + 8,
|
|
"SWP: " + display::ui::text::formatFloat(static_cast<float>(metrics.memory.swap.used) / 1073741824) + "/" + display::ui::text::formatFloat(static_cast<float>(metrics.memory.swap.total) / 1073741824),
|
|
display::ui::theme::text::TEXT,
|
|
display::ui::theme::text::OUTLINE,
|
|
display::ui::text::Font{config.hostblock.memory.font.name, config.hostblock.memory.font.size});
|
|
|
|
cursorY += config.hostblock.memory.height + config.hostblock.gap;
|
|
}
|
|
|
|
// ===== Disk bar =====
|
|
int diskCount = metrics.disks.size();
|
|
|
|
for (int i = 0; i < diskCount; ++i)
|
|
{
|
|
int by = cursorY +
|
|
i * (config.hostblock.disks.height + config.hostblock.disks.gap);
|
|
|
|
float value = std::clamp(static_cast<float>(metrics.disks[i].metrics.used) / metrics.disks[i].metrics.total, 0.0f, 1.0f);
|
|
|
|
memBar.draw(fb, x + config.hostblock.padding, by, value, 0, online);
|
|
text.drawTextOutlined(fb,
|
|
x + config.hostblock.disks.font.padding,
|
|
by + 8,
|
|
"D/" + metrics.disks[i].name + ": " + display::ui::text::formatFloat(static_cast<float>(metrics.disks[i].metrics.used) / 1073741824) + "/" + display::ui::text::formatFloat(static_cast<float>(metrics.disks[i].metrics.total) / 1073741824),
|
|
display::ui::theme::text::TEXT,
|
|
display::ui::theme::text::OUTLINE,
|
|
display::ui::text::Font{config.hostblock.disks.font.name, config.hostblock.disks.font.size});
|
|
}
|
|
|
|
cursorY += diskCount * (config.hostblock.disks.height + config.hostblock.disks.gap);
|
|
|
|
// ===== Network bar =====
|
|
for (const auto &iface : metrics.networks)
|
|
{
|
|
int by = cursorY;
|
|
|
|
float rxNorm = 0.0f;
|
|
float txNorm = 0.0f;
|
|
|
|
if (iface.online)
|
|
{
|
|
if (iface.rxMaxBps > 0)
|
|
rxNorm = std::clamp(static_cast<float>(iface.rxBps / iface.rxMaxBps), 0.0f, 1.0f);
|
|
if (iface.txMaxBps > 0)
|
|
txNorm = std::clamp(static_cast<float>(iface.txBps / iface.txMaxBps), 0.0f, 1.0f);
|
|
}
|
|
|
|
// background bar
|
|
memBar.draw(
|
|
fb,
|
|
x + config.hostblock.padding,
|
|
by,
|
|
0.0f,
|
|
0.0f,
|
|
iface.online && online);
|
|
|
|
int barX = x + config.hostblock.padding;
|
|
int barW = config.hostblock.width - config.hostblock.padding * 2;
|
|
int barH = config.hostblock.networks.height;
|
|
|
|
// RX overlay
|
|
fb.fillRect(
|
|
barX,
|
|
by,
|
|
static_cast<int>(barW * rxNorm),
|
|
barH,
|
|
{0, 180, 0});
|
|
|
|
// TX overlay
|
|
fb.fillRect(
|
|
barX,
|
|
by,
|
|
static_cast<int>(barW * txNorm),
|
|
barH,
|
|
{200, 200, 0});
|
|
|
|
// border
|
|
fb.drawRect(barX, by, barW, barH, display::ui::theme::hostblock::BORDER);
|
|
|
|
// interface name + speeds
|
|
std::string label =
|
|
iface.name + " " +
|
|
display::ui::text::formatSpeed(iface.rxBps) + " ↓ " +
|
|
display::ui::text::formatSpeed(iface.txBps) + " ↑";
|
|
|
|
text.drawTextOutlined(
|
|
fb,
|
|
barX + config.hostblock.networks.font.padding,
|
|
by + barH - 1,
|
|
label,
|
|
display::ui::theme::text::TEXT,
|
|
display::ui::theme::text::OUTLINE,
|
|
display::ui::text::Font{
|
|
config.hostblock.networks.font.name,
|
|
config.hostblock.networks.font.size});
|
|
|
|
cursorY += config.hostblock.networks.height + config.hostblock.networks.gap;
|
|
}
|
|
}
|
|
}
|