Add Sprite

This commit is contained in:
Trevor Slocum 2024-09-18 19:41:36 -07:00
parent 7b35245a5a
commit b9ddff24b5
6 changed files with 115 additions and 9 deletions

View file

@ -151,11 +151,11 @@ func (b *Button) SetHorizontal(h Alignment) {
}
// SetVertical sets the vertical alignment of the button label.
func (b *Button) SetVertical(h Alignment) {
func (b *Button) SetVertical(v Alignment) {
b.Lock()
defer b.Unlock()
b.field.SetVertical(messeji.Alignment(h))
b.field.SetVertical(messeji.Alignment(v))
}
// Cursor returns the cursor shape shown when a mouse cursor hovers over the

2
go.mod
View file

@ -5,7 +5,7 @@ go 1.22.0
toolchain go1.23.0
require (
github.com/hajimehoshi/ebiten/v2 v2.7.9
github.com/hajimehoshi/ebiten/v2 v2.7.10
github.com/llgcode/draw2d v0.0.0-20240627062922-0ed1ff131195
golang.org/x/image v0.20.0
)

4
go.sum
View file

@ -8,8 +8,8 @@ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF0
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/hajimehoshi/bitmapfont/v3 v3.0.0 h1:r2+6gYK38nfztS/et50gHAswb9hXgxXECYgE8Nczmi4=
github.com/hajimehoshi/bitmapfont/v3 v3.0.0/go.mod h1:+CxxG+uMmgU4mI2poq944i3uZ6UYFfAkj9V6WqmuvZA=
github.com/hajimehoshi/ebiten/v2 v2.7.9 h1:DYH/usAa9dMHcGkBIIEApJsVqDekrJBxYHmsBuly8Iw=
github.com/hajimehoshi/ebiten/v2 v2.7.9/go.mod h1:Ulbq5xDmdx47P24EJ+Mb31Zps7vQq+guieG9mghQUaA=
github.com/hajimehoshi/ebiten/v2 v2.7.10 h1:fsVukQdPDUlalSSpFkuszTy0cK2DL0fxFoSnTVdlmAM=
github.com/hajimehoshi/ebiten/v2 v2.7.10/go.mod h1:Ulbq5xDmdx47P24EJ+Mb31Zps7vQq+guieG9mghQUaA=
github.com/jezek/xgb v1.1.1 h1:bE/r8ZZtSv7l9gk6nU0mYx51aXrvnyb44892TwSaqS4=
github.com/jezek/xgb v1.1.1/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
github.com/llgcode/draw2d v0.0.0-20240627062922-0ed1ff131195 h1:Vdz2cBh5Fw2MYHWi3ED2PraDQaWEUhNCr1XFHrP4N5A=

View file

@ -209,11 +209,11 @@ func (i *Input) SetHorizontal(h Alignment) {
}
// SetVertical sets the vertical alignment of the text within the field.
func (i *Input) SetVertical(h Alignment) {
func (i *Input) SetVertical(v Alignment) {
i.Lock()
defer i.Unlock()
i.field.SetVertical(messeji.Alignment(h))
i.field.SetVertical(messeji.Alignment(v))
}
// SetMask sets the rune used to mask the text buffer contents. Set to 0 to disable.

106
spite.go Normal file
View file

@ -0,0 +1,106 @@
package etk
import (
"image"
"github.com/hajimehoshi/ebiten/v2"
)
// Sprite is a resizable image.
type Sprite struct {
*Box
img *ebiten.Image
imgBounds image.Rectangle
thumb *ebiten.Image
thumbBounds image.Rectangle
horizontal Alignment
vertical Alignment
}
// NewSprite returns a new Sprite widget.
func NewSprite(img *ebiten.Image) *Sprite {
return &Sprite{
Box: NewBox(),
img: img,
imgBounds: img.Bounds(),
horizontal: AlignCenter,
vertical: AlignCenter,
}
}
// SetImage sets the image of the Sprite.
func (s *Sprite) SetImage(img *ebiten.Image) {
s.Lock()
defer s.Unlock()
s.img = img
s.thumbBounds = image.Rectangle{}
}
// SetHorizontal sets the horizontal alignment of the Sprite.
func (s *Sprite) SetHorizontal(h Alignment) {
s.Lock()
defer s.Unlock()
s.horizontal = h
s.thumbBounds = image.Rectangle{}
}
// SetVertical sets the vertical alignment of the Sprite.
func (s *Sprite) SetVertical(v Alignment) {
s.Lock()
defer s.Unlock()
s.vertical = v
s.thumbBounds = image.Rectangle{}
}
// Draw draws the Sprite on the screen.
func (s *Sprite) Draw(screen *ebiten.Image) error {
s.Lock()
defer s.Unlock()
op := &ebiten.DrawImageOptions{}
op.GeoM.Translate(float64(s.rect.Min.X), float64(s.rect.Min.Y))
if s.imgBounds.Dx() == s.rect.Dx() && s.imgBounds.Dy() == s.rect.Dy() {
screen.DrawImage(s.img, op)
return nil
} else if s.thumbBounds.Dx() != s.rect.Dx() || s.thumbBounds.Dy() != s.rect.Dy() {
scale, yScale := float64(s.rect.Dx())/float64(s.imgBounds.Dx()), float64(s.rect.Dy())/float64(s.imgBounds.Dy())
if yScale < scale {
scale = yScale
}
thumbOp := &ebiten.DrawImageOptions{}
thumbOp.GeoM.Scale(scale, scale)
if s.horizontal != AlignStart {
delta := float64(s.rect.Dx()) - float64(s.imgBounds.Dx())*scale
if s.horizontal == AlignCenter {
thumbOp.GeoM.Translate(delta/2, 0)
} else { // AlignEnd
thumbOp.GeoM.Translate(delta, 0)
}
}
if s.vertical != AlignStart {
delta := float64(s.rect.Dy()) - float64(s.imgBounds.Dy())*scale
if s.vertical == AlignCenter {
thumbOp.GeoM.Translate(0, delta/2)
} else { // AlignEnd
thumbOp.GeoM.Translate(0, delta)
}
}
createThumb := s.thumb == nil
if !createThumb {
bounds := s.thumb.Bounds()
createThumb = bounds.Dx() != s.rect.Dx() || bounds.Dy() != s.rect.Dy()
}
if createThumb {
s.thumb = ebiten.NewImage(s.rect.Dx(), s.rect.Dy())
}
s.thumb.DrawImage(s.img, thumbOp)
}
screen.DrawImage(s.thumb, op)
return nil
}

View file

@ -118,11 +118,11 @@ func (t *Text) SetHorizontal(h Alignment) {
}
// SetVertical sets the vertical alignment of the text within the field.
func (t *Text) SetVertical(h Alignment) {
func (t *Text) SetVertical(v Alignment) {
t.Lock()
defer t.Unlock()
t.field.SetVertical(messeji.Alignment(h))
t.field.SetVertical(messeji.Alignment(v))
}
// Cursor returns the cursor shape shown when a mouse cursor hovers over the