parent
cfce21cc90
commit
ce60530a57
|
@ -3,6 +3,7 @@ v1.4.6 (WIP)
|
|||
- Add Vim-style keybindings to List
|
||||
- Fix List not updating selected item before calling selected handlers
|
||||
- Do not handle right click on List when there is no context menu
|
||||
- Always initialize context menu List
|
||||
|
||||
v1.4.5 (2020-04-25)
|
||||
- Add multithreading support
|
||||
|
|
|
@ -18,9 +18,28 @@ type ContextMenu struct {
|
|||
|
||||
// NewContextMenu returns a new context menu.
|
||||
func NewContextMenu(parent Primitive) *ContextMenu {
|
||||
c := &ContextMenu{parent: parent}
|
||||
return &ContextMenu{
|
||||
parent: parent,
|
||||
}
|
||||
}
|
||||
|
||||
return c
|
||||
func (c *ContextMenu) initializeList() {
|
||||
if c.list != nil {
|
||||
return
|
||||
}
|
||||
|
||||
c.list = NewList().
|
||||
ShowSecondaryText(false).
|
||||
SetHover(true).
|
||||
SetWrapAround(true)
|
||||
c.list.
|
||||
SetBorder(true).
|
||||
SetBorderPadding(
|
||||
Styles.ContextMenuPaddingTop,
|
||||
Styles.ContextMenuPaddingBottom,
|
||||
Styles.ContextMenuPaddingLeft,
|
||||
Styles.ContextMenuPaddingRight)
|
||||
c.list.showFocus = false
|
||||
}
|
||||
|
||||
// ContextMenuList returns the underlying List of the context menu.
|
||||
|
@ -28,6 +47,8 @@ func (c *ContextMenu) ContextMenuList() *List {
|
|||
c.l.Lock()
|
||||
defer c.l.Unlock()
|
||||
|
||||
c.initializeList()
|
||||
|
||||
return c.list
|
||||
}
|
||||
|
||||
|
@ -37,20 +58,7 @@ func (c *ContextMenu) AddContextItem(text string, shortcut rune, selected func(i
|
|||
c.l.Lock()
|
||||
defer c.l.Unlock()
|
||||
|
||||
if c.list == nil {
|
||||
c.list = NewList().
|
||||
ShowSecondaryText(false).
|
||||
SetHover(true).
|
||||
SetWrapAround(true)
|
||||
c.list.
|
||||
SetBorder(true).
|
||||
SetBorderPadding(
|
||||
Styles.ContextMenuPaddingTop,
|
||||
Styles.ContextMenuPaddingBottom,
|
||||
Styles.ContextMenuPaddingLeft,
|
||||
Styles.ContextMenuPaddingRight)
|
||||
c.list.showFocus = false
|
||||
}
|
||||
c.initializeList()
|
||||
|
||||
c.list.AddItem(text, "", shortcut, c.wrap(selected))
|
||||
if text == "" && shortcut == 0 {
|
||||
|
@ -74,9 +82,9 @@ func (c *ContextMenu) ClearContextMenu() *ContextMenu {
|
|||
c.l.Lock()
|
||||
defer c.l.Unlock()
|
||||
|
||||
if c.list != nil {
|
||||
c.list.Clear()
|
||||
}
|
||||
c.initializeList()
|
||||
|
||||
c.list.Clear()
|
||||
|
||||
return c
|
||||
}
|
||||
|
@ -101,8 +109,26 @@ func (c *ContextMenu) ShowContextMenu(item int, x int, y int, setFocus func(Prim
|
|||
c.show(item, x, y, setFocus)
|
||||
}
|
||||
|
||||
// HideContextMenu hides the context menu.
|
||||
func (c *ContextMenu) HideContextMenu(setFocus func(Primitive)) {
|
||||
c.l.Lock()
|
||||
defer c.l.Unlock()
|
||||
|
||||
c.hide(setFocus)
|
||||
}
|
||||
|
||||
// ContextMenuVisible returns whether or not the context menu is visible.
|
||||
func (c *ContextMenu) ContextMenuVisible() bool {
|
||||
c.l.Lock()
|
||||
defer c.l.Unlock()
|
||||
|
||||
return c.open
|
||||
}
|
||||
|
||||
func (c *ContextMenu) show(item int, x int, y int, setFocus func(Primitive)) {
|
||||
if c.list == nil || len(c.list.items) == 0 {
|
||||
c.initializeList()
|
||||
|
||||
if len(c.list.items) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -139,11 +165,9 @@ func (c *ContextMenu) show(item int, x int, y int, setFocus func(Primitive)) {
|
|||
}
|
||||
|
||||
func (c *ContextMenu) hide(setFocus func(Primitive)) {
|
||||
c.open = false
|
||||
c.initializeList()
|
||||
|
||||
if c.list == nil {
|
||||
return
|
||||
}
|
||||
c.open = false
|
||||
|
||||
if c.list.HasFocus() {
|
||||
setFocus(c.parent)
|
||||
|
|
30
list.go
30
list.go
|
@ -577,12 +577,12 @@ func (l *List) Focus(delegate func(p Primitive)) {
|
|||
|
||||
// HasFocus returns whether or not this primitive has focus.
|
||||
func (l *List) HasFocus() bool {
|
||||
l.RLock()
|
||||
defer l.RUnlock()
|
||||
|
||||
if l.ContextMenu.open {
|
||||
return l.ContextMenu.list.HasFocus()
|
||||
}
|
||||
|
||||
l.RLock()
|
||||
defer l.RUnlock()
|
||||
return l.hasFocus
|
||||
}
|
||||
|
||||
|
@ -791,13 +791,13 @@ func (l *List) Draw(screen tcell.Screen) {
|
|||
|
||||
// Draw context menu.
|
||||
if hasFocus && l.ContextMenu.open {
|
||||
list := l.ContextMenu.list
|
||||
ctx := l.ContextMenuList()
|
||||
|
||||
x, y, width, height = l.GetInnerRect()
|
||||
|
||||
// What's the longest option text?
|
||||
maxWidth := 0
|
||||
for _, option := range list.items {
|
||||
for _, option := range ctx.items {
|
||||
strWidth := TaggedStringWidth(option.MainText)
|
||||
if option.Shortcut != 0 {
|
||||
strWidth += 4
|
||||
|
@ -807,15 +807,15 @@ func (l *List) Draw(screen tcell.Screen) {
|
|||
}
|
||||
}
|
||||
|
||||
lheight := len(list.items)
|
||||
lheight := len(ctx.items)
|
||||
lwidth := maxWidth
|
||||
|
||||
// Add space for borders
|
||||
lwidth += 2
|
||||
lheight += 2
|
||||
|
||||
lwidth += l.list.paddingLeft + l.list.paddingRight
|
||||
lheight += l.list.paddingTop + l.list.paddingBottom
|
||||
lwidth += ctx.paddingLeft + ctx.paddingRight
|
||||
lheight += ctx.paddingTop + ctx.paddingBottom
|
||||
|
||||
cx, cy := l.ContextMenu.x, l.ContextMenu.y
|
||||
if cx < 0 || cy < 0 {
|
||||
|
@ -834,12 +834,12 @@ func (l *List) Draw(screen tcell.Screen) {
|
|||
lheight = sheight - cy
|
||||
}
|
||||
|
||||
if list.scrollBarVisibility == ScrollBarAlways || (list.scrollBarVisibility == ScrollBarAuto && len(list.items) > lheight) {
|
||||
if ctx.scrollBarVisibility == ScrollBarAlways || (ctx.scrollBarVisibility == ScrollBarAuto && len(ctx.items) > lheight) {
|
||||
lwidth++ // Add space for scroll bar
|
||||
}
|
||||
|
||||
list.SetRect(cx, cy, lwidth, lheight)
|
||||
list.Draw(screen)
|
||||
ctx.SetRect(cx, cy, lwidth, lheight)
|
||||
ctx.Draw(screen)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1016,8 +1016,8 @@ func (l *List) MouseHandler() func(action MouseAction, event *tcell.EventMouse,
|
|||
l.Lock()
|
||||
|
||||
// Pass events to context menu.
|
||||
if l.ContextMenu.open && l.ContextMenu.list != nil && l.ContextMenu.list.InRect(event.Position()) {
|
||||
defer l.ContextMenu.list.MouseHandler()(action, event, setFocus)
|
||||
if l.ContextMenuVisible() && l.ContextMenuList().InRect(event.Position()) {
|
||||
defer l.ContextMenuList().MouseHandler()(action, event, setFocus)
|
||||
consumed = true
|
||||
l.Unlock()
|
||||
return
|
||||
|
@ -1031,7 +1031,7 @@ func (l *List) MouseHandler() func(action MouseAction, event *tcell.EventMouse,
|
|||
// Process mouse event.
|
||||
switch action {
|
||||
case MouseLeftClick:
|
||||
if l.ContextMenu.open {
|
||||
if l.ContextMenuVisible() {
|
||||
defer l.ContextMenu.hide(setFocus)
|
||||
consumed = true
|
||||
l.Unlock()
|
||||
|
@ -1073,7 +1073,7 @@ func (l *List) MouseHandler() func(action MouseAction, event *tcell.EventMouse,
|
|||
return
|
||||
}
|
||||
case MouseRightDown:
|
||||
if l.ContextMenu.list == nil || len(l.ContextMenu.list.items) == 0 {
|
||||
if len(l.ContextMenuList().items) == 0 {
|
||||
l.Unlock()
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue