TabTitleMenu's added
1 parent 97249cf commit c5bcfc55ac4d7a4b2889fcc7723928817957fc8f
0xRoM authored on 7 Feb 2023
Showing 5 changed files
View
11
TabTitleMenu/README.md 0 → 100644
Tabs Instead of Title for TUI Example
===============
see central box's tabs where the other box's titles are
 
![screenshot](/screenshot.png?raw=true "screenshot")
 
 
Thanks
===============
A MASSIVE thanks to @LoreleiAurora for helping with this!
View
88
TabTitleMenu/main.go 0 → 100755
// Demo code for the TabbedPanels primitive.
package main
 
import (
"fmt"
 
//"github.com/rivo/tview"
"github.com/gdamore/tcell/v2"
"code.rocketnine.space/tslocum/cview"
)
 
const panelCount = 5
 
 
func demoBox(title string) *cview.Box {
b := cview.NewBox()
b.SetBorder(true)
b.SetTitle(title)
return b
}
 
 
func main() {
 
app := cview.NewApplication()
defer app.HandlePanic()
app.EnableMouse(true)
 
panels := NewTabbedPanels()
 
for panel := 0; panel < panelCount; panel++ {
func(panel int) {
form := cview.NewForm()
form.SetBorder(true)
form.SetDrawFunc(func(screen tcell.Screen, x int, y int, width int, height int) (int, int, int, int) {
//fix corners
screen.SetContent(x, y, cview.BoxDrawingsLightVertical, nil, tcell.StyleDefault.Background(tcell.Color16))
screen.SetContent(x+width-1, y, cview.BoxDrawingsLightVertical, nil, tcell.StyleDefault.Background(tcell.Color16))
// Draw nothing across the top of the box.
for cx := x + 1; cx < x+width-1; cx++ {
screen.SetContent(cx, y, ' ', nil, tcell.StyleDefault.Background(tcell.Color16))
}
// Space for other content.
return x + 1, y, width - 2, height - y +1
})
//form.SetTitle(fmt.Sprintf("This is tab %d. Choose another tab.", panel+1))
form.AddButton("Next", func() {
panels.SetCurrentTab(fmt.Sprintf("panel-%d", (panel+1)%panelCount))
})
form.AddButton("Quit", func() {
app.Stop()
})
form.SetCancelFunc(func() {
app.Stop()
})
 
panels.AddTab(fmt.Sprintf("panel-%d", panel), fmt.Sprintf("Panel #%d", panel), form)
}(panel)
}
 
subFlex := cview.NewFlex()
subFlex.SetDirection(cview.FlexRow)
subFlex.AddItem(demoBox("Top"), 0, 1, false)
subFlex.AddItem(panels, 0, 3, false)
subFlex.AddItem(demoBox("Bottom (5 rows)"), 5, 1, false)
 
flex := cview.NewFlex()
flex.AddItem(demoBox("Left (1/2 x width of Top)"), 0, 1, false)
flex.AddItem(subFlex, 0, 2, false)
flex.AddItem(demoBox("Right (20 cols)"), 20, 1, false)
 
app.SetRoot(flex, true)
if err := app.Run(); err != nil {
panic(err)
}
 
//app := cview.NewApplication()
//defer app.HandlePanic()
 
 
 
//app.SetRoot(panels, true)
//if err := app.Run(); err != nil {
// panic(err)
//}
}
View
450
TabTitleMenu/panels.go 0 → 100755
package main
 
import (
"sync"
 
"github.com/gdamore/tcell/v2"
"code.rocketnine.space/tslocum/cview"
)
 
// panel represents a single panel of a Panels object.
type panel struct {
Name string // The panel's name.
Item cview.Primitive // The panel's cview.Primitive.
Resize bool // Whether or not to resize the panel when it is drawn.
Visible bool // Whether or not this panel is visible.
}
 
// Panels is a container for other cview.Primitives often used as the application's
// root cview.Primitive. It allows to easily switch the visibility of the contained
// cview.Primitives.
type Panels struct {
*cview.Box
 
// The contained panels. (Visible) panels are drawn from back to front.
panels []*panel
 
// We keep a reference to the function which allows us to set the focus to
// a newly visible panel.
setFocus func(p cview.Primitive)
 
// An optional handler which is called whenever the visibility or the order of
// panels changes.
changed func()
 
sync.RWMutex
}
 
// NewPanels returns a new Panels object.
func NewPanels() *Panels {
p := &Panels{
Box: cview.NewBox(),
}
//p.focus = p
return p
}
 
