aboutsummaryrefslogtreecommitdiff
path: root/lib/ui/popover.go
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ui/popover.go')
-rw-r--r--lib/ui/popover.go62
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)
+ })
+}