Skip to content

Commit

Permalink
new property editor ui
Browse files Browse the repository at this point in the history
  • Loading branch information
moritz-h committed Dec 30, 2024
1 parent 99b4fbd commit c1839d6
Show file tree
Hide file tree
Showing 17 changed files with 747 additions and 1,281 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace SatisfactorySave {
public:
virtual ~SetVisitor() = default;

virtual void visit(StructSet& a) = 0;
virtual void visit(UInt32Set& a) = 0;
virtual void visit(StructSet& s) = 0;
virtual void visit(UInt32Set& s) = 0;
};
} // namespace SatisfactorySave
1 change: 1 addition & 0 deletions map/src/MapWindow/BaseWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ void Satisfactory3DMap::BaseWindow::validateImGuiScale() {
// Setup style
ImGui::GetStyle() = ImGuiStyle();
ImGui::StyleColorsDark();
ImGui::GetStyle().Colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); // Match DisabledAlpha
ImGui::GetStyle().IndentSpacing = 10.0f;
ImGui::GetStyle().ScaleAllSizes(scale);

Expand Down
18 changes: 0 additions & 18 deletions map/src/MapWindow/MapWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
#include "UI/ObjectWidgets.h"
#include "Utils/FileDialogUtil.h"
#include "Utils/GLMUtil.h"
#include "Utils/ImGuiUtil.h"
#include "Utils/ResourceUtils.h"

Satisfactory3DMap::MapWindow::MapWindow()
Expand Down Expand Up @@ -73,15 +72,13 @@ Satisfactory3DMap::MapWindow::MapWindow()
},
2);
showSelectionMarkerSetting_ = BoolSetting::create("Selection marker", false);
showEditorSetting_ = BoolSetting::create("Enable Editor (experimental)", false);
showSaveTreePerLevelSetting_ = BoolSetting::create("Show save tree per level", false);

config_->registerSetting(samplingFactorSetting_);
config_->registerSetting(metallicSetting_);
config_->registerSetting(roughnessSetting_);
config_->registerSetting(worldRenderModeSetting_);
config_->registerSetting(showSelectionMarkerSetting_);
config_->registerSetting(showEditorSetting_);
config_->registerSetting(showSaveTreePerLevelSetting_);

dataView_ = std::make_shared<DataView>(config_);
Expand Down Expand Up @@ -139,9 +136,6 @@ Satisfactory3DMap::MapWindow::MapWindow()
mapTileRenderer_ = std::make_unique<MapTileRenderer>(config_, dataView_->pakManager());
modelRenderer_ = std::make_unique<ModelRenderer>(config_, dataView_);

propertyTableGuiRenderer_ = std::make_unique<PropertyTableGuiRenderer>();
propertyTableEditor_ = std::make_unique<PropertyTableEditor>();