// SetChangedFunc sets a handler which is called whenever the visibility or the
// order of any visible panels changes. This can be used to redraw the panels.
func (p *Panels) SetChangedFunc(handler func()) {
p.Lock()
defer p.Unlock()
 
p.changed = handler
}
 
// GetPanelCount returns the number of panels currently stored in this object.
func (p *Panels) GetPanelCount() int {
p.RLock()
defer p.RUnlock()
 
return len(p.panels)
}
 
// AddPanel adds a new panel with the given name and cview.Primitive. If there was
// previously a panel with the same name, it is overwritten. Leaving the name
// empty may cause conflicts in other functions so always specify a non-empty
// name.
//
// Visible panels will be drawn in the order they were added (unless that order
// was changed in one of the other functions). If "resize" is set to true, the
// cview.Primitive will be set to the size available to the Panels cview.Primitive whenever
// the panels are drawn.
func (p *Panels) AddPanel(name string, item cview.Primitive, resize, visible bool) {
hasFocus := p.HasFocus()
 
p.Lock()
defer p.Unlock()
 
var added bool
for i, pg := range p.panels {
if pg.Name == name {
p.panels[i] = &panel{Item: item, Name: name, Resize: resize, Visible: visible}
added = true
break
}
}
if !added {
p.panels = append(p.panels, &panel{Item: item, Name: name, Resize: resize, Visible: visible})
}
if p.changed != nil {
p.Unlock()
p.changed()
p.Lock()
}
if hasFocus {
p.Unlock()
p.Focus(p.setFocus)
p.Lock()
}
}
 
// RemovePanel removes the panel with the given name. If that panel was the only
// visible panel, visibility is assigned to the last panel.
func (p *Panels) RemovePanel(name string) {
hasFocus := p.HasFocus()
 
p.Lock()
defer p.Unlock()
 
var isVisible bool
for index, panel := range p.panels {
if panel.Name == name {
isVisible = panel.Visible
p.panels = append(p.panels[:index], p.panels[index+1:]...)
if panel.Visible && p.changed != nil {
p.Unlock()
p.changed()
p.Lock()
}
break
}
}
if isVisible {
for index, panel := range p.panels {
if index < len(p.panels)-1 {
if panel.Visible {
break // There is a remaining visible panel.
}
} else {
panel.Visible = true // We need at least one visible panel.
}
}
}
if hasFocus {
p.Unlock()
p.Focus(p.setFocus)
p.Lock()
}
}
 
// HasPanel returns true if a panel with the given name exists in this object.
func (p *Panels) HasPanel(name string) bool {
p.RLock()
defer p.RUnlock()
 
for _, panel := range p.panels {
if panel.Name == name {
return true
}
}
return false
}
 
// ShowPanel sets a panel's visibility to "true" (in addition to any other panels
// which are already visible).
func (p *Panels) ShowPanel(name string) {
hasFocus := p.HasFocus()
 
p.Lock()
defer p.Unlock()
 
for _, panel := range p.panels {
if panel.Name == name {
panel.Visible = true
if p.changed != nil {
p.Unlock()
p.changed()
p.Lock()
}
break
}
}
if hasFocus {
p.Unlock()
p.Focus(p.setFocus)
p.Lock()
}
}
 
// HidePanel sets a panel's visibility to "false".
func (p *Panels) HidePanel(name string) {
hasFocus := p.HasFocus()
 
p.Lock()
defer p.Unlock()
 
for _, panel := range p.panels {
if panel.Name == name {
panel.Visible = false
if p.changed != nil {
p.Unlock()
p.changed()
p.Lock()
}
break
}
}
if hasFocus {
p.Unlock()
p.Focus(p.setFocus)
p.Lock()
}
}
 
// SetCurrentPanel sets a panel's visibility to "true" and all other panels'
// visibility to "false".
func (p *Panels) SetCurrentPanel(name string) {
hasFocus := p.HasFocus()
 
p.Lock()
defer p.Unlock()
 
for _, panel := range p.panels {
if panel.Name == name {
panel.Visible = true
} else {
panel.Visible = false
}
}
if p.changed != nil {
p.Unlock()
p.changed()
p.Lock()
}
if hasFocus {
p.Unlock()
p.Focus(p.setFocus)
p.Lock()
}
}
 
