rui_orig/image.go

142 lines
3.4 KiB
Go

package rui
import (
"strconv"
)
const (
// ImageLoading is the image loading status: in the process of loading
ImageLoading = 0
// ImageReady is the image loading status: the image is loaded successfully
ImageReady = 1
// ImageLoadingError is the image loading status: an error occurred while loading
ImageLoadingError = 2
)
// Image defines the image that is used for drawing operations on the Canvas.
type Image interface {
// URL returns the url of the image
URL() string
// LoadingStatus returns the status of the image loading: ImageLoading (0), ImageReady (1), ImageLoadingError (2)
LoadingStatus() int
// LoadingError: if LoadingStatus() == ImageLoadingError then returns the error text, "" otherwise
LoadingError() string
setLoadingError(err string)
// Width returns the width of the image in pixels. While LoadingStatus() != ImageReady returns 0
Width() float64
// Height returns the height of the image in pixels. While LoadingStatus() != ImageReady returns 0
Height() float64
}
type imageData struct {
url string
loadingStatus int
loadingError string
width, height float64
listener func(Image)
}
type imageManager struct {
images map[string]*imageData
}
func (image *imageData) URL() string {
return image.url
}
func (image *imageData) LoadingStatus() int {
return image.loadingStatus
}
func (image *imageData) LoadingError() string {
return image.loadingError
}
func (image *imageData) setLoadingError(err string) {
image.loadingError = err
}
func (image *imageData) Width() float64 {
return image.width
}
func (image *imageData) Height() float64 {
return image.height
}
func (manager *imageManager) loadImage(url string, onLoaded func(Image), session Session) Image {
if manager.images == nil {
manager.images = make(map[string]*imageData)
}
if image, ok := manager.images[url]; ok && image.loadingStatus == ImageReady {
return image
}
image := new(imageData)
image.url = url
image.listener = onLoaded
image.loadingStatus = ImageLoading
manager.images[url] = image
session.callFunc("loadImage", url)
session.sendResponse()
return image
}
func (manager *imageManager) imageLoaded(obj DataObject) {
if manager.images == nil {
manager.images = make(map[string]*imageData)
return
}
if url, ok := obj.PropertyValue("url"); ok {
if image, ok := manager.images[url]; ok {
image.loadingStatus = ImageReady
if width, ok := obj.PropertyValue("width"); ok {
if w, err := strconv.ParseFloat(width, 64); err == nil {
image.width = w
}
}
if height, ok := obj.PropertyValue("height"); ok {
if h, err := strconv.ParseFloat(height, 64); err == nil {
image.height = h
}
}
if image.listener != nil {
image.listener(image)
}
}
}
}
func (manager *imageManager) imageLoadError(obj DataObject) {
if manager.images == nil {
manager.images = make(map[string]*imageData)
return
}
if url, ok := obj.PropertyValue("url"); ok {
if image, ok := manager.images[url]; ok {
delete(manager.images, url)
text, _ := obj.PropertyValue("message")
image.setLoadingError(text)
if image.listener != nil {
image.listener(image)
}
}
}
}
// LoadImage starts the async image loading by url
func LoadImage(url string, onLoaded func(Image), session Session) Image {
if url != "" && url[0] == '@' {
if image, ok := session.ImageConstant(url[1:]); ok {
url = image
}
}
return session.imageManager().loadImage(url, onLoaded, session)
}