diff options
author | Ben Burwell <ben@benburwell.com> | 2019-12-20 13:21:32 -0500 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2019-12-21 09:23:20 -0500 |
commit | bcd03c4c4a94e73b2545bf5dfc404082a674c76e (patch) | |
tree | 8366af84dfd9011d20794f2a7556e7d6fc71b7db /lib/ui/popover.go | |
parent | ef4c2f61d8c599ac25b4f465ffa3bea9ca6ce1a3 (diff) | |
download | aerc-bcd03c4c4a94e73b2545bf5dfc404082a674c76e.tar.gz |
Add popovers
A popover is a special UI element which can be layered over the rest of the UI (i.e. it is painted last) and can fall anywhere on the screen, not just with the bounds of its parent's viewport/context. With these special abilities comes the restriction that only one popover may be visible on screen at once. Popovers are requested from the UI context passed to Draw calls and specify the anchor point and the desired dimensions. The popover is then fit to the available space and placed relative to the anchor point.
Diffstat (limited to 'lib/ui/popover.go')
-rw-r--r-- | lib/ui/popover.go | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/lib/ui/popover.go b/lib/ui/popover.go new file mode 100644 index 0000000..a76f222 --- /dev/null +++ b/lib/ui/popover.go @@ -0,0 +1,62 @@ +package ui + +import "github.com/gdamore/tcell" + +type Popover struct { + x, y, width, height int + content Drawable +} + +func (p *Popover) Draw(ctx *Context) { + var subcontext *Context + + // trim desired width to fit + width := p.width + if p.x+p.width > ctx.Width() { + width = ctx.Width() - p.x + } + + if p.y+p.height+1 < ctx.Height() { + // draw below + subcontext = ctx.Subcontext(p.x, p.y+1, width, p.height) + } else if p.y-p.height >= 0 { + // draw above + subcontext = ctx.Subcontext(p.x, p.y-p.height, width, p.height) + } else { + // can't fit entirely above or below, so find the largest available + // vertical space and shrink to fit + if p.y > ctx.Height()-p.y { + // there is more space above than below + height := p.y + subcontext = ctx.Subcontext(p.x, 0, width, height) + } else { + // there is more space below than above + height := ctx.Height() - p.y + subcontext = ctx.Subcontext(p.x, p.y+1, width, height-1) + } + } + p.content.Draw(subcontext) +} + +func (p *Popover) Event(e tcell.Event) bool { + if di, ok := p.content.(DrawableInteractive); ok { + return di.Event(e) + } + return false +} + +func (p *Popover) Focus(f bool) { + if di, ok := p.content.(DrawableInteractive); ok { + di.Focus(f) + } +} + +func (p *Popover) Invalidate() { + p.content.Invalidate() +} + +func (p *Popover) OnInvalidate(f func(Drawable)) { + p.content.OnInvalidate(func(_ Drawable) { + f(p) + }) +} |