Compare commits

...
17 Commits
13 changed files with 404 additions and 216 deletions

No files matched your search

+32 -8
View File
@@ -5,14 +5,38 @@ import (
"github.com/libretro/ludo/input"
)
// Used to easily compose different hint bars based on the context.
func stackHint(stack *float32, icon uint32, label string, h int) {
vid.Font.SetColor(darkGrey)
*stack += 30 * menu.ratio
vid.DrawImage(icon, *stack, float32(h)-70*menu.ratio, 70*menu.ratio, 70*menu.ratio, 1.0, darkGrey)
*stack += 70 * menu.ratio
vid.Font.Printf(*stack, float32(h)-23*menu.ratio, 0.4*menu.ratio, label)
*stack += vid.Font.Width(0.4*menu.ratio, label)
// HintBar is the bar showing at the bottom of the screen
func HintBar(props *Props, children ...func()) func() {
w, h := vid.Window.GetFramebufferSize()
return HBox(&Props{
Y: float32(h) - 70*menu.ratio,
Width: float32(w),
Height: 70 * menu.ratio,
Color: lightGrey,
Hidden: props.Hidden,
},
children...,
)
}
// Hint is a widget combining an icon and a label
func Hint(props *Props, icon uint32, title string) func() {
darkGrey := darkGrey
return HBox(props,
Box(&Props{Width: 15}),
Image(&Props{
Width: 70 * menu.ratio,
Height: 70 * menu.ratio,
Scale: 1,
Color: darkGrey,
}, icon),
Label(&Props{
Height: 70 * menu.ratio,
Scale: 0.4 * menu.ratio,
Color: darkGrey,
}, title),
Box(&Props{Width: 15}),
)
}
func hintIcons() (arrows, upDown, leftRight, a, b, x, y, start, slct, guide uint32) {
+35 -26
View File
@@ -23,32 +23,41 @@ var severityBgColor = map[ntf.Severity]video.Color{
func (m *Menu) RenderNotifications() {
fbw, fbh := vid.Window.GetFramebufferSize()
vid.Font.UpdateResolution(fbw, fbh)
var h float32 = 75
stack := h
stack := float32(0)
for _, n := range ntf.List() {
fading := n.Duration * 4
if fading > 1 {
fading = 1
}
offset := fading*h - h
lw := vid.Font.Width(0.5*m.ratio, n.Message)
fg := severityFgColor[n.Severity]
bg := severityBgColor[n.Severity]
vid.DrawRect(
25*m.ratio,
(stack+offset-46)*m.ratio,
lw+40*m.ratio,
70*m.ratio,
0.25,
bg.Alpha(fading),
)
vid.Font.SetColor(fg.Alpha(fading))
vid.Font.Printf(
45*m.ratio,
(stack+offset)*m.ratio,
0.5*m.ratio,
n.Message,
)
stack += h + offset
offset := minf32(n.Duration*4, 1) * 80
lw := vid.Font.Width(0.4*menu.ratio, n.Message)
Toast(&Props{
X: 25 * menu.ratio,
Y: (stack + offset - 80 + 25) * menu.ratio,
Width: lw + 70*menu.ratio + 20*menu.ratio,
Height: 70 * menu.ratio,
BorderRadius: 0.25,
}, n)()
stack += offset
}
}
// Toast can render a notification
func Toast(props *Props, n *ntf.Notification) func() {
alpha := minf32(n.Duration*4, 1)
fg := severityFgColor[n.Severity].Alpha(alpha)
bg := severityBgColor[n.Severity].Alpha(alpha)
props.Color = bg
return HBox(props,
Image(&Props{
Width: props.Height,
Height: props.Height,
Scale: 1,
Color: fg,
}, menu.icons["core-infos"]),
Label(&Props{
Height: props.Height,
Scale: 0.4 * menu.ratio,
Color: fg,
}, n.Message),
)
}
+7 -13
View File
@@ -174,6 +174,7 @@ func thumbnailDrawCursor(list *entry) {
// It also display values of settings if we are displaying a settings scene
func genericRender(list *entry) {
w, h := vid.Window.GetFramebufferSize()
fontOffset := 64 * 0.7 * menu.ratio * 0.3
genericDrawCursor(list)
@@ -184,8 +185,6 @@ func genericRender(list *entry) {
continue
}
fontOffset := 64 * 0.7 * menu.ratio * 0.3
vid.DrawImage(menu.icons[e.icon],
610*menu.ratio-64*0.5*menu.ratio,
float32(h)*e.yp-14*menu.ratio-64*0.5*menu.ratio+fontOffset,
@@ -215,16 +214,11 @@ func genericRender(list *entry) {
}
func genericDrawHintBar() {
w, h := vid.Window.GetFramebufferSize()
vid.DrawRect(0, float32(h)-70*menu.ratio, float32(w), 70*menu.ratio, 0, lightGrey)
_, upDown, _, a, b, _, _, _, _, guide := hintIcons()
var stack float32
if state.Global.CoreRunning {
stackHint(&stack, guide, "RESUME", h)
}
stackHint(&stack, upDown, "NAVIGATE", h)
stackHint(&stack, b, "BACK", h)
stackHint(&stack, a, "OK", h)
HintBar(&Props{},
Hint(&Props{Hidden: !state.Global.CoreRunning}, guide, "RESUME"),
Hint(&Props{}, upDown, "NAVIGATE"),
Hint(&Props{}, b, "BACK"),
Hint(&Props{}, a, "OK"),
)()
}
+6 -11
View File
@@ -80,16 +80,11 @@ func (s *sceneCoreOptions) render() {
}
func (s *sceneCoreOptions) drawHintBar() {
w, h := vid.Window.GetFramebufferSize()
vid.DrawRect(0, float32(h)-70*menu.ratio, float32(w), 70*menu.ratio, 0, lightGrey)
_, upDown, leftRight, _, b, _, _, _, _, guide := hintIcons()
var stack float32
if state.Global.CoreRunning {
stackHint(&stack, guide, "RESUME", h)
}
stackHint(&stack, upDown, "NAVIGATE", h)
stackHint(&stack, b, "BACK", h)
stackHint(&stack, leftRight, "SET", h)
HintBar(&Props{},
Hint(&Props{Hidden: !state.Global.CoreRunning}, guide, "RESUME"),
Hint(&Props{}, upDown, "NAVIGATE"),
Hint(&Props{}, b, "BACK"),
Hint(&Props{}, leftRight, "SET"),
)()
}
+42 -49
View File
@@ -50,59 +50,52 @@ func (s *sceneDialog) render() {
w, h := vid.Window.GetFramebufferSize()
fw := float32(w)
fh := float32(h)
vid.DrawRect(0, 0, fw, fh, 0, black.Alpha(0.85))
var width float32 = 1000
var height float32 = 400
vid.DrawRect(
fw/2-width/2*menu.ratio,
fh/2-height/2*menu.ratio,
width*menu.ratio,
height*menu.ratio,
0.05,
white,
)
vid.Font.SetColor(orange)
msg1 := "A game is currently running."
lw1 := vid.Font.Width(0.7*menu.ratio, msg1)
vid.Font.Printf(fw/2-lw1/2, fh/2-120*menu.ratio+20*menu.ratio, 0.7*menu.ratio, msg1)
vid.Font.SetColor(black)
msg2 := "If you have not saved yet, your progress will be lost."
lw2 := vid.Font.Width(0.5*menu.ratio, msg2)
vid.Font.Printf(fw/2-lw2/2, fh/2-30*menu.ratio+20*menu.ratio, 0.5*menu.ratio, msg2)
msg3 := "Do you want to exit Ludo anyway?"
lw3 := vid.Font.Width(0.5*menu.ratio, msg3)
vid.Font.Printf(fw/2-lw3/2, fh/2+30*menu.ratio+20*menu.ratio, 0.5*menu.ratio, msg3)
vid.Font.SetColor(darkGrey)
var margin float32 = 15
width := 1000 * menu.ratio
height := 400 * menu.ratio
_, _, _, a, b, _, _, _, _, _ := hintIcons()
vid.DrawImage(
b,
fw/2-width/2*menu.ratio+margin*menu.ratio,
fh/2+height/2*menu.ratio-70*menu.ratio-margin*menu.ratio,
70*menu.ratio, 70*menu.ratio, 1.0, darkGrey)
vid.Font.Printf(
fw/2-width/2*menu.ratio+margin*menu.ratio+70*menu.ratio,
fh/2+height/2*menu.ratio-23*menu.ratio-margin*menu.ratio,
0.4*menu.ratio,
"NO")
vid.DrawImage(
a,
fw/2+width/2*menu.ratio-150*menu.ratio-margin*menu.ratio,
fh/2+height/2*menu.ratio-70*menu.ratio-margin*menu.ratio,
70*menu.ratio, 70*menu.ratio, 1.0, darkGrey)
vid.Font.Printf(
fw/2+width/2*menu.ratio-150*menu.ratio-margin*menu.ratio+70*menu.ratio,
fh/2+height/2*menu.ratio-23*menu.ratio-margin*menu.ratio,
0.4*menu.ratio,
"YES")
// Background
Box(&Props{Width: fw, Height: fh, Color: black.Alpha(0.85)},
// Dialog
VBox(&Props{
X: fw/2 - width/2,
Y: fh/2 - height/2,
Width: width,
Height: height,
BorderRadius: 0.05,
Color: white,
},
// Title
Label(&Props{
TextAlign: "center",
Scale: 0.7 * menu.ratio,
Color: orange,
Height: 150 * menu.ratio,
}, "A game is currently running"),
// Messages
Label(&Props{
TextAlign: "center",
Scale: 0.5 * menu.ratio,
Color: black,
Height: 60 * menu.ratio,
}, "If you have not saved yet, your progress will be lost."),
Label(&Props{
TextAlign: "center",
Scale: 0.5 * menu.ratio,
Color: black,
Height: 60 * menu.ratio,
}, "Do you want to exit Ludo anyway?"),
Box(&Props{Height: 40 * menu.ratio}),
Box(&Props{},
// The NO Hint
Hint(&Props{}, b, "NO"),
// The YES Hint
Hint(&Props{X: width - 175*menu.ratio}, a, "YES"),
),
),
)()
}
func (s *sceneDialog) drawHintBar() {
+6 -11
View File
@@ -189,16 +189,11 @@ func (s *sceneHistory) render() {
}
func (s *sceneHistory) drawHintBar() {
w, h := vid.Window.GetFramebufferSize()
vid.DrawRect(0, float32(h)-70*menu.ratio, float32(w), 70*menu.ratio, 0, lightGrey)
_, upDown, _, a, b, _, _, _, _, guide := hintIcons()
var stack float32
if state.Global.CoreRunning {
stackHint(&stack, guide, "RESUME", h)
}
stackHint(&stack, upDown, "NAVIGATE", h)
stackHint(&stack, b, "BACK", h)
stackHint(&stack, a, "RUN", h)
HintBar(&Props{},
Hint(&Props{Hidden: !state.Global.CoreRunning}, guide, "RESUME"),
Hint(&Props{}, upDown, "NAVIGATE"),
Hint(&Props{}, b, "BACK"),
Hint(&Props{}, a, "RUN"),
)()
}
+8 -11
View File
@@ -204,16 +204,13 @@ func (s *sceneKeyboard) render() {
}
func (s *sceneKeyboard) drawHintBar() {
w, h := vid.Window.GetFramebufferSize()
vid.DrawRect(0, float32(h)-70*menu.ratio, float32(w), 70*menu.ratio, 0, lightGrey)
arrows, _, _, a, b, x, y, start, _, _ := hintIcons()
var stack float32
stackHint(&stack, arrows, "SELECT", h)
stackHint(&stack, b, "BACK", h)
stackHint(&stack, x, "SHIFT", h)
stackHint(&stack, y, "DELETE", h)
stackHint(&stack, a, "INSERT", h)
stackHint(&stack, start, "DONE", h)
HintBar(&Props{},
Hint(&Props{}, arrows, "SELECT"),
Hint(&Props{}, b, "BACK"),
Hint(&Props{}, x, "SHIFT"),
Hint(&Props{}, y, "DELETE"),
Hint(&Props{}, a, "INSERT"),
Hint(&Props{}, start, "DONE"),
)()
}
+6 -11
View File
@@ -210,16 +210,11 @@ func (s *scenePlaylist) render() {
}
func (s *scenePlaylist) drawHintBar() {
w, h := vid.Window.GetFramebufferSize()
vid.DrawRect(0, float32(h)-70*menu.ratio, float32(w), 70*menu.ratio, 0, lightGrey)
_, upDown, _, a, b, _, _, _, _, guide := hintIcons()
var stack float32
if state.Global.CoreRunning {
stackHint(&stack, guide, "RESUME", h)
}
stackHint(&stack, upDown, "NAVIGATE", h)
stackHint(&stack, b, "BACK", h)
stackHint(&stack, a, "RUN", h)
HintBar(&Props{},
Hint(&Props{Hidden: !state.Global.CoreRunning}, guide, "RESUME"),
Hint(&Props{}, upDown, "NAVIGATE"),
Hint(&Props{}, b, "BACK"),
Hint(&Props{}, a, "RUN"),
)()
}
+7 -16
View File
@@ -135,22 +135,13 @@ func (s *sceneSavestates) render() {
}
func (s *sceneSavestates) drawHintBar() {
w, h := vid.Window.GetFramebufferSize()
vid.DrawRect(0, float32(h)-70*menu.ratio, float32(w), 70*menu.ratio, 0, lightGrey)
ptr := menu.stack[len(menu.stack)-1].Entry().ptr
_, upDown, _, a, b, _, _, _, _, guide := hintIcons()
var stack float32
if state.Global.CoreRunning {
stackHint(&stack, guide, "RESUME", h)
}
stackHint(&stack, upDown, "NAVIGATE", h)
stackHint(&stack, b, "BACK", h)
if ptr == 0 {
stackHint(&stack, a, "SAVE", h)
} else {
stackHint(&stack, a, "LOAD", h)
}
HintBar(&Props{},
Hint(&Props{Hidden: !state.Global.CoreRunning}, guide, "RESUME"),
Hint(&Props{}, upDown, "NAVIGATE"),
Hint(&Props{}, b, "BACK"),
Hint(&Props{Hidden: ptr != 0}, a, "SAVE"),
Hint(&Props{Hidden: ptr == 0}, a, "LOAD"),
)()
}
+8 -16
View File
@@ -260,21 +260,13 @@ func (s *sceneSettings) render() {
}
func (s *sceneSettings) drawHintBar() {
w, h := vid.Window.GetFramebufferSize()
vid.DrawRect(0, float32(h)-70*menu.ratio, float32(w), 70*menu.ratio, 0, lightGrey)
cb := s.children[s.ptr].callbackOK
_, upDown, leftRight, a, b, _, _, _, _, guide := hintIcons()
var stack float32
list := menu.stack[len(menu.stack)-1].Entry()
if state.Global.CoreRunning {
stackHint(&stack, guide, "RESUME", h)
}
stackHint(&stack, upDown, "NAVIGATE", h)
stackHint(&stack, b, "BACK", h)
if list.children[list.ptr].callbackOK != nil {
stackHint(&stack, a, "SET", h)
} else {
stackHint(&stack, leftRight, "SET", h)
}
HintBar(&Props{},
Hint(&Props{Hidden: !state.Global.CoreRunning}, guide, "RESUME"),
Hint(&Props{}, upDown, "NAVIGATE"),
Hint(&Props{}, b, "BACK"),
Hint(&Props{Hidden: cb == nil}, a, "SET"),
Hint(&Props{Hidden: cb != nil}, leftRight, "SET"),
)()
}
+51 -34
View File
@@ -256,47 +256,64 @@ func (tabs *sceneTabs) update(dt float32) {
}
}
// Tab is a widget that draws the homepage hexagon plus title
func Tab(props *Props, i int, e entry) func() {
c := colorful.Hcl(float64(i)*20, 0.5, 0.5)
return Box(props,
Box(&Props{Width: e.width * menu.ratio},
Image(&Props{
X: e.width/2*menu.ratio - 220*e.scale*menu.ratio,
Y: -220 * e.scale * menu.ratio,
Width: 440 * menu.ratio,
Height: 440 * menu.ratio,
Scale: e.scale,
Color: video.Color{R: float32(c.R), G: float32(c.B), B: float32(c.G), A: e.iconAlpha},
}, menu.icons["hexagon"]),
Image(&Props{
X: e.width/2*menu.ratio - 128*e.scale*menu.ratio,
Y: -128 * e.scale * menu.ratio,
Width: 256 * menu.ratio,
Height: 256 * menu.ratio,
Scale: e.scale,
Color: video.Color{R: 1, G: 1, B: 1, A: e.iconAlpha},
}, menu.icons[e.icon]),
Label(&Props{
Y: 250 * menu.ratio,
TextAlign: "center",
Scale: 0.6 * menu.ratio,
Color: video.Color{R: float32(c.R), G: float32(c.B), B: float32(c.G), A: e.labelAlpha},
}, e.label),
Label(&Props{
Y: 330 * menu.ratio,
TextAlign: "center",
Scale: 0.4 * menu.ratio,
Color: video.Color{R: float32(c.R), G: float32(c.B), B: float32(c.G), A: e.labelAlpha},
}, e.subLabel),
),
)
}
func (tabs sceneTabs) render() {
_, h := vid.Window.GetFramebufferSize()
stackWidth := 710 * menu.ratio
var children []func()
for i, e := range tabs.children {
cf := colorful.Hcl(float64(i)*20, 0.5, 0.5)
c := video.Color{R: float32(cf.R), G: float32(cf.B), B: float32(cf.G), A: e.iconAlpha}
x := -menu.scroll*menu.ratio + stackWidth + e.width/2*menu.ratio
stackWidth += e.width*menu.ratio + e.margin*menu.ratio
if e.labelAlpha > 0 {
vid.Font.SetColor(c.Alpha(e.labelAlpha))
lw := vid.Font.Width(0.5*menu.ratio, e.label)
vid.Font.Printf(x-lw/2, float32(int(float32(h)/2+250*menu.ratio)), 0.5*menu.ratio, e.label)
lw = vid.Font.Width(0.4*menu.ratio, e.subLabel)
vid.Font.Printf(x-lw/2, float32(int(float32(h)/2+330*menu.ratio)), 0.4*menu.ratio, e.subLabel)
}
vid.DrawImage(menu.icons["hexagon"],
x-220*e.scale*menu.ratio, float32(h)/2-220*e.scale*menu.ratio,
440*menu.ratio, 440*menu.ratio, e.scale, c)
vid.DrawImage(menu.icons[e.icon],
x-128*e.scale*menu.ratio, float32(h)/2-128*e.scale*menu.ratio,
256*menu.ratio, 256*menu.ratio, e.scale, white.Alpha(e.iconAlpha))
children = append(children, Tab(&Props{
Y: float32(h) / 2,
Width: e.width*menu.ratio + e.margin*menu.ratio,
}, i, e))
}
HBox(&Props{
X: 710*menu.ratio - menu.scroll*menu.ratio,
}, children...)()
}
func (tabs sceneTabs) drawHintBar() {
w, h := vid.Window.GetFramebufferSize()
vid.DrawRect(0, float32(h)-70*menu.ratio, float32(w), 70*menu.ratio, 0, lightGrey)
_, _, leftRight, a, _, _, _, _, _, guide := hintIcons()
var stack float32
if state.Global.CoreRunning {
stackHint(&stack, guide, "RESUME", h)
}
stackHint(&stack, leftRight, "NAVIGATE", h)
stackHint(&stack, a, "OPEN", h)
HintBar(&Props{},
Hint(&Props{Hidden: !state.Global.CoreRunning}, guide, "RESUME"),
Hint(&Props{}, leftRight, "NAVIGATE"),
Hint(&Props{}, a, "OPEN"),
)()
}
+5 -10
View File
@@ -85,15 +85,10 @@ func (s *sceneWiFi) render() {
}
func (s *sceneWiFi) drawHintBar() {
w, h := vid.Window.GetFramebufferSize()
vid.DrawRect(0, float32(h)-70*menu.ratio, float32(w), 70*menu.ratio, 0, lightGrey)
_, upDown, _, a, b, _, _, _, _, _ := hintIcons()
var stack float32
stackHint(&stack, upDown, "NAVIGATE", h)
stackHint(&stack, b, "BACK", h)
if s.children[0].callbackOK != nil {
stackHint(&stack, a, "CONNECT", h)
}
HintBar(&Props{},
Hint(&Props{}, upDown, "NAVIGATE"),
Hint(&Props{}, b, "BACK"),
Hint(&Props{Hidden: s.children[0].callbackOK == nil}, a, "CONNECT"),
)()
}
+191
View File
@@ -0,0 +1,191 @@
package menu
import (
"github.com/libretro/ludo/video"
)
// Direction of the children widgets in a container
type Direction uint8
const (
// Vertical means that the children will stack on top of each others
Vertical Direction = iota
// Horizontal means that the children will stack from left to right
Horizontal
)
// Props are the properties of a widget
type Props struct {
X, Y float32
Width, Height float32
BorderRadius float32
Scale float32
TextAlign string
ContentWidth float32
ContentHeight float32
Direction Direction
Color video.Color
Hidden bool
}
type propsStack []*Props
func (s *propsStack) Push(v *Props) *propsStack {
*s = append(*s, v)
return s
}
func (s *propsStack) Pop() {
l := len(*s)
*s = (*s)[:l-1]
}
func (s *propsStack) Last() *Props {
if len(*s) == 0 {
return nil
}
return (*s)[len(*s)-1]
}
func (s *propsStack) Sum() *Props {
sum := Props{}
for _, t := range *s {
sum.X += t.X
sum.Y += t.Y
}
return &sum
}
var wStack = &propsStack{}
var tStack = &propsStack{}
// Box is a basic widget container
func Box(props *Props, children ...func()) func() {
return func() {
if props.Hidden {
return
}
parent := wStack.Last()
self := wStack.Push(props).Last()
tsum := tStack.Push(&Props{}).Sum()
sum := wStack.Sum()
vid.DrawRect(sum.X+tsum.X, sum.Y+tsum.Y, props.Width, props.Height, props.BorderRadius, props.Color)
for _, child := range children {
child()
}
updateParent(parent, maxf32(props.Width, self.ContentWidth), maxf32(props.Height, self.ContentHeight))
tStack.Pop()
wStack.Pop()
}
}
// HBox is an horizontal widget container
func HBox(props *Props, children ...func()) func() {
return func() {
if props.Hidden {
return
}
props.Direction = Horizontal
parent := wStack.Last()
self := wStack.Push(props).Last()
tsum := tStack.Push(&Props{}).Sum()
sum := wStack.Sum()
vid.DrawRect(sum.X+tsum.X, sum.Y+tsum.Y, props.Width, props.Height, props.BorderRadius, props.Color)
for _, child := range children {
tStack.Push(&Props{X: wStack.Last().ContentWidth})
child()
tStack.Pop()
}
updateParent(parent, maxf32(props.Width, self.ContentWidth), maxf32(props.Height, self.ContentHeight))
tStack.Pop()
wStack.Pop()
}
}
// VBox is a vertical widget container
func VBox(props *Props, children ...func()) func() {
return func() {
if props.Hidden {
return
}
props.Direction = Vertical
parent := wStack.Last()
self := wStack.Push(props).Last()
tsum := tStack.Push(&Props{}).Sum()
sum := wStack.Sum()
vid.DrawRect(sum.X+tsum.X, sum.Y+tsum.Y, props.Width, props.Height, props.BorderRadius, props.Color)
for _, child := range children {
tStack.Push(&Props{Y: wStack.Last().ContentHeight})
child()
tStack.Pop()
}
updateParent(parent, maxf32(props.Width, self.ContentWidth), maxf32(props.Height, self.ContentHeight))
tStack.Pop()
wStack.Pop()
}
}
// Label a widget is used to draw some text
func Label(props *Props, msg string) func() {
return func() {
if props.Hidden || props.Color.A == 0 {
return
}
parent := wStack.Last()
self := wStack.Push(props).Last()
tsum := tStack.Push(&Props{}).Sum()
sum := wStack.Sum()
vid.Font.SetColor(props.Color)
textWidth := vid.Font.Width(props.Scale, msg)
switch props.TextAlign {
case "center":
vid.Font.Printf(sum.X+tsum.X+parent.Width/2-textWidth/2, sum.Y+tsum.Y+self.Height*0.67, props.Scale, msg)
default:
vid.Font.Printf(sum.X+tsum.X, sum.Y+tsum.Y+self.Height*0.67, props.Scale, msg)
}
updateParent(parent, textWidth, maxf32(props.Height, self.ContentHeight))
tStack.Pop()
wStack.Pop()
}
}
// Image is a widget used to display an image
func Image(props *Props, image uint32) func() {
return func() {
if props.Hidden {
return
}
parent := wStack.Last()
sum := wStack.Push(props).Sum()
tsum := tStack.Push(&Props{}).Sum()
vid.DrawImage(image, sum.X+tsum.X, sum.Y+tsum.Y, props.Width, props.Height, props.Scale, props.Color)
updateParent(parent, props.Width, props.Height)
tStack.Pop()
wStack.Pop()
}
}
func updateParent(parent *Props, w, h float32) {
if parent != nil {
switch parent.Direction {
case Horizontal:
parent.ContentWidth += w
case Vertical:
parent.ContentHeight += h
}
}
}
func maxf32(a, b float32) float32 {
if b > a {
return b
}
return a
}
func minf32(a, b float32) float32 {
if b < a {
return b
}
return a
}