Installer/steps.go
2024-12-20 18:58:53 +01:00

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