Edit(Mirror): ContentBrowserPanel

This commit is contained in:
Light 2022-03-06 22:25:23 +03:30
parent 1a5f99d69a
commit 8c0bdbf849
10 changed files with 708 additions and 277 deletions

139
.clang-format Normal file
View file

@ -0,0 +1,139 @@
---
# Core
Language: Cpp
Standard: Cpp11
ColumnLimit: '0' # No limit
### Bin pack ###
BinPackArguments: 'true'
BinPackParameters: 'true'
# Includes
SortIncludes: 'true'
IncludeBlocks: Regroup
IncludeCategories:
# Current Project
- Regex: '"'
Priority: 001
# Custom Project Categories...
# Dependecies
- Regex: '<'
Priority: 500
# Custom Deependencies Categories...
# C++ includes
- Regex: '[^.h .hpp]>'
Priority: 998
# C includes
- Regex: '<[^/\n]+[.]h>'
Priority: 999
# Braces
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: true
AfterClass: true
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: true
BeforeElse: true
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
# Indentation
UseTab: ForIndentation
TabWidth: '4'
IndentWidth: '4'
ContinuationIndentWidth: '4'
ConstructorInitializerIndentWidth: '4'
IndentCaseLabels: 'false'
IndentWrappedFunctionNames: 'true'
IndentPPDirectives: BeforeHash
NamespaceIndentation: None
AccessModifierOffset: '-4'
# Space
SpaceAfterCStyleCast: 'false'
SpaceAfterLogicalNot: 'false'
SpaceAfterTemplateKeyword: 'false'
SpaceBeforeAssignmentOperators: 'true'
SpaceBeforeCpp11BracedList: 'true'
SpaceBeforeCtorInitializerColon: 'false'
SpaceBeforeInheritanceColon: 'false'
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: 'true'
SpaceInEmptyParentheses: 'false'
SpacesBeforeTrailingComments: '1'
SpacesInAngles: 'false'
SpacesInCStyleCastParentheses: 'false'
SpacesInContainerLiterals: 'false'
SpacesInParentheses: 'false'
SpacesInSquareBrackets: 'false'
### Alignment ###
PointerAlignment: Left
DerivePointerAlignment: 'false'
AlignAfterOpenBracket: Align
AlignEscapedNewlines: Left
AlignConsecutiveDeclarations: 'false'
AlignConsecutiveAssignments: 'true'
AlignConsecutiveMacros: 'true'
AlignOperands: 'true'
AlignTrailingComments: 'true'
### Single Line ###
AllowShortCaseLabelsOnASingleLine: 'true'
AllowShortFunctionsOnASingleLine: Inline
AllowShortLambdasOnASingleLine: Inline
AllowAllArgumentsOnNextLine: 'false'
AllowShortLoopsOnASingleLine: 'false'
AllowShortBlocksOnASingleLine: 'false'
AllowAllParametersOfDeclarationOnNextLine: 'false'
AllowShortIfStatementsOnASingleLine: Never
### Break ###
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: 'false'
AlwaysBreakTemplateDeclarations: 'Yes'
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: 'false'
BreakInheritanceList: BeforeComma
BreakStringLiterals: 'false'
# Penalties
PenaltyBreakAssignment: '0'
PenaltyBreakBeforeFirstCallParameter: '0'
PenaltyBreakComment: '0'
PenaltyBreakFirstLessLess: '0'
PenaltyBreakString: '0'
PenaltyBreakTemplateDeclaration: '0'
PenaltyExcessCharacter: '0'
PenaltyReturnTypeOnItsOwnLine: '999999999' # Nope
# Constructor Initializers
ConstructorInitializerAllOnOneLineOrOnePerLine: 'true'
AllowAllConstructorInitializersOnNextLine: 'true'
BreakConstructorInitializers: BeforeComma
# Comments
ReflowComments: 'false'
CommentPragmas: '^ TODO@:'
FixNamespaceComments: 'true'
# Misc
Cpp11BracedListStyle: 'false'
SortUsingDeclarations: 'true'
KeepEmptyLinesAtTheStartOfBlocks: 'false'
MaxEmptyLinesToKeep: '2'

View file

