bombadillo/pages.go

109 lines
3.1 KiB
Go
Raw Normal View History

package main
import (
"fmt"
)
//------------------------------------------------\\
// + + + T Y P E S + + + \\
//--------------------------------------------------\\
// Pages is a struct that represents the history of the client.
// It functions as a container for the pages (history array) and
// tracks the current history length and location.
type Pages struct {
Position int
2019-11-10 18:41:12 +00:00
Length int
History [20]Page
}
//------------------------------------------------\\
// + + + R E C E I V E R S + + + \\
//--------------------------------------------------\\
// NavigateHistory takes a positive or negative integer
// and updates the current history position. Checks are done
// to make sure that the position moved to is a valid history
// location. Returns an error or nil.
func (p *Pages) NavigateHistory(qty int) error {
newPosition := p.Position + qty
if newPosition < 0 {
return fmt.Errorf("You are already at the beginning of history")
2019-11-10 18:41:12 +00:00
} else if newPosition > p.Length-1 {
return fmt.Errorf("Your way is blocked by void, there is nothing forward")
}
p.Position = newPosition
return nil
}
// Add gets passed a Page, which gets added to the history
// arrayr. Add also updates the current length and position
// of the Pages struct to which it belongs. Add also shifts
// off array items if necessary.
2019-09-12 05:53:36 +00:00
func (p *Pages) Add(pg Page) {
2019-11-10 18:41:12 +00:00
if p.Position == p.Length-1 && p.Length < len(p.History) {
2019-09-12 05:53:36 +00:00
p.History[p.Length] = pg
p.Length++
p.Position++
2019-11-10 18:41:12 +00:00
} else if p.Position == p.Length-1 && p.Length == 20 {
2019-09-12 05:53:36 +00:00
for x := 1; x < len(p.History); x++ {
p.History[x-1] = p.History[x]
}
p.History[len(p.History)-1] = pg
} else {
2019-11-10 19:35:52 +00:00
p.Position++
2019-09-12 05:53:36 +00:00
p.Length = p.Position + 1
p.History[p.Position] = pg
}
}
// Render wraps the content for the current page and returns
// the page content as a string slice
func (p *Pages) Render(termHeight, termWidth int, color bool) []string {
2019-09-12 05:53:36 +00:00
if p.Length < 1 {
return make([]string, 0)
2019-09-12 05:53:36 +00:00
}
pos := p.History[p.Position].ScrollPosition
prev := len(p.History[p.Position].WrappedContent)
// TODO figure out a way to only do this when needed
// it is horribly slow to do this every render.
//
// Current thought is add a "WrapWidth" to each page
// and compare the WrapWidth against the width being
// passed in here. If it is different then go through
// all of that. Otherwise, just send the already wrapped
// data.
p.History[p.Position].WrapContent(termWidth, color)
now := len(p.History[p.Position].WrappedContent)
if prev > now {
diff := prev - now
pos = pos - diff
} else if prev < now {
diff := now - prev
pos = pos + diff
2019-11-10 18:41:12 +00:00
if pos > now-termHeight {
pos = now - termHeight
}
}
2019-11-10 18:41:12 +00:00
if pos < 0 || now < termHeight-3 {
pos = 0
}
p.History[p.Position].ScrollPosition = pos
return p.History[p.Position].WrappedContent[pos:]
}
//------------------------------------------------\\
// + + + F U N C T I O N S + + + \\
//--------------------------------------------------\\
// MakePages returns a Pages struct with default values
func MakePages() Pages {
return Pages{-1, 0, [20]Page{}}
}