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

164 lines
4.1 KiB
Go

package main
import (
"math"
rl "github.com/gen2brain/raylib-go/raylib"
)
// drawBrowserIcon now draws:
// - Semi-transparent rounded square background with color mixing based on contrast/theme
// - 1px accent outline inside (replaced by outside highlight in steps.go highlight function? Here we still draw 1px line)
// - A 1px horizontal top line
// - An 'X' in the top-right corner
//
// Background mixing and accent colors are adjusted for better contrast in light theme.
func drawBrowserIcon(x, y, width, height float32, theme string, col rl.Color, contrastLevel int) {
roundness := float32(0.2)
segments := int32(8)
accentColor := getAccentColorForContrast(col, contrastLevel, theme)
bgColor := getMixedBackgroundColor(theme, col, contrastLevel)
bgColor.A = 200 // semi-transparent background
r := rl.Rectangle{X: x, Y: y, Width: width, Height: height}
rl.DrawRectangleRounded(r, roundness, segments, bgColor)
// Draw 1px accent outline inside the shape
rl.DrawRectangleRoundedLines(r, roundness, segments, accentColor)
// Horizontal top line
lineY := y + 10
startX := x + 5
endX := x + width - 5
rl.DrawLine(int32(startX), int32(lineY), int32(endX), int32(lineY), accentColor)
// 'X' close button in top-right corner
xRight := endX - 5
xLeft := xRight - 4
yTop := y + 4
yBottom := yTop + 4
rl.DrawLine(int32(xLeft), int32(yTop), int32(xRight), int32(yBottom), accentColor)
rl.DrawLine(int32(xLeft), int32(yBottom), int32(xRight), int32(yTop), accentColor)
}
// getMixedBackgroundColor creates a background that mixes the base theme color with the accent color differently
// based on contrast for better visibility in light theme.
func getMixedBackgroundColor(theme string, baseColor rl.Color, contrastLevel int) rl.Color {
var base rl.Color
if theme == "Light" {
// Use a slightly darker off-white to ensure lines stand out
base = rl.Color{R: 240, G: 240, B: 240, A: 255}
} else {
base = rl.Color{R: 20, G: 20, B: 20, A: 255}
}
// Default accent reference
accent := getAccentColorForContrast(baseColor, 1, theme)
var factor float32
switch contrastLevel {
case 0:
factor = 0.0
case 1:
factor = 0.2
case 2:
factor = 0.5
}
return blendColors(base, accent, factor)
}
func blendColors(c1, c2 rl.Color, factor float32) rl.Color {
R := float32(c1.R)*(1-factor) + float32(c2.R)*factor
G := float32(c1.G)*(1-factor) + float32(c2.G)*factor
B := float32(c1.B)*(1-factor) + float32(c2.B)*factor
return rl.Color{R: uint8(R), G: uint8(G), B: uint8(B), A: 255}
}
func getAccentColorForContrast(base rl.Color, contrastLevel int, theme string) rl.Color {
h, s, v := rgbToHsv(base.R, base.G, base.B)
switch contrastLevel {
case 0: // Low contrast
s *= 0.2
v *= 0.8
case 1: // Default
if theme == "Light" {
// Clamp v lower so line is visible against light bg
if v > 0.6 {
v = 0.6
}
} else {
v *= 0.9
}
case 2: // High
s = float32(math.Min(float64(s*1.5), 1.0))
if theme == "Light" {
if v < 0.7 {
v = 0.7
}
} else {
v = float32(math.Min(float64(v*1.1), 1.0))
}
}
r, g, b := hsvToRgb(h, s, v)
return rl.Color{R: r, G: g, B: b, A: 255}
}
func rgbToHsv(r, g, b uint8) (float32, float32, float32) {
R := float32(r) / 255.0
G := float32(g) / 255.0
B := float32(b) / 255.0
max := float32(math.Max(math.Max(float64(R), float64(G)), float64(B)))
min := float32(math.Min(math.Min(float64(R), float64(G)), float64(B)))
delta := max - min
var h float32
if delta < 0.00001 {
h = 0
} else if max == R {
h = (G - B) / delta
if G < B {
h += 6
}
} else if max == G {
h = (B-R)/delta + 2
} else {
h = (R-G)/delta + 4
}
h *= 60.0 / 360.0
s := float32(0)
if max > 0 {
s = delta / max
}
v := max
return h, s, v
}
func hsvToRgb(h, s, v float32) (uint8, uint8, uint8) {
h = h * 6.0
i := int(math.Floor(float64(h)))
f := h - float32(i)
p := v * (1 - s)
q := v * (1 - s*f)
t := v * (1 - s*(1-f))
var R, G, B float32
switch i {
case 0:
R, G, B = v, t, p
case 1:
R, G, B = q, v, p
case 2:
R, G, B = p, v, t
case 3:
R, G, B = p, q, v
case 4:
R, G, B = t, p, v
default:
R, G, B = v, p, q
}
return uint8(R * 255), uint8(G * 255), uint8(B * 255)
}