Created
June 6, 2020 14:12
-
-
Save tux21b/b2a2a1b8ae1dd0f24b6729ed3f33eb9d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Problem: | |
// The green and red area (and the intersection) receive | |
// click events (press and release). | |
// The green area also receives hover events (enter and leave), | |
// but the red one does not. | |
package main | |
import ( | |
"image" | |
"image/color" | |
"log" | |
"gioui.org/app" | |
"gioui.org/f32" | |
"gioui.org/io/pointer" | |
"gioui.org/io/system" | |
"gioui.org/layout" | |
"gioui.org/op" | |
"gioui.org/op/clip" | |
"gioui.org/op/paint" | |
"gioui.org/unit" | |
) | |
func main() { | |
go func() { | |
w := app.NewWindow() | |
if err := loop(w); err != nil { | |
log.Fatal(err) | |
} | |
}() | |
app.Main() | |
} | |
func loop(w *app.Window) error { | |
var ops op.Ops | |
var btn Button | |
for { | |
e := <-w.Events() | |
switch e := e.(type) { | |
case system.DestroyEvent: | |
return e.Err | |
case system.FrameEvent: | |
gtx := layout.NewContext(&ops, e.Queue, e.Config, e.Size) | |
btn.Layout(gtx) | |
e.Frame(gtx.Ops) | |
} | |
} | |
} | |
type Button struct { | |
active bool | |
hover bool | |
} | |
func (b *Button) Layout(gtx layout.Context) layout.Dimensions { | |
for _, ev := range gtx.Queue.Events(b) { | |
log.Println("event", ev) | |
if x, ok := ev.(pointer.Event); ok { | |
switch x.Type { | |
case pointer.Enter: | |
b.hover = true | |
case pointer.Leave: | |
b.hover = false | |
case pointer.Press: | |
b.active = true | |
case pointer.Release: | |
b.active = false | |
} | |
} | |
} | |
defer op.Push(gtx.Ops).Pop() | |
rect := f32.Rect(100, 100, 400, 400) | |
rr := unit.Px(50) | |
clip.Rect{Rect: rect, SE: rr.V, SW: rr.V, NE: rr.V, NW: rr.V}.Add(gtx.Ops) | |
col := color.RGBA{B: 100, A: 0xff} | |
if b.hover { | |
col = color.RGBA{B: 150, A: 0xff} | |
} | |
if b.active { | |
col = color.RGBA{B: 200, A: 0xff} | |
} | |
paint.ColorOp{Color: col}.Add(gtx.Ops) | |
paint.PaintOp{Rect: rect}.Add(gtx.Ops) | |
func() { | |
defer op.Push(gtx.Ops).Pop() | |
drawBorderRect(gtx, f32.Rect(150, 100, 350, 400), color.RGBA{R: 0xFF, A: 0xFF}) | |
pointer.Rect(image.Rect(150, 100, 350, 400)).Add(gtx.Ops) | |
pointer.InputOp{Tag: b, Types: pointer.Enter | pointer.Leave | pointer.Press | pointer.Release}.Add(gtx.Ops) | |
}() | |
func() { | |
defer op.Push(gtx.Ops).Pop() | |
drawBorderRect(gtx, f32.Rect(100, 150, 400, 350), color.RGBA{G: 0xFF, A: 0xFF}) | |
pointer.Rect(image.Rect(100, 150, 400, 350)).Add(gtx.Ops) | |
pointer.InputOp{Tag: b, Types: pointer.Enter | pointer.Leave | pointer.Press | pointer.Release}.Add(gtx.Ops) | |
}() | |
return layout.Dimensions{ | |
Size: image.Point{500, 500}, | |
} | |
} | |
func drawBorderRect(gfx layout.Context, rect f32.Rectangle, fill color.RGBA) { | |
border := unit.Px(2).V | |
paint.ColorOp{Color: fill}.Add(gfx.Ops) | |
paint.PaintOp{Rect: f32.Rect(rect.Min.X, rect.Min.Y, rect.Min.X+border, rect.Max.Y)}.Add(gfx.Ops) // left | |
paint.PaintOp{Rect: f32.Rect(rect.Max.X - border, rect.Min.Y, rect.Max.X, rect.Max.Y)}.Add(gfx.Ops) // right | |
paint.PaintOp{Rect: f32.Rect(rect.Min.X, rect.Min.Y, rect.Max.X, rect.Min.Y+border)}.Add(gfx.Ops) // top | |
paint.PaintOp{Rect: f32.Rect(rect.Min.X, rect.Max.Y - border, rect.Max.X, rect.Max.Y)}.Add(gfx.Ops) // bottom | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment