aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ui
diff options
context:
space:
mode:
authorKoni Marti <koni.marti@gmail.com>2022-11-20 16:22:40 +0100
committerRobin Jarry <robin@jarry.cc>2022-11-21 13:31:04 +0100
commitbf683c7b09a17702e7d467b0b9f907edc15dc0bd (patch)
treeac85784dc3e2b69dc96c01a7b15a5ac57e8171f1 /lib/ui
parentc063b1d5f38ae144b7c86fe450a58f5f0ead667b (diff)
downloadaerc-bf683c7b09a17702e7d467b0b9f907edc15dc0bd.tar.gz
ui: box and frame an interactive widget
Draw a framed box with a title containing an interactive-drawable widget. Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Tim Culverhouse <tim@timculverhouse.com>
Diffstat (limited to 'lib/ui')
-rw-r--r--lib/ui/box.go74
1 files changed, 74 insertions, 0 deletions
diff --git a/lib/ui/box.go b/lib/ui/box.go
new file mode 100644
index 00000000..96b95d59
--- /dev/null
+++ b/lib/ui/box.go
@@ -0,0 +1,74 @@
+package ui
+
+import (
+ "strings"
+
+ "git.sr.ht/~rjarry/aerc/config"
+ "github.com/gdamore/tcell/v2"
+ "github.com/mattn/go-runewidth"
+)
+
+type Box struct {
+ content Drawable
+ title string
+ borders string
+ uiConfig *config.UIConfig
+}
+
+func NewBox(
+ content Drawable, title, borders string, uiConfig *config.UIConfig,
+) *Box {
+ if borders == "" || len(borders) < 8 {
+ borders = "││┌─┐└─┘"
+ }
+
+ b := &Box{
+ content: content,
+ title: title,
+ borders: borders,
+ uiConfig: uiConfig,
+ }
+ return b
+}
+
+func (b *Box) Draw(ctx *Context) {
+ w := ctx.Width()
+ h := ctx.Height()
+
+ style := b.uiConfig.GetStyle(config.STYLE_BORDER)
+
+ box := []rune(b.borders)
+ ctx.Fill(0, 0, 1, h, box[0], style)
+ ctx.Fill(w-1, 0, 1, h, box[1], style)
+
+ ctx.Printf(0, 0, style, "%c%s%c", box[2], strings.Repeat(string(box[3]), w-2), box[4])
+ ctx.Printf(0, h-1, style, "%c%s%c", box[5], strings.Repeat(string(box[6]), w-2), box[7])
+
+ if b.title != "" && w > 4 {
+ title := runewidth.Truncate(b.title, w-4, "…")
+ ctx.Printf(2, 0, style, "%s", title)
+ }
+
+ subctx := ctx.Subcontext(1, 1, w-2, h-2)
+ b.content.Draw(subctx)
+}
+
+func (b *Box) Invalidate() {
+ b.content.Invalidate()
+}
+
+func (b *Box) MouseEvent(localX int, localY int, event tcell.Event) {
+ if content, ok := b.content.(Mouseable); ok {
+ content.MouseEvent(localX, localY, event)
+ }
+}
+
+func (b *Box) Event(e tcell.Event) bool {
+ if content, ok := b.content.(Interactive); ok {
+ return content.Event(e)
+ }
+ return false
+}
+
+func (b *Box) Focus(_ bool) {
+}