1package vulkan
2
3import (
4 "image"
5
6 "github.com/bnema/neferwl/internal/ports"
7)
8
9func (w *sceneWalk) positionHint() {
10 h := w.s.PositionHint
11 if !h.Shown() {
12 return
13 }
14 b := h.Bounds(w.s.OutputWidth, w.s.OutputHeight)
15 alpha := w.alpha
16 w.alpha = h.Opacity * 0.8
17 w.hintRound(w.physRect(b.X, b.Y, b.W, b.H), w.phys(ports.PositionHintRadius), [3]uint8{30, 30, 38})
18 // The active dot is white, opaque and larger, whatever border.active is:
19 // a grey accent must not blend it into the other dots of its column.
20 for col := range min(int(h.Columns), ports.PositionHintMaxColumns) {
21 for row := range min(int(h.Counts[col]), ports.PositionHintMaxRows) {
22 color, opacity, d := [3]uint8{190, 190, 200}, float32(0.2), ports.PositionHintDiameter
23 if !h.Vertical && col == int(h.ActiveCol) {
24 opacity = 0.45
25 }
26 if col == int(h.ActiveCol) && row == int(h.ActiveRow) {
27 color, opacity, d = [3]uint8{255, 255, 255}, 1, ports.PositionHintActiveDiameter
28 }
29 w.alpha = h.Opacity * opacity
30 // Every dot is centered in its PositionHintDiameter cell.
31 inset := (ports.PositionHintDiameter - d) / 2
32 x := b.X + ports.PositionHintPadding + col*(ports.PositionHintDiameter+ports.PositionHintGap) + inset
33 y := b.Y + ports.PositionHintPadding + row*(ports.PositionHintDiameter+ports.PositionHintGap) + inset
34 w.hintRound(w.physRect(x, y, d, d), w.phys(d)/2, color)
35 }
36 }
37 w.alpha = alpha
38}
39
40// hintRound draws one rounded quad (SDF in the shader), so the pill and each
41// dot cost a single draw whatever the scale. Fills are one translucent draw,
42// so alpha stays exact.
43func (w *sceneWalk) hintRound(r image.Rectangle, radius int, color [3]uint8) {
44 radius = min(radius, r.Dx()/2, r.Dy()/2)
45 w.fillRounded(r, color, float32(radius))
46}