summaryrefslogtreecommitdiff
path: root/internal/display/hittest.go
blob: 15b1343e06b5e4d5038cb8da0dd94332f571c8a7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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
	barLoad
	barDisk
)

// barDescriptor describes a single bar's position, host, and type.
type barDescriptor struct {
	host     string  // hostname this bar belongs to
	kind     barKind // CPU, mem, net, load, or disk
	cpuName  string  // CPU name (e.g. "cpu", "cpu0"); only set for barCPU
	diskName string  // disk device name (e.g. "sda", "all"); only set for barDisk
	rect     sdl.Rect
}

// iterateBars emits bars in the canonical host/CPU/mem/net/load/disk order.
func iterateBars(snap map[string]*stats.HostStats, state *runState, visit func(h *stats.HostStats, bar barDescriptor)) {
	for _, host := range sortedHosts(snap) {
		h := snap[host]
		if h == nil {
			continue
		}
		for _, name := range sortedCPUNames(h.CPU, state.cpuMode) {
			visit(h, barDescriptor{host: host, kind: barCPU, cpuName: name})
		}
		if state.showMem {
			visit(h, barDescriptor{host: host, kind: barMem})
		}
		if state.showNet {
			visit(h, barDescriptor{host: host, kind: barNet})
		}
		if state.showLoad {
			visit(h, barDescriptor{host: host, kind: barLoad})
		}
		for _, dname := range sortedDiskNames(h.Disk, state.diskMode) {
			visit(h, barDescriptor{host: host, kind: barDisk, diskName: dname})
		}
	}
}

// buildBarMap produces bar descriptors with screen rectangles.
func buildBarMap(snap map[string]*stats.HostStats, cfg *config.Config, state *runState) []barDescriptor {
	numBars := countBars(snap, state.cpuMode, state.showMem, state.showNet, state.showLoad, state.diskMode)
	bars := make([]barDescriptor, 0, numBars)
	barIndex := 0
	iterateBars(snap, state, func(_ *stats.HostStats, bar barDescriptor) {
		x, y, w, bh := barRect(state.winW, state.winH, numBars, cfg.MaxBarsPerRow, barIndex)
		bar.rect = sdl.Rect{X: x, Y: y, W: w, H: bh}
		bars = append(bars, bar)
		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
}