-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
1341 add file selector plugin #1342
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,193 @@ | ||||||||
#include "plugin.hpp" | ||||||||
#include <filesystem> | ||||||||
|
||||||||
#include <imgui.h> | ||||||||
|
||||||||
#include <cubos/core/data/fs/file_system.hpp> | ||||||||
#include <cubos/core/memory/standard_stream.hpp> | ||||||||
|
||||||||
#include <cubos/engine/imgui/plugin.hpp> | ||||||||
|
||||||||
using cubos::core::data::FileSystem; | ||||||||
using cubos::engine::Cubos; | ||||||||
|
||||||||
namespace fs = std::filesystem; | ||||||||
|
||||||||
using namespace tesseratos; | ||||||||
|
||||||||
namespace | ||||||||
{ | ||||||||
struct FileSelectorState | ||||||||
{ | ||||||||
CUBOS_ANONYMOUS_REFLECT(FileSelectorState); | ||||||||
|
||||||||
// Absolute path to the current directory (for the filesystem not for the virtual filesystem) | ||||||||
std::string currentPath = | ||||||||
(fs::current_path().parent_path().parent_path() / "tools" / "tesseratos" / "assets").string(); | ||||||||
// bool isLocal = true to use the virtual filesystem | ||||||||
bool isLocal = true; | ||||||||
bool isGridMode = true; | ||||||||
bool showFileSelector = false; | ||||||||
std::string selectedFile; | ||||||||
}; | ||||||||
} // namespace | ||||||||
|
||||||||
static std::optional<std::string> showFileSelector(FileSelectorState& state) | ||||||||
{ | ||||||||
if (!state.showFileSelector) | ||||||||
{ | ||||||||
return std::nullopt; | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||
} | ||||||||
|
||||||||
ImGui::Begin("File Selector"); | ||||||||
|
||||||||
// Absolue path for the virtual filesystem | ||||||||
std::string relativePath = | ||||||||
fs::relative(state.currentPath, fs::current_path().parent_path().parent_path() / "tools" / "tesseratos") | ||||||||
.string(); | ||||||||
|
||||||||
std::replace(relativePath.begin(), relativePath.end(), '\\', '/'); | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||
|
||||||||
ImGui::Text("Current Path: %s", state.isLocal ? std::string(relativePath).c_str() : state.currentPath.c_str()); | ||||||||
|
||||||||
ImGui::Separator(); | ||||||||
|
||||||||
// Search bar | ||||||||
static char searchBuffer[256] = ""; | ||||||||
ImGui::InputTextWithHint("##search", "Search...", searchBuffer, sizeof(searchBuffer)); | ||||||||
|
||||||||
ImGui::SameLine(); | ||||||||
|
||||||||
// Parent directory button | ||||||||
if (!(state.isLocal && relativePath == "assets")) | ||||||||
{ | ||||||||
if (ImGui::Button("Up")) | ||||||||
{ | ||||||||
state.currentPath = fs::path(state.currentPath).parent_path().string(); | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
ImGui::SameLine(); | ||||||||
|
||||||||
// View mode toggle | ||||||||
if (ImGui::RadioButton("Grid", state.isGridMode)) | ||||||||
{ | ||||||||
state.isGridMode = true; | ||||||||
} | ||||||||
|
||||||||
ImGui::SameLine(); | ||||||||
|
||||||||
if (ImGui::RadioButton("List", !state.isGridMode)) | ||||||||
{ | ||||||||
state.isGridMode = false; | ||||||||
} | ||||||||
|
||||||||
ImGui::Separator(); | ||||||||
|
||||||||
float cellSize = 100.0F; // Size of each grid cell | ||||||||
float padding = 10.0F; // Padding between cells | ||||||||
|
||||||||
if (state.isGridMode) | ||||||||
{ | ||||||||
// Calculate number of columns for grid layout | ||||||||
float panelWidth = ImGui::GetContentRegionAvail().x; | ||||||||
int columns = (int)(panelWidth / (cellSize + padding)); | ||||||||
if (columns < 1) | ||||||||
{ | ||||||||
columns = 1; | ||||||||
} | ||||||||
ImGui::Columns(columns, nullptr, false); | ||||||||
} | ||||||||
|
||||||||
for (const auto& entry : fs::directory_iterator(state.currentPath)) | ||||||||
{ | ||||||||
// Filter files and directories based on search query | ||||||||
std::string fileName = entry.path().filename().string(); | ||||||||
if (strlen(searchBuffer) > 0 && fileName.find(searchBuffer) == std::string::npos) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
continue; | ||||||||
|
||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
if (entry.is_directory()) | ||||||||
{ | ||||||||
// Directories | ||||||||
if (ImGui::Button((fileName + "/").c_str(), state.isGridMode ? ImVec2(cellSize, cellSize) : ImVec2(0, 0))) | ||||||||
{ | ||||||||
state.currentPath = entry.path().string(); | ||||||||
} | ||||||||
} | ||||||||
else if (entry.is_regular_file()) | ||||||||
{ | ||||||||
// Files | ||||||||
if (ImGui::Selectable(fileName.c_str(), state.selectedFile == entry.path().string(), 0, | ||||||||
state.isGridMode ? ImVec2(cellSize, cellSize) : ImVec2(0, 0))) | ||||||||
{ | ||||||||
std::string selectedFilePath = entry.path().string(); | ||||||||
if (state.isLocal) | ||||||||
{ | ||||||||
selectedFilePath = fs::relative(selectedFilePath, fs::current_path().parent_path().parent_path() / | ||||||||
"tools" / "tesseratos") | ||||||||
.string(); | ||||||||
std::replace(selectedFilePath.begin(), selectedFilePath.end(), '\\', '/'); | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||
state.selectedFile = selectedFilePath; | ||||||||
} | ||||||||
else | ||||||||
{ | ||||||||
state.selectedFile = selectedFilePath; | ||||||||
} | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
if (state.isGridMode) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
ImGui::NextColumn(); // Move to next column in grid layout | ||||||||
} | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
||||||||
if (state.isGridMode) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
ImGui::Columns(1); // End grid layout | ||||||||
|
||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
ImGui::Separator(); | ||||||||
|
||||||||
// Display selected file | ||||||||
if (!state.selectedFile.empty()) | ||||||||
{ | ||||||||
ImGui::Text("Selected File: %s", state.selectedFile.c_str()); | ||||||||
|
||||||||
// Confirm button | ||||||||
if (ImGui::Button("Select")) | ||||||||
{ | ||||||||
ImGui::End(); | ||||||||
std::string selectedFile = state.selectedFile; | ||||||||
state.selectedFile.clear(); | ||||||||
state.showFileSelector = false; | ||||||||
return selectedFile; | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||
} | ||||||||
} | ||||||||
else | ||||||||
{ | ||||||||
ImGui::Text("No file selected."); | ||||||||
} | ||||||||
|
||||||||
ImGui::End(); | ||||||||
return std::nullopt; | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||
} | ||||||||
|
||||||||
static std::optional<std::string> createFileSelectorButton(FileSelectorState& state, const char* label) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||
{ | ||||||||
if (ImGui::Button(label)) | ||||||||
{ | ||||||||
state.showFileSelector = true; | ||||||||
} | ||||||||
|
||||||||
auto selectedFile = showFileSelector(state); | ||||||||
return selectedFile; | ||||||||
} | ||||||||
|
||||||||
void tesseratos::fileSelectorPlugin(Cubos& cubos) | ||||||||
{ | ||||||||
cubos.depends(cubos::engine::imguiPlugin); | ||||||||
cubos.resource<FileSelectorState>(); | ||||||||
|
||||||||
cubos.system("show File Selector UI").tagged(cubos::engine::imguiTag).call([](FileSelectorState& state) { | ||||||||
ImGui::Begin("File Selector"); | ||||||||
createFileSelectorButton(state, "Open File Selector"); | ||||||||
ImGui::End(); | ||||||||
}); | ||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/// @dir | ||
/// @brief @ref tesseratos-file-selector-plugin plugin directory. | ||
|
||
/// @file | ||
/// @brief Plugin entry point. | ||
/// @ingroup tesseratos-file-selector-plugin | ||
|
||
#pragma once | ||
|
||
#include <cubos/engine/prelude.hpp> | ||
|
||
namespace tesseratos | ||
{ | ||
/// @defgroup tesseratos-file-selector-plugin Asset explorer | ||
/// @ingroup tesseratos | ||
/// @brief Allows selecting files in the filesystem | ||
/// | ||
/// ## Dependencies | ||
/// - @ref imgui-plugin | ||
|
||
/// @brief Plugin entry function. | ||
/// @param cubos @b Cubos main class | ||
/// @ingroup tesseratos-file-selector-plugin | ||
void fileSelectorPlugin(cubos::engine::Cubos& cubos); | ||
} // namespace tesseratos |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no template named
optional
in namespacestd