From 09566a404358525948c4bc54fbe1a38df516de22 Mon Sep 17 00:00:00 2001 From: Bradley Cicenas Date: Fri, 3 Jan 2020 12:53:25 +0000 Subject: [PATCH] add optional tooltip to menu widget --- menus.go | 1 + widgets/menu/main.go | 26 +++++++++++++------ widgets/menu/tooltip.go | 55 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 8 deletions(-) create mode 100644 widgets/menu/tooltip.go diff --git a/menus.go b/menus.go index f891cd8..1b15281 100644 --- a/menus.go +++ b/menus.go @@ -129,6 +129,7 @@ func ColumnsMenu() MenuFn { m.Selectable = true m.SortItems = false m.BorderLabel = "Columns" + //m.SubText = "Enabled Columns" rebuild := func() { // get padding for right alignment of enabled status diff --git a/widgets/menu/main.go b/widgets/menu/main.go index e6f2df1..476bab8 100644 --- a/widgets/menu/main.go +++ b/widgets/menu/main.go @@ -11,13 +11,14 @@ type Padding [2]int // x,y padding type Menu struct { ui.Block SortItems bool // enable automatic sorting of menu items + Selectable bool // whether menu is navigable SubText string // optional text to display before items TextFgColor ui.Attribute TextBgColor ui.Attribute - Selectable bool cursorPos int items Items padding Padding + toolTip *ToolTip } func NewMenu() *Menu { @@ -71,13 +72,9 @@ func (m *Menu) SetCursor(s string) (success bool) { return false } -// Sort menu items(if enabled) and re-calculate window size -func (m *Menu) refresh() { - if m.SortItems { - sort.Sort(m.items) - } - m.calcSize() - ui.Render(m) +// SetToolTip sets an optional tooltip string to show at bottom of screen +func (m *Menu) SetToolTip(lines ...string) { + m.toolTip = NewToolTip(lines...) } func (m *Menu) SelectedItem() Item { @@ -117,6 +114,10 @@ func (m *Menu) Buffer() ui.Buffer { } } + if m.toolTip != nil { + buf.Merge(m.toolTip.Buffer()) + } + return buf } @@ -134,6 +135,15 @@ func (m *Menu) Down() { } } +// Sort menu items(if enabled) and re-calculate window size +func (m *Menu) refresh() { + if m.SortItems { + sort.Sort(m.items) + } + m.calcSize() + ui.Render(m) +} + // Set width and height based on menu items func (m *Menu) calcSize() { m.Width = 7 // minimum width diff --git a/widgets/menu/tooltip.go b/widgets/menu/tooltip.go new file mode 100644 index 0000000..1909ede --- /dev/null +++ b/widgets/menu/tooltip.go @@ -0,0 +1,55 @@ +package menu + +import ( + ui "github.com/gizak/termui" +) + +type ToolTip struct { + ui.Block + Lines []string + TextFgColor ui.Attribute + TextBgColor ui.Attribute + padding Padding +} + +func NewToolTip(lines ...string) *ToolTip { + t := &ToolTip{ + Block: *ui.NewBlock(), + Lines: lines, + TextFgColor: ui.ThemeAttr("menu.text.fg"), + TextBgColor: ui.ThemeAttr("menu.text.bg"), + padding: Padding{2, 1}, + } + t.BorderFg = ui.ThemeAttr("menu.border.fg") + t.BorderLabelFg = ui.ThemeAttr("menu.label.fg") + t.X = 1 + t.Align() + return t +} + +func (t *ToolTip) Buffer() ui.Buffer { + var cell ui.Cell + buf := t.Block.Buffer() + + y := t.Y + t.padding[1] + + for n, line := range t.Lines { + x := t.X + t.padding[0] + for _, ch := range line { + cell = ui.Cell{Ch: ch, Fg: t.TextFgColor, Bg: t.TextBgColor} + buf.Set(x, y+n, cell) + x++ + } + } + + return buf +} + +// Set width and height based on screen size +func (t *ToolTip) Align() { + t.Width = ui.TermWidth() - (t.padding[0] * 2) + t.Height = len(t.Lines) + (t.padding[1] * 2) + t.Y = ui.TermHeight() - t.Height + + t.Block.Align() +}