aboutsummaryrefslogtreecommitdiff
path: root/source/Game/EditorUtils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Game/EditorUtils.cpp')
-rw-r--r--source/Game/EditorUtils.cpp447
1 files changed, 0 insertions, 447 deletions
diff --git a/source/Game/EditorUtils.cpp b/source/Game/EditorUtils.cpp
deleted file mode 100644
index 20caef7..0000000
--- a/source/Game/EditorUtils.cpp
+++ /dev/null
@@ -1,447 +0,0 @@
-#include "EditorUtils.hpp"
-
-#define IMGUI_DEFINE_MATH_OPERATORS
-#include <imgui_internal.h>
-
-#include <backends/imgui_impl_glfw.h>
-#include <cmath>
-#include <glm/gtc/quaternion.hpp>
-#include <glm/gtx/quaternion.hpp>
-#include <numbers>
-
-const char* ImGui::GetKeyNameGlfw(int key) {
- return GetKeyName(ImGui_ImplGlfw_KeyToImGuiKey(key));
-}
-
-void ImGui::SetNextWindowSizeRelScreen(float xPercent, float yPercent, ImGuiCond cond) {
- auto vs = ImGui::GetMainViewport()->Size;
- ImGui::SetNextWindowSize({ vs.x * xPercent, vs.y * yPercent }, cond);
-}
-
-void ImGui::SetNextWindowCentered(ImGuiCond cond) {
- auto vs = ImGui::GetMainViewport()->Size;
- ImGui::SetNextWindowPos({ vs.x / 2, vs.y / 2 }, cond, { 0.5f, 0.5f });
-}
-
-void ImGui::PushDisabled() {
- ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
- ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.5f * ImGui::GetStyle().Alpha);
-}
-
-void ImGui::PopDisabled() {
- ImGui::PopItemFlag();
- ImGui::PopStyleVar();
-}
-
-bool ImGui::Button(const char* label, bool disabled) {
- return Button(label, ImVec2{}, disabled);
-}
-
-bool ImGui::Button(const char* label, const ImVec2& sizeArg, bool disabled) {
- if (disabled) PushDisabled();
- bool res = ImGui::Button(label, sizeArg);
- if (disabled) PopDisabled();
-
- return res;
-}
-
-#define EDIT_RGBA_COLOR(EditorFunction, kUsesAlpha) \
- float components[4]; \
- components[0] = color->GetNormalizedRed(); \
- components[1] = color->GetNormalizedGreen(); \
- components[2] = color->GetNormalizedBlue(); \
- if constexpr (kUsesAlpha) components[3] = color->GetNormalizedAlpha(); \
- if (EditorFunction(label, components, flags)) { \
- color->r = components[0] * 255; \
- color->g = components[1] * 255; \
- color->b = components[2] * 255; \
- if constexpr (kUsesAlpha) color->a = components[3] * 255; \
- return true; \
- } else { \
- return false; \
- }
-
-bool ImGui::ColorEdit3(const char* label, RgbaColor* color, ImGuiColorEditFlags flags) {
- EDIT_RGBA_COLOR(ColorEdit3, false);
-}
-
-bool ImGui::ColorEdit4(const char* label, RgbaColor* color, ImGuiColorEditFlags flags) {
- EDIT_RGBA_COLOR(ColorEdit4, true);
-}
-
-bool ImGui::ColorPicker3(const char* label, RgbaColor* color, ImGuiColorEditFlags flags) {
- EDIT_RGBA_COLOR(ColorPicker3, false);
-}
-
-bool ImGui::ColorPicker4(const char* label, RgbaColor* color, ImGuiColorEditFlags flags) {
- EDIT_RGBA_COLOR(ColorPicker4, true);
-}
-
-#undef EDIT_RGBA_COLOR
-
-struct InputTextCallbackUserData {
- std::string* str;
- ImGuiInputTextCallback chainCallback;
- void* chainCallbackUserData;
-};
-
-static int InputTextCallback(ImGuiInputTextCallbackData* data) {
- auto user_data = (InputTextCallbackUserData*)data->UserData;
- if (data->EventFlag == ImGuiInputTextFlags_CallbackResize) {
- // Resize string callback
- // If for some reason we refuse the new length (BufTextLen) and/or capacity (BufSize) we need to set them back to what we want.
- auto str = user_data->str;
- IM_ASSERT(data->Buf == str->c_str());
- str->resize(data->BufTextLen);
- data->Buf = (char*)str->c_str();
- } else if (user_data->chainCallback) {
- // Forward to user callback, if any
- data->UserData = user_data->chainCallbackUserData;
- return user_data->chainCallback(data);
- }
- return 0;
-}
-
-bool ImGui::Splitter(bool splitVertically, float thickness, float* size1, float* size2, float minSize1, float minSize2, float splitterLongAxisSize) {
- // Adapted from https://github.com/thedmd/imgui-node-editor/blob/master/examples/blueprints-example/blueprints-example.cpp
- // ::Splitter
-
- ImGuiContext& g = *GImGui;
- ImGuiWindow* window = g.CurrentWindow;
- ImGuiID id = window->GetID("##Splitter");
- ImRect bb;
- bb.Min = window->DC.CursorPos + (splitVertically ? ImVec2(*size1, 0.0f) : ImVec2(0.0f, *size1));
- bb.Max = bb.Min + CalcItemSize(splitVertically ? ImVec2(thickness, splitterLongAxisSize) : ImVec2(splitterLongAxisSize, thickness), 0.0f, 0.0f);
-
- // Adapted from ImGui::SplitterBehavior, changes:
- // - Simplified unneeded logic (hover_extend and hover_visibility_delay)
- // - Changed clamped delta to clamping result size1 and deriving size2 from size1, allowing automatically adapting to the latest window content region width
-
- auto itemFlagsBackup = g.CurrentItemFlags;
- g.CurrentItemFlags |= ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus;
- bool itemAdd = ItemAdd(bb, id);
- g.CurrentItemFlags = itemFlagsBackup;
- if (!itemAdd) {
- return false;
- }
-
- bool hovered, held;
- auto bbInteract = bb;
- ButtonBehavior(bbInteract, id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap);
- if (hovered) {
- g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredRect;
- } // for IsItemHovered(), because bbInteract is larger than bb
- if (g.ActiveId != id) {
- SetItemAllowOverlap();
- }
-
- if (held || (hovered && g.HoveredIdPreviousFrame == id && g.HoveredIdTimer >= 0.0f)) {
- SetMouseCursor((splitVertically ? ImGuiAxis_X : ImGuiAxis_Y) == ImGuiAxis_Y ? ImGuiMouseCursor_ResizeNS : ImGuiMouseCursor_ResizeEW);
- }
-
- float contentSize = splitVertically ? window->ContentRegionRect.GetWidth() : window->ContentRegionRect.GetHeight();
- if (held) {
- ImVec2 mouseDelta2D = g.IO.MousePos - g.ActiveIdClickOffset - bbInteract.Min;
- float mouseDelta = ((splitVertically ? ImGuiAxis_X : ImGuiAxis_Y) == ImGuiAxis_Y) ? mouseDelta2D.y : mouseDelta2D.x;
-
- // Apply resize
- if (mouseDelta != 0.0f) {
- *size1 = ImClamp(*size1 + mouseDelta, minSize1, contentSize - minSize2 - thickness);
- *size2 = contentSize - *size1 - thickness;
- MarkItemEdited(id);
- }
- }
-
- ImU32 col;
- if (held) {
- col = GetColorU32(ImGuiCol_SeparatorActive);
- } else if (hovered && g.HoveredIdTimer >= 0.0f) {
- col = GetColorU32(ImGuiCol_SeparatorHovered);
- } else {
- col = GetColorU32(ImGuiCol_Separator);
- }
- window->DrawList->AddRectFilled(bb.Min, bb.Max, col, 0.0f);
-
- return held;
-}
-
-void ImGui::AddUnderLine(ImColor col) {
- auto min = ImGui::GetItemRectMin();
- auto max = ImGui::GetItemRectMax();
- min.y = max.y;
- ImGui::GetWindowDrawList()->AddLine(min, max, col, 1.0f);
-}
-
-void ImGui::DrawIcon(ImDrawList* drawList, const ImVec2& a, const ImVec2& b, IconType type, bool filled, ImU32 color, ImU32 innerColor) {
- // Taken from https://github.com/thedmd/imgui-node-editor/blob/master/examples/blueprints-example/utilities/drawing.cpp
- // ax::NodeEditor::DrawIcon
-
- auto rect = ImRect(a, b);
- auto rect_x = rect.Min.x;
- auto rect_y = rect.Min.y;
- auto rect_w = rect.Max.x - rect.Min.x;
- auto rect_h = rect.Max.y - rect.Min.y;
- auto rect_center_x = (rect.Min.x + rect.Max.x) * 0.5f;
- auto rect_center_y = (rect.Min.y + rect.Max.y) * 0.5f;
- auto rect_center = ImVec2(rect_center_x, rect_center_y);
- const auto outline_scale = rect_w / 24.0f;
- const auto extra_segments = static_cast<int>(2 * outline_scale); // for full circle
-
- if (type == IconType::Flow) {
- const auto origin_scale = rect_w / 24.0f;
-
- const auto offset_x = 1.0f * origin_scale;
- const auto offset_y = 0.0f * origin_scale;
- const auto margin = 2.0f * origin_scale;
- const auto rounding = 0.1f * origin_scale;
- const auto tip_round = 0.7f; // percentage of triangle edge (for tip)
- // const auto edge_round = 0.7f; // percentage of triangle edge (for corner)
- const auto canvas = ImRect(
- rect.Min.x + margin + offset_x,
- rect.Min.y + margin + offset_y,
- rect.Max.x - margin + offset_x,
- rect.Max.y - margin + offset_y);
- const auto canvas_x = canvas.Min.x;
- const auto canvas_y = canvas.Min.y;
- const auto canvas_w = canvas.Max.x - canvas.Min.x;
- const auto canvas_h = canvas.Max.y - canvas.Min.y;
-
- const auto left = canvas_x + canvas_w * 0.5f * 0.3f;
- const auto right = canvas_x + canvas_w - canvas_w * 0.5f * 0.3f;
- const auto top = canvas_y + canvas_h * 0.5f * 0.2f;
- const auto bottom = canvas_y + canvas_h - canvas_h * 0.5f * 0.2f;
- const auto center_y = (top + bottom) * 0.5f;
- // const auto angle = AX_PI * 0.5f * 0.5f * 0.5f;
-
- const auto tip_top = ImVec2(canvas_x + canvas_w * 0.5f, top);
- const auto tip_right = ImVec2(right, center_y);
- const auto tip_bottom = ImVec2(canvas_x + canvas_w * 0.5f, bottom);
-
- drawList->PathLineTo(ImVec2(left, top) + ImVec2(0, rounding));
- drawList->PathBezierCubicCurveTo(
- ImVec2(left, top),
- ImVec2(left, top),
- ImVec2(left, top) + ImVec2(rounding, 0));
- drawList->PathLineTo(tip_top);
- drawList->PathLineTo(tip_top + (tip_right - tip_top) * tip_round);
- drawList->PathBezierCubicCurveTo(
- tip_right,
- tip_right,
- tip_bottom + (tip_right - tip_bottom) * tip_round);
- drawList->PathLineTo(tip_bottom);
- drawList->PathLineTo(ImVec2(left, bottom) + ImVec2(rounding, 0));
- drawList->PathBezierCubicCurveTo(
- ImVec2(left, bottom),
- ImVec2(left, bottom),
- ImVec2(left, bottom) - ImVec2(0, rounding));
-
- if (!filled) {
- if (innerColor & 0xFF000000) {
- drawList->AddConvexPolyFilled(drawList->_Path.Data, drawList->_Path.Size, innerColor);
- }
-
- drawList->PathStroke(color, true, 2.0f * outline_scale);
- } else {
- drawList->PathFillConvex(color);
- }
- } else {
- auto triangleStart = rect_center_x + 0.32f * rect_w;
-
- auto rect_offset = -static_cast<int>(rect_w * 0.25f * 0.25f);
-
- rect.Min.x += rect_offset;
- rect.Max.x += rect_offset;
- rect_x += rect_offset;
- rect_center_x += rect_offset * 0.5f;
- rect_center.x += rect_offset * 0.5f;
-
- if (type == IconType::Circle) {
- const auto c = rect_center;
-
- if (!filled) {
- const auto r = 0.5f * rect_w / 2.0f - 0.5f;
-
- if (innerColor & 0xFF000000)
- drawList->AddCircleFilled(c, r, innerColor, 12 + extra_segments);
- drawList->AddCircle(c, r, color, 12 + extra_segments, 2.0f * outline_scale);
- } else {
- drawList->AddCircleFilled(c, 0.5f * rect_w / 2.0f, color, 12 + extra_segments);
- }
- }
-
- if (type == IconType::Square) {
- if (filled) {
- const auto r = 0.5f * rect_w / 2.0f;
- const auto p0 = rect_center - ImVec2(r, r);
- const auto p1 = rect_center + ImVec2(r, r);
-
- drawList->AddRectFilled(p0, p1, color, 0, 15 + extra_segments);
- } else {
- const auto r = 0.5f * rect_w / 2.0f - 0.5f;
- const auto p0 = rect_center - ImVec2(r, r);
- const auto p1 = rect_center + ImVec2(r, r);
-
- if (innerColor & 0xFF000000)
- drawList->AddRectFilled(p0, p1, innerColor, 0, 15 + extra_segments);
-
- drawList->AddRect(p0, p1, color, 0, 15 + extra_segments, 2.0f * outline_scale);
- }
- }
-
- if (type == IconType::Grid) {
- const auto r = 0.5f * rect_w / 2.0f;
- const auto w = ceilf(r / 3.0f);
-
- const auto baseTl = ImVec2(floorf(rect_center_x - w * 2.5f), floorf(rect_center_y - w * 2.5f));
- const auto baseBr = ImVec2(floorf(baseTl.x + w), floorf(baseTl.y + w));
-
- auto tl = baseTl;
- auto br = baseBr;
- for (int i = 0; i < 3; ++i) {
- tl.x = baseTl.x;
- br.x = baseBr.x;
- drawList->AddRectFilled(tl, br, color);
- tl.x += w * 2;
- br.x += w * 2;
- if (i != 1 || filled)
- drawList->AddRectFilled(tl, br, color);
- tl.x += w * 2;
- br.x += w * 2;
- drawList->AddRectFilled(tl, br, color);
-
- tl.y += w * 2;
- br.y += w * 2;
- }
-
- triangleStart = br.x + w + 1.0f / 24.0f * rect_w;
- }
-
- if (type == IconType::RoundSquare) {
- if (filled) {
- const auto r = 0.5f * rect_w / 2.0f;
- const auto cr = r * 0.5f;
- const auto p0 = rect_center - ImVec2(r, r);
- const auto p1 = rect_center + ImVec2(r, r);
-
- drawList->AddRectFilled(p0, p1, color, cr, 15);
- } else {
- const auto r = 0.5f * rect_w / 2.0f - 0.5f;
- const auto cr = r * 0.5f;
- const auto p0 = rect_center - ImVec2(r, r);
- const auto p1 = rect_center + ImVec2(r, r);
-
- if (innerColor & 0xFF000000)
- drawList->AddRectFilled(p0, p1, innerColor, cr, 15);
-
- drawList->AddRect(p0, p1, color, cr, 15, 2.0f * outline_scale);
- }
- } else if (type == IconType::Diamond) {
- if (filled) {
- const auto r = 0.607f * rect_w / 2.0f;
- const auto c = rect_center;
-
- drawList->PathLineTo(c + ImVec2(0, -r));
- drawList->PathLineTo(c + ImVec2(r, 0));
- drawList->PathLineTo(c + ImVec2(0, r));
- drawList->PathLineTo(c + ImVec2(-r, 0));
- drawList->PathFillConvex(color);
- } else {
- const auto r = 0.607f * rect_w / 2.0f - 0.5f;
- const auto c = rect_center;
-
- drawList->PathLineTo(c + ImVec2(0, -r));
- drawList->PathLineTo(c + ImVec2(r, 0));
- drawList->PathLineTo(c + ImVec2(0, r));
- drawList->PathLineTo(c + ImVec2(-r, 0));
-
- if (innerColor & 0xFF000000)
- drawList->AddConvexPolyFilled(drawList->_Path.Data, drawList->_Path.Size, innerColor);
-
- drawList->PathStroke(color, true, 2.0f * outline_scale);
- }
- } else {
- const auto triangleTip = triangleStart + rect_w * (0.45f - 0.32f);
-
- drawList->AddTriangleFilled(
- ImVec2(ceilf(triangleTip), rect_y + rect_h * 0.5f),
- ImVec2(triangleStart, rect_center_y + 0.15f * rect_h),
- ImVec2(triangleStart, rect_center_y - 0.15f * rect_h),
- color);
- }
- }
-}
-
-void ImGui::Icon(const ImVec2& size, IconType type, bool filled, const ImVec4& color, const ImVec4& innerColor) {
- // Taken from https://github.com/thedmd/imgui-node-editor/blob/master/examples/blueprints-example/utilities/widgets.cpp
- // ax::NodeEditor::Icon
-
- if (ImGui::IsRectVisible(size)) {
- auto cursorPos = ImGui::GetCursorScreenPos();
- auto drawList = ImGui::GetWindowDrawList();
- DrawIcon(drawList, cursorPos, cursorPos + size, type, filled, ImColor(color), ImColor(innerColor));
- }
-
- ImGui::Dummy(size);
-}
-
-void ImGui::DrawArrow(ImDrawList* drawList, ImVec2 from, ImVec2 to, ImU32 color, float lineThickness) {
- // Adapted from https://stackoverflow.com/a/6333775
-
- using namespace std::numbers;
- constexpr float kHeadLength = 10;
-
- auto angle = std::atan2(to.y - from.y, to.x - from.x);
- drawList->AddLine(from, to, color, lineThickness);
- drawList->AddLine(to, ImVec2(to.x - kHeadLength * std::cos(angle - pi / 6), to.y - kHeadLength * std::sin(angle - pi / 6)), color, lineThickness);
- drawList->AddLine(to, ImVec2(to.x - kHeadLength * std::cos(angle + pi / 6), to.y - kHeadLength * std::sin(angle + pi / 6)), color, lineThickness);
-}
-
-struct DialogObject {
- std::string message;
- std::function<void(int)> callback;
-};
-
-static DialogObject gConfirmationDialog{};
-
-void ImGui::DialogConfirmation(std::string message, std::function<void(bool)> callback) {
- gConfirmationDialog.message = std::move(message);
- // TODO is converting void(bool) to void(int) fine?
- gConfirmationDialog.callback = std::move(callback);
-}
-
-void ImGui::ShowDialogs() {
- if (gConfirmationDialog.callback) {
- if (ImGui::BeginPopupModal("Confirmation")) {
- ImGui::Text("%s", gConfirmationDialog.message.c_str());
- if (ImGui::Button("Cancel")) {
- gConfirmationDialog.callback(false);
- gConfirmationDialog.callback = {};
- ImGui::CloseCurrentPopup();
- }
- ImGui::SameLine();
- if (ImGui::Button("Confirm")) {
- gConfirmationDialog.callback(true);
- gConfirmationDialog.callback = {};
- ImGui::CloseCurrentPopup();
- }
- ImGui::EndPopup();
- }
- }
-}
-
-float Utils::CalcImageHeight(glm::vec2 original, int targetWidth) {
- // Xorig / Yorig = Xnew / Ynew
- // Ynew = Xnew * Yorig / Xorig
- return targetWidth * original.y / original.x;
-}
-
-float Utils::CalcImageWidth(glm::vec2 original, float targetHeight) {
- // Xorig / Yorig = Xnew / Ynew
- // Xnew = Xorig / Yorig * Ynew
- return original.x / original.y * targetHeight;
-}
-
-ImVec2 Utils::FitImage(glm::vec2 original) {
- float newWidth = ImGui::GetContentRegionAvail().x;
- return ImVec2(newWidth, CalcImageHeight(original, newWidth));
-}