peco.peco/view.go
2015-09-28 21:38:40 +09:00

112 lines
2.2 KiB
Go

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 PagingRequestType int
type PagingRequest interface {
Type() PagingRequestType
}
func (prt PagingRequestType) Type() PagingRequestType {
return prt
}
type JumpToLineRequest uint
func (jlr JumpToLineRequest) Type() PagingRequestType {
return ToLineInPage
}
func (jlr JumpToLineRequest) Line() int {
return int(jlr)
}
const (
// ToLineAbove moves the selection to the line above
ToLineAbove PagingRequestType = 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
// ToScrollLeft scrolls screen to the left
ToScrollLeft
// ToScrollRight scrolls screen to the right
ToScrollRight
ToLineInPage
)
// 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()
switch tmp.(type) {
case string:
if tmp.(string) == "prompt" {
v.drawPrompt()
}
case bool:
v.drawScreen(tmp.(bool))
default:
v.drawScreen(false)
}
lines.Done()
}
}
}
func (v *View) printStatus(r StatusMsgRequest) {
v.layout.PrintStatus(r.message, r.clearDelay)
}
func (v *View) drawScreen(runningQuery bool) {
v.mutex.Lock()
defer v.mutex.Unlock()
v.layout.DrawScreen(runningQuery)
}
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()
if v.layout.MovePage(p) {
v.layout.DrawScreen(false)
}
}