selectionMarkerModel_ = std::make_unique<GltfModel>("models/ui/selection_marker.glb");
try {
selectionMarkerShader_ = std::make_unique<glowl::GLSLProgram>(glowl::GLSLProgram::ShaderSourceList{
Expand Down Expand Up @@ -326,18 +320,6 @@ void Satisfactory3DMap::MapWindow::renderGui() {
const auto& selectedProxy = dataView_->selectedObject();
const auto& saveObject = selectedProxy->getSaveObject();

if (ImGui::CollapsingHeader("Properties", ImGuiTreeNodeFlags_DefaultOpen)) {
if (saveObject->Object->Properties.empty()) {
ImGui::Text("None!");
} else if (showEditorSetting_->getVal()) {
propertyTableEditor_->renderGui(saveObject->Object->Properties,
[&](const std::string& p) { dataView_->selectPathName(p); });
} else {
propertyTableGuiRenderer_->renderGui(saveObject->Object->Properties,
[&](const std::string& p) { dataView_->selectPathName(p); });
}
}

if (!saveObject->BinaryClassData.empty()) {
if (ImGui::CollapsingHeader("Binary Class Data", ImGuiTreeNodeFlags_DefaultOpen)) {
ImGui::Text("Length: %zu", saveObject->BinaryClassData.size());
Expand Down
6 changes: 0 additions & 6 deletions map/src/MapWindow/MapWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
#include "ModelRenderer.h"
#include "OpenGL/GltfModel.h"
#include "Pak/PakExplorer.h"
#include "UI/PropertyTableEditor.h"
#include "UI/PropertyTableGuiRenderer.h"
#include "World/MapTileRenderer.h"
#include "World/WorldRenderer.h"

Expand Down Expand Up @@ -78,9 +76,6 @@ namespace Satisfactory3DMap {
std::unique_ptr<MapTileRenderer> mapTileRenderer_;
std::unique_ptr<ModelRenderer> modelRenderer_;

std::unique_ptr<PropertyTableGuiRenderer> propertyTableGuiRenderer_;
std::unique_ptr<PropertyTableEditor> propertyTableEditor_;

int mapViewLeft_;
int mapViewTop_;
int mapViewWidth_;
Expand Down Expand Up @@ -113,7 +108,6 @@ namespace Satisfactory3DMap {
std::shared_ptr<FloatSetting> roughnessSetting_;
std::shared_ptr<EnumSetting<WorldRenderMode>> worldRenderModeSetting_;
std::shared_ptr<BoolSetting> showSelectionMarkerSetting_;
std::shared_ptr<BoolSetting> showEditorSetting_;
std::shared_ptr<BoolSetting> showSaveTreePerLevelSetting_;

std::unique_ptr<GltfModel> selectionMarkerModel_;
Expand Down
10 changes: 9 additions & 1 deletion map/src/MapWindow/Pak/AssetObjectWindow.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "AssetObjectWindow.h"

#include "../UI/ObjectWidgets.h"
#include "AssetWindow.h"

Satisfactory3DMap::AssetObjectWindow::AssetObjectWindow(std::shared_ptr<AssetWindow> assetWindow,
Expand All @@ -18,7 +19,14 @@ void Satisfactory3DMap::AssetObjectWindow::renderGui() {
ImGui::Begin(windowTitle_.c_str(), &open);
if (ImGui::CollapsingHeader("Properties", ImGuiTreeNodeFlags_DefaultOpen)) {
if (assetExport_->propertiesError.empty()) {
propertyRenderer_.renderGui(assetExport_->properties, [&]([[maybe_unused]] const std::string& p) {});
UI::PushEditorTableStyle();
if (UI::BeginEditorTable()) {
// ImGui::BeginDisabled(); TODO ?
UI::EditorPropertyList("Properties", assetExport_->properties);
// ImGui::EndDisabled(); TODO ?
UI::EndEditorTable();
}
UI::PopEditorTableStyle();
} else {
ImGui::Text("Error parsing properties:");
ImGui::Text("%s", assetExport_->propertiesError.c_str());
Expand Down
3 changes: 0 additions & 3 deletions map/src/MapWindow/Pak/AssetObjectWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@

#include "SatisfactorySave/GameTypes/Properties/Base/PropertyList.h"

#include "../UI/PropertyTableGuiRenderer.h"

namespace Satisfactory3DMap {

class AssetWindow;
Expand All @@ -33,7 +31,6 @@ namespace Satisfactory3DMap {
std::shared_ptr<AssetWindow> assetWindow_;
std::unique_ptr<AssetExport> assetExport_;
std::string windowTitle_;
PropertyTableGuiRenderer propertyRenderer_;
MemoryEditor hexEditor_;
int hexEditorMode_ = 2;
};
Expand Down
1 change: 0 additions & 1 deletion map/src/MapWindow/Pak/PakExplorer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include "SatisfactorySave/Utils/StringUtils.h"

#include "Utils/FileDialogUtil.h"
#include "Utils/ImGuiUtil.h"

Satisfactory3DMap::PakExplorer::PakExplorer(std::shared_ptr<DataView> dataView)
: dataView_(std::move(dataView)),
Expand Down
2 changes: 1 addition & 1 deletion map/src/MapWindow/UI/ObjectEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace Satisfactory3DMap::UI {
const EventContext& ctx_;

class UObjectEditor : public s::ObjectVisitor {
private:
protected:
const ObjectEditor& parent_;

public:
Expand Down
119 changes: 111 additions & 8 deletions map/src/MapWindow/UI/ObjectWidgets.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
#include "ObjectWidgets.h"

#include <array>

#include <IconsFontAwesome6.h>
#include <imgui_stdlib.h>

#include "PropertyEditor.h"

bool Satisfactory3DMap::UI::BeginEditorTable() {
if (ImGui::BeginTable("##PropertyTable", 3, ImGuiTableFlags_Resizable)) {
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch, 1.0f);
Expand Down Expand Up @@ -89,10 +93,14 @@ void Satisfactory3DMap::UI::EditorShowSelectable(const char* label, const std::s
EditorTreeEndLeaf();
}

void Satisfactory3DMap::UI::EditorShowText(const char* label, const char* text) {
void Satisfactory3DMap::UI::EditorShowText(const char* label, const char* text, bool disabled) {
EditorTreeStartLeaf(label);
ImGui::TableNextColumn();
ImGui::TextUnformatted(text);
if (disabled) {
ImGui::TextDisabled("%s", text);
} else {
ImGui::TextUnformatted(text);
}
EditorTreeEndLeaf();
}

Expand All @@ -114,6 +122,15 @@ bool Satisfactory3DMap::UI::EditorScalar(const char* label, ImGuiDataType data_t
return changed;
}

bool Satisfactory3DMap::UI::EditorString(const char* label, std::string& str) {
EditorTreeStartLeaf(label);
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(-FLT_MIN);
const bool changed = ImGui::InputText("##string", &str);
EditorTreeEndLeaf();
return changed;
}

bool Satisfactory3DMap::UI::EditorName(const char* label, s::FName& name) {
bool changed = false;
if (EditorTreeNode(label, ImGuiTreeNodeFlags_DefaultOpen)) {
Expand Down Expand Up @@ -149,11 +166,58 @@ bool Satisfactory3DMap::UI::EditorObjectReference(const char* label, s::FObjectR
return changed;
}

bool Satisfactory3DMap::UI::EditorSoftObjectPath(const char* label, s::FSoftObjectPath& p) {
bool changed = false;
if (EditorTreeNode(label, ImGuiTreeNodeFlags_DefaultOpen)) {
changed |= EditorName("AssetPath.PackageName", p.AssetPath.PackageName);
changed |= EditorName("AssetPath.AssetName", p.AssetPath.AssetName);
changed |= EditorString("SubPathString", p.SubPathString);
ImGui::TreePop();
}
return changed;
}

bool Satisfactory3DMap::UI::EditorVector(const char* label, s::FVector& v) {
EditorTreeStartLeaf(label);
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(-FLT_MIN);
const bool changed = ImGui::InputScalarN("##vector", ImGuiDataType_Double, reinterpret_cast<double*>(&v), 3);
const bool changed = ImGui::InputScalarN("##Vector", ImGuiDataType_Double, reinterpret_cast<double*>(&v), 3);
EditorTreeEndLeaf();
return changed;
}

bool Satisfactory3DMap::UI::EditorVector2D(const char* label, s::FVector2D& v) {
EditorTreeStartLeaf(label);
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(-FLT_MIN);
const bool changed = ImGui::InputScalarN("##Vector2D", ImGuiDataType_Double, reinterpret_cast<double*>(&v), 2);
EditorTreeEndLeaf();
return changed;
}

bool Satisfactory3DMap::UI::EditorVector4(const char* label, s::FVector4& v) {
EditorTreeStartLeaf(label);
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(-FLT_MIN);
const bool changed = ImGui::InputScalarN("##Vector4", ImGuiDataType_Double, reinterpret_cast<double*>(&v), 4);
EditorTreeEndLeaf();
return changed;
}

bool Satisfactory3DMap::UI::EditorIntVector(const char* label, s::FIntVector& v) {
EditorTreeStartLeaf(label);
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(-FLT_MIN);
const bool changed = ImGui::InputScalarN("##IntVector", ImGuiDataType_S32, reinterpret_cast<int32_t*>(&v), 3);
EditorTreeEndLeaf();
return changed;
}

bool Satisfactory3DMap::UI::EditorIntPoint(const char* label, s::FIntPoint& p) {
EditorTreeStartLeaf(label);
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(-FLT_MIN);
const bool changed = ImGui::InputScalarN("##IntPoint", ImGuiDataType_S32, reinterpret_cast<int32_t*>(&p), 2);
EditorTreeEndLeaf();
return changed;
}
Expand All @@ -162,7 +226,37 @@ bool Satisfactory3DMap::UI::EditorQuat(const char* label, s::FQuat& q) {
EditorTreeStartLeaf(label);
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(-FLT_MIN);
const bool changed = ImGui::InputScalarN("##quat", ImGuiDataType_Double, reinterpret_cast<double*>(&q), 4);
const bool changed = ImGui::InputScalarN("##Quat", ImGuiDataType_Double, reinterpret_cast<double*>(&q), 4);
EditorTreeEndLeaf();
return changed;
}

bool Satisfactory3DMap::UI::EditorRotator(const char* label, s::FRotator& r) {
EditorTreeStartLeaf(label);
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(-FLT_MIN);
const bool changed = ImGui::InputScalarN("##Rotator", ImGuiDataType_Double, reinterpret_cast<double*>(&r), 3);
EditorTreeEndLeaf();
return changed;
}

bool Satisfactory3DMap::UI::EditorColor(const char* label, s::FColor& c) {
EditorTreeStartLeaf(label);
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(-FLT_MIN);
std::array<float, 4> col{
static_cast<float>(c.R) / 255.0f,
static_cast<float>(c.G) / 255.0f,
static_cast<float>(c.B) / 255.0f,
static_cast<float>(c.A) / 255.0f,
};
const bool changed = ImGui::ColorEdit4("##Color", col.data(), ImGuiColorEditFlags_Uint8);
if (changed) {
c.R = static_cast<uint8_t>(std::clamp(col[0], 0.0f, 1.0f) * 255.0 + 0.5f);
c.G = static_cast<uint8_t>(std::clamp(col[1], 0.0f, 1.0f) * 255.0 + 0.5f);
c.B = static_cast<uint8_t>(std::clamp(col[2], 0.0f, 1.0f) * 255.0 + 0.5f);
c.A = static_cast<uint8_t>(std::clamp(col[3], 0.0f, 1.0f) * 255.0 + 0.5f);
}
EditorTreeEndLeaf();
return changed;
}
Expand All @@ -171,7 +265,7 @@ bool Satisfactory3DMap::UI::EditorLinearColor(const char* label, s::FLinearColor
EditorTreeStartLeaf(label);
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(-FLT_MIN);
const bool changed = ImGui::ColorEdit4("##color", reinterpret_cast<float*>(&c), ImGuiColorEditFlags_Float);
const bool changed = ImGui::ColorEdit4("##LinearColor", reinterpret_cast<float*>(&c), ImGuiColorEditFlags_Float);
EditorTreeEndLeaf();
return changed;
}
Expand Down Expand Up @@ -209,16 +303,25 @@ bool Satisfactory3DMap::UI::EditorDynamicStruct(const char* label, s::FFGDynamic
}

bool Satisfactory3DMap::UI::EditorProperty(s::Property& p, const EventContext& ctx) {
// TODO
EditorShowText(p.Name().toString().c_str(), p.Type().toString().c_str());
const bool open = EditorTreeNode(p.Name().toString().c_str(), ImGuiTreeNodeFlags_DefaultOpen);
ImGui::TableNextColumn();
ImGui::TextDisabled("%s", p.Type().toString().c_str());
if (open) {
PropertyEditor editor(ctx);
p.accept(editor);
ImGui::TreePop();
return editor.changed();
}
return false;
}

bool Satisfactory3DMap::UI::EditorPropertyList(const char* label, s::PropertyList& properties,
const EventContext& ctx) {
bool changed = false;
EditorList(label, properties, [&]([[maybe_unused]] std::size_t idx, auto& item) {
EditorList(label, properties, [&](std::size_t idx, auto& item) {
ImGui::PushID(static_cast<int>(idx)); // Property name is not unique. Some properties appear duplicated.
changed |= EditorProperty(*item, ctx);
ImGui::PopID();
});
return changed;
}
17 changes: 16 additions & 1 deletion map/src/MapWindow/UI/ObjectWidgets.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,16 @@
#include "SatisfactorySave/GameTypes/Properties/Base/PropertyList.h"
#include "SatisfactorySave/GameTypes/UE/Core/Containers/Map.h"
#include "SatisfactorySave/GameTypes/UE/Core/Math/Color.h"
#include "SatisfactorySave/GameTypes/UE/Core/Math/IntPoint.h"
#include "SatisfactorySave/GameTypes/UE/Core/Math/IntVector.h"
#include "SatisfactorySave/GameTypes/UE/Core/Math/Quat.h"
#include "SatisfactorySave/GameTypes/UE/Core/Math/Rotator.h"
#include "SatisfactorySave/GameTypes/UE/Core/Math/Transform.h"
#include "SatisfactorySave/GameTypes/UE/Core/Math/Vector.h"
#include "SatisfactorySave/GameTypes/UE/Core/Math/Vector2D.h"
#include "SatisfactorySave/GameTypes/UE/Core/Math/Vector4.h"
#include "SatisfactorySave/GameTypes/UE/Core/UObject/NameTypes.h"
#include "SatisfactorySave/GameTypes/UE/CoreUObject/UObject/SoftObjectPath.h"

#include "CommonUI.h"
#include "Utils/GLMUtil.h"
Expand Down Expand Up @@ -57,24 +63,33 @@ namespace Satisfactory3DMap::UI {
// Text Widgets
void ClassOrPathButton(const std::string& name, const EventContext& ctx = {});
void EditorShowSelectable(const char* label, const std::string& name, const EventContext& ctx = {});
void EditorShowText(const char* label, const char* text);
// Disabled flag for value only. To also disable tree node wrap inside BeginDisabled()/EndDisabled().
void EditorShowText(const char* label, const char* text, bool disabled = false);

// Arithmetic Type Widgets
bool EditorBool(const char* label, bool& v);
bool EditorScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_step = nullptr,
const void* p_step_fast = nullptr, const char* format = nullptr, ImGuiInputTextFlags flags = 0);
bool EditorString(const char* label, std::string& str);

// UE Core Type Widgets
bool EditorName(const char* label, s::FName& name);
bool EditorObjectReference(const char* label, s::FObjectReferenceDisc& r, const EventContext& ctx = {});
bool EditorSoftObjectPath(const char* label, s::FSoftObjectPath& p);

// UE Math Type Widgets
bool EditorVector(const char* label, s::FVector& v);
bool EditorVector2D(const char* label, s::FVector2D& v);
bool EditorVector4(const char* label, s::FVector4& v);
bool EditorIntVector(const char* label, s::FIntVector& v);
bool EditorIntPoint(const char* label, s::FIntPoint& p);
bool EditorQuat(const char* label, s::FQuat& q);
bool EditorRotator(const char* label, s::FRotator& r);
template<typename T>
bool EditorTransform(s::TTransform<T>& t);

// Struct Widgets
bool EditorColor(const char* label, s::FColor& c);
bool EditorLinearColor(const char* label, s::FLinearColor& c);
bool EditorInventoryItem(const char* label, s::FInventoryItem& i, const EventContext& ctx = {});
bool EditorConveyorBeltItem(const char* label, s::FConveyorBeltItem& i, const EventContext& ctx = {});
Expand Down
Loading

0 comments on commit c1839d6

Please sign in to comment.