feat: add portable Windows zone manager
This commit is contained in:
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user