// SendToFront changes the order of the panels such that the panel with the given
// name comes last, causing it to be drawn last with the next update (if
// visible).
func (p *Panels) SendToFront(name string) {
hasFocus := p.HasFocus()
 
p.Lock()
defer p.Unlock()
 
for index, panel := range p.panels {
if panel.Name == name {
if index < len(p.panels)-1 {
p.panels = append(append(p.panels[:index], p.panels[index+1:]...), panel)
}
if panel.Visible && p.changed != nil {
p.Unlock()
p.changed()
p.Lock()
}
break
}
}
if hasFocus {
p.Unlock()
p.Focus(p.setFocus)
p.Lock()
}
}
 
// SendToBack changes the order of the panels such that the panel with the given
// name comes first, causing it to be drawn first with the next update (if
// visible).
func (p *Panels) SendToBack(name string) {
hasFocus := p.HasFocus()
 
p.Lock()
defer p.Unlock()
 
for index, pg := range p.panels {
if pg.Name == name {
if index > 0 {
p.panels = append(append([]*panel{pg}, p.panels[:index]...), p.panels[index+1:]...)
}
if pg.Visible && p.changed != nil {
p.Unlock()
p.changed()
p.Lock()
}
break
}
}
if hasFocus {
p.Unlock()
p.Focus(p.setFocus)
p.Lock()
}
}
 
// GetFrontPanel returns the front-most visible panel. If there are no visible
// panels, ("", nil) is returned.
func (p *Panels) GetFrontPanel() (name string, item cview.Primitive) {
p.RLock()
defer p.RUnlock()
 
for index := len(p.panels) - 1; index >= 0; index-- {
if p.panels[index].Visible {
return p.panels[index].Name, p.panels[index].Item
}
}
return
}
 
// HasFocus returns whether or not this cview.Primitive has focus.
func (p *Panels) HasFocus() bool {
p.RLock()
defer p.RUnlock()
 
for _, panel := range p.panels {
if panel.Item.GetFocusable().HasFocus() {
return true
}
}
return false
}
 
// Focus is called by the application when the cview.Primitive receives focus.
func (p *Panels) Focus(delegate func(p cview.Primitive)) {
p.Lock()
defer p.Unlock()
 
if delegate == nil {
return // We cannot delegate so we cannot focus.
}
p.setFocus = delegate
var topItem cview.Primitive
for _, panel := range p.panels {
if panel.Visible {
topItem = panel.Item
}
}
if topItem != nil {
p.Unlock()
delegate(topItem)
p.Lock()
}
}
 
// Draw draws this cview.Primitive onto the screen.
func (p *Panels) Draw(screen tcell.Screen) {
if !p.GetVisible() {
return
}
 
p.Box.Draw(screen)
 
p.Lock()
defer p.Unlock()
 
x, y, width, height := p.GetInnerRect()
 
for _, panel := range p.panels {
if !panel.Visible {
continue
}
if panel.Resize {
panel.Item.SetRect(x, y, width, height)
}
panel.Item.Draw(screen)
}
}
 
// MouseHandler returns the mouse handler for this cview.Primitive.
func (p *Panels) MouseHandler() func(action cview.MouseAction, event *tcell.EventMouse, setFocus func(p cview.Primitive)) (consumed bool, capture cview.Primitive) {
return p.WrapMouseHandler(func(action cview.MouseAction, event *tcell.EventMouse, setFocus func(p cview.Primitive)) (consumed bool, capture cview.Primitive) {
if !p.InRect(event.Position()) {
return false, nil
}
 
// Pass mouse events along to the last visible panel item that takes it.
for index := len(p.panels) - 1; index >= 0; index-- {
panel := p.panels[index]
if panel.Visible {
consumed, capture = panel.Item.MouseHandler()(action, event, setFocus)
if consumed {
return
}
}
}
 
return
})
}
 
// Support backwards compatibility with Pages.
type page = panel
 
// Pages is a wrapper around Panels.
//
// Deprecated: This type is provided for backwards compatibility.
// Developers should use Panels instead.
type Pages struct {
*Panels
}
 
// NewPages returns a new Panels object.
//
// Deprecated: This function is provided for backwards compatibility.
// Developers should use NewPanels instead.
func NewPages() *Pages {
return &Pages{NewPanels()}
}
 
// GetPageCount returns the number of panels currently stored in this object.
func (p *Pages) GetPageCount() int {
return p.GetPanelCount()
}
 
// AddPage adds a new panel with the given name and cview.Primitive.
func (p *Pages) AddPage(name string, item cview.Primitive, resize, visible bool) {
p.AddPanel(name, item, resize, visible)
}
 
