Skip to content
2 changes: 1 addition & 1 deletion Hazel/src/Hazel/Scene/SceneSerializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ namespace Hazel {
{
YAML::Emitter out;
out << YAML::BeginMap;
out << YAML::Key << "Scene" << YAML::Value << "Untitled";
out << YAML::Key << "Scene" << YAML::Value << std::filesystem::path(filepath).stem().string();
out << YAML::Key << "Entities" << YAML::Value << YAML::BeginSeq;
m_Scene->m_Registry.each([&](auto entityID)
{
Expand Down
81 changes: 78 additions & 3 deletions Hazelnut/src/Panels/ContentBrowserPanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,81 @@
#include "Hazel/Project/Project.h"

#include <imgui/imgui.h>
#include "Hazel/Core/Application.h"

namespace Hazel {

namespace Utils {

static bool IsImageFile(const std::filesystem::path& path)
{
if (path.extension() == ".png" || path.extension() == ".jpg")
return true;

return false;
}

}

ContentBrowserPanel::ContentBrowserPanel()
: m_BaseDirectory(Project::GetAssetDirectory()), m_CurrentDirectory(m_BaseDirectory)
{
m_DirectoryIcon = Texture2D::Create("Resources/Icons/ContentBrowser/DirectoryIcon.png");
m_FileIcon = Texture2D::Create("Resources/Icons/ContentBrowser/FileIcon.png");

auto FileAssetEvent = [this](const std::string& filepath, const filewatch::Event change_type)
{
switch (change_type)
{
case filewatch::Event::added:
{
Application::Get().SubmitToMainThread([this, filepath]()
{
if (Utils::IsImageFile(filepath))
{
std::filesystem::path texturePath = filepath;
texturePath = m_BaseDirectory / filepath;

// NOTE: Waiting for Texture to load fully on directory otherwise we'll get black thumbnails
// Waiting Time can vary depending on asset size
// To remove this we need a way to know if file has loaded completely or not
using namespace std::literals::chrono_literals;
std::this_thread::sleep_for(0.02s);

m_TextureIcons[texturePath.string()] = Texture2D::Create(texturePath.string());
HZ_WARN("{}: File Added", texturePath.string());
}
});

break;
}
case filewatch::Event::removed:
{
Application::Get().SubmitToMainThread([this, filepath]()
{
std::filesystem::path texturePath = filepath;
texturePath = m_BaseDirectory / filepath;

m_TextureIcons.erase(texturePath.string());
HZ_WARN("{}: File Deleted", texturePath.string());
});

break;
}
}
};

m_ContentBrowserFileWatcher = CreateScope<filewatch::FileWatch<std::string>>(m_BaseDirectory.string(), FileAssetEvent);

// Loading Textures
for (auto& directoryEntry : std::filesystem::recursive_directory_iterator(m_BaseDirectory))
{
const auto& path = directoryEntry.path();
const auto& filenameString = path.string();

if (Utils::IsImageFile(path))
m_TextureIcons[filenameString] = Texture2D::Create(filenameString);
}
}

void ContentBrowserPanel::OnImGuiRender()
Expand All @@ -20,7 +87,7 @@ namespace Hazel {

if (m_CurrentDirectory != std::filesystem::path(m_BaseDirectory))
{
if (ImGui::Button("<-"))
if (ImGui::Button("Back"))
{
m_CurrentDirectory = m_CurrentDirectory.parent_path();
}
Expand All @@ -43,9 +110,17 @@ namespace Hazel {
std::string filenameString = path.filename().string();

ImGui::PushID(filenameString.c_str());
Ref<Texture2D> icon = directoryEntry.is_directory() ? m_DirectoryIcon : m_FileIcon;
Ref<Texture2D> icon = nullptr;

if (Utils::IsImageFile(path))
icon = m_TextureIcons[path.string()];

else
icon = directoryEntry.is_directory() ? m_DirectoryIcon : m_FileIcon;

ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
ImGui::ImageButton((ImTextureID)icon->GetRendererID(), { thumbnailSize, thumbnailSize }, { 0, 1 }, { 1, 0 });
if (icon)
ImGui::ImageButton((ImTextureID)icon->GetRendererID(), { thumbnailSize, thumbnailSize }, { 0, 1 }, { 1, 0 });

if (ImGui::BeginDragDropSource())
{
Expand Down
4 changes: 4 additions & 0 deletions Hazelnut/src/Panels/ContentBrowserPanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "Hazel/Renderer/Texture.h"

#include <filesystem>
#include "FileWatch.h"

namespace Hazel {

Expand All @@ -18,6 +19,9 @@ namespace Hazel {

Ref<Texture2D> m_DirectoryIcon;
Ref<Texture2D> m_FileIcon;
std::unordered_map<std::string, Ref<Texture2D>> m_TextureIcons;

Scope<filewatch::FileWatch<std::string>> m_ContentBrowserFileWatcher;
};

}
20 changes: 18 additions & 2 deletions Hazelnut/src/Panels/SceneHierarchyPanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -399,11 +399,26 @@ namespace Hazel {
}
});

DrawComponent<SpriteRendererComponent>("Sprite Renderer", entity, [](auto& component)
DrawComponent<SpriteRendererComponent>("Sprite Renderer", entity, [defaultTexture = m_DefaultTexture](auto& component)
{
ImGui::ColorEdit4("Color", glm::value_ptr(component.Color));

ImGui::Button("Texture", ImVec2(100.0f, 0.0f));
uint32_t buttonTex = component.Texture ? component.Texture->GetRendererID()
: defaultTexture->GetRendererID();

ImGui::ImageButton((ImTextureID)buttonTex, ImVec2{ 100.0f, 100.0f });

if (ImGui::IsItemClicked(ImGuiMouseButton_Right))
ImGui::OpenPopup("RemoveTexture");

if (ImGui::BeginPopup("RemoveTexture"))
{
if (ImGui::MenuItem("Remove Texture"))
component.Texture = nullptr;

ImGui::EndPopup();
}

if (ImGui::BeginDragDropTarget())
{
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("CONTENT_BROWSER_ITEM"))
Expand All @@ -416,6 +431,7 @@ namespace Hazel {
else
HZ_WARN("Could not load texture {0}", texturePath.filename().string());
}

ImGui::EndDragDropTarget();
}

Expand Down
1 change: 1 addition & 0 deletions Hazelnut/src/Panels/SceneHierarchyPanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ namespace Hazel {
private:
Ref<Scene> m_Context;
Entity m_SelectionContext;
const Ref<Texture2D> m_DefaultTexture = Texture2D::Create(1, 1);
};

}