summaryrefslogtreecommitdiff
path: root/internal/display/hittest.go
blob: fd2a218c03e42fedc9f0639210046da517a3301c (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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
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
)

// 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, state.showLoad)
	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++
		}
		if state.showLoad {
			x, y, w, bh := barRect(state.winW, state.winH, numBars, maxPerRow, barIndex)
			bars = append(bars, barDescriptor{
				host: host,
				kind: barLoad,
				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
}