#include "ProductBuiltInIcons.h" #include "EditorResources.h" #include namespace XCEngine::UI::Editor::App { namespace { void AppendLoadError( std::ostringstream& stream, std::string_view label, const std::string& error) { if (error.empty()) { return; } if (stream.tellp() > 0) { stream << '\n'; } stream << label << ": " << error; } bool LoadEmbeddedPngBytes( UINT resourceId, const std::uint8_t*& outData, std::size_t& outSize, std::string& outError) { outData = nullptr; outSize = 0u; outError.clear(); HMODULE module = GetModuleHandleW(nullptr); if (module == nullptr) { outError = "GetModuleHandleW(nullptr) returned null."; return false; } HRSRC resource = FindResourceW(module, MAKEINTRESOURCEW(resourceId), L"PNG"); if (resource == nullptr) { outError = "FindResourceW failed."; return false; } HGLOBAL resourceData = LoadResource(module, resource); if (resourceData == nullptr) { outError = "LoadResource failed."; return false; } const DWORD resourceSize = SizeofResource(module, resource); if (resourceSize == 0u) { outError = "SizeofResource returned zero."; return false; } const void* lockedBytes = LockResource(resourceData); if (lockedBytes == nullptr) { outError = "LockResource failed."; return false; } outData = reinterpret_cast(lockedBytes); outSize = static_cast(resourceSize); return true; } void LoadEmbeddedPngTexture( Host::NativeRenderer& renderer, UINT resourceId, std::string_view label, ::XCEngine::UI::UITextureHandle& outTexture, std::ostringstream& errorStream) { const std::uint8_t* bytes = nullptr; std::size_t byteCount = 0u; std::string error = {}; if (!LoadEmbeddedPngBytes(resourceId, bytes, byteCount, error)) { AppendLoadError(errorStream, label, error); return; } error.clear(); if (!renderer.LoadTextureFromMemory(bytes, byteCount, outTexture, error)) { AppendLoadError(errorStream, label, error); } } } // namespace void ProductBuiltInIcons::Initialize(Host::NativeRenderer& renderer) { Shutdown(); m_renderer = &renderer; std::ostringstream errorStream = {}; LoadEmbeddedPngTexture( renderer, IDR_PNG_FOLDER_ICON, "folder_icon.png", m_folderIcon, errorStream); LoadEmbeddedPngTexture( renderer, IDR_PNG_GAMEOBJECT_ICON, "gameobject_icon.png", m_gameObjectIcon, errorStream); LoadEmbeddedPngTexture( renderer, IDR_PNG_SCENE_ICON, "scene_icon.png", m_sceneIcon, errorStream); m_lastError = errorStream.str(); } void ProductBuiltInIcons::Shutdown() { if (m_renderer != nullptr) { m_renderer->ReleaseTexture(m_folderIcon); m_renderer->ReleaseTexture(m_gameObjectIcon); m_renderer->ReleaseTexture(m_sceneIcon); } m_renderer = nullptr; m_lastError.clear(); } const ::XCEngine::UI::UITextureHandle& ProductBuiltInIcons::Resolve( ProductBuiltInIconKind kind) const { switch (kind) { case ProductBuiltInIconKind::Folder: return m_folderIcon; case ProductBuiltInIconKind::GameObject: return m_gameObjectIcon; case ProductBuiltInIconKind::Scene: return m_sceneIcon; default: return m_folderIcon; } } const std::string& ProductBuiltInIcons::GetLastError() const { return m_lastError; } } // namespace XCEngine::UI::Editor::App