forked from peco/peco
-
Notifications
You must be signed in to change notification settings - Fork 0
/
view.go
101 lines (88 loc) · 2.06 KB
/
view.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package peco
import (
"sync"
"time"
)
// View handles the drawing/updating the screen
type View struct {
*Ctx
mutex sync.Locker
layout Layout
}
// PagingRequest can be sent to move the selection cursor
type PagingRequest int
const (
// ToLineAbove moves the selection to the line above
ToLineAbove PagingRequest = iota
// ToScrollPageDown moves the selection to the next page
ToScrollPageDown
// ToLineBelow moves the selection to the line below
ToLineBelow
// ToScrollPageUp moves the selection to the previous page
ToScrollPageUp
)
// StatusMsgRequest specifies the string to be drawn
// on the status message bar and an optional delay that tells
// the view to clear that message
type StatusMsgRequest struct {
message string
clearDelay time.Duration
}
// Loop receives requests to update the screen
func (v *View) Loop() {
defer v.ReleaseWaitGroup()
for {
select {
case <-v.LoopCh():
return
case m := <-v.StatusMsgCh():
v.printStatus(m.DataInterface().(StatusMsgRequest))
m.Done()
case r := <-v.PagingCh():
v.movePage(r.DataInterface().(PagingRequest))
r.Done()
case lines := <-v.DrawCh():
tmp := lines.DataInterface()
if tmp == nil {
v.drawScreen(nil)
} else if matches, ok := tmp.([]Line); ok {
v.drawScreen(matches)
} else if name, ok := tmp.(string); ok {
if name == "prompt" {
v.drawPrompt()
}
}
lines.Done()
}
}
}
func (v *View) printStatus(r StatusMsgRequest) {
v.layout.PrintStatus(r.message, r.clearDelay)
}
func (v *View) drawScreenNoLock(targets []Line) {
if targets == nil {
if current := v.GetCurrent(); current != nil {
targets = current
} else {
targets = v.GetLines()
}
}
v.layout.DrawScreen(targets)
v.SetCurrent(targets)
}
func (v *View) drawScreen(targets []Line) {
v.mutex.Lock()
defer v.mutex.Unlock()
v.drawScreenNoLock(targets)
}
func (v *View) drawPrompt() {
v.mutex.Lock()
defer v.mutex.Unlock()
v.layout.DrawPrompt()
}
func (v *View) movePage(p PagingRequest) {
v.mutex.Lock()
defer v.mutex.Unlock()
v.layout.MovePage(p)
v.drawScreenNoLock(nil)
}