mirror of
https://github.com/vsariola/sointu.git
synced 2025-07-21 06:24:32 -04:00
100 lines
2.0 KiB
Go
100 lines
2.0 KiB
Go
package gioui
|
|
|
|
import (
|
|
"image"
|
|
"image/color"
|
|
|
|
"gioui.org/io/event"
|
|
"gioui.org/io/pointer"
|
|
"gioui.org/layout"
|
|
"gioui.org/op"
|
|
"gioui.org/op/clip"
|
|
"gioui.org/op/paint"
|
|
"gioui.org/unit"
|
|
)
|
|
|
|
type (
|
|
PopupStyle struct {
|
|
Color color.NRGBA
|
|
CornerRadii struct {
|
|
SE, SW, NW, NE unit.Dp
|
|
}
|
|
Shadow struct {
|
|
Color color.NRGBA
|
|
N, E, W, S unit.Dp
|
|
}
|
|
}
|
|
|
|
PopupWidget struct {
|
|
Style *PopupStyle
|
|
Visible *bool
|
|
}
|
|
)
|
|
|
|
func Popup(th *Theme, visible *bool) PopupWidget {
|
|
return PopupWidget{
|
|
Style: &th.Popup.Dialog,
|
|
Visible: visible,
|
|
}
|
|
}
|
|
|
|
func (s PopupWidget) Layout(gtx C, contents layout.Widget) D {
|
|
s.update(gtx)
|
|
|
|
if !*s.Visible {
|
|
return D{}
|
|
}
|
|
|
|
bg := func(gtx C) D {
|
|
rrect := clip.RRect{
|
|
Rect: image.Rectangle{Max: gtx.Constraints.Min},
|
|
SE: gtx.Dp(s.Style.CornerRadii.SE),
|
|
SW: gtx.Dp(s.Style.CornerRadii.SW),
|
|
NW: gtx.Dp(s.Style.CornerRadii.NW),
|
|
NE: gtx.Dp(s.Style.CornerRadii.NE),
|
|
}
|
|
rrect2 := rrect
|
|
rrect2.Rect.Min = rrect2.Rect.Min.Sub(image.Pt(gtx.Dp(s.Style.Shadow.W), gtx.Dp(s.Style.Shadow.N)))
|
|
rrect2.Rect.Max = rrect2.Rect.Max.Add(image.Pt(gtx.Dp(s.Style.Shadow.E), gtx.Dp(s.Style.Shadow.S)))
|
|
paint.FillShape(gtx.Ops, s.Style.Shadow.Color, rrect2.Op(gtx.Ops))
|
|
paint.FillShape(gtx.Ops, s.Style.Color, rrect.Op(gtx.Ops))
|
|
area := clip.Rect(image.Rect(-1e6, -1e6, 1e6, 1e6)).Push(gtx.Ops)
|
|
event.Op(gtx.Ops, s.Visible)
|
|
area.Pop()
|
|
area = clip.Rect(rrect2.Rect).Push(gtx.Ops)
|
|
event.Op(gtx.Ops, &dummyTag)
|
|
area.Pop()
|
|
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
|
|
}
|
|
|
|
func (s *PopupWidget) update(gtx C) {
|
|
for {
|
|
event, ok := gtx.Event(pointer.Filter{
|
|
Target: s.Visible,
|
|
Kinds: pointer.Press,
|
|
})
|
|
if !ok {
|
|
break
|
|
}
|
|
e, ok := event.(pointer.Event)
|
|
if !ok {
|
|
continue
|
|
}
|
|
switch e.Kind {
|
|
case pointer.Press:
|
|
*s.Visible = false
|
|
}
|
|
}
|
|
}
|
|
|
|
var dummyTag bool
|