started implementing button

This commit is contained in:
Squishy Bloob 2024-03-25 00:55:14 +00:00
parent 68ef5dcac5
commit 25d3d8cb0d
7 changed files with 157 additions and 7 deletions

View File

@ -37,9 +37,8 @@ func Run(game Runnable) {
Cursor: DefaultCursor,
}
game.Init(&bloob, &settings)
gui.InitGui(settings.WindowSize)
game.Init(&bloob, &settings)
window, _ := sdl.CreateWindow(
settings.Title,

14
font.go
View File

@ -30,3 +30,17 @@ func LoadTilesetFontBytes(data []byte, tilesize Vec2i) *Font {
font.lineHeight = tilesize.Y + 2
return &font
}
func (f *Font) StringWidth(str string) int {
var l int
for i := 0; i < len(str); i += 1 {
l += f.chars[i].xForward
}
return l - 1
}
func (f *Font) StringBounds(str string) Vec2i {
//todo: multiline
return Vec2i{X: f.StringWidth(str), Y: f.lineHeight}
}

60
gui/button.go Normal file
View File

@ -0,0 +1,60 @@
package gui
import . "git.danitheskunk.com/squishy/blooblib"
type Button struct {
BaseWidget
label string
}
func NewButton(label string) *Button {
return &Button{
BaseWidget: BaseWidget{
Size: Vec2i{X: 80, Y: 22},
},
label: label,
}
}
func (w *Button) Draw(target *Image) {
//col1 := Color(0xffffff)
col2 := Color(0xccccdd)
col3 := Color(0x888899)
col4 := Color(0x555566)
//col5 := Color(0x444444)
pressed := false
if pressed {
//todo: non-filled
target.DrawRectRounded(Recti{Pos: w.Pos, Size: w.Size}, 0, 2)
target.DrawHLine(Vec2i{X: w.Pos.X + 2, Y: w.Pos.Y + 1}, w.Size.X-4, col4)
target.DrawVLine(Vec2i{X: w.Pos.X + 1, Y: w.Pos.Y + 2}, w.Size.Y-4, col4)
target.DrawHLine(Vec2i{X: w.Pos.X + 2, Y: w.Pos.Y + w.Size.Y - 2}, w.Size.X-4, col2)
target.DrawVLine(Vec2i{X: w.Pos.X + w.Size.X - 2, Y: w.Pos.Y + 2}, w.Size.Y-4, col2)
innerRect := Recti{Pos: Vec2i{X: w.Pos.X + 2, Y: w.Pos.Y + 2}, Size: Vec2i{X: w.Size.X - 4, Y: w.Size.Y - 4}}
target.DrawRect(innerRect, col3)
innerRect.Pos.X += 1
innerRect.Pos.Y += 1
target.DrawTextOutlineCenter(w.label, DefaultFont, innerRect, col2, 0x000000)
} else {
//todo: non-filled
target.DrawRectRounded(Recti{Pos: w.Pos, Size: w.Size}, 0, 2)
target.DrawHLine(Vec2i{X: w.Pos.X + 2, Y: w.Pos.Y + 1}, w.Size.X-4, col2)
target.DrawVLine(Vec2i{X: w.Pos.X + 1, Y: w.Pos.Y + 2}, w.Size.Y-4, col2)
target.DrawHLine(Vec2i{X: w.Pos.X + 2, Y: w.Pos.Y + w.Size.Y - 2}, w.Size.X-4, col4)
target.DrawVLine(Vec2i{X: w.Pos.X + w.Size.X - 2, Y: w.Pos.Y + 2}, w.Size.Y-4, col4)
innerRect := Recti{Pos: Vec2i{X: w.Pos.X + 2, Y: w.Pos.Y + 2}, Size: Vec2i{X: w.Size.X - 4, Y: w.Size.Y - 4}}
target.DrawRect(innerRect, col3)
target.DrawTextOutlineCenter(w.label, DefaultFont, innerRect, col2, 0x000000)
}
}

View File

@ -3,6 +3,7 @@ package gui
import . "git.danitheskunk.com/squishy/blooblib"
type gui struct {
Root Widget
}
var Gui gui
@ -12,5 +13,13 @@ func InitGui(size Vec2i) {
}
func DrawGui(target *Image) {
if Gui.Root != nil {
Gui.Root.Draw(target)
}
}
func UpdateGui() {
if Gui.Root != nil {
Gui.Root.Layout()
}
}

18
gui/widget.go Normal file
View File

@ -0,0 +1,18 @@
package gui
import . "git.danitheskunk.com/squishy/blooblib"
type BaseWidget struct {
childs []*Widget
parent *Widget
Pos Vec2i
Size Vec2i
}
type Widget interface {
Draw(target *Image)
Layout()
}
func (w *BaseWidget) Draw(target *Image) {}
func (w *BaseWidget) Layout() {}

View File

@ -91,6 +91,10 @@ func CropToArea(sizeDst Vec2i, rectSrc Recti, posDst Vec2i) (start, end, dst Vec
return
}
func (image *Image) DrawPixel(pos Vec2i, color Color) {
image.Data[pos.X+pos.Y*image.Size.X] = color
}
func (image *Image) DrawHLine(pos Vec2i, length int, color Color) {
for i := 0; i < length; i += 1 {
image.Data[pos.X+i+pos.Y*image.Size.X] = color
@ -103,6 +107,35 @@ func (image *Image) DrawVLine(pos Vec2i, length int, color Color) {
}
}
func (image *Image) DrawRect(rect Recti, color Color) {
start, end, _ := CropToArea(image.Size, rect, Vec2i{})
for y := start.Y; y < end.Y; y += 1 {
for x := start.X; x < end.X; x += 1 {
image.Data[x+y*image.Size.X] = color
}
}
}
func (image *Image) DrawRectRounded(rect Recti, color Color, round int) {
round = min(max(rect.Size.X, rect.Size.Y)/2-1, round)
start, end, _ := CropToArea(image.Size, rect, Vec2i{})
for y := start.Y; y < end.Y; y += 1 {
ri := 0
yt := y - start.Y
yp := -(y - end.Y+1)
if yt < round {
ri = round - yt
}
if yp < round {
ri = round - yp
}
for x := start.X + ri; x < end.X-ri; x += 1 {
image.Data[x+y*image.Size.X] = color
}
}
}
func (image *Image) Draw(other *Image, dst Vec2i) {
image.DrawSub(other, dst, Recti{Size: other.Size})
}
@ -278,6 +311,12 @@ func (image *Image) DrawText(str string, font *Font, pos Vec2i, color Color) {
}
}
func (image *Image) DrawTextCenter(str string, font *Font, rect Recti, color Color) {
size := font.StringBounds(str)
pos := Add(DivScalar(Sub(rect.Size, size), 2), Add(rect.Pos, Vec2i{X: 0, Y: 1}))
image.DrawText(str, font, pos, color)
}
func (image *Image) DrawTextSin(str string, font *Font, pos Vec2i, color Color, freq, amplitude, phase float64) {
origX := pos.X
for _, ch := range str {
@ -319,6 +358,12 @@ func (image *Image) DrawTextOutline(str string, font *Font, pos Vec2i, color, ou
}
}
func (image *Image) DrawTextOutlineCenter(str string, font *Font, rect Recti, color, outlineColor Color) {
size := font.StringBounds(str)
pos := Add(DivScalar(Sub(rect.Size, size), 2), Add(rect.Pos, Vec2i{X: 0, Y: 1}))
image.DrawTextOutline(str, font, pos, color, outlineColor)
}
func (image *Image) DrawTextOutlineSin(str string, font *Font, pos Vec2i, color, outlineColor Color, freq, amplitude, phase float64) {
origX := pos.X
for _, ch := range str {

View File

@ -1,20 +1,25 @@
package main
import (
bloob "git.danitheskunk.com/squishy/blooblib"
. "git.danitheskunk.com/squishy/blooblib"
. "git.danitheskunk.com/squishy/blooblib/gui"
run "git.danitheskunk.com/squishy/blooblib/Run"
)
type Game struct {
}
func (g Game) Init(bloob *bloob.Bloob, settings *bloob.Settings) {
func (g Game) Init(bloob *Bloob, settings *Settings) {
button := NewButton("Ok")
button.Pos = Vec2i{X: 20, Y: 20}
Gui.Root = button
}
func (g Game) Render(bloob *bloob.Bloob, screen *bloob.Image) {
func (g Game) Render(bloob *Bloob, screen *Image) {
screen.Clear(0xcccccc)
}
func (g Game) Update(bloob *bloob.Bloob) {
func (g Game) Update(bloob *Bloob) {
}
func main() {