161 lines
4.3 KiB
Odin
161 lines
4.3 KiB
Odin
package assetviewer
|
|
|
|
import rl "vendor:raylib"
|
|
import "core:os"
|
|
import "core:fmt"
|
|
import "core:strings"
|
|
import fp "core:path/filepath"
|
|
|
|
Vec2 :: [2]f32
|
|
Rect :: rl.Rectangle
|
|
Img :: rl.Image
|
|
Tex :: rl.Texture
|
|
|
|
SCREEN_WIDTH : i32 = 1000
|
|
SCREEN_HEIGHT : i32 = 800
|
|
BW := f32(SCREEN_WIDTH)
|
|
BH := f32(SCREEN_HEIGHT)
|
|
|
|
AppState :: struct {
|
|
dt: f32,
|
|
img_scale: f32,
|
|
image_paths: [dynamic]string,
|
|
textures: [dynamic]Tex,
|
|
selection_single: int,
|
|
selection_path: cstring,
|
|
selection_tex: [dynamic]int,
|
|
}
|
|
|
|
check_dir :: proc(info: os.File_Info, in_err: os.Error, user_data: rawptr) -> (err: os.Error, skip_dir: bool) {
|
|
state := transmute(^AppState) user_data
|
|
if !info.is_dir {
|
|
if fp.ext(info.name) == ".png" {
|
|
append(&state.image_paths, info.fullpath)
|
|
}
|
|
}
|
|
return nil, false
|
|
}
|
|
|
|
init_state :: proc() -> ^AppState {
|
|
state := AppState {
|
|
img_scale = 1
|
|
}
|
|
|
|
arguments := os.args[1:]
|
|
root_dir := len(arguments) == 0 ? os.get_current_directory() : arguments[0]
|
|
fp.walk(root_dir, check_dir, &state)
|
|
|
|
for path in state.image_paths {
|
|
path := strings.clone_to_cstring(path)
|
|
defer delete(path)
|
|
img := rl.LoadImage(path)
|
|
defer rl.UnloadImage(img)
|
|
tex := rl.LoadTextureFromImage(img)
|
|
append(&state.textures, tex)
|
|
}
|
|
set_sprite_info(&state)
|
|
|
|
return new_clone(state)
|
|
}
|
|
|
|
set_sprite_info :: proc(s: ^AppState) {
|
|
path := s.image_paths[s.selection_single]
|
|
spath,_ := fp.rel(os.get_current_directory(), path)
|
|
tex := s.textures[s.selection_single]
|
|
info := fmt.aprintf("Width: %d | Height: %d | Path: %s", tex.width, tex.height, spath)
|
|
defer delete(info)
|
|
s.selection_path = strings.clone_to_cstring(info)
|
|
}
|
|
|
|
player_input :: proc(s: ^AppState) {
|
|
if rl.IsKeyPressed(.EQUAL) {
|
|
s.img_scale += 1
|
|
}
|
|
if rl.IsKeyPressed(.MINUS) && s.img_scale > 1 {
|
|
s.img_scale -= 1
|
|
}
|
|
is_dir_pressed :: proc(keys: []rl.KeyboardKey) -> bool {
|
|
for k in keys {
|
|
pressed := rl.IsKeyPressed(k) || rl.IsKeyPressedRepeat(k)
|
|
if pressed {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
left := is_dir_pressed([]rl.KeyboardKey{.A, .H, .LEFT})
|
|
right := is_dir_pressed([]rl.KeyboardKey{.D, .L, .RIGHT})
|
|
up := is_dir_pressed([]rl.KeyboardKey{.W, .K, .UP})
|
|
down := is_dir_pressed([]rl.KeyboardKey{.S, .J, .DOWN})
|
|
if left && s.selection_single > 0 {
|
|
s.selection_single -= 1
|
|
set_sprite_info(s)
|
|
}
|
|
if right && s.selection_single < len(s.textures) - 1 {
|
|
s.selection_single += 1
|
|
set_sprite_info(s)
|
|
}
|
|
}
|
|
|
|
draw :: proc(s: ^AppState) {
|
|
row :i32 = 0
|
|
col :i32 = 0
|
|
padding :i32 = 0
|
|
scale := s.img_scale
|
|
tallest_height :f32 = 0
|
|
for tex,i in s.textures {
|
|
tw := f32(tex.width) * scale
|
|
th := f32(tex.height) * scale
|
|
if col + i32(tw) > SCREEN_WIDTH {
|
|
row += i32(tallest_height)
|
|
col = 0
|
|
}
|
|
if th > tallest_height {
|
|
tallest_height = th
|
|
}
|
|
pos := Vec2{f32(col), f32(row)}
|
|
rl.DrawTextureEx(tex, pos, 0, scale, rl.WHITE);
|
|
color := i == s.selection_single ? rl.GREEN : rl.BLACK
|
|
rl.DrawRectangleLinesEx({pos.x, pos.y, tw, th}, 2, color);
|
|
col += i32(tw) + padding
|
|
}
|
|
// Info box at the bottom
|
|
tsize :f32 = 18
|
|
pos := Vec2{0, f32(SCREEN_HEIGHT) - tsize}
|
|
info_rect := Rect{pos.x, pos.y, f32(SCREEN_WIDTH), tsize}
|
|
rl.DrawRectangleRec(info_rect, rl.BLACK);
|
|
rl.DrawText(s.selection_path, i32(pos.x), i32(pos.y), i32(tsize), rl.WHITE)
|
|
}
|
|
|
|
main :: proc() {
|
|
rl.SetTraceLogLevel(.ERROR)
|
|
rl.InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Asset Browser")
|
|
monitor := rl.GetCurrentMonitor()
|
|
SCREEN_WIDTH = rl.GetMonitorWidth(monitor) - 50
|
|
SCREEN_HEIGHT = rl.GetMonitorHeight(monitor) - 50
|
|
rl.SetWindowSize(rl.GetMonitorWidth(monitor), rl.GetMonitorHeight(monitor))
|
|
rl.SetTargetFPS(60)
|
|
|
|
state := init_state()
|
|
|
|
for !rl.WindowShouldClose() {
|
|
state.dt = rl.GetFrameTime()
|
|
|
|
player_input(state)
|
|
|
|
// update(state)
|
|
|
|
rl.BeginDrawing()
|
|
rl.ClearBackground(rl.GRAY)
|
|
|
|
draw(state)
|
|
|
|
rl.EndDrawing()
|
|
}
|
|
|
|
for tex in state.textures {
|
|
rl.UnloadTexture(tex)
|
|
}
|
|
rl.CloseWindow()
|
|
}
|