feat: update editor ui framework and assets
This commit is contained in:
128
editor/src/UI/PropertyLayout.h
Normal file
128
editor/src/UI/PropertyLayout.h
Normal file
@@ -0,0 +1,128 @@
|
||||
#pragma once
|
||||
|
||||
#include "StyleTokens.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <imgui.h>
|
||||
#include <utility>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Editor {
|
||||
namespace UI {
|
||||
|
||||
struct PropertyLayoutSpec {
|
||||
float labelInset = InspectorPropertyLabelInset();
|
||||
float controlColumnStart = InspectorPropertyControlColumnStart();
|
||||
float labelControlGap = InspectorPropertyLabelControlGap();
|
||||
float controlTrailingInset = InspectorPropertyControlTrailingInset();
|
||||
};
|
||||
|
||||
struct PropertyLayoutMetrics {
|
||||
ImVec2 cursorPos = ImVec2(0.0f, 0.0f);
|
||||
ImVec2 screenPos = ImVec2(0.0f, 0.0f);
|
||||
float rowWidth = 0.0f;
|
||||
float rowHeight = 0.0f;
|
||||
float labelX = 0.0f;
|
||||
float labelWidth = 0.0f;
|
||||
float controlX = 0.0f;
|
||||
float controlWidth = 0.0f;
|
||||
};
|
||||
|
||||
inline PropertyLayoutSpec MakePropertyLayout() {
|
||||
return PropertyLayoutSpec{};
|
||||
}
|
||||
|
||||
inline void PushPropertyLayoutStyles() {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ControlFramePadding());
|
||||
}
|
||||
|
||||
inline float GetPropertyControlWidth(
|
||||
const PropertyLayoutMetrics& layout,
|
||||
float trailingInset = 0.0f) {
|
||||
return std::max(layout.controlWidth - trailingInset, 1.0f);
|
||||
}
|
||||
|
||||
inline void SetNextPropertyControlWidth(
|
||||
const PropertyLayoutMetrics& layout,
|
||||
float trailingInset = 0.0f) {
|
||||
ImGui::SetNextItemWidth(GetPropertyControlWidth(layout, trailingInset));
|
||||
}
|
||||
|
||||
inline void AlignPropertyControlToRight(
|
||||
const PropertyLayoutMetrics& layout,
|
||||
float width,
|
||||
float trailingInset = 0.0f) {
|
||||
const float offset = layout.controlWidth - width - trailingInset;
|
||||
if (offset > 0.0f) {
|
||||
ImGui::SetCursorPosX(layout.controlX + offset);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename DrawControlFn>
|
||||
inline auto DrawPropertyRow(
|
||||
const char* label,
|
||||
const PropertyLayoutSpec& spec,
|
||||
DrawControlFn&& drawControl) -> decltype(drawControl(std::declval<const PropertyLayoutMetrics&>())) {
|
||||
using Result = decltype(drawControl(std::declval<const PropertyLayoutMetrics&>()));
|
||||
|
||||
Result result{};
|
||||
ImGui::PushID(label);
|
||||
PushPropertyLayoutStyles();
|
||||
|
||||
const ImVec2 rowCursorPos = ImGui::GetCursorPos();
|
||||
const ImVec2 rowScreenPos = ImGui::GetCursorScreenPos();
|
||||
const float rowWidth = std::max(ImGui::GetContentRegionAvail().x, 1.0f);
|
||||
const float rowHeight = ImGui::GetFrameHeight() + ControlRowHeightOffset();
|
||||
const float labelInset = std::max(spec.labelInset, 0.0f);
|
||||
const float controlColumnStart = std::clamp(
|
||||
std::max(spec.controlColumnStart, 0.0f),
|
||||
labelInset,
|
||||
rowWidth);
|
||||
const float labelWidth = std::max(
|
||||
controlColumnStart - labelInset - std::max(spec.labelControlGap, 0.0f),
|
||||
0.0f);
|
||||
const float controlX = rowCursorPos.x + controlColumnStart;
|
||||
const float controlRight = rowCursorPos.x + rowWidth - std::max(spec.controlTrailingInset, 0.0f);
|
||||
const float controlWidth = std::max(controlRight - controlX, 1.0f);
|
||||
const float labelX = rowCursorPos.x + labelInset;
|
||||
|
||||
const PropertyLayoutMetrics metrics{
|
||||
rowCursorPos,
|
||||
rowScreenPos,
|
||||
rowWidth,
|
||||
rowHeight,
|
||||
labelX,
|
||||
labelWidth,
|
||||
controlX,
|
||||
controlWidth
|
||||
};
|
||||
|
||||
if (label && label[0] != '\0') {
|
||||
ImDrawList* drawList = ImGui::GetWindowDrawList();
|
||||
const float textY = rowScreenPos.y + std::max(0.0f, (rowHeight - ImGui::GetTextLineHeight()) * 0.5f);
|
||||
drawList->PushClipRect(
|
||||
ImVec2(rowScreenPos.x + labelInset, rowScreenPos.y),
|
||||
ImVec2(rowScreenPos.x + labelInset + labelWidth, rowScreenPos.y + rowHeight),
|
||||
true);
|
||||
drawList->AddText(
|
||||
ImVec2(rowScreenPos.x + labelInset, textY),
|
||||
ImGui::GetColorU32(ImGuiCol_Text),
|
||||
label);
|
||||
drawList->PopClipRect();
|
||||
}
|
||||
|
||||
ImGui::SetCursorPos(ImVec2(controlX, rowCursorPos.y));
|
||||
result = drawControl(metrics);
|
||||
|
||||
const float consumedHeight = std::max(rowHeight, ImGui::GetCursorPosY() - rowCursorPos.y);
|
||||
ImGui::SetCursorPos(rowCursorPos);
|
||||
ImGui::Dummy(ImVec2(rowWidth, consumedHeight));
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::PopID();
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace UI
|
||||
} // namespace Editor
|
||||
} // namespace XCEngine
|
||||
Reference in New Issue
Block a user