// AddAndSwitchToPage calls Add(), then SwitchTo() on that newly added panel.
func (p *Pages) AddAndSwitchToPage(name string, item cview.Primitive, resize bool) {
p.AddPanel(name, item, resize, true)
p.SetCurrentPanel(name)
}
 
// RemovePage removes the panel with the given name.
func (p *Pages) RemovePage(name string) {
p.RemovePanel(name)
}
 
// HasPage returns true if a panel with the given name exists in this object.
func (p *Pages) HasPage(name string) bool {
return p.HasPanel(name)
}
 
// ShowPage sets a panel's visibility to "true".
func (p *Pages) ShowPage(name string) {
p.ShowPanel(name)
}
 
// HidePage sets a panel's visibility to "false".
func (p *Pages) HidePage(name string) {
p.HidePanel(name)
}
 
// SwitchToPage sets a panel's visibility to "true" and all other panels'
// visibility to "false".
func (p *Pages) SwitchToPage(name string) {
p.SetCurrentPanel(name)
}
 
// GetFrontPage returns the front-most visible panel.
func (p *Pages) GetFrontPage() (name string, item cview.Primitive) {
return p.GetFrontPanel()
}
View
TabTitleMenu/screenshot.png 0 → 100755
View
434
TabTitleMenu/tabbedpanels.go 0 → 100755
package main
 
import (
"bytes"
"fmt"
"sync"
"strings"
 
"github.com/gdamore/tcell/v2"
"code.rocketnine.space/tslocum/cview"
)
 
// TabbedPanels is a tabbed container for other cview.Primitives. The tab switcher
// may be positioned vertically or horizontally, before or after the content.
type TabbedPanels struct {
*cview.Flex
Switcher *cview.TextView
panels *Panels
 
tabLabels map[string]string
currentTab string
 
dividerStart string
dividerMid string
dividerEnd string
 
switcherVertical bool
switcherAfterContent bool
switcherHeight int
 
width, lastWidth int
 
setFocus func(cview.Primitive)
 
sync.RWMutex
}
 
// NewTabbedPanels returns a new TabbedPanels object.
func NewTabbedPanels() *TabbedPanels {
t := &TabbedPanels{
Flex: cview.NewFlex(),
Switcher: cview.NewTextView(),
panels: NewPanels(),
dividerStart: string(cview.BoxDrawingsLightDownAndRight),
dividerMid: string("-"),
dividerEnd: string(cview.BoxDrawingsLightDownAndLeft),
tabLabels: make(map[string]string),
}
 
s := t.Switcher
s.SetDynamicColors(true)
s.SetHighlightForegroundColor(tcell.Color226) // yellow
s.SetHighlightBackgroundColor(tcell.Color16) // black
s.SetRegions(true)
s.SetScrollable(true)
s.SetWrap(true)
s.SetWordWrap(true)
s.SetHighlightedFunc(func(added, removed, remaining []string) {
if len(added) == 0 {
return
}
 
s.ScrollToHighlight()
t.SetCurrentTab(added[0])
if t.setFocus != nil {
t.setFocus(t.panels)
}
})
 
t.rebuild()
 
return t
}
 
// SetChangedFunc sets a handler which is called whenever a tab is added,
// selected, reordered or removed.
func (t *TabbedPanels) SetChangedFunc(handler func()) {
t.panels.SetChangedFunc(handler)
}
 
// AddTab adds a new tab. Tab names should consist only of letters, numbers
// and spaces.
func (t *TabbedPanels) AddTab(name, label string, item cview.Primitive) {
t.Lock()
t.tabLabels[name] = label
t.Unlock()
 
t.panels.AddPanel(name, item, true, false)
 
t.updateAll()
}
 
// RemoveTab removes a tab.
func (t *TabbedPanels) RemoveTab(name string) {
t.panels.RemovePanel(name)
 
t.updateAll()
}
 
// HasTab returns true if a tab with the given name exists in this object.
func (t *TabbedPanels) HasTab(name string) bool {
t.RLock()
defer t.RUnlock()
 
for _, panel := range t.panels.panels {
if panel.Name == name {
return true
}
}
return false
}
 
