added titlebar, some refactoring

This commit is contained in:
Nico 2021-02-14 19:44:10 +00:00
parent f046166bad
commit ba28a1714f
2 changed files with 102 additions and 50 deletions

116
main.go
View File

@ -23,7 +23,7 @@ var (
hosts tofu.KnownHosts
hostsfile *tofu.HostWriter
scanner *bufio.Scanner
face font.Face
uiFace font.Face
fbinkOpts gofbink.FBInkConfig
fb *gofbink.FBInk
f *truetype.Font
@ -32,11 +32,12 @@ var (
// Visual options
const (
width int = 1080
height int = 1440 // TODO get from device instead of hardcoding
linewidth float64 = 5
oskpadding float64 = 20
keyspacing float64 = 5 // spacing between keys
width int = 1080
height int = 1440 // TODO get from device instead of hardcoding
linewidth float64 = 5
oskpadding float64 = 20
keyspacing float64 = 5 // spacing between keys
titleBarHeight int = height / 6
)
func trustCertificate(hostname string, cert *x509.Certificate) error {
@ -67,7 +68,7 @@ func do(req *gemini.Request, via []*gemini.Request) (*gemini.Response, error) {
switch resp.Status.Class() {
case gemini.StatusClassInput: // TODO sensitive input
input, err := GetInput(&face, resp.Meta+":")
input, err := GetInput(&uiFace, resp.Meta+":")
if err != nil {
break
}
@ -94,6 +95,29 @@ func do(req *gemini.Request, via []*gemini.Request) (*gemini.Response, error) {
return resp, err
}
func getPage(u *url.URL) (string, error) {
req, err := gemini.NewRequest(u.String())
if err != nil {
return "", nil
}
resp, err := do(req, nil)
if err != nil {
return "", nil
}
defer resp.Body.Close()
// Handle response
if resp.Status.Class() == gemini.StatusClassSuccess {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
return string(body), nil
} else {
return "", errors.New(fmt.Sprintf("%s %s", string(resp.Status), string(resp.Meta)))
}
}
func main() {
// Framebuffer setup
fbinkOpts = gofbink.FBInkConfig{}
@ -113,7 +137,7 @@ func main() {
// Logging setup
var logFile, err = os.Create("/mnt/onboard/gemini.log")
if err != nil {
drawErrorBox(err, &face)
drawErrorBox(err, &uiFace)
}
var logger *log.Logger = log.New(logFile, "gemini", log.LstdFlags)
defer logFile.Close()
@ -126,7 +150,7 @@ func main() {
}
err = hosts.Load(path)
if err != nil {
drawErrorBox(err, &face)
drawErrorBox(err, &uiFace)
logger.Fatal(err)
}
@ -147,53 +171,45 @@ func main() {
logger.Println(err)
return
}
face = truetype.NewFace(f, &truetype.Options{Size: 32})
uiFace = truetype.NewFace(f, &truetype.Options{Size: 32})
str, err := GetInput(&face, "Test:")
titleBarButtons, err := DrawTitleBar(&uiFace)
if err != nil {
fb.Println("Error: ")
drawErrorBox(err, &uiFace)
logger.Fatal(err)
}
u, err := url.Parse(str)
if err != nil {
drawErrorBox(err, &face)
logger.Println(err)
}
if u.Scheme == "" {
u.Scheme = "gemini"
}
fmt.Println(u.String())
req, err := gemini.NewRequest(u.String())
if err != nil {
drawErrorBox(err, &face)
logger.Fatal(err)
}
resp, err := do(req, nil)
if err != nil {
drawErrorBox(err, &face)
logger.Fatal(err)
}
defer resp.Body.Close()
// Handle response
if resp.Status.Class() == gemini.StatusClassSuccess {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
drawErrorBox(err, &face)
logger.Fatal(err)
}
fb.ClearScreen(&fbinkOpts)
fb.Println(string(body))
fmt.Println(string(body))
} else {
fb.Println(fmt.Sprintf("%d %s\n", resp.Status, resp.Meta))
}
for {
x, y, _ := t.GetInput()
if x < 100 && y < 100 {
break
for _, b := range titleBarButtons {
if touchingButton(x, y, b) {
if b.Label == "Exit" {
return
} else if b.Label == "Go" {
str, err := GetInput(&uiFace, "Enter URL:")
if err != nil {
drawErrorBox(err, &uiFace)
logger.Println(err)
}
u, err := url.Parse(str)
if err != nil {
drawErrorBox(err, &uiFace)
logger.Println(err)
}
if u.Scheme == "" {
u.Scheme = "gemini"
}
content, err := getPage(u)
if err != nil {
drawErrorBox(err, &uiFace)
logger.Println(err)
} else {
fb.Println(content) // TODO rendering, not this! Also links
}
}
}
}
}
hostsfile.Close()

36
ui.go
View File

@ -33,6 +33,20 @@ type KeyLocation struct {
Keycode string
}
// Button records a button and where it is on screen so it can be pressed
type Button struct {
X, Y, W, H int
Label string
}
func touchingButton(x, y int, b Button) bool {
if x > b.X && x < b.X+b.W && y > b.Y && y < b.Y+b.H {
return true
} else {
return false
}
}
func touchingKey(x, y int, k KeyLocation) bool {
if x > k.X && x < k.X+k.W && y > k.Y && y < k.Y+k.H {
return true
@ -63,6 +77,28 @@ func drawDialog(text string, f *font.Face) {
}
func DrawTitleBar(f *font.Face) ([]Button, error) {
buttons := []Button{
Button{X: 0, Y: 0, W: width / 2, H: 100, Label: "Exit"},
Button{X: width / 2, Y: 0, W: width / 2, H: 100, Label: "Go"}}
i := image.NewRGBA(image.Rect(0, 0, width, titleBarHeight))
dc := gg.NewContextForRGBA(i)
if *f != nil {
dc.SetFontFace(*f)
}
dc.SetLineWidth(linewidth)
for _, b := range buttons {
dc.DrawRectangle(float64(b.X), float64(b.Y), float64(b.W), float64(b.H))
dc.SetRGB(1, 1, 1)
dc.FillPreserve()
dc.SetRGB(0, 0, 0)
dc.Stroke()
dc.DrawStringWrapped(b.Label, float64(b.X+b.W/2), float64(b.Y+b.H/2), 0.5, 0.5, float64(b.W), 1.0, gg.AlignCenter)
}
fb.PrintRBGA(0, 0, i, &fbinkOpts)
return buttons, nil
}
// GetInput draws an OSK and dialog then gets input from the user. It returns the inputted string and a potential error.
// TODO: more feedback to the user
func GetInput(f *font.Face, prompt string) (string, error) {