Added binding support for canvas "draw-function"

This commit is contained in:
Alexei Anoshenko 2025-06-24 18:41:56 +03:00
parent 73b14ed78a
commit e618377c11
2 changed files with 51 additions and 12 deletions

View File

@ -1,5 +1,7 @@
package rui
import "reflect"
// DrawFunction is the constant for "draw-function" property tag.
//
// Used by `CanvasView`.
@ -55,7 +57,7 @@ func (canvasView *canvasViewData) removeFunc(tag PropertyName) []PropertyName {
if tag == DrawFunction {
if canvasView.getRaw(DrawFunction) != nil {
canvasView.setRaw(DrawFunction, nil)
canvasView.Redraw()
//canvasView.Redraw()
return []PropertyName{DrawFunction}
}
return []PropertyName{}
@ -66,9 +68,14 @@ func (canvasView *canvasViewData) removeFunc(tag PropertyName) []PropertyName {
func (canvasView *canvasViewData) setFunc(tag PropertyName, value any) []PropertyName {
if tag == DrawFunction {
if fn, ok := value.(func(Canvas)); ok {
canvasView.setRaw(DrawFunction, fn)
} else {
switch value := value.(type) {
case func(Canvas):
canvasView.setRaw(DrawFunction, value)
case string:
canvasView.setRaw(DrawFunction, value)
default:
notCompatibleType(tag, value)
return nil
}
@ -94,8 +101,30 @@ func (canvasView *canvasViewData) Redraw() {
canvas := newCanvas(canvasView)
canvas.ClearRect(0, 0, canvasView.frame.Width, canvasView.frame.Height)
if value := canvasView.getRaw(DrawFunction); value != nil {
if drawer, ok := value.(func(Canvas)); ok {
switch drawer := value.(type) {
case func(Canvas):
drawer(canvas)
case string:
bind := canvasView.binding()
if bind == nil {
ErrorLogF(`There is no a binding object for call "%s"`, drawer)
break
}
val := reflect.ValueOf(bind)
method := val.MethodByName(drawer)
if !method.IsValid() {
ErrorLogF(`The "%s" method is not valid`, drawer)
break
}
methodType := method.Type()
if methodType.NumIn() == 1 && equalType(methodType.In(0), reflect.TypeOf(canvas)) {
method.Call([]reflect.Value{reflect.ValueOf(canvas)})
} else {
ErrorLogF(`Unsupported prototype of "%s" method`, drawer)
}
}
}
canvas.finishDraw()

View File

@ -4,34 +4,44 @@ import (
"strconv"
)
// ImageLoadingStatus defines type of status of the image loading
type ImageLoadingStatus int
// Constants which represent return values of the LoadingStatus function of an [Image] view
const (
// ImageLoading is the image loading status: in the process of loading
ImageLoading = 0
ImageLoading ImageLoadingStatus = 0
// ImageReady is the image loading status: the image is loaded successfully
ImageReady = 1
ImageReady ImageLoadingStatus = 1
// ImageLoadingError is the image loading status: an error occurred while loading
ImageLoadingError = 2
ImageLoadingError ImageLoadingStatus = 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
// LoadingStatus returns the status of the image loading:
// - ImageLoading (0) - in the process of loading;
// - ImageReady (1) - the image is loaded successfully;
// - ImageLoadingError (2) - an error occurred while loading.
LoadingStatus() ImageLoadingStatus
// 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
loadingStatus ImageLoadingStatus
loadingError string
width, height float64
listener func(Image)
@ -45,7 +55,7 @@ func (image *imageData) URL() string {
return image.url
}
func (image *imageData) LoadingStatus() int {
func (image *imageData) LoadingStatus() ImageLoadingStatus {
return image.loadingStatus
}