prime8dev

prime8dev
git clone https://git.prime8.dev/prime8dev.git
Log | Files | Refs | README | LICENSE

hscroll.go (1624B)


      1 package tui
      2 
      3 import (
      4 	"strings"
      5 
      6 	"github.com/charmbracelet/x/ansi"
      7 )
      8 
      9 const detailHorizontalStep = 8
     10 
     11 var cutMarkerStyle = dimStyle
     12 
     13 func lineWidths(content string) []int {
     14 	lines := strings.Split(content, "\n")
     15 	widths := make([]int, len(lines))
     16 	for i, l := range lines {
     17 		widths[i] = ansi.StringWidth(l)
     18 	}
     19 	return widths
     20 }
     21 
     22 func (m portfolioModel) detailMaxXOffset() int {
     23 	longest := 0
     24 	for _, w := range m.detailLineWidths {
     25 		longest = max(longest, w)
     26 	}
     27 	return max(longest-m.viewport.Width, 0)
     28 }
     29 
     30 // scrollDetailX pans the detail viewport sideways; only wide preformatted
     31 // blocks are wider than the pane, so prose never moves out of view for long.
     32 func (m *portfolioModel) scrollDetailX(delta int) {
     33 	m.detailXOffset = min(max(m.detailXOffset+delta, 0), m.detailMaxXOffset())
     34 	m.viewport.SetXOffset(m.detailXOffset)
     35 }
     36 
     37 // detailViewWithCutMarkers renders the viewport and marks lines that continue
     38 // past the right edge with › (and past the left edge with ‹ when panned).
     39 func (m portfolioModel) detailViewWithCutMarkers() string {
     40 	view := m.viewport.View()
     41 	w := m.viewport.Width
     42 	if w < 4 || m.detailMaxXOffset() == 0 {
     43 		return view
     44 	}
     45 	lines := strings.Split(view, "\n")
     46 	for i, line := range lines {
     47 		idx := m.viewport.YOffset + i
     48 		if idx >= len(m.detailLineWidths) {
     49 			break
     50 		}
     51 		full := m.detailLineWidths[idx]
     52 		if full > m.detailXOffset+w {
     53 			line = ansi.Truncate(line, w-1, "") + cutMarkerStyle.Render("›")
     54 		}
     55 		if m.detailXOffset > 0 && full > m.detailXOffset {
     56 			line = cutMarkerStyle.Render("‹") + ansi.Cut(line, 1, w)
     57 		}
     58 		lines[i] = line
     59 	}
     60 	return strings.Join(lines, "\n")
     61 }