MORE MESSING AROUND

This commit is contained in:
Caleb Gardner
2025-01-11 13:16:58 -06:00
parent c8e0f08aae
commit 6e8d97f29b
4 changed files with 227 additions and 53 deletions
+1
View File
@@ -0,0 +1 @@
testing/
+180 -46
View File
@@ -1,8 +1,10 @@
package ui
import (
"fmt"
"image"
"image/color"
"time"
rl "github.com/gen2brain/raylib-go/raylib"
)
@@ -10,21 +12,25 @@ import (
// A rectangle with borders.
// Default only has black borders.
type Rect struct {
x int32
y int32
h int32
w int32
radius int32
x int32
y int32
h int32
w int32
radius int32
reload bool
shown bool
rendering bool
borderWidth int32
borderColor color.RGBA
fillColor color.RGBA
tex *rl.Texture2D
curTweens map[string]*Tween
tex rl.RenderTexture2D
}
func NewRect(x, y, height, width int32) *Rect {
return &Rect{
r := &Rect{
x: x,
y: y,
h: height,
@@ -33,93 +39,221 @@ func NewRect(x, y, height, width int32) *Rect {
borderWidth: 2,
borderColor: rl.Black,
fillColor: rl.Blank,
reload: true,
curTweens: make(map[string]*Tween),
}
r.tex = rl.LoadRenderTexture(width, height)
rl.SetTextureFilter(r.tex.Texture, rl.FilterAnisotropic8x|rl.FilterBilinear)
return r
}
func (r *Rect) Copy() *Rect {
return &Rect{
x: r.x,
y: r.y,
h: r.h,
w: r.w,
radius: r.radius,
borderWidth: r.borderWidth,
borderColor: r.borderColor,
fillColor: r.fillColor,
}
}
func (r *Rect) addTween(key string, old, new int32) {
r.curTweens[key] = NewTween(old, new, 1000*time.Millisecond)
}
func (r *Rect) SetPosition(x, y int32) {
r.x, r.y = x, y
if !r.shown {
r.x, r.y = x, y
return
}
if r.x != x {
r.addTween("x", r.x, x)
}
if r.y != y {
r.addTween("y", r.y, y)
}
}
func (r *Rect) SetSize(h, w int32) {
r.h, r.w = h, w
r.Unload()
if !r.shown {
r.h, r.w = h, w
return
}
if r.h != h {
r.addTween("h", r.h, h)
r.reload = true
}
if r.w != w {
r.addTween("w", r.w, w)
r.reload = true
}
}
func (r *Rect) SetBorderRadius(radius int32) {
r.radius = radius
r.Unload()
if !r.shown {
r.radius = radius
return
}
if r.radius != radius {
r.addTween("radius", r.radius, radius)
r.reload = true
}
}
func (r *Rect) SetBorderWidth(w int32) {
r.borderWidth = w
r.Unload()
if !r.shown {
r.borderWidth = w
return
}
if r.borderWidth != w {
r.addTween("borderWidth", r.borderWidth, w)
r.reload = true
}
}
func (r *Rect) SetBorderColor(c color.RGBA) {
if r.borderColor != c {
r.reload = true
}
r.borderColor = c
r.Unload()
}
func (r *Rect) SetFillColor(c color.RGBA) {
r.fillColor = c
r.Unload()
}
func (r *Rect) Unload() {
if r.tex != nil {
rl.UnloadTexture(*r.tex)
r.tex = nil
if r.fillColor != c {
r.reload = true
}
r.fillColor = c
}
func (r *Rect) Draw() {
if r.tex != nil {
rl.DrawTextureEx(*r.tex, rl.NewVector2(float32(r.x), float32(r.y)), 0, 1, rl.White)
r.shown = true
if !r.reload && len(r.curTweens) == 0 {
rl.DrawTextureEx(r.tex.Texture, rl.NewVector2(float32(r.x), float32(r.y)), 0, 1, rl.White)
return
}
// Create image at 16x resolution then resize down so it looks better
img := rl.NewImageFromImage(image.NewAlpha(image.Rect(0, 0, int(r.w*4), int(r.h*4))))
var curRect *Rect
updateTex := false
if len(r.curTweens) != 0 {
curRect = r.Copy()
tween, ok := r.curTweens["x"]
if ok {
curRect.x = tween.CurVal()
if tween.Ended() {
r.x = curRect.x
delete(r.curTweens, "x")
}
}
tween, ok = r.curTweens["y"]
if ok {
curRect.y = tween.CurVal()
if tween.Ended() {
r.y = curRect.y
delete(r.curTweens, "y")
}
}
tween, ok = r.curTweens["h"]
if ok {
curRect.h = tween.CurVal()
if curRect.h != r.h {
updateTex = true
}
fmt.Println("h", curRect.h, r.h)
if tween.Ended() {
r.h = curRect.h
delete(r.curTweens, "h")
}
}
tween, ok = r.curTweens["w"]
if ok {
curRect.w = tween.CurVal()
if curRect.w != r.w {
updateTex = true
}
fmt.Println("w", curRect.w, r.w)
if tween.Ended() {
r.w = curRect.w
delete(r.curTweens, "w")
}
}
tween, ok = r.curTweens["radius"]
if ok {
curRect.radius = tween.CurVal()
if curRect.radius != r.radius {
updateTex = true
}
if tween.Ended() {
r.radius = curRect.radius
delete(r.curTweens, "radius")
}
}
tween, ok = r.curTweens["borderWidth"]
if ok {
curRect.borderWidth = tween.CurVal()
if curRect.borderWidth != r.borderWidth {
updateTex = true
}
if tween.Ended() {
r.borderWidth = curRect.borderWidth
delete(r.curTweens, "borderWidth")
}
}
} else {
curRect = r
}
if r.reload || updateTex {
// rl.UnloadTexture(r.tex)
// r.tex = rl.LoadTextureFromImage(curRect.buildImage())
// rl.UpdateTexture(r.tex, rl.LoadImageColors(curRect.buildImage()))
rl.BeginTextureMode(r.tex)
rl.UpdateTextureRec(r.tex.Texture, rl.NewRectangle(0, 0, float32(curRect.w), float32(curRect.h)), rl.LoadImageColors(curRect.buildImage()))
rl.EndTextureMode()
}
rl.DrawTextureEx(r.tex.Texture, rl.NewVector2(float32(curRect.x), float32(curRect.y)), 0, 1, rl.White)
r.reload = false
}
func (r Rect) buildImage() *rl.Image {
// Create image at 16x resolution then resize down so it looks better
img := rl.NewImageFromImage(image.NewAlpha(image.Rect(0, 0, int(r.w), int(r.h))))
// Filled areas
if r.fillColor != rl.Blank {
rl.ImageDrawRectangle(img, 4*r.radius, 0, 4*(r.w-(2*r.radius)), 4*r.h, r.fillColor)
rl.ImageDrawRectangle(img, r.radius, 0, (r.w - (2 * r.radius)), r.h, r.fillColor)
if r.radius > 0 {
rl.ImageDrawRectangle(img, 4*(r.w-r.radius), 4*r.radius, 4*r.radius, 4*(r.h-(2*r.radius)), r.fillColor)
rl.ImageDrawRectangle(img, 0, 4*r.radius, 4*r.radius, 4*(r.h-(2*r.radius)), r.fillColor)
rl.ImageDrawRectangle(img, (r.w - r.radius), r.radius, r.radius, (r.h - (2 * r.radius)), r.fillColor)
rl.ImageDrawRectangle(img, 0, r.radius, r.radius, (r.h - (2 * r.radius)), r.fillColor)
}
}
if r.borderColor != rl.Blank {
// Horizontal lines
rl.ImageDrawRectangle(img, 4*r.radius, 0, 4*(r.w-(2*r.radius)), r.borderWidth*4, r.borderColor)
rl.ImageDrawRectangle(img, 4*r.radius, (4*r.h)-(r.borderWidth*4), 4*(r.w-(2*r.radius)), r.borderWidth*4, r.borderColor)
rl.ImageDrawRectangle(img, r.radius, 0, (r.w - (2 * r.radius)), r.borderWidth, r.borderColor)
rl.ImageDrawRectangle(img, r.radius, (r.h)-(r.borderWidth), (r.w - (2 * r.radius)), r.borderWidth, r.borderColor)
// Vertical lines
rl.ImageDrawRectangle(img, 0, 4*r.radius, r.borderWidth*4, 4*(r.h-(2*r.radius)), r.borderColor)
rl.ImageDrawRectangle(img, (4*r.w)-(4*r.borderWidth), 4*r.radius, r.borderWidth*4, 4*(r.h-(2*r.radius)), r.borderColor)
rl.ImageDrawRectangle(img, 0, r.radius, r.borderWidth, (r.h - (2 * r.radius)), r.borderColor)
rl.ImageDrawRectangle(img, (r.w)-(r.borderWidth), r.radius, r.borderWidth, (r.h - (2 * r.radius)), r.borderColor)
}
if r.radius > 0 {
r.placeCorners(r.radius, img)
}
rl.ImageResize(img, r.w, r.h)
tmp := rl.LoadTextureFromImage(img)
r.tex = &tmp
rl.DrawTextureEx(*r.tex, rl.NewVector2(float32(r.x), float32(r.y)), 0, 1, r.borderColor)
return img
}
func (r Rect) placeCorners(radius float32, img *rl.Image) {
func (r Rect) placeCorners(radius int32, img *rl.Image) {
// Setup corner
corner := rl.NewImageFromImage(image.NewAlpha(image.Rect(0, 0, int(radius*4), int(radius*4))))
corner := rl.NewImageFromImage(image.NewAlpha(image.Rect(0, 0, int(radius), int(radius))))
if r.borderWidth > 0 {
rl.ImageDrawCircleV(corner, 4*radius, 4*radius, 4*radius, r.borderColor)
rl.ImageDrawCircle(corner, radius, radius, radius, r.borderColor)
}
rl.ImageDrawCircle(corner, 4*radius, 4*radius, (4*radius)-(4*r.borderWidth), r.fillColor)
rl.ImageDrawCircle(corner, radius, radius, (radius)-(r.borderWidth), r.fillColor)
// Add corners to actual image
rl.ImageDraw(img, corner, rl.NewRectangle(0, 0, float32(corner.Width), float32(corner.Height)), rl.NewRectangle(0, 0, float32(corner.Width), float32(corner.Height)), rl.White)
rl.ImageRotateCW(corner)
rl.ImageDraw(img, corner, rl.NewRectangle(0, 0, float32(corner.Width), float32(corner.Height)), rl.NewRectangle(float32(4*(r.w-radius)), 0, float32(corner.Width), float32(corner.Height)), rl.White)
rl.ImageDraw(img, corner, rl.NewRectangle(0, 0, float32(corner.Width), float32(corner.Height)), rl.NewRectangle(float32((r.w-radius)), 0, float32(corner.Width), float32(corner.Height)), rl.White)
rl.ImageRotateCW(corner)
rl.ImageDraw(img, corner, rl.NewRectangle(0, 0, float32(corner.Width), float32(corner.Height)), rl.NewRectangle(float32(4*(r.w-radius)), float32(4*(r.h-radius)), float32(corner.Width), float32(corner.Height)), rl.White)
rl.ImageDraw(img, corner, rl.NewRectangle(0, 0, float32(corner.Width), float32(corner.Height)), rl.NewRectangle(float32((r.w-radius)), float32((r.h-radius)), float32(corner.Width), float32(corner.Height)), rl.White)
rl.ImageRotateCW(corner)
rl.ImageDraw(img, corner, rl.NewRectangle(0, 0, float32(corner.Width), float32(corner.Height)), rl.NewRectangle(0, float32(4*(r.h-radius)), float32(corner.Width), float32(corner.Height)), rl.White)
rl.ImageDraw(img, corner, rl.NewRectangle(0, 0, float32(corner.Width), float32(corner.Height)), rl.NewRectangle(0, float32((r.h-radius)), float32(corner.Width), float32(corner.Height)), rl.White)
}
+12 -1
View File
@@ -1,6 +1,8 @@
package ui
import (
"time"
rl "github.com/gen2brain/raylib-go/raylib"
)
@@ -8,7 +10,7 @@ type Window struct{}
func Test() {
rl.InitWindow(800, 450, "raylib [core] example - basic window")
rl.SetWindowState(rl.FlagWindowResizable | rl.FlagWindowHighdpi)
rl.SetWindowState(rl.FlagWindowResizable | rl.FlagWindowHighdpi | rl.FlagVsyncHint)
rl.SetConfigFlags(rl.FlagMsaa4xHint)
defer rl.CloseWindow()
rl.Scalef(2, 2, 2)
@@ -20,9 +22,18 @@ func Test() {
tmpRect := NewRect(10, 10, 250, 500)
tmpRect.SetBorderRadius(25)
go func() {
for {
time.Sleep(5 * time.Second)
tmpRect.SetSize(200, 400)
time.Sleep(5 * time.Second)
tmpRect.SetSize(250, 500)
}
}()
// tmpRect.SetFillColor(rl.Green)
for !rl.WindowShouldClose() {
rl.BeginDrawing()
rl.DrawFPS(0, 0)
rl.ClearBackground(rl.DarkGray)
// rl.DrawText("Congrats! You created your first window!", 190, 100, 20, rl.LightGray)
+34 -6
View File
@@ -1,11 +1,39 @@
package ui
type num interface {
int32 | float32
import (
"math"
"time"
)
type Tween struct {
startVal int32
startTime time.Time
dif int32
dur time.Duration
}
type Tween[T num] struct {
start T
nextMult float32
end T
func NewTween(startVal, endVal int32, duration time.Duration) *Tween {
return &Tween{
startVal: startVal,
dif: endVal - startVal,
dur: duration,
startTime: time.Now().Round(time.Millisecond),
}
}
func (t *Tween) CurVal() int32 {
since := time.Now().Round(time.Millisecond).Sub(t.startTime)
if since <= 0 {
return t.startVal
}
if since >= t.dur {
return t.startVal + t.dif
}
m := float32(since.Milliseconds()) / float32(t.dur.Milliseconds())
m = -1 * float32(math.Log10(-.9*float64(m)+1))
return t.startVal + int32(math.Round(float64(float32(t.dif)*m)))
}
func (t *Tween) Ended() bool {
return time.Now().Round(time.Millisecond).Sub(t.startTime) >= t.dur
}