turbo-editors/turbo-corepublic Fork 0
v1.0.0
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_events.go · 141 lines · 3.2 KBGo Blame HistoryRaw
🛟 Updated. 28d5985 k33g 18h ago1package filetree
2
3import "github.com/gdamore/tcell/v2"
4
5// HandleKey walks the tree, opens branches and chooses files.
6//
7// Left and right do what they do in every tree: right opens a closed branch
8// and steps into an open one, left closes an open branch and steps out of a
9// closed one, so the two together walk the shape without ever being a no-op.
10func (v *View) HandleKey(ev *tcell.EventKey) bool {
11 if !v.Focused() {
12 return false
13 }
14 if v.handleMovementKey(ev) {
15 return true
16 }
17
18 switch ev.Key() {
19 case tcell.KeyRight:
20 v.expandOrDescend()
21 case tcell.KeyLeft:
22 v.collapseOrAscend()
23 case tcell.KeyEnter:
24 v.Choose()
25 case tcell.KeyF5, tcell.KeyCtrlR:
26 v.Refresh()
27 default:
28 return false
29 }
30 return true
31}
32
33// handleMovementKey deals with the keys that only move the highlight.
34func (v *View) handleMovementKey(ev *tcell.EventKey) bool {
35 page := max(v.Bounds().H, 1)
36
37 switch ev.Key() {
38 case tcell.KeyUp:
39 v.move(-1)
40 case tcell.KeyDown:
41 v.move(1)
42 case tcell.KeyPgUp:
43 v.move(-page)
44 case tcell.KeyPgDn:
45 v.move(page)
46 case tcell.KeyHome:
47 v.moveTo(0)
48 case tcell.KeyEnd:
49 v.moveTo(len(v.tree.Rows()) - 1)
50 default:
51 return false
52 }
53 return true
54}
55
56// move shifts the highlight by a number of rows, stopping at either end.
57func (v *View) move(by int) { v.moveTo(v.selected + by) }
58
59// moveTo puts the highlight on a row, clamped to the rows there are.
60func (v *View) moveTo(index int) {
61 v.selected = min(max(index, 0), max(len(v.tree.Rows())-1, 0))
62}
63
64// expandOrDescend opens a closed directory, or steps into one already open.
65func (v *View) expandOrDescend() {
66 node := v.Selected()
67 if node == nil {
68 return
69 }
70 if node.IsDir() && !node.Expanded() {
71 node.Expand()
72 return
73 }
74 v.move(1)
75}
76
77// collapseOrAscend closes an open directory, or steps out to the parent of
78// anything else.
79func (v *View) collapseOrAscend() {
80 node := v.Selected()
81 if node == nil {
82 return
83 }
84 if node.IsDir() && node.Expanded() {
85 node.Collapse()
86 v.keepSelectionInRange()
87 return
88 }
89 v.selectParent()
90}
91
92// selectParent moves the highlight to the branch the current row sits in.
93//
94// The parent is the nearest row above with a smaller depth, which is what the
95// eye reads as "the folder this is in" — and needs no parent pointer on the
96// nodes to find.
97func (v *View) selectParent() {
98 rows := v.tree.Rows()
99 if v.selected <= 0 || v.selected >= len(rows) {
100 return
101 }
102
103 depth := rows[v.selected].Depth
104 for i := v.selected - 1; i >= 0; i-- {
105 if rows[i].Depth < depth {
106 v.selected = i
107 return
108 }
109 }
110}
111
112// HandleMouse highlights the clicked row, chooses it on a second click, and
113// scrolls with the wheel.
114func (v *View) HandleMouse(ev *tcell.EventMouse) bool {
115 if !v.Bounds().Contains(ev.Position()) {
116 return false
117 }
118
119 switch ev.Buttons() {
120 case tcell.WheelUp:
121 v.move(-wheelStep)
122 case tcell.WheelDown:
123 v.move(wheelStep)
124 case tcell.Button1:
125 v.clickRow(ev)
126 }
127 return true
128}
129
130// clickRow selects the row under the pointer, or acts on it when it was
131// already the selected one — the same second-click rule the list boxes use.
132func (v *View) clickRow(ev *tcell.EventMouse) {
133 _, y := ev.Position()
134 index := v.top + y - v.Bounds().Y
135
136 if index == v.selected {
137 v.Choose()
138 return
139 }
140 v.moveTo(index)
141}