@ -29,15 +29,20 @@ add_subdirectory(${MIRROR_DIR}/)
# Dependencies # Dependencies
add_subdirectory(${DEPENDENCIES_DIR}GLAD/) add_subdirectory(${DEPENDENCIES_DIR}GLAD/)
add_subdirectory(${DEPENDENCIES_DIR}GLFW/) add_subdirectory(${DEPENDENCIES_DIR}GLFW/)
add_subdirectory(${DEPENDENCIES_DIR})
add_subdirectory(${DEPENDENCIES_DIR}spdlog/) add_subdirectory(${DEPENDENCIES_DIR}spdlog/)
add_subdirectory(${DEPENDENCIES_DIR}glm/) add_subdirectory(${DEPENDENCIES_DIR}glm/)
add_subdirectory(${DEPENDENCIES_DIR}entt/) add_subdirectory(${DEPENDENCIES_DIR}entt/)
add_subdirectory(${DEPENDENCIES_DIR}imgui/)
add_subdirectory(${DEPENDENCIES_DIR}stb_image/) add_subdirectory(${DEPENDENCIES_DIR}stb_image/)
add_subdirectory(${DEPENDENCIES_DIR}yaml-cpp/) add_subdirectory(${DEPENDENCIES_DIR}yaml-cpp/)
add_subdirectory(${DEPENDENCIES_DIR}shaderc/) add_subdirectory(${DEPENDENCIES_DIR}shaderc/)
# Link # Link
target_link_libraries(
imgui
PUBLIC glad
PUBLIC glfw)
target_link_libraries( target_link_libraries(
Engine Engine
PRIVATE glad PRIVATE glad
@ -48,14 +53,10 @@ target_link_libraries(
PRIVATE yaml-cpp PRIVATE yaml-cpp
PRIVATE shaderc) PRIVATE shaderc)
target_link_libraries(
imgui
PRIVATE glad
PRIVATE glfw)
target_link_libraries( target_link_libraries(
Mirror Mirror
PRIVATE Engine) PRIVATE Engine
PRIVATE imgui)
# Precompiled headers # Precompiled headers
target_precompile_headers(Engine PUBLIC ${ENGINE_DIR}src/Engine/ltpch.h) target_precompile_headers(Engine PUBLIC ${ENGINE_DIR}src/Engine/ltpch.h)

View file

@ -9,22 +9,28 @@ if(MSVC)
endif() endif()
file(GLOB IMGUI_FILES true ABSOLUTE file(GLOB IMGUI_FILES true ABSOLUTE
${CMAKE_CURRENT_SOURCE_DIR} *.cpp *.h) ${CMAKE_CURRENT_SOURCE_DIR}/imgui/imgui.cpp
${CMAKE_CURRENT_SOURCE_DIR}/imgui/imgui_tables.cpp
${CMAKE_CURRENT_SOURCE_DIR}/imgui/imgui_widgets.cpp
${CMAKE_CURRENT_SOURCE_DIR}/imgui/imgui_draw.cpp
${CMAKE_CURRENT_SOURCE_DIR}/imgui/imgui_demo.cpp
)
set(BACKENDS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/backends/) set(BACKENDS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/imgui/backends/)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/imgui)
file(GLOB IMGUI_BACKEND_FILES true ABSOLUTE file(GLOB IMGUI_BACKEND_FILES true ABSOLUTE
${BACKENDS_DIR}imgui_impl_opengl3.cpp ${BACKENDS_DIR}imgui_impl_opengl3.h ${BACKENDS_DIR}imgui_impl_opengl3.cpp
# ${BACKENDS_DIR}imgui_impl_vulkan.cpp ${BACKENDS_DIR}imgui_impl_vulkan.h ${BACKENDS_DIR}imgui_impl_glfw.cpp
${BACKENDS_DIR}imgui_impl_glfw.cpp ${BACKENDS_DIR}imgui_impl_glfw.h) # ${BACKENDS_DIR}imgui_impl_vulkan.cpp ${BACKENDS_DIR}imgui_impl_vulkan.h
)
if(WIN32) if(WIN32)
file(GLOB IMGUI_WINDOWS_BACKEND_FILES true ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/backends/ file(GLOB IMGUI_WINDOWS_BACKEND_FILES true ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/backends/
${BACKENDS_DIR}imgui_impl_dx11.cpp ${BACKENDS_DIR}imgui_impl_dx11.h ${BACKENDS_DIR}imgui_impl_dx11.cpp
# ${BACKENDS_DIR}imgui_impl_dx12.cpp ${BACKENDS_DIR}imgui_impl_dx12.h ${BACKENDS_DIR}imgui_impl_win32.cpp
${BACKENDS_DIR}imgui_impl_win32.cpp ${BACKENDS_DIR}imgui_impl_win32.h) )
list(APPEND IMGUI_BACKEND_FILES ${IMGUI_WINDOWS_BACKEND_FILES}) list(APPEND IMGUI_BACKEND_FILES ${IMGUI_WINDOWS_BACKEND_FILES})
endif() endif()
@ -32,5 +38,10 @@ endif()
add_compile_definitions(IMGUI_IMPL_OPENGL_LOADER_GLAD) add_compile_definitions(IMGUI_IMPL_OPENGL_LOADER_GLAD)
include_directories(${DEPENDENCIES_DIR}GLAD/include) include_directories(${DEPENDENCIES_DIR}GLAD/include)
include_directories(${DEPENDENCIES_DIR}GLFW/include) include_directories(${DEPENDENCIES_DIR}GLFW/include)
include_directories(${DEPENDENCIES_DIR}glm/)
add_library(imgui STATIC ${IMGUI_FILES} ${IMGUI_BACKEND_FILES}) add_library(imgui STATIC ${IMGUI_FILES} ${IMGUI_BACKEND_FILES})
# Copy imconfig.h over
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/Configurations/imgui/imconfig.h
DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/imgui/)

