package tui import ( "github.com/rivo/uniseg" "strings" ) var menuStyle = Style {Fg: Black, Bg: Yellow} var menuState struct { open bool x, y int width, height int boxId string menu []string selected string } func MenuOption(name string) bool { b := top() b.contextMenu = append(b.contextMenu, name) if menuState.boxId == top().id && menuState.selected == name { menuState.selected = "" return true } return false } func openContextMenu(x int, y int, b *Box) { menuState.open = true menuState.boxId = b.id menuState.menu = b.contextMenu menuState.height = len(menuState.menu) for _, option := range menuState.menu { menuState.width = max(menuState.width, uniseg.StringWidth(option)) } size := Size() if x + menuState.width < size.Width { menuState.x = x + 1 } else { menuState.x = x - menuState.width - 1 } if y + menuState.height < size.Height { menuState.y = y } else { menuState.y = y - menuState.height } } func processContextMenu(ev MouseEvent) { for i, option := range menuState.menu { x, y := menuState.x, menuState.y + i if ev.Button <= 2 && (ev.Pressed || ev.Released) && ev.X >= x && ev.X < x + menuState.width && ev.Y == y { menuState.selected = option menuState.open = false } } if ev.Button <= 2 && ev.Pressed { menuState.open = false } } func drawContextMenu() { if !menuState.open { return } for i, option := range menuState.menu { x, y := menuState.x, menuState.y + i WriteAt(x, y, strings.Repeat(" ", menuState.width), menuStyle) WriteAt(x, y, option, menuStyle) } }