turbo-editors/turbo-corepublic Fork 0
main
Commits
Clone
git clone https://git.rickub.com/turbo-editors/turbo-core.git
git clone ssh://git@rickub.com/turbo-editors/turbo-core.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

view_draw.go · 95 lines · 2.5 KBGo Blame HistoryRaw
🛟 Updated. 28d5985 k33g 5h ago1package filetree
2
3import (
4 "strings"
5
6 "github.com/gdamore/tcell/v2"
7
8 "codeberg.org/turbo-editors/turbo-core/theme"
9 "codeberg.org/turbo-editors/turbo-core/ui"
10)
11
12// Draw paints the visible rows and the scroll bar beside them.
13func (v *View) Draw(p *ui.Painter, th *theme.Theme) {
14 area := p.Sub(v.Bounds())
15 area.Clear(th.Style(theme.KeyTreeText))
16
17 rows := v.tree.Rows()
18 v.scrollToSelection(len(rows), area.Size().H)
19 width := max(area.Size().W-1, 0)
20
21 for line := range area.Size().H {
22 index := v.top + line
23 if index >= len(rows) {
24 break
25 }
26 v.drawRow(area, line, width, rows[index], index == v.selected, th)
27 }
28
29 ui.DrawVScrollBar(area, area.Size().W-1, 0, area.Size().H,
30 v.top, area.Size().H, len(rows),
31 th.Style(theme.KeyScrollBar), th.Style(theme.KeyScrollBarThumb))
32}
33
34// drawRow paints one entry: its indentation, its marker and its name.
35func (v *View) drawRow(p *ui.Painter, line, width int, row Row, selected bool, th *theme.Theme) {
36 style := v.styleFor(row.Node, selected, th)
37 if selected {
38 p.HLine(0, line, width, ' ', style)
39 }
40 p.TextLimited(0, line, width, label(row), style)
41}
42
43// label renders one row as the text to draw.
44//
45// A file is indented by a marker's width as well, so that names line up in a
46// column whatever their neighbours are.
47func label(row Row) string {
48 return strings.Repeat(indent, row.Depth) + marker(row.Node) + row.Node.Name()
49}
50
51// marker returns the glyph that says whether a directory is open, closed, or
52// not a directory at all.
53func marker(node *Node) string {
54 switch {
55 case !node.IsDir():
56 return fileMarker
57 case node.Expanded():
58 return openMarker
59 default:
60 return closedMarker
61 }
62}
63
64// styleFor picks the colour of one row.
65//
66// The highlight is dimmed when the tree does not have the focus, the same way
67// a list box dims its own, so that a screenful of windows still says where the
68// keyboard is.
69func (v *View) styleFor(node *Node, selected bool, th *theme.Theme) tcell.Style {
70 switch {
71 case selected && v.Focused():
72 return th.Style(theme.KeyTreeSelected)
73 case selected:
74 return th.Style(theme.KeyTreeUnfocused)
75 case node.IsDir():
76 return th.Style(theme.KeyTreeDirectory)
77 default:
78 return th.Style(theme.KeyTreeText)
79 }
80}
81
82// scrollToSelection moves the window of visible rows just enough to keep the
83// highlight on screen.
84func (v *View) scrollToSelection(total, height int) {
85 if height <= 0 {
86 return
87 }
88 if v.selected < v.top {
89 v.top = v.selected
90 }
91 if v.selected >= v.top+height {
92 v.top = v.selected - height + 1
93 }
94 v.top = min(max(v.top, 0), max(total-height, 0))
95}