View file

@ -0,0 +1,131 @@
//-----------------------------------------------------------------------------
// COMPILE-TIME OPTIONS FOR DEAR IMGUI
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
//-----------------------------------------------------------------------------
// A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/rebased branch with your modifications to it)
// B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template.
//-----------------------------------------------------------------------------
// You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp
// files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
// Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using.
//-----------------------------------------------------------------------------
#pragma once
//---- Define assertion handler. Defaults to calling assert().
// If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement.
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
// Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility.
// DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions()
// for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details.
//#define IMGUI_API __declspec( dllexport )
//#define IMGUI_API __declspec( dllimport )
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names.
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
//#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87: disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This will be folded into IMGUI_DISABLE_OBSOLETE_FUNCTIONS in a few versions.
//---- Disable all of Dear ImGui or don't implement standard windows.
// It is very strongly recommended to NOT disable the demo windows during development. Please read comments in imgui_demo.cpp.
//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. Not recommended.
//#define IMGUI_DISABLE_METRICS_WINDOW // Disable metrics/debugger and other debug tools: ShowMetricsWindow() and ShowStackToolWindow() will be empty.
//---- Don't implement some functions to reduce linkage requirements.
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a)
//#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW)
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a)
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime).
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
//---- Include imgui_user.h at the end of imgui.h as a convenience
//#define IMGUI_INCLUDE_IMGUI_USER_H
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
//#define IMGUI_USE_BGRA_PACKED_COLOR
//---- Use 32-bit for ImWchar (default is 16-bit) to support unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
//#define IMGUI_USE_WCHAR32
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
//---- Use stb_printf's faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
// Requires 'stb_sprintf.h' to be available in the include path. Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf.
// #define IMGUI_USE_STB_SPRINTF
//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided).
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
//#define IMGUI_ENABLE_FREETYPE
//---- Use stb_truetype to build and rasterize the font atlas (default)
// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
//#define IMGUI_ENABLE_STB_TRUETYPE
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
#include <glm/glm.hpp>
#define IM_VEC2_CLASS_EXTRA \
bool operator==(glm::vec2 rhs) { return x == rhs.x && y == rhs.y; } \
bool operator!=(glm::vec2 rhs) { return (*this) == rhs; } \
bool operator==(ImVec2 rhs) { return x == rhs.x && y == rhs.y; } \
bool operator!=(ImVec2 rhs) { return (*this) == rhs; }
#define IM_VEC4_CLASS_EXTRA \
bool operator==(glm::vec4 rhs) { return x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w; } \
bool operator!=(glm::vec4 rhs) { return (*this) == rhs; } \
bool operator==(ImVec4 rhs) { return x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w; } \
bool operator!=(ImVec4 rhs) { return (*this) == rhs; }
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
//#define ImDrawIdx unsigned int
//---- Override ImDrawCallback signature (will need to modify renderer backends accordingly)
//struct ImDrawList;
//struct ImDrawCmd;
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
//#define ImDrawCallback MyImDrawCallback
//---- Debug Tools: Macro to break in Debugger
// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
//#define IM_DEBUG_BREAK IM_ASSERT(0)
//#define IM_DEBUG_BREAK __debugbreak()
//---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(),
// (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.)
// This adds a small runtime cost which is why it is not enabled by default.
//#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
//---- Debug Tools: Enable slower asserts
//#define IMGUI_DEBUG_PARANOID
//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
/*
namespace ImGui
{
void MyFunction(const char* name, const MyMatrix44& v);
}
*/

2
Dependencies/imgui vendored

@ -1 +1 @@
Subproject commit 419e401d1fe8e9b6e45a31b5c0a27673b5d88fdc Subproject commit 5f3925c45393cf5e82fd1b106a1548ad68baf52e

103
Mirror/src/EditorLayer.cpp~ Normal file
View file

