summaryrefslogtreecommitdiff
path: root/internal/display/hittest.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-02-18 09:00:35 +0200
committerPaul Buetow <paul@buetow.org>2026-02-18 09:00:35 +0200
commit88f4e239a7521112a4db8c7842e3a05db4446cd4 (patch)
tree8c331f9f2e23ad9c9319d6dc8275205b23ce811a /internal/display/hittest.go
parent11204092b5ab5dc0f71515adfcaa6f07111363e5 (diff)
feat: triple-toggle CPU display mode via 1 key; add tooltip, font, hit-test
CPU display now cycles through three states with each press of 1: 0 = CPUModeAverage – aggregate bar only (default) 1 = CPUModeCores – individual core bars + aggregate 2 = CPUModeOff – all CPU bars hidden Config file stores cpumode=N (integer); old showcores=0/1 is read for backward compatibility. CLI flag --showcores replaced by --cpumode. Other improvements landed in this commit: - internal/display: add font.go (text rendering), hittest.go (bar hit testing), tooltip.go (mouse-over tooltip), tooltip_test.go - internal/display: mouse tracking and drawOverlay hook in display.go - internal/display: update build tags to //go:build form - internal/collector: embed remote script via script_embed.go / scriptdata/loadbars-remote.sh - internal/collector: CPULine.Total() changed to value receiver - internal/collector: table test improvements (name field, t.Run) - internal/constants: BytesPerSec consts promoted from var to const - Magefile.go: fix error formatting and install path Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/display/hittest.go')
-rw-r--r--internal/display/hittest.go82
1 files changed, 82 insertions, 0 deletions
diff --git a/internal/display/hittest.go b/internal/display/hittest.go
new file mode 100644
index 0000000..fe88471
--- /dev/null
+++ b/internal/display/hittest.go
@@ -0,0 +1,82 @@
+package display
+
+import (
+ "codeberg.org/snonux/loadbars/internal/config"
+ "codeberg.org/snonux/loadbars/internal/stats"
+ "github.com/veandco/go-sdl2/sdl"
+)
+
+// barKind identifies what type of data a bar represents.
+type barKind int
+
+const (
+ barCPU barKind = iota
+ barMem
+ barNet
+)
+
+// barDescriptor describes a single bar's position, host, and type.
+type barDescriptor struct {
+ host string // hostname this bar belongs to
+ kind barKind // CPU, mem, or net
+ cpuName string // CPU name (e.g. "cpu", "cpu0"); only set for barCPU
+ rect sdl.Rect
+}
+
+// buildBarMap replays the same host/bar iteration as drawBars to produce
+// a slice of bar descriptors with their screen rectangles.
+func buildBarMap(snap map[string]*stats.HostStats, cfg *config.Config, state *runState) []barDescriptor {
+ numBars := countBars(snap, state.cpuMode, state.showMem, state.showNet)
+ maxPerRow := cfg.MaxBarsPerRow
+ hosts := sortedHosts(snap)
+
+ bars := make([]barDescriptor, 0, numBars)
+ barIndex := 0
+ for _, host := range hosts {
+ h := snap[host]
+ if h == nil {
+ continue
+ }
+ cpuNames := sortedCPUNames(h.CPU, state.cpuMode)
+ for _, name := range cpuNames {
+ x, y, w, bh := barRect(state.winW, state.winH, numBars, maxPerRow, barIndex)
+ bars = append(bars, barDescriptor{
+ host: host,
+ kind: barCPU,
+ cpuName: name,
+ rect: sdl.Rect{X: x, Y: y, W: w, H: bh},
+ })
+ barIndex++
+ }
+ if state.showMem {
+ x, y, w, bh := barRect(state.winW, state.winH, numBars, maxPerRow, barIndex)
+ bars = append(bars, barDescriptor{
+ host: host,
+ kind: barMem,
+ rect: sdl.Rect{X: x, Y: y, W: w, H: bh},
+ })
+ barIndex++
+ }
+ if state.showNet {
+ x, y, w, bh := barRect(state.winW, state.winH, numBars, maxPerRow, barIndex)
+ bars = append(bars, barDescriptor{
+ host: host,
+ kind: barNet,
+ rect: sdl.Rect{X: x, Y: y, W: w, H: bh},
+ })
+ barIndex++
+ }
+ }
+ return bars
+}
+
+// hitTest returns the bar descriptor under the given point, or nil if none.
+func hitTest(bars []barDescriptor, mx, my int32) *barDescriptor {
+ for i := range bars {
+ r := &bars[i].rect
+ if mx >= r.X && mx < r.X+r.W && my >= r.Y && my < r.Y+r.H {
+ return &bars[i]
+ }
+ }
+ return nil
+}