commit b75cb83

Nomeji  ·  2022-06-23 10:05:32 +0000 UTC
parent b3f64ae
Scroll to the channel when changing the horizontal channel

Previously, when running CTRL+N or CTRL+P to go to the next or previous
channel, with the horizontal channel mode, the selected channel could
appear offscreen.

This patch ensures that we scroll just enough to make the newly selected
chan visible.

Thanks to Nomeji for his hard work on this. Adapted slightly to
refactor existing code to use the newly created width computation
routine.
3 files changed,  +50, -16
M app.go
M app.go
+2, -0
 1@@ -514,8 +514,10 @@ func (app *App) handleKeyEvent(ev *tcell.EventKey) {
 2 		app.win.ScrollDown()
 3 	case tcell.KeyCtrlN:
 4 		app.win.NextBuffer()
 5+		app.win.HorizontalBufferScrollTo()
 6 	case tcell.KeyCtrlP:
 7 		app.win.PreviousBuffer()
 8+		app.win.HorizontalBufferScrollTo()
 9 	case tcell.KeyRight:
10 		if ev.Modifiers() == tcell.ModAlt {
11 			app.win.NextBuffer()
+32, -16
 1@@ -607,14 +607,7 @@ func (bs *BufferList) HorizontalBufferOffset(x int, offset int) int {
 2 				return -1
 3 			}
 4 		}
 5-		if b.title == "" {
 6-			x -= stringWidth(b.netName)
 7-		} else {
 8-			x -= stringWidth(b.title)
 9-		}
10-		if 0 < b.highlights {
11-			x -= 2 + len(fmt.Sprintf("%d", b.highlights))
12-		}
13+		x -= bufferWidth(&b)
14 		if x < 0 {
15 			return offset + i
16 		}
17@@ -622,19 +615,42 @@ func (bs *BufferList) HorizontalBufferOffset(x int, offset int) int {
18 	return -1
19 }
20 
21+func (bs *BufferList) GetLeftMost(screenWidth int) int {
22+	width := 0
23+	var leftMost int
24+
25+	for leftMost = bs.current; leftMost >= 0; leftMost-- {
26+		if leftMost < bs.current {
27+			width++
28+		}
29+		width += bufferWidth(&bs.list[leftMost])
30+		if width > screenWidth {
31+			return leftMost + 1 // Went offscreen, need to go one step back
32+		}
33+	}
34+
35+	return 0
36+}
37+
38+func bufferWidth(b *buffer) int {
39+	width := 0
40+	if b.title == "" {
41+		width += stringWidth(b.netName)
42+	} else {
43+		width += stringWidth(b.title)
44+	}
45+	if 0 < b.highlights {
46+		width += 2 + len(fmt.Sprintf("%d", b.highlights))
47+	}
48+	return width
49+}
50+
51 func (bs *BufferList) DrawHorizontalBufferList(screen tcell.Screen, x0, y0, width int, offset *int) {
52 	x := width
53 	for i := len(bs.list) - 1; i >= 0; i-- {
54 		b := &bs.list[i]
55 		x--
56-		if b.title == "" {
57-			x -= stringWidth(b.netName)
58-		} else {
59-			x -= stringWidth(b.title)
60-		}
61-		if 0 < b.highlights {
62-			x -= 2 + len(fmt.Sprintf("%d", b.highlights))
63-		}
64+		x -= bufferWidth(b)
65 		if x <= 10 {
66 			break
67 		}
+16, -0
 1@@ -452,6 +452,22 @@ func (ui *UI) Draw(members []irc.Member) {
 2 	ui.screen.Show()
 3 }
 4 
 5+func (ui *UI) HorizontalBufferScrollTo() {
 6+	w, _ := ui.screen.Size()
 7+	screenWidth := w - ui.memberWidth
 8+	if ui.bs.current < ui.channelOffset {
 9+		ui.channelOffset = ui.bs.current
10+		return
11+	}
12+
13+	leftMost := ui.bs.GetLeftMost(screenWidth)
14+
15+	if ui.channelOffset >= leftMost {
16+		return
17+	}
18+	ui.channelOffset = leftMost
19+}
20+
21 func (ui *UI) drawStatusBar(x0, y, width int) {
22 	clearArea(ui.screen, x0, y, width, 1)
23