Worked out resizing and wrapping bugs. Now hard wraps, rather than soft.

This commit is contained in:
sloumdrone 2019-09-12 20:57:48 -07:00
parent bccca61ec2
commit 98e34576ca
7 changed files with 114 additions and 54 deletions

View File

@ -106,11 +106,11 @@ func (b Bookmarks) Render(termwidth, termheight int) []string {
bl = cui.Shapes["bl"] bl = cui.Shapes["bl"]
} }
out := make([]string, 5) out := make([]string, 0, 5)
top := fmt.Sprintf("%s%s%s", tl, strings.Repeat(ceil, width-2), tr) top := fmt.Sprintf("%s%s%s", tl, strings.Repeat(ceil, width-2), tr)
out = append(out, top) out = append(out, top)
marks := b.List() marks := b.List()
contentWidth := termwidth - 2 contentWidth := width - 2
for i := 0; i < termheight - 2; i++ { for i := 0; i < termheight - 2; i++ {
if i + b.Position >= b.Length { if i + b.Position >= b.Length {
out = append(out, fmt.Sprintf("%s%-*.*s%s", wall, contentWidth, contentWidth, "", wall )) out = append(out, fmt.Sprintf("%s%-*.*s%s", wall, contentWidth, contentWidth, "", wall ))

View File

@ -59,32 +59,45 @@ func (c *client) GetSize() {
c.Height = h c.Height = h
c.Width = w c.Width = w
if redraw { if redraw {
c.Draw() c.Draw()
} }
time.Sleep(1 * time.Second) time.Sleep(500 * time.Millisecond)
} }
} }
func (c *client) Draw() { func (c *client) Draw() {
var screen strings.Builder var screen strings.Builder
screen.Grow(c.Height * c.Width) screen.Grow(c.Height * c.Width)
screen.WriteString(c.TopBar.Render(c.Width, "This is a test")) screen.WriteString(c.TopBar.Render(c.Width))
screen.WriteString("\n") screen.WriteString("\n")
pageContent := c.PageState.Render(c.Height) pageContent := c.PageState.Render(c.Height, c.Width)
if c.BookMarks.IsOpen { if c.BookMarks.IsOpen {
bm := c.BookMarks.Render(c.Width, c.Height) bm := c.BookMarks.Render(c.Width, c.Height)
bmWidth := len([]rune(bm[0])) bmWidth := 40
for i, ln := range pageContent { for i := 0; i < c.Height - 3; i++ {
screen.WriteString(ln[:len(ln) - bmWidth]) if c.Width > bmWidth {
contentWidth := c.Width - bmWidth - 1
if i < len(pageContent) - 1 {
screen.WriteString(fmt.Sprintf("%-*.*s", contentWidth, contentWidth, pageContent[i]))
} else {
screen.WriteString(fmt.Sprintf("%-*.*s", contentWidth, contentWidth, " "))
}
}
screen.WriteString(bm[i]) screen.WriteString(bm[i])
screen.WriteString("\n") screen.WriteString("\n")
} }
} else { } else {
for _, ln := range pageContent { for i := 0; i < c.Height - 3; i++ {
screen.WriteString(ln) if i < len(pageContent) - 1 {
screen.WriteString("\n") screen.WriteString(pageContent[i])
screen.WriteString("\n")
} else {
screen.WriteString(fmt.Sprintf("%*s", c.Width, " "))
screen.WriteString("\n")
}
} }
} }
screen.WriteString("\n") // for the input line screen.WriteString("\n") // for the input line
@ -92,6 +105,7 @@ func (c *client) Draw() {
cui.Clear("screen") cui.Clear("screen")
cui.MoveCursorTo(0,0) cui.MoveCursorTo(0,0)
fmt.Print(screen.String()) fmt.Print(screen.String())
c.DrawMessage()
} }
func (c *client) TakeControlInput() { func (c *client) TakeControlInput() {
@ -100,34 +114,49 @@ func (c *client) TakeControlInput() {
switch input { switch input {
case 'j', 'J': case 'j', 'J':
// scroll down one line // scroll down one line
c.ClearMessage()
c.ClearMessageLine()
c.Scroll(1) c.Scroll(1)
case 'k', 'K': case 'k', 'K':
// scroll up one line // scroll up one line
c.ClearMessage()
c.ClearMessageLine()
c.Scroll(-1) c.Scroll(-1)
case 'q', 'Q': case 'q', 'Q':
// quite bombadillo // quite bombadillo
cui.Exit() cui.Exit()
case 'g': case 'g':
// scroll to top // scroll to top
c.ClearMessage()
c.ClearMessageLine()
c.Scroll(-len(c.PageState.History[c.PageState.Position].WrappedContent)) c.Scroll(-len(c.PageState.History[c.PageState.Position].WrappedContent))
case 'G': case 'G':
// scroll to bottom // scroll to bottom
c.ClearMessage()
c.ClearMessageLine()
c.Scroll(len(c.PageState.History[c.PageState.Position].WrappedContent)) c.Scroll(len(c.PageState.History[c.PageState.Position].WrappedContent))
case 'd': case 'd':
// scroll down 75% // scroll down 75%
c.ClearMessage()
c.ClearMessageLine()
distance := c.Height - c.Height / 4 distance := c.Height - c.Height / 4
c.Scroll(distance) c.Scroll(distance)
case 'u': case 'u':
// scroll up 75% // scroll up 75%
c.ClearMessage()
c.ClearMessageLine()
distance := c.Height - c.Height / 4 distance := c.Height - c.Height / 4
c.Scroll(-distance) c.Scroll(-distance)
case 'b': case 'b':
// go back // go back
c.ClearMessage()
c.ClearMessageLine()
err := c.PageState.NavigateHistory(-1) err := c.PageState.NavigateHistory(-1)
if err != nil { if err != nil {
c.SetMessage(err.Error(), false) c.SetMessage(err.Error(), false)
c.DrawMessage() c.DrawMessage()
} else { } else {
c.SetHeaderUrl()
c.Draw() c.Draw()
} }
case 'B': case 'B':
@ -136,11 +165,14 @@ func (c *client) TakeControlInput() {
c.Draw() c.Draw()
case 'f', 'F': case 'f', 'F':
// go forward // go forward
c.ClearMessage()
c.ClearMessageLine()
err := c.PageState.NavigateHistory(1) err := c.PageState.NavigateHistory(1)
if err != nil { if err != nil {
c.SetMessage(err.Error(), false) c.SetMessage(err.Error(), false)
c.DrawMessage() c.DrawMessage()
} else { } else {
c.SetHeaderUrl()
c.Draw() c.Draw()
} }
case '\t': case '\t':
@ -151,7 +183,6 @@ func (c *client) TakeControlInput() {
// Process a command // Process a command
c.ClearMessage() c.ClearMessage()
c.ClearMessageLine() c.ClearMessageLine()
cui.MoveCursorTo(c.Height-2, 0)
entry, err := cui.GetLine() entry, err := cui.GetLine()
c.ClearMessageLine() c.ClearMessageLine()
if err != nil { if err != nil {
@ -378,13 +409,13 @@ func (c *client) search() {
func (c *client) Scroll(amount int) { func (c *client) Scroll(amount int) {
page := c.PageState.History[c.PageState.Position] page := c.PageState.History[c.PageState.Position]
bottom := len(page.WrappedContent) - c.Height bottom := len(page.WrappedContent) - c.Height + 3 // 3 for the three bars: top, msg, bottom
if amount < 0 && page.ScrollPosition == 0 { if amount < 0 && page.ScrollPosition == 0 {
c.SetMessage("You are already at the top", false) c.SetMessage("You are already at the top", false)
c.DrawMessage() c.DrawMessage()
fmt.Print("\a") fmt.Print("\a")
return return
} else if amount > 0 && page.ScrollPosition == bottom || bottom < 0 { } else if (amount > 0 && page.ScrollPosition == bottom) || bottom < 0 {
c.SetMessage("You are already at the bottom", false) c.SetMessage("You are already at the bottom", false)
c.DrawMessage() c.DrawMessage()
fmt.Print("\a") fmt.Print("\a")
@ -398,7 +429,7 @@ func (c *client) Scroll(amount int) {
newScrollPosition = bottom newScrollPosition = bottom
} }
page.ScrollPosition = newScrollPosition c.PageState.History[c.PageState.Position].ScrollPosition = newScrollPosition
c.Draw() c.Draw()
} }
@ -464,9 +495,15 @@ func (c *client) goToLink(l string) {
return return
} }
} }
}
c.SetMessage(fmt.Sprintf("Invalid link id: %s", l), true) func (c *client) SetHeaderUrl() {
c.DrawMessage() if c.PageState.Length > 0 {
u := c.PageState.History[c.PageState.Position].Location.Full
c.TopBar.url = u
} else {
c.TopBar.url = ""
}
} }
func (c *client) Visit(url string) { func (c *client) Visit(url string) {
@ -487,6 +524,8 @@ func (c *client) Visit(url string) {
c.DrawMessage() c.DrawMessage()
return return
} }
c.SetMessage("Loading...", false)
c.DrawMessage()
content, links, err := gopher.Visit(u.Mime, u.Host, u.Port, u.Resource) content, links, err := gopher.Visit(u.Mime, u.Host, u.Port, u.Resource)
if err != nil { if err != nil {
c.SetMessage(err.Error(), true) c.SetMessage(err.Error(), true)
@ -496,6 +535,9 @@ func (c *client) Visit(url string) {
pg := MakePage(u, content, links) pg := MakePage(u, content, links)
pg.WrapContent(c.Width) pg.WrapContent(c.Width)
c.PageState.Add(pg) c.PageState.Add(pg)
c.ClearMessage()
c.ClearMessageLine()
c.SetHeaderUrl()
c.Draw() c.Draw()
case "gemini": case "gemini":
// TODO send over to gemini request // TODO send over to gemini request

View File

@ -10,6 +10,7 @@ import (
type Headbar struct { type Headbar struct {
title string title string
url string
} }
@ -27,9 +28,9 @@ func (h *Headbar) Draw() {
// without having to redraw everything else // without having to redraw everything else
} }
func (h *Headbar) Render(width int, message string) string { func (h *Headbar) Render(width int) string {
maxMsgWidth := width - len([]rune(h.title)) maxMsgWidth := width - len([]rune(h.title))
return fmt.Sprintf("\033[7m%s%-*.*s\033[0m", h.title, maxMsgWidth, maxMsgWidth, message) return fmt.Sprintf("\033[7m%s%-*.*s\033[0m", h.title, maxMsgWidth, maxMsgWidth, h.url)
} }
@ -38,6 +39,6 @@ func (h *Headbar) Render(width int, message string) string {
//--------------------------------------------------\\ //--------------------------------------------------\\
func MakeHeadbar(title string) Headbar { func MakeHeadbar(title string) Headbar {
return Headbar{title} return Headbar{title, ""}
} }

View File

@ -163,6 +163,10 @@ func loadConfig() error {
} }
} }
for i, v := range settings.Bookmarks.Titles {
bombadillo.BookMarks.Add([]string{v, settings.Bookmarks.Links[i]})
}
return nil return nil
} }
@ -174,8 +178,8 @@ func initClient() error {
} }
func main() { func main() {
// cui.HandleAlternateScreen("smcup") cui.HandleAlternateScreen("smcup")
// defer cui.Exit() defer cui.Exit()
err := initClient() err := initClient()
if err != nil { if err != nil {
// if we can't initialize we should bail out // if we can't initialize we should bail out

45
page.go
View File

@ -2,7 +2,6 @@ package main
import ( import (
"strings" "strings"
"bytes"
) )
//------------------------------------------------\\ //------------------------------------------------\\
@ -42,35 +41,31 @@ func (p *Page) ScrollPositionRange(termHeight int) (int, int) {
func (p *Page) WrapContent(width int) { func (p *Page) WrapContent(width int) {
// TODO this is a temporary wrapping function // TODO this is a temporary wrapping function
// in order to test. Rebuild it. // in order to test. Rebuild it.
src := strings.Split(p.RawContent, "\n") counter := 0
out := []string{} var content strings.Builder
for _, ln := range src { content.Grow(len(p.RawContent))
if len([]rune(ln)) <= width { for _, ch := range p.RawContent {
out = append(out, ln) if ch == '\n' {
content.WriteRune(ch)
counter = 0
} else { } else {
words := strings.SplitAfter(ln, " ") if counter < width {
var subout bytes.Buffer content.WriteRune(ch)
for i, wd := range words { counter++
sublen := subout.Len() } else {
wdlen := len([]rune(wd)) content.WriteRune('\n')
if sublen+wdlen <= width { counter = 0
subout.WriteString(wd) if p.Location.Mime == "1" {
if i == len(words)-1 { spacer := " "
out = append(out, subout.String()) content.WriteString(spacer)
} counter += len(spacer)
} else {
out = append(out, subout.String())
subout.Reset()
subout.WriteString(wd)
if i == len(words)-1 {
out = append(out, subout.String())
subout.Reset()
}
} }
content.WriteRune(ch)
} }
} }
} }
p.WrappedContent = out
p.WrappedContent = strings.Split(content.String(), "\n")
} }
//------------------------------------------------\\ //------------------------------------------------\\

View File

@ -2,7 +2,6 @@ package main
import ( import (
"fmt" "fmt"
"strings"
) )
//------------------------------------------------\\ //------------------------------------------------\\
@ -49,13 +48,32 @@ func (p *Pages) Add(pg Page) {
} }
} }
func (p *Pages) Render(termHeight int) []string { func (p *Pages) Render(termHeight, termWidth int) []string {
if p.Length < 1 { if p.Length < 1 {
msg := "Welcome to Bombadillo,\nif this is your first time here\ntype:\n\n:help\n(and then press enter)" return []string{""}
return strings.Split(msg, "\n")
} }
beg, end := p.History[p.Position].ScrollPositionRange(termHeight) pos := p.History[p.Position].ScrollPosition
return p.History[p.Position].WrappedContent[beg:end] prev := len(p.History[p.Position].WrappedContent)
p.History[p.Position].WrapContent(termWidth)
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
if pos > now - termHeight {
pos = now - termHeight
}
}
if pos < 0 || now < termHeight - 3 {
pos = 0
}
p.History[p.Position].ScrollPosition = pos
return p.History[p.Position].WrappedContent[pos:]
} }
//------------------------------------------------\\ //------------------------------------------------\\

2
url.go
View File

@ -78,7 +78,7 @@ func MakeUrl(u string) (Url, error) {
} }
if out.Scheme == "gopher" && out.Mime == "" { if out.Scheme == "gopher" && out.Mime == "" {
out.Mime = "0" out.Mime = "1"
} }
if out.Mime == "" && (out.Resource == "" || out.Resource == "/") && out.Scheme == "gopher" { if out.Mime == "" && (out.Resource == "" || out.Resource == "/") && out.Scheme == "gopher" {