diff options
| author | Sam Anthony <sam@samanthony.xyz> | 2026-02-09 22:00:33 -0500 |
|---|---|---|
| committer | Sam Anthony <sam@samanthony.xyz> | 2026-02-09 22:00:33 -0500 |
| commit | 8f28d1044fb83153fde4505421b75072930d6fb9 (patch) | |
| tree | ec39000ed901dc959626fc09d8e270268c6b3d03 | |
| parent | 5fde17eafa11bf397bbf1f18864b8ee26d9a701d (diff) | |
| download | gui-8f28d1044fb83153fde4505421b75072930d6fb9.zip | |
layout: add background color option
| -rw-r--r-- | color.go | 12 | ||||
| -rw-r--r-- | examples/pexeso/main.go | 47 | ||||
| -rw-r--r-- | layout/layout.go (renamed from layout/doc.go) | 13 | ||||
| -rw-r--r-- | layout/options.go | 34 | ||||
| -rw-r--r-- | layout/region.go | 13 | ||||
| -rw-r--r-- | test/region.go | 13 |
6 files changed, 97 insertions, 35 deletions
diff --git a/color.go b/color.go new file mode 100644 index 0000000..e2b9bc1 --- /dev/null +++ b/color.go @@ -0,0 +1,12 @@ +package gui + +import ( + "fmt" + "image/color" +) + +func HexToColor(hex string) color.Color { + var r, g, b uint8 + fmt.Sscanf(hex, "#%2X%2X%2X", &r, &g, &b) + return color.RGBA{r, g, b, 255} +} diff --git a/examples/pexeso/main.go b/examples/pexeso/main.go index 56bd6e6..7be7baa 100644 --- a/examples/pexeso/main.go +++ b/examples/pexeso/main.go @@ -1,7 +1,6 @@ package main import ( - "fmt" "image" "image/color" "image/draw" @@ -19,31 +18,25 @@ func EqualColors(c1, c2 color.Color) bool { return r1 == r2 && g1 == g2 && b1 == b2 && a1 == a2 } -func HexToColor(hex string) color.Color { - var r, g, b uint8 - fmt.Sscanf(hex, "#%2X%2X%2X", &r, &g, &b) - return color.RGBA{r, g, b, 255} -} - var Colors = []color.Color{ - HexToColor("#E53935"), - HexToColor("#F06292"), - HexToColor("#9C27B0"), - HexToColor("#673AB7"), - HexToColor("#3F51B5"), - HexToColor("#2196F3"), - HexToColor("#29B6F6"), - HexToColor("#00BCD4"), - HexToColor("#009688"), - HexToColor("#4CAF50"), - HexToColor("#8BC34A"), - HexToColor("#CDDC39"), - HexToColor("#FFEB3B"), - HexToColor("#FFC107"), - HexToColor("#FF9800"), - HexToColor("#8D6E63"), - HexToColor("#9E9E9E"), - HexToColor("#607D8B"), + gui.HexToColor("#E53935"), + gui.HexToColor("#F06292"), + gui.HexToColor("#9C27B0"), + gui.HexToColor("#673AB7"), + gui.HexToColor("#3F51B5"), + gui.HexToColor("#2196F3"), + gui.HexToColor("#29B6F6"), + gui.HexToColor("#00BCD4"), + gui.HexToColor("#009688"), + gui.HexToColor("#4CAF50"), + gui.HexToColor("#8BC34A"), + gui.HexToColor("#CDDC39"), + gui.HexToColor("#FFEB3B"), + gui.HexToColor("#FFC107"), + gui.HexToColor("#FF9800"), + gui.HexToColor("#8D6E63"), + gui.HexToColor("#9E9E9E"), + gui.HexToColor("#607D8B"), } type PairMsg struct { @@ -59,7 +52,7 @@ func Tile(env gui.Env, pair chan PairMsg, r image.Rectangle, clr color.Color) { bottomR.Min.Y = bottomR.Max.Y - coveredY topR := r topR.Max.Y = bottomR.Min.Y - draw.Draw(drw, bottomR, &image.Uniform{HexToColor("#37474F")}, image.ZP, draw.Src) + draw.Draw(drw, bottomR, &image.Uniform{gui.HexToColor("#37474F")}, image.ZP, draw.Src) draw.Draw(drw, topR, &image.Uniform{clr}, image.ZP, draw.Src) return r } @@ -124,7 +117,7 @@ func run() { env.Draw() <- func(drw draw.Image) image.Rectangle { r := image.Rect(0, 0, 600, 600) - draw.Draw(drw, r, &image.Uniform{HexToColor("#CFD8DC")}, image.ZP, draw.Src) + draw.Draw(drw, r, &image.Uniform{gui.HexToColor("#CFD8DC")}, image.ZP, draw.Src) return r } diff --git a/layout/doc.go b/layout/layout.go index bae4673..b04aa35 100644 --- a/layout/doc.go +++ b/layout/layout.go @@ -13,3 +13,16 @@ Draw calls from the children are intercepted and translated onto their respective areas before being forwarded to the parent Env. */ package layout + +import ( + "image" + "image/color" + "image/draw" +) + +func drawBackground(c color.Color) func(draw.Image) image.Rectangle { + return func(img draw.Image) image.Rectangle { + draw.Draw(img, img.Bounds(), &image.Uniform{c}, image.ZP, draw.Src) + return img.Bounds() + } +} diff --git a/layout/options.go b/layout/options.go new file mode 100644 index 0000000..2ea0c81 --- /dev/null +++ b/layout/options.go @@ -0,0 +1,34 @@ +package layout + +import ( + "image/color" +) + +var ( + defaultBg = color.Transparent +) + +// Option is a function option for layout constructors. +type Option func(*options) + +type options struct { + bg color.Color // background color +} + +// Background sets the background color of a layout. +func Background(bg color.Color) Option { + return func(o *options) { + o.bg = bg + } +} + +// EvalOptions evaluates a list of option functions, returning the final set. +func evalOptions(o ...Option) options { + opts := options{ + bg: defaultBg, + } + for i := range o { + o[i](&opts) + } + return opts +} diff --git a/layout/region.go b/layout/region.go index 1e92455..4e3a791 100644 --- a/layout/region.go +++ b/layout/region.go @@ -15,7 +15,9 @@ type Region struct { // NewRegion creates a region layout that occupies part of the parent env's area, as determined by the resize function. // Resize takes the area of the parent and returns the area of the region. -func NewRegion(env gui.Env, resize func(image.Rectangle) image.Rectangle) gui.Env { +func NewRegion(env gui.Env, resize func(image.Rectangle) image.Rectangle, o ...Option) gui.Env { + opts := evalOptions(o...) + events := make(chan gui.Event) // to child drw := make(chan func(draw.Image) image.Rectangle) // from child @@ -25,17 +27,20 @@ func NewRegion(env gui.Env, resize func(image.Rectangle) image.Rectangle) gui.En area := resize(event.(gui.Resize).Rectangle) // first event guaranteed to be Resize events <- gui.Resize{area} + env.Draw() <- drawBackground(opts.bg) + for { select { - case event := <-env.Events(): + case event := <-env.Events(): // event from parent switch event := event.(type) { case gui.Resize: + env.Draw() <- drawBackground(opts.bg) area = resize(event.Rectangle) - events <- gui.Resize{area} + events <- gui.Resize{area} // forward to child default: events <- event } - case f, ok := <-drw: + case f, ok := <-drw: // draw call from child if !ok { close(events) close(env.Draw()) diff --git a/test/region.go b/test/region.go index afd739e..0b99a3a 100644 --- a/test/region.go +++ b/test/region.go @@ -11,6 +11,10 @@ import ( "github.com/faiface/mainthread" ) +var ( + bg = gui.HexToColor("#999999") // background color +) + func main() { mainthread.Run(run) } @@ -24,9 +28,10 @@ func run() { mux, env := gui.NewMux(w) // Create region in bottom-right quadrant of window - region := layout.NewRegion(mux.MakeEnv(), func(r image.Rectangle) image.Rectangle { + resize := func(r image.Rectangle) image.Rectangle { return image.Rect(r.Min.X+r.Dx()/2, r.Min.Y+r.Dy()/2, r.Max.X, r.Max.Y) - }) + } + region := layout.NewRegion(mux.MakeEnv(), resize, layout.Background(bg)) go blinker(region) for event := range env.Events() { @@ -64,9 +69,9 @@ func blinker(env gui.Env) { go func() { for i := 0; i < 3; i++ { env.Draw() <- redraw(false) - time.Sleep(time.Second / 3) + time.Sleep(time.Second / 6) env.Draw() <- redraw(true) - time.Sleep(time.Second / 3) + time.Sleep(time.Second / 6) } }() } |