2023-06-30 14:38:51 -06:00
|
|
|
package tomo
|
|
|
|
|
2023-07-15 23:06:24 -06:00
|
|
|
import "sync"
|
2023-06-30 14:38:51 -06:00
|
|
|
import "image"
|
|
|
|
import "errors"
|
2023-08-23 23:01:40 -06:00
|
|
|
import "git.tebibyte.media/tomo/tomo/canvas"
|
2023-06-30 14:38:51 -06:00
|
|
|
|
2023-07-15 23:06:24 -06:00
|
|
|
var backendLock sync.Mutex
|
2023-06-30 14:38:51 -06:00
|
|
|
var backend Backend
|
|
|
|
|
|
|
|
// Run initializes a backend, runs the specified callback function, and runs the
|
|
|
|
// event loop in that order. This function blocks until Stop is called, or the
|
|
|
|
// backend experiences a fatal error.
|
|
|
|
func Run (callback func ()) error {
|
|
|
|
if backend != nil {
|
|
|
|
return errors.New("there is already a backend running")
|
|
|
|
}
|
|
|
|
|
2024-05-24 22:52:25 -06:00
|
|
|
back, err := initialize()
|
2023-06-30 14:38:51 -06:00
|
|
|
if err != nil { return err }
|
2023-07-15 23:06:24 -06:00
|
|
|
|
|
|
|
backendLock.Lock()
|
2023-06-30 14:38:51 -06:00
|
|
|
backend = back
|
2023-07-15 23:06:24 -06:00
|
|
|
backendLock.Unlock()
|
2023-06-30 14:38:51 -06:00
|
|
|
|
|
|
|
callback()
|
|
|
|
return backend.Run()
|
|
|
|
}
|
|
|
|
|
|
|
|
func assertBackend () {
|
|
|
|
if backend == nil { panic("nil backend") }
|
|
|
|
}
|
|
|
|
|
|
|
|
// Stop stops the backend, unblocking run. Run may be called again after calling
|
|
|
|
// Stop.
|
|
|
|
func Stop () {
|
|
|
|
assertBackend()
|
|
|
|
backend.Stop()
|
2023-07-15 23:06:24 -06:00
|
|
|
|
|
|
|
backendLock.Lock()
|
2023-06-30 14:38:51 -06:00
|
|
|
backend = nil
|
2023-07-15 23:06:24 -06:00
|
|
|
backendLock.Unlock()
|
2023-06-30 14:38:51 -06:00
|
|
|
}
|
|
|
|
|
2023-07-18 19:49:36 -06:00
|
|
|
// Do performs a callback function in the event loop thread as soon as possible.
|
2023-07-15 22:33:44 -06:00
|
|
|
func Do (callback func ()) {
|
2023-07-15 23:06:24 -06:00
|
|
|
backendLock.Lock()
|
|
|
|
if backend != nil { backend.Do(callback) }
|
|
|
|
backendLock.Unlock()
|
2023-07-15 22:33:44 -06:00
|
|
|
}
|
|
|
|
|
2023-07-18 19:49:36 -06:00
|
|
|
// NewWindow creates and returns a window within the specified bounds on screen.
|
2024-06-06 22:56:29 -06:00
|
|
|
func NewWindow (bounds image.Rectangle) (Window, error) {
|
2023-06-30 14:38:51 -06:00
|
|
|
assertBackend()
|
|
|
|
return backend.NewWindow(bounds)
|
|
|
|
}
|
|
|
|
|
2023-09-05 11:21:59 -06:00
|
|
|
// NewPlainWindow is like NewWindow, but it creates an undecorated window that
|
|
|
|
// does not appear in window lists. It is intended for creating things like
|
|
|
|
// docks, panels, etc.
|
2024-06-06 22:56:29 -06:00
|
|
|
func NewPlainWindow (bounds image.Rectangle) (Window, error) {
|
2023-09-05 11:21:59 -06:00
|
|
|
assertBackend()
|
|
|
|
return backend.NewPlainWindow(bounds)
|
|
|
|
}
|
|
|
|
|
2023-07-18 19:49:36 -06:00
|
|
|
// NewBox creates and returns a basic Box.
|
2023-06-30 14:38:51 -06:00
|
|
|
func NewBox () Box {
|
|
|
|
assertBackend()
|
|
|
|
return backend.NewBox()
|
|
|
|
}
|
|
|
|
|
2023-07-18 19:49:36 -06:00
|
|
|
// NewTextBox creates and returns a Box that can display text.
|
2023-06-30 14:38:51 -06:00
|
|
|
func NewTextBox () TextBox {
|
|
|
|
assertBackend()
|
|
|
|
return backend.NewTextBox()
|
|
|
|
}
|
|
|
|
|
2023-07-18 19:49:36 -06:00
|
|
|
// NewCanvasBox creates and returns a Box that can display custom graphics.
|
2023-06-30 14:38:51 -06:00
|
|
|
func NewCanvasBox () CanvasBox {
|
|
|
|
assertBackend()
|
|
|
|
return backend.NewCanvasBox()
|
|
|
|
}
|
|
|
|
|
2023-07-18 19:49:36 -06:00
|
|
|
// NewContainerBox creates and returns a Box that can contain other boxes.
|
2023-06-30 14:38:51 -06:00
|
|
|
func NewContainerBox () ContainerBox {
|
|
|
|
assertBackend()
|
|
|
|
return backend.NewContainerBox()
|
|
|
|
}
|
2023-08-20 15:54:06 -06:00
|
|
|
|
|
|
|
// NewTexture creates a new texture from an image. When no longer in use, it
|
|
|
|
// must be freed using Close().
|
2023-09-04 10:21:17 -06:00
|
|
|
func NewTexture (source image.Image) canvas.TextureCloser {
|
2023-08-20 15:54:06 -06:00
|
|
|
assertBackend()
|
|
|
|
return backend.NewTexture(source)
|
|
|
|
}
|
2024-06-03 17:29:41 -06:00
|
|
|
|
|
|
|
// NewCanvas creates a new canvas with the specified bounds. When no longer in
|
|
|
|
// use, it must be freed using Close().
|
|
|
|
func NewCanvas (bounds image.Rectangle) canvas.CanvasCloser {
|
|
|
|
assertBackend()
|
2024-06-03 17:32:47 -06:00
|
|
|
return backend.NewCanvas(bounds)
|
2024-06-03 17:29:41 -06:00
|
|
|
}
|