diff options
| author | Paul Buetow <paul@buetow.org> | 2026-02-18 09:00:35 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-02-18 09:00:35 +0200 |
| commit | 88f4e239a7521112a4db8c7842e3a05db4446cd4 (patch) | |
| tree | 8c331f9f2e23ad9c9319d6dc8275205b23ce811a /internal/display/hittest.go | |
| parent | 11204092b5ab5dc0f71515adfcaa6f07111363e5 (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.go | 82 |
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 +} |