// SetCurrentTab sets the currently visible tab.
func (t *TabbedPanels) SetCurrentTab(name string) {
t.Lock()
 
if t.currentTab == name {
t.Unlock()
return
}
 
t.currentTab = name
 
t.updateAll()
 
t.Unlock()
 
h := t.Switcher.GetHighlights()
var found bool
for _, hl := range h {
if hl == name {
found = true
break
}
}
if !found {
t.Switcher.Highlight(t.currentTab)
}
t.Switcher.ScrollToHighlight()
}
 
// GetCurrentTab returns the currently visible tab.
func (t *TabbedPanels) GetCurrentTab() string {
t.RLock()
defer t.RUnlock()
return t.currentTab
}
 
// SetTabLabel sets the label of a tab.
func (t *TabbedPanels) SetTabLabel(name, label string) {
t.Lock()
defer t.Unlock()
 
if t.tabLabels[name] == label {
return
}
 
t.tabLabels[name] = label
t.updateTabLabels()
}
 
// SetTabTextColor sets the color of the tab text.
func (t *TabbedPanels) SetTabTextColor(color tcell.Color) {
t.Switcher.SetTextColor(color)
}
 
// SetTabTextColorFocused sets the color of the tab text when the tab is in focus.
func (t *TabbedPanels) SetTabTextColorFocused(color tcell.Color) {
t.Switcher.SetHighlightForegroundColor(color)
}
 
// SetTabBackgroundColor sets the background color of the tab.
func (t *TabbedPanels) SetTabBackgroundColor(color tcell.Color) {
t.Switcher.SetBackgroundColor(color)
}
 
// SetTabBackgroundColorFocused sets the background color of the tab when the
// tab is in focus.
func (t *TabbedPanels) SetTabBackgroundColorFocused(color tcell.Color) {
t.Switcher.SetHighlightBackgroundColor(color)
}
 
// SetTabSwitcherDivider sets the tab switcher divider text. Color tags are supported.
func (t *TabbedPanels) SetTabSwitcherDivider(start, mid, end string) {
t.Lock()
defer t.Unlock()
t.dividerStart, t.dividerMid, t.dividerEnd = start, mid, end
}
 
// SetTabSwitcherHeight sets the tab switcher height. This setting only applies
// when rendering horizontally. A value of 0 (the default) indicates the height
// should automatically adjust to fit all of the tab labels.
func (t *TabbedPanels) SetTabSwitcherHeight(height int) {
t.Lock()
defer t.Unlock()
 
t.switcherHeight = height
t.rebuild()
}
 
// SetTabSwitcherVertical sets the orientation of the tab switcher.
func (t *TabbedPanels) SetTabSwitcherVertical(vertical bool) {
t.Lock()
defer t.Unlock()
if t.switcherVertical == vertical {
return
}
 
t.switcherVertical = vertical
t.rebuild()
}
 
// SetTabSwitcherAfterContent sets whether the tab switcher is positioned after content.
func (t *TabbedPanels) SetTabSwitcherAfterContent(after bool) {
t.Lock()
defer t.Unlock()
 
if t.switcherAfterContent == after {
return
}
 
t.switcherAfterContent = after
t.rebuild()
}
 
func (t *TabbedPanels) rebuild() {
f := t.Flex
if t.switcherVertical {
f.SetDirection(cview.FlexColumn)
} else {
f.SetDirection(cview.FlexRow)
}
f.RemoveItem(t.panels)
f.RemoveItem(t.Switcher)
if t.switcherAfterContent {
f.AddItem(t.panels, 0, 1, true)
f.AddItem(t.Switcher, 1, 1, false)
} else {
f.AddItem(t.Switcher, 1, 1, false)
f.AddItem(t.panels, 0, 1, true)
}
 
t.updateTabLabels()
 
t.Switcher.SetMaxLines(t.switcherHeight)
}
 
