sointu/tracker/popup.go

85 lines
2.0 KiB
Go

package tracker
import (
"image/color"
"gioui.org/f32"
"gioui.org/io/pointer"
"gioui.org/layout"
"gioui.org/op"
"gioui.org/op/clip"
"gioui.org/op/paint"
"gioui.org/unit"
)
type PopupStyle struct {
Visible *bool
SurfaceColor color.NRGBA
ShadowColor color.NRGBA
ShadowN unit.Value
ShadowE unit.Value
ShadowW unit.Value
ShadowS unit.Value
SE, SW, NW, NE unit.Value
}
func Popup(visible *bool) PopupStyle {
return PopupStyle{
Visible: visible,
SurfaceColor: popupSurfaceColor,
ShadowColor: popupShadowColor,
ShadowN: unit.Dp(2),
ShadowE: unit.Dp(2),
ShadowS: unit.Dp(2),
ShadowW: unit.Dp(2),
SE: unit.Dp(6),
SW: unit.Dp(6),
NW: unit.Dp(6),
NE: unit.Dp(6),
}
}
func (s PopupStyle) Layout(gtx C, contents layout.Widget) D {
if !*s.Visible {
return D{}
}
for _, ev := range gtx.Events(s.Visible) {
e, ok := ev.(pointer.Event)
if !ok {
continue
}
switch e.Type {
case pointer.Press:
*s.Visible = false
}
}
bg := func(gtx C) D {
pointer.InputOp{Tag: s.Visible,
Types: pointer.Press,
}.Add(gtx.Ops)
rrect := clip.RRect{
Rect: f32.Rectangle{Max: f32.Pt(float32(gtx.Constraints.Min.X), float32(gtx.Constraints.Min.Y))},
SE: float32(gtx.Px(s.SE)),
SW: float32(gtx.Px(s.SW)),
NW: float32(gtx.Px(s.NW)),
NE: float32(gtx.Px(s.NE)),
}
rrect2 := rrect
rrect2.Rect.Min = rrect2.Rect.Min.Sub(f32.Pt(float32(gtx.Px(s.ShadowW)), float32(gtx.Px(s.ShadowN))))
rrect2.Rect.Max = rrect2.Rect.Max.Add(f32.Pt(float32(gtx.Px(s.ShadowE)), float32(gtx.Px(s.ShadowS))))
paint.FillShape(gtx.Ops, s.ShadowColor, rrect2.Op(gtx.Ops))
paint.FillShape(gtx.Ops, s.SurfaceColor, rrect.Op(gtx.Ops))
return D{Size: gtx.Constraints.Min}
}
macro := op.Record(gtx.Ops)
dims := layout.Stack{}.Layout(gtx,
layout.Expanded(bg),
layout.Stacked(contents),
)
callop := macro.Stop()
op.Defer(gtx.Ops, callop)
return dims
}