From 3b09c07e7a75feed8a9086b0a9003c2cf3ffea59 Mon Sep 17 00:00:00 2001 From: Jeffas Date: Thu, 11 Jul 2019 23:15:15 +0100 Subject: [PATCH] Add clickable tabs This introduces a new interface `Clickable`. I'd imagine this would be implemented for most widgets eventually and would allow for programs run in the terminal to also have their mouse events forwarded to them. For the tabs it was relatively simple to check that the position of the click is within the boxes for the tabs. For other components I'd imagine that some state representing their currently drawn bounding box would be useful. --- lib/ui/interfaces.go | 7 +++++++ lib/ui/tab.go | 28 ++++++++++++++++++++++++++++ lib/ui/ui.go | 1 + widgets/aerc.go | 2 ++ 4 files changed, 38 insertions(+) diff --git a/lib/ui/interfaces.go b/lib/ui/interfaces.go index 0cdffc1..9008ea7 100644 --- a/lib/ui/interfaces.go +++ b/lib/ui/interfaces.go @@ -40,3 +40,10 @@ type Container interface { // recurse into your grandchildren). Children() []Drawable } + +// A drawable that can be clicked +type Clickable interface { + Drawable + + MouseEvent(event tcell.Event) +} diff --git a/lib/ui/tab.go b/lib/ui/tab.go index 61d544a..0061472 100644 --- a/lib/ui/tab.go +++ b/lib/ui/tab.go @@ -126,6 +126,19 @@ func (tabs *Tabs) removeHistory(index int) { tabs.history = newHist } +func (tabs *Tabs) MouseEvent(event tcell.Event) { + switch event := event.(type) { + case *tcell.EventMouse: + if event.Buttons()&tcell.Button1 != 0 { + x, y := event.Position() + selectedTab, ok := tabs.TabStrip.Clicked(x, y) + if ok { + tabs.Select(selectedTab) + } + } + } +} + // TODO: Color repository func (strip *TabStrip) Draw(ctx *Context) { x := 0 @@ -151,6 +164,21 @@ func (strip *TabStrip) OnInvalidate(onInvalidate func(d Drawable)) { strip.onInvalidateStrip = onInvalidate } +func (strip *TabStrip) Clicked(mouseX int, mouseY int) (int, bool) { + x := 0 + if mouseY == 0 { + for i, tab := range strip.Tabs { + trunc := runewidth.Truncate(tab.Name, 32, "…") + length := len(trunc) + 2 + if x <= mouseX && mouseX < x+length { + return i, true + } + x += length + } + } + return 0, false +} + func (content *TabContent) Children() []Drawable { children := make([]Drawable, len(content.Tabs)) for i, tab := range content.Tabs { diff --git a/lib/ui/ui.go b/lib/ui/ui.go index f04d3d8..b057885 100644 --- a/lib/ui/ui.go +++ b/lib/ui/ui.go @@ -32,6 +32,7 @@ func Initialize(conf *config.AercConfig, screen.Clear() screen.HideCursor() + screen.EnableMouse() width, height := screen.Size() diff --git a/widgets/aerc.go b/widgets/aerc.go index ade56d1..e113830 100644 --- a/widgets/aerc.go +++ b/widgets/aerc.go @@ -190,6 +190,8 @@ func (aerc *Aerc) Event(event tcell.Event) bool { } return false } + case *tcell.EventMouse: + aerc.tabs.MouseEvent(event) } return false }