This commit is contained in:
Ivar Fatland
2026-05-11 09:56:23 +02:00
parent 77a65b3d57
commit fb3877bca0
+125 -125
View File
@@ -24,160 +24,160 @@ const textBoxHeight = fontSize + 6
var font_tff []byte var font_tff []byte
type State struct { type State struct {
Font rl.Font Font rl.Font
} }
func main() { func main() {
input, err := io.ReadAll(os.Stdin) input, err := io.ReadAll(os.Stdin)
if err != nil { if err != nil {
log.Fatalln(err) log.Fatalln(err)
} }
choices := strings.Split(string(input), "\n") choices := strings.Split(string(input), "\n")
choices = slices.DeleteFunc(choices, func(l string) bool { choices = slices.DeleteFunc(choices, func(l string) bool {
return l == "" return l == ""
}) })
choice, ok := raymenu(choices) choice, ok := raymenu(choices)
if ok { if ok {
fmt.Println(choice) fmt.Println(choice)
} }
} }
func isPressedRepeat(key int32) bool { func isPressedRepeat(key int32) bool {
return rl.IsKeyPressed(key) || rl.IsKeyPressedRepeat(key) return rl.IsKeyPressed(key) || rl.IsKeyPressedRepeat(key)
} }
func raymenu(options []string) (choice string, ok bool) { func raymenu(options []string) (choice string, ok bool) {
state := initialize(len(options)) state := initialize(len(options))
rg.SetFont(state.Font) rg.SetFont(state.Font)
rg.SetStyle(rg.DEFAULT, rg.TEXT_SIZE, fontSize) rg.SetStyle(rg.DEFAULT, rg.TEXT_SIZE, fontSize)
// TODO kinda dumb with additional initialization here // TODO kinda dumb with additional initialization here
originalOrder := make([]matching.Matched, len(options)) originalOrder := make([]matching.Matched, len(options))
for i := range options { for i := range options {
originalOrder[i].Idx=i originalOrder[i].Idx=i
} }
cursor := 0 cursor := 0
matched := originalOrder matched := originalOrder
var prevInput string var prevInput string
var input string var input string
for !rl.WindowShouldClose() { for !rl.WindowShouldClose() {
rl.BeginDrawing() rl.BeginDrawing()
rl.ClearBackground(rl.Black) rl.ClearBackground(rl.Black)
resetBounds() resetBounds()
bounds := nextBounds() bounds := nextBounds()
isControlDown := rl.IsKeyDown(rl.KeyLeftControl) || rl.IsKeyDown(rl.KeyRightControl) isControlDown := rl.IsKeyDown(rl.KeyLeftControl) || rl.IsKeyDown(rl.KeyRightControl)
alternativeBackspace := isPressedRepeat(rl.KeyH) && isControlDown alternativeBackspace := isPressedRepeat(rl.KeyH) && isControlDown
enter := (rl.IsKeyPressed(rl.KeyY) && isControlDown) || enter := (rl.IsKeyPressed(rl.KeyY) && isControlDown) ||
rl.IsKeyPressed(rl.KeyEnter) rl.IsKeyPressed(rl.KeyEnter)
if alternativeBackspace && len(input) > 0 { if alternativeBackspace && len(input) > 0 {
input = input[:len(input)-1] input = input[:len(input)-1]
} }
rg.TextBox(bounds, &input, 1024, true) rg.TextBox(bounds, &input, 1024, true)
if prevInput != input { if prevInput != input {
if len(input) > 0 { if len(input) > 0 {
matched = matching.FindAll(input, options) matched = matching.FindAll(input, options)
} else { } else {
matched = originalOrder matched = originalOrder
} }
cursor = 0 cursor = 0
prevInput = input prevInput = input
} }
{ // cursor update { // cursor update
moveCursorUp := isPressedRepeat(rl.KeyP) && isControlDown moveCursorUp := isPressedRepeat(rl.KeyP) && isControlDown
moveCursorDown := isPressedRepeat(rl.KeyN) && isControlDown moveCursorDown := isPressedRepeat(rl.KeyN) && isControlDown
if moveCursorUp { if moveCursorUp {
cursor -= 1 cursor -= 1
} }
if moveCursorDown { if moveCursorDown {
cursor += 1 cursor += 1
} }
if cursor >= len(matched) { if cursor >= len(matched) {
cursor = len(matched) - 1 cursor = len(matched) - 1
} }
if cursor < 0 { if cursor < 0 {
cursor = 0 cursor = 0
} }
} }
if enter { if enter {
rl.CloseWindow() rl.CloseWindow()
if cursor < len(matched) { if cursor < len(matched) {
return options[matched[cursor].Idx], true return options[matched[cursor].Idx], true
} }
return "", false return "", false
} }
for i, match := range matched { for i, match := range matched {
bounds := nextBounds() bounds := nextBounds()
textBounds := bounds textBounds := bounds
textBounds.X += textBounds.Height textBounds.X += textBounds.Height
textBounds.Width -= textBounds.Height textBounds.Width -= textBounds.Height
rg.DrawText( rg.DrawText(
options[match.Idx], options[match.Idx],
textBounds, textBounds,
int32(rg.TEXT_ALIGN_LEFT), int32(rg.TEXT_ALIGN_LEFT),
rl.White, rl.White,
) )
if i == cursor { if i == cursor {
// TODO if cursor is not visible then keep some offset or make // TODO if cursor is not visible then keep some offset or make
// 2d camera so you can scroll through all the options if you // 2d camera so you can scroll through all the options if you
// want // want
rl.DrawCircle( rl.DrawCircle(
int32(bounds.X)+int32(bounds.Height)/2, int32(bounds.X)+int32(bounds.Height)/2,
int32(bounds.Y)+int32(bounds.Height)/2, int32(bounds.Y)+int32(bounds.Height)/2,
max(textBoxHeight / 8, 1), max(textBoxHeight / 8, 1),
rl.White, rl.White,
) )
} }
} }
rl.EndDrawing() rl.EndDrawing()
} }
return "", false return "", false
} }
var yOffset float32 = 0.0 var yOffset float32 = 0.0
func resetBounds() { func resetBounds() {
yOffset = 0.0 yOffset = 0.0
} }
func nextBounds() (bounds rl.Rectangle) { func nextBounds() (bounds rl.Rectangle) {
bounds = rl.Rectangle{X: 0, Y: yOffset, Width: float32(rl.GetScreenWidth()), Height: textBoxHeight} bounds = rl.Rectangle{X: 0, Y: yOffset, Width: float32(rl.GetScreenWidth()), Height: textBoxHeight}
yOffset += textBoxHeight yOffset += textBoxHeight
return return
} }
func initialize(nOptions int) State { func initialize(nOptions int) State {
rl.SetTraceLogLevel(rl.LogError) rl.SetTraceLogLevel(rl.LogError)
rl.InitWindow(0, 0, "raymenu") rl.InitWindow(0, 0, "raymenu")
rl.SetWindowState(rl.FlagWindowUndecorated) rl.SetWindowState(rl.FlagWindowUndecorated)
rl.SetTargetFPS( rl.SetTargetFPS(
int32( int32(
rl.GetMonitorRefreshRate( rl.GetMonitorRefreshRate(
rl.GetCurrentMonitor(), rl.GetCurrentMonitor(),
), ),
), ),
) )
monitor := rl.GetCurrentMonitor() monitor := rl.GetCurrentMonitor()
monitorWidth := rl.GetMonitorWidth(monitor) monitorWidth := rl.GetMonitorWidth(monitor)
monitorHeight := rl.GetMonitorHeight(monitor) monitorHeight := rl.GetMonitorHeight(monitor)
rl.SetWindowSize( rl.SetWindowSize(
monitorWidth/2, monitorWidth/2,
min(monitorHeight/2/textBoxHeight, nOptions+1)*textBoxHeight, min(monitorHeight/2/textBoxHeight, nOptions+1)*textBoxHeight,
) )
rl.SetWindowPosition( rl.SetWindowPosition(
monitorWidth/2-rl.GetScreenWidth()/2, monitorWidth/2-rl.GetScreenWidth()/2,
monitorHeight/2-rl.GetScreenHeight()/2, monitorHeight/2-rl.GetScreenHeight()/2,
) )
return State{ return State{
Font: rl.LoadFontFromMemory(".ttf", font_tff, fontSize, nil), Font: rl.LoadFontFromMemory(".ttf", font_tff, fontSize, nil),
} }
} }