@ -0,0 +1,103 @@
#include "EditorLayer.h"
#include "Utility/Serializer.h"
namespace Light {
EditorLayer::EditorLayer(const std::string& name, const std::vector<std::string>& args)
: Layer(name), m_SceneDir(args.empty() ? "" : args[0])
{
m_Scene = CreateRef<Scene>();
m_PropertiesPanel = CreateRef<PropertiesPanel>();
m_SceneHierarchyPanel = CreateRef<SceneHierarchyPanel>(m_Scene, m_PropertiesPanel);
m_ContentBrowserPanel = CreateRef<ContentBrowserPanel>();
m_Framebuffer = Framebuffer::Create({ 1, 1, 1 }, GraphicsContext::GetSharedContext());
if (m_SceneDir.empty())
{
m_CameraEntity = m_Scene->CreateEntity("Camera");
m_CameraEntity.AddComponent<CameraComponent>(SceneCamera(), true);
ResourceManager::LoadTexture("Awesomeface", "Assets/Textures/awesomeface.png");
Entity entity = m_Scene->CreateEntity("Awesomeface", {});
entity.AddComponent<SpriteRendererComponent>(ResourceManager::GetTexture("Awesomeface"), glm::vec4 { 0.0f, 1.0f, 1.0f, 1.0f });
}
else
{
SceneSerializer serializer(m_Scene);
LT_ENGINE_ASSERT(serializer.Deserialize(m_SceneDir), "EditorLayer::EditorLayer: failed to de-serialize: ", m_SceneDir);
m_CameraEntity = m_Scene->GetEntityByTag("Game Camera");
}
}
EditorLayer::~EditorLayer()
{
if (!m_SceneDir.empty())
{
SceneSerializer serializer(m_Scene);
serializer.Serialize(m_SceneDir);
}
}
void EditorLayer::OnUpdate(float deltaTime)
{
m_Scene->OnUpdate(deltaTime);
m_Direction.x = Input::GetKeyboardKey(Key::A) ? -1.0f :
Input::GetKeyboardKey(Key::D) ? 1.0f :
0.0f;
m_Direction.y = Input::GetKeyboardKey(Key::S) ? -1.0f :
Input::GetKeyboardKey(Key::W) ? 1.0f :
0.0f;
auto& cameraTranslation = m_CameraEntity.GetComponent<TransformComponent>().translation;
cameraTranslation += glm::vec3(m_Direction * m_Speed * deltaTime, 0.0f);
if (Input::GetKeyboardKey(Key::Escape))
Application::Quit();
}
void EditorLayer::OnRender()
{
m_Scene->OnRender(m_Framebuffer);
}
void EditorLayer::OnUserInterfaceUpdate()
{
UserInterface::DockspaceBegin();
ImGui::ShowDemoWindow();
if (ImGui::Begin("Game"))
{
Input::ReceiveGameEvents(ImGui::IsWindowFocused());
ImVec2 regionAvail = ImGui::GetContentRegionAvail();
if (m_AvailableContentRegionPrev != regionAvail)
{
m_Framebuffer->Resize({ regionAvail.x, regionAvail.y });
auto& camera = m_CameraEntity.GetComponent<CameraComponent>().camera;
camera.SetViewportSize(regionAvail.x, regionAvail.y);
m_AvailableContentRegionPrev = regionAvail;
}
if (GraphicsContext::GetGraphicsAPI() == GraphicsAPI::DirectX)
ImGui::Image(m_Framebuffer->GetColorAttachment(), regionAvail);
else
ImGui::Image(m_Framebuffer->GetColorAttachment(), regionAvail, ImVec2(0, 1), ImVec2(1, 0));
}
ImGui::End();
// Panels
m_SceneHierarchyPanel->OnUserInterfaceUpdate();
m_PropertiesPanel->OnUserInterfaceUpdate();
m_ContentBrowserPanel->OnUserInterfaceUpdate();
UserInterface::DockspaceEnd();
}
} // namespace Light

View file

