360 lines
11 KiB
Go
360 lines
11 KiB
Go
package main
|
|
|
|
import rl "github.com/gen2brain/raylib-go/raylib"
|
|
|
|
type uiElement struct {
|
|
drawFunc func(x, y float32)
|
|
width float32
|
|
height float32
|
|
}
|
|
|
|
func layoutElementsCentered(screenW, screenH int, elements []uiElement) []rl.Rectangle {
|
|
totalHeight := float32(0)
|
|
for _, e := range elements {
|
|
totalHeight += e.height
|
|
}
|
|
gap := float32(20)
|
|
totalHeight += gap * float32(len(elements)-1)
|
|
|
|
startY := float32(screenH)/2 - totalHeight/2
|
|
currentY := startY
|
|
|
|
positions := make([]rl.Rectangle, len(elements))
|
|
for i, e := range elements {
|
|
x := float32(screenW)/2 - e.width/2
|
|
e.drawFunc(x, currentY)
|
|
positions[i] = rl.Rectangle{X: x, Y: currentY, Width: e.width, Height: e.height}
|
|
currentY += e.height + gap
|
|
}
|
|
return positions
|
|
}
|
|
|
|
// Step 1 buttons rect defined in main.go
|
|
var step2Positions []rl.Rectangle
|
|
var step3Positions []rl.Rectangle
|
|
|
|
// Step 2
|
|
var colorCirclePositions []rl.Vector2
|
|
var browserIconRects [3]rl.Rectangle
|
|
var themeButtonRects [2]rl.Rectangle
|
|
|
|
// Step 3
|
|
var layoutOptionRects []rl.Rectangle
|
|
|
|
func drawStep(step int, screenW, screenH int, mousePos rl.Vector2, alpha, scale, offsetX float32) {
|
|
rl.PushMatrix()
|
|
rl.Translatef(offsetX, 0, 0)
|
|
rl.Translatef(float32(screenW)/2, float32(screenH)/2, 0)
|
|
rl.Scalef(scale, scale, 1)
|
|
rl.Translatef(-float32(screenW)/2, -float32(screenH)/2, 0)
|
|
|
|
switch step {
|
|
case 0:
|
|
drawStep1Content(screenW, screenH, mousePos, alpha)
|
|
case 1:
|
|
drawStep2Content(screenW, screenH, mousePos, alpha)
|
|
case 2:
|
|
drawStep3Content(screenW, screenH, mousePos, alpha)
|
|
}
|
|
|
|
rl.PopMatrix()
|
|
}
|
|
|
|
func drawStep1Content(screenW, screenH int, mousePos rl.Vector2, alpha float32) {
|
|
heading := "Default or Customize"
|
|
col := applyAlpha(rl.RayWhite, alpha)
|
|
headingFont := int32(20)
|
|
headingW := rl.MeasureText(heading, headingFont)
|
|
headingY := float32(80)
|
|
rl.DrawTextEx(rl.GetFontDefault(), heading,
|
|
rl.Vector2{X: float32((screenW - int(headingW))) / 2, Y: headingY}, float32(headingFont), 1, col)
|
|
|
|
sub := "Do you want to install with default settings?"
|
|
subFont := int32(20)
|
|
subW := float32(rl.MeasureText(sub, subFont))
|
|
subH := float32(subFont)
|
|
|
|
buttonWidth := float32(150)
|
|
buttonHeight := float32(50)
|
|
buttonSpacing := float32(50)
|
|
totalButtonWidth := buttonWidth*2 + buttonSpacing
|
|
|
|
subDraw := func(x, y float32) {
|
|
rl.DrawTextEx(rl.GetFontDefault(), sub, rl.Vector2{X: x, Y: y}, float32(subFont), 1, col)
|
|
}
|
|
defaultDraw := func(x, y float32) {
|
|
drawRectButtonAlpha(rl.Rectangle{X: x, Y: y, Width: buttonWidth, Height: buttonHeight}, "Default", alpha)
|
|
step1DefaultRect = rl.Rectangle{X: x, Y: y, Width: buttonWidth, Height: buttonHeight}
|
|
}
|
|
customDraw := func(x, y float32) {
|
|
cx := x + buttonWidth + buttonSpacing
|
|
drawRectButtonAlpha(rl.Rectangle{X: cx, Y: y, Width: buttonWidth, Height: buttonHeight}, "Customize", alpha)
|
|
step1CustomRect = rl.Rectangle{X: cx, Y: y, Width: buttonWidth, Height: buttonHeight}
|
|
}
|
|
|
|
elements := []uiElement{
|
|
{drawFunc: subDraw, width: subW, height: subH},
|
|
{
|
|
drawFunc: func(x, y float32) {
|
|
defaultDraw(x, y)
|
|
customDraw(x, y)
|
|
},
|
|
width: totalButtonWidth,
|
|
height: buttonHeight,
|
|
},
|
|
}
|
|
|
|
layoutElementsCentered(screenW, screenH, elements)
|
|
}
|
|
|
|
func drawStep2Content(screenW, screenH int, mousePos rl.Vector2, alpha float32) {
|
|
heading := "Look and Feel"
|
|
sub := "Color"
|
|
col := applyAlpha(rl.RayWhite, alpha)
|
|
headingFont := int32(20)
|
|
subFont := int32(20)
|
|
headingW := rl.MeasureText(heading, headingFont)
|
|
|
|
headingY := float32(80)
|
|
rl.DrawTextEx(rl.GetFontDefault(), heading,
|
|
rl.Vector2{X: float32((screenW - int(headingW))) / 2, Y: headingY}, float32(headingFont), 1, col)
|
|
|
|
subW := float32(rl.MeasureText(sub, subFont))
|
|
subH := float32(subFont)
|
|
subDraw := func(x, y float32) {
|
|
rl.DrawTextEx(rl.GetFontDefault(), sub, rl.Vector2{X: x, Y: y}, float32(subFont), 1, col)
|
|
}
|
|
|
|
// Color row
|
|
circleCount := len(catColors)
|
|
spacing := float32(50)
|
|
circleR := float32(8)
|
|
circleDiameter := circleR * 2
|
|
totalColorWidth := spacing*float32(circleCount-1) + circleDiameter
|
|
colorRowH := circleDiameter
|
|
colorDraw := func(x, y float32) {
|
|
for i, c := range catColors {
|
|
cx := x + float32(i)*spacing
|
|
drawColorCircleAlpha(cx, y+circleR, c.Color, c.Name == selectedColor, alpha)
|
|
}
|
|
}
|
|
|
|
// Three browser icons (Low=0, Default=1, High=2)
|
|
browserW := float32(60)
|
|
browserH := float32(50)
|
|
browserCount := 3
|
|
browserTotalWidth := browserW*float32(browserCount) + spacing*float32(browserCount-1)
|
|
browserDraw := func(x, y float32) {
|
|
theme := selectedTheme
|
|
for i := 0; i < browserCount; i++ {
|
|
bx := x + float32(i)*(browserW+spacing)
|
|
drawBrowserIcon(bx, y, browserW, browserH, theme, getSelectedColorColor(), i)
|
|
browserIconRects[i] = rl.Rectangle{X: bx, Y: y, Width: browserW, Height: browserH}
|
|
}
|
|
// Highlight hovered/selected
|
|
for i, rect := range browserIconRects {
|
|
hovered := overRect(mousePos, rect)
|
|
selected := (contrastLevel == i)
|
|
drawHighlightRounded(rect, hovered, selected, 0.2)
|
|
}
|
|
}
|
|
|
|
// Theme section: Light or Dark
|
|
themeLabel := "Theme"
|
|
labelFont := int32(20)
|
|
themeLabelW := float32(rl.MeasureText(themeLabel, labelFont))
|
|
themeLabelH := float32(labelFont)
|
|
themeButtonWidth := float32(100)
|
|
themeButtonHeight := float32(40)
|
|
themeButtonSpacing := float32(50)
|
|
themeButtonCount := 2
|
|
themeTotalWidth := themeButtonWidth*float32(themeButtonCount) + themeButtonSpacing*float32(themeButtonCount-1)
|
|
|
|
themeDraw := func(x, y float32) {
|
|
rl.DrawTextEx(rl.GetFontDefault(), themeLabel, rl.Vector2{X: x + (themeTotalWidth-themeLabelW)/2, Y: y}, float32(labelFont), 1, col)
|
|
y += themeLabelH + 10
|
|
lightX := x
|
|
lightY := y
|
|
lightRect := rl.Rectangle{X: lightX, Y: lightY, Width: themeButtonWidth, Height: themeButtonHeight}
|
|
drawRectButtonAlpha(lightRect, "Light", alpha)
|
|
themeButtonRects[0] = lightRect
|
|
|
|
darkX := lightX + themeButtonWidth + themeButtonSpacing
|
|
darkRect := rl.Rectangle{X: darkX, Y: lightY, Width: themeButtonWidth, Height: themeButtonHeight}
|
|
drawRectButtonAlpha(darkRect, "Dark", alpha)
|
|
themeButtonRects[1] = darkRect
|
|
|
|
// Highlight hovered/selected
|
|
var selectedIndex int
|
|
if selectedTheme == "Light" {
|
|
selectedIndex = 0
|
|
} else {
|
|
selectedIndex = 1
|
|
}
|
|
for i, r := range themeButtonRects {
|
|
hovered := overRect(rl.GetMousePosition(), r)
|
|
selected := (i == selectedIndex)
|
|
drawHighlightRounded(r, hovered, selected, 0.3)
|
|
}
|
|
}
|
|
themeBlockH := themeLabelH + 10 + themeButtonHeight
|
|
|
|
elements := []uiElement{
|
|
{drawFunc: subDraw, width: subW, height: subH},
|
|
{drawFunc: colorDraw, width: totalColorWidth, height: colorRowH},
|
|
{drawFunc: browserDraw, width: browserTotalWidth, height: browserH},
|
|
{
|
|
drawFunc: func(x, y float32) {
|
|
themeDraw(x, y)
|
|
}, width: themeTotalWidth, height: themeBlockH,
|
|
},
|
|
}
|
|
|
|
step2Positions = layoutElementsCentered(screenW, screenH, elements)
|
|
|
|
// Compute color circle positions
|
|
colorCirclePositions = nil
|
|
colorRowPos := step2Positions[1]
|
|
for i := 0; i < circleCount; i++ {
|
|
cx := colorRowPos.X + float32(i)*spacing
|
|
cy := colorRowPos.Y + circleR
|
|
colorCirclePositions = append(colorCirclePositions, rl.Vector2{X: cx, Y: cy})
|
|
}
|
|
}
|
|
|
|
func drawStep3Content(screenW, screenH int, mousePos rl.Vector2, alpha float32) {
|
|
heading := "Layout Selection"
|
|
sub := "Tab layout"
|
|
col := applyAlpha(rl.RayWhite, alpha)
|
|
headingFont := int32(20)
|
|
subFont := int32(20)
|
|
headingW := rl.MeasureText(heading, headingFont)
|
|
subW := rl.MeasureText(sub, subFont)
|
|
headingY := float32(80)
|
|
|
|
rl.DrawTextEx(rl.GetFontDefault(), heading,
|
|
rl.Vector2{X: float32((screenW - int(headingW))) / 2, Y: headingY}, float32(headingFont), 1, col)
|
|
|
|
subY := headingY + 40
|
|
rl.DrawTextEx(rl.GetFontDefault(), sub,
|
|
rl.Vector2{X: float32((screenW - int(subW))) / 2, Y: subY}, float32(subFont), 1, col)
|
|
|
|
layoutCount := len(layoutOptions)
|
|
layoutSpacing := float32(200)
|
|
layoutWidth := float32((layoutCount-1))*layoutSpacing + 120
|
|
layoutHeight := float32(40)
|
|
|
|
layoutDraw := func(x, y float32) {
|
|
for i, l := range layoutOptions {
|
|
optX := x + float32(i)*layoutSpacing
|
|
drawLayoutOptionAlpha(optX, y, l.Name, l.Name == selectedLayout, alpha)
|
|
}
|
|
|
|
for i, r := range layoutOptionRects {
|
|
hovered := overRect(rl.GetMousePosition(), r)
|
|
selected := (layoutOptions[i].Name == selectedLayout)
|
|
drawHighlightRounded(r, hovered, selected, 0.3)
|
|
}
|
|
}
|
|
|
|
elements := []uiElement{
|
|
{drawFunc: layoutDraw, width: layoutWidth, height: layoutHeight},
|
|
}
|
|
|
|
step3Positions = layoutElementsCentered(screenW, screenH, elements)
|
|
|
|
// Compute layout option rects
|
|
layoutOptionRects = nil
|
|
layoutRow := step3Positions[0]
|
|
for i := 0; i < layoutCount; i++ {
|
|
optX := layoutRow.X + float32(i)*layoutSpacing
|
|
optY := layoutRow.Y
|
|
r := rl.Rectangle{X: optX - 60, Y: optY - 20, Width: 120, Height: 40}
|
|
layoutOptionRects = append(layoutOptionRects, r)
|
|
}
|
|
}
|
|
|
|
func getSelectedColorColor() rl.Color {
|
|
for _, c := range catColors {
|
|
if c.Name == selectedColor {
|
|
return c.Color
|
|
}
|
|
}
|
|
return rl.White
|
|
}
|
|
|
|
func selectColor(mousePos rl.Vector2) {
|
|
circleR := float32(8)
|
|
for i, pos := range colorCirclePositions {
|
|
if overCircle(mousePos, pos, circleR) {
|
|
selectedColor = catColors[i].Name
|
|
}
|
|
}
|
|
}
|
|
|
|
func selectContrastIcon(mousePos rl.Vector2) {
|
|
for i, r := range browserIconRects {
|
|
if overRect(mousePos, r) {
|
|
contrastLevel = i
|
|
}
|
|
}
|
|
}
|
|
|
|
func selectTheme(mousePos rl.Vector2) {
|
|
for i, r := range themeButtonRects {
|
|
if overRect(mousePos, r) {
|
|
if i == 0 {
|
|
selectedTheme = "Light"
|
|
} else {
|
|
selectedTheme = "Dark"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func selectLayoutOption(mousePos rl.Vector2) {
|
|
for i, r := range layoutOptionRects {
|
|
if overRect(mousePos, r) {
|
|
selectedLayout = layoutOptions[i].Name
|
|
}
|
|
}
|
|
}
|
|
|
|
// Draw highlight with rounded corners to match buttons/icons shape
|
|
func drawHighlightRounded(r rl.Rectangle, hovered, selected bool, roundness float32) {
|
|
segments := int32(8)
|
|
var color rl.Color
|
|
if selected && hovered {
|
|
color = rl.Color{R: 255, G: 255, B: 255, A: 255}
|
|
} else if selected {
|
|
color = rl.Color{R: 255, G: 255, B: 255, A: 255}
|
|
} else if hovered {
|
|
color = rl.Color{R: 255, G: 255, B: 255, A: 128}
|
|
} else {
|
|
return
|
|
}
|
|
|
|
// Make highlight outside element:
|
|
margin := float32(2)
|
|
highlightRect := rl.Rectangle{
|
|
X: r.X - margin,
|
|
Y: r.Y - margin,
|
|
Width: r.Width + margin*2,
|
|
Height: r.Height + margin*2,
|
|
}
|
|
|
|
rl.DrawRectangleRoundedLines(highlightRect, roundness, segments, color)
|
|
|
|
if selected {
|
|
// White strip reflection:
|
|
// Draw a diagonal line from left border to top border in top right corner
|
|
stripColor := rl.Color{R: 255, G: 255, B: 255, A: 80}
|
|
|
|
// This goes up to top border near top-right corner.
|
|
// We'll pick start near left border at 40% height, end near top border at 70% width:
|
|
start := rl.Vector2{X: highlightRect.X + margin, Y: highlightRect.Y + highlightRect.Height*0.4}
|
|
end := rl.Vector2{X: highlightRect.X + highlightRect.Width*0.7, Y: highlightRect.Y + margin}
|
|
|
|
rl.DrawLineEx(start, end, 5, stripColor)
|
|
}
|
|
}
|