Files
XCEngine/new_editor/app/Panels/ProductInspectorPanel.cpp

225 lines
7.6 KiB
C++

#include "ProductInspectorPanel.h"
#include <XCEditor/Foundation/UIEditorTheme.h>
#include <algorithm>
namespace XCEngine::UI::Editor::App {
namespace {
using ::XCEngine::UI::UIColor;
using ::XCEngine::UI::UIDrawList;
using ::XCEngine::UI::UIPoint;
using ::XCEngine::UI::UIRect;
constexpr std::string_view kInspectorPanelId = "inspector";
constexpr float kPanelPadding = 10.0f;
constexpr float kHeaderHeight = 22.0f;
constexpr float kSectionGap = 10.0f;
constexpr float kRowHeight = 21.0f;
constexpr float kLabelWidth = 88.0f;
constexpr float kTitleFontSize = 13.0f;
constexpr float kSubtitleFontSize = 11.0f;
constexpr float kSectionTitleFontSize = 11.0f;
constexpr float kRowFontSize = 11.0f;
constexpr UIColor kSurfaceColor(0.205f, 0.205f, 0.205f, 1.0f);
constexpr UIColor kSectionHeaderColor(0.225f, 0.225f, 0.225f, 1.0f);
constexpr UIColor kSectionBodyColor(0.215f, 0.215f, 0.215f, 1.0f);
constexpr UIColor kTitleColor(0.910f, 0.910f, 0.910f, 1.0f);
constexpr UIColor kSubtitleColor(0.650f, 0.650f, 0.650f, 1.0f);
constexpr UIColor kLabelColor(0.700f, 0.700f, 0.700f, 1.0f);
constexpr UIColor kValueColor(0.860f, 0.860f, 0.860f, 1.0f);
float ResolveTextTop(float rectY, float rectHeight, float fontSize) {
const float lineHeight = fontSize * 1.6f;
return rectY + std::floor((rectHeight - lineHeight) * 0.5f);
}
std::string PathToUtf8String(const std::filesystem::path& path) {
const std::u8string value = path.u8string();
return std::string(value.begin(), value.end());
}
} // namespace
const UIEditorPanelContentHostPanelState* ProductInspectorPanel::FindMountedInspectorPanel(
const UIEditorPanelContentHostFrame& contentHostFrame) const {
for (const UIEditorPanelContentHostPanelState& panelState : contentHostFrame.panelStates) {
if (panelState.panelId == kInspectorPanelId && panelState.mounted) {
return &panelState;
}
}
return nullptr;
}
void ProductInspectorPanel::BuildPresentation(const ProductEditorSession& session) {
m_sections.clear();
m_title.clear();
m_subtitle.clear();
m_hasSelection = false;
switch (session.selection.kind) {
case ProductEditorSelectionKind::HierarchyNode: {
m_hasSelection = true;
m_title = session.selection.displayName.empty()
? std::string("GameObject")
: session.selection.displayName;
m_subtitle = "GameObject";
Section identity = {};
identity.title = "Identity";
identity.rows = {
{ "Type", "GameObject" },
{ "Name", m_title },
{ "Id", session.selection.itemId }
};
m_sections.push_back(std::move(identity));
break;
}
case ProductEditorSelectionKind::ProjectItem: {
m_hasSelection = true;
m_title = session.selection.displayName.empty()
? (session.selection.directory ? std::string("Folder") : std::string("Asset"))
: session.selection.displayName;
m_subtitle = session.selection.directory ? "Folder" : "Asset";
Section identity = {};
identity.title = "Identity";
identity.rows = {
{ "Type", session.selection.directory ? std::string("Folder") : std::string("Asset") },
{ "Name", m_title },
{ "Id", session.selection.itemId }
};
m_sections.push_back(std::move(identity));
Section location = {};
location.title = "Location";
location.rows = {
{ "Path", PathToUtf8String(session.selection.absolutePath) }
};
m_sections.push_back(std::move(location));
break;
}
case ProductEditorSelectionKind::None:
default:
m_title = "Nothing selected";
m_subtitle = "Select a hierarchy item or project asset.";
break;
}
}
void ProductInspectorPanel::Update(
const ProductEditorSession& session,
const UIEditorPanelContentHostFrame& contentHostFrame) {
const UIEditorPanelContentHostPanelState* panelState =
FindMountedInspectorPanel(contentHostFrame);
if (panelState == nullptr) {
m_visible = false;
m_bounds = {};
m_sections.clear();
m_title.clear();
m_subtitle.clear();
m_hasSelection = false;
return;
}
m_visible = true;
m_bounds = panelState->bounds;
BuildPresentation(session);
}
void ProductInspectorPanel::Append(UIDrawList& drawList) const {
if (!m_visible || m_bounds.width <= 0.0f || m_bounds.height <= 0.0f) {
return;
}
const UIColor borderColor = ResolveUIEditorDockHostPalette().splitterColor;
drawList.AddFilledRect(m_bounds, kSurfaceColor);
const float contentX = m_bounds.x + kPanelPadding;
const float contentWidth = (std::max)(m_bounds.width - kPanelPadding * 2.0f, 0.0f);
float nextY = m_bounds.y + kPanelPadding;
const UIRect titleRect(contentX, nextY, contentWidth, 18.0f);
drawList.AddText(
UIPoint(titleRect.x, ResolveTextTop(titleRect.y, titleRect.height, kTitleFontSize)),
m_title,
kTitleColor,
kTitleFontSize);
nextY += titleRect.height;
const UIRect subtitleRect(contentX, nextY, contentWidth, 16.0f);
drawList.AddText(
UIPoint(subtitleRect.x, ResolveTextTop(subtitleRect.y, subtitleRect.height, kSubtitleFontSize)),
m_subtitle,
kSubtitleColor,
kSubtitleFontSize);
nextY += subtitleRect.height + kSectionGap;
if (!m_hasSelection) {
return;
}
for (const Section& section : m_sections) {
const float bodyHeight = static_cast<float>(section.rows.size()) * kRowHeight;
const UIRect headerRect(contentX, nextY, contentWidth, kHeaderHeight);
const UIRect bodyRect(contentX, headerRect.y + headerRect.height, contentWidth, bodyHeight);
drawList.AddFilledRect(headerRect, kSectionHeaderColor);
drawList.AddFilledRect(bodyRect, kSectionBodyColor);
drawList.AddRectOutline(
UIRect(headerRect.x, headerRect.y, headerRect.width, headerRect.height + bodyRect.height),
borderColor,
1.0f,
0.0f);
drawList.AddText(
UIPoint(headerRect.x + 8.0f, ResolveTextTop(headerRect.y, headerRect.height, kSectionTitleFontSize)),
section.title,
kTitleColor,
kSectionTitleFontSize);
float rowY = bodyRect.y;
for (std::size_t rowIndex = 0u; rowIndex < section.rows.size(); ++rowIndex) {
const SectionRow& row = section.rows[rowIndex];
const UIRect rowRect(contentX, rowY, contentWidth, kRowHeight);
const UIRect labelRect(rowRect.x + 8.0f, rowRect.y, kLabelWidth, rowRect.height);
const UIRect valueRect(
labelRect.x + labelRect.width + 8.0f,
rowRect.y,
(std::max)(rowRect.width - (labelRect.width + 24.0f), 0.0f),
rowRect.height);
if (rowIndex > 0u) {
drawList.AddFilledRect(
UIRect(rowRect.x, rowRect.y, rowRect.width, 1.0f),
borderColor);
}
drawList.AddText(
UIPoint(labelRect.x, ResolveTextTop(labelRect.y, labelRect.height, kRowFontSize)),
row.label,
kLabelColor,
kRowFontSize);
drawList.PushClipRect(valueRect);
drawList.AddText(
UIPoint(valueRect.x, ResolveTextTop(valueRect.y, valueRect.height, kRowFontSize)),
row.value,
kValueColor,
kRowFontSize);
drawList.PopClipRect();
rowY += kRowHeight;
}
nextY = bodyRect.y + bodyRect.height + kSectionGap;
}
}
} // namespace XCEngine::UI::Editor::App