VideoCommon: add graphics mod editor control for displaying an asset

This commit is contained in:
iwubcode 2023-11-04 19:51:23 -05:00
commit 5134d1708b
2 changed files with 291 additions and 0 deletions

View file

@ -0,0 +1,267 @@
// Copyright 2023 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "VideoCommon/GraphicsModEditor/Controls/AssetDisplay.h"
#include "VideoCommon/GraphicsModEditor/EditorEvents.h"
#include <algorithm>
#include <array>
#include <string_view>
#include <imgui.h>
namespace GraphicsModEditor::Controls
{
namespace
{
std::string_view AssetDragDropTypeFromType(AssetDataType asset_type)
{
switch (asset_type)
{
case Material:
return "MaterialAsset";
case RasterMaterial:
return "RasterMaterialAsset";
case PixelShader:
return "PixelShaderAsset";
case Shader:
return "ShaderAsset";
case Texture:
return "TextureAsset";
case Mesh:
return "MeshAsset";
}
return "";
}
AbstractTexture* GenericImageIconFromType(AssetDataType asset_type, const EditorState& state)
{
switch (asset_type)
{
case Material:
if (const auto it = state.m_editor_data.m_name_to_texture.find("file");
it != state.m_editor_data.m_name_to_texture.end())
{
return it->second.get();
}
case RasterMaterial:
if (const auto it = state.m_editor_data.m_name_to_texture.find("file");
it != state.m_editor_data.m_name_to_texture.end())
{
return it->second.get();
}
case PixelShader:
if (const auto it = state.m_editor_data.m_name_to_texture.find("code");
it != state.m_editor_data.m_name_to_texture.end())
{
return it->second.get();
}
case Shader:
if (const auto it = state.m_editor_data.m_name_to_texture.find("code");
it != state.m_editor_data.m_name_to_texture.end())
{
return it->second.get();
}
case Texture:
if (const auto it = state.m_editor_data.m_name_to_texture.find("image");
it != state.m_editor_data.m_name_to_texture.end())
{
return it->second.get();
}
case Mesh:
if (const auto it = state.m_editor_data.m_name_to_texture.find("file");
it != state.m_editor_data.m_name_to_texture.end())
{
return it->second.get();
}
}
return nullptr;
}
ImVec2 asset_button_size{150, 150};
} // namespace
bool AssetDisplay(std::string_view popup_name, EditorState* state,
VideoCommon::CustomAssetLibrary::AssetID* asset_id_chosen,
AssetDataType* asset_type_chosen,
std::span<const AssetDataType> asset_types_allowed)
{
if (!state) [[unlikely]]
return false;
if (!asset_id_chosen) [[unlikely]]
return false;
if (!asset_type_chosen) [[unlikely]]
return false;
static std::string asset_filter_text = "";
const std::string reset_popup_name = std::string{popup_name} + "Reset";
bool changed = false;
const EditorAsset* asset = nullptr;
if (!asset_id_chosen->empty())
{
asset = state->m_user_data.m_asset_library->GetAssetFromID(*asset_id_chosen);
}
if (!asset)
{
if (ImGui::Button("None", asset_button_size))
{
if (!ImGui::IsPopupOpen(popup_name.data()))
{
asset_filter_text = "";
ImGui::OpenPopup(popup_name.data());
}
}
}
else
{
AbstractTexture* texture =
state->m_user_data.m_asset_library->GetAssetPreview(asset->m_asset_id);
state->m_editor_data.m_assets_waiting_for_preview.erase(asset->m_asset_id);
ImGui::BeginGroup();
if (texture)
{
if (ImGui::ImageButton(asset->m_asset_id.c_str(), *texture, asset_button_size))
{
if (!ImGui::IsPopupOpen(popup_name.data()))
{
asset_filter_text = "";
ImGui::OpenPopup(popup_name.data());
}
}
if (ImGui::BeginPopupContextItem(reset_popup_name.data()))
{
if (ImGui::Selectable("View properties"))
{
EditorEvents::JumpToAssetInBrowserEvent::Trigger(asset->m_asset_id);
}
if (ImGui::Selectable("Reset"))
{
*asset_id_chosen = "";
changed = true;
}
ImGui::EndPopup();
}
ImGui::TextWrapped("%s", PathToString(asset->m_asset_path.stem()).c_str());
}
else
{
if (ImGui::Button(PathToString(asset->m_asset_path).c_str(), asset_button_size))
{
if (!ImGui::IsPopupOpen(popup_name.data()))
{
asset_filter_text = "";
ImGui::OpenPopup(popup_name.data());
}
}
}
ImGui::EndGroup();
}
if (ImGui::BeginDragDropTarget())
{
for (const auto asset_type_allowed : asset_types_allowed)
{
if (const ImGuiPayload* payload =
ImGui::AcceptDragDropPayload(AssetDragDropTypeFromType(asset_type_allowed).data()))
{
VideoCommon::CustomAssetLibrary::AssetID new_asset_id(
static_cast<const char*>(payload->Data), payload->DataSize);
*asset_id_chosen = new_asset_id;
*asset_type_chosen = asset_type_allowed;
changed = true;
}
}
ImGui::EndDragDropTarget();
}
// Asset browser popup below
const ImVec2 center = ImGui::GetMainViewport()->GetCenter();
const ImVec2 size = ImGui::GetMainViewport()->WorkSize;
ImGui::SetNextWindowPos(center, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
ImGui::SetNextWindowSize(ImVec2(size.x / 4.0f, size.y / 2.0f));
if (ImGui::BeginPopup(popup_name.data()))
{
const u32 column_count = 5;
u32 current_columns = 0;
u32 assets_displayed = 0;
const float search_size = 200.0f;
ImGui::SetNextItemWidth(search_size);
ImGui::InputTextWithHint("##", "Search...", &asset_filter_text);
if (ImGui::BeginTable("AssetBrowserPopupTable", column_count))
{
ImGui::TableNextRow();
for (const auto& asset_from_library : state->m_user_data.m_asset_library->GetAllAssets())
{
if (std::ranges::find(asset_types_allowed, asset_from_library.m_data_type) ==
asset_types_allowed.end())
{
continue;
}
const auto name = PathToString(asset_from_library.m_asset_path.stem());
if (!asset_filter_text.empty() && name.find(asset_filter_text) == std::string::npos)
{
continue;
}
assets_displayed++;
ImGui::TableNextColumn();
ImGui::BeginGroup();
AbstractTexture* texture =
state->m_user_data.m_asset_library->GetAssetPreview(asset_from_library.m_asset_id);
if (texture)
{
if (ImGui::ImageButton(asset_from_library.m_asset_id.c_str(), *texture,
asset_button_size))
{
*asset_id_chosen = asset_from_library.m_asset_id;
changed = true;
ImGui::CloseCurrentPopup();
}
ImGui::TextWrapped("%s", name.c_str());
}
else
{
if (ImGui::Button(name.c_str(), asset_button_size))
{
*asset_id_chosen = asset_from_library.m_asset_id;
changed = true;
ImGui::CloseCurrentPopup();
}
}
ImGui::EndGroup();
current_columns++;
if (current_columns == column_count)
{
ImGui::TableNextRow();
current_columns = 0;
}
}
ImGui::EndTable();
}
if (assets_displayed == 0)
{
ImGui::Text("No assets found");
}
ImGui::EndPopup();
}
return changed;
}
bool AssetDisplay(std::string_view popup_name, EditorState* state,
VideoCommon::CustomAssetLibrary::AssetID* asset_id_chosen,
AssetDataType asset_type_allowed)
{
AssetDataType asset_data_type_chosen;
return AssetDisplay(popup_name, state, asset_id_chosen, &asset_data_type_chosen,
std::array<AssetDataType, 1>{asset_type_allowed});
}
} // namespace GraphicsModEditor::Controls

View file

@ -0,0 +1,24 @@
// Copyright 2023 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <span>
#include <string_view>
#include "VideoCommon/Assets/CustomAssetLibrary.h"
#include "VideoCommon/GraphicsModEditor/EditorState.h"
#include "VideoCommon/GraphicsModEditor/EditorTypes.h"
namespace GraphicsModEditor::Controls
{
// Displays an asset that can be overwritten by dragging/dropping or selecting from an asset browser
// Returns true if asset id changed
bool AssetDisplay(std::string_view popup_name, EditorState* state,
VideoCommon::CustomAssetLibrary::AssetID* asset_id_chosen,
AssetDataType* asset_type_chosen,
std::span<const AssetDataType> asset_types_allowed);
bool AssetDisplay(std::string_view popup_name, EditorState* state,
VideoCommon::CustomAssetLibrary::AssetID* asset_id_chosen,
AssetDataType asset_type_allowed);
} // namespace GraphicsModEditor::Controls