diff options
| author | citrons <citrons@mondecitronne.com> | 2025-06-07 15:58:35 -0500 |
|---|---|---|
| committer | citrons <citrons@mondecitronne.com> | 2025-06-07 16:02:18 -0500 |
| commit | 4fd84671877754ae3b66acb8a8af8cf0935a53c9 (patch) | |
| tree | 4d7b6de81bd28e0c1184037f236e1a0e3701b646 | |
| parent | 4067adfc361e87bc4e73e31fdfc4933802f05413 (diff) | |
context menus
| -rw-r--r-- | client/channel_window.go | 10 | ||||
| -rw-r--r-- | tui/context_menu.go | 75 | ||||
| -rw-r--r-- | tui/layout.go | 15 |
3 files changed, 97 insertions, 3 deletions
diff --git a/client/channel_window.go b/client/channel_window.go index 3fec792..95f0dbf 100644 --- a/client/channel_window.go +++ b/client/channel_window.go @@ -3,6 +3,7 @@ package main import ( "citrons.xyz/talk/client/buffer" "citrons.xyz/talk/client/window" + "citrons.xyz/talk/client/clipboard" "citrons.xyz/talk/proto" "citrons.xyz/talk/tui" "strconv" @@ -297,11 +298,16 @@ func (m channelMsg) Show(odd bool) { m.showName(bg) tui.Pop() - tui.Push("", tui.Box { - Width: tui.TextSize, Height: tui.TextSize, + tui.Push(m.Id() + ".content", tui.Box { + Width: tui.Fill, Height: tui.TextSize, Margins: [4]int {1, 0, 0, 0}, }) tui.Text(m.Fields[""], nil) + switch { + case tui.MenuOption("copy"): + clipboard.Get().Copy(m.Fields[""]) + case tui.MenuOption("reply"): + } tui.Pop() default: tui.Push("", tui.Box {Width: tui.Fill, Height: tui.TextSize}) diff --git a/tui/context_menu.go b/tui/context_menu.go new file mode 100644 index 0000000..e6d5bb9 --- /dev/null +++ b/tui/context_menu.go @@ -0,0 +1,75 @@ +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) + } +} diff --git a/tui/layout.go b/tui/layout.go index ede0fa6..039ce52 100644 --- a/tui/layout.go +++ b/tui/layout.go @@ -24,6 +24,7 @@ type Box struct { computedRect rect isOverflow bool mouseEvent MouseEvent + contextMenu []string } type BoxSize int @@ -439,6 +440,9 @@ func (b *Box) mouseEvents(ev MouseEvent) { bev.Pressed = ev.Pressed bev.Released = ev.Released bev.Scroll = ev.Scroll + if ev.Pressed && ev.Button == 2 && len(b.contextMenu) > 0 { + openContextMenu(ev.X, ev.Y, b) + } } b.mouseEvent = bev for _, c := range b.children { @@ -470,5 +474,14 @@ func DrawLayout() { b.drawComputed(parentRect, DefaultStyle) ev := getLastEvent() - b.mouseEvents(ev.Mouse) + if menuState.open { + processContextMenu(ev.Mouse) + var releaseEvent MouseEvent + releaseEvent.Button = ev.Mouse.Button + releaseEvent.ReleasedAnywhere = ev.Mouse.ReleasedAnywhere + b.mouseEvents(releaseEvent) + } else { + b.mouseEvents(ev.Mouse) + } + drawContextMenu() } |
