add raymenu project
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
module github.com/roodletoof/raymenu
|
||||
|
||||
go 1.26.2
|
||||
|
||||
require (
|
||||
github.com/gen2brain/raylib-go/raygui v0.0.0-20260309161816-4c350487f71d
|
||||
github.com/gen2brain/raylib-go/raylib v0.55.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/ebitengine/purego v0.10.0 // indirect
|
||||
github.com/ktr0731/go-fuzzyfinder v0.9.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20260508232706-74f9aab9d74a // indirect
|
||||
golang.org/x/sys v0.44.0 // indirect
|
||||
)
|
||||
@@ -0,0 +1,12 @@
|
||||
github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ISU=
|
||||
github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/gen2brain/raylib-go/raygui v0.0.0-20260309161816-4c350487f71d h1:os8MZA0q9yHNk2KQVFepMhtukfC9QLBubBoxN3hKxAk=
|
||||
github.com/gen2brain/raylib-go/raygui v0.0.0-20260309161816-4c350487f71d/go.mod h1:Don7nFrETwG1JBACDZPvRahYPaSSvhLY9v9NUzD1YWc=
|
||||
github.com/gen2brain/raylib-go/raylib v0.55.1 h1:1rdc10WvvYjtj7qijHnV9T38/WuvlT6IIL+PaZ6cNA8=
|
||||
github.com/gen2brain/raylib-go/raylib v0.55.1/go.mod h1:BaY76bZk7nw1/kVOSQObPY1v1iwVE1KHAGMfvI6oK1Q=
|
||||
github.com/ktr0731/go-fuzzyfinder v0.9.0 h1:JV8S118RABzRl3Lh/RsPhXReJWc2q0rbuipzXQH7L4c=
|
||||
github.com/ktr0731/go-fuzzyfinder v0.9.0/go.mod h1:uybx+5PZFCgMCSDHJDQ9M3nNKx/vccPmGffsXPn2ad8=
|
||||
golang.org/x/exp v0.0.0-20260508232706-74f9aab9d74a h1:+3jdDGGB8NGb1Zktc737jlt3/A5f6UlwSzmvqUuufxw=
|
||||
golang.org/x/exp v0.0.0-20260508232706-74f9aab9d74a/go.mod h1:d2fgXJLVs4dYDHUk5lwMIfzRzSrWCfGZb0ZqeLa/Vcw=
|
||||
golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ=
|
||||
golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,36 @@
|
||||
These fonts were created by the Bigelow & Holmes foundry specifically for the
|
||||
Go project. See https://blog.golang.org/go-fonts for details.
|
||||
|
||||
They are licensed under the same open source license as the rest of the Go
|
||||
project's software:
|
||||
|
||||
Copyright (c) 2016 Bigelow & Holmes Inc.. All rights reserved.
|
||||
|
||||
Distribution of this font is governed by the following license. If you do not
|
||||
agree to this license, including the disclaimer, do not distribute or modify
|
||||
this font.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of Google Inc. nor the names of its contributors may be
|
||||
used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
DISCLAIMER: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,52 @@
|
||||
# Nerd Fonts
|
||||
|
||||
This is an archived font from the Nerd Fonts release v3.4.0.
|
||||
|
||||
For more information see:
|
||||
* https://github.com/ryanoasis/nerd-fonts/
|
||||
* https://github.com/ryanoasis/nerd-fonts/releases/latest/
|
||||
|
||||
# Go Mono
|
||||
|
||||
**Go** is a font created for the Go project.
|
||||
|
||||
https://go.dev/blog/go-fonts
|
||||
|
||||
For more information have a look at the upstream website: https://go.googlesource.com/image/
|
||||
|
||||
Download link https://go.googlesource.com/image/+/master/font/gofont/ttfs/
|
||||
|
||||
Version: 2.010
|
||||
|
||||
## Which font?
|
||||
|
||||
### TL;DR
|
||||
|
||||
* Pick your font family:
|
||||
* If you are limited to monospaced fonts (because of your terminal, etc) then pick a font with `Nerd Font Mono` (or `NFM`).
|
||||
* If you want to have bigger icons (usually around 1.5 normal letters wide) pick a font without `Mono` i.e. `Nerd Font` (or `NF`). Most terminals support this, but ymmv.
|
||||
* If you work in a proportional context (GUI elements or edit a presentation etc) pick a font with `Nerd Font Propo` (or `NFP`).
|
||||
|
||||
### Ligatures
|
||||
|
||||
Ligatures are generally preserved in the patched fonts.
|
||||
Nerd Fonts `v2.0.0` had no ligatures in the `Nerd Font Mono` fonts, this has been dropped with `v2.1.0`.
|
||||
If you have a ligature-aware terminal and don't want ligatures you can (usually) disable them in the terminal settings.
|
||||
|
||||
### Explanation
|
||||
|
||||
Once you narrow down your font choice of family (`Droid Sans`, `Inconsolata`, etc) and style (`bold`, `italic`, etc) you have 2 main choices:
|
||||
|
||||
#### `Option 1: Download already patched font`
|
||||
|
||||
* For a stable version download a font package from the [release page](https://github.com/ryanoasis/nerd-fonts/releases)
|
||||
* Or download the development version from the folders here
|
||||
|
||||
#### `Option 2: Patch your own font`
|
||||
|
||||
* Patch your own variations with the various options provided by the font patcher (i.e. not include all symbols for smaller font size)
|
||||
|
||||
For more information see: [The FAQ](https://github.com/ryanoasis/nerd-fonts/wiki/FAQ-and-Troubleshooting#which-font)
|
||||
|
||||
[SIL-RFN]:http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web_fonts_and_RFNs#14cbfd4a
|
||||
|
||||
+188
@@ -0,0 +1,188 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
_ "embed"
|
||||
|
||||
rg "github.com/gen2brain/raylib-go/raygui"
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
"github.com/ktr0731/go-fuzzyfinder/matching"
|
||||
)
|
||||
|
||||
//go:embed gomono-font/GoMonoNerdFontMono-Regular.ttf
|
||||
var gomonoNerdFont_ttf []byte
|
||||
|
||||
type State struct {
|
||||
Font rl.Font
|
||||
}
|
||||
|
||||
func main() {
|
||||
input, err := io.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
lines := strings.Split(string(input), "\n")
|
||||
lines = slices.DeleteFunc(lines, func(l string) bool {
|
||||
return l == ""
|
||||
})
|
||||
choice, result := raymenu(lines)
|
||||
switch (result) {
|
||||
case RayMenuResult_NoChoice:
|
||||
return
|
||||
case RayMenuResult_Chosen:
|
||||
fmt.Println(choice)
|
||||
return
|
||||
default:
|
||||
log.Fatalln("Unhandled RayMenuResult", result)
|
||||
}
|
||||
}
|
||||
|
||||
type RayMenuResult int
|
||||
|
||||
const (
|
||||
RayMenuResult_NoChoice RayMenuResult = iota
|
||||
RayMenuResult_Chosen
|
||||
Count_RayMenuResult int = iota
|
||||
)
|
||||
|
||||
const width = 800
|
||||
|
||||
func isPressedRepeat(key int32) bool {
|
||||
return rl.IsKeyPressed(key) || rl.IsKeyPressedRepeat(key)
|
||||
}
|
||||
|
||||
const fontSize = 14
|
||||
|
||||
func raymenu(options []string) (choice string, result RayMenuResult) {
|
||||
state := initialize()
|
||||
rg.SetFont(state.Font)
|
||||
rg.SetStyle(rg.DEFAULT, rg.TEXT_SIZE, fontSize)
|
||||
// TODO kinda dumb with additional initialization here
|
||||
originalOrder := make([]matching.Matched, len(options))
|
||||
for i := range options {
|
||||
originalOrder[i].Idx=i
|
||||
}
|
||||
cursor := 0
|
||||
matched := originalOrder
|
||||
var prevInput string
|
||||
var input string
|
||||
for !rl.WindowShouldClose() {
|
||||
rl.BeginDrawing()
|
||||
rl.ClearBackground(rl.Black)
|
||||
resetBounds()
|
||||
bounds := nextBounds()
|
||||
|
||||
isControlDown := rl.IsKeyDown(rl.KeyLeftControl) || rl.IsKeyDown(rl.KeyRightControl)
|
||||
alternativeBackspace := isPressedRepeat(rl.KeyH) && isControlDown
|
||||
enter := (rl.IsKeyPressed(rl.KeyY) && isControlDown) ||
|
||||
rl.IsKeyPressed(rl.KeyEnter)
|
||||
|
||||
if alternativeBackspace && len(input) > 0 {
|
||||
input = input[:len(input)-1]
|
||||
}
|
||||
|
||||
rg.TextBox(bounds, &input, 1024, true)
|
||||
if prevInput != input {
|
||||
if len(input) > 0 {
|
||||
matched = matching.FindAll(input, options)
|
||||
} else {
|
||||
matched = originalOrder
|
||||
}
|
||||
cursor = 0
|
||||
prevInput = input
|
||||
}
|
||||
|
||||
{ // cursor update
|
||||
moveCursorUp := isPressedRepeat(rl.KeyP) && isControlDown
|
||||
moveCursorDown := isPressedRepeat(rl.KeyN) && isControlDown
|
||||
if moveCursorUp {
|
||||
cursor -= 1
|
||||
}
|
||||
if moveCursorDown {
|
||||
cursor += 1
|
||||
}
|
||||
if cursor >= len(matched) {
|
||||
cursor = len(matched) - 1
|
||||
}
|
||||
if cursor < 0 {
|
||||
cursor = 0
|
||||
}
|
||||
}
|
||||
|
||||
if enter {
|
||||
rl.EndDrawing() // TODO: dont need this?
|
||||
rl.CloseWindow()
|
||||
if cursor < len(matched) {
|
||||
return options[matched[cursor].Idx], RayMenuResult_Chosen
|
||||
}
|
||||
return "", RayMenuResult_NoChoice
|
||||
}
|
||||
|
||||
for i, match := range matched {
|
||||
bounds := nextBounds()
|
||||
textBounds := bounds
|
||||
textBounds.X += textBounds.Height
|
||||
textBounds.Width -= textBounds.Height
|
||||
rg.DrawText(
|
||||
options[match.Idx],
|
||||
textBounds,
|
||||
int32(rg.TEXT_ALIGN_LEFT),
|
||||
rl.White,
|
||||
)
|
||||
|
||||
if i == cursor {
|
||||
rl.DrawCircle(
|
||||
int32(bounds.X)+int32(bounds.Height)/2,
|
||||
int32(bounds.Y)+int32(bounds.Height)/2,
|
||||
max(textBoxHeight / 8, 1),
|
||||
rl.White,
|
||||
)
|
||||
}
|
||||
}
|
||||
rl.EndDrawing()
|
||||
}
|
||||
|
||||
return "", RayMenuResult_NoChoice
|
||||
}
|
||||
|
||||
var yOffset float32 = 0.0
|
||||
const textBoxHeight = fontSize + 6
|
||||
|
||||
func resetBounds() {
|
||||
yOffset = 0.0
|
||||
}
|
||||
|
||||
func nextBounds() (bounds rl.Rectangle) {
|
||||
bounds = rl.Rectangle{X: 0, Y: yOffset, Width: float32(rl.GetScreenWidth()), Height: textBoxHeight}
|
||||
yOffset += textBoxHeight
|
||||
return
|
||||
}
|
||||
|
||||
func initialize() State {
|
||||
rl.SetTraceLogLevel(rl.LogError)
|
||||
rl.InitWindow(width, 0, "raymenu")
|
||||
rl.SetWindowState(rl.FlagWindowUndecorated)
|
||||
rl.SetTargetFPS(
|
||||
int32(
|
||||
rl.GetMonitorRefreshRate(
|
||||
rl.GetCurrentMonitor(),
|
||||
),
|
||||
),
|
||||
)
|
||||
rl.SetWindowSize(
|
||||
width,
|
||||
rl.GetMonitorHeight(
|
||||
rl.GetCurrentMonitor(),
|
||||
),
|
||||
)
|
||||
|
||||
return State{
|
||||
Font: rl.LoadFontFromMemory(".ttf", gomonoNerdFont_ttf, fontSize, nil),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user