added titlebar, some refactoring
This commit is contained in:
parent
f046166bad
commit
ba28a1714f
116
main.go
116
main.go
|
@ -23,7 +23,7 @@ var (
|
||||||
hosts tofu.KnownHosts
|
hosts tofu.KnownHosts
|
||||||
hostsfile *tofu.HostWriter
|
hostsfile *tofu.HostWriter
|
||||||
scanner *bufio.Scanner
|
scanner *bufio.Scanner
|
||||||
face font.Face
|
uiFace font.Face
|
||||||
fbinkOpts gofbink.FBInkConfig
|
fbinkOpts gofbink.FBInkConfig
|
||||||
fb *gofbink.FBInk
|
fb *gofbink.FBInk
|
||||||
f *truetype.Font
|
f *truetype.Font
|
||||||
|
@ -32,11 +32,12 @@ var (
|
||||||
|
|
||||||
// Visual options
|
// Visual options
|
||||||
const (
|
const (
|
||||||
width int = 1080
|
width int = 1080
|
||||||
height int = 1440 // TODO get from device instead of hardcoding
|
height int = 1440 // TODO get from device instead of hardcoding
|
||||||
linewidth float64 = 5
|
linewidth float64 = 5
|
||||||
oskpadding float64 = 20
|
oskpadding float64 = 20
|
||||||
keyspacing float64 = 5 // spacing between keys
|
keyspacing float64 = 5 // spacing between keys
|
||||||
|
titleBarHeight int = height / 6
|
||||||
)
|
)
|
||||||
|
|
||||||
func trustCertificate(hostname string, cert *x509.Certificate) error {
|
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() {
|
switch resp.Status.Class() {
|
||||||
case gemini.StatusClassInput: // TODO sensitive input
|
case gemini.StatusClassInput: // TODO sensitive input
|
||||||
input, err := GetInput(&face, resp.Meta+":")
|
input, err := GetInput(&uiFace, resp.Meta+":")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -94,6 +95,29 @@ func do(req *gemini.Request, via []*gemini.Request) (*gemini.Response, error) {
|
||||||
return resp, err
|
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() {
|
func main() {
|
||||||
// Framebuffer setup
|
// Framebuffer setup
|
||||||
fbinkOpts = gofbink.FBInkConfig{}
|
fbinkOpts = gofbink.FBInkConfig{}
|
||||||
|
@ -113,7 +137,7 @@ func main() {
|
||||||
// Logging setup
|
// Logging setup
|
||||||
var logFile, err = os.Create("/mnt/onboard/gemini.log")
|
var logFile, err = os.Create("/mnt/onboard/gemini.log")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
drawErrorBox(err, &face)
|
drawErrorBox(err, &uiFace)
|
||||||
}
|
}
|
||||||
var logger *log.Logger = log.New(logFile, "gemini", log.LstdFlags)
|
var logger *log.Logger = log.New(logFile, "gemini", log.LstdFlags)
|
||||||
defer logFile.Close()
|
defer logFile.Close()
|
||||||
|
@ -126,7 +150,7 @@ func main() {
|
||||||
}
|
}
|
||||||
err = hosts.Load(path)
|
err = hosts.Load(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
drawErrorBox(err, &face)
|
drawErrorBox(err, &uiFace)
|
||||||
logger.Fatal(err)
|
logger.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,53 +171,45 @@ func main() {
|
||||||
logger.Println(err)
|
logger.Println(err)
|
||||||
return
|
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 {
|
if err != nil {
|
||||||
fb.Println("Error: ")
|
drawErrorBox(err, &uiFace)
|
||||||
logger.Fatal(err)
|
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 {
|
for {
|
||||||
x, y, _ := t.GetInput()
|
x, y, _ := t.GetInput()
|
||||||
if x < 100 && y < 100 {
|
for _, b := range titleBarButtons {
|
||||||
break
|
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()
|
hostsfile.Close()
|
||||||
|
|
36
ui.go
36
ui.go
|
@ -33,6 +33,20 @@ type KeyLocation struct {
|
||||||
Keycode string
|
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 {
|
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 {
|
if x > k.X && x < k.X+k.W && y > k.Y && y < k.Y+k.H {
|
||||||
return true
|
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.
|
// 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
|
// TODO: more feedback to the user
|
||||||
func GetInput(f *font.Face, prompt string) (string, error) {
|
func GetInput(f *font.Face, prompt string) (string, error) {
|
||||||
|
|
Reference in New Issue