From 45bc8a8bb4771df0dbd741187d6cf4772b916ccc Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Thu, 3 Oct 2024 17:36:29 -0500 Subject: [PATCH] cleanup render path --- Makefile | 8 +- scripts/prosperon.js | 28 +- scripts/render.js | 23 +- source/engine/HandmadeMath.c | 12 + source/engine/HandmadeMath.h | 4 + source/engine/jsffi.c | 39 +- source/engine/texture.c | 2 + .../engine/thirdparty/imgui/ImSequencer.cpp | 695 --------- source/engine/thirdparty/imgui/ImSequencer.h | 79 - .../thirdparty/imgui/imgui_neo_internal.cpp | 167 -- .../thirdparty/imgui/imgui_neo_internal.h | 24 - .../thirdparty/imgui/imgui_neo_sequencer.cpp | 1376 ----------------- .../thirdparty/imgui/imgui_neo_sequencer.h | 156 -- 13 files changed, 87 insertions(+), 2526 deletions(-) delete mode 100644 source/engine/thirdparty/imgui/ImSequencer.cpp delete mode 100644 source/engine/thirdparty/imgui/ImSequencer.h delete mode 100644 source/engine/thirdparty/imgui/imgui_neo_internal.cpp delete mode 100644 source/engine/thirdparty/imgui/imgui_neo_internal.h delete mode 100644 source/engine/thirdparty/imgui/imgui_neo_sequencer.cpp delete mode 100644 source/engine/thirdparty/imgui/imgui_neo_sequencer.h diff --git a/Makefile b/Makefile index ddf9685..ce8e14a 100755 --- a/Makefile +++ b/Makefile @@ -77,7 +77,7 @@ endif CXXFLAGS += -std=c++14 -CPPFLAGS += -DHAVE_CEIL -DCP_USE_CGTYPES=0 -DCP_USE_DOUBLES=0 -DHAVE_FLOOR -DHAVE_FMOD -DHAVE_LRINT -DHAVE_LRINTF $(includeflag) $(WARNING_FLAGS) -I. -DVER=\"$(SEM)\" -DCOM=\"$(COM)\" -DDATE=\"$(DATE)\" -DINFO=\"$(INFO)\" -Wno-narrowing -Wno-int-conversion #-DENABLE_SINC_MEDIUM_CONVERTER -DENABLE_SINC_FAST_CONVERTER -DCP_COLLISION_TYPE_TYPE=uintptr_t -DCP_BITMASK_TYPE=uintptr_t +CPPFLAGS += -DHAVE_CEIL -DCP_USE_CGTYPES=0 -DCP_USE_DOUBLES=0 -DHAVE_FLOOR -DHAVE_FMOD -DHAVE_LRINT -DHAVE_LRINTF $(includeflag) $(WARNING_FLAGS) -I. -DPROSPERON_VER=\"$(SEM)\" -DPROSPERON_COM=\"$(COM)\" -DPROSPERON_DATE=\"$(DATE)\" -DPROSPERON_INFO=\"$(INFO)\" -Wno-narrowing -Wno-int-conversion #-DENABLE_SINC_MEDIUM_CONVERTER -DENABLE_SINC_FAST_CONVERTER -DCP_COLLISION_TYPE_TYPE=uintptr_t -DCP_BITMASK_TYPE=uintptr_t CPPFLAGS += -DCONFIG_VERSION=\"2024-02-14\" -DCONFIG_BIGNUM #for quickjs # ENABLE_SINC_[BEST|FAST|MEDIUM]_CONVERTER @@ -139,7 +139,7 @@ endif # All other sources OBJS != find source -type f -name '*.c' | grep -vE 'test|tool|example|fuzz|main' | grep -vE 'quickjs' -CPPOBJS != find source -type f -name '*.cpp' | grep -vE 'test|tool|example|fuzz|main|ImCurveEdit|GraphEditor|neo_sequencer|imgui_neo_sequencer' +CPPOBJS != find source -type f -name '*.cpp' | grep -vE 'test|tool|example|fuzz|main|GraphEditor|ImCurveEdit' OBJS += $(CPPOBJS) OBJS += source/engine/yugine.c OBJS += $(shell find source/engine -type f -name '*.m') @@ -240,8 +240,8 @@ ICNSIZE = 16 32 128 256 512 1024 ICNNAME := $(addsuffix .png, $(ICNSIZE)) ICON = icons/moon.gif icon.ico: $(ICON) - for i in $(ICNSIZE); do convert $^ -thumbnail $${i}x$${i} $${i}.png; done - convert $(ICNNAME) icon.ico + for i in $(ICNSIZE); do magick $^ -thumbnail $${i}x$${i} $${i}.png; done + magick $(ICNNAME) icon.ico rm $(ICNNAME) resource.o: resource.rc resource.manifest icon.ico diff --git a/scripts/prosperon.js b/scripts/prosperon.js index dab76ba..98e2d1f 100644 --- a/scripts/prosperon.js +++ b/scripts/prosperon.js @@ -101,7 +101,27 @@ game.engine_start = function (s) { 1, 0, 0, 1, 1, 0], 0), verts: 4, - uv: os.make_buffer([0, 1, 1, 1, 0, 0, 1, 0], 2), + uv: os.make_buffer([ + 0, 0, + 0, 1, + 1, 0, + 1, 1], 2), + index: os.make_buffer([0, 1, 2, 2, 1, 3], 1), + count: 6, + }; + + shape.flipquad = { + pos: os.make_buffer([ + 0, 0, 0, + 0, 1, 0, + 1, 0, 0, + 1, 1, 0], 0), + verts: 4, + uv: os.make_buffer([ + 0, 1, + 0, 0, + 1, 1, + 1, 0], 2), index: os.make_buffer([0, 1, 2, 2, 1, 3], 1), count: 6, }; @@ -121,7 +141,11 @@ game.engine_start = function (s) { 0.5, -0.5, -0.5, 0.5, 0.5, -0.5], 0), verts: 4, - uv: os.make_buffer([0, 1, 1, 1, 0, 0, 1, 0], 2), + uv: os.make_buffer([ + 0, 0, + 0, 1, + 1, 0, + 1, 1], 2), index: os.make_buffer([0, 1, 2, 2, 1, 3], 1), count: 6, }; diff --git a/scripts/render.js b/scripts/render.js index c7693f1..3d0552c 100644 --- a/scripts/render.js +++ b/scripts/render.js @@ -111,11 +111,6 @@ var stencilop = { decr_wrap: 8 }; -var depth_map = { - off: false, - on: true, -}; - var face_map = { ccw: 1, cw: 2, @@ -180,7 +175,6 @@ render.colormask = colormask; render.primitive_map = primitive_map; render.cull_map = cull_map; render.stencilop = stencilop; -render.depth_map = depth_map; render.face_map = face_map; render.compare = compare; render.blendfactor = blendfactor; @@ -421,7 +415,7 @@ function create_shader_obj(file) { return compiled; } -function make_shader(shader) { +function make_shader(shader, pipe) { if (shader_cache[shader]) return shader_cache[shader]; var file = shader; @@ -444,7 +438,9 @@ function make_shader(shader) { var shaderobj = json.decode(io.slurp(writejson)); var obj = shaderobj[os.sys()]; - obj.pipe = render.pipeline(obj, base_pipeline); + + pipe ??= base_pipeline; + obj.pipe = render.pipeline(obj, pipe); shader_cache[file] = obj; shader_times[file] = io.mod(file); return obj; @@ -611,7 +607,9 @@ render.init = function () { textshader = make_shader("shaders/text_base.cg"); render.spriteshader = make_shader("shaders/sprite.cg"); spritessboshader = make_shader("shaders/sprite_ssbo.cg"); - render.postshader = make_shader("shaders/simplepost.cg"); + var postpipe = Object.create(base_pipeline); + postpipe.cull = cull_map.none; + render.postshader = make_shader("shaders/simplepost.cg", postpipe); slice9shader = make_shader("shaders/9slice.cg"); circleshader = make_shader("shaders/circle.cg"); polyshader = make_shader("shaders/poly.cg"); @@ -1089,7 +1087,7 @@ prosperon.gizmos = function () { prosperon.make_camera = function () { var cam = world.spawn(); - cam.near = 0.1; + cam.near = -1; cam.far = 1000; cam.ortho = true; cam.viewport = [0, 0, 1, 1]; @@ -1213,7 +1211,6 @@ prosperon.render = function () { profile.endreport("sprites"); profile.report("draws"); prosperon.draw(); -// sgl.draw(); profile.endreport("draws"); profile.endreport("world"); prosperon.hudcam.size = prosperon.camera.size; @@ -1239,8 +1236,9 @@ prosperon.render = function () { render.viewport(...prosperon.camera.view()); render.use_shader(render.postshader); prosperon.postvals.diffuse = prosperon.screencolor; + render.use_mat(prosperon.postvals); - render.draw(shape.quad); + render.draw(os.backend() === "directx" ? shape.flipquad : shape.quad); profile.endreport("post process"); @@ -1249,7 +1247,6 @@ prosperon.render = function () { // Flush & render prosperon.appcam.transform.pos = [window.size.x / 2, window.size.y / 2, -100]; prosperon.appcam.size = window.size.slice(); - if (os.sys() !== "macos") prosperon.appcam.size.y *= -1; render.set_camera(prosperon.appcam); render.viewport(...prosperon.appcam.view()); diff --git a/source/engine/HandmadeMath.c b/source/engine/HandmadeMath.c index 389350d..f642558 100644 --- a/source/engine/HandmadeMath.c +++ b/source/engine/HandmadeMath.c @@ -1224,6 +1224,18 @@ HMM_Mat4 HMM_InvOrthographic(HMM_Mat4 OrthoMatrix) { return Result; } +HMM_Mat4 HMM_Orthographic_DX(float l, float r, float b, float t, float near, float far) +{ + return HMM_Orthographic_LH_ZO(l,r,b,t,near,far); +} + +HMM_Mat4 HMM_Orthographic_GL(float l, float r, float b, float t, float near, float far) +{ +// return HMM_MulM4(HMM_Orthographic_LH_NO(l,r,b,t,near,far), HMM_Scale((HMM_Vec3){1,-1,1})); + return HMM_Orthographic_LH_NO(l,r,b,t,near,far); +} + + HMM_Mat4 HMM_Orthographic_Metal(float l, float r, float b, float t, float near, float far) { HMM_Mat4 adjust = {0}; diff --git a/source/engine/HandmadeMath.h b/source/engine/HandmadeMath.h index 69b17f7..f663aa9 100644 --- a/source/engine/HandmadeMath.h +++ b/source/engine/HandmadeMath.h @@ -623,6 +623,10 @@ HMM_Mat4 HMM_Perspective_LH_ZO(float FOV, float AspectRatio, float Near, float F HMM_Mat4 HMM_Perspective_Metal(float FOV, float AspectRation, float Near, float Far); HMM_Mat4 HMM_Orthographic_Metal(float l, float r, float b, float t, float near, float far); + +HMM_Mat4 HMM_Orthographic_DX(float l, float r, float b, float t, float near, float far); +HMM_Mat4 HMM_Orthographic_GL(float l, float r, float b, float t, float near, float far); + HMM_Mat4 HMM_InvPerspective_RH(HMM_Mat4 PerspectiveMatrix); HMM_Mat4 HMM_InvPerspective_LH(HMM_Mat4 PerspectiveMatrix); HMM_Mat4 HMM_Translate(HMM_Vec3 Translation); diff --git a/source/engine/jsffi.c b/source/engine/jsffi.c index bcb50c8..8524e4a 100644 --- a/source/engine/jsffi.c +++ b/source/engine/jsffi.c @@ -41,7 +41,10 @@ #include #include "gui.h" #include "timer.h" + +#ifndef _WIN32 #include +#endif #define STB_PERLIN_IMPLEMENTATION #include "stb_perlin.h" @@ -795,16 +798,17 @@ HMM_Mat4 camera2projection(JSValue cam) { HMM_Vec2 size = js2vec2(js_getpropstr(cam,"size")); if (ortho) +#ifdef SOKOL_GLCORE + return HMM_Orthographic_GL( +#elifdef SOKOL_D3D11 + return HMM_Orthographic_DX( +#else return HMM_Orthographic_Metal( +#endif -size.x/2, size.x/2, -#ifdef SOKOL_GLCORE //flipping orthographic Y if opengl - size.y/2, - -size.y/2, -#else -size.y/2, size.y/2, -#endif near, far ); @@ -1369,7 +1373,6 @@ static const JSCFunctionListEntry js_sgl_funcs[] = { JSC_CCALL(gui_scissor, sg_apply_scissor_rect(js2number(argv[0]), js2number(argv[1]), js2number(argv[2]), js2number(argv[3]), 0); -// sgl_scissor_rectf(js2number(argv[0]), js2number(argv[1]), js2number(argv[2]), js2number(argv[3]), 0); ) JSC_CCALL(gui_text, @@ -2880,6 +2883,18 @@ JSValue js_os_sys(JSContext *js, JSValue self, int argc, JSValue *argv) return JS_UNDEFINED; } +JSC_CCALL(os_backend, + #ifdef SOKOL_GLCORE + return str2js("opengl"); + #elifdef SOKOL_WGPU + return str2js("wgpu"); + #elifdef SOKOL_D3D11 + return str2js("directx"); + #elifdef SOKOL_METAL + return str2js("metal"); + #endif +) + JSC_CCALL(os_quit, quit();) JSC_CCALL(os_exit, exit(js2number(argv[0]));) JSC_CCALL(os_reindex_static, cpSpaceReindexStatic(space)); @@ -2960,9 +2975,11 @@ JSC_CCALL(os_mallinfo, ) JSC_CCALL(os_rusage, + ret = JS_NewObject(js); + +#ifndef _WIN32 struct rusage jsmem; getrusage(RUSAGE_SELF, &jsmem); - ret = JS_NewObject(js); JSJMEMRET(ru_maxrss); JSJMEMRET(ru_ixrss); JSJMEMRET(ru_idrss); @@ -2977,6 +2994,7 @@ JSC_CCALL(os_rusage, JSJMEMRET(ru_nsignals); JSJMEMRET(ru_nvcsw); JSJMEMRET(ru_nivcsw); +#endif ) JSC_CCALL(os_mem, @@ -3527,6 +3545,7 @@ JSC_CCALL(os_turbulence, static const JSCFunctionListEntry js_os_funcs[] = { MIST_FUNC_DEF(os, turbulence, 4), MIST_FUNC_DEF(os, fbm, 4), + MIST_FUNC_DEF(os, backend, 0), MIST_FUNC_DEF(os, ridge, 5), MIST_FUNC_DEF(os, perlin, 3), MIST_FUNC_DEF(os, rectpack, 3), @@ -3633,9 +3652,9 @@ void ffi_load() { QJSGLOBALCLASS(poly2d); - JS_SetPropertyStr(js, prosperon, "version", str2js(VER)); - JS_SetPropertyStr(js, prosperon, "revision", str2js(COM)); - JS_SetPropertyStr(js, prosperon, "date", str2js(DATE)); + JS_SetPropertyStr(js, prosperon, "version", str2js(PROSPERON_VER)); + JS_SetPropertyStr(js, prosperon, "revision", str2js(PROSPERON_COM)); + JS_SetPropertyStr(js, prosperon, "date", str2js(PROSPERON_DATE)); JS_SetPropertyStr(js, globalThis, "window", window2js(&mainwin)); JS_SetPropertyStr(js, globalThis, "texture", JS_DupValue(js,texture_proto)); diff --git a/source/engine/texture.c b/source/engine/texture.c index 7bd53bf..02ba8ce 100644 --- a/source/engine/texture.c +++ b/source/engine/texture.c @@ -171,6 +171,8 @@ struct texture *texture_from_file(const char *path) { unsigned char *data; struct texture *tex = calloc(1, sizeof(*tex)); + + stbi_set_flip_vertically_on_load(1); int n; diff --git a/source/engine/thirdparty/imgui/ImSequencer.cpp b/source/engine/thirdparty/imgui/ImSequencer.cpp deleted file mode 100644 index aff7729..0000000 --- a/source/engine/thirdparty/imgui/ImSequencer.cpp +++ /dev/null @@ -1,695 +0,0 @@ -// https://github.com/CedricGuillemet/ImGuizmo -// v 1.89 WIP -// -// The MIT License(MIT) -// -// Copyright(c) 2021 Cedric Guillemet -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -#include "ImSequencer.h" -#include "imgui.h" -#include "imgui_internal.h" -#include - -namespace ImSequencer -{ -#ifndef IMGUI_DEFINE_MATH_OPERATORS - static ImVec2 operator+(const ImVec2& a, const ImVec2& b) { - return ImVec2(a.x + b.x, a.y + b.y); - } -#endif - static bool SequencerAddDelButton(ImDrawList* draw_list, ImVec2 pos, bool add = true) - { - ImGuiIO& io = ImGui::GetIO(); - ImRect btnRect(pos, ImVec2(pos.x + 16, pos.y + 16)); - bool overBtn = btnRect.Contains(io.MousePos); - bool containedClick = overBtn && btnRect.Contains(io.MouseClickedPos[0]); - bool clickedBtn = containedClick && io.MouseReleased[0]; - int btnColor = overBtn ? 0xAAEAFFAA : 0x77A3B2AA; - if (containedClick && io.MouseDownDuration[0] > 0) - btnRect.Expand(2.0f); - - float midy = pos.y + 16 / 2 - 0.5f; - float midx = pos.x + 16 / 2 - 0.5f; - draw_list->AddRect(btnRect.Min, btnRect.Max, btnColor, 4); - draw_list->AddLine(ImVec2(btnRect.Min.x + 3, midy), ImVec2(btnRect.Max.x - 3, midy), btnColor, 2); - if (add) - draw_list->AddLine(ImVec2(midx, btnRect.Min.y + 3), ImVec2(midx, btnRect.Max.y - 3), btnColor, 2); - return clickedBtn; - } - - bool Sequencer(SequenceInterface* sequence, int* currentFrame, bool* expanded, int* selectedEntry, int* firstFrame, int sequenceOptions) - { - bool ret = false; - ImGuiIO& io = ImGui::GetIO(); - int cx = (int)(io.MousePos.x); - int cy = (int)(io.MousePos.y); - static float framePixelWidth = 10.f; - static float framePixelWidthTarget = 10.f; - int legendWidth = 200; - - static int movingEntry = -1; - static int movingPos = -1; - static int movingPart = -1; - int delEntry = -1; - int dupEntry = -1; - int ItemHeight = 20; - - bool popupOpened = false; - int sequenceCount = sequence->GetItemCount(); - if (!sequenceCount) - return false; - ImGui::BeginGroup(); - - ImDrawList* draw_list = ImGui::GetWindowDrawList(); - ImVec2 canvas_pos = ImGui::GetCursorScreenPos(); // ImDrawList API uses screen coordinates! - ImVec2 canvas_size = ImGui::GetContentRegionAvail(); // Resize canvas to what's available - int firstFrameUsed = firstFrame ? *firstFrame : 0; - - - int controlHeight = sequenceCount * ItemHeight; - for (int i = 0; i < sequenceCount; i++) - controlHeight += int(sequence->GetCustomHeight(i)); - int frameCount = ImMax(sequence->GetFrameMax() - sequence->GetFrameMin(), 1); - - static bool MovingScrollBar = false; - static bool MovingCurrentFrame = false; - struct CustomDraw - { - int index; - ImRect customRect; - ImRect legendRect; - ImRect clippingRect; - ImRect legendClippingRect; - }; - ImVector customDraws; - ImVector compactCustomDraws; - // zoom in/out - const int visibleFrameCount = (int)floorf((canvas_size.x - legendWidth) / framePixelWidth); - const float barWidthRatio = ImMin(visibleFrameCount / (float)frameCount, 1.f); - const float barWidthInPixels = barWidthRatio * (canvas_size.x - legendWidth); - - ImRect regionRect(canvas_pos, canvas_pos + canvas_size); - - static bool panningView = false; - static ImVec2 panningViewSource; - static int panningViewFrame; - if (ImGui::IsWindowFocused() && io.KeyAlt && io.MouseDown[2]) - { - if (!panningView) - { - panningViewSource = io.MousePos; - panningView = true; - panningViewFrame = *firstFrame; - } - *firstFrame = panningViewFrame - int((io.MousePos.x - panningViewSource.x) / framePixelWidth); - *firstFrame = ImClamp(*firstFrame, sequence->GetFrameMin(), sequence->GetFrameMax() - visibleFrameCount); - } - if (panningView && !io.MouseDown[2]) - { - panningView = false; - } - framePixelWidthTarget = ImClamp(framePixelWidthTarget, 0.1f, 50.f); - - framePixelWidth = ImLerp(framePixelWidth, framePixelWidthTarget, 0.33f); - - frameCount = sequence->GetFrameMax() - sequence->GetFrameMin(); - if (visibleFrameCount >= frameCount && firstFrame) - *firstFrame = sequence->GetFrameMin(); - - - // -- - if (expanded && !*expanded) - { - ImGui::InvisibleButton("canvas", ImVec2(canvas_size.x - canvas_pos.x, (float)ItemHeight)); - draw_list->AddRectFilled(canvas_pos, ImVec2(canvas_size.x + canvas_pos.x, canvas_pos.y + ItemHeight), 0xFF3D3837, 0); - char tmps[512]; - ImFormatString(tmps, IM_ARRAYSIZE(tmps), sequence->GetCollapseFmt(), frameCount, sequenceCount); - draw_list->AddText(ImVec2(canvas_pos.x + 26, canvas_pos.y + 2), 0xFFFFFFFF, tmps); - } - else - { - bool hasScrollBar(true); - /* - int framesPixelWidth = int(frameCount * framePixelWidth); - if ((framesPixelWidth + legendWidth) >= canvas_size.x) - { - hasScrollBar = true; - } - */ - // test scroll area - ImVec2 headerSize(canvas_size.x, (float)ItemHeight); - ImVec2 scrollBarSize(canvas_size.x, 14.f); - ImGui::InvisibleButton("topBar", headerSize); - draw_list->AddRectFilled(canvas_pos, canvas_pos + headerSize, 0xFFFF0000, 0); - ImVec2 childFramePos = ImGui::GetCursorScreenPos(); - ImVec2 childFrameSize(canvas_size.x, canvas_size.y - 8.f - headerSize.y - (hasScrollBar ? scrollBarSize.y : 0)); - ImGui::PushStyleColor(ImGuiCol_FrameBg, 0); - ImGui::BeginChildFrame(889, childFrameSize); - sequence->focused = ImGui::IsWindowFocused(); - ImGui::InvisibleButton("contentBar", ImVec2(canvas_size.x, float(controlHeight))); - const ImVec2 contentMin = ImGui::GetItemRectMin(); - const ImVec2 contentMax = ImGui::GetItemRectMax(); - const ImRect contentRect(contentMin, contentMax); - const float contentHeight = contentMax.y - contentMin.y; - - // full background - draw_list->AddRectFilled(canvas_pos, canvas_pos + canvas_size, 0xFF242424, 0); - - // current frame top - ImRect topRect(ImVec2(canvas_pos.x + legendWidth, canvas_pos.y), ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + ItemHeight)); - - if (!MovingCurrentFrame && !MovingScrollBar && movingEntry == -1 && sequenceOptions & SEQUENCER_CHANGE_FRAME && currentFrame && *currentFrame >= 0 && topRect.Contains(io.MousePos) && io.MouseDown[0]) - { - MovingCurrentFrame = true; - } - if (MovingCurrentFrame) - { - if (frameCount) - { - *currentFrame = (int)((io.MousePos.x - topRect.Min.x) / framePixelWidth) + firstFrameUsed; - if (*currentFrame < sequence->GetFrameMin()) - *currentFrame = sequence->GetFrameMin(); - if (*currentFrame >= sequence->GetFrameMax()) - *currentFrame = sequence->GetFrameMax(); - } - if (!io.MouseDown[0]) - MovingCurrentFrame = false; - } - - //header - draw_list->AddRectFilled(canvas_pos, ImVec2(canvas_size.x + canvas_pos.x, canvas_pos.y + ItemHeight), 0xFF3D3837, 0); - if (sequenceOptions & SEQUENCER_ADD) - { - if (SequencerAddDelButton(draw_list, ImVec2(canvas_pos.x + legendWidth - ItemHeight, canvas_pos.y + 2), true)) - ImGui::OpenPopup("addEntry"); - - if (ImGui::BeginPopup("addEntry")) - { - for (int i = 0; i < sequence->GetItemTypeCount(); i++) - if (ImGui::Selectable(sequence->GetItemTypeName(i))) - { - sequence->Add(i); - *selectedEntry = sequence->GetItemCount() - 1; - } - - ImGui::EndPopup(); - popupOpened = true; - } - } - - //header frame number and lines - int modFrameCount = 10; - int frameStep = 1; - while ((modFrameCount * framePixelWidth) < 150) - { - modFrameCount *= 2; - frameStep *= 2; - }; - int halfModFrameCount = modFrameCount / 2; - - auto drawLine = [&](int i, int regionHeight) { - bool baseIndex = ((i % modFrameCount) == 0) || (i == sequence->GetFrameMax() || i == sequence->GetFrameMin()); - bool halfIndex = (i % halfModFrameCount) == 0; - int px = (int)canvas_pos.x + int(i * framePixelWidth) + legendWidth - int(firstFrameUsed * framePixelWidth); - int tiretStart = baseIndex ? 4 : (halfIndex ? 10 : 14); - int tiretEnd = baseIndex ? regionHeight : ItemHeight; - - if (px <= (canvas_size.x + canvas_pos.x) && px >= (canvas_pos.x + legendWidth)) - { - draw_list->AddLine(ImVec2((float)px, canvas_pos.y + (float)tiretStart), ImVec2((float)px, canvas_pos.y + (float)tiretEnd - 1), 0xFF606060, 1); - - draw_list->AddLine(ImVec2((float)px, canvas_pos.y + (float)ItemHeight), ImVec2((float)px, canvas_pos.y + (float)regionHeight - 1), 0x30606060, 1); - } - - if (baseIndex && px > (canvas_pos.x + legendWidth)) - { - char tmps[512]; - ImFormatString(tmps, IM_ARRAYSIZE(tmps), "%d", i); - draw_list->AddText(ImVec2((float)px + 3.f, canvas_pos.y), 0xFFBBBBBB, tmps); - } - - }; - - auto drawLineContent = [&](int i, int /*regionHeight*/) { - int px = (int)canvas_pos.x + int(i * framePixelWidth) + legendWidth - int(firstFrameUsed * framePixelWidth); - int tiretStart = int(contentMin.y); - int tiretEnd = int(contentMax.y); - - if (px <= (canvas_size.x + canvas_pos.x) && px >= (canvas_pos.x + legendWidth)) - { - //draw_list->AddLine(ImVec2((float)px, canvas_pos.y + (float)tiretStart), ImVec2((float)px, canvas_pos.y + (float)tiretEnd - 1), 0xFF606060, 1); - - draw_list->AddLine(ImVec2(float(px), float(tiretStart)), ImVec2(float(px), float(tiretEnd)), 0x30606060, 1); - } - }; - for (int i = sequence->GetFrameMin(); i <= sequence->GetFrameMax(); i += frameStep) - { - drawLine(i, ItemHeight); - } - drawLine(sequence->GetFrameMin(), ItemHeight); - drawLine(sequence->GetFrameMax(), ItemHeight); - /* - draw_list->AddLine(canvas_pos, ImVec2(canvas_pos.x, canvas_pos.y + controlHeight), 0xFF000000, 1); - draw_list->AddLine(ImVec2(canvas_pos.x, canvas_pos.y + ItemHeight), ImVec2(canvas_size.x, canvas_pos.y + ItemHeight), 0xFF000000, 1); - */ - // clip content - - draw_list->PushClipRect(childFramePos, childFramePos + childFrameSize, true); - - // draw item names in the legend rect on the left - size_t customHeight = 0; - for (int i = 0; i < sequenceCount; i++) - { - int type; - sequence->Get(i, NULL, NULL, &type, NULL); - ImVec2 tpos(contentMin.x + 3, contentMin.y + i * ItemHeight + 2 + customHeight); - draw_list->AddText(tpos, 0xFFFFFFFF, sequence->GetItemLabel(i)); - - if (sequenceOptions & SEQUENCER_DEL) - { - if (SequencerAddDelButton(draw_list, ImVec2(contentMin.x + legendWidth - ItemHeight + 2 - 10, tpos.y + 2), false)) - delEntry = i; - - if (SequencerAddDelButton(draw_list, ImVec2(contentMin.x + legendWidth - ItemHeight - ItemHeight + 2 - 10, tpos.y + 2), true)) - dupEntry = i; - } - customHeight += sequence->GetCustomHeight(i); - } - - // slots background - customHeight = 0; - for (int i = 0; i < sequenceCount; i++) - { - unsigned int col = (i & 1) ? 0xFF3A3636 : 0xFF413D3D; - - size_t localCustomHeight = sequence->GetCustomHeight(i); - ImVec2 pos = ImVec2(contentMin.x + legendWidth, contentMin.y + ItemHeight * i + 1 + customHeight); - ImVec2 sz = ImVec2(canvas_size.x + canvas_pos.x, pos.y + ItemHeight - 1 + localCustomHeight); - if (!popupOpened && cy >= pos.y && cy < pos.y + (ItemHeight + localCustomHeight) && movingEntry == -1 && cx>contentMin.x && cx < contentMin.x + canvas_size.x) - { - col += 0x80201008; - pos.x -= legendWidth; - } - draw_list->AddRectFilled(pos, sz, col, 0); - customHeight += localCustomHeight; - } - - draw_list->PushClipRect(childFramePos + ImVec2(float(legendWidth), 0.f), childFramePos + childFrameSize, true); - - // vertical frame lines in content area - for (int i = sequence->GetFrameMin(); i <= sequence->GetFrameMax(); i += frameStep) - { - drawLineContent(i, int(contentHeight)); - } - drawLineContent(sequence->GetFrameMin(), int(contentHeight)); - drawLineContent(sequence->GetFrameMax(), int(contentHeight)); - - // selection - bool selected = selectedEntry && (*selectedEntry >= 0); - if (selected) - { - customHeight = 0; - for (int i = 0; i < *selectedEntry; i++) - customHeight += sequence->GetCustomHeight(i); - draw_list->AddRectFilled(ImVec2(contentMin.x, contentMin.y + ItemHeight * *selectedEntry + customHeight), ImVec2(contentMin.x + canvas_size.x, contentMin.y + ItemHeight * (*selectedEntry + 1) + customHeight), 0x801080FF, 1.f); - } - - // slots - customHeight = 0; - for (int i = 0; i < sequenceCount; i++) - { - int* start, * end; - unsigned int color; - sequence->Get(i, &start, &end, NULL, &color); - size_t localCustomHeight = sequence->GetCustomHeight(i); - - ImVec2 pos = ImVec2(contentMin.x + legendWidth - firstFrameUsed * framePixelWidth, contentMin.y + ItemHeight * i + 1 + customHeight); - ImVec2 slotP1(pos.x + *start * framePixelWidth, pos.y + 2); - ImVec2 slotP2(pos.x + *end * framePixelWidth + framePixelWidth, pos.y + ItemHeight - 2); - ImVec2 slotP3(pos.x + *end * framePixelWidth + framePixelWidth, pos.y + ItemHeight - 2 + localCustomHeight); - unsigned int slotColor = color | 0xFF000000; - unsigned int slotColorHalf = (color & 0xFFFFFF) | 0x40000000; - - if (slotP1.x <= (canvas_size.x + contentMin.x) && slotP2.x >= (contentMin.x + legendWidth)) - { - draw_list->AddRectFilled(slotP1, slotP3, slotColorHalf, 2); - draw_list->AddRectFilled(slotP1, slotP2, slotColor, 2); - } - if (ImRect(slotP1, slotP2).Contains(io.MousePos) && io.MouseDoubleClicked[0]) - { - sequence->DoubleClick(i); - } - // Ensure grabbable handles - const float max_handle_width = slotP2.x - slotP1.x / 3.0f; - const float min_handle_width = ImMin(10.0f, max_handle_width); - const float handle_width = ImClamp(framePixelWidth / 2.0f, min_handle_width, max_handle_width); - ImRect rects[3] = { ImRect(slotP1, ImVec2(slotP1.x + handle_width, slotP2.y)) - , ImRect(ImVec2(slotP2.x - handle_width, slotP1.y), slotP2) - , ImRect(slotP1, slotP2) }; - - const unsigned int quadColor[] = { 0xFFFFFFFF, 0xFFFFFFFF, slotColor + (selected ? 0 : 0x202020) }; - if (movingEntry == -1 && (sequenceOptions & SEQUENCER_EDIT_STARTEND))// TODOFOCUS && backgroundRect.Contains(io.MousePos)) - { - for (int j = 2; j >= 0; j--) - { - ImRect& rc = rects[j]; - if (!rc.Contains(io.MousePos)) - continue; - draw_list->AddRectFilled(rc.Min, rc.Max, quadColor[j], 2); - } - - for (int j = 0; j < 3; j++) - { - ImRect& rc = rects[j]; - if (!rc.Contains(io.MousePos)) - continue; - if (!ImRect(childFramePos, childFramePos + childFrameSize).Contains(io.MousePos)) - continue; - if (ImGui::IsMouseClicked(0) && !MovingScrollBar && !MovingCurrentFrame) - { - movingEntry = i; - movingPos = cx; - movingPart = j + 1; - sequence->BeginEdit(movingEntry); - break; - } - } - } - - // custom draw - if (localCustomHeight > 0) - { - ImVec2 rp(canvas_pos.x, contentMin.y + ItemHeight * i + 1 + customHeight); - ImRect customRect(rp + ImVec2(legendWidth - (firstFrameUsed - sequence->GetFrameMin() - 0.5f) * framePixelWidth, float(ItemHeight)), - rp + ImVec2(legendWidth + (sequence->GetFrameMax() - firstFrameUsed - 0.5f + 2.f) * framePixelWidth, float(localCustomHeight + ItemHeight))); - ImRect clippingRect(rp + ImVec2(float(legendWidth), float(ItemHeight)), rp + ImVec2(canvas_size.x, float(localCustomHeight + ItemHeight))); - - ImRect legendRect(rp + ImVec2(0.f, float(ItemHeight)), rp + ImVec2(float(legendWidth), float(localCustomHeight))); - ImRect legendClippingRect(canvas_pos + ImVec2(0.f, float(ItemHeight)), canvas_pos + ImVec2(float(legendWidth), float(localCustomHeight + ItemHeight))); - customDraws.push_back({ i, customRect, legendRect, clippingRect, legendClippingRect }); - } - else - { - ImVec2 rp(canvas_pos.x, contentMin.y + ItemHeight * i + customHeight); - ImRect customRect(rp + ImVec2(legendWidth - (firstFrameUsed - sequence->GetFrameMin() - 0.5f) * framePixelWidth, float(0.f)), - rp + ImVec2(legendWidth + (sequence->GetFrameMax() - firstFrameUsed - 0.5f + 2.f) * framePixelWidth, float(ItemHeight))); - ImRect clippingRect(rp + ImVec2(float(legendWidth), float(0.f)), rp + ImVec2(canvas_size.x, float(ItemHeight))); - - compactCustomDraws.push_back({ i, customRect, ImRect(), clippingRect, ImRect() }); - } - customHeight += localCustomHeight; - } - - - // moving - if (/*backgroundRect.Contains(io.MousePos) && */movingEntry >= 0) - { -#if IMGUI_VERSION_NUM >= 18723 - ImGui::SetNextFrameWantCaptureMouse(true); -#else - ImGui::CaptureMouseFromApp(); -#endif - int diffFrame = int((cx - movingPos) / framePixelWidth); - if (std::abs(diffFrame) > 0) - { - int* start, * end; - sequence->Get(movingEntry, &start, &end, NULL, NULL); - if (selectedEntry) - *selectedEntry = movingEntry; - int& l = *start; - int& r = *end; - if (movingPart & 1) - l += diffFrame; - if (movingPart & 2) - r += diffFrame; - if (l < 0) - { - if (movingPart & 2) - r -= l; - l = 0; - } - if (movingPart & 1 && l > r) - l = r; - if (movingPart & 2 && r < l) - r = l; - movingPos += int(diffFrame * framePixelWidth); - } - if (!io.MouseDown[0]) - { - // single select - if (!diffFrame && movingPart && selectedEntry) - { - *selectedEntry = movingEntry; - ret = true; - } - - movingEntry = -1; - sequence->EndEdit(); - } - } - - // cursor - if (currentFrame && firstFrame && *currentFrame >= *firstFrame && *currentFrame <= sequence->GetFrameMax()) - { - static const float cursorWidth = 8.f; - float cursorOffset = contentMin.x + legendWidth + (*currentFrame - firstFrameUsed) * framePixelWidth + framePixelWidth / 2 - cursorWidth * 0.5f; - draw_list->AddLine(ImVec2(cursorOffset, canvas_pos.y), ImVec2(cursorOffset, contentMax.y), 0xA02A2AFF, cursorWidth); - char tmps[512]; - ImFormatString(tmps, IM_ARRAYSIZE(tmps), "%d", *currentFrame); - draw_list->AddText(ImVec2(cursorOffset + 10, canvas_pos.y + 2), 0xFF2A2AFF, tmps); - } - - draw_list->PopClipRect(); - draw_list->PopClipRect(); - - for (auto& customDraw : customDraws) - sequence->CustomDraw(customDraw.index, draw_list, customDraw.customRect, customDraw.legendRect, customDraw.clippingRect, customDraw.legendClippingRect); - for (auto& customDraw : compactCustomDraws) - sequence->CustomDrawCompact(customDraw.index, draw_list, customDraw.customRect, customDraw.clippingRect); - - // copy paste - if (sequenceOptions & SEQUENCER_COPYPASTE) - { - ImRect rectCopy(ImVec2(contentMin.x + 100, canvas_pos.y + 2) - , ImVec2(contentMin.x + 100 + 30, canvas_pos.y + ItemHeight - 2)); - bool inRectCopy = rectCopy.Contains(io.MousePos); - unsigned int copyColor = inRectCopy ? 0xFF1080FF : 0xFF000000; - draw_list->AddText(rectCopy.Min, copyColor, "Copy"); - - ImRect rectPaste(ImVec2(contentMin.x + 140, canvas_pos.y + 2) - , ImVec2(contentMin.x + 140 + 30, canvas_pos.y + ItemHeight - 2)); - bool inRectPaste = rectPaste.Contains(io.MousePos); - unsigned int pasteColor = inRectPaste ? 0xFF1080FF : 0xFF000000; - draw_list->AddText(rectPaste.Min, pasteColor, "Paste"); - - if (inRectCopy && io.MouseReleased[0]) - { - sequence->Copy(); - } - if (inRectPaste && io.MouseReleased[0]) - { - sequence->Paste(); - } - } - // - - ImGui::EndChildFrame(); - ImGui::PopStyleColor(); - if (hasScrollBar) - { - ImGui::InvisibleButton("scrollBar", scrollBarSize); - ImVec2 scrollBarMin = ImGui::GetItemRectMin(); - ImVec2 scrollBarMax = ImGui::GetItemRectMax(); - - // ratio = number of frames visible in control / number to total frames - - float startFrameOffset = ((float)(firstFrameUsed - sequence->GetFrameMin()) / (float)frameCount) * (canvas_size.x - legendWidth); - ImVec2 scrollBarA(scrollBarMin.x + legendWidth, scrollBarMin.y - 2); - ImVec2 scrollBarB(scrollBarMin.x + canvas_size.x, scrollBarMax.y - 1); - draw_list->AddRectFilled(scrollBarA, scrollBarB, 0xFF222222, 0); - - ImRect scrollBarRect(scrollBarA, scrollBarB); - bool inScrollBar = scrollBarRect.Contains(io.MousePos); - - draw_list->AddRectFilled(scrollBarA, scrollBarB, 0xFF101010, 8); - - - ImVec2 scrollBarC(scrollBarMin.x + legendWidth + startFrameOffset, scrollBarMin.y); - ImVec2 scrollBarD(scrollBarMin.x + legendWidth + barWidthInPixels + startFrameOffset, scrollBarMax.y - 2); - draw_list->AddRectFilled(scrollBarC, scrollBarD, (inScrollBar || MovingScrollBar) ? 0xFF606060 : 0xFF505050, 6); - - ImRect barHandleLeft(scrollBarC, ImVec2(scrollBarC.x + 14, scrollBarD.y)); - ImRect barHandleRight(ImVec2(scrollBarD.x - 14, scrollBarC.y), scrollBarD); - - bool onLeft = barHandleLeft.Contains(io.MousePos); - bool onRight = barHandleRight.Contains(io.MousePos); - - static bool sizingRBar = false; - static bool sizingLBar = false; - - draw_list->AddRectFilled(barHandleLeft.Min, barHandleLeft.Max, (onLeft || sizingLBar) ? 0xFFAAAAAA : 0xFF666666, 6); - draw_list->AddRectFilled(barHandleRight.Min, barHandleRight.Max, (onRight || sizingRBar) ? 0xFFAAAAAA : 0xFF666666, 6); - - ImRect scrollBarThumb(scrollBarC, scrollBarD); - static const float MinBarWidth = 44.f; - if (sizingRBar) - { - if (!io.MouseDown[0]) - { - sizingRBar = false; - } - else - { - float barNewWidth = ImMax(barWidthInPixels + io.MouseDelta.x, MinBarWidth); - float barRatio = barNewWidth / barWidthInPixels; - framePixelWidthTarget = framePixelWidth = framePixelWidth / barRatio; - int newVisibleFrameCount = int((canvas_size.x - legendWidth) / framePixelWidthTarget); - int lastFrame = *firstFrame + newVisibleFrameCount; - if (lastFrame > sequence->GetFrameMax()) - { - framePixelWidthTarget = framePixelWidth = (canvas_size.x - legendWidth) / float(sequence->GetFrameMax() - *firstFrame); - } - } - } - else if (sizingLBar) - { - if (!io.MouseDown[0]) - { - sizingLBar = false; - } - else - { - if (fabsf(io.MouseDelta.x) > FLT_EPSILON) - { - float barNewWidth = ImMax(barWidthInPixels - io.MouseDelta.x, MinBarWidth); - float barRatio = barNewWidth / barWidthInPixels; - float previousFramePixelWidthTarget = framePixelWidthTarget; - framePixelWidthTarget = framePixelWidth = framePixelWidth / barRatio; - int newVisibleFrameCount = int(visibleFrameCount / barRatio); - int newFirstFrame = *firstFrame + newVisibleFrameCount - visibleFrameCount; - newFirstFrame = ImClamp(newFirstFrame, sequence->GetFrameMin(), ImMax(sequence->GetFrameMax() - visibleFrameCount, sequence->GetFrameMin())); - if (newFirstFrame == *firstFrame) - { - framePixelWidth = framePixelWidthTarget = previousFramePixelWidthTarget; - } - else - { - *firstFrame = newFirstFrame; - } - } - } - } - else - { - if (MovingScrollBar) - { - if (!io.MouseDown[0]) - { - MovingScrollBar = false; - } - else - { - float framesPerPixelInBar = barWidthInPixels / (float)visibleFrameCount; - *firstFrame = int((io.MousePos.x - panningViewSource.x) / framesPerPixelInBar) - panningViewFrame; - *firstFrame = ImClamp(*firstFrame, sequence->GetFrameMin(), ImMax(sequence->GetFrameMax() - visibleFrameCount, sequence->GetFrameMin())); - } - } - else - { - if (scrollBarThumb.Contains(io.MousePos) && ImGui::IsMouseClicked(0) && firstFrame && !MovingCurrentFrame && movingEntry == -1) - { - MovingScrollBar = true; - panningViewSource = io.MousePos; - panningViewFrame = -*firstFrame; - } - if (!sizingRBar && onRight && ImGui::IsMouseClicked(0)) - sizingRBar = true; - if (!sizingLBar && onLeft && ImGui::IsMouseClicked(0)) - sizingLBar = true; - - } - } - } - } - - ImGui::EndGroup(); - - if (regionRect.Contains(io.MousePos)) - { - bool overCustomDraw = false; - for (auto& custom : customDraws) - { - if (custom.customRect.Contains(io.MousePos)) - { - overCustomDraw = true; - } - } - if (overCustomDraw) - { - } - else - { -#if 0 - frameOverCursor = *firstFrame + (int)(visibleFrameCount * ((io.MousePos.x - (float)legendWidth - canvas_pos.x) / (canvas_size.x - legendWidth))); - //frameOverCursor = max(min(*firstFrame - visibleFrameCount / 2, frameCount - visibleFrameCount), 0); - - /**firstFrame -= frameOverCursor; - *firstFrame *= framePixelWidthTarget / framePixelWidth; - *firstFrame += frameOverCursor;*/ - if (io.MouseWheel < -FLT_EPSILON) - { - *firstFrame -= frameOverCursor; - *firstFrame = int(*firstFrame * 1.1f); - framePixelWidthTarget *= 0.9f; - *firstFrame += frameOverCursor; - } - - if (io.MouseWheel > FLT_EPSILON) - { - *firstFrame -= frameOverCursor; - *firstFrame = int(*firstFrame * 0.9f); - framePixelWidthTarget *= 1.1f; - *firstFrame += frameOverCursor; - } -#endif - } - } - - if (expanded) - { - if (SequencerAddDelButton(draw_list, ImVec2(canvas_pos.x + 2, canvas_pos.y + 2), !*expanded)) - *expanded = !*expanded; - } - - if (delEntry != -1) - { - sequence->Del(delEntry); - if (selectedEntry && (*selectedEntry == delEntry || *selectedEntry >= sequence->GetItemCount())) - *selectedEntry = -1; - } - - if (dupEntry != -1) - { - sequence->Duplicate(dupEntry); - } - return ret; - } -} diff --git a/source/engine/thirdparty/imgui/ImSequencer.h b/source/engine/thirdparty/imgui/ImSequencer.h deleted file mode 100644 index c410844..0000000 --- a/source/engine/thirdparty/imgui/ImSequencer.h +++ /dev/null @@ -1,79 +0,0 @@ -// https://github.com/CedricGuillemet/ImGuizmo -// v 1.89 WIP -// -// The MIT License(MIT) -// -// Copyright(c) 2021 Cedric Guillemet -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files(the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions : -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -#pragma once - -#include - -struct ImDrawList; -struct ImRect; -namespace ImSequencer -{ - enum SEQUENCER_OPTIONS - { - SEQUENCER_EDIT_NONE = 0, - SEQUENCER_EDIT_STARTEND = 1 << 1, - SEQUENCER_CHANGE_FRAME = 1 << 3, - SEQUENCER_ADD = 1 << 4, - SEQUENCER_DEL = 1 << 5, - SEQUENCER_COPYPASTE = 1 << 6, - SEQUENCER_EDIT_ALL = SEQUENCER_EDIT_STARTEND | SEQUENCER_CHANGE_FRAME - }; - - struct SequenceInterface - { - bool focused = false; - virtual int GetFrameMin() const = 0; - virtual int GetFrameMax() const = 0; - virtual int GetItemCount() const = 0; - - virtual void BeginEdit(int /*index*/) {} - virtual void EndEdit() {} - virtual int GetItemTypeCount() const { return 0; } - virtual const char* GetItemTypeName(int /*typeIndex*/) const { return ""; } - virtual const char* GetItemLabel(int /*index*/) const { return ""; } - virtual const char* GetCollapseFmt() const { return "%d Frames / %d entries"; } - - virtual void Get(int index, int** start, int** end, int* type, unsigned int* color) = 0; - virtual void Add(int /*type*/) {} - virtual void Del(int /*index*/) {} - virtual void Duplicate(int /*index*/) {} - - virtual void Copy() {} - virtual void Paste() {} - - virtual size_t GetCustomHeight(int /*index*/) { return 0; } - virtual void DoubleClick(int /*index*/) {} - virtual void CustomDraw(int /*index*/, ImDrawList* /*draw_list*/, const ImRect& /*rc*/, const ImRect& /*legendRect*/, const ImRect& /*clippingRect*/, const ImRect& /*legendClippingRect*/) {} - virtual void CustomDrawCompact(int /*index*/, ImDrawList* /*draw_list*/, const ImRect& /*rc*/, const ImRect& /*clippingRect*/) {} - - virtual ~SequenceInterface() = default; - }; - - - // return true if selection is made - bool Sequencer(SequenceInterface* sequence, int* currentFrame, bool* expanded, int* selectedEntry, int* firstFrame, int sequenceOptions); - -} diff --git a/source/engine/thirdparty/imgui/imgui_neo_internal.cpp b/source/engine/thirdparty/imgui/imgui_neo_internal.cpp deleted file mode 100644 index 0865689..0000000 --- a/source/engine/thirdparty/imgui/imgui_neo_internal.cpp +++ /dev/null @@ -1,167 +0,0 @@ -// -// Created by Matty on 2022-01-28. -// - -#define IMGUI_DEFINE_MATH_OPERATORS - -#include "imgui_neo_internal.h" -#include "imgui_internal.h" -#include - -namespace ImGui { - void RenderNeoSequencerBackground(const ImVec4 &color, const ImVec2 & cursor, const ImVec2 &size, ImDrawList * drawList, float sequencerRounding) { - if(!drawList) drawList = ImGui::GetWindowDrawList(); - - const ImRect area = {cursor, cursor + size}; - - drawList->AddRectFilled(area.Min, area.Max, ColorConvertFloat4ToU32(color), sequencerRounding); - } - - void RenderNeoSequencerTopBarBackground(const ImVec4 &color, const ImVec2 &cursor, const ImVec2 &size, - ImDrawList *drawList, float sequencerRounding) { - if(!drawList) drawList = ImGui::GetWindowDrawList(); - - const ImRect barArea = {cursor, cursor + size}; - - drawList->AddRectFilled(barArea.Min, barArea.Max, ColorConvertFloat4ToU32(color), sequencerRounding); - } - - void - RenderNeoSequencerTopBarOverlay(float zoom, float valuesWidth,uint32_t startFrame, uint32_t endFrame, uint32_t offsetFrame, const ImVec2 &cursor, const ImVec2 &size, - ImDrawList *drawList, bool drawFrameLines, - bool drawFrameText, float maxPixelsPerTick) { - if(!drawList) drawList = ImGui::GetWindowDrawList(); - - const auto & style = GetStyle(); - - const ImRect barArea = {cursor + ImVec2{style.FramePadding.x + valuesWidth,style.FramePadding.y}, cursor + size }; - - const uint32_t viewEnd = endFrame + offsetFrame; - const uint32_t viewStart = startFrame + offsetFrame; - - if(drawFrameLines) { - const auto count = (int32_t)((float)((viewEnd + 1) - viewStart) / zoom); - - int32_t counter = 0; - uint32_t primaryFrames = pow(10, counter++); - uint32_t secondaryFrames = pow(10, counter); - - float perFrameWidth = GetPerFrameWidth(size.x, valuesWidth, endFrame, startFrame, zoom); - - if(perFrameWidth <= 0.0f) return; - - while (perFrameWidth < maxPixelsPerTick) - { - primaryFrames = pow(10, counter++); - secondaryFrames = pow(10, counter); - - perFrameWidth *= (float)primaryFrames; - } - - if(primaryFrames == 0 || secondaryFrames == 0) { - primaryFrames = 1; - secondaryFrames = 10; - } - - for(int32_t i = 0; i < count; i++) { - - const auto primaryFrame = ((viewStart + i) % primaryFrames == 0); - const auto secondaryFrame = ((viewStart + i) % secondaryFrames == 0); - - if(!primaryFrame && !secondaryFrame) continue; - - const auto lineHeight = secondaryFrame ? barArea.GetSize().y : barArea.GetSize().y / 2.0f; - - const ImVec2 p1 = {barArea.Min.x + (float)i * (perFrameWidth / (float)primaryFrames), barArea.Max.y}; - const ImVec2 p2 = {barArea.Min.x + (float)i * (perFrameWidth / (float)primaryFrames), barArea.Max.y - lineHeight}; - - drawList->AddLine(p1,p2, IM_COL32_WHITE, 1.0f); - - if(drawFrameText && secondaryFrame) { - char text[10]; - const auto printRes = snprintf(text, sizeof(text), "%i", viewStart + i); - if(printRes > 0) { - drawList->AddText(NULL, 0, {p1.x + 2.0f, barArea.Min.y }, IM_COL32_WHITE,text); - } - } - } - } - } - - void RenderNeoTimelineLabel(const char * label,const ImVec2 & cursor,const ImVec2 & size, const ImVec4& color,bool isGroup, bool isOpen, ImDrawList *drawList) - { - const auto& imStyle = GetStyle(); - - if(!drawList) drawList = ImGui::GetWindowDrawList(); - - auto c = cursor; - - if(isGroup) { - RenderArrow(drawList,c,IM_COL32_WHITE,isOpen ? ImGuiDir_Down : ImGuiDir_Right); - c.x += size.y + imStyle.ItemSpacing.x; - } - - drawList->AddText(c,ColorConvertFloat4ToU32(color),label, FindRenderedTextEnd(label)); - } - - void RenderNeoTimelinesBorder(const ImVec4 &color, const ImVec2 &cursor, const ImVec2 &size, ImDrawList *drawList, - float rounding, float borderSize) - { - if(!drawList) drawList = ImGui::GetWindowDrawList(); - - drawList->AddRect(cursor,cursor + size,ColorConvertFloat4ToU32(color),rounding, 0, borderSize); - } - - void RenderNeoTimelane(bool selected,const ImVec2 & cursor, const ImVec2& size, const ImVec4& highlightColor, ImDrawList *drawList) { - if(!drawList) drawList = ImGui::GetWindowDrawList(); - - if(selected) { - const ImRect area = {cursor, cursor + size}; - drawList->AddRectFilled(area.Min, area.Max, ColorConvertFloat4ToU32(highlightColor)); - } - } - - float GetPerFrameWidth(float totalSizeX, float valuesWidth, uint32_t endFrame, uint32_t startFrame, float zoom) { - const auto& imStyle = GetStyle(); - - const auto size = totalSizeX - valuesWidth - imStyle.FramePadding.x; - - auto count = (endFrame + 1) - startFrame; - - return ((size / (float)count) * zoom); - } - - struct Vec2Pair { - ImVec2 a; - ImVec2 b; - }; - - static Vec2Pair getCurrentFrameLine(const ImRect & pointerBB, float timelineHeight) { - const auto center = ImVec2{pointerBB.Min.x, pointerBB.Max.y} + ImVec2{pointerBB.GetSize().x / 2.0f, 0}; - - return Vec2Pair{ center, center + ImVec2{0, timelineHeight} }; - } - - void RenderNeoSequencerCurrentFrame(const ImVec4 &color, const ImVec4 &topColor, const ImRect &pointerBB, - float timelineHeight, float lineWidth, ImDrawList *drawList) { - if(!drawList) drawList = ImGui::GetWindowDrawList(); - - const auto pair = getCurrentFrameLine(pointerBB, timelineHeight); - - drawList->AddLine(pair.a, pair.b, ColorConvertFloat4ToU32(color), lineWidth); - - drawList->PopClipRect(); - - { //Top pointer has custom shape, we have to create it - const auto size = pointerBB.GetSize(); - ImVec2 pts[5]; - pts[0] = pointerBB.Min; - pts[1] = pointerBB.Min + ImVec2{size.x, 0}; - pts[2] = pointerBB.Min + ImVec2{size.x, size.y * 0.85f}; - pts[3] = pointerBB.Min + ImVec2{size.x / 2, size.y}; - pts[4] = pointerBB.Min + ImVec2{0, size.y * 0.85f}; - - drawList->AddConvexPolyFilled(pts, sizeof(pts) / sizeof(*pts), ColorConvertFloat4ToU32(topColor)); - } - } -} diff --git a/source/engine/thirdparty/imgui/imgui_neo_internal.h b/source/engine/thirdparty/imgui/imgui_neo_internal.h deleted file mode 100644 index 817b377..0000000 --- a/source/engine/thirdparty/imgui/imgui_neo_internal.h +++ /dev/null @@ -1,24 +0,0 @@ -// -// Created by Matty on 2022-01-28. -// - -#ifndef IMGUI_NEO_INTERNAL_H -#define IMGUI_NEO_INTERNAL_H - -#include "imgui.h" -#include "imgui_internal.h" -#include - -namespace ImGui { - IMGUI_API void RenderNeoSequencerBackground(const ImVec4& color, const ImVec2 & cursor, const ImVec2& size, ImDrawList * drawList = nullptr, float sequencerRounding = 0.0f); - IMGUI_API void RenderNeoSequencerTopBarBackground(const ImVec4& color, const ImVec2 & cursor, const ImVec2& size, ImDrawList * drawList = nullptr, float sequencerRounding = 0.0f); - IMGUI_API void RenderNeoSequencerTopBarOverlay(float zoom, float valuesWidth,uint32_t startFrame, uint32_t endFrame, uint32_t offsetFrame, const ImVec2 &cursor, const ImVec2& size, ImDrawList * drawList = nullptr, bool drawFrameLines = true, bool drawFrameText = true, float maxPixelsPerTick = -1.0f); - IMGUI_API void RenderNeoTimelineLabel(const char * label,const ImVec2 & cursor,const ImVec2 & size, const ImVec4& color,bool isGroup = false, bool isOpen = false, ImDrawList *drawList = nullptr ); - IMGUI_API void RenderNeoTimelane(bool selected,const ImVec2 & cursor, const ImVec2& size, const ImVec4& highlightColor, ImDrawList *drawList = nullptr); - IMGUI_API void RenderNeoTimelinesBorder(const ImVec4& color, const ImVec2 & cursor, const ImVec2& size, ImDrawList * drawList = nullptr, float rounding = 0.0f, float borderSize = 1.0f); - IMGUI_API void RenderNeoSequencerCurrentFrame(const ImVec4& color,const ImVec4 & topColor,const ImRect & pointerBB ,float timelineHeight, float lineWidth = 1.0f, ImDrawList * drawList = nullptr); - - IMGUI_API float GetPerFrameWidth(float totalSizeX, float valuesWidth, uint32_t endFrame, uint32_t startFrame, float zoom); -} - -#endif //IMGUI_NEO_INTERNAL_H diff --git a/source/engine/thirdparty/imgui/imgui_neo_sequencer.cpp b/source/engine/thirdparty/imgui/imgui_neo_sequencer.cpp deleted file mode 100644 index 5ea6950..0000000 --- a/source/engine/thirdparty/imgui/imgui_neo_sequencer.cpp +++ /dev/null @@ -1,1376 +0,0 @@ -// -// Created by Matty on 2022-01-28. -// -#define IMGUI_DEFINE_MATH_OPERATORS - -#include "imgui_neo_sequencer.h" -#include "imgui_internal.h" -#include "imgui_neo_internal.h" - -#include - -namespace ImGui -{ - // Internal state, used for deletion of old keyframes. - struct ImGuiNeoTimelineKeyframes - { - ImGuiID TimelineID; - ImVector KeyframesToDelete; - }; - - // Internal struct holding how many times was keyframe on certain frame rendered, used as offset for duplicates - struct ImGuiNeoKeyframeDuplicate - { - int32_t Frame; - uint32_t Count; - }; - - enum class SelectionState - { - Idle, // Doing nothing related - Selecting, // Selecting selection - Dragging // Dragging selection - }; - - struct ImGuiNeoSequencerInternalData - { - ImVec2 TopLeftCursor = {0, 0}; // Cursor on top of whole widget - ImVec2 TopBarStartCursor = {0, 0}; // Cursor on top, below Zoom slider - ImVec2 StartValuesCursor = {0, 0}; // Cursor on top of values - ImVec2 ValuesCursor = {0, 0}; // Current cursor position, used for values drawing - - ImVec2 Size = {0, 0}; // Size of whole sequencer - ImVec2 TopBarSize = {0, 0}; // Size of top bar without Zoom - - FrameIndexType StartFrame = 0; - FrameIndexType EndFrame = 0; - FrameIndexType OffsetFrame = 0; // Offset from start - - float ValuesWidth = 32.0f; // Width of biggest label in timeline, used for offset of timeline - - float FilledHeight = 0.0f; // Height of whole sequencer - - float Zoom = 1.0f; - - ImGuiID Id; - - ImGuiID LastSelectedTimeline = 0; - ImGuiID SelectedTimeline = 0; - bool LastTimelineOpenned = false; - - ImVector TimelineStack; - ImVector GroupStack; - - FrameIndexType CurrentFrame = 0; - bool HoldingCurrentFrame = false; // Are we draging current frame? - ImVec4 CurrentFrameColor; // Color of current frame, we have to save it because we render on EndNeoSequencer, but process at BeginneoSequencer - - bool HoldingZoomSlider = false; - - //Selection - ImVector Selection; // Contains ids of keyframes - ImVec2 SelectionMouseStart = {0, 0}; - SelectionState StateOfSelection = SelectionState::Idle; - ImVec2 DraggingMouseStart = {0, 0}; - bool StartDragging = true; - ImVector DraggingSelectionStart; // Contains start values of all selection elements - bool DraggingEnabled = true; - bool SelectionEnabled = true; - bool IsSelectionRightClicked = false; - - //Last keyframe data - bool IsLastKeyframeHovered = false; - bool IsLastKeyframeSelected = false; - bool IsLastKeyframeRightClicked = false; - - //Deletion - bool DeleteDataDirty = false; - bool DeleteEnabled = true; - ImVector SelectionData; - }; - - static ImGuiNeoSequencerStyle style; // NOLINT(cert-err58-cpp) - - //Global context stuff - static bool inSequencer = false; - - // Height of timeline right now - static float currentTimelineHeight = 0.0f; - - // Current active sequencer - static ImGuiID currentSequencer; - - // Current timeline depth, used for offset of label - static uint32_t currentTimelineDepth = 0; - - static ImVector sequencerColorStack; - - // Data of all sequencers, this is main c++ part and I should create C alternative or use imgui ImVector or something - static std::unordered_map sequencerData; - - static ImVector keyframeDuplicates; - - ///////////// STATIC HELPERS /////////////////////// - - static float getPerFrameWidth(ImGuiNeoSequencerInternalData& context) - { - return GetPerFrameWidth(context.Size.x, context.ValuesWidth, context.EndFrame, context.StartFrame, - context.Zoom); - } - - static float getKeyframePositionX(FrameIndexType frame, ImGuiNeoSequencerInternalData& context) - { - const auto perFrameWidth = getPerFrameWidth(context); - return (float) (frame - context.OffsetFrame - context.StartFrame) * perFrameWidth; - } - - static float getWorkTimelineWidth(ImGuiNeoSequencerInternalData& context) - { - const auto perFrameWidth = getPerFrameWidth(context); - return context.Size.x - context.ValuesWidth - perFrameWidth; - } - - // Dont pull frame from context, its used for dragging - static ImRect getCurrentFrameBB(FrameIndexType frame, ImGuiNeoSequencerInternalData& context) - { - const auto& imStyle = GetStyle(); - const auto width = style.CurrentFramePointerSize * GetIO().FontGlobalScale; - const auto cursor = - context.TopBarStartCursor + ImVec2{context.ValuesWidth + imStyle.FramePadding.x - width / 2.0f, 0}; - const auto currentFrameCursor = cursor + ImVec2{getKeyframePositionX(frame, context), 0}; - - float pointerHeight = style.CurrentFramePointerSize * 2.5f; - ImRect rect{currentFrameCursor, currentFrameCursor + ImVec2{width, pointerHeight * GetIO().FontGlobalScale}}; - - return rect; - } - - static void processCurrentFrame(FrameIndexType* frame, ImGuiNeoSequencerInternalData& context) - { - auto pointerRect = getCurrentFrameBB(*frame, context); - pointerRect.Min -= ImVec2{2.0f, 2.0f}; - pointerRect.Max += ImVec2{2.0f, 2.0f}; - - const auto& imStyle = GetStyle(); - - const auto timelineXmin = context.TopBarStartCursor.x + context.ValuesWidth + imStyle.FramePadding.x; - - const ImVec2 timelineXRange = { - timelineXmin, //min - timelineXmin + context.Size.x - context.ValuesWidth - }; - - const auto hovered = ItemHoverable(pointerRect, GetCurrentWindow()->GetID("##_top_selector_neo"), 0); - - context.CurrentFrameColor = GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_FramePointer); - - if (hovered) - { - context.CurrentFrameColor = GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_FramePointerHovered); - } - - if (context.HoldingCurrentFrame) - { - if (IsMouseDragging(ImGuiMouseButton_Left, 0.0f)) - { - const auto mousePosX = GetMousePos().x; - const auto v = mousePosX - timelineXRange.x;// Subtract min - - const auto normalized = v / getWorkTimelineWidth(context); //Divide by width to remap to 0 - 1 range - - const auto clamped = ImClamp(normalized, 0.0f, 1.0f); - - const auto viewSize = (float) (context.EndFrame - context.StartFrame) / context.Zoom; - - const auto frameViewVal = (float) context.StartFrame + (clamped * (float) viewSize); - - const auto finalFrame = (FrameIndexType) round(frameViewVal) + context.OffsetFrame; - - context.CurrentFrameColor = GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_FramePointerPressed); - - *frame = finalFrame; - } - - if (!IsMouseDown(ImGuiMouseButton_Left)) - { - context.HoldingCurrentFrame = false; - context.CurrentFrameColor = GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_FramePointer); - } - } - - if (hovered && IsMouseDown(ImGuiMouseButton_Left) && !context.HoldingCurrentFrame) - { - context.HoldingCurrentFrame = true; - context.CurrentFrameColor = GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_FramePointerPressed); - } - - context.CurrentFrame = *frame; - } - - static void finishPreviousTimeline(ImGuiNeoSequencerInternalData& context) - { - context.ValuesCursor = {context.TopBarStartCursor.x, context.ValuesCursor.y}; - currentTimelineHeight = 0.0f; - } - - static ImColor getKeyframeColor(ImGuiNeoSequencerInternalData& context, bool hovered, bool inSelection) - { - if (inSelection) - { - return ColorConvertFloat4ToU32(GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_KeyframeSelected)); - } - - return hovered ? - ColorConvertFloat4ToU32( - GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_KeyframeHovered)) : - ColorConvertFloat4ToU32(GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_Keyframe)); - } - - static void addKeyframeToDeleteData(int32_t value, ImGuiNeoSequencerInternalData& context, const ImGuiID timelineId) - { - bool foundTimeline = false; - for (auto&& val: context.SelectionData) - { - if (val.TimelineID == timelineId) - { - foundTimeline = true; - if (!val.KeyframesToDelete.contains(value)) - val.KeyframesToDelete.push_back(value); - break; - } - } - - if (!foundTimeline) - { - context.SelectionData.push_back({}); - auto& data = context.SelectionData.back(); - data.TimelineID = timelineId; - data.KeyframesToDelete.push_back(value); - } - } - - static bool - getKeyframeInSelection(int32_t value, ImGuiID id, ImGuiNeoSequencerInternalData& context, const ImRect bb) - { - //TODO(matej.vrba): This is kinda slow, it works for smaller data sample, but for bigger sample it should be changed to hashset - const ImGuiID timelineId = context.TimelineStack.back(); - - if (context.DeleteDataDirty && context.Selection.contains(id)) - { - addKeyframeToDeleteData(value, context, timelineId); - } - - if (context.StateOfSelection != SelectionState::Selecting) - { - return context.Selection.contains(id); - } - - ImRect sel = {context.SelectionMouseStart, GetMousePos()}; - - if (sel.Min.y > sel.Max.y) - { - ImVec2 tmp = sel.Min; - sel.Min = sel.Max; - sel.Max = tmp; - } - - if (sel.Min.x > sel.Max.x) - { - float tmp = sel.Min.x; - sel.Min.x = sel.Max.x; - sel.Max.x = tmp; - } - - const bool overlaps = bb.Overlaps(sel); - - const bool forceRemove = IsKeyDown(style.ModRemoveKey); - const bool forceAdd = IsKeyDown(style.ModAddKey); - - - auto removeKeyframe = [&]() - { - for (auto&& val: context.SelectionData) - { - if (val.TimelineID == timelineId) - { - val.KeyframesToDelete.find_erase(value); - break; - } - } - context.Selection.find_erase(id); - }; - - if (overlaps) - { - if (forceRemove) - { - removeKeyframe(); - return context.Selection.contains(id); - } else - { - if (!context.Selection.contains(id)) - { - addKeyframeToDeleteData(value, context, timelineId); - - context.Selection.push_back(id); - } - } - } else - { - if (!forceRemove && !forceAdd) - { - removeKeyframe(); - } else - { - return context.Selection.contains(id); - } - } - return overlaps; - } - - static ImGuiID getKeyframeID(int32_t* frame) - { - return GetCurrentWindow()->GetID(frame); - } - - static bool createKeyframe(int32_t* frame) - { - const auto& imStyle = GetStyle(); - auto& context = sequencerData[currentSequencer]; - - const auto timelineOffset = getKeyframePositionX(*frame, context); - - float offset = 0.0f; - - for (auto&& duplicateData: keyframeDuplicates) - { - if (duplicateData.Frame == *frame) - { - offset = (float) duplicateData.Count * style.CollidedKeyframeOffset; - duplicateData.Count++; - } - } - - if (offset < style.CollidedKeyframeOffset) - { - keyframeDuplicates.push_back({}); - keyframeDuplicates.back().Frame = *frame; - keyframeDuplicates.back().Count = 1; - } - - const auto pos = ImVec2{context.StartValuesCursor.x + imStyle.FramePadding.x, context.ValuesCursor.y} + - ImVec2{timelineOffset + context.ValuesWidth + offset, 0}; - - const auto bbPos = pos - ImVec2{currentTimelineHeight / 2, 0}; - - const ImRect bb = {bbPos, bbPos + ImVec2{currentTimelineHeight, currentTimelineHeight}}; - - const auto drawList = ImGui::GetWindowDrawList(); - - const ImGuiID id = getKeyframeID(frame); - - bool hovered = ItemHoverable(bb, id, 0); - - if (context.SelectionEnabled && context.Selection.contains(id) && - (context.StateOfSelection != SelectionState::Selecting)) - { - // process dragging - if (bb.Contains(GetMousePos()) && IsMouseClicked(ImGuiMouseButton_Left) && - context.StateOfSelection != SelectionState::Dragging && - context.DraggingEnabled) - { - //Start dragging - context.StartDragging = true; - } - - if (context.StateOfSelection == SelectionState::Dragging) - { - ImGuiID* it = context.Selection.find(id); - int32_t index = context.Selection.index_from_ptr(it); - - if (context.DraggingSelectionStart.size() < index + 1 || context.DraggingSelectionStart[index] == -1) - { - if (context.DraggingSelectionStart.size() < index + 1) - { - context.DraggingSelectionStart.resize(index + 1, -1); - } - - context.DraggingSelectionStart[index] = *frame; - } - float mouseDelta = GetMousePos().x - context.DraggingMouseStart.x; - - auto offsetA = int32_t( - mouseDelta / (context.Size.x / (float) context.EndFrame - (float) context.StartFrame)); - - *frame = context.DraggingSelectionStart[index] + offsetA; - } - } - - const bool inSelection = getKeyframeInSelection(*frame, id, context, bb); - - context.IsLastKeyframeSelected = inSelection; - - if (timelineOffset >= 0.0f) - { - - ImColor color = getKeyframeColor(context, hovered, inSelection); - - drawList->AddCircleFilled(pos + ImVec2{0, currentTimelineHeight / 2.f}, currentTimelineHeight / 3.0f, - color, 4); - } - - context.IsLastKeyframeHovered = hovered; - context.IsLastKeyframeRightClicked = hovered && IsMouseClicked(ImGuiMouseButton_Right); - - if (context.Selection.contains(id) && context.IsLastKeyframeRightClicked) - { - context.IsSelectionRightClicked = true; - } - - return true; - } - - static uint32_t idCounter = 0; - static char idBuffer[16]; - - const char* generateID() - { - idBuffer[0] = '#'; - idBuffer[1] = '#'; - memset(idBuffer + 2, 0, 14); - snprintf(idBuffer + 2, 14, "%o", idCounter++); - - return &idBuffer[0]; - } - - void resetID() - { - idCounter = 0; - } - - static void renderCurrentFrame(ImGuiNeoSequencerInternalData& context) - { - const auto bb = getCurrentFrameBB(context.CurrentFrame, context); - - const auto drawList = ImGui::GetWindowDrawList(); - - RenderNeoSequencerCurrentFrame( - GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_FramePointerLine), - context.CurrentFrameColor, - bb, - context.Size.y - context.TopBarSize.y, - style.CurrentFrameLineWidth, - drawList - ); - } - - static float calculateZoomBarHeight() - { - const auto& imStyle = GetStyle(); - return GetFontSize() * style.ZoomHeightScale + imStyle.FramePadding.y * 2.0f; - } - - static void - processAndRenderZoom(ImGuiNeoSequencerInternalData& context, const ImVec2& cursor, bool allowEditingLength, - FrameIndexType* start, - FrameIndexType* end) - { - const auto& imStyle = GetStyle(); - ImGuiWindow* window = GetCurrentWindow(); - - const auto zoomHeight = calculateZoomBarHeight(); - - auto* drawList = GetWindowDrawList(); - - //Input width - const auto inputWidth = CalcTextSize("123456").x; - - const auto inputWidthWithPadding = inputWidth + imStyle.ItemSpacing.x; - - const auto cursorV = allowEditingLength ? cursor + ImVec2{inputWidthWithPadding, 0} - : cursor; - - const auto size = allowEditingLength ? - context.Size.x - 2 * inputWidthWithPadding : - context.Size.x; - - const ImRect bb{cursorV, cursorV + ImVec2{size, zoomHeight}}; - - - const auto zoomBarEndWithSpacing = ImVec2{bb.Max.x + imStyle.ItemSpacing.x, bb.Min.y}; - - FrameIndexType startFrameVal = *start; - FrameIndexType endFrameVal = *end; - - if (allowEditingLength) - { - const float sideOffset = imStyle.ItemSpacing.x / 2.0f; - auto prevWindowCursor = window->DC.CursorPos; - - window->DC.CursorPos = cursor; - - window->DC.CursorPos.x += sideOffset; - - PushItemWidth(inputWidth); - InputScalar("##input_start_frame", ImGuiDataType_U32, &startFrameVal, NULL, NULL, "%i", - allowEditingLength ? 0 : ImGuiInputTextFlags_ReadOnly); - - window->DC.CursorPos = ImVec2{zoomBarEndWithSpacing.x, cursor.y}; - window->DC.CursorPos.x -= sideOffset; - - PushItemWidth(inputWidth); - InputScalar("##input_end_frame", ImGuiDataType_U32, &endFrameVal, NULL, NULL, "%i", - allowEditingLength ? 0 : ImGuiInputTextFlags_ReadOnly); - - window->DC.CursorPos = prevWindowCursor; - } - - //if (startFrameVal < 0) - // startFrameVal = (int32_t) *start; -// - //if (endFrameVal < 0) - // endFrameVal = (int32_t) *end; - - if (endFrameVal <= startFrameVal) - endFrameVal = (int32_t) *end; - - *start = startFrameVal; - *end = endFrameVal; - - //drawList->AddText(startFrameTextCursor + ImVec2{frameNumberBorderSize.x, 0} - ImVec2{numberTextWidth,0},IM_COL32_WHITE,numberText); - - //Background - drawList->AddRectFilled(bb.Min, bb.Max, - ColorConvertFloat4ToU32(GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_ZoomBarBg)), - 10.0f); - - const auto baseWidth = bb.GetSize().x - - imStyle.ItemInnerSpacing.x; //There is just half spacing applied, doing it normally makes big gap on sides - - const auto sliderHeight = bb.GetSize().y - imStyle.ItemInnerSpacing.y; - - const auto sliderWidth = baseWidth / context.Zoom; - - const auto sliderMin = bb.Min + imStyle.ItemInnerSpacing / 2.0f; - - //const auto sliderMax = bb.Max - imStyle.ItemInnerSpacing / 2.0f; - - const auto sliderMaxWidth = baseWidth; - - const auto totalFrames = (*end - *start); - - const auto singleFrameWidthOffset = sliderMaxWidth / (float) totalFrames; - - const auto zoomSliderOffset = singleFrameWidthOffset * (float) context.OffsetFrame; - - const auto sliderStart = sliderMin + ImVec2{zoomSliderOffset, 0}; - - const float sideSize = sliderHeight; - - const ImRect finalSliderBB{sliderStart, sliderStart + ImVec2{sliderWidth, sliderHeight}}; - - const ImRect finalSliderInteractBB = {finalSliderBB.Min + ImVec2{sideSize, 0}, - finalSliderBB.Max - ImVec2{sideSize, 0}}; - - - const auto viewWidth = (uint32_t) ((float) totalFrames / context.Zoom); - - const bool hovered = ItemHoverable(bb, GetCurrentWindow()->GetID("##zoom_slider"), 0); - - if (hovered) - { - SetKeyOwner(ImGuiKey_MouseWheelY, GetItemID()); - const float currentScroll = GetIO().MouseWheel; - - context.Zoom = ImClamp(context.Zoom + float(currentScroll) * 0.3f, 1.0f, (float) viewWidth); - const auto newZoomWidth = (FrameIndexType) ceil((float) totalFrames / (context.Zoom)); - - if (*start + context.OffsetFrame + newZoomWidth > *end) - context.OffsetFrame = ImMax(0U, totalFrames - viewWidth); - } - - if (context.HoldingZoomSlider) - { - if (IsMouseDragging(ImGuiMouseButton_Left, 0.01f)) - { - const auto currentX = GetMousePos().x; - - const auto v = currentX - bb.Min.x;// Subtract min - - const auto normalized = v / bb.GetWidth(); //Divide by width to remap to 0 - 1 range - - const auto sliderWidthNormalized = 1.0f / context.Zoom; - - const auto singleFrameWidthOffsetNormalized = singleFrameWidthOffset / bb.GetWidth(); - - FrameIndexType finalFrame = (FrameIndexType) ((float) (normalized - sliderWidthNormalized / 2.0f) / - singleFrameWidthOffsetNormalized); - - if (normalized - sliderWidthNormalized / 2.0f < 0.0f) - { - finalFrame = 0; - } - - - if (normalized + sliderWidthNormalized / 2.0f > 1.0f) - { - finalFrame = totalFrames - viewWidth; - } - - - context.OffsetFrame = finalFrame; - } - - if (!IsMouseDown(ImGuiMouseButton_Left)) - { - context.HoldingZoomSlider = false; - } - } - - if (hovered && IsMouseDown(ImGuiMouseButton_Left)) - { - context.HoldingZoomSlider = true; - } - - - const auto res = ItemAdd(finalSliderInteractBB, 0); - - - const auto viewStart = *start + context.OffsetFrame; - const auto viewEnd = viewStart + viewWidth; - - if (res) - { - auto sliderColor = GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_ZoomBarSlider); - - if (IsItemHovered()) - { - sliderColor = GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_ZoomBarSliderHovered); - } - - //Render bar - drawList->AddRectFilled(finalSliderBB.Min, finalSliderBB.Max, ColorConvertFloat4ToU32(sliderColor), 10.0f); - - const auto sliderCenter = finalSliderBB.GetCenter(); - - char overlayTextBuffer[128]; - - snprintf(overlayTextBuffer, sizeof(overlayTextBuffer), "%i - %i", viewStart, viewEnd); - - const auto overlaySize = CalcTextSize(overlayTextBuffer); - - drawList->AddText(sliderCenter - overlaySize / 2.0f, IM_COL32_WHITE, overlayTextBuffer); - } - } - - static void processSelection(ImGuiNeoSequencerInternalData& context) - { - context.DeleteDataDirty = false; - - if (context.StartDragging) - { - context.StateOfSelection = SelectionState::Dragging; - context.DraggingMouseStart = GetMousePos(); - context.StartDragging = false; - return; - } - - const auto windowWorkRect = GetCurrentWindow()->ClipRect; - - const auto sequencerWorkRect = ImRect{ - context.TopBarStartCursor + ImVec2{context.ValuesWidth, context.TopBarSize.y}, - context.TopBarStartCursor + context.Size - ImVec2{0, context.TopBarSize.y}}; - - if (IsMouseDown(ImGuiMouseButton_Left) && windowWorkRect.Contains(GetMousePos()) && - sequencerWorkRect.Contains(GetMousePos())) - { - // Not dragging yet - switch (context.StateOfSelection) - { - case SelectionState::Idle: - { - if (!IsMouseClicked(ImGuiMouseButton_Left)) return; - - context.SelectionMouseStart = GetMousePos(); - context.StateOfSelection = SelectionState::Selecting; - break; - } - case SelectionState::Selecting: - { - break; - } - case SelectionState::Dragging: - { - - break; - } - } - } else - { - switch (context.StateOfSelection) - { - case SelectionState::Idle: - { - break; - } - case SelectionState::Selecting: - { - context.SelectionMouseStart = {0, 0}; - context.StateOfSelection = SelectionState::Idle; - break; - } - case SelectionState::Dragging: - { - context.DraggingSelectionStart.resize(0); - context.StateOfSelection = SelectionState::Idle; - context.DraggingMouseStart = {0, 0}; - context.DeleteDataDirty = true; - for (auto&& t: context.SelectionData) - t.KeyframesToDelete.resize(0); - break; - } - } - } - } - - static void renderSelection(ImGuiNeoSequencerInternalData& context) - { - if (context.StateOfSelection != SelectionState::Selecting) - { - return; - } - const ImVec2 currentMousePosition = GetMousePos(); - - auto* drawList = GetWindowDrawList(); - - ImRect sel{context.SelectionMouseStart, - currentMousePosition}; - - if (sel.Min.y > sel.Max.y) - { - ImVec2 tmp = sel.Min; - sel.Min = sel.Max; - sel.Max = tmp; - } - - if (sel.Min.x > sel.Max.x) - { - float tmp = sel.Min.x; - sel.Min.x = sel.Max.x; - sel.Max.x = tmp; - } - - if (sel.GetArea() < 32.0f) - return; - - // Inner - drawList->AddRectFilled( - context.SelectionMouseStart, - currentMousePosition, - ColorConvertFloat4ToU32(style.Colors[ImGuiNeoSequencerCol_Selection]) - ); - - // border - drawList->AddRect( - context.SelectionMouseStart, - currentMousePosition, - ColorConvertFloat4ToU32(style.Colors[ImGuiNeoSequencerCol_SelectionBorder]), - 0.0f, - 0, - 0.5f - ); - } - - static bool groupBehaviour(const ImGuiID id, bool* open, const ImVec2 labelSize) - { - auto& context = sequencerData[currentSequencer]; - ImGuiWindow* window = GetCurrentWindow(); - - const bool closable = open != nullptr; - - auto drawList = ImGui::GetWindowDrawList(); - const float arrowWidth = drawList->_Data->FontSize; - const ImVec2 arrowSize = {arrowWidth, arrowWidth}; - const ImRect arrowBB = { - context.ValuesCursor, - context.ValuesCursor + arrowSize - }; - const ImVec2 groupBBMin = {context.ValuesCursor + ImVec2{arrowSize.x, 0.0f}}; - const ImRect groupBB = { - groupBBMin, - groupBBMin + labelSize - }; - const ImGuiID arrowID = window->GetID(generateID()); - const auto addArrowRes = ItemAdd(arrowBB, arrowID); - if (addArrowRes) - { - if (IsItemClicked() && closable) - (*open) = !(*open); - } - - const auto addGroupRes = ItemAdd(groupBB, id); - if (addGroupRes) - { - if (IsItemClicked()) - { - context.LastSelectedTimeline = context.SelectedTimeline; - context.SelectedTimeline = context.SelectedTimeline == id ? 0 : id; - } - } - const float width = groupBB.Max.x - arrowBB.Min.x; - context.ValuesWidth = std::max(context.ValuesWidth, width); // Make left panel wide enough - return addGroupRes && addArrowRes; - } - - static bool timelineBehaviour(const ImGuiID id, const ImVec2 labelSize) - { - auto& context = sequencerData[currentSequencer]; - //ImGuiWindow *window = GetCurrentWindow(); - - const ImRect groupBB = { - context.ValuesCursor, - context.ValuesCursor + labelSize - }; - - const auto addGroupRes = ItemAdd(groupBB, id); - if (addGroupRes) - { - if (IsItemClicked()) - { - context.LastSelectedTimeline = context.SelectedTimeline; - context.SelectedTimeline = context.SelectedTimeline == id ? 0 : id; - } - } - const float width = groupBB.Max.x - groupBB.Min.x; - context.ValuesWidth = std::max(context.ValuesWidth, width); // Make left panel wide enough - - return addGroupRes; - } - - //////////////////////////////////// - - const ImVec4& GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol idx) - { - return GetNeoSequencerStyle().Colors[idx]; - } - - ImGuiNeoSequencerStyle& GetNeoSequencerStyle() - { - return style; - } - - bool - BeginNeoSequencer(const char* idin, FrameIndexType* frame, FrameIndexType* startFrame, FrameIndexType* endFrame, - const ImVec2& size, - ImGuiNeoSequencerFlags flags) - { - IM_ASSERT(!inSequencer && "Called when while in other NeoSequencer, that won't work, call End!"); - IM_ASSERT(*startFrame < *endFrame && "Start frame must be smaller than end frame"); - - static char childNameStorage[64]; - snprintf(childNameStorage, sizeof(childNameStorage), "##%s_child_wrapper", idin); - const bool openChild = BeginChild(childNameStorage); - - if (!openChild) - { - EndChild(); - return openChild; - } - - //ImGuiContext &g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - const auto& imStyle = GetStyle(); - //auto &neoStyle = GetNeoSequencerStyle(); - - if (inSequencer) - return false; - - if (window->SkipItems) - return false; - - const auto drawList = GetWindowDrawList(); - - const auto cursor = GetCursorScreenPos(); - const auto area = ImGui::GetContentRegionAvail(); - - const auto cursorBasePos = GetCursorScreenPos() + window->Scroll; - - PushID(idin); - const auto id = window->IDStack[window->IDStack.size() - 1]; - - inSequencer = true; - - auto& context = sequencerData[id]; - context.Id = id; - - auto realSize = ImFloor(size); - if (realSize.x <= 0.0f) - realSize.x = ImMax(4.0f, area.x); - if (realSize.y <= 0.0f) - realSize.y = ImMax(4.0f, context.FilledHeight); - - const bool showZoom = !(flags & ImGuiNeoSequencerFlags_HideZoom); - const bool headerAlwaysVisible = (flags & ImGuiNeoSequencerFlags_AlwaysShowHeader); - context.SelectionEnabled = (flags & ImGuiNeoSequencerFlags_EnableSelection); - context.DraggingEnabled = context.SelectionEnabled && (flags & ImGuiNeoSequencerFlags_Selection_EnableDragging); - context.DeleteEnabled = context.SelectionEnabled && (flags & ImGuiNeoSequencerFlags_Selection_EnableDeletion); - - context.TopLeftCursor = headerAlwaysVisible ? cursorBasePos : cursor; - - // If Zoom is shown, we offset it by height of Zoom bar + padding - context.TopBarStartCursor = showZoom ? context.TopLeftCursor + - ImVec2{0, calculateZoomBarHeight()} - : context.TopLeftCursor; - context.StartFrame = *startFrame; - context.EndFrame = *endFrame; - context.Size = realSize; - - context.TopBarSize = ImVec2(context.Size.x, style.TopBarHeight); - - if (context.TopBarSize.y <= 0.0f) - context.TopBarSize.y = CalcTextSize("100").y + imStyle.FramePadding.y * 2.0f; - - currentSequencer = window->IDStack[window->IDStack.size() - 1]; - - auto backgroundSize = context.Size; - const float topCut = abs(context.TopLeftCursor.y - cursor.y); - backgroundSize.y = backgroundSize.y - (topCut); - - RenderNeoSequencerBackground(GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_Bg), context.TopLeftCursor, - backgroundSize, - drawList, style.SequencerRounding); - - - RenderNeoSequencerTopBarBackground(GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_TopBarBg), - context.TopBarStartCursor, context.TopBarSize, - drawList, style.SequencerRounding); - - - RenderNeoSequencerTopBarOverlay(context.Zoom, context.ValuesWidth, context.StartFrame, context.EndFrame, - context.OffsetFrame, - context.TopBarStartCursor, context.TopBarSize, drawList, - style.TopBarShowFrameLines, style.TopBarShowFrameTexts, style.MaxSizePerTick); - - if (showZoom) - processAndRenderZoom(context, context.TopLeftCursor, flags & ImGuiNeoSequencerFlags_AllowLengthChanging, - startFrame, endFrame); - - if (context.Size.y < context.FilledHeight) - context.Size.y = context.FilledHeight; - - context.FilledHeight = context.TopBarSize.y + style.TopBarSpacing + - (showZoom ? calculateZoomBarHeight() : 0.0f); - - context.StartValuesCursor = cursor + ImVec2{0, context.TopBarSize.y + style.TopBarSpacing}; - if (showZoom) - context.StartValuesCursor = context.StartValuesCursor + ImVec2{0, calculateZoomBarHeight()}; - context.ValuesCursor = context.StartValuesCursor; - - processCurrentFrame(frame, context); - - //if (enableSelection) - //processSelection(context); - - const auto clipMin = context.TopBarStartCursor + ImVec2(0, context.TopBarSize.y); - - drawList->PushClipRect(clipMin, - clipMin + backgroundSize - ImVec2(0, context.TopBarSize.y) - - ImVec2{0, GetFontSize() * style.ZoomHeightScale}, true); - - return true; - } - - void EndNeoSequencer() - { - IM_ASSERT(inSequencer && "Called end sequencer when BeginSequencer didnt return true or wasn't called at all!"); - IM_ASSERT(sequencerData.count(currentSequencer) != 0 && "Ended sequencer has no context!"); - - auto& context = sequencerData[currentSequencer]; - IM_ASSERT(context.TimelineStack.empty() && "Missmatch in timeline Begin / End"); - - if (context.SelectionEnabled) - processSelection(context); - - context.LastSelectedTimeline = context.SelectedTimeline; - context.IsSelectionRightClicked = false; - - if (context.SelectionEnabled) - renderSelection(context); - - renderCurrentFrame(context); - - inSequencer = false; - - const ImVec2 min = {0, 0}; - context.Size.y = context.FilledHeight; - const auto max = context.Size; - - ItemSize({min, max}); - PopID(); - resetID(); - - EndChild(); - } - - IMGUI_API bool BeginNeoGroup(const char* label, bool* open) - { - return BeginNeoTimeline(label, nullptr, 0, open, ImGuiNeoTimelineFlags_Group); - } - - IMGUI_API void EndNeoGroup() - { - return EndNeoTimeLine(); - } - -#ifdef __cplusplus - - bool - BeginNeoTimeline(const char* label, std::vector& keyframes, bool* open, ImGuiNeoTimelineFlags flags) - { - std::vector c_keyframes{keyframes.size()}; - for (uint32_t i = 0; i < keyframes.size(); i++) - c_keyframes[i] = &keyframes[i]; - - return BeginNeoTimeline(label, c_keyframes.data(), c_keyframes.size(), open, flags); - } - -#endif - - void PushNeoSequencerStyleColor(ImGuiNeoSequencerCol idx, ImU32 col) - { - ImGuiColorMod backup; - backup.Col = idx; - backup.BackupValue = style.Colors[idx]; - sequencerColorStack.push_back(backup); - style.Colors[idx] = ColorConvertU32ToFloat4(col); - } - - void PushNeoSequencerStyleColor(ImGuiNeoSequencerCol idx, const ImVec4& col) - { - ImGuiColorMod backup; - backup.Col = idx; - backup.BackupValue = style.Colors[idx]; - sequencerColorStack.push_back(backup); - style.Colors[idx] = col; - } - - void PopNeoSequencerStyleColor(int count) - { - while (count > 0) - { - ImGuiColorMod& backup = sequencerColorStack.back(); - style.Colors[backup.Col] = backup.BackupValue; - sequencerColorStack.pop_back(); - count--; - } - } - - void SetSelectedTimeline(const char* timelineLabel) - { - IM_ASSERT(inSequencer && "Not in active sequencer!"); - - auto& context = sequencerData[currentSequencer]; - - ImGuiWindow* window = GetCurrentWindow(); - - ImGuiID timelineID = 0; - - if (timelineLabel) - { - timelineID = window->GetID(timelineLabel); - } - context.LastSelectedTimeline = context.SelectedTimeline; - context.SelectedTimeline = timelineID; - } - - bool IsNeoTimelineSelected(ImGuiNeoTimelineIsSelectedFlags flags) - { - IM_ASSERT(inSequencer && "Not in active sequencer!"); - auto& context = sequencerData[currentSequencer]; - - IM_ASSERT(!context.TimelineStack.empty() && "No active timelines are present!"); - - const bool newly = flags & ImGuiNeoTimelineIsSelectedFlags_NewlySelected; - - const auto openTimeline = context.TimelineStack[context.TimelineStack.size() - 1]; - - if (!newly) - { - return context.SelectedTimeline == openTimeline; - } - - return (context.SelectedTimeline != context.LastSelectedTimeline) && - context.SelectedTimeline == openTimeline; - } - - bool BeginNeoTimelineEx(const char* label, bool* open, ImGuiNeoTimelineFlags flags) - { - IM_ASSERT(inSequencer && "Not in active sequencer!"); - - const bool closable = open != nullptr; - - auto& context = sequencerData[currentSequencer]; - const auto& imStyle = GetStyle(); - ImGuiWindow* window = GetCurrentWindow(); - const ImGuiID id = window->GetID(label); - auto labelSize = CalcTextSize(label); - - labelSize.y += imStyle.FramePadding.y * 2 + style.ItemSpacing.y * 2; - labelSize.x += imStyle.FramePadding.x * 2 + style.ItemSpacing.x * 2 + - (float) currentTimelineDepth * style.DepthItemSpacing; - - - bool isGroup = flags & ImGuiNeoTimelineFlags_Group && closable; - bool addRes = false; - if (isGroup) - { - labelSize.x += imStyle.ItemSpacing.x + GetFontSize(); - addRes = groupBehaviour(id, open, labelSize); - } else - { - addRes = timelineBehaviour(id, labelSize); - } - - if (currentTimelineDepth > 0) - { - context.ValuesCursor = {context.TopBarStartCursor.x, context.ValuesCursor.y}; - } - - currentTimelineHeight = labelSize.y; - context.FilledHeight += currentTimelineHeight; - const auto result = !closable || (*open); - context.LastTimelineOpenned = result; - - if (addRes) - { - RenderNeoTimelane(id == context.SelectedTimeline, - context.ValuesCursor + ImVec2{context.ValuesWidth, 0}, - ImVec2{context.Size.x - context.ValuesWidth, currentTimelineHeight}, - GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_SelectedTimeline)); - - ImVec4 color = GetStyleColorVec4(ImGuiCol_Text); - if (IsItemHovered()) color.w *= 0.7f; - - RenderNeoTimelineLabel(label, - context.ValuesCursor + imStyle.FramePadding + - ImVec2{(float) currentTimelineDepth * style.DepthItemSpacing, 0}, - labelSize, - color, - isGroup, - isGroup && (*open)); - - } - - if (result) - context.TimelineStack.push_back(id); - - if (isGroup) - { // Group requires special behaviour if its closed - context.ValuesCursor.y += currentTimelineHeight; - if (result) - { - currentTimelineDepth++; - context.GroupStack.push_back(id); - } - } - - keyframeDuplicates.resize(0); - - return result; - } - - bool BeginNeoTimeline(const char* label, FrameIndexType** keyframes, uint32_t keyframeCount, bool* open, - ImGuiNeoTimelineFlags flags) - { - if (!BeginNeoTimelineEx(label, open, flags)) - return false; - - for (uint32_t i = 0; i < keyframeCount; i++) - { - NeoKeyframe(keyframes[i]); - } - - return true; - } - - void EndNeoTimeLine() - { - IM_ASSERT(inSequencer && "Not in active sequencer!"); - - auto& context = sequencerData[currentSequencer]; - const auto& imStyle = GetStyle(); - - IM_ASSERT(context.TimelineStack.size() > 0 && "Timeline stack push/pop missmatch!"); - - context.ValuesCursor.x += imStyle.FramePadding.x + (float) currentTimelineDepth * style.DepthItemSpacing; - context.ValuesCursor.y += currentTimelineHeight; - - finishPreviousTimeline(context); - - if (!context.TimelineStack.empty() && !context.GroupStack.empty() && - context.TimelineStack.back() == context.GroupStack.back()) - { - currentTimelineDepth--; - context.GroupStack.pop_back(); - } - - context.TimelineStack.pop_back(); - } - - void NeoKeyframe(int32_t* value) - { - IM_ASSERT(inSequencer && "Not in active sequencer!"); - auto& context = sequencerData[currentSequencer]; - IM_ASSERT(!context.TimelineStack.empty() && "Not in timeline!"); - - createKeyframe(value); - } - - bool IsNeoKeyframeHovered() - { - IM_ASSERT(inSequencer && "Not in active sequencer!"); - auto& context = sequencerData[currentSequencer]; - - return context.IsLastKeyframeHovered; - } - - bool IsNeoKeyframeSelected() - { - IM_ASSERT(inSequencer && "Not in active sequencer!"); - auto& context = sequencerData[currentSequencer]; - - return context.IsLastKeyframeSelected; - } - - bool IsNeoKeyframeRightClicked() - { - IM_ASSERT(inSequencer && "Not in active sequencer!"); - auto& context = sequencerData[currentSequencer]; - - return context.IsLastKeyframeRightClicked; - } - - void NeoClearSelection() - { - IM_ASSERT(inSequencer && "Not in active sequencer!"); - auto& context = sequencerData[currentSequencer]; - - context.Selection.resize(0); - context.SelectionData.resize(0); - } - - bool NeoIsSelecting() - { - IM_ASSERT(inSequencer && "Not in active sequencer!"); - auto& context = sequencerData[currentSequencer]; - - return context.StateOfSelection == SelectionState::Selecting; - } - - bool NeoHasSelection() - { - IM_ASSERT(inSequencer && "Not in active sequencer!"); - auto& context = sequencerData[currentSequencer]; - - return !context.Selection.empty(); - } - - bool NeoIsDraggingSelection() - { - IM_ASSERT(inSequencer && "Not in active sequencer!"); - auto& context = sequencerData[currentSequencer]; - - return context.StateOfSelection == SelectionState::Dragging; - } - - uint32_t GetNeoKeyframeSelectionSize() - { - IM_ASSERT(inSequencer && "Not in active sequencer!"); - auto& context = sequencerData[currentSequencer]; - - if (!context.DeleteEnabled) - return 0; - - IM_ASSERT(!context.TimelineStack.empty() && "Not in timeline!"); - const ImGuiID timelineId = context.TimelineStack.back(); - - for (auto&& deleteSelection: context.SelectionData) - { - if (deleteSelection.TimelineID == timelineId) - return deleteSelection.KeyframesToDelete.size(); - } - - return 0; - } - - void GetNeoKeyframeSelection(FrameIndexType * selection) - { - IM_ASSERT(inSequencer && "Not in active sequencer!"); - auto& context = sequencerData[currentSequencer]; - - if (!context.DeleteEnabled) - return; - - IM_ASSERT(!context.TimelineStack.empty() && "Not in timeline!"); - const ImGuiID timelineId = context.TimelineStack.back(); - - for (auto&& deleteSelection: context.SelectionData) - { - if (deleteSelection.TimelineID == timelineId) - { - for (int32_t i = 0; i < deleteSelection.KeyframesToDelete.size(); i++) - { - selection[i] = deleteSelection.KeyframesToDelete[i]; - } - return; - } - } - - } - - bool IsNeoKeyframeSelectionRightClicked() - { - IM_ASSERT(inSequencer && "Not in active sequencer!"); - auto& context = sequencerData[currentSequencer]; - - return context.IsSelectionRightClicked; - } - - bool NeoCanDeleteSelection() - { - IM_ASSERT(inSequencer && "Not in active sequencer!"); - auto& context = sequencerData[currentSequencer]; - - return context.DeleteEnabled && NeoHasSelection() && !NeoIsSelecting() && !NeoIsDraggingSelection(); - } -} - -ImGuiNeoSequencerStyle::ImGuiNeoSequencerStyle() -{ - Colors[ImGuiNeoSequencerCol_Bg] = ImVec4{0.31f, 0.31f, 0.31f, 1.00f}; - Colors[ImGuiNeoSequencerCol_TopBarBg] = ImVec4{0.22f, 0.22f, 0.22f, 0.84f}; - Colors[ImGuiNeoSequencerCol_SelectedTimeline] = ImVec4{0.98f, 0.706f, 0.322f, 0.88f}; - Colors[ImGuiNeoSequencerCol_TimelinesBg] = Colors[ImGuiNeoSequencerCol_TopBarBg]; - Colors[ImGuiNeoSequencerCol_TimelineBorder] = Colors[ImGuiNeoSequencerCol_Bg] * ImVec4{0.5f, 0.5f, 0.5f, 1.0f}; - - Colors[ImGuiNeoSequencerCol_FramePointer] = ImVec4{0.98f, 0.24f, 0.24f, 0.50f}; - Colors[ImGuiNeoSequencerCol_FramePointerHovered] = ImVec4{0.98f, 0.15f, 0.15f, 1.00f}; - Colors[ImGuiNeoSequencerCol_FramePointerPressed] = ImVec4{0.98f, 0.08f, 0.08f, 1.00f}; - - Colors[ImGuiNeoSequencerCol_Keyframe] = ImVec4{0.59f, 0.59f, 0.59f, 0.50f}; - Colors[ImGuiNeoSequencerCol_KeyframeHovered] = ImVec4{0.98f, 0.39f, 0.36f, 1.00f}; - Colors[ImGuiNeoSequencerCol_KeyframePressed] = ImVec4{0.98f, 0.39f, 0.36f, 1.00f}; - Colors[ImGuiNeoSequencerCol_KeyframeSelected] = ImVec4{0.32f, 0.23f, 0.98f, 1.00f}; - - Colors[ImGuiNeoSequencerCol_FramePointerLine] = ImVec4{0.98f, 0.98f, 0.98f, 0.8f}; - - Colors[ImGuiNeoSequencerCol_ZoomBarBg] = ImVec4{0.59f, 0.59f, 0.59f, 0.90f}; - Colors[ImGuiNeoSequencerCol_ZoomBarSlider] = ImVec4{0.8f, 0.8f, 0.8f, 0.60f}; - Colors[ImGuiNeoSequencerCol_ZoomBarSliderHovered] = ImVec4{0.98f, 0.98f, 0.98f, 0.80f}; - Colors[ImGuiNeoSequencerCol_ZoomBarSliderEnds] = ImVec4{0.59f, 0.59f, 0.59f, 0.90f}; - Colors[ImGuiNeoSequencerCol_ZoomBarSliderEndsHovered] = ImVec4{0.93f, 0.93f, 0.93f, 0.93f}; - - Colors[ImGuiNeoSequencerCol_SelectionBorder] = ImVec4{0.98f, 0.706f, 0.322f, 0.61f}; - Colors[ImGuiNeoSequencerCol_Selection] = ImVec4{0.98f, 0.706f, 0.322f, 0.33f}; - -} diff --git a/source/engine/thirdparty/imgui/imgui_neo_sequencer.h b/source/engine/thirdparty/imgui/imgui_neo_sequencer.h deleted file mode 100644 index 009a23a..0000000 --- a/source/engine/thirdparty/imgui/imgui_neo_sequencer.h +++ /dev/null @@ -1,156 +0,0 @@ -// -// Created by Matty on 2022-01-28. -// - -#ifndef IMGUI_NEO_SEQUENCER_H -#define IMGUI_NEO_SEQUENCER_H - -#include "imgui.h" -#include -#include - -typedef int ImGuiNeoSequencerFlags; -typedef int ImGuiNeoSequencerCol; -typedef int ImGuiNeoTimelineFlags; -typedef int ImGuiNeoTimelineIsSelectedFlags; - -// Flags for ImGui::BeginNeoSequencer() -enum ImGuiNeoSequencerFlags_ -{ - ImGuiNeoSequencerFlags_None = 0 , - ImGuiNeoSequencerFlags_AllowLengthChanging = 1 << 0, // Allows changing length of sequence - ImGuiNeoSequencerFlags_EnableSelection = 1 << 1, // Enables selection of keyframes - ImGuiNeoSequencerFlags_HideZoom = 1 << 2, // Disables zoom bar - //ImGuiNeoSequencerFlags_PH = 1 << 3, // PLACEHOLDER - ImGuiNeoSequencerFlags_AlwaysShowHeader = 1 << 4, // Enables overlay header, keeping it visible when scrolling - - // Selection options, only work with enable selection flag - ImGuiNeoSequencerFlags_Selection_EnableDragging = 1 << 5, - ImGuiNeoSequencerFlags_Selection_EnableDeletion = 1 << 6, - -}; - -// Flags for ImGui::BeginNeoTimeline() -enum ImGuiNeoTimelineFlags_ -{ - ImGuiNeoTimelineFlags_None = 0 , - ImGuiNeoTimelineFlags_AllowFrameChanging = 1 << 0, - ImGuiNeoTimelineFlags_Group = 1 << 1, -}; - -// Flags for ImGui::IsNeoTimelineSelected() -enum ImGuiNeoTimelineIsSelectedFlags_ -{ - ImGuiNeoTimelineIsSelectedFlags_None = 0 , - ImGuiNeoTimelineIsSelectedFlags_NewlySelected = 1 << 0, -}; - -enum ImGuiNeoSequencerCol_ -{ - ImGuiNeoSequencerCol_Bg, - ImGuiNeoSequencerCol_TopBarBg, - ImGuiNeoSequencerCol_SelectedTimeline, - ImGuiNeoSequencerCol_TimelineBorder, - ImGuiNeoSequencerCol_TimelinesBg, - ImGuiNeoSequencerCol_FramePointer, - ImGuiNeoSequencerCol_FramePointerHovered, - ImGuiNeoSequencerCol_FramePointerPressed, - ImGuiNeoSequencerCol_Keyframe, - ImGuiNeoSequencerCol_KeyframeHovered, - ImGuiNeoSequencerCol_KeyframePressed, - ImGuiNeoSequencerCol_KeyframeSelected, - ImGuiNeoSequencerCol_FramePointerLine, - - ImGuiNeoSequencerCol_ZoomBarBg, - ImGuiNeoSequencerCol_ZoomBarSlider, - ImGuiNeoSequencerCol_ZoomBarSliderHovered, - ImGuiNeoSequencerCol_ZoomBarSliderEnds, - ImGuiNeoSequencerCol_ZoomBarSliderEndsHovered, - - ImGuiNeoSequencerCol_SelectionBorder, - ImGuiNeoSequencerCol_Selection, - - ImGuiNeoSequencerCol_COUNT -}; - -struct ImGuiNeoSequencerStyle { - float SequencerRounding = 2.5f; // Corner rounding around whole sequencer - float TopBarHeight = 0.0f; // Value <= 0.0f = Height is calculated by FontSize + FramePadding.y * 2.0f - bool TopBarShowFrameLines = true; // Show line for every frame in top bar - bool TopBarShowFrameTexts = true; // Show frame number every 10th frame - ImVec2 ItemSpacing = {4.0f,0.5f}; - float DepthItemSpacing = 10.0f; // Amount of text offset per depth level in timeline values - float TopBarSpacing = 3.0f; // Space between top bar and timeline - float TimelineBorderSize = 1.0f; - float CurrentFramePointerSize = 7.0f; // Size of pointing arrow above current frame line - float CurrentFrameLineWidth = 1.0f; // Width of line showing current frame over timeline - float ZoomHeightScale = 1.0f; // Scale of Zoom bar, base height is font size - float CollidedKeyframeOffset = 3.5f; // Offset on which colliding keyframes are rendered - - float MaxSizePerTick = 4.0f; // Maximum amount of pixels per tick on timeline (if less pixels is present, ticks are not rendered) - - ImVec4 Colors[ImGuiNeoSequencerCol_COUNT]; - - ImGuiKey ModRemoveKey = ImGuiMod_Ctrl; // Key mod which when held removes selected keyframes from present selection - ImGuiKey ModAddKey = ImGuiMod_Shift; // Key mod which when held adds selected keyframes to present selection - - ImGuiNeoSequencerStyle(); -}; - -namespace ImGui { - typedef int32_t FrameIndexType; - - IMGUI_API const ImVec4& GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol idx); - IMGUI_API ImGuiNeoSequencerStyle& GetNeoSequencerStyle(); - - IMGUI_API void PushNeoSequencerStyleColor(ImGuiNeoSequencerCol idx, ImU32 col); - IMGUI_API void PushNeoSequencerStyleColor(ImGuiNeoSequencerCol idx, const ImVec4& col); - IMGUI_API void PopNeoSequencerStyleColor(int count = 1); - - IMGUI_API bool BeginNeoSequencer(const char* id, FrameIndexType * frame, FrameIndexType * startFrame, FrameIndexType * endFrame,const ImVec2& size = ImVec2(0, 0),ImGuiNeoSequencerFlags flags = ImGuiNeoSequencerFlags_None); - IMGUI_API void EndNeoSequencer(); //Call only when BeginNeoSequencer() returns true!! - - IMGUI_API bool BeginNeoGroup(const char* label, bool* open = nullptr); - IMGUI_API void EndNeoGroup(); - - IMGUI_API bool BeginNeoTimeline(const char* label,FrameIndexType ** keyframes, uint32_t keyframeCount, bool * open = nullptr, ImGuiNeoTimelineFlags flags = ImGuiNeoTimelineFlags_None); - IMGUI_API void EndNeoTimeLine(); //Call only when BeginNeoTimeline() returns true!! - - // Fully customizable timeline with per key callback - IMGUI_API bool BeginNeoTimelineEx(const char* label, bool * open = nullptr, ImGuiNeoTimelineFlags flags = ImGuiNeoTimelineFlags_None); - IMGUI_API void NeoKeyframe(int32_t* value); - - IMGUI_API bool IsNeoKeyframeHovered(); - IMGUI_API bool IsNeoKeyframeSelected(); - IMGUI_API bool IsNeoKeyframeRightClicked(); - - - // Selection API - // DON'T delete keyframes while dragging, internal buffer will get corrupted - // Order for deletion is generally: - // CanDelete? -> DataSize? -> GetData() -> Delete your data -> ClearSelection() - IMGUI_API void NeoClearSelection(); // Clears selection - IMGUI_API bool NeoIsSelecting(); // Are we currently selecting? - IMGUI_API bool NeoHasSelection(); // Is anything selected? - IMGUI_API bool NeoIsDraggingSelection(); // Are we dragging selection? - IMGUI_API bool NeoCanDeleteSelection(); // Can selection deletion be done? - IMGUI_API bool IsNeoKeyframeSelectionRightClicked(); // Is selection rightclicked? - - // Call only in BeginNeoTimeline / EndNeoTimeLine scope, returns selection per timeline and size per timeline - IMGUI_API uint32_t GetNeoKeyframeSelectionSize(); - IMGUI_API void GetNeoKeyframeSelection(FrameIndexType * selection); - - - // Sets currently selected timeline inside BeginNeoSequencer scope - IMGUI_API void SetSelectedTimeline(const char* timelineLabel); - - IMGUI_API bool IsNeoTimelineSelected(ImGuiNeoTimelineIsSelectedFlags flags = ImGuiNeoTimelineIsSelectedFlags_None); - -#ifdef __cplusplus - // C++ helper -// IMGUI_API bool BeginNeoTimeline(const char* label,std::vector & keyframes ,bool * open = nullptr, ImGuiNeoTimelineFlags flags = ImGuiNeoTimelineFlags_None); -#endif -} - - -#endif //IMGUI_NEO_SEQUENCER_H