Updated examples and added more documentation

This commit is contained in:
Sasha Koshka 2022-11-19 18:00:47 -05:00
parent 9a8bb85afc
commit 9a37fbf04a
4 changed files with 110 additions and 25 deletions

View File

@ -33,42 +33,60 @@ func (application *Application) Run () (
return
}
// OnQuit registers an event handler to be called just before the application
// quits. This can happen when the user closes the application, or the backend
// experiences an unrecoverable error.
func (application *Application) OnQuit (
onQuit func (),
) {
application.callbackManager.onQuit = onQuit
}
// OnPress registers an event handler to be called when a key or mouse button
// is pressed.
func (application *Application) OnPress (
onPress func (button Button),
) {
application.callbackManager.onPress = onPress
}
// OnPress registers an event handler to be called when a key or mouse button
// is released.
func (application *Application) OnRelease (
onRelease func (button Button),
) {
application.callbackManager.onRelease = onRelease
}
// OnResize registers an event handler to be called when the application window
// is resized. After the event handler is called, any updates it makes will
// automatically be pushed to the screen.
func (application *Application) OnResize (
onResize func (),
) {
application.callbackManager.onResize = onResize
}
// OnMouseMove registers an event handler to be called when mouse motion is
// detected. The coordinates of the cell that the mouse now hovers over are
// given as input.
func (application *Application) OnMouseMove (
onMouseMove func (x, y int),
) {
application.callbackManager.onMouseMove = onMouseMove
}
// OnScroll registers an event handler to be called when the user uses the mouse
// scroll wheel. Horizontal and vertical amounts are given as input.
func (application *Application) OnScroll (
onScroll func (x, y int),
) {
application.callbackManager.onScroll = onScroll
}
// OnStart registers an event handler to be called once when the application
// starts, right before the first time updates are pushed to the screen.
// Anything done in here will be the first thing to appear on screen.
func (application *Application) OnStart (
onStart func (),
) {

View File

@ -3,13 +3,51 @@ package stone
import "image"
import "errors"
// Backend represents a backend for stone. Backends can be registered for use
// with the RegisterBackend() function. All of the below methods MUST be thread
// safe!
type Backend interface {
Run ()
// Run is the backend's event loop. It must cleanly exit when the user
// closes the window, but not before calling the OnQuit event. Run
// must call event handlers within its own event loop in a
// non-concurrent fashion.
//
// The OnStart event handler must run after the backend has been fully
// initialized, and right before updates are first pushed to the screen.
// Whatever the application draws from within this event handler must be
// the first thing that appears on-screen.
//
// The OnResize evnt handler must run whenever the window is resized.
// The backend must push updates to the screen after OnResize has been
// run.
//
// The backend must not push updates to the screen in any other case,
// except when its Draw() method is specifically called.
//
// The OnPress, OnRelease, OnMouseMove, and OnMouseScroll events are to
// be called when such events happen. It is reccommended to compress
// resize, mouse move, and mouse scroll events whenever possible to
// reduce the likelihood of event buildup.
Run ()
// SetTitle sets the application title. This will most often be the
// window title. This method may not always produce an effect, depending
// on the backend.
SetTitle (title string) (err error)
SetIcon (icons []image.Image) (err error)
Draw ()
// SetIcon takes in a set of images of different sizes and sets the
// window's icon to them. This method may not always produce an effect,
// depending on the backend.
SetIcon (icons []image.Image) (err error)
// Draw pushes all updates made to the application's buffer to the
// screen.
Draw ()
}
// BackendFactory should completely initialize a backend, and return it. If
// anything goes wrong, it should stop, clean up any resources and return an
// error so another backend can be chosen.
type BackendFactory func (
application *Application,
callbackManager *CallbackManager,
@ -20,6 +58,7 @@ type BackendFactory func (
var factories []BackendFactory
// RegisterBackend registers a backend factory.
func RegisterBackend (factory BackendFactory) {
factories = append(factories, factory)
}

View File

@ -58,7 +58,7 @@ func redraw () {
application.SetRune(0, height - 1, '+')
for x := 0; x < width; x ++ {
application.SetColor(x, height / 2, stone.Color(x % 6 + 2))
application.SetColor(x, height / 2, stone.Color(x % 5 + 3))
}
for x := 1; x < width - 1; x ++ {

View File

@ -1,17 +1,20 @@
package main
import "os"
import "fmt"
import "image"
import _ "image/png"
import "git.tebibyte.media/sashakoshka/stone"
import _ "git.tebibyte.media/sashakoshka/stone/backends/x"
var application = &stone.Application { }
var caret = 0
var caretX = 0
var caretY = 2
var page = 1
func main () {
application.SetTitle("hellorld")
application.SetSize(32, 16)
application.SetSize(32, 28)
iconFile16, err := os.Open("assets/scaffold16.png")
if err != nil { panic(err) }
@ -25,32 +28,57 @@ func main () {
iconFile16.Close()
application.SetIcon([]image.Image { icon16, icon32 })
application.OnStart(redraw)
application.OnPress(onPress)
application.OnResize(redraw)
channel, err := application.Run()
err = application.Run()
if err != nil { panic(err) }
application.Draw()
}
for {
event := <- channel
switch event.(type) {
case stone.EventQuit:
os.Exit(0)
func redraw () {
application.Clear()
_, height := application.Size()
application.SetDot(0, 0)
fmt.Fprint(application, "type some text below:")
caretX = 0
caretY = 2
application.SetDot(0, height - 1)
fmt.Fprintf(application, "page %d", page)
drawCaret()
}
case stone.EventPress:
button := event.(stone.EventPress).Button
if button.Printable() {
application.SetRune(caret, 0, rune(button))
caret ++
width, _ := application.Size()
if caret >= width {
caret = 0
}
application.Draw()
}
func drawCaret () {
application.SetRune(caretX, caretY, '+')
application.SetColor(caretX, caretY, stone.ColorDim)
}
case stone.EventResize:
application.Draw()
func onPress (button stone.Button) {
width, height := application.Size()
if button == stone.KeyEnter {
application.SetRune(caretX, caretY, 0)
caretX = 0
caretY ++
} else if button.Printable() {
application.SetRune(caretX, caretY, rune(button))
application.SetColor(caretX, caretY, stone.ColorForeground)
caretX ++
if caretX >= width {
caretX = 0
caretY ++
}
}
if caretY >= height - 2 {
page ++
redraw()
}
drawCaret()
application.Draw()
}