Features: - Beautiful system statistics display using IBM Plex Mono font - Direct framebuffer rendering without X11/Wayland - Multiple screens with automatic carousel rotation - Real-time system monitoring (CPU, memory, disk, network, processes) - Systemd service integration with install command - Clean architecture using uber/fx dependency injection Architecture: - Cobra CLI with daemon, install, status, and info commands - Modular design with separate packages for display, rendering, and stats - Font embedding for zero runtime dependencies - Layout API for clean text rendering - Support for multiple screen types (overview, top CPU, top memory) Technical details: - Uses gopsutil for cross-platform system stats collection - Direct Linux framebuffer access via memory mapping - Anti-aliased text rendering with freetype - Configurable screen rotation and update intervals - Structured logging with slog - Comprehensive test coverage and linting setup This initial version provides a solid foundation for displaying rich system information on resource-constrained devices like Raspberry Pis.
52 lines
1.1 KiB
Go
52 lines
1.1 KiB
Go
package renderer
|
|
|
|
import (
|
|
"image"
|
|
"log/slog"
|
|
|
|
"git.eeqj.de/sneak/hdmistat/internal/layout"
|
|
"git.eeqj.de/sneak/hdmistat/internal/statcollector"
|
|
"github.com/golang/freetype/truetype"
|
|
)
|
|
|
|
// Screen represents a displayable screen
|
|
type Screen interface {
|
|
Name() string
|
|
Render(canvas *layout.Canvas, info *statcollector.SystemInfo) error
|
|
}
|
|
|
|
// Renderer manages screen rendering
|
|
type Renderer struct {
|
|
font *truetype.Font
|
|
logger *slog.Logger
|
|
width int
|
|
height int
|
|
}
|
|
|
|
// NewRenderer creates a new renderer
|
|
func NewRenderer(font *truetype.Font, logger *slog.Logger) *Renderer {
|
|
return &Renderer{
|
|
font: font,
|
|
logger: logger,
|
|
width: 1920, // Default HD resolution
|
|
height: 1080,
|
|
}
|
|
}
|
|
|
|
// SetResolution sets the rendering resolution
|
|
func (r *Renderer) SetResolution(width, height int) {
|
|
r.width = width
|
|
r.height = height
|
|
}
|
|
|
|
// RenderScreen renders a screen to an image
|
|
func (r *Renderer) RenderScreen(screen Screen, info *statcollector.SystemInfo) (*image.RGBA, error) {
|
|
canvas := layout.NewCanvas(r.width, r.height, r.font, r.logger)
|
|
|
|
if err := screen.Render(canvas, info); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return canvas.Image(), nil
|
|
}
|