Watch
2
0
Fork
You've already forked raylib-cs
0
raylib-cs/Examples/Core/DirectoryFiles.cs
2026-07-17 07:52:43 +02:00

205 lines
7 KiB
C#

/*******************************************************************************************
*
* raylib [core] example - directory files
*
* Example complexity rating: [★☆☆☆] 1/4
*
* Example originally created with raylib 5.5, last time updated with raylib 5.6
*
* Example contributed by Hugo ARNAL (@hugoarnal) and reviewed by Ramon Santamaria (@raysan5)
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2025 Hugo ARNAL (@hugoarnal)
*
********************************************************************************************/
// NOTE: The original example relies on raygui (GuiButton, GuiLabel, GuiListViewEx) for its UI.
// raygui is not part of the raylib-cs bindings, so the back button, directory label and file
// list view are reimplemented here with plain raylib primitives. The directory navigation
// behaviour (enter directories, go back) is preserved.
using System;
using System.Numerics;
using static Raylib_cs.Raylib;
namespace Examples.Core;
public partial class DirectoryFiles : IExample
{
private const int screenWidth = 800;
private const int screenHeight = 450;
private const string FileFilter = "DIRS*;.png;.c";
public string Name => "Core / Directory Files";
public string Title => "raylib [core] example - directory files";
private string directory;
private FilePathList files;
private bool btnBackPressed;
private int listScrollIndex;
private int listItemActive;
private int listItemFocused;
public void Init()
{
directory = GetWorkingDirectoryAsString();
// Load file-paths on current working directory
// NOTE: LoadDirectoryFiles() loads files and directories by default,
// use LoadDirectoryFilesEx() for custom filters and recursive directories loading
//files = LoadDirectoryFiles(directory);
files = LoadDirectoryFilesEx(directory, FileFilter, false);
btnBackPressed = false;
listScrollIndex = 0;
listItemActive = -1;
listItemFocused = -1;
}
public void Update()
{
// Update
//----------------------------------------------------------------------------------
if (btnBackPressed)
{
directory = GetPrevDirectoryPath(directory);
UnloadDirectoryFiles(files);
files = LoadDirectoryFilesEx(directory, FileFilter, false);
listScrollIndex = 0;
listItemActive = -1;
listItemFocused = -1;
}
if ((listItemActive >= 0) && (listItemActive < (int)files.Count))
{
string selected = files[(uint)listItemActive];
bool isDirectory = DirectoryExists(selected);
if (isDirectory)
{
directory = selected;
UnloadDirectoryFiles(files);
files = LoadDirectoryFilesEx(directory, FileFilter, false);
listScrollIndex = 0;
listItemActive = -1;
listItemFocused = -1;
}
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(Color.RayWhite);
Vector2 mouse = GetMousePosition();
// Back button "<"
Rectangle backBounds = new Rectangle(40.0f, 10.0f, 48, 28);
bool backHover = CheckCollisionPointRec(mouse, backBounds);
DrawRectangleRec(backBounds, backHover ? Color.SkyBlue : Color.LightGray);
DrawRectangleLinesEx(backBounds, 1, Color.Gray);
int backTextWidth = MeasureText("<", 20);
DrawText("<", (int)(backBounds.X + (backBounds.Width - backTextWidth) / 2), (int)(backBounds.Y + 4), 20, Color.DarkGray);
btnBackPressed = backHover && IsMouseButtonReleased(MouseButton.Left);
// Current directory label
DrawText(directory, 40 + 48 + 10, 16, 20, Color.DarkGray);
// File list view
Rectangle listBounds = new Rectangle(0, 50, GetScreenWidth(), GetScreenHeight() - 50);
DrawRectangleRec(listBounds, Color.RayWhite);
DrawRectangleLinesEx(listBounds, 1, Color.Gray);
int count = (int)files.Count;
float rowHeight = 28;
int visibleRows = (int)(listBounds.Height / rowHeight);
bool mouseInList = CheckCollisionPointRec(mouse, listBounds);
if (mouseInList)
{
listScrollIndex -= (int)GetMouseWheelMove();
}
int maxScroll = Math.Max(0, count - visibleRows);
listScrollIndex = Math.Clamp(listScrollIndex, 0, maxScroll);
listItemFocused = -1;
for (int i = 0; i < visibleRows; i++)
{
int itemIndex = listScrollIndex + i;
if (itemIndex >= count)
{
break;
}
Rectangle rowRec = new Rectangle(listBounds.X + 1, listBounds.Y + 1 + i * rowHeight, listBounds.Width - 2, rowHeight);
bool rowHover = mouseInList && CheckCollisionPointRec(mouse, rowRec);
if (itemIndex == listItemActive)
{
DrawRectangleRec(rowRec, Fade(Color.SkyBlue, 0.7f));
}
else if (rowHover)
{
DrawRectangleRec(rowRec, Fade(Color.SkyBlue, 0.3f));
}
if (rowHover)
{
listItemFocused = itemIndex;
if (IsMouseButtonReleased(MouseButton.Left))
{
listItemActive = itemIndex;
}
}
DrawText(files[(uint)itemIndex], (int)rowRec.X + 40, (int)rowRec.Y + 8, 10, Color.DarkGray);
}
EndDrawing();
//----------------------------------------------------------------------------------
}
public void Unload()
{
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadDirectoryFiles(files);
}
public static int Main()
{
// Initialization
//--------------------------------------------------------------------------------------
InitWindow(screenWidth, screenHeight, "raylib [core] example - directory files");
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
var game = new DirectoryFiles();
game.Init();
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
game.Update();
}
game.Unload();
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
}