Rebuild trinity visualizer from bare SDL and OpenGL to using Raylib. Added Code for serial parsing on linux. Current functionality reads incoming quaternion packet data coming in over serial and displays the values and also visualizes with a cube, connect and disconnect is implemented. Essentially rebuild the functionality of the old version with added linux support.
This commit is contained in:
@@ -0,0 +1,280 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib-extras [ImGui] example - asset browser
|
||||
*
|
||||
* This is a more complex ImGui Integration
|
||||
* It shows how to build windows on top of 2d and 3d views using a render texture
|
||||
*
|
||||
* Copyright (c) 2024 Jeffery Myers
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#define _CRT_NONSTDC_NO_WARNINGS
|
||||
|
||||
#include "asset_browser.h"
|
||||
#include "imgui_utils.h"
|
||||
#include "imgui.h"
|
||||
#include "imgui_internal.h"
|
||||
#include "raylib.h"
|
||||
#include "extras/IconsFontAwesome6.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
AssetBrowserPanel::AssetBrowserPanel()
|
||||
{
|
||||
AssetRoot = GetWorkingDirectory();
|
||||
RebuildFolderTree();
|
||||
SetCurrentFolder(&FolderRoot);
|
||||
|
||||
CurrentView = &ListView;
|
||||
}
|
||||
|
||||
void AssetBrowserPanel::Show()
|
||||
{
|
||||
ShowHeader();
|
||||
|
||||
ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingStretchSame | ImGuiTableFlags_Borders;
|
||||
|
||||
if (ImGui::BeginTable("AssetBrowserTab", 2, flags, ImGui::GetContentRegionAvail()))
|
||||
{
|
||||
ImGui::TableSetupColumn("FolderView", ImGuiTableColumnFlags_None, 0.25f);
|
||||
ImGui::TableSetupColumn("AssetView", ImGuiTableColumnFlags_None, 0.75f);
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
if (ImGui::BeginChild("FolderList", ImGui::GetContentRegionAvail(),ImGuiChildFlags_None, ImGuiWindowFlags_None))
|
||||
{
|
||||
ShowFolderTree();
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ShowFilePane();
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
void AssetBrowserPanel::RebuildFolderTree()
|
||||
{
|
||||
FolderRoot.Children.clear();
|
||||
|
||||
FolderRoot.FullPath = AssetRoot;
|
||||
FolderRoot.Name = GetFileNameWithoutExt(AssetRoot.c_str());
|
||||
FolderRoot.Parent = nullptr;
|
||||
FolderRoot.Icon = ICON_FA_SERVER;
|
||||
FolderRoot.ForceOpenNextFrame = true;
|
||||
FolderRoot.PopulateChildren();
|
||||
}
|
||||
|
||||
void AssetBrowserPanel::SetCurrentFolder(FolderInfo* folder)
|
||||
{
|
||||
if (CurrentFolderContents.Folder == folder)
|
||||
return;
|
||||
|
||||
CurrentFolderContents.Folder = folder;
|
||||
CurrentFolderContents.Files.clear();
|
||||
|
||||
if (folder == nullptr)
|
||||
return;
|
||||
|
||||
FolderInfo* openFolder = folder;
|
||||
while (openFolder != nullptr)
|
||||
{
|
||||
openFolder->ForceOpenNextFrame = true;
|
||||
openFolder = openFolder->Parent;
|
||||
}
|
||||
|
||||
auto files = LoadDirectoryFiles(CurrentFolderContents.Folder->FullPath.c_str());
|
||||
|
||||
for (unsigned int i = 0; i < files.count; i++)
|
||||
{
|
||||
if (DirectoryExists(files.paths[i]))
|
||||
continue;
|
||||
|
||||
const char* name = GetFileName(files.paths[i]);
|
||||
if (!name || *name == '.')
|
||||
continue;
|
||||
|
||||
FileInfo& file = CurrentFolderContents.Files.emplace_back();
|
||||
file.FullPath = files.paths[i];
|
||||
file.Name = name;
|
||||
file.Icon = GetFileIcon(name);
|
||||
}
|
||||
|
||||
UnloadDirectoryFiles(files);
|
||||
}
|
||||
|
||||
void AssetBrowserPanel::FolderInfo::PopulateChildren()
|
||||
{
|
||||
constexpr Color folderColor = { 255,255,145,255 };
|
||||
|
||||
auto folders = LoadDirectoryFiles(FullPath.c_str());
|
||||
|
||||
for (unsigned int i = 0; i < folders.count; i++)
|
||||
{
|
||||
if (DirectoryExists(folders.paths[i]))
|
||||
{
|
||||
const char* name = GetFileNameWithoutExt(folders.paths[i]);
|
||||
if (!name || *name == '.')
|
||||
continue;
|
||||
|
||||
FolderInfo& child = Children.emplace_back();
|
||||
child.FullPath = folders.paths[i];
|
||||
child.Name = name;
|
||||
child.Parent = this;
|
||||
child.Tint = folderColor;
|
||||
child.Icon = ICON_FA_FOLDER;
|
||||
child.PopulateChildren();
|
||||
}
|
||||
}
|
||||
UnloadDirectoryFiles(folders);
|
||||
}
|
||||
|
||||
bool AssetBrowserPanel::ShowFolderTreeNode(FolderInfo& info)
|
||||
{
|
||||
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick;
|
||||
if (info.Children.empty())
|
||||
flags |= ImGuiTreeNodeFlags_Leaf;
|
||||
|
||||
if (CurrentFolderContents.Folder == &info)
|
||||
flags |= ImGuiTreeNodeFlags_Selected;
|
||||
|
||||
if (info.ForceOpenNextFrame)
|
||||
{
|
||||
ImGui::SetNextItemOpen(true);
|
||||
}
|
||||
|
||||
bool open = ImGui::TreeNodeEx(info.Name.c_str(), flags, "%s %s", info.Icon.c_str(), info.Name.c_str());
|
||||
|
||||
if (info.ForceOpenNextFrame && CurrentFolderContents.Folder == &info)
|
||||
ImGui::ScrollToItem(ImGuiScrollFlags_KeepVisibleCenterY);
|
||||
|
||||
info.ForceOpenNextFrame = false;
|
||||
if (ImGui::IsItemClicked())
|
||||
SetCurrentFolder(&info);
|
||||
|
||||
if (open)
|
||||
{
|
||||
for (auto& node : info.Children)
|
||||
ShowFolderTreeNode(node);
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
return CurrentFolderContents.Folder == &info;
|
||||
}
|
||||
|
||||
void AssetBrowserPanel::ShowHeader()
|
||||
{
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ChildBorderSize, 1);
|
||||
if (ImGui::BeginChild("Header", ImVec2{ ImGui::GetContentRegionAvail().x, ImGui::GetFrameHeight() }))
|
||||
{
|
||||
ImGui::Text("%s Root", ICON_FA_FOLDER_OPEN);
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x * 0.33f);
|
||||
ImGui::InputText("###Path", (char*)(CurrentFolderContents.Folder->FullPath.c_str() + AssetRoot.size()), CurrentFolderContents.Folder->FullPath.size(), ImGuiInputTextFlags_ReadOnly);
|
||||
|
||||
ImGui::EndChild();
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
void AssetBrowserPanel::ShowFolderTree()
|
||||
{
|
||||
ShowFolderTreeNode(FolderRoot);
|
||||
}
|
||||
|
||||
void AssetBrowserPanel::ShowFilePane()
|
||||
{
|
||||
if (ImGui::BeginChild("FileList", ImGui::GetContentRegionAvail(), ImGuiChildFlags_None, ImGuiWindowFlags_None))
|
||||
{
|
||||
if (CurrentView)
|
||||
{
|
||||
auto *item = CurrentView->Show(CurrentFolderContents);
|
||||
if (item)
|
||||
{
|
||||
AssetItemInfo* assetItem = static_cast<AssetItemInfo*>(item);
|
||||
if (!assetItem->IsFile())
|
||||
SetCurrentFolder(static_cast<FolderInfo*>(item));
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
}
|
||||
}
|
||||
|
||||
ViewableItem* AssetBrowserPanel::AssetContainer::Reset()
|
||||
{
|
||||
FileItr = Files.begin();
|
||||
FolderItr = Folder->Children.begin();
|
||||
if (FileItr != Files.end())
|
||||
return &(*FileItr);
|
||||
if (FolderItr != Folder->Children.end())
|
||||
return &(*FolderItr);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t AssetBrowserPanel::AssetContainer::Count()
|
||||
{
|
||||
return Files.size() + Folder->Children.size();
|
||||
}
|
||||
|
||||
ViewableItem* AssetBrowserPanel::AssetContainer::Next()
|
||||
{
|
||||
if (FileItr != Files.end())
|
||||
{
|
||||
FileItr++;
|
||||
if (FileItr != Files.end())
|
||||
return &(*FileItr);
|
||||
else
|
||||
{
|
||||
if (FolderItr != Folder->Children.end())
|
||||
return &(*FolderItr);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (FolderItr != Folder->Children.end())
|
||||
{
|
||||
FolderItr++;
|
||||
if (FolderItr != Folder->Children.end())
|
||||
return &(*FolderItr);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char* AssetBrowserPanel::GetFileIcon(const char* filename)
|
||||
{
|
||||
const char* e = GetFileExtension(filename);
|
||||
|
||||
if (e == nullptr)
|
||||
return ICON_FA_FILE;
|
||||
|
||||
std::string ext = e;
|
||||
|
||||
std::transform(ext.begin(), ext.end(), ext.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); } // correct
|
||||
);
|
||||
|
||||
if (!ext.empty())
|
||||
{
|
||||
if (ext==".png")
|
||||
return ICON_FA_FILE_IMAGE;
|
||||
|
||||
if (ext==".wav" || ext==".mp3" || ext==".oog")
|
||||
return ICON_FA_FILE_AUDIO;
|
||||
|
||||
if (ext==".ttf" || ext==".otf" || ext==".fnt")
|
||||
return ICON_FA_FONT;
|
||||
|
||||
if (ext==".txt" || ext==".md")
|
||||
return ICON_FA_FILE_LINES;
|
||||
|
||||
if (ext==".lua" || ext==".c" || ext==".h" || ext==".cpp")
|
||||
return ICON_FA_FILE_CODE;
|
||||
}
|
||||
return ICON_FA_FILE;
|
||||
}
|
||||
Reference in New Issue
Block a user