func (t *TabbedPanels) updateTabLabels() {
if len(t.panels.panels) == 0 {
t.Switcher.SetText("")
t.Flex.ResizeItem(t.Switcher, 0, 1)
return
}
 
maxWidth := 0
for _, panel := range t.panels.panels {
label := t.tabLabels[panel.Name]
if len(label) > maxWidth {
maxWidth = len(label)
}
}
 
var b bytes.Buffer
if !t.switcherVertical {
b.WriteString(t.dividerStart)
}
l := len(t.panels.panels)
spacer := []byte(" ")
for i, panel := range t.panels.panels {
if i > 0 && t.switcherVertical {
b.WriteRune('\n')
}
 
if t.switcherVertical && t.switcherAfterContent {
b.WriteString(t.dividerMid)
b.WriteRune(' ')
}
 
label := t.tabLabels[panel.Name]
if !t.switcherVertical {
label = " " + label
}
 
if t.switcherVertical {
spacer = bytes.Repeat([]byte(" "), maxWidth-len(label)+1)
}
b.WriteString(fmt.Sprintf(`["%s"]%s%s[""]`, panel.Name, label, spacer))
if i == l-1 && !t.switcherVertical {
//fmt.Println("t.width", t.width, "maxwidth", maxWidth, "label", label, "l", l)
/***
* This did not work! (trying to make when panel highlighted borders change)
*/
/*
spacer_char := ""
div_end := ""
if t.setFocus != nil { // not in focus!
spacer_char = string(cview.BoxDrawingsLightHorizontal)
div_end = t.dividerEnd
}else{
spacer_char = "[::b]"+string(cview.BoxDrawingsHeavyHorizontal)+"[::-]"
div_end = string(cview.BoxDrawingsHeavyDownAndLeft)
}
*/
spacer_char := string(cview.BoxDrawingsLightHorizontal)
div_end := t.dividerEnd
 
spacer_str := ""
if t.width > 0 {
spacer_len := 0
for _, panel_test := range t.panels.panels{
spacer_len += len(t.tabLabels[panel_test.Name])+2
}
spacer_str = strings.Repeat(spacer_char, t.width-maxWidth-spacer_len+2)
}else{
spacer_str = strings.Repeat("─", maxWidth+1)
}
b.WriteString(spacer_str + div_end)
} else if !t.switcherAfterContent {
b.WriteString(t.dividerMid)
}
}
t.Switcher.SetText(b.String())
 
var reqLines int
if t.switcherVertical {
reqLines = maxWidth + 2
} else {
if t.switcherHeight > 0 {
reqLines = t.switcherHeight
} else {
reqLines = len(cview.WordWrap(t.Switcher.GetText(true), t.width))
if reqLines < 1 {
reqLines = 1
}
}
}
t.Flex.ResizeItem(t.Switcher, reqLines, 1)
}
 
func (t *TabbedPanels) updateVisibleTabs() {
allPanels := t.panels.panels
 
var newTab string
 
var foundCurrent bool
for _, panel := range allPanels {
if panel.Name == t.currentTab {
newTab = panel.Name
foundCurrent = true
break
}
}
if !foundCurrent {
for _, panel := range allPanels {
if panel.Name != "" {
newTab = panel.Name
break
}
}
}
 
if t.currentTab != newTab {
t.SetCurrentTab(newTab)
return
}
 
for _, panel := range allPanels {
if panel.Name == t.currentTab {
t.panels.ShowPanel(panel.Name)
} else {
t.panels.HidePanel(panel.Name)
}
}
}
 
func (t *TabbedPanels) updateAll() {
t.updateTabLabels()
t.updateVisibleTabs()
}
 
// Draw draws this cview.Primitive onto the screen.
func (t *TabbedPanels) Draw(screen tcell.Screen) {
if !t.GetVisible() {
return
}
 
t.Box.Draw(screen)
 
_, _, t.width, _ = t.GetInnerRect()
if t.width != t.lastWidth {
t.updateTabLabels()
}
t.lastWidth = t.width
 
t.Flex.Draw(screen)
}
 
// InputHandler returns the handler for this cview.Primitive.
func (t *TabbedPanels) InputHandler() func(event *tcell.EventKey, setFocus func(p cview.Primitive)) {
return t.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p cview.Primitive)) {
if t.setFocus == nil {
t.setFocus = setFocus
}
t.Flex.InputHandler()(event, setFocus)
})
}
 
// MouseHandler returns the mouse handler for this cview.Primitive.
func (t *TabbedPanels) MouseHandler() func(action cview.MouseAction, event *tcell.EventMouse, setFocus func(p cview.Primitive)) (consumed bool, capture cview.Primitive) {
return t.WrapMouseHandler(func(action cview.MouseAction, event *tcell.EventMouse, setFocus func(p cview.Primitive)) (consumed bool, capture cview.Primitive) {
if t.setFocus == nil {
t.setFocus = setFocus
}
 
x, y := event.Position()
if !t.InRect(x, y) {
return false, nil
}
 
if t.Switcher.InRect(x, y) {
if t.setFocus != nil {
defer t.setFocus(t.panels)
}
defer t.Switcher.MouseHandler()(action, event, setFocus)
return true, nil
}
 
return t.Flex.MouseHandler()(action, event, setFocus)
})
}
Buy Me A Coffee