@ -1,11 +1,16 @@
#include "ContentBrowser.h" #include "ContentBrowser.h"
#include <LightEngine.h>
#include <imgui.h> #include <imgui.h>
namespace Light { namespace Light {
ContentBrowserPanel::ContentBrowserPanel() ContentBrowserPanel::ContentBrowserPanel()
: m_CurrentDirectory("Assets"), m_AssetsPath("Assets") {} : m_CurrentDirectory("Assets"), m_AssetsPath("Assets")
{
// ResourceManager::LoadTexture("_Assets_Directory", "EngineResources/Icons/Asset_Directory");
// m_DirectoryTexture = ResourceManager::GetTexture("_Assets_Directory");
}
void ContentBrowserPanel::OnUserInterfaceUpdate() void ContentBrowserPanel::OnUserInterfaceUpdate()
{ {
@ -19,30 +24,66 @@ void ContentBrowserPanel::OnUserInterfaceUpdate()
} }
} }
for (auto& dirEntry : std::filesystem::directory_iterator(m_CurrentDirectory))
{
const auto& path = dirEntry.path();
{
auto relativePath = std::filesystem::relative(path, m_AssetsPath);
std::string relativePathString = relativePath.string();
if (dirEntry.is_directory()) ImVec2 regionAvail = ImGui::GetContentRegionAvail();
uint32_t cellSize = m_FileSize + m_FilePadding;
uint32_t columnCount = std::clamp(static_cast<uint32_t>(std::floor(regionAvail.x / cellSize)), 1u, 64u);
if (ImGui::BeginTable("ContentBrowser", columnCount))
{
for (auto& dirEntry : std::filesystem::directory_iterator(m_CurrentDirectory))
{
ImGui::TableNextColumn();
LT_ENGINE_TRACE("File: ", dirEntry.path().string());
FileType assetType;
std::string extension = dirEntry.path().extension().string();
// TODO: Tidy up
assetType = extension.empty() ? FileType::Directory :
extension == ".txt" ? FileType::Text :
extension == ".png" ? FileType::Image :
FileType::None;
if (assetType == FileType::None)
{ {
if (ImGui::Button(relativePathString.c_str())) LT_ENGINE_ERROR("Unsupported file exetnsion: {}", extension);
{ return;
m_CurrentDirectory /= path.filename();
}
} }
else
const auto& path = dirEntry.path();
{ {
if (ImGui::Button(relativePathString.c_str())) auto relativePath = std::filesystem::relative(path, m_AssetsPath);
std::string relativePathString = relativePath.string();
switch (assetType)
{ {
case FileType::Directory:
if (ImGui::Button(relativePathString.c_str(), ImVec2(m_FileSize, m_FileSize)))
{
m_CurrentDirectory /= path.filename();
}
ImGui::Text("Test");
break;
case FileType::Image:
if (ImGui::Button(relativePathString.c_str(), ImVec2(m_FileSize, m_FileSize)))
{
}
break;
case FileType::Text:
if (ImGui::Button(relativePathString.c_str(), ImVec2(m_FileSize, m_FileSize)))
{
}
default:
break;
} }
} }
} }
ImGui::End(); ImGui::EndTable();
} }
ImGui::DragInt("Size", (int*)&m_FileSize, 32u, 512u);
ImGui::DragInt("Padding", (int*)&m_FilePadding, 32u, 512u);
ImGui::End();
} }
} // namespace Light } // namespace Light

View file

@ -2,22 +2,36 @@
#include "Panel.h" #include "Panel.h"
#include <LightEngine.h>
#include <filesystem> #include <filesystem>
namespace Light { namespace Light {
class ContentBrowserPanel : public Panel class ContentBrowserPanel: public Panel
{
private:
enum FileType
{ {
private: None = 0,
Directory,
public: Text,
ContentBrowserPanel(); Image,
void OnUserInterfaceUpdate();
private:
std::filesystem::path m_CurrentDirectory;
const std::filesystem::path m_AssetsPath;
}; };
} public:
ContentBrowserPanel();
void OnUserInterfaceUpdate();
private:
std::filesystem::path m_CurrentDirectory;
const std::filesystem::path m_AssetsPath;
// TODO: Save configuration
uint32_t m_FileSize = 256u;
uint32_t m_FilePadding = 16u;
Ref<Texture> m_DirectoryTexture;
};
} // namespace Light

View file

@ -1,240 +1,232 @@
#include "PropertiesPanel.h" #include "PropertiesPanel.h"
#include "Scene/Components.h" #include "Scene/Components.h"
#include "Utility/ResourceManager.h" #include "Utility/ResourceManager.h"
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp> #include <glm/gtc/type_ptr.hpp>
#include <imgui.h> #include <imgui.h>
#include <imgui_internal.h> #include <imgui_internal.h>
namespace Light { namespace Light {
void PropertiesPanel::OnUserInterfaceUpdate() void PropertiesPanel::OnUserInterfaceUpdate()
{
ImGui::Begin("Properties");
if (m_EntityContext.IsValid())
{ {
ImGui::Begin("Properties"); if (m_EntityContext.HasComponent<TagComponent>())
if (m_EntityContext.IsValid())
{ {
if (m_EntityContext.HasComponent<TagComponent>()) auto& tagComponent = m_EntityContext.GetComponent<TagComponent>();
char buffer[256];
memset(buffer, 0, sizeof(buffer));
std::strncpy(buffer, tagComponent.tag.c_str(), sizeof(buffer));
if (ImGui::InputText("##Tag", buffer, sizeof(buffer)))
tagComponent.tag = std::string(buffer);
}
ImGui::SameLine();
ImGui::PushItemWidth(-1);
if (ImGui::Button("Add component"))
ImGui::OpenPopup("Components");
if (ImGui::BeginPopup("Components"))
{
if (ImGui::Selectable("SpriteRenderer", false, m_EntityContext.HasComponent<SpriteRendererComponent>() ? ImGuiSelectableFlags_Disabled : NULL))
m_EntityContext.AddComponent<SpriteRendererComponent>(Light::ResourceManager::GetTexture("awesomeface"));
if (ImGui::Selectable("Camera", false, m_EntityContext.HasComponent<CameraComponent>() ? ImGuiSelectableFlags_Disabled : NULL))
m_EntityContext.AddComponent<CameraComponent>();
ImGui::EndPopup();
}
ImGui::PopItemWidth();
DrawComponent<TransformComponent>("Transform Component", m_EntityContext, [&](auto& transformComponent) {
DrawVec3Control("Translation", transformComponent.translation);
});
DrawComponent<SpriteRendererComponent>("SpriteRenderer Component", m_EntityContext, [&](auto& spriteRendererComponent) {
ImGui::ColorEdit4("Color", &spriteRendererComponent.tint[0]);
});
DrawComponent<CameraComponent>("Camera Component", m_EntityContext, [&](auto& cameraComponent) {
auto& camera = cameraComponent.camera;
SceneCamera::ProjectionType projectionType = camera.GetProjectionType();
const char* projectionTypesString[] = { "Orthographic", "Perspective" };
if (ImGui::BeginCombo("ProjectionType", projectionTypesString[(int)projectionType]))
{ {
auto& tagComponent = m_EntityContext.GetComponent<TagComponent>(); for (int i = 0; i < 2; i++)
char buffer[256];
memset(buffer, 0, sizeof(buffer));
std::strncpy(buffer, tagComponent.tag.c_str(), sizeof(buffer));
if (ImGui::InputText("##Tag", buffer, sizeof(buffer)))
tagComponent.tag = std::string(buffer);
}
ImGui::SameLine();
ImGui::PushItemWidth(-1);
if (ImGui::Button("Add component"))
ImGui::OpenPopup("Components");
if (ImGui::BeginPopup("Components"))
{
if (ImGui::Selectable("SpriteRenderer", false, m_EntityContext.HasComponent<SpriteRendererComponent>() ? ImGuiSelectableFlags_Disabled : NULL))
m_EntityContext.AddComponent<SpriteRendererComponent>(Light::ResourceManager::GetTexture("awesomeface"));
if (ImGui::Selectable("Camera", false, m_EntityContext.HasComponent<CameraComponent>() ? ImGuiSelectableFlags_Disabled : NULL))
m_EntityContext.AddComponent<CameraComponent>();
ImGui::EndPopup();
}
ImGui::PopItemWidth();
DrawComponent<TransformComponent>("Transform Component", m_EntityContext, [&](auto& transformComponent)
{
DrawVec3Control("Translation", transformComponent.translation);
});
DrawComponent<SpriteRendererComponent>("SpriteRenderer Component", m_EntityContext, [&](auto& spriteRendererComponent)
{
ImGui::ColorEdit4("Color", &spriteRendererComponent.tint[0]);
});
DrawComponent<CameraComponent>("Camera Component", m_EntityContext, [&](auto& cameraComponent)
{
auto& camera = cameraComponent.camera;
SceneCamera::ProjectionType projectionType = camera.GetProjectionType();
const char* projectionTypesString[] = { "Orthographic", "Perspective" };
if (ImGui::BeginCombo("ProjectionType", projectionTypesString[(int)projectionType]))
{ {
for (int i = 0; i < 2; i++) const bool isSelected = (int)projectionType == i;
if (ImGui::Selectable(projectionTypesString[i], isSelected))
{ {
const bool isSelected = (int)projectionType == i; projectionType = (SceneCamera::ProjectionType)i;
if (ImGui::Selectable(projectionTypesString[i], isSelected)) camera.SetProjectionType(projectionType);
{
projectionType = (SceneCamera::ProjectionType)i;
camera.SetProjectionType(projectionType);
}
if (isSelected)
ImGui::SetItemDefaultFocus();
} }
ImGui::EndCombo(); if (isSelected)
ImGui::SetItemDefaultFocus();
} }
if (projectionType == SceneCamera::ProjectionType::Orthographic) ImGui::EndCombo();
{
float orthoSize, nearPlane, farPlane;
orthoSize = camera.GetOrthographicSize();
nearPlane = camera.GetOrthographicNearPlane();
farPlane = camera.GetOrthographicFarPlane();
if (ImGui::DragFloat("Orthographic Size", &orthoSize))
camera.SetOrthographicSize(orthoSize);
if (ImGui::DragFloat("Near Plane", &nearPlane))
camera.SetOrthographicNearPlane(nearPlane);
if (ImGui::DragFloat("Far Plane", &farPlane))
camera.SetOrthographicFarPlane(farPlane);
}
else // perspective
{
float verticalFOV, nearPlane, farPlane;
verticalFOV = glm::degrees(camera.GetPerspectiveVerticalFOV());
nearPlane = camera.GetPerspectiveNearPlane();
farPlane = camera.GetPerspectiveFarPlane();
if (ImGui::DragFloat("Vertical FOV", &verticalFOV))
camera.SetPerspectiveVerticalFOV(glm::radians(verticalFOV));
if (ImGui::DragFloat("Near Plane", &nearPlane))
camera.SetPerspectiveNearPlane(nearPlane);
if (ImGui::DragFloat("Far Plane", &farPlane))
camera.SetPerspectiveFarPlane(farPlane);
}
ImGui::Separator();
});
}
ImGui::End();
}
void PropertiesPanel::SetEntityContext(Entity entity)
{
m_EntityContext = entity;
}
void PropertiesPanel::DrawVec3Control(const std::string& label, glm::vec3& values, float resetValue /*= 0.0f*/, float columnWidth /*= 100.0f*/)
{
ImGuiIO& io = ImGui::GetIO();
auto boldFont = io.Fonts->Fonts[0];
ImGui::Columns(2);
ImGui::SetColumnWidth(0, columnWidth);
ImGui::Text(label.c_str());
ImGui::NextColumn();
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth());
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2{ 0, 0 });
float lineHeight = GImGui->Font->FontSize + GImGui->Style.FramePadding.y * 2.0f;
ImVec2 buttonSize = { lineHeight + 3.0f, lineHeight };
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.8f, 0.1f, 0.15f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.9f, 0.2f, 0.2f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.8f, 0.1f, 0.15f, 1.0f));
ImGui::PushFont(boldFont);
if (ImGui::Button("X", buttonSize))
values.x = resetValue;
ImGui::PopFont();
ImGui::PopStyleColor(3);
ImGui::SameLine();
ImGui::DragFloat("##X", &values.x, 0.1f);
ImGui::PopItemWidth();
ImGui::SameLine();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.2f, 0.7f, 0.2f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.3f, 0.8f, 0.3f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.2f, 0.7f, 0.2f, 1.0f));
ImGui::PushFont(boldFont);
if (ImGui::Button("Y", buttonSize))
values.y = resetValue;
ImGui::PopFont();
ImGui::PopStyleColor(3);
ImGui::SameLine();
ImGui::DragFloat("##Y", &values.y, 0.1f);
ImGui::PopItemWidth();
ImGui::SameLine();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.1f, 0.25f, 0.8f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.2f, 0.35f, 0.9f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.1f, 0.25f, 0.8f, 1.0f));
ImGui::PushFont(boldFont);
if (ImGui::Button("Z", buttonSize))
values.z = resetValue;
ImGui::PopFont();
ImGui::PopStyleColor(3);
ImGui::SameLine();
ImGui::DragFloat("##Z", &values.z, 0.1f);
ImGui::PopItemWidth();
ImGui::PopStyleVar();
ImGui::Columns(1);
}
template<typename ComponentType, typename UIFunction>
void PropertiesPanel::DrawComponent(const std::string& name, Entity entity, UIFunction userInterfaceFunction)
{
if (!entity.HasComponent<ComponentType>())
return;
auto& component = entity.GetComponent<ComponentType>();
ImVec2 regionAvail = ImGui::GetContentRegionAvail();
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_FramePadding;
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, { 4, 4 });
float lineHeight = GImGui->Font->FontSize + GImGui->Style.FramePadding.y * 2.0f;
ImGui::Separator();
if (ImGui::TreeNodeEx((void*)typeid(ComponentType).hash_code(), flags, name.c_str()))
{
ImGui::PopStyleVar();
ImGui::SameLine(regionAvail.x - lineHeight * .5f);
if (ImGui::Button("+", { lineHeight, lineHeight }))
ImGui::OpenPopup("ComponentSettings");
if (ImGui::BeginPopup("ComponentSettings"))
{
if (ImGui::Selectable("Remove component"))
entity.RemoveComponent<ComponentType>();
ImGui::EndPopup();
} }
userInterfaceFunction(component); if (projectionType == SceneCamera::ProjectionType::Orthographic)
ImGui::TreePop(); {
} float orthoSize, nearPlane, farPlane;
else
ImGui::PopStyleVar(); orthoSize = camera.GetOrthographicSize();
nearPlane = camera.GetOrthographicNearPlane();
farPlane = camera.GetOrthographicFarPlane();
if (ImGui::DragFloat("Orthographic Size", &orthoSize))
camera.SetOrthographicSize(orthoSize);
if (ImGui::DragFloat("Near Plane", &nearPlane))
camera.SetOrthographicNearPlane(nearPlane);
if (ImGui::DragFloat("Far Plane", &farPlane))
camera.SetOrthographicFarPlane(farPlane);
}
else // perspective
{
float verticalFOV, nearPlane, farPlane;
verticalFOV = glm::degrees(camera.GetPerspectiveVerticalFOV());
nearPlane = camera.GetPerspectiveNearPlane();
farPlane = camera.GetPerspectiveFarPlane();
if (ImGui::DragFloat("Vertical FOV", &verticalFOV))
camera.SetPerspectiveVerticalFOV(glm::radians(verticalFOV));
if (ImGui::DragFloat("Near Plane", &nearPlane))
camera.SetPerspectiveNearPlane(nearPlane);
if (ImGui::DragFloat("Far Plane", &farPlane))
camera.SetPerspectiveFarPlane(farPlane);
}
ImGui::Separator();
});
} }
} ImGui::End();
}
void PropertiesPanel::SetEntityContext(Entity entity)
{
m_EntityContext = entity;
}
void PropertiesPanel::DrawVec3Control(const std::string& label, glm::vec3& values, float resetValue /*= 0.0f*/, float columnWidth /*= 100.0f*/)
{
ImGuiIO& io = ImGui::GetIO();
auto boldFont = io.Fonts->Fonts[0];
ImGui::Columns(2);
ImGui::SetColumnWidth(0, columnWidth);
ImGui::Text(label.c_str());
ImGui::NextColumn();
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth());
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2 { 0, 0 });
float lineHeight = GImGui->Font->FontSize + GImGui->Style.FramePadding.y * 2.0f;
ImVec2 buttonSize = { lineHeight + 3.0f, lineHeight };
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.8f, 0.1f, 0.15f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.9f, 0.2f, 0.2f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.8f, 0.1f, 0.15f, 1.0f));
ImGui::PushFont(boldFont);
if (ImGui::Button("X", buttonSize))
values.x = resetValue;
ImGui::PopFont();
ImGui::PopStyleColor(3);
ImGui::SameLine();
ImGui::DragFloat("##X", &values.x, 0.1f);
ImGui::PopItemWidth();
ImGui::SameLine();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.2f, 0.7f, 0.2f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.3f, 0.8f, 0.3f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.2f, 0.7f, 0.2f, 1.0f));
ImGui::PushFont(boldFont);
if (ImGui::Button("Y", buttonSize))
values.y = resetValue;
ImGui::PopFont();
ImGui::PopStyleColor(3);
ImGui::SameLine();
ImGui::DragFloat("##Y", &values.y, 0.1f);
ImGui::PopItemWidth();
ImGui::SameLine();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.1f, 0.25f, 0.8f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.2f, 0.35f, 0.9f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.1f, 0.25f, 0.8f, 1.0f));
ImGui::PushFont(boldFont);
if (ImGui::Button("Z", buttonSize))
values.z = resetValue;
ImGui::PopFont();
ImGui::PopStyleColor(3);
ImGui::SameLine();
ImGui::DragFloat("##Z", &values.z, 0.1f);
ImGui::PopItemWidth();
ImGui::PopStyleVar();
ImGui::Columns(1);
}
template<typename ComponentType, typename UIFunction>
void PropertiesPanel::DrawComponent(const std::string& name, Entity entity, UIFunction userInterfaceFunction)
{
if (!entity.HasComponent<ComponentType>())
return;
auto& component = entity.GetComponent<ComponentType>();
ImVec2 regionAvail = ImGui::GetContentRegionAvail();
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_FramePadding;
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, { 4, 4 });
float lineHeight = GImGui->Font->FontSize + GImGui->Style.FramePadding.y * 2.0f;
ImGui::Separator();
if (ImGui::TreeNodeEx((void*)typeid(ComponentType).hash_code(), flags, name.c_str()))
{
ImGui::PopStyleVar();
ImGui::SameLine(regionAvail.x - lineHeight * .5f);
if (ImGui::Button("+", { lineHeight, lineHeight }))
ImGui::OpenPopup("ComponentSettings");
if (ImGui::BeginPopup("ComponentSettings"))
{
if (ImGui::Selectable("Remove component"))
entity.RemoveComponent<ComponentType>();
ImGui::EndPopup();
}
userInterfaceFunction(component);
ImGui::TreePop();
}
else
ImGui::PopStyleVar();
}
} // namespace Light

View file

@ -1,30 +1,29 @@
#pragma once #pragma once
#include "Panel.h" #include "Panel.h"
#include "Scene/Entity.h" #include "Scene/Entity.h"
namespace Light { namespace Light {
class PropertiesPanel : public Panel class PropertiesPanel: public Panel
{ {
private: private:
Entity m_EntityContext; Entity m_EntityContext;
public: public:
PropertiesPanel() = default; PropertiesPanel() = default;
~PropertiesPanel() = default; ~PropertiesPanel() = default;
void OnUserInterfaceUpdate();
void SetEntityContext(Entity entity); void OnUserInterfaceUpdate();
private: void SetEntityContext(Entity entity);
void DrawVec3Control(const std::string& label, glm::vec3& values, float resetValue = 0.0f, float columnWidth = 100.0f);
template<typename ComponentType, typename UIFunction> private:
void DrawComponent(const std::string& name, Entity entity, UIFunction function); void DrawVec3Control(const std::string& label, glm::vec3& values, float resetValue = 0.0f, float columnWidth = 100.0f);
};
template<typename ComponentType, typename UIFunction>
void DrawComponent(const std::string& name, Entity entity, UIFunction function);
};
} } // namespace Light