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) } }