Simple file manager for loading, resizing
This commit is contained in:
parent
a1f90962f6
commit
55f30654f4
|
@ -29,6 +29,7 @@ loadCart :: proc(target: ^Cart, filename: cstring) -> CartLoadError {
|
||||||
return CartLoadError.Wrong_Size
|
return CartLoadError.Wrong_Size
|
||||||
}
|
}
|
||||||
target.texture = rl.LoadTextureFromImage(target.image)
|
target.texture = rl.LoadTextureFromImage(target.image)
|
||||||
|
rl.SetTextureFilter(target.texture, .POINT)
|
||||||
target.loaded = true
|
target.loaded = true
|
||||||
return CartLoadError.None
|
return CartLoadError.None
|
||||||
}
|
}
|
||||||
|
|
134
guimode.odin
134
guimode.odin
|
@ -5,11 +5,12 @@ import rl "vendor:raylib"
|
||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
import "core:slice"
|
import "core:slice"
|
||||||
|
import "core:bytes"
|
||||||
import "core:os"
|
import "core:os"
|
||||||
|
|
||||||
|
|
||||||
W :: 400
|
W :: 640
|
||||||
H :: 300
|
H :: 480
|
||||||
|
|
||||||
width : int = W
|
width : int = W
|
||||||
height : int = H
|
height : int = H
|
||||||
|
@ -23,17 +24,31 @@ fileNameBuffer : [FILENAME_MAX]byte
|
||||||
fileNameString := cstring(&fileNameBuffer[0])
|
fileNameString := cstring(&fileNameBuffer[0])
|
||||||
editMode := false
|
editMode := false
|
||||||
|
|
||||||
|
fileListScrolling : i32 = 0
|
||||||
|
fileListActive : i32 = -1
|
||||||
|
fileListFocus : i32 = -1
|
||||||
|
|
||||||
|
fileList : rl.FilePathList
|
||||||
|
|
||||||
|
|
||||||
State :: enum {
|
State :: enum {
|
||||||
CartsInput,
|
CartsInput,
|
||||||
Export,
|
Export,
|
||||||
GotError,
|
GotError,
|
||||||
Exported
|
Exported,
|
||||||
|
FileSelect
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphicsMode :: proc() {
|
GraphicsMode :: proc() {
|
||||||
|
files = slice.into_dynamic(filesBuf[:])
|
||||||
cart := Cart{}
|
cart := Cart{}
|
||||||
target := Cart{}
|
target := Cart{}
|
||||||
|
fileListTarget : ^Cart
|
||||||
|
|
||||||
|
DefaultName :string : "output.p8.png"
|
||||||
|
for char, i in DefaultName {
|
||||||
|
fileNameBuffer[i] = auto_cast char
|
||||||
|
}
|
||||||
|
|
||||||
errorMessages := map[CartLoadError]cstring {
|
errorMessages := map[CartLoadError]cstring {
|
||||||
.None = "",
|
.None = "",
|
||||||
|
@ -44,15 +59,15 @@ GraphicsMode :: proc() {
|
||||||
defer delete(errorMessages)
|
defer delete(errorMessages)
|
||||||
currentError := CartLoadError.None
|
currentError := CartLoadError.None
|
||||||
|
|
||||||
rl.SetConfigFlags({rl.ConfigFlag.WINDOW_RESIZABLE})
|
rl.SetConfigFlags({.WINDOW_RESIZABLE, .INTERLACED_HINT})
|
||||||
rl.InitWindow(W, H, "PicoRepico")
|
rl.InitWindow(W, H, "PicoRepico")
|
||||||
rl.SetTargetFPS(60)
|
rl.SetTargetFPS(60)
|
||||||
|
|
||||||
//fontData := #load("font.ttf")
|
//fontData := #load("font.ttf")
|
||||||
//font := rl.LoadFontFromMemory(".ttf", raw_data(fontData), auto_cast len(fontData), 8, nil, 0)
|
//font := rl.LoadFontFromMemory(".ttf", raw_data(fontData), auto_cast len(fontData), 8, nil, 0)
|
||||||
font := rl.LoadFontEx("font.ttf", 32, nil, 0)
|
//font := rl.LoadFontEx("font.ttf", 32, nil, 0)
|
||||||
rl.GuiSetFont(font)
|
//rl.GuiSetFont(font)
|
||||||
rl.GuiSetStyle(auto_cast rl.GuiControl.DEFAULT, auto_cast rl.GuiControlProperty.BORDER_COLOR_NORMAL, i32(rl.ColorToInt(rl.Color{211, 2, 255, 255})))
|
//rl.GuiSetStyle(auto_cast rl.GuiControl.DEFAULT, auto_cast rl.GuiControlProperty.BORDER_COLOR_NORMAL, i32(rl.ColorToInt(rl.Color{211, 2, 255, 255})))
|
||||||
|
|
||||||
hw : f32 = auto_cast width / 2
|
hw : f32 = auto_cast width / 2
|
||||||
hh : f32 = auto_cast height / 2
|
hh : f32 = auto_cast height / 2
|
||||||
|
@ -67,7 +82,7 @@ GraphicsMode :: proc() {
|
||||||
hw = auto_cast width / 2
|
hw = auto_cast width / 2
|
||||||
hh = auto_cast height / 2
|
hh = auto_cast height / 2
|
||||||
|
|
||||||
#partial switch state {
|
switch state {
|
||||||
case .CartsInput: {
|
case .CartsInput: {
|
||||||
mouse := rl.GetMousePosition()
|
mouse := rl.GetMousePosition()
|
||||||
if rl.IsFileDropped() {
|
if rl.IsFileDropped() {
|
||||||
|
@ -93,18 +108,24 @@ GraphicsMode :: proc() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zoom = 1
|
||||||
|
if width >= 640 && height > 450 {
|
||||||
|
zoom = 2
|
||||||
|
}
|
||||||
|
|
||||||
buttonCartRect := rl.Rectangle{
|
buttonCartRect := rl.Rectangle{
|
||||||
x = hw - CART_WIDTH - 20,
|
x = hw - CART_WIDTH * f32(zoom) - 5,
|
||||||
y = 8,
|
y = 8,
|
||||||
width = CART_WIDTH,
|
width = CART_WIDTH * f32(zoom),
|
||||||
height = CART_HEIGHT,
|
height = CART_HEIGHT * f32(zoom),
|
||||||
}
|
}
|
||||||
buttonTargetRect := rl.Rectangle{
|
buttonTargetRect := rl.Rectangle{
|
||||||
x = hw + 20,
|
x = hw + 5,
|
||||||
y = 8,
|
y = 8,
|
||||||
width = CART_WIDTH,
|
width = CART_WIDTH * f32(zoom),
|
||||||
height = CART_HEIGHT,
|
height = CART_HEIGHT * f32(zoom),
|
||||||
}
|
}
|
||||||
|
cartRect := rl.Rectangle{0, 0, CART_WIDTH, CART_HEIGHT}
|
||||||
convertButtonRect := rl.Rectangle{
|
convertButtonRect := rl.Rectangle{
|
||||||
x = hw - 40,
|
x = hw - 40,
|
||||||
y = auto_cast height - 38,
|
y = auto_cast height - 38,
|
||||||
|
@ -114,20 +135,32 @@ GraphicsMode :: proc() {
|
||||||
|
|
||||||
rl.BeginDrawing()
|
rl.BeginDrawing()
|
||||||
rl.GuiDummyRec(rl.Rectangle{0, 0, auto_cast width, auto_cast height}, "")
|
rl.GuiDummyRec(rl.Rectangle{0, 0, auto_cast width, auto_cast height}, "")
|
||||||
rl.GuiButton(buttonCartRect, "Place here cart")
|
|
||||||
rl.GuiButton(buttonTargetRect, "Place here target")
|
|
||||||
|
|
||||||
|
if rl.GuiButton(buttonCartRect, "Drag original\ncart here") {
|
||||||
|
fileListTarget = &cart
|
||||||
|
cd(".")
|
||||||
|
state = .FileSelect
|
||||||
|
}
|
||||||
if cart.loaded {
|
if cart.loaded {
|
||||||
rl.DrawTexture(cart.texture, auto_cast buttonCartRect.x, auto_cast buttonCartRect.y, rl.WHITE)
|
rl.DrawTexturePro(cart.texture, cartRect, buttonCartRect, {0, 0}, 0, rl.WHITE)
|
||||||
|
}
|
||||||
|
if rl.GuiButton(buttonTargetRect, "Drag target\nshell here") {
|
||||||
|
fileListTarget = &target
|
||||||
|
cd(".")
|
||||||
|
state = .FileSelect
|
||||||
}
|
}
|
||||||
if target.loaded {
|
if target.loaded {
|
||||||
rl.DrawTexture(target.texture, auto_cast buttonTargetRect.x, auto_cast buttonTargetRect.y, rl.WHITE)
|
rl.DrawTexturePro(target.texture, cartRect, buttonTargetRect, {0, 0}, 0, rl.WHITE)
|
||||||
}
|
}
|
||||||
if !(cart.loaded && target.loaded) { rl.GuiDisable() }
|
if !(cart.loaded && target.loaded) { rl.GuiDisable() }
|
||||||
if rl.GuiButton(convertButtonRect, "CONVERT!") {
|
if rl.GuiButton(convertButtonRect, "CONVERT!") {
|
||||||
state = .Export
|
state = .Export
|
||||||
}
|
}
|
||||||
rl.GuiEnable()
|
rl.GuiEnable()
|
||||||
|
|
||||||
|
if rl.GuiLabelButton(rl.Rectangle{auto_cast width-60, auto_cast height-20, 60, 20}, "by Nefrace") {
|
||||||
|
rl.OpenURL("https://nefrace.itch.io")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case .Export: {
|
case .Export: {
|
||||||
res := rl.GuiTextInputBox(rl.Rectangle{hw - 100, 60, 200, 100}, "Input filename for result", "", "ok;cancel", fileNameString, FILENAME_MAX, nil)
|
res := rl.GuiTextInputBox(rl.Rectangle{hw - 100, 60, 200, 100}, "Input filename for result", "", "ok;cancel", fileNameString, FILENAME_MAX, nil)
|
||||||
|
@ -151,8 +184,35 @@ GraphicsMode :: proc() {
|
||||||
state = .CartsInput
|
state = .CartsInput
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case .FileSelect: {
|
||||||
|
rl.GuiPanel(rl.Rectangle{4, 4, auto_cast width - 8, auto_cast height - 8}, "Select a file")
|
||||||
|
if rl.GuiButton(rl.Rectangle{auto_cast width - 26, 8, 16, 16}, "#128#") {
|
||||||
|
state = .CartsInput
|
||||||
}
|
}
|
||||||
|
if rl.GuiButton(rl.Rectangle{8, 30, 50, 22}, "Open") {
|
||||||
|
if fileListActive == -1 {break}
|
||||||
|
if rl.DirectoryExists(files[fileListActive]) {
|
||||||
|
cd(files[fileListActive])
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if rl.GetFileExtension(files[fileListActive]) != ".png" {
|
||||||
|
fmt.println("not a png")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
currentError = loadCart(fileListTarget, files[fileListActive])
|
||||||
|
if currentError != .None {
|
||||||
|
state = .GotError
|
||||||
|
}
|
||||||
|
state = .CartsInput
|
||||||
|
|
||||||
|
}
|
||||||
|
if rl.GuiButton(rl.Rectangle{60, 30, 50, 22}, "Up") {
|
||||||
|
cd("..")
|
||||||
|
}
|
||||||
|
rl.GuiSetStyle(auto_cast rl.GuiControl.LISTVIEW, auto_cast rl.GuiControlProperty.TEXT_ALIGNMENT, auto_cast rl.GuiTextAlignment.TEXT_ALIGN_LEFT)
|
||||||
|
res := rl.GuiListViewEx(rl.Rectangle{8, 54, auto_cast width - 16, auto_cast height - 62}, filesPtr, auto_cast filesCount, &fileListScrolling, &fileListActive, &fileListFocus)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rl.EndDrawing()
|
rl.EndDrawing()
|
||||||
}
|
}
|
||||||
|
@ -161,3 +221,41 @@ GraphicsMode :: proc() {
|
||||||
unloadCart(&target)
|
unloadCart(&target)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filesBuf : [1024*8]cstring
|
||||||
|
files : [dynamic]cstring
|
||||||
|
filesPtr : [^]cstring
|
||||||
|
filesCount : i32 = 0
|
||||||
|
|
||||||
|
cd :: proc(dir: cstring) -> (result: bool) {
|
||||||
|
result = rl.ChangeDirectory(dir)
|
||||||
|
rl.UnloadDirectoryFiles(fileList)
|
||||||
|
clear(&files)
|
||||||
|
fileList = rl.LoadDirectoryFiles(".")
|
||||||
|
|
||||||
|
for fname in fileList.paths[:fileList.count] {
|
||||||
|
if rl.DirectoryExists(fname) || rl.GetFileExtension(fname) == ".png" {
|
||||||
|
append(&files, fname)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
slice.sort_by(files[:], proc(i,j:cstring) -> bool {
|
||||||
|
a := string(i)
|
||||||
|
b := string(j)
|
||||||
|
adir := rl.DirectoryExists(i)
|
||||||
|
bdir := rl.DirectoryExists(j)
|
||||||
|
if (adir && bdir) || (!adir && !bdir) {
|
||||||
|
return strings.compare(a, b) == -1
|
||||||
|
}
|
||||||
|
return adir && !bdir
|
||||||
|
})
|
||||||
|
|
||||||
|
filesPtr = raw_data(files)
|
||||||
|
filesCount = auto_cast len(files)
|
||||||
|
|
||||||
|
|
||||||
|
// slice.sort_by_cmp(fileList.paths[:fileList.count], strings.compare())
|
||||||
|
fileListScrolling = 0
|
||||||
|
fileListActive = -1
|
||||||
|
fileListFocus = -1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue