feat: add portable Windows zone manager

This commit is contained in:
Steve Cliff
2026-08-20 08:57:41 +01:00
parent 318300ef79
commit 6ddecad74d
15 changed files with 1760 additions and 4 deletions
+58
View File
@@ -0,0 +1,58 @@
package layout
import (
"math"
"github.com/stevec/fancywin/internal/config"
)
type Rect struct{ Left, Top, Right, Bottom int32 }
type Point struct{ X, Y int32 }
func Resolve(work Rect, z config.Zone, gap int) Rect {
w, h := float64(work.Right-work.Left), float64(work.Bottom-work.Top)
r := Rect{
Left: work.Left + int32(math.Round(w*z.X/100)),
Top: work.Top + int32(math.Round(h*z.Y/100)),
Right: work.Left + int32(math.Round(w*(z.X+z.Width)/100)),
Bottom: work.Top + int32(math.Round(h*(z.Y+z.Height)/100)),
}
g := int32(gap)
r.Left += g
r.Top += g
r.Right -= g
r.Bottom -= g
if r.Right <= r.Left {
r.Right = r.Left + 1
}
if r.Bottom <= r.Top {
r.Bottom = r.Top + 1
}
return r
}
func Contains(r Rect, p Point) bool {
return p.X >= r.Left && p.X < r.Right && p.Y >= r.Top && p.Y < r.Bottom
}
func ZoneAt(work Rect, zones []config.Zone, gap int, p Point) int {
for i, z := range zones {
if Contains(Resolve(work, z, gap), p) {
return i
}
}
return -1
}
func Closest(work Rect, zones []config.Zone, p Point) int {
best, bestD := -1, math.MaxFloat64
for i, z := range zones {
r := Resolve(work, z, 0)
cx, cy := float64(r.Left+r.Right)/2, float64(r.Top+r.Bottom)/2
dx, dy := float64(p.X)-cx, float64(p.Y)-cy
if d := dx*dx + dy*dy; d < bestD {
best, bestD = i, d
}
}
return best
}
+21
View File
@@ -0,0 +1,21 @@
package layout
import (
"github.com/stevec/fancywin/internal/config"
"testing"
)
func TestResolvePercentageAndGap(t *testing.T) {
got := Resolve(Rect{0, 0, 1920, 1040}, config.Zone{X: 50, Y: 0, Width: 50, Height: 100}, 8)
want := (Rect{968, 8, 1912, 1032})
if got != want {
t.Fatalf("got %+v, want %+v", got, want)
}
}
func TestZoneAt(t *testing.T) {
z := []config.Zone{{X: 0, Y: 0, Width: 50, Height: 100}, {X: 50, Y: 0, Width: 50, Height: 100}}
if got := ZoneAt(Rect{0, 0, 100, 100}, z, 0, Point{75, 20}); got != 1 {
t.Fatalf("got %d", got)
}
}