From e9634a8763fef9c74d2bfeb349e10a43de45c0e1 Mon Sep 17 00:00:00 2001 From: Fox Caminiti Date: Sat, 26 Nov 2022 14:19:30 -0500 Subject: v1 release --- build.bat | 20 +- build.sh | 80 +- createcalls.cpp | 13 +- main.cpp | 304 ++++--- main.h | 10 + my_imgui_widgets.cpp | 2291 ++------------------------------------------------ package.sh | 20 + stable_diffusion.cpp | 2 +- 8 files changed, 347 insertions(+), 2393 deletions(-) create mode 100755 package.sh diff --git a/build.bat b/build.bat index 17eb14e..e212882 100755 --- a/build.bat +++ b/build.bat @@ -5,29 +5,29 @@ set SDL2_DIR=C:\lib\SDL2-2.0.22 set FFMPEG_DIR=C:\lib\ffmpeg-n5.0-latest-win64-lgpl-shared-5.0 REM /Zi /O2 -set OPTIMIZATION=/Zi -set DEBUG=1 +set OPTIMIZATION=/O2 +set DEBUG=0 set IMGUI=0 -set WINDOWS=1 set ARM=0 -set PACKEDRGB=0 set PERF=0 +set STABLE=0 -set INCLUDES=/I.. /Iimgui /I%SDL2_DIR%\include /IC:\lib\glew-2.1.0\include /I%FFMPEG_DIR%\include /Ilib/glad/include +REM /I%FFMPEG_DIR%\include +set INCLUDES=/I.. /Iimgui /I%SDL2_DIR%\include /IC:\lib\glew-2.1.0\include /Ilib/glad/include /Icurl set SDL_LIBS=/LIBPATH:%SDL2_DIR%\lib\x64 SDL2.lib SDL2main.lib opengl32.lib shell32.lib set FFMPEG_LIBS=/LIBPATH:%FFMPEG_DIR%\lib avcodec.lib avfilter.lib avformat.lib swscale.lib avutil.lib set IMGUI_FILES=imgui\backends\imgui_impl_sdl.cpp imgui\backends\imgui_impl_opengl3.cpp imgui\imgui*.cpp set WARNING_FLAGS=/W2 /wd4805 /wd4477 /wd4244 /wd4305 -if %DEBUG%==1 ( set PREPROCESSORS="/DDEBUG=1" ) -if %WINDOWS%==1 ( set PREPROCESSORS=%PREPROCESSORS% "/DWINDOWS=1" ) -if %ARM%==1 ( set PREPROCESSORS=%PREPROCESSORS% "/DARM=1" ) -if %PACKEDRGB%==1 ( set PREPROCESSORS=%PREPROCESSORS% "/DPACKEDRGB=1" ) +set PREPROCESSORS="/DWINDOWS=1" +if %DEBUG%==1 ( set PREPROCESSORS=%PREPROCESSORS% "/DDEBUG=1" ) if %PERF%==1 ( set PREPROCESSORS=%PREPROCESSORS% "/DPERF=1" ) +if %STABLE%==1 ( set PREPROCESSORS=%PREPROCESSORS% "/DSTABLE=1" ) cl /nologo %OPTIMIZATION% /MD /I.. /Iimgui /I%SDL2_DIR%\include my_imgui_internal_widgets.cpp /Fobin/ /c if %IMGUI%==1 ( cl /nologo %OPTIMIZATION% /MD /I.. /Iimgui /I%SDL2_DIR%\include %IMGUI_FILES% /Fobin/ /c ) cl /nologo %OPTIMIZATION% /MD /I.. /Ilib/glad/include lib/glad.c /Fobin/ /c -cl /nologo /Zi /MD %WARNING_FLAGS% %PREPROCESSORS% %INCLUDES% main.cpp bin/*.obj /Febin/real2d.exe /Fobin/ /link %SDL_LIBS% %FFMPEG_LIBS% /subsystem:console +REM /link %SDL_LIBS% %FFMPEG_LIBS% +cl /nologo /Zi /MD %WARNING_FLAGS% %PREPROCESSORS% %INCLUDES% main.cpp bin/*.obj /Febin/real2d.exe /Fobin/ /link %SDL_LIBS% /subsystem:console diff --git a/build.sh b/build.sh index 69bb75d..f4fb702 100755 --- a/build.sh +++ b/build.sh @@ -1,7 +1,5 @@ #!/bin/bash -ARM=0 # Compile on ARM machines. - OPTIMIZATION="-O2" # Enable optimization. DEBUG=0 # Compile with debug UI. IMGUI=1 # Compile ImGui libs. Our custom ImGui functions still compile on zero. @@ -46,43 +44,48 @@ WARNING_FLAGS=" " if [[ "$DEBUG" == 1 ]]; then -WARNING_FLAGS="$WARNING_FLAGS -DDEBUG=1" + WARNING_FLAGS="$WARNING_FLAGS -DDEBUG=1" fi if [[ "$THREADED" == 1 ]]; then -WARNING_FLAGS="$WARNING_FLAGS -DTHREADED=1" -fi -if [[ "$ARM" == 1 ]]; then -WARNING_FLAGS="$WARNING_FLAGS -DARM=1" -ADDITIONAL_FLAGS=" - -march=armv8.5-a+sve -" -else -ADDITIONAL_FLAGS=" - -march=native -" + WARNING_FLAGS="$WARNING_FLAGS -DTHREADED=1" fi if [[ "$PERF" == 1 ]]; then -WARNING_FLAGS="$WARNING_FLAGS -DPERF=1" + WARNING_FLAGS="$WARNING_FLAGS -DPERF=1" fi if [[ "$STABLE" == 1 ]]; then -WARNING_FLAGS="$WARNING_FLAGS -DSTABLE=1" -OPTIONAL_FLAGS="$OPTIONAL_FLAGS -lcurl" + WARNING_FLAGS="$WARNING_FLAGS -DSTABLE=1" + OPTIONAL_FLAGS="$OPTIONAL_FLAGS -lcurl" fi -if [[ "$OSTYPE" =~ ^darwin ]]; then -IMGUI_FLAGS=" - -std=c++11 -Iimgui -Iimgui/backends $OPTIMIZATION -Wall -Wformat `sdl2-config --cflags` -I/usr/local/include -I/opt/local/include -c -" + +if [[ "$(uname -m)" == "x86_64" ]]; then + ARCHNAME="x86" + ADDITIONAL_FLAGS=" + -march=native + " else -IMGUI_FLAGS=" - -Iimgui -Iimgui/backends $OPTIMIZATION -Wall -Wformat `sdl2-config --cflags` -c -" + ARCHNAME="arm" + ADDITIONAL_FLAGS=" + -march=armv8.5-a+sve + " + WARNING_FLAGS="$WARNING_FLAGS -DARM=1" fi - if [[ "$OSTYPE" =~ ^darwin ]]; then - SDL_ARGS="`sdl2-config --cflags` -framework OpenGL -ldl `sdl2-config --libs`" + OSNAME="mac" + IMGUI_FLAGS=" + -std=c++11 -Iimgui -Iimgui/backends $OPTIMIZATION -Wall -Wformat `sdl2-config --cflags` -I/usr/local/include -I/opt/local/include -c + " + SDL_ARGS=" + `sdl2-config --cflags` -framework OpenGL -ldl `sdl2-config --libs` + " else - SDL_ARGS="`sdl2-config --cflags` -lGL -ldl `sdl2-config --libs`" + OSNAME="linux" + IMGUI_FLAGS=" + -Iimgui -Iimgui/backends $OPTIMIZATION -Wall -Wformat `sdl2-config --cflags` -c + " + SDL_ARGS=" + `sdl2-config --cflags` -lGL -ldl `sdl2-config --libs` + " fi GLAD_FLAGS=" @@ -106,10 +109,19 @@ fi clang lib/glad.c $GLAD_FLAGS -I/usr/local/include -I/opt/local/include -c \ $WARNING_FLAGS $OPTIMIZATION $ADDITIONAL_FLAGS -o bin/glad.o -clang main.cpp $WARNING_FLAGS $OPTIMIZATION $ADDITIONAL_FLAGS -o bin/real2d bin/*.o \ - $GLAD_FLAGS \ - -std=c++11 -lstdc++ -Iimgui -Iimgui/backends \ - $SDL_ARGS \ - $OPTIONAL_FLAGS \ - -I . \ - -lm -I /usr/local/include $(pkg-config --cflags --libs $FFMPEG_LIBS) +clang main.cpp $WARNING_FLAGS $OPTIMIZATION $ADDITIONAL_FLAGS -o bin/real2d_"$ARCHNAME"_"$OSNAME" bin/*.o \ + $GLAD_FLAGS \ + -std=c++11 -lstdc++ -Iimgui -Iimgui/backends \ + $SDL_ARGS \ + $OPTIONAL_FLAGS \ + -I . \ + -lm -I /usr/local/include # $(pkg-config --cflags --libs $FFMPEG_LIBS) + + +if [[ "$OSTYPE" =~ ^darwin ]]; then +mv bin/real2d_"$ARCHNAME"_"$OSNAME" lib/mac_app_template/Contents/MacOS/real +mkdir bin/real_"$ARCHNAME".app +cp -r lib/mac_app_template/Contents bin/real_"$ARCHNAME".app +xattr -cr bin/real_"$ARCHNAME".app +dylibbundler -od -b -x bin/real_"$ARCHNAME".app/Contents/MacOS/real -d bin/real_"$ARCHNAME".app/Contents/libs +fi diff --git a/createcalls.cpp b/createcalls.cpp index d3da841..1eac4cc 100644 --- a/createcalls.cpp +++ b/createcalls.cpp @@ -91,11 +91,12 @@ File_Open(project_data *File, project_state *State, memory *Memory, char *Filena File->Source_Count--; } } + String_Copy(State->Filename, State->DummyName, 512); return 1; } static bool32 -File_SaveAs(project_data *File, project_state *State, memory *Memory, char *Filename) +IO_Save(project_data *File, project_state *State, memory *Memory, char *Filename) { SDL_RWops *TestFile = SDL_RWFromFile(Filename, "wb"); @@ -132,6 +133,16 @@ File_SaveAs(project_data *File, project_state *State, memory *Memory, char *File return 1; } +static void +File_SaveAs(project_data *File, project_state *State, memory *Memory, char *Filename) +{ + if (IO_Save(File, State, Memory, State->Filename)) { + PostMsg(State, "File saved!"); + } else { + PostMsg(State, "File save failed..."); + } +} + static void Playhead_Increment(int32 *Frame_Current, int32 Frame_Start, int32 Frame_End, int32 Increment) { diff --git a/main.cpp b/main.cpp index 10e74ec..83d3dcb 100644 --- a/main.cpp +++ b/main.cpp @@ -18,11 +18,7 @@ #include "imgui/imgui.h" #include "imgui/backends/imgui_impl_sdl.h" #include "imgui/backends/imgui_impl_opengl3.h" -#if WINDOWS #include -#else -#include -#endif #if defined(IMGUI_IMPL_OPENGL_ES2) #include #else @@ -94,12 +90,6 @@ static uint32 RandomGlobalIncrement = 0; #include "effects_gl_shader.cpp" #include "effects.cpp" #include "effects_constructors.cpp" -#if 0 -#include "keyframes.cpp" -#include "layer.cpp" -#include "bitmap_calls.cpp" -#endif - static void Main_RenderUI(ImGuiIO io, ImVec4 clear_color, SDL_Window *window) @@ -178,114 +168,26 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, ui *UI, ImGui::DockSpaceOverViewport(); +#if DEBUG if (Debug.ToggleWindow) { ImGui::ShowDemoWindow(); ImGui_DebugMemoryViewer(Memory, State); ImGui_DebugUndoTree(Memory, State); } - - if (State->Initializing == 3) { - Source_UICreateButton(File, State, Memory, Sorted.CompArray, Sorted.LayerArray); - block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, 0); - Layer->IsSelected = true; - // Layer->Block_Effect_Index[0] = Effect_Init(State, Memory, 0, Layer->Block_Effect_Count); - // Layer->Block_Effect_Count = 1; - } - // if (State->Initializing == 2) { - // block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex); - // Precomp_UICreateButton(File, State, Memory, MainComp, *Sorted.CompArray, Sorted.LayerArray); - // } -#if 0 - // Layera->x.IsToggled = true; - // Layera->y.IsToggled = true; - // block_layer *Layerb = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, 1); - // Layerb->x.IsToggled = true; - // Layerb->y.IsToggled = true; - // block_layer *Layerc = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, 0); - // Layerc->x.IsToggled = true; - // Layerc->y.IsToggled = true; - // Layer_Select(Memory, State, 0); - // Layer_Select(Memory, State, 1); - // Layer_Select(Memory, State, 2); - } - if (State->Initializing == 2) { - // block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex); - // Precomp_UICreateButton(File, State, Memory, MainComp, *Sorted.CompArray, Sorted.LayerArray); - // Layer_DeselectAll(Memory, State, File->Layer_Count); - - block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, 0); - block_layer *Layer2 = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, 1); - block_layer *Layer3 = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, 2); - Layer_Select(Memory, State, 0); - // History_Entry_Commit(Memory, "Add keyframe"); - property_channel *Property = &Layer->x; - Layer->scale.CurrentValue = 0.3; - Layer2->scale.CurrentValue = 0.3; - Layer3->scale.CurrentValue = 0.3; - /* - State->UpdateFrame = true; - { - bezier_point Point = { 1, {1, 0, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 }; - Bezier_Add(Memory, Property, Point); - } - { - bezier_point Point = { 1, {10, 300, -3, 0, 3, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 }; - Bezier_Add(Memory, Property, Point); - } - { - bezier_point Point = { 1, {20, 300, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 }; - Bezier_Add(Memory, Property, Point); - } - History_Entry_End(Memory); - Property = &Layer->y; - { - bezier_point Point = { 1, {10, 50, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 }; - Bezier_Add(Memory, Property, Point); - } - { - bezier_point Point = { 1, {0, -800, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 }; - Bezier_Add(Memory, Property, Point); - } - { - bezier_point Point = { 1, {20, 400, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 }; - Bezier_Add(Memory, Property, Point); - } - Property = &Layer->rotation; - { - bezier_point Point = { 1, {0, 0, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 }; - Bezier_Add(Memory, Property, Point); - } - { - bezier_point Point = { 1, {20, -360, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 }; - Bezier_Add(Memory, Property, Point); - } - { - bezier_point Point = { 1, {40, 360, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 }; - Bezier_Add(Memory, Property, Point); - } - Property = &Layer->opacity; - { - bezier_point Point = { 1, {0, 1, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 }; - Bezier_Add(Memory, Property, Point); - } - { - bezier_point Point = { 1, {35, 0, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 }; - Bezier_Add(Memory, Property, Point); - } - History_Entry_End(Memory); - */ - } #endif + ImGui_Popups(File, State, UI, Memory, io); ImGui_Viewport(File, State, UI, Memory, io, textureID, Sorted.CompArray, Sorted.LayerArray); ImGui_Timeline(File, State, Memory, UI, io, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyInfo, Sorted.PropertyArray); ImGui_File(File, State, Memory, io, Sorted.CompArray, Sorted.LayerArray); ImGui_PropertiesPanel(File, State, UI, Memory, io); ImGui_ColorPanel(File, State, UI, Memory, io); - ImGui_EffectsPanel(File, State, Memory, UI, io); + // ImGui_EffectsPanel(File, State, Memory, UI, io); #if STABLE - ImGui_SD_Prompt(File, State, UI, Memory, io, Sorted.CompArray, Sorted.LayerArray); - ImGui_SD_Thumbnail(File, State, UI, Memory, io, Sorted.CompArray, Sorted.LayerArray, Sorted.SourceArray, Sorted.TempSourceCount); + if (State->StableEnabled) { + ImGui_SD_Prompt(File, State, UI, Memory, io, Sorted.CompArray, Sorted.LayerArray); + ImGui_SD_Thumbnail(File, State, UI, Memory, io, Sorted.CompArray, Sorted.LayerArray, Sorted.SourceArray, Sorted.TempSourceCount); + } #endif ImGui_Menu(File, State, UI, Memory, io); @@ -444,7 +346,7 @@ Render_Comp(project_data *File, project_state *State, memory *Memory, ImGuiIO io uint64 ScratchSize = Width * Height * BytesPerPixel; RenderAddress = Memory_PushScratch(Memory, ScratchSize); - // Memory_Copy((uint8 *)RenderAddress, (uint8 *)BitmapAddress, ScratchSize); + Memory_Copy((uint8 *)RenderAddress, (uint8 *)BitmapAddress, ScratchSize); if (State->Interact_Active == interact_type_brush && State->Brush.LayerToPaint_Index == Index_Physical) { // TODO(fox): Do all these extra precomputes really make a difference in the renderer? @@ -460,7 +362,7 @@ Render_Comp(project_data *File, project_state *State, memory *Memory, ImGuiIO io Assert(Width); Assert(Height); transform_info T = Transform_Calculate(State, Memory, File, Layer, Comp, Width, Height, BytesPerPixel); - T.SourceBuffer = BitmapAddress; + T.SourceBuffer = RenderAddress; rectangle RenderRegion = {0, 0, Comp->Width, Comp->Height}; Render_Main((void *)&T, CompBuffer, render_type_main, RenderRegion); @@ -472,6 +374,173 @@ Render_Comp(project_data *File, project_state *State, memory *Memory, ImGuiIO io return CompBuffer; } +static char ImGuiPrefs[] = "[Window][DockSpaceViewport_11111111]\n" +"Pos=0,0\n" +"Size=2133,1333\n" +"Collapsed=0\n" +"\n" +"[Window][Debug##Default]\n" +"Pos=122,442\n" +"Size=400,400\n" +"Collapsed=0\n" +"\n" +"[Window][Viewport]\n" +"Pos=443,34\n" +"Size=1165,738\n" +"Collapsed=0\n" +"DockId=0x00000010,0\n" +"\n" +"[Window][###Properties]\n" +"Pos=0,34\n" +"Size=441,738\n" +"Collapsed=0\n" +"DockId=0x0000000B,0\n" +"\n" +"[Window][Timeline]\n" +"Pos=0,774\n" +"Size=2133,559\n" +"Collapsed=0\n" +"DockId=0x0000000A,0\n" +"\n" +"[Window][Dear ImGui Demo]\n" +"Pos=1610,34\n" +"Size=523,267\n" +"Collapsed=0\n" +"DockId=0x00000011,1\n" +"\n" +"[Window][Files]\n" +"Pos=1610,303\n" +"Size=523,469\n" +"Collapsed=0\n" +"DockId=0x00000007,0\n" +"\n" +"[Window][Effects list]\n" +"Pos=2677,1047\n" +"Size=523,192\n" +"Collapsed=0\n" +"DockId=0x00000008,0\n" +"\n" +"[Window][Graph editor]\n" +"Pos=0,949\n" +"Size=3200,526\n" +"Collapsed=0\n" +"DockId=0x00000009,0\n" +"\n" +"[Window][undotree]\n" +"Pos=2114,80\n" +"Size=256,565\n" +"Collapsed=0\n" +"\n" +"[Window][memoryviewer]\n" +"Pos=50,273\n" +"Size=800,200\n" +"Collapsed=0\n" +"\n" +"[Window][Example: Custom rendering]\n" +"Pos=758,789\n" +"Size=485,414\n" +"Collapsed=0\n" +"\n" +"[Window][Memory viewer]\n" +"Pos=1610,303\n" +"Size=523,469\n" +"Collapsed=0\n" +"DockId=0x00000007,1\n" +"\n" +"[Window][Graph info]\n" +"Pos=2838,1265\n" +"Size=235,353\n" +"Collapsed=0\n" +"\n" +"[Window][Properties]\n" +"Pos=0,34\n" +"Size=495,1056\n" +"Collapsed=0\n" +"DockId=0x0000000F,0\n" +"\n" +"[Window][Colors]\n" +"Pos=1610,34\n" +"Size=523,267\n" +"Collapsed=0\n" +"DockId=0x00000011,0\n" +"\n" +"[Window][Menu]\n" +"Pos=0,0\n" +"Size=2133,32\n" +"Collapsed=0\n" +"DockId=0x0000000D,0\n" +"\n" +"[Window][Stable Diffusion]\n" +"Pos=2206,684\n" +"Size=421,462\n" +"Collapsed=0\n" +"\n" +"[Window][SD prompt input]\n" +"Pos=2677,473\n" +"Size=523,541\n" +"Collapsed=0\n" +"DockId=0x00000007,2\n" +"\n" +"[Window][Example: Console]\n" +"Pos=747,851\n" +"Size=520,600\n" +"Collapsed=0\n" +"\n" +"[Window][SD gallery]\n" +"Pos=0,718\n" +"Size=441,557\n" +"Collapsed=0\n" +"DockId=0x0000000C,0\n" +"\n" +"[Window][Save as]\n" +"Pos=300,800\n" +"Size=300,300\n" +"Collapsed=0\n" +"\n" +"[Table][0x861D378E,3]\n" +"Column 0 Weight=1.0000\n" +"Column 1 Weight=1.0000\n" +"Column 2 Weight=1.0000\n" +"\n" +"[Table][0x1F146634,3]\n" +"RefScale=13\n" +"Column 0 Width=63\n" +"Column 1 Width=63\n" +"Column 2 Width=63\n" +"\n" +"[Table][0x64418101,3]\n" +"RefScale=13\n" +"Column 0 Width=63\n" +"Column 1 Width=63\n" +"Column 2 Width=63\n" +"\n" +"[Table][0xC9935533,3]\n" +"Column 0 Weight=1.0000\n" +"Column 1 Weight=1.0000\n" +"Column 2 Weight=1.0000\n" +"\n" +"[Docking][Data]\n" +"DockSpace ID=0x8B93E3BD Window=0xA787BDB4 Pos=0,0 Size=2133,1333 Split=Y Selected=0x13926F0B\n" +" DockNode ID=0x0000000D Parent=0x8B93E3BD SizeRef=3200,32 HiddenTabBar=1 Selected=0xA57AB2C6\n" +" DockNode ID=0x0000000E Parent=0x8B93E3BD SizeRef=3200,1299 Split=Y\n" +" DockNode ID=0x00000001 Parent=0x0000000E SizeRef=3200,1205 Split=X Selected=0x13926F0B\n" +" DockNode ID=0x00000003 Parent=0x00000001 SizeRef=441,1171 Split=Y Selected=0xDBB8CEFA\n" +" DockNode ID=0x0000000B Parent=0x00000003 SizeRef=521,425 Selected=0xDBB8CEFA\n" +" DockNode ID=0x0000000C Parent=0x00000003 SizeRef=521,347 Selected=0x56290987\n" +" DockNode ID=0x00000004 Parent=0x00000001 SizeRef=1690,1171 Split=X Selected=0x13926F0B\n" +" DockNode ID=0x00000005 Parent=0x00000004 SizeRef=1165,1171 Split=X Selected=0x13926F0B\n" +" DockNode ID=0x0000000F Parent=0x00000005 SizeRef=495,856 Selected=0x199AB496\n" +" DockNode ID=0x00000010 Parent=0x00000005 SizeRef=2199,856 CentralNode=1 Selected=0x13926F0B\n" +" DockNode ID=0x00000006 Parent=0x00000004 SizeRef=523,1171 Split=Y Selected=0x86FA2F90\n" +" DockNode ID=0x00000011 Parent=0x00000006 SizeRef=483,437 Selected=0xBF7DFDC9\n" +" DockNode ID=0x00000012 Parent=0x00000006 SizeRef=483,766 Split=Y Selected=0x59A2A092\n" +" DockNode ID=0x00000007 Parent=0x00000012 SizeRef=523,572 Selected=0x86FA2F90\n" +" DockNode ID=0x00000008 Parent=0x00000012 SizeRef=523,192 Selected=0x812F222D\n" +" DockNode ID=0x00000002 Parent=0x0000000E SizeRef=3200,559 Split=Y Selected=0x0F18B61B\n" +" DockNode ID=0x00000009 Parent=0x00000002 SizeRef=3250,526 Selected=0xA1F22F4D\n" +" DockNode ID=0x0000000A Parent=0x00000002 SizeRef=3250,323 HiddenTabBar=1 Selected=0x0F18B61B\n" +"\n"; + static void Main_Renderer(project_data *File, project_state *State, memory *Memory, SDL_Window *window, GLuint textureID, ImGuiIO io) { @@ -593,23 +662,9 @@ int main(int argc, char *argv[]) { File->Comp_Count = 1; - { - uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/a_small.jpg"); - block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, File->Source_Count - 1); - Source->IsSelected = true; - } #if 0 - const char *myb[] = { "../asset/hand/IMG_4239.jpg", "../asset/hand/IMG_4242.jpg", "../asset/hand/IMG_4243.jpg", - "../asset/hand/IMG_4244.jpg", "../asset/hand/IMG_4248.jpg", "../asset/hand/IMG_4249.jpg" }; - - for (int i = 0; i < 6; i++) { - uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)myb[i]); - block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, File->Source_Count - 1); - Source->IsSelected = true; - } - { - uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/hand/c.png"); + uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/a_small.jpg"); block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, File->Source_Count - 1); Source->IsSelected = true; } @@ -703,8 +758,8 @@ int main(int argc, char *argv[]) { // I'm loading the window positions from this convenient tool. ImGui by // default saves window position to an external .ini file, which can be // loaded from disk or memory. - // io.IniFilename = NULL; - // ImGui::LoadIniSettingsFromMemory(ImGuiPrefs); + io.IniFilename = NULL; + ImGui::LoadIniSettingsFromMemory(ImGuiPrefs); ImGui::StyleColorsDark(); @@ -722,7 +777,6 @@ int main(int argc, char *argv[]) { Brush_CalcBitmapAlphaFromSize(&Memory, &State->Brush, 4); State_BindBrushTexture(&Memory, &State->Brush, 4); - #if STABLE curl_global_init(CURL_GLOBAL_ALL); curl_state MainHandle = {}; diff --git a/main.h b/main.h index f55e6fc..b4f5cb5 100644 --- a/main.h +++ b/main.h @@ -368,6 +368,12 @@ struct header_effect uint32 GLShaderIndex; }; +enum imgui_popups +{ + popup_none, + popup_saveas +}; + struct project_state { bool32 UpdateKeyframes = 0; @@ -383,6 +389,7 @@ struct project_state brush_state Brush; #if STABLE + bool32 StableEnabled = 0; sd_state SD; char JSONPayload[1024*1024*4]; int32 CurlActive = 0; @@ -427,6 +434,9 @@ struct project_state int32 MsgTime; // currently in "frames" char *Msg; + imgui_popups ImGuiPopups; + char Filename[512]; + ImGuiTextFilter filter; // This filter API is pretty ballin'. bool32 RerouteEffects; // Allows shift+space hotkey to gain focus on the effects panel. }; diff --git a/my_imgui_widgets.cpp b/my_imgui_widgets.cpp index 5bc78bd..c8971c2 100644 --- a/my_imgui_widgets.cpp +++ b/my_imgui_widgets.cpp @@ -420,11 +420,11 @@ ImGui_SD_Prompt(project_data *File, project_state *State, ui *UI, memory *Memory Source->Width, Source->Height, Source->BytesPerPixel, &len); Assert(PNGBitmap); - uint64 EncodedEstimateSize = base64_encode_size(Size); + uint64 EncodedEstimateSize = base64_encode_size((size_t)Size); uint8 *EncodedOutput = (uint8 *)Memory_PushScratch(Memory, EncodedEstimateSize); uint64 EncodedTrueSize = 0; - base64_encode((uint8 *)PNGBitmap, len, EncodedOutput, &EncodedTrueSize); + base64_encode((uint8 *)PNGBitmap, len, EncodedOutput, (size_t *)&EncodedTrueSize); Assert(EncodedOutput[EncodedTrueSize] == '\0'); // printf("%s", EncodedOutput); @@ -1700,7 +1700,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem State->Interact_Offset[0] = (DragDelta.x / TimelineSizeWithBorder.x * UI->TimelinePercentZoomed.x) * Comp->Frame_Count; State->Interact_Offset[1] = b; - DebugWatchVar("Offset1", &State->Interact_Offset[0], d_float); + // DebugWatchVar("Offset1", &State->Interact_Offset[0], d_float); } } if (ImGui::IsItemDeactivated()) { @@ -1988,7 +1988,7 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, ImVec2 TimelineZoomSize = TimelineSizeWithBorder / UI->TimelinePercentZoomed; ImVec2 TimelineMoveSize = TimelineSizeWithBorder * UI->TimelinePercentOffset / UI->TimelinePercentZoomed; - DebugWatchVar("TimelineY: ", &TimelineMoveSize.y, d_float); + // DebugWatchVar("TimelineY: ", &TimelineMoveSize.y, d_float); ImVec2 Increment = ImVec2((real32)1 / MainComp->Frame_Count, (real32)1 / LayerIncrement); @@ -2008,12 +2008,12 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, ImVec2 ZoomDifference = (UI->TimelinePercentZoomed / UI->GraphZoomSize); ImVec2 MoveDifference = (UI->TimelinePercentOffset + (UI->GraphMoveSize)); - DebugWatchVar("zoomdif: ", &ZoomDifference.y, d_float); - DebugWatchVar("movedif: ", &MoveDifference.y, d_float); + // DebugWatchVar("zoomdif: ", &ZoomDifference.y, d_float); + // DebugWatchVar("movedif: ", &MoveDifference.y, d_float); ImVec2 GraphZoomSize = TimelineSizeWithBorder / ZoomDifference; ImVec2 GraphMoveSize = TimelineSizeWithBorder * (MoveDifference) / UI->TimelinePercentZoomed; - DebugWatchVar("zoomsize: ", &GraphZoomSize.y, d_float); - DebugWatchVar("movesize: ", &GraphMoveSize.y, d_float); + // DebugWatchVar("zoomsize: ", &GraphZoomSize.y, d_float); + // DebugWatchVar("movesize: ", &GraphMoveSize.y, d_float); draw_list->AddRectFilled(WindowMinAbs, WindowMaxAbs, IM_COL32(50, 50, 50, 230)); @@ -2247,6 +2247,42 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, ImGui::End(); } +static void +ImGui_Popups(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io) +{ + switch (State->ImGuiPopups) + { + case popup_none: + { + } break; + case popup_saveas: + { + ImGui::OpenPopup("Save as"); + ImGui::SetNextWindowPos(ImVec2(300, 800)); + ImGui::SetNextWindowSize(ImVec2(300, 300)); + ImGui::SetKeyboardFocusHere(); + } break; + default: + { + Assert(0); + } + } + State->ImGuiPopups = popup_none; + + if (ImGui::BeginPopupModal("Save as")) { + ImGui::Text("Destination path..."); + ImGui::InputText("File", State->Filename, 512); + if (ImGui::Button("Save file")) { + ImGui::Text("Saving..."); + File_SaveAs(File, State, Memory, State->Filename); + ImGui::CloseCurrentPopup(); + } + if (ImGui::IsKeyPressed(ImGuiKey_Escape)) { + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } +} static void ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io) @@ -2409,7 +2445,15 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me bool32 mod_key = io.ConfigMacOSXBehaviors ? io.KeySuper : io.KeyCtrl; if (mod_key) { if (ImGui::IsKeyPressed(ImGuiKey_S)) { - File_SaveAs(File, State, Memory, "test"); + if (io.KeyShift) { + State->ImGuiPopups = popup_saveas; + } else { + if (State->Filename[0] == '\0') { + State->ImGuiPopups = popup_saveas; + } else { + File_SaveAs(File, State, Memory, State->Filename); + } + } } if (ImGui::IsKeyPressed(ImGuiKey_C)) { State->HotkeyInput = hotkey_copy; @@ -2427,31 +2471,6 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me } } } - - /* - if (ImGui::IsKeyPressed(ImGuiKey_S)) { - if (io.KeyShift) { - State->ImGuiPopups = popup_saveas; - } else { - if (State->Context[0].Filename[0] == '\0') { - State->ImGuiPopups = popup_saveas; - } else { - if (File_SaveAs(State, Memory, 0, State->Context[0].Filename)) { - PostMsg(State, "File saved!"); - } else { - PostMsg(State, "File save failed..."); - } - } - } - } - if (ImGui::IsKeyPressed(ImGuiKey_N)) { - if (io.KeyShift) - State->ImGuiPopups = popup_newfile; - else - State->ImGuiPopups = popup_newlayer; - } - */ - } static void @@ -2465,12 +2484,14 @@ ImGui_Menu(project_data *File, project_state *State, ui *UI, memory *Memory, ImG { if (ImGui::MenuItem("Save", "Ctrl+S")) { - // if (File_SaveAs(State, Memory, 0, State->Context[0].Filename)) { - if (0) { - PostMsg(State, "File saved!"); - } else { - PostMsg(State, "File save failed..."); - } + if (State->Filename[0] == '\0') + State->ImGuiPopups = popup_saveas; + else + File_SaveAs(File, State, Memory, State->Filename); + } + if (ImGui::MenuItem("Save as", "Ctrl+Shift+S")) + { + State->ImGuiPopups = popup_saveas; } if (ImGui::BeginMenu("Open file")) { @@ -2484,16 +2505,6 @@ ImGui_Menu(project_data *File, project_state *State, ui *UI, memory *Memory, ImG } ImGui::EndMenu(); } - /* - if (ImGui::MenuItem("New project file", "Ctrl+Shift+N")) - { - State->ImGuiPopups = popup_newfile; - } - if (ImGui::MenuItem("Save as", "Ctrl+Shift+S")) - { - State->ImGuiPopups = popup_saveas; - } - */ ImGui::EndMenu(); } if (ImGui::BeginMenu("Layer")) @@ -2507,36 +2518,16 @@ ImGui_Menu(project_data *File, project_state *State, ui *UI, memory *Memory, ImG } ImGui::EndMenu(); } - /* - if (ImGui::MenuItem("New layer", "Ctrl+N")) - { - State->ImGuiPopups = popup_newlayer; - } - if (ImGui::BeginMenu("Layer from image path")) - { - ImGui::InputText("Path to image", State->DummyName2, 512); - if (ImGui::IsItemDeactivated() && ImGui::IsKeyPressed(ImGuiKey_Enter)) { - Layer_CreateFromFile(State, Memory, Index, State->DummyName2); - Layer_DeselectAll(State, File, &Context->UI); - layer_sorted Sorts = Layer_GetSortedList(State, File); - file_layer *Layer = (file_layer *)Sorts.Location[File->NumberOfLayers - 1]; - Layer_Select(Layer, &Context->UI, File->NumberOfLayers - 1); - State->Context[Index].UpdateFrame = true; - } - ImGui::EndMenu(); - } - if (ImGui::MenuItem("New adjustment layer", "Ctrl+Shift+Y")) - { - Layer_CreateAdjustment(State, Memory, Index); - } - if (ImGui::MenuItem("Duplicate layer", "Ctrl+Shift+Y")) - { - if (State->Context[Index].UI.MostRecentlySelectedLayer > -1) - Layer_Duplicate(State, Memory, Index, State->Context[Index].UI.MostRecentlySelectedLayer); - } - */ ImGui::EndMenu(); } + if (ImGui::BeginMenu("Window")) + { +#if STABLE + if (ImGui::Selectable("Stable Diffusion tools", State->StableEnabled)) + State->StableEnabled ^= 1; + ImGui::EndMenu(); +#endif + } ImGui::EndMenuBar(); } @@ -2601,2147 +2592,3 @@ ImGui_EffectsPanel(project_data *File, project_state *State, memory *Memory, ui } ImGui::End(); } - - - -#if 0 - real32 MaxVal_Y = -10000; - real32 MinVal_Y = 10000; - for (int b = 0; b < Property->NumberOfTotalKeyframes; b++) { - keyframe *Keyframe = KeyframeLookup(Property, b); - MaxVal_Y = (Keyframe->Value.f > MaxVal_Y) ? Keyframe->Value.f : MaxVal_Y; - MinVal_Y = (Keyframe->Value.f < MinVal_Y) ? Keyframe->Value.f : MinVal_Y; - } - - keyframe *FirstKeyframe = KeyframeLookup(Property, 0); - keyframe *LastKeyframe = KeyframeLookup(Property, Property->NumberOfTotalKeyframes - 1); - real32 MinVal_X = (Layer->BitmapInfo.FrameOffset + FirstKeyframe->FrameNumber); - real32 MaxVal_X = (Layer->BitmapInfo.FrameOffset + LastKeyframe->FrameNumber); - - UI->Y_MaxVal = MaxVal_Y; - UI->Y_MinVal = MinVal_Y; - - if (!UI->IsDragging) { - UI->Display_Y_MinVal = UI->Y_MinVal; - UI->Display_Y_MaxVal = UI->Y_MaxVal; - } - - real32 Y_TimelinePercentZoomed = UI->Y_TimelinePercentZoomed; - real32 Y_TimelinePercentOffset = UI->Y_TimelinePercentOffset; - MaxVal_Y = UI->Display_Y_MaxVal; - MinVal_Y = UI->Display_Y_MinVal; - - DebugWatchVar("offset: ", &Y_TimelinePercentOffset, d_float); - DebugWatchVar("zoom: ", &Y_TimelinePercentZoomed, d_float); - - real32 Ratio_Graph_X = (MaxVal_X - MinVal_X) / File->NumberOfFrames; - real32 TimelineZoomSize = TimelineSizeWithBorder.x / UI->TimelinePercentZoomed; - real32 TimelineMoveSize = TimelineSizeWithBorder.x * UI->TimelinePercentOffset / UI->TimelinePercentZoomed; - real32 Y_TimelineZoomSize = TimelineSizeWithBorder.y / Y_TimelinePercentZoomed; - real32 Y_TimelineMoveSize = TimelineSizeWithBorder.y * Y_TimelinePercentOffset / Y_TimelinePercentZoomed; - - for (int b = 0; b < Property->NumberOfTotalKeyframes; b++) { - ImGui::PushID(b); - - keyframe *Keyframe = KeyframeLookup(Property, b); - // Only used for drawing the bezier. - keyframe *NextKeyframe = (b != Property->NumberOfTotalKeyframes - 1) ? KeyframeLookup(Property, b + 1) : NULL; - - real32 Increment_X = (real32)1 / File->NumberOfFrames; - real32 UI_FrameDistance = Increment_X*TimelineZoomSize; - - int32 Keyframe_X = (Layer->BitmapInfo.FrameOffset + Keyframe->FrameNumber); - real32 Keyframe_Y = Keyframe->Value.f; - - real32 Ratio_X_Mid = (real32)Keyframe_X / File->NumberOfFrames; - real32 Ratio_Y_Mid = (Keyframe_Y - MinVal_Y) / (MaxVal_Y - MinVal_Y); - - ImVec2 KeyframePos_Mid = ImVec2(TimelineAbsolutePos.x + TimelineMoveSize + Ratio_X_Mid*TimelineZoomSize, - TimelineAbsolutePos.y + Y_TimelineMoveSize + (1.0f - Ratio_Y_Mid)*Y_TimelineZoomSize); - - ImGui::SetCursorScreenPos(KeyframePos_Mid); - ImGui::Button("##keyframe", ImVec2(FontHeight, FontHeight)); - - if (ImGui::IsItemHovered() && ImGui::IsKeyPressed(ImGuiKey_R)) { - UI->TempVal = Keyframe->Value.f; - UI->TempVal_X = Keyframe->FrameNumber; - } - - if (ImGui::IsItemActivated()) { - UI->IsDragging = true; - UI->TempVal = Keyframe->Value.f; - UI->TempVal_X = Keyframe->FrameNumber; - } - - if ((ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1))) - { - ImVec2 DragDelta = ImGui::GetMouseDragDelta(); - DragDelta = DragDelta + (ImVec2(UI->Wrap_X, UI->Wrap_Y) * TimelineSize); - DebugWatchVar("DragX", &DragDelta.x, d_float); - DebugWatchVar("DragY", &DragDelta.y, d_float); - DebugWatchVar("Wrap_X", &UI->Wrap_X, d_int); - DebugWatchVar("Wrap_Y", &UI->Wrap_Y, d_int); - real32 MouseDeltaRatio = -DragDelta.y / TimelineSizeWithBorder.y * Y_TimelinePercentZoomed; - ImVec2 Increment = ImVec2(DragDelta.x / UI_FrameDistance, ((MaxVal_Y - MinVal_Y) * MouseDeltaRatio)); - - // The plus 0.5 * X_Direction is for making the frame jump happen - // when the cursor is between two frames rather than when passing one. - real32 X_Direction = (Increment.x > 0) ? fabsf(Increment.x) / Increment.x : 0; - - Keyframe->FrameNumber = UI->TempVal_X + (int32)(Increment.x + 0.5*X_Direction); - Keyframe->Value.f = UI->TempVal + Increment.y; - - if (io.KeyShift) { - bool32 RestrainAxis = (fabsf(DragDelta.x) > fabsf(DragDelta.y)); - if (RestrainAxis) { - Keyframe->Value.f = UI->TempVal; - } else { - Keyframe->FrameNumber = UI->TempVal_X; - } - } - ImGui_WrapMouse(UI, io.MousePos, TimelineAbsolutePos, TimelineAbsolutePos + TimelineSizeWithBorder); - } - - // TODO(fox): This is kind of a mess. I built the graph around the - // ratios of the keyframes/timeline to make the bars straightforward, - // meaning the position/offset have to be transformed into a new space - // when a new min/max value is reached. - - if (ImGui::IsItemDeactivated()) { - if ((UI->TempVal >= MaxVal_Y) || Keyframe->Value.f == UI->Y_MaxVal) { - real32 Min = ((Ratio_Y_Mid <= 0.0f) && (UI->TempVal >= MaxVal_Y)) ? MinVal_Y : UI->Y_MinVal; - real32 RealRatio_Y = (UI->Y_MaxVal - UI->Y_MinVal) / (MaxVal_Y - MinVal_Y); - UI->Y_TimelinePercentZoomed = UI->Y_TimelinePercentZoomed / RealRatio_Y; - UI->Y_TimelinePercentOffset = (1.0f/RealRatio_Y + UI->Y_TimelinePercentOffset/RealRatio_Y - 1.0f); - } else if (UI->TempVal <= MinVal_Y || Keyframe->Value.f == UI->Y_MinVal) { - real32 RealRatio_Y = (UI->Y_MinVal - MinVal_Y) / (MaxVal_Y - MinVal_Y); - UI->Y_TimelinePercentOffset = UI->Y_TimelinePercentOffset / (1 - RealRatio_Y); - UI->Y_TimelinePercentZoomed = UI->Y_TimelinePercentZoomed / (1 - RealRatio_Y); - } - UI->IsDragging = false; - UI->Wrap_X = 0; - UI->Wrap_Y = 0; - } - - ImU32 col = ImGui::GetColorU32(ImGuiCol_ScrollbarGrab); - - ImVec2 Handle_Pos[2] = {}; - - if (Keyframe->Type == bezier) { - ImVec2 Handle_Ratio[2] = {}; - - Handle_Ratio[0] = ImVec2((real32)(Keyframe_X + Keyframe->TangentLeft.x) / File->NumberOfFrames, - (Keyframe_Y + Keyframe->TangentLeft.y - MinVal_Y) / (MaxVal_Y - MinVal_Y)); - Handle_Ratio[1] = ImVec2((real32)(Keyframe_X + Keyframe->TangentRight.x) / File->NumberOfFrames, - (Keyframe_Y + Keyframe->TangentRight.y - MinVal_Y) / (MaxVal_Y - MinVal_Y)); - - Handle_Pos[0] = ImVec2(TimelineAbsolutePos.x + TimelineMoveSize + Handle_Ratio[0].x*TimelineZoomSize, - TimelineAbsolutePos.y + Y_TimelineMoveSize + (1.0f - Handle_Ratio[0].y)*Y_TimelineZoomSize); - Handle_Pos[1] = ImVec2(TimelineAbsolutePos.x + TimelineMoveSize + Handle_Ratio[1].x*TimelineZoomSize, - TimelineAbsolutePos.y + Y_TimelineMoveSize + (1.0f - Handle_Ratio[1].y)*Y_TimelineZoomSize); - - draw_list->AddLine(KeyframePos_Mid, Handle_Pos[0], col, 1.0f); - draw_list->AddLine(KeyframePos_Mid, Handle_Pos[1], col, 1.0f); - - for (int i = 0; i < 2; i++) { - ImGui::SetCursorScreenPos(Handle_Pos[i]); - ImGui::Button((i == 0) ? "##keyframe_left" : "##keyframe_right", ImVec2(FontHeight, FontHeight)); - v2 *Tangent = (i == 0) ? &Keyframe->TangentLeft : &Keyframe->TangentRight; - - if (ImGui::IsItemActivated()) { - UI->IsDragging = true; - UI->TempVal_X = Tangent->x; - UI->TempVal = Tangent->y; - } - - if ((ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1))) - { - ImVec2 DragDelta = ImGui::GetMouseDragDelta(); - DragDelta = DragDelta + (ImVec2(UI->Wrap_X, UI->Wrap_Y) * TimelineSize); - ImVec2 MouseDeltaRatio = (ImVec2(1, -1) * DragDelta) / TimelineSizeWithBorder * ImVec2(UI->TimelinePercentZoomed / Ratio_Graph_X, Y_TimelinePercentZoomed); - real32 NewPos_X = ((MaxVal_X - MinVal_X) * MouseDeltaRatio.x); - real32 NewPos_Y = (io.KeyShift) ? 0 : ((MaxVal_Y - MinVal_Y) * MouseDeltaRatio.y); - *Tangent = V2(UI->TempVal_X, UI->TempVal) + V2(NewPos_X, NewPos_Y); - ImGui_WrapMouse(UI, io.MousePos, TimelineAbsolutePos, TimelineAbsolutePos + TimelineSizeWithBorder); - } - - if (ImGui::IsItemDeactivated()) { - UI->IsDragging = false; - UI->Wrap_X = 0; - UI->Wrap_Y = 0; - } - } - } - - if (NextKeyframe) { - real32 Ratio_X_2 = (real32)(Layer->BitmapInfo.FrameOffset + NextKeyframe->FrameNumber) / File->NumberOfFrames; - real32 Ratio_Y_2 = (NextKeyframe->Value.f - MinVal_Y) / (MaxVal_Y - MinVal_Y); - - ImVec2 NextKeyframePos = ImVec2(TimelineAbsolutePos.x + TimelineMoveSize + Ratio_X_2*TimelineZoomSize, - TimelineAbsolutePos.y + Y_TimelineMoveSize + (1.0f - Ratio_Y_2)*Y_TimelineZoomSize); - draw_list->AddLine(KeyframePos_Mid, NextKeyframePos, col, 1.0f); - } - - ImGui::PopID(); - } - - ImGui_TimelineIncrementDraw(File, UI, draw_list, TimelineSizeWithBorder, TimelineAbsolutePos, 0); - ImGui_TimelineIncrementDraw2(File, draw_list, MaxVal_Y, MinVal_Y, Y_TimelinePercentZoomed, Y_TimelinePercentOffset, TimelineSizeWithBorder, TimelineAbsolutePos, 0); - -#if DEBUG - draw_list->AddCircle(TimelineAbsolutePos + ImVec2(TimelineSizeWithBorder.x * 0.25, TimelineSizeWithBorder.y - 50), - 2, IM_COL32(200, 000, 200, 200), 16, 1); - draw_list->AddCircle(TimelineAbsolutePos + ImVec2(TimelineSizeWithBorder.x * 0.5, TimelineSizeWithBorder.y - 50), - 2, IM_COL32(200, 000, 200, 200), 16, 1); - draw_list->AddCircle(TimelineAbsolutePos + ImVec2(TimelineSizeWithBorder.x * 0.75, TimelineSizeWithBorder.y - 50), - 2, IM_COL32(200, 000, 200, 200), 16, 1); -#endif - -#endif - -#if 0 - - ImVec2 MouseDelta = io.MouseDelta / TimelineSize; - - real32 BarHandleSize = FontHeight; - real32 BarThickness = 50; - real32 BarMinZoom = 0.01; - - real32 BarH_Pos = -TimelineSizeWithBorder.x * UI->TimelinePercentOffset; - real32 BarH_Size = TimelineSizeWithBorder.x / (1 / UI->TimelinePercentZoomed); - - // I use "UI" to denote the size/position after clipping the bar so that it - // doesn't go out of bounds and the handles are always selectable at the edges. - - real32 BarH_Offset = Max(BarH_Pos, 0); - - real32 BarH_SizeUI = (BarH_Size + BarH_Pos > TimelineSizeWithBorder.x) ? - TimelineSizeWithBorder.x - BarH_Pos : - BarH_Size + (BarH_Pos - BarH_Offset); - - if (BarH_Offset == 0 && BarH_SizeUI > TimelineSizeWithBorder.x) - BarH_SizeUI = TimelineSizeWithBorder.x; - - BarH_SizeUI = BarH_SizeUI - BarHandleSize*2; - - BarH_SizeUI = Max(BarH_SizeUI, FontHeight*4); - - BarH_Offset = Min(BarH_Offset, TimelineSize.x - BarH_SizeUI - BarHandleSize*4); - ImVec2 BarH_PosUI = TimelineAbsolutePos + ImVec2(BarH_Offset, TimelineSize.y - BarThickness); - bool32 BarHeld = false; - - ImGui::SetCursorScreenPos(BarH_PosUI); - ImGui::Button("##scrollbarleft", ImVec2(BarHandleSize, BarThickness)); - - if ((ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1))) - { - if ((UI->TimelinePercentZoomed - MouseDelta.x) > BarMinZoom) { - UI->TimelinePercentZoomed -= MouseDelta.x; - UI->TimelinePercentOffset -= MouseDelta.x; - } - BarHeld = true; - } - - ImGui::SetCursorScreenPos(BarH_PosUI + ImVec2(BarHandleSize, 0)); - ImGui::Button("##scrollbarhori", ImVec2(BarH_SizeUI, BarThickness)); - - if (ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) - { - UI->TimelinePercentOffset -= MouseDelta.x; - BarHeld = true; - } - - ImGui::SetCursorScreenPos(BarH_PosUI + ImVec2(BarHandleSize, 0) + ImVec2(BarH_SizeUI, 0)); - ImGui::Button("##scrollbarright", ImVec2(BarHandleSize, BarThickness)); - - if ((ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1))) - { - if ((UI->TimelinePercentZoomed + MouseDelta.x) > BarMinZoom) { - UI->TimelinePercentZoomed += MouseDelta.x; - } - BarHeld = true; - } - - if (BarHeld) { - ImGui_WrapMouse(UI, io.MousePos, TimelineAbsolutePos, TimelineAbsolutePos + TimelineSizeWithBorder, 1); - } - - Assert(UI->TimelinePercentZoomed > BarMinZoom); - - real32 BarV_MaxSize = TimelineSizeWithBorder.y - BarThickness/2; - real32 BarV_Pos = -BarV_MaxSize * Y_TimelinePercentOffset; - real32 BarV_Size = BarV_MaxSize / (1 / Y_TimelinePercentZoomed); - BarV_Size = Max(BarV_Size, FontHeight*4); - - real32 BarV_Offset = Max(BarV_Pos, 0); - - real32 BarV_SizeUI = (BarV_Size + BarV_Pos > BarV_MaxSize) ? - BarV_MaxSize - BarV_Pos : - BarV_Size + (BarV_Pos - BarV_Offset); - - if (BarV_Offset == 0 && BarV_SizeUI > BarV_MaxSize) - BarV_SizeUI = BarV_MaxSize; - - BarV_SizeUI = BarV_SizeUI - BarHandleSize*2; - - BarV_SizeUI = Max(BarV_SizeUI, FontHeight*4); - - BarV_Offset = Min(BarV_Offset, BarV_MaxSize - BarV_SizeUI - BarHandleSize*4); - ImVec2 BarV_PosUI = TimelineAbsolutePos + ImVec2(TimelineSize.x - BarThickness, BarV_Offset); - BarHeld = false; - - ImGui::SetCursorScreenPos(BarV_PosUI); - ImGui::Button("##h-scrollbarleft", ImVec2(BarThickness, BarHandleSize)); - - if ((ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1))) - { - UI->Y_TimelinePercentZoomed -= MouseDelta.y; - UI->Y_TimelinePercentOffset -= MouseDelta.y; - BarHeld = true; - } - - ImGui::SetCursorScreenPos(BarV_PosUI + ImVec2(0, BarHandleSize)); - ImGui::Button("##h-scrollbar", ImVec2(BarThickness, BarV_SizeUI)); - - if (ImGui::IsItemHovered() && io.MouseWheel) - { - UI->Y_TimelinePercentOffset -= io.MouseWheel/10; - } - - if (ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) - { - UI->Y_TimelinePercentOffset -= MouseDelta.y; - BarHeld = true; - } - - ImGui::SetCursorScreenPos(BarV_PosUI + ImVec2(0, BarHandleSize) + ImVec2(0, BarV_SizeUI)); - ImGui::Button("##h-scrollbarright", ImVec2(BarThickness, BarHandleSize)); - - if ((ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1))) - { - UI->Y_TimelinePercentZoomed += MouseDelta.y; - BarHeld = true; - } - - UI->Y_TimelinePercentZoomed = Max(UI->Y_TimelinePercentZoomed, 0.01); - - if (BarHeld) { - ImGui_WrapMouse(UI, io.MousePos, TimelineAbsolutePos, TimelineAbsolutePos + TimelineSizeWithBorder, 2); - } - - draw_list->PopClipRect(); - ImGui::PopClipRect(); - - ImGui::PopStyleVar(); - - if (io.MouseWheel) { - // NOTE(fox): Change this if any other action is added when hovering over the bar area. - bool32 BarHovering_H = TestRectangle(TimelineAbsolutePos + ImVec2(0, TimelineSize.y - BarThickness), - TimelineAbsolutePos + ImVec2(TimelineSize.x, TimelineSize.y), - io.MousePos); - bool32 BarHovering_V = TestRectangle(TimelineAbsolutePos + ImVec2(TimelineSize.x - BarThickness, 0), - TimelineAbsolutePos + ImVec2(TimelineSize.x, TimelineSize.y), - io.MousePos); - if (BarHovering_H && io.MouseWheel) { - UI->TimelinePercentOffset -= io.MouseWheel/15; - } else if (BarHovering_V && io.MouseWheel) { - UI->Y_TimelinePercentOffset -= io.MouseWheel/15; - } else { - real32 Increment = 0.1; - bool32 Direction = (io.MouseWheel > 0) ? 1 : -1; - real32 Offset = (io.MousePos.y - (TimelineAbsolutePos.y + Y_TimelineMoveSize)) / Y_TimelineZoomSize; - real32 X_Offset = (io.MousePos.x - (TimelineAbsolutePos.x + TimelineMoveSize)) / TimelineZoomSize; - DebugWatchVar("X Offset", &X_Offset, d_float); - if (io.KeyShift) { - UI->Y_TimelinePercentOffset += Increment*Direction; - } else if (io.KeyCtrl) { - UI->TimelinePercentOffset += Increment*Direction*0.3; - } else { - if (Direction == 1) { - UI->Y_TimelinePercentZoomed -= (UI->Y_TimelinePercentZoomed * Increment); - UI->Y_TimelinePercentOffset -= (UI->Y_TimelinePercentOffset * Increment) + Offset*Increment; - UI->TimelinePercentZoomed -= (UI->TimelinePercentZoomed * Increment); - UI->TimelinePercentOffset -= (UI->TimelinePercentOffset * Increment) + X_Offset*Increment; - } else { - UI->Y_TimelinePercentOffset = ((UI->Y_TimelinePercentOffset + Offset*Increment) / (1.0f - Increment)); - UI->Y_TimelinePercentZoomed = (UI->Y_TimelinePercentZoomed / (1.0f - Increment)); - UI->TimelinePercentOffset = ((UI->TimelinePercentOffset + X_Offset*Increment) / (1.0f - Increment)); - UI->TimelinePercentZoomed = (UI->TimelinePercentZoomed / (1.0f - Increment)); - } - } - } - } - - // General timeline interaction - - ImGui::SetCursorScreenPos(TimelineAbsolutePos); - ImGui::InvisibleButton("TimelineMoving", TimelineSizeWithBorder, ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight); - bool32 IsHovered = ImGui::IsItemHovered(); - bool32 IsActive = ImGui::IsItemActive(); - bool32 IsItemActivated = ImGui::IsItemActivated(); - bool32 IsItemDeactivated = ImGui::IsItemDeactivated(); - bool32 LeftClick = ImGui::IsMouseDown(ImGuiMouseButton_Left); - bool32 RightClick = ImGui::IsMouseDown(ImGuiMouseButton_Right); - - if (IsActive) { - if (LeftClick) { - if (io.KeyCtrl && IsActive) { - real32 LocalMousePos = ImGui::GetMousePos().x - TimelineStartingPos.x; - real32 ZoomRatio = LocalMousePos / UI->TimelineZoom; - File->CurrentFrame = (int32)(ZoomRatio + 0.5); - State->UpdateFrame = true; - State->UpdateKeyframes = true; - } else { - if (IsItemActivated) - { - if (!io.KeyShift) { - // DeselectAllKeyframes(&State); - // DeselectAllLayers(File, State); - } - UI->BoxStart = ImGui::GetMousePos(); - UI->BoxSelectActive = true; - } - if (ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1) ) - { - UI->BoxEnd = ImGui::GetMousePos(); - draw_list->AddRectFilled(UI->BoxStart, UI->BoxEnd, - IM_COL32(0, 0, 200, 50)); - } - } - // Timeline zooming interaction - } else if (RightClick && IsActive) { - if (IsItemActivated) - { - real32 LocalMousePos = io.MousePos.x - WindowMinAbs.x - UI->TimelineSplit; - UI->TempZoomRatioTimeline = LocalMousePos / TimelineSize.x; - } - if (ImGui::IsMouseDragging(ImGuiMouseButton_Right, -1) ) - { - UI->TimelineZoom += io.MouseDelta.x; - } - } - } - if (IsItemDeactivated) { - UI->BoxStart = {0, 0}; - UI->BoxEnd = {0, 0}; - UI->BoxSelectActive = false; - if (!io.KeyShift) DeselectAllLayers(File, State); - } - - ImGui::EndChild(); - - ImGui::PopStyleVar(2); - -#endif - - - -#if 0 -// 0 for timeline keyframe, 1 for graph keyframe, 2 for left graph handle, 3 for right graph handle -static void -ImGui_KeyframeDragging(project_data *File, project_state *State, ui *UI, property_channel *Property, int32 b, ImGuiIO io, int16 Type) -{ - keyframe *Keyframe = KeyframeLookup(Property, b); - if (ImGui::IsItemActive()) { - - if (!Keyframe->IsSelected && ImGui::IsItemActivated()) - { - if (!io.KeyShift) { - temp_keyframe_list Bad = GetSelectedKeyframes(File); - for (int i = 0; i < Bad.Amount; i++) - Bad.SelectedKeyframe[i]->IsSelected = false; - } - Keyframe->IsSelected = true; - State->RecentSelectionType = selection_keyframe; - } - if (ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) - { - ImGui::SetMouseCursor(ImGuiMouseCursor_Hand); - if (Type == 0 || Type == 1) - { - UI->DraggingKeyframeThreshold += io.MouseDelta.x; - if (abs(UI->DraggingKeyframeThreshold) >= UI->TimelineZoom) { - int16 Increment = UI->DraggingKeyframeThreshold/UI->TimelineZoom; - // temp_keyframe_list Bad = GetSelectedKeyframes(File); - // for (int b = 0; b < Bad.Amount; b++) { - // keyframe *SelectedKeyframe = Bad.SelectedKeyframe[b]; - if (!(Keyframe->FrameNumber == 0 && Increment == -1)) { - Keyframe->FrameNumber += Increment; - CheckKeyframeSort(Property, Increment, b); - // SortAndCacheKeyframeAtFrame(SelectedKeyframe->FrameNumber, &File.LayerPTR[i]->Property[a], &Cache); - ClampSurroundingKeyframeHandles(Property, b); - } - // } - UI->DraggingKeyframeThreshold += -1*Increment*UI->TimelineZoom; - State->UpdateFrame = true; - State->UpdateKeyframes = true; - // Cache.Frame[File.CurrentFrame].Cached = false; - } - } - /* - if (Type != 0) - { - if (Type == 1) - { - real32 IncrementsPerPixel = (Property->LocalMaxVal.f - Property->LocalMinVal.f)/Property->GraphLength; - Keyframe->Value.f -= io.MouseDelta.y*IncrementsPerPixel; - CalculatePropertyMinMax(Property); - } - if (Type == 2) - { - Keyframe->TangentLeft.x += io.MouseDelta.x/UI->TimelineZoom; - Keyframe->TangentLeft.y -= io.MouseDelta.y; - ClampKeyframeHandles(Property, b, 0); - } - if (Type == 3) - { - Keyframe->TangentRight.x += io.MouseDelta.x/UI->TimelineZoom; - Keyframe->TangentRight.y -= io.MouseDelta.y; - ClampKeyframeHandles(Property, b, 1); - } - State->UpdateFrame = true; - State->UpdateKeyframes = true; - } - */ - } - } -} - -static void -ImGui_InteractSliderProperty(project_state *State, memory *Memory, property_channel *Property) -{ - ImGui::DragScalar(Property->Name, ImGuiDataType_Float, &Property->CurrentValue.f, - Property->ScrubVal.f, &Property->MinVal.f, &Property->MaxVal.f, "%f"); - if (ImGui::IsItemActivated()) { - State->InteractCache[0] = Property->CurrentValue.f; - } - if (ImGui::IsItemActive()) { - State->UpdateFrame = true; - } - if (ImGui::IsItemDeactivatedAfterEdit()) { - if (ImGui::IsKeyPressed(ImGuiKey_Escape)) { - Property->CurrentValue.f = State->InteractCache[0]; - } else { - History_Entry_Commit(Memory, action_entry_default, "Tranforms interact"); - History_Action_Change(Memory, &Property->CurrentValue.f, &State->InteractCache[0], - &Property->CurrentValue.f, action_type_change_r32); - History_Entry_End(Memory); - } - State->UpdateFrame = true; - } -} - -static void -ImGui_DebugUndoTree(project_data *File, memory *Memory) -{ - ImGui::SetNextWindowSize(ImVec2(200, 800)); - ImGui::Begin("undotree"); - for (int i = 0; i < Memory->Action.NumberOfEntries; i++) { - action_entry Entry = Memory->Action.Entry[i]; - bool32 CurrentPos = (i < Memory->Action.Index); - ImGui::MenuItem(Entry.Name, NULL, CurrentPos); - } - ImGui::End(); -} - -static void -ImGui_DebugMemoryViewer(project_data *File, memory *Memory) -{ - ImGui::SetNextWindowSize(ImVec2(800, 200)); - ImGui::Begin("memoryviewer"); - ImVec2 ViewportMin = ImGui::GetCursorScreenPos(); - ImVec2 ViewportScale = ImGui::GetContentRegionAvail(); - ImVec2 ViewportMax = ImVec2(ViewportMin.x + ViewportScale.x, ViewportMin.y + ViewportScale.y); - - memory_table *Table = &Memory->Slot[B_LoadedBitmaps]; - - real32 TotalMB = Table->Size/1024/1024; - real32 LineAmount = 50; - real32 IncrementMB = TotalMB / LineAmount; - real32 ScreenIncrement = ViewportScale.x / LineAmount; - - real32 CubeHeight = ImGui::GetFontSize(); - real32 TotalHeight = CubeHeight*4; - - ImDrawList* draw_list = ImGui::GetWindowDrawList(); - draw_list->AddRectFilled(ViewportMin, ViewportMax, IM_COL32(50, 50, 50, 255)); - - for (float x = 0; x < LineAmount; x++) { - uint32 LineColor = IM_COL32(200, 200, 200, 40); - ImVec2 Min = ImVec2(ViewportMin.x + ScreenIncrement * x, ViewportMin.y); - ImVec2 Max = ImVec2(Min.x + 2, ViewportMax.y); - draw_list->AddLine(Min, Max, LineColor); - } - // CurrentPosition line - { - uint32 LineColor = IM_COL32(000, 100, 200, 200); - real32 CurPosMB = (real32)Table->CurrentPosition/1024/1024; - ImVec2 Min = ImVec2(ViewportMin.x + (CurPosMB/IncrementMB * ScreenIncrement), ViewportMin.y); - ImVec2 Max = ImVec2(Min.x + 2, ViewportMax.y); - draw_list->AddLine(Min, Max, LineColor); - } - - for (uint32 i = 0; i < Table->NumberOfPointers; i++) { - if (Memory->Bitmap[i].SourceOwner) { - void *DataStart = Memory->Bitmap[i].Data; - void *NextDataStart; - int pp = 1; - for (;;) { - if (Memory->Bitmap[i+pp].SourceOwner) { - NextDataStart = Memory->Bitmap[i+pp].Data; - break; - } - pp++; - } - uint64 BytesBetween = (uint8 *)NextDataStart - (uint8 *)DataStart; - source *Source = Memory->Bitmap[i].SourceOwner; - real32 Pos = Memory_NormalizedPosition(&File->Source[0], File->NumberOfSources, sizeof(source), Source); - - ImVec4 col = ImColor::HSV(Pos, 0.3, 0.6, 1.0f); - uint64 BitmapSize = Bitmap_CalcTotalBytes(Source->Info.Width, Source->Info.Height, Source->Info.BytesPerPixel); - if (BitmapSize > BytesBetween && i != Table->NumberOfPointers - 1) { - col = ImColor::HSV(Pos, 1.0, 1.0, 1.0f); - } - - uint64 DataStart2 = (uint8 *)DataStart - (uint8 *)Table->Address; - real32 StartReal = ((real32)DataStart2/1024/1024); - ImVec2 Min = ImVec2(ViewportMin.x + (StartReal/IncrementMB * ScreenIncrement), ViewportMin.y + (ViewportScale.y / 2) - (TotalHeight / 2) + TotalHeight*Pos); - real32 SizeReal = ((real32)BitmapSize/1024/1024); - ImVec2 Size = ImVec2(SizeReal/IncrementMB * ScreenIncrement, CubeHeight); - ImGui::SetCursorScreenPos(Min); - ImGui::PushID(i); - ImGui::PushStyleColor(ImGuiCol_Button, col); - char buf2[256]; - sprintf(buf2, "%i##mempos", Memory->Bitmap[i].Frame); - ImGui::Button(buf2, Size); - ImGui::PopStyleColor(); - if (ImGui::IsItemHovered()) { - char buf[1024]; - sprintf(buf, "Source owner: %s\nSize: %.02f MB\n Frame number: %i\n Index: %i", - Memory->Bitmap[i].SourceOwner->Path, SizeReal, - Memory->Bitmap[i].Frame, i); - ImGui::BeginTooltip(); - ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f); - ImGui::TextUnformatted(buf); - ImGui::PopTextWrapPos(); - ImGui::EndTooltip(); - } - ImGui::PopID(); - ImVec2 Max = ImVec2(ViewportMax.x, Min.y + CubeHeight); - // draw_list->AddRectFilled(Min, Max, IM_COL32(200, 200, 200, 255)); - } - } - ImGui::SetCursorScreenPos(ImVec2(ViewportMin.x, ViewportMax.y - CubeHeight*2)); - char buf[1024]; - sprintf(buf, "Current index: %i\nAmount of pointers: %i", - Table->PointerIndex, Table->NumberOfPointers); - ImGui::Text(buf); - - ImGui::End(); -} - -static bool32 FU; - -static void -ImGui_TimelineIncrementDraw2(project_data *File, ImDrawList *draw_list, real32 MaxVal_Y, real32 MinVal_Y, - real32 Y_TimelinePercentZoomed, real32 Y_TimelinePercentOffset, - ImVec2 TimelineSizeWithBorder, ImVec2 TimelineAbsolutePos, bool32 IsText) -{ - uint32 LineColor = IM_COL32(200, 200, 200, 40); - - real32 TimelineZoomSize = TimelineSizeWithBorder.y / Y_TimelinePercentZoomed; - real32 TimelineMoveSize = TimelineSizeWithBorder.y * Y_TimelinePercentOffset / Y_TimelinePercentZoomed; - - Assert(TimelineZoomSize > 0.0f); - - real32 Fraction = (MinVal_Y > 0) ? MinVal_Y - (int32)MinVal_Y : (int32)MinVal_Y - MinVal_Y; - real32 x = (int32)MinVal_Y; - bool32 RightmostEdge = false; - - while (!RightmostEdge) { - real32 Ratio_Y = (x - MinVal_Y) / (MaxVal_Y - MinVal_Y); - ImVec2 Min = ImVec2(TimelineAbsolutePos.x, TimelineAbsolutePos.y + TimelineMoveSize + (1.0f - Ratio_Y)*TimelineZoomSize); - ImVec2 Max = ImVec2(TimelineAbsolutePos.x + TimelineSizeWithBorder.x, Min.y + 2); - if (Min.y > TimelineAbsolutePos.y) { - draw_list->AddLine(Min, Max, LineColor); - char buf2[6]; - sprintf(buf2, "%.2f", x); - draw_list->AddText(ImVec2(TimelineAbsolutePos.x, Min.y), IM_COL32(200, 200, 200, 130), buf2); - x += 1.0f; - } else { - RightmostEdge = true; - } - } - - x = (int32)MinVal_Y; - x -= 1.0f; - bool32 LeftmostEdge = false; - - while (!LeftmostEdge) { - real32 Ratio_Y = (x - MinVal_Y) / (MaxVal_Y - MinVal_Y); - ImVec2 Min = ImVec2(TimelineAbsolutePos.x, TimelineAbsolutePos.y + TimelineMoveSize + (1.0f - Ratio_Y)*TimelineZoomSize); - ImVec2 Max = ImVec2(TimelineAbsolutePos.x + TimelineSizeWithBorder.x, Min.y + 2); - if (Min.y < TimelineAbsolutePos.y + TimelineSizeWithBorder.y) { - draw_list->AddLine(Min, Max, LineColor); - char buf2[6]; - sprintf(buf2, "%.2f", x); - draw_list->AddText(ImVec2(TimelineAbsolutePos.x, Min.y), IM_COL32(200, 200, 200, 130), buf2); - x -= 1.0f; - } else { - LeftmostEdge = true; - } - } -} - -static void -ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io) -{ - if (State->MostRecentlySelectedLayer > -1) { - project_layer *Layer = File->Layer[State->MostRecentlySelectedLayer]; - char buf[256]; - sprintf(buf, "Properties: %s###Properties", Layer->Name); - ImGui::Begin(buf); - if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) - UI->FocusedWindow = focus_properties; - ImGui::Text("Transform"); - for (int h = 0; h < AmountOf(Layer->Property); h++) { - property_channel *Property = &Layer->Property[h]; - ImGui::PushID(Property); - if (ImGui::Button("K")) - Keyframe_Insert(Property, Memory, File->CurrentFrame, Property->CurrentValue.f); - ImGui::SameLine(); - ImGui_InteractSliderProperty(State, Memory, Property); - ImGui::PopID(); - } - for (int h = 0; h < Layer->NumberOfEffects; h++) { - effect *Effect = Layer->Effect[h]; - ImGui::PushID(Effect->ImGuiID); - if (FU && h == 0) { - int a = 0; - } - // this is stupid - if (Effect->IsActive) - ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetColorU32(ImGuiCol_ButtonHovered)); - else - ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetColorU32(ImGuiCol_Button)); - if (ImGui::Button("V")) { - History_Entry_Commit(Memory, action_entry_default, "Toggle effect"); - History_Action_Change_SwapBool(Memory, &Effect->IsActive); - History_Entry_End(Memory); - State->UpdateFrame = true; - } - ImGui::SameLine(); - ImGui::PopStyleColor(); - ImGui::Button("R"); ImGui::SameLine(); - ImGui::Selectable(Effect->Name, Effect->IsSelected); - // NOTE(fox): The logic for effect dragging has to be after we've - // done the UI for the rest of the effect! - real32 Effect_Top = ImGui::GetCursorScreenPos().y; - bool32 IsHovered = ImGui::IsItemHovered(); - bool32 IsActive = ImGui::IsItemActive(); - bool32 IsActivated = ImGui::IsItemActivated(); - bool32 IsDeactivated = ImGui::IsItemDeactivated(); - - if (Effect->DisplayType == standard) { - for (int i = 0; i < Effect->NumberOfProperties; i++) { - property_channel *Property = &Effect->Property[i]; - ImGui::PushID(Property); - if (Property->VarType == type_real) { - ImGui_InteractSliderProperty(State, Memory, Property); - } - if (Property->VarType == type_color) - if (ImGui::ColorEdit4("color 1", &Property->CurrentValue.f, ImGuiColorEditFlags_Float)) - State->UpdateFrame = true; - if (Property->VarType == type_blendmode) - { - uint32 *item_current_idx = (uint32 *)&Property->CurrentValue.blendmode; // Here we store our selection data as an index. - if (ImGui::BeginListBox("Blend mode")) - { - for (int n = 0; n < IM_ARRAYSIZE(BlendmodeNames); n++) - { - const bool is_selected = (*item_current_idx == n); - if (ImGui::Selectable(BlendmodeNames[n], is_selected)) { - *item_current_idx = n; - State->UpdateFrame = true; - } - - // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) - if (is_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndListBox(); - } - } - ImGui::PopID(); - } - } else if (Effect->DisplayType == levels) { - source *Source = Layer->Source; - layer_bitmap_info *BitmapInfo = &Layer->BitmapInfo; - - if (!BitmapInfo->HistogramVals) { - uint64 Size = Bitmap_CalcUnpackedBytes(Source->Info.Width, Source->Info.Height, Source->Info.BytesPerPixel); - BitmapInfo->HistogramVals = AllocateMemory(Memory, (sizeof(uint32) * 5 * 256), P_MiscCache); - Bitmap_CalcHistogram(BitmapInfo->HistogramVals, BitmapInfo->BitmapBuffer, Source->Info.BytesPerPixel, Size); - } - - char *LevelsButtons[5] = { "All", "Red", "Green", "Blue", "Alpha" }; - for (int i = 0; i < 5; i++) { - if (ImGui::Button(LevelsButtons[i])) { - BitmapInfo->LevelsSelector = i; - } - if (i != 4) { ImGui::SameLine(); } - } - - real32 *Min, *Mid, *Max; - if (BitmapInfo->LevelsSelector == 0) { - Min = &Effect->Property[0].CurrentValue.f; - Mid = &Effect->Property[1].CurrentValue.f; - Max = &Effect->Property[2].CurrentValue.f; - } else { - Min = &Effect->Property[3].CurrentValue.col.E[BitmapInfo->LevelsSelector - 1]; - Mid = &Effect->Property[4].CurrentValue.col.E[BitmapInfo->LevelsSelector - 1]; - Max = &Effect->Property[5].CurrentValue.col.E[BitmapInfo->LevelsSelector - 1]; - } - - if (BitmapInfo->LevelsSelector == 0) { - ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(0.6f, 0.6f, 0.6f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_PlotHistogramHovered, ImVec4(0.6f, 0.6f, 0.6f, 1.0f)); - } else if (BitmapInfo->LevelsSelector == 1) { - ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(0.9f, 0.6f, 0.6f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_PlotHistogramHovered, ImVec4(0.9f, 0.6f, 0.6f, 1.0f)); - } else if (BitmapInfo->LevelsSelector == 2) { - ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(0.6f, 0.9f, 0.6f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_PlotHistogramHovered, ImVec4(0.6f, 0.9f, 0.6f, 1.0f)); - } else if (BitmapInfo->LevelsSelector == 3) { - ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(0.6f, 0.6f, 0.9f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_PlotHistogramHovered, ImVec4(0.6f, 0.6f, 0.9f, 1.0f)); - } else if (BitmapInfo->LevelsSelector == 4) { - ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(0.9f, 0.9f, 0.9f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_PlotHistogramHovered, ImVec4(0.9f, 0.9f, 0.9f, 1.0f)); - } - - float *values = (float *)BitmapInfo->HistogramVals + 256*BitmapInfo->LevelsSelector; - int values_count = 256; - int values_offset = 0; - float scale_min = FLT_MIN; - float scale_max = FLT_MAX; - ImVec2 graph_size = ImVec2(0, 250); - int stride = sizeof(float); - - // The default histogram is good enough for what we need. - ImGui::PlotHistogram("##histo", values, values_count, values_offset, NULL, scale_min, scale_max, graph_size, stride); - // TODO(fox): Figure out the proper way to represent these IDs. - if (ImGui::SliderLevels("##one", "##two", "three", Mid, Min, Max)) - State->UpdateFrame = true; - - ImGui::PopStyleColor(); - ImGui::PopStyleColor(); - - if (State->UpdateFrame) { - uint64 Size = Bitmap_CalcUnpackedBytes(Source->Info.Width, Source->Info.Height, Source->Info.BytesPerPixel); - Bitmap_CalcHistogram(BitmapInfo->HistogramVals, BitmapInfo->BitmapBuffer, Source->Info.BytesPerPixel, Size); - } - - ImGui::Button("K"); - } - ImGui::PopID(); - - if (IsActive) - { - if (!Effect->IsSelected && IsActivated) { - Effect->IsSelected ^= 1; - } - if (ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) - { - real32 Effect_Bottom = ImGui::GetCursorScreenPos().y; - real32 Effect_Length = Effect_Bottom - Effect_Top; - ImGui::SetMouseCursor(ImGuiMouseCursor_Hand); - UI->DraggingEffectThreshold += io.MouseDelta.y; - if (abs(UI->DraggingEffectThreshold) >= Effect_Length) { - int16 Increment = UI->DraggingEffectThreshold/Effect_Length; - effect *Effect = Layer->Effect[1]; - Layer->Effect[1] = Layer->Effect[0]; - Layer->Effect[0] = Effect; - // History_Entry_Commit(Memory, action_entry_default, "Change effect order"); - // History_Entry_End(Memory); - FU = true; - UI->DraggingEffectThreshold += -1*Increment*Effect_Length; - State->UpdateFrame = true; - State->UpdateKeyframes = true; - } - } - } - if (FU) { - FU = false; - break; - } - } - } else { - char buf[256]; - sprintf(buf, "Properties: empty###Properties"); - ImGui::Begin(buf); - if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) - UI->FocusedWindow = focus_properties; - } - ImGui::End(); -} - -static void -ImGui_Viewport(project_data File, project_state *State, ui *UI, memory *Memory, comp_buffer CompBuffer, - ImGuiIO io, GLuint textureID, sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray) -{ - bool open = true; - ImGui::Begin("Viewport", &open, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse); - - if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) - UI->FocusedWindow = focus_viewport; - - // Primarily taken from the Custom Rendering section of the demo - - ImVec2 ViewportMin = ImGui::GetCursorScreenPos(); - ImVec2 ViewportScale = ImGui::GetContentRegionAvail(); - ViewportScale.y -= ImGui::GetFontSize()*0.5; - if (ViewportScale.x < 50.0f) ViewportScale.x = 50.0f; - if (ViewportScale.y < 50.0f) ViewportScale.y = 50.0f; - ImVec2 ViewportMax = ImVec2(ViewportMin.x + ViewportScale.x, ViewportMin.y + ViewportScale.y); - - if (UI->Initializing) { - UI->CompZoom = ImVec2(CompBuffer.Width, CompBuffer.Height); -#if DEBUG - UI->CompZoom = UI->CompZoom * ImVec(0.5, 0.5); -#endif - UI->CompPos = ImVec2(ViewportMin.x + ((ViewportMax.x - ViewportMin.x)/2 - UI->CompZoom.x/2), - ViewportMin.y + ((ViewportMax.y - ViewportMin.y)/2 - UI->CompZoom.y/2)); - } - - ImDrawList* draw_list = ImGui::GetWindowDrawList(); - draw_list->AddRectFilled(ViewportMin, ViewportMax, IM_COL32(50, 50, 50, 255)); - draw_list->AddRect(ViewportMin, ViewportMax, IM_COL32(255, 255, 255, 255)); - - // Actual composition texture - draw_list->PushClipRect(ViewportMin, ViewportMax, true); - draw_list->AddImage((void *)(intptr_t)textureID, ImVec2(UI->CompPos.x, UI->CompPos.y), - ImVec2(UI->CompPos.x + UI->CompZoom.x, UI->CompPos.y + UI->CompZoom.y)); - draw_list->PopClipRect(); - - // UI+interaction for layer - if (State->MostRecentlySelectedLayer > -1) { - project_layer *Layer = File.Layer[State->MostRecentlySelectedLayer]; - source *Source = Layer->Source; - - // Anchor point UI - ImVec2 AUV = ImVec2(Layer->x.CurrentValue.f / CompBuffer.Width, Layer->y.CurrentValue.f / CompBuffer.Height); - ImVec2 ScreenAP = ImVec2(UI->CompPos.x + AUV.x * UI->CompZoom.x, UI->CompPos.y + AUV.y * UI->CompZoom.y); - draw_list->AddNgon(ScreenAP, 20, ImGui::GetColorU32(ImGuiCol_ScrollbarGrab), 8, 10.0f); - - // Mask UI - if (Layer->NumberOfMasks) { - for (int i = 0; i < Layer->NumberOfMasks; i++) { - mask *Mask = &Layer->Mask[i]; - ImGui::PushID(i); - - real32 PointSize = 40; - - for (int p = 0; p < Mask->NumberOfPoints; p++) { - - mask_point *Point0 = &Mask->Point[p]; - mask_point *Point1 = &Mask->Point[p+1]; - if (p+1 == Mask->NumberOfPoints) - Point1 = &Mask->Point[0]; - - // NOTE(fox): I want to keep operations in local space under the v2 data - // type and operations in screen space under ImVec2. - - v2 Point0_Pos = Point0->Pos; - v2 Point0_Pos_Left = Point0_Pos + Point0->TangentLeft; - v2 Point0_Pos_Right = Point0_Pos + Point0->TangentRight; - - v2 Point1_Pos = Point1->Pos; - v2 Point1_Pos_Left = Point1_Pos + Point1->TangentLeft; - v2 Point1_Pos_Right = Point1_Pos + Point1->TangentRight; - - ImVec2 Point0_ScreenPos = Layer_LocalToScreenSpace(Layer, UI, CompBuffer, Point0_Pos); - ImVec2 Point0_ScreenPos_Left = Layer_LocalToScreenSpace(Layer, UI, CompBuffer, Point0_Pos_Left); - ImVec2 Point0_ScreenPos_Right = Layer_LocalToScreenSpace(Layer, UI, CompBuffer, Point0_Pos_Right); - - ImVec2 Point1_ScreenPos = Layer_LocalToScreenSpace(Layer, UI, CompBuffer, Point1_Pos); - ImVec2 Point1_ScreenPos_Left = Layer_LocalToScreenSpace(Layer, UI, CompBuffer, Point1_Pos_Left); - // ImVec2 Point1_ScreenPos_Right = Layer_LocalToScreenSpace(Layer, UI, CompBuffer, Point1_Pos_Right); - - ImGui::PushID(p); - - ImU32 col = ImGui::GetColorU32(ImGuiCol_ScrollbarGrab); - - // The handle itself - - col = ImGui::GetColorU32(ImGuiCol_ButtonHovered); - if (Point0->HandleBezier) { - draw_list->AddNgon(Point0_ScreenPos_Left, 10, col, 8, 5.0f); - draw_list->AddNgon(Point0_ScreenPos_Right, 10, col, 8, 5.0f); - draw_list->AddLine(Point0_ScreenPos, Point0_ScreenPos_Left, col, 2.0f); - draw_list->AddLine(Point0_ScreenPos, Point0_ScreenPos_Right, col, 2.0f); - } - - draw_list->AddNgon(Point0_ScreenPos, 10, col, 8, 5.0f); - - int max = 1; - - if (Point0->HandleBezier && Point0->IsSelected) { - max = 3; - } - - for (int b = 0; b < max; b++) - { - ImGui::PushID(b); - if (b == 0) { - ImGui::SetCursorScreenPos(Point0_ScreenPos - ImVec2(PointSize/2, PointSize/2)); - } else if (b == 1) { - ImGui::SetCursorScreenPos(Point0_ScreenPos_Left - ImVec2(PointSize/2, PointSize/2)); - } else { - ImGui::SetCursorScreenPos(Point0_ScreenPos_Right - ImVec2(PointSize/2, PointSize/2)); - } - - ImGui::InvisibleButton("##point", ImVec2(PointSize, PointSize), ImGuiButtonFlags_MouseButtonLeft); - - if (ImGui::IsItemHovered()) { - ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); - } - if (ImGui::IsItemHovered() && ImGui::IsKeyPressed(ImGuiKey_Backspace)) { - Mask_DeletePoint(Memory, Mask, p); - State->UpdateFrame = true; - } - if (ImGui::IsItemActivated() && b == 0) { - if (p == 0 && State->Pen.IsActive) { - History_Entry_Commit(Memory, action_entry_default, "Close mask path"); - History_Action_Change_SwapBool(Memory, &State->Pen.IsActive); - History_Action_Change_SwapBool(Memory, &Mask->IsClosed); - // State->Pen.IsActive = false; - // Mask->IsClosed = true; - History_Entry_End(Memory); - } else if (io.KeyAlt) { - History_Entry_Commit(Memory, action_entry_default, "Switch handles on point"); - History_Action_Change_SwapBool(Memory, &Point0->HandleBezier); - History_Entry_End(Memory); - } - Point0->IsSelected = true; - } - if (ImGui::IsItemActive()) { - ImVec2 MouseIncrement = io.MouseDelta * (ImVec2(CompBuffer.Width, CompBuffer.Height) / UI->CompZoom); - if (b == 0) { - Layer_CalcRotatedOffset(Layer, V2(MouseIncrement), V2(1, 1), - &Point0->Pos.x, &Point0->Pos.y); - } else if (b == 1) { - Layer_CalcRotatedOffset(Layer, V2(MouseIncrement), V2(1, 1), - &Point0->TangentLeft.x, &Point0->TangentLeft.y); - } else { - Layer_CalcRotatedOffset(Layer, V2(MouseIncrement), V2(1, 1), - &Point0->TangentRight.x, &Point0->TangentRight.y); - } - State->UpdateFrame = true; - } - ImGui::PopID(); - } - - // The bezier path - - - if (Mask->NumberOfPoints == 1 || (p+1 == Mask->NumberOfPoints && !Mask->IsClosed)) { - ImGui::PopID(); - continue; - } - - ImU32 col2 = ImGui::GetColorU32(ImGuiCol_Button); - - if (Point0->HandleBezier && Point1->HandleBezier) { - draw_list->AddBezierCubic(Point0_ScreenPos, Point0_ScreenPos_Right, - Point1_ScreenPos_Left, Point1_ScreenPos, col2, 6.0f, 0); - } else if (Point0->HandleBezier) { - draw_list->AddBezierCubic(Point0_ScreenPos, Point0_ScreenPos_Right, - Point1_ScreenPos, Point1_ScreenPos, col2, 6.0f, 0); - } else if (Point1->HandleBezier) { - draw_list->AddBezierCubic(Point0_ScreenPos, Point0_ScreenPos, - Point1_ScreenPos_Left, Point1_ScreenPos,col2, 6.0f, 0); - } else { - draw_list->AddLine(Point0_ScreenPos, Point1_ScreenPos, col2, 6.0f); - } - - if (Point0->HandleBezier && Point1->HandleBezier) { - if (ImGui::BezierInteractive(Point0_ScreenPos, Point0_ScreenPos_Right, - Point1_ScreenPos_Left, Point1_ScreenPos) && - State->Tool == tool_pen) - { - - // Using a button like this may be kinda janky, but it gives us access - // to all of ButtonBehavior and the ID system without having to write on top of ImGui's. - ImGui::SetCursorScreenPos(io.MousePos - ImVec2(5,5)); - ImGui::Button("maskbezier", ImVec2(10, 10)); - - if (ImGui::IsItemHovered()) { -#if DEBUG - // Code that basically mimics Mask_AddPointToCurve but visualized in screen space, for checking bugs. - v2 LayerPoint = Layer_ScreenSpaceToLocal(Layer, UI, CompBuffer, ViewportMin, io.MousePos); - real32 ratio = Bezier_CubicRatioOfPoint(Point0_Pos, Point0_Pos_Right, Point1_Pos_Left, Point1_Pos, LayerPoint); - draw_list->AddNgon(io.MousePos, 2, col, 8, 5.0f); - ImVec2 RatioLeft = ImGui::RatioToPoint(Point0_ScreenPos, Point0_ScreenPos_Right, ratio); - ImVec2 RatioRight = ImGui::RatioToPoint(Point1_ScreenPos_Left, Point1_ScreenPos, ratio); - ImVec2 RatioTop = ImGui::RatioToPoint(Point0_ScreenPos_Right, Point1_ScreenPos_Left, ratio); - ImVec2 TangentLeft = ImGui::RatioToPoint(RatioLeft, RatioTop, ratio); - ImVec2 TangentRight = ImGui::RatioToPoint(RatioTop, RatioRight, ratio); - draw_list->AddLine(RatioLeft, RatioTop, col, 2.0f); - draw_list->AddLine(RatioRight, RatioTop, col, 2.0f); - draw_list->AddLine(TangentLeft, TangentRight, col, 2.0f); -#endif - } - if (ImGui::IsItemActivated() && io.KeyCtrl) { - v2 LayerPoint = Layer_ScreenSpaceToLocal(Layer, UI, CompBuffer, ViewportMin, io.MousePos); - real32 ratio = Bezier_CubicRatioOfPoint(Point0_Pos, Point0_Pos_Right, Point1_Pos_Left, Point1_Pos, LayerPoint); - Mask_AddPointToCurve(Memory, Mask, p, ratio); - } - } - } else { - if (ImGui::LineInteractive(Point0_ScreenPos, Point1_ScreenPos) && - State->Tool == tool_pen) - { - ImGui::SetCursorScreenPos(io.MousePos - ImVec2(5,5)); - ImGui::Button("maskline", ImVec2(10, 10)); - - if (ImGui::IsItemHovered()) { - draw_list->AddNgon(io.MousePos, 2, col, 8, 5.0f); - } - if (ImGui::IsItemActivated() && io.KeyCtrl) { - v2 LayerPoint = Layer_ScreenSpaceToLocal(Layer, UI, CompBuffer, ViewportMin, io.MousePos); - Mask_AddPointToLine(Mask, p, LayerPoint); - } - } - } - ImGui::PopID(); - } - ImGui::PopID(); - } - } - } - - // Interactions for dragging and zooming - ImGui::SetCursorScreenPos(ViewportMin); - - real32 ButtonSize = 20; - - for (int t = 0; t < tool_count; t++) { - ImGui::PushID(t); - bool32 Selected = (State->Tool == t); - if (ImGui::Selectable(ToolName[t], Selected, 0, ImVec2(ButtonSize*2, ButtonSize))) { - State->Tool = (tool)t; - } - ImGui::PopID(); - } - - ImGui::InvisibleButton("canvas", ViewportScale, ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight); - bool32 IsHovered = ImGui::IsItemHovered(); - bool32 IsActive = ImGui::IsItemActive(); - bool32 IsActivated = ImGui::IsItemActivated(); - bool32 IsDeactivated = ImGui::IsItemDeactivated(); - - if (State->MostRecentlySelectedLayer > -1) - { - project_layer *Layer = File.Layer[State->MostRecentlySelectedLayer]; - if (Layer->NumberOfMasks == 0) { - if (IsActivated && ImGui::IsMouseDown(ImGuiMouseButton_Left)) { - if (State->Tool == tool_pen && !State->Pen.IsActive) { - State->Pen.IsActive = true; - Layer->NumberOfMasks++; - } - } - } - if (State->Pen.IsActive && !ImGui::IsKeyDown(ImGuiKey_Z)) { - if (IsActivated) { - v2 LayerPos = Layer_ScreenSpaceToLocal(Layer, UI, CompBuffer, ViewportMin, io.MousePos); - Mask_PushPoint(&Layer->Mask[Layer->NumberOfMasks-1], LayerPos); - } - if (IsActive) { - mask *Mask = &Layer->Mask[Layer->NumberOfMasks-1]; - mask_point *CurrentPoint = &Mask->Point[Mask->NumberOfPoints-1]; - v2 CompUV = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, io.MousePos); - v2 LayerUV = CompUVToLayerUV(Layer, &CompBuffer, CompUV); - v2 LayerPos = LayerUV * V2(Layer->Source->Info.Width, Layer->Source->Info.Height); - v2 OffsetPos = CurrentPoint->Pos - LayerPos; - CurrentPoint->HandleBezier = true; - CurrentPoint->TangentRight = -OffsetPos; - CurrentPoint->TangentLeft = OffsetPos; - } - // Escape can be pressed to exit point-adding mode or to delete the - // mask if it was just created. - if (ImGui::IsKeyPressed(ImGuiKey_Escape)) { - mask *Mask = &Layer->Mask[Layer->NumberOfMasks-1]; - if (IsActive && Mask->NumberOfPoints == 1) { - Layer->NumberOfMasks--; - Mask->NumberOfPoints = 0; - State->Pen.IsActive = false; - } else { - History_Entry_Commit(Memory, action_entry_default, "Path adding exited"); - History_Action_Change_SwapBool(Memory, &State->Pen.IsActive); - History_Entry_End(Memory); - } - IsDeactivated = false; // just in case escape and mouse release happen simultaneously - } - mask *Mask = &Layer->Mask[Layer->NumberOfMasks-1]; - if (IsDeactivated) { - mask *Mask = &Layer->Mask[Layer->NumberOfMasks-1]; - if (Mask->NumberOfPoints == 1) { - // NOTE(fox): We have to use this slightly janky way of writing to - // the history tree since we can only create entries/actions once we - // know the user is committed to them. Might write an escapable - // entry mode if we do this often. - uint16 PreviousNumberOfMasks = Layer->NumberOfMasks - 1; - uint16 PreviousNumberOfPoints = Mask->NumberOfPoints - 1; - bool32 NotActive = false; - History_Entry_Commit(Memory, action_entry_default, "Create mask"); - History_Action_Change(Memory, &State->Pen.IsActive, &NotActive, - &State->Pen.IsActive, action_type_change_u32); - History_Action_Change(Memory, &Layer->NumberOfMasks, &PreviousNumberOfMasks, - &Layer->NumberOfMasks, action_type_change_u16); - History_Action_Change(Memory, &Mask->NumberOfPoints, &PreviousNumberOfPoints, - &Mask->NumberOfPoints, action_type_change_u16); - History_Entry_End(Memory); - } else { - uint16 PreviousNumberOfPoints = Mask->NumberOfPoints - 1; - mask_point *CurrentPoint = &Mask->Point[Mask->NumberOfPoints-1]; - History_Entry_Commit(Memory, action_entry_default, "Add point"); - History_Action_Change(Memory, &Mask->NumberOfPoints, &PreviousNumberOfPoints, - &Mask->NumberOfPoints, action_type_change_u16); - History_Action_StoreData(Memory, &CurrentPoint, sizeof(mask_point)); - History_Entry_End(Memory); - } - } - if (State->Tool != tool_pen) { - State->Pen.IsActive = false; - } - } - } - - ImGui::OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonMiddle); - if (ImGui::BeginPopup("context")) { - if (ImGui::MenuItem("Scalar", NULL, false, InstructionMode != instruction_mode_scalar)) { InstructionMode = instruction_mode_scalar; State->UpdateFrame = true; } -#if ARM - if (ImGui::MenuItem("NEON", NULL, false, InstructionMode != instruction_mode_neon)) { InstructionMode = instruction_mode_neon; State->UpdateFrame = true; } -#else - if (ImGui::MenuItem("SSE", NULL, false, InstructionMode != instruction_mode_sse)) { InstructionMode = instruction_mode_sse; State->UpdateFrame = true; } - if (ImGui::MenuItem("AVX2", NULL, false, InstructionMode != instruction_mode_avx)) { InstructionMode = instruction_mode_avx; State->UpdateFrame = true; } -#endif - ImGui::EndPopup(); - } - - if (IsHovered && IsActivated && ImGui::IsMouseDown(ImGuiMouseButton_Left)) - { - // Point to zoom in on if Z is held - UI->TempZoomRatio = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, io.MousePos); - - // Layer selection - if (!ImGui::IsKeyDown(ImGuiKey_Z) || !State->Pen.IsActive) { - for (int i = File.NumberOfLayers - 1; i >= 0; i--) { - project_layer *Layer = File.Layer[i]; - if (!io.KeyShift) DeselectAllLayers(&File, State); - v2 LayerUV = CompUVToLayerUV(Layer, &CompBuffer, UI->TempZoomRatio); - if (TestUV(LayerUV) && !Layer->IsSelected) - { - SelectLayer(Layer, State, i); - break; - } - } - } - } - - if (IsActive && ImGui::IsMouseDragging(ImGuiMouseButton_Right, -1.0f)) - { - UI->CompPos.x += io.MouseDelta.x; - UI->CompPos.y += io.MouseDelta.y; - } - - if (IsActive && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1.0f) && ImGui::IsKeyDown(ImGuiKey_Z)) - { - real32 Distance = io.MouseDelta.x + io.MouseDelta.y; - UI->CompZoom.x += (Distance)*(real32)CompBuffer.Width/CompBuffer.Height; - UI->CompZoom.y += (Distance); - UI->CompPos.x -= ((Distance)*(real32)CompBuffer.Width/CompBuffer.Height)*UI->TempZoomRatio.x; - UI->CompPos.y -= Distance*UI->TempZoomRatio.y; - } - - ImGui::SetCursorScreenPos(ImVec2(ViewportMin.x, ViewportMin.y + ViewportScale.y - ImGui::GetFontSize()*1.5)); - - ImGui::Text("%.1f", 100.0f * (UI->CompZoom.x / CompBuffer.Width)); - if (State->MsgTime > 0) { - ImGui::SameLine(); - ImGui::SetCursorPosX((ViewportScale.x / 5)*4); - ImGui::Text(State->Msg); - State->MsgTime--; - } - - - ImGui::End(); -} - -// 1 for left, 2 for right, 3 for both -static bool32 -ImGui_SlidingLayer(project_layer *Layer, real32 *DraggingThreshold, real32 Delta, int16 TimelineZoom, int16 Side) -{ - bool32 Result = 0; - if (ImGui::IsItemActivated()) - { - // if (Side & 1) - // Layer->StartFrame += Increment; - // if (Side & 2) - // Layer->EndFrame += Increment; - // if (Side == 3) { - } - if (ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) - { - ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); - *DraggingThreshold += Delta; - if (abs(*DraggingThreshold) >= TimelineZoom) { - int16 Increment = *DraggingThreshold/TimelineZoom; - - if (Side & 1) - Layer->StartFrame += Increment; - if (Side & 2) - Layer->EndFrame += Increment; - if (Side == 3) { - // TODO(fox): Make frame offset in keyframes local! - IncrementKeyframesInLayer(Layer, Increment); - if (Layer->Source->SourceType == source_type_video) { - Layer->BitmapInfo.FrameOffset += Increment; - } - } - *DraggingThreshold += -1*Increment*TimelineZoom; - } - Result = 1; - } - return Result; -} - - - -static char ImGuiPrefs[] = "[Window][DockSpaceViewport_11111111]" -"\nPos=0,0" -"\nSize=3200,1800" -"\nCollapsed=0" -"\n" -"\n[Window][Debug##Default]" -"\nPos=60,60" -"\nSize=400,400" -"\nCollapsed=0" -"\n" -"\n[Window][Viewport]" -"\nPos=528,0" -"\nSize=2168,1171" -"\nCollapsed=0" -"\nDockId=0x00000005,0" -"\n" -"\n[Window][###Properties]" -"\nPos=0,0" -"\nSize=526,1171" -"\nCollapsed=0" -"\nDockId=0x00000003,0" -"\n" -"\n[Window][Timeline]" -"\nPos=0,1173" -"\nSize=3200,627" -"\nCollapsed=0" -"\nDockId=0x00000002,0" -"\n" -"\n[Window][Dear ImGui Demo]" -"\nPos=1881,692" -"\nSize=550,680" -"\nCollapsed=0" -"\n" -"\n[Window][Files]" -"\nPos=2698,0" -"\nSize=502,913" -"\nCollapsed=0" -"\nDockId=0x00000007,0" -"\n" -"\n[Window][Effects list]" -"\nPos=2698,915" -"\nSize=502,256" -"\nCollapsed=0" -"\nDockId=0x00000008,0" -"\n" -"\n[Docking][Data]" -"\nDockSpace ID=0x8B93E3BD Window=0xA787BDB4 Pos=0,0 Size=3200,1800 Split=Y Selected=0x13926F0B" -"\n DockNode ID=0x00000001 Parent=0x8B93E3BD SizeRef=3200,1171 Split=X Selected=0x13926F0B" -"\n DockNode ID=0x00000003 Parent=0x00000001 SizeRef=526,1171 Selected=0xDBB8CEFA" -"\n DockNode ID=0x00000004 Parent=0x00000001 SizeRef=2672,1171 Split=X Selected=0x13926F0B" -"\n DockNode ID=0x00000005 Parent=0x00000004 SizeRef=2115,1171 CentralNode=1 Selected=0x13926F0B" -"\n DockNode ID=0x00000006 Parent=0x00000004 SizeRef=502,1171 Split=Y Selected=0x86FA2F90" -"\n DockNode ID=0x00000007 Parent=0x00000006 SizeRef=502,913 Selected=0x86FA2F90" -"\n DockNode ID=0x00000008 Parent=0x00000006 SizeRef=502,256 Selected=0x812F222D" -"\n DockNode ID=0x00000002 Parent=0x8B93E3BD SizeRef=3200,627 HiddenTabBar=1 Selected=0x0F18B61B"; - -[Window][DockSpaceViewport_11111111] -Pos=0,0 -Size=3200,1800 -Collapsed=0 - -[Window][Debug##Default] -Pos=122,442 -Size=400,400 -Collapsed=0 - -[Window][Viewport] -Pos=596,34 -Size=2079,1149 -Collapsed=0 -DockId=0x00000010,0 - -[Window][###Properties] -Pos=0,34 -Size=594,452 -Collapsed=0 -DockId=0x0000000B,0 - -[Window][Timeline] -Pos=0,1185 -Size=3200,615 -Collapsed=0 -DockId=0x0000000A,0 - -[Window][Dear ImGui Demo] -Pos=2677,34 -Size=523,633 -Collapsed=0 -DockId=0x00000011,1 - -[Window][Files] -Pos=2677,669 -Size=523,514 -Collapsed=0 -DockId=0x00000012,0 - -[Window][Effects list] -Pos=2717,414 -Size=483,623 -Collapsed=0 -DockId=0x00000008,0 - -[Window][Graph editor] -Pos=0,949 -Size=3200,526 -Collapsed=0 -DockId=0x00000009,0 - -[Window][undotree] -Pos=2367,83 -Size=256,565 -Collapsed=0 - -[Window][memoryviewer] -Pos=50,273 -Size=800,200 -Collapsed=0 - -[Window][Example: Custom rendering] -Pos=758,789 -Size=485,414 -Collapsed=0 - -[Window][Memory viewer] -Pos=2677,669 -Size=523,514 -Collapsed=0 -DockId=0x00000012,1 - -[Window][Graph info] -Pos=1303,1142 -Size=235,353 -Collapsed=0 - -[Window][Properties] -Pos=0,34 -Size=495,1056 -Collapsed=0 -DockId=0x0000000F,0 - -[Window][Colors] -Pos=2677,34 -Size=523,633 -Collapsed=0 -DockId=0x00000011,0 - -[Window][Menu] -Pos=0,0 -Size=3200,32 -Collapsed=0 -DockId=0x0000000D,0 - -[Window][Stable Diffusion] -Pos=2206,684 -Size=421,462 -Collapsed=0 - -[Window][SD prompt input] -Pos=2677,669 -Size=523,514 -Collapsed=0 -DockId=0x00000012,2 - -[Window][Example: Console] -Pos=747,851 -Size=520,600 -Collapsed=0 - -[Window][SD gallery] -Pos=0,488 -Size=594,695 -Collapsed=0 -DockId=0x0000000C,0 - -[Table][0x861D378E,3] -Column 0 Weight=1.0000 -Column 1 Weight=1.0000 -Column 2 Weight=1.0000 - -[Table][0x1F146634,3] -RefScale=13 -Column 0 Width=63 -Column 1 Width=63 -Column 2 Width=63 - -[Table][0x64418101,3] -RefScale=13 -Column 0 Width=63 -Column 1 Width=63 -Column 2 Width=63 - -[Table][0xC9935533,3] -Column 0 Weight=1.0000 -Column 1 Weight=1.0000 -Column 2 Weight=1.0000 - -[Docking][Data] -DockSpace ID=0x8B93E3BD Window=0xA787BDB4 Pos=0,0 Size=3200,1800 Split=Y Selected=0x13926F0B - DockNode ID=0x0000000D Parent=0x8B93E3BD SizeRef=3200,32 HiddenTabBar=1 Selected=0xA57AB2C6 - DockNode ID=0x0000000E Parent=0x8B93E3BD SizeRef=3200,1766 Split=Y - DockNode ID=0x00000001 Parent=0x0000000E SizeRef=3200,1149 Split=X Selected=0x13926F0B - DockNode ID=0x00000003 Parent=0x00000001 SizeRef=594,1171 Split=Y Selected=0xDBB8CEFA - DockNode ID=0x0000000B Parent=0x00000003 SizeRef=521,452 Selected=0xDBB8CEFA - DockNode ID=0x0000000C Parent=0x00000003 SizeRef=521,695 Selected=0x56290987 - DockNode ID=0x00000004 Parent=0x00000001 SizeRef=2604,1171 Split=X Selected=0x13926F0B - DockNode ID=0x00000005 Parent=0x00000004 SizeRef=2079,1171 Split=X Selected=0x13926F0B - DockNode ID=0x0000000F Parent=0x00000005 SizeRef=495,856 Selected=0x199AB496 - DockNode ID=0x00000010 Parent=0x00000005 SizeRef=2199,856 CentralNode=1 Selected=0x13926F0B - DockNode ID=0x00000006 Parent=0x00000004 SizeRef=523,1171 Split=Y Selected=0x86FA2F90 - DockNode ID=0x00000007 Parent=0x00000006 SizeRef=502,412 Split=Y Selected=0x86FA2F90 - DockNode ID=0x00000011 Parent=0x00000007 SizeRef=483,633 Selected=0xBF7DFDC9 - DockNode ID=0x00000012 Parent=0x00000007 SizeRef=483,514 Selected=0x59A2A092 - DockNode ID=0x00000008 Parent=0x00000006 SizeRef=502,623 Selected=0x812F222D - DockNode ID=0x00000002 Parent=0x0000000E SizeRef=3200,615 Split=Y Selected=0x0F18B61B - DockNode ID=0x00000009 Parent=0x00000002 SizeRef=3250,526 Selected=0xA1F22F4D - DockNode ID=0x0000000A Parent=0x00000002 SizeRef=3250,323 HiddenTabBar=1 Selected=0x0F18B61B - - - /* - // Graph window - - if (UI->NumberOfGraphsEnabled) - { - ui_graph Graph = UI->Graph[0]; - - ImGui::SetCursorScreenPos(ImVec2(ImGui::GetCursorScreenPos().x, - TimelineAbsolutePos.y + TimelineSizeWithBorder.y - Graph.WindowYOffset)); - - ImVec2 GraphMin = ImVec2(TimelineAbsolutePos.x, ImGui::GetCursorScreenPos().y); - ImVec2 GraphSize = ImVec2(TimelineSizeWithBorder.x, Graph.WindowYOffset); - - ImDrawList* draw_list = ImGui::GetWindowDrawList(); - draw_list->AddRectFilled(GraphMin, GraphMin + GraphSize, - IM_COL32(0, 0, 30, 50)); - - // draw_list->PushClipRect(GraphMin, GraphMin + GraphSize, true); - // draw_list->PopClipRect(); - - ImVec2 LeftPos[2]; - ImVec2 MidPos[2]; - ImVec2 RightPos[2]; - ImU32 col = ImGui::GetColorU32(ImGuiCol_ScrollbarGrab); - - for (int b = 0; b < Property->NumberOfTotalKeyframes; b++) { - keyframe *Keyframe = KeyframeLookup(Property, b); - // int32 Index = KeyframeMemoryToIndex(Property, b); - - ImGui::PushID(Keyframe); - - real32 MinVal = Property->LocalMinVal.f; - real32 MaxVal = Property->LocalMaxVal.f; - - // Normalized ratio between the smallest and largest value - real32 HandleYRatio = (Keyframe->Value.f - MaxVal) / (MaxVal - MinVal); - real32 HandleYRatio_L = (Keyframe->Value.f + Keyframe->TangentLeft.y - MaxVal) / (MaxVal - MinVal); - real32 HandleYRatio_R = (Keyframe->Value.f + Keyframe->TangentRight.y - MaxVal) / (MaxVal - MinVal); - - real32 LocalHandlePosX = UI->TimelineZoom*Keyframe->FrameNumber; - real32 LocalHandlePosX_L = LocalHandlePosX + UI->TimelineZoom*Keyframe->TangentLeft.x; - real32 LocalHandlePosX_R = LocalHandlePosX + UI->TimelineZoom*Keyframe->TangentRight.x; - - real32 HandlePosX = TimelineStartingPos.x + LocalHandlePosX - FontHeight*0.5; - real32 HandlePosX_L = TimelineStartingPos.x + LocalHandlePosX_L - FontHeight*0.5; - real32 HandlePosX_R = TimelineStartingPos.x + LocalHandlePosX_R - FontHeight*0.5; - - real32 LocalHandlePosY = HandleYRatio * Property->GraphLength; - real32 LocalHandlePosY_L = HandleYRatio_L * Property->GraphLength; - real32 LocalHandlePosY_R = HandleYRatio_R * Property->GraphLength; - - real32 HandlePosY = MinPos.y - LocalHandlePosY + Property->GraphYOffset; - real32 HandlePosY_L = MinPos.y - LocalHandlePosY_L + Property->GraphYOffset; - real32 HandlePosY_R = MinPos.y - LocalHandlePosY_R + Property->GraphYOffset; - - ImVec2 HandlePos = ImVec2(HandlePosX, HandlePosY); - ImVec2 HandlePos_L = ImVec2(HandlePosX_L, HandlePosY_L); - ImVec2 HandlePos_R = ImVec2(HandlePosX_R, HandlePosY_R); - - if (UI->BoxSelectActive && UI->BoxStart.y >= NextY) { - if (IsRectTouching(UI->BoxStart, UI->BoxEnd, HandlePos, HandlePos + KeyframeSize)) { - Keyframe->IsSelected = true; - State->RecentSelectionType = selection_keyframe; - } else if (!io.KeyShift) { - Keyframe->IsSelected = false; - } - } - - ImGui::PushStyleColor(ImGuiCol_Button, col); - - ImGui::SetCursorScreenPos(ImVec2(HandlePosX - FontHeight*1.5, HandlePosY - FontHeight*1.5)); - ImGui::Text("%.02f", Keyframe->Value.f); - - ImGui::SetCursorScreenPos(ImVec2(HandlePosX - FontHeight*1.0, HandlePosY - FontHeight*1.0)); - ImGui::InvisibleButton("##keyframepoint", ImVec2(FontHeight*2, FontHeight*2), ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight); - - draw_list->AddRect(ImVec2(HandlePosX - FontHeight*0.5, HandlePosY - FontHeight*0.5), - ImVec2(HandlePosX + FontHeight*0.5, HandlePosY + FontHeight*0.5), - ImGui::GetColorU32(ImGuiCol_ButtonHovered)); - - ImGui_KeyframeDragging(File, State, UI, Property, b, io, 1); - - if (Keyframe->IsSelected && Keyframe->Type == bezier) { - - ImGui::SetCursorScreenPos(ImVec2(HandlePosX_L, HandlePosY_L)); - draw_list->AddCircle(ImVec2(HandlePosX_L, HandlePosY_L), 2, col, 16, 1); - ImGui::Button("##keyframehandleleft", ImVec2(FontHeight, FontHeight)); - - ImGui_KeyframeDragging(File, State, UI, Property, b, io, 2); - - ImGui::SetCursorScreenPos(ImVec2(HandlePosX_R, HandlePosY_R)); - ImGui::Button("##keyframehandleright", ImVec2(FontHeight, FontHeight)); - - ImGui_KeyframeDragging(File, State, UI, Property, b, io, 3); - - draw_list->AddLine(MidPos[b & 1], RightPos[b & 1], col, 1.0f); - draw_list->AddLine(MidPos[b & 1], LeftPos[b & 1], col, 1.0f); - } - - ImGui::PopStyleColor(); - - ImGui::PopID(); - } - - // TODO(fox): Reformat this so it's all done in one loop. - - for (int b = 0; b < Property->NumberOfTotalKeyframes; b++) { - keyframe *Keyframe = KeyframeLookup(Property, b); - - real32 MinVal = Property->LocalMinVal.f; - real32 MaxVal = Property->LocalMaxVal.f; - - real32 HandleYRatio = (Keyframe->Value.f - MaxVal) / (MaxVal - MinVal); - real32 HandleYRatio_L = (Keyframe->Value.f + Keyframe->TangentLeft.y - MaxVal) / (MaxVal - MinVal); - real32 HandleYRatio_R = (Keyframe->Value.f + Keyframe->TangentRight.y - MaxVal) / (MaxVal - MinVal); - - real32 LocalHandlePosX = UI->TimelineZoom*Keyframe->FrameNumber; - real32 LocalHandlePosX_L = LocalHandlePosX + UI->TimelineZoom*Keyframe->TangentLeft.x; - real32 LocalHandlePosX_R = LocalHandlePosX + UI->TimelineZoom*Keyframe->TangentRight.x; - - real32 HandlePosX = TimelineStartingPos.x + LocalHandlePosX - FontHeight*0.5; - real32 HandlePosX_L = TimelineStartingPos.x + LocalHandlePosX_L - FontHeight*0.5; - real32 HandlePosX_R = TimelineStartingPos.x + LocalHandlePosX_R - FontHeight*0.5; - - real32 LocalHandlePosY = HandleYRatio * Property->GraphLength; - real32 LocalHandlePosY_L = HandleYRatio_L * Property->GraphLength; - real32 LocalHandlePosY_R = HandleYRatio_R * Property->GraphLength; - - real32 HandlePosY = MinPos.y - LocalHandlePosY + Property->GraphYOffset; - real32 HandlePosY_L = MinPos.y - LocalHandlePosY_L + Property->GraphYOffset; - real32 HandlePosY_R = MinPos.y - LocalHandlePosY_R + Property->GraphYOffset; - - ImVec2 HandlePos = ImVec2(HandlePosX, HandlePosY); - ImVec2 HandlePos_L = ImVec2(HandlePosX_L, HandlePosY_L); - ImVec2 HandlePos_R = ImVec2(HandlePosX_R, HandlePosY_R); - - MidPos[b & 1] = HandlePos; - LeftPos[b & 1] = HandlePos_L; - RightPos[b & 1] = HandlePos_R; - - if (b != 0) - { - if (b & 1) { - if (Keyframe->Type == linear) - draw_list->AddLine(MidPos[0], MidPos[1], col, 1.0f); - else if (Keyframe->Type == bezier) - draw_list->AddBezierCubic(MidPos[0], RightPos[0], LeftPos[1], MidPos[1], col, 1.0f, 8); - } else { - if (Keyframe->Type == linear) - draw_list->AddLine(MidPos[1], MidPos[0], col, 1.0f); - else if (Keyframe->Type == bezier) - draw_list->AddBezierCubic(MidPos[1], RightPos[1], LeftPos[0], MidPos[0], col, 1.0f, 8); - } - } - } - // Horiziontal value lines - - // uint32 LineColor = IM_COL32(200, 200, 200, 40); - // for (int i = 0; i < 10; i++) { - // real32 YPos = MinPos.y + (UI->TimelineZoom/2 * i) + 5; - // ImVec2 Min = ImVec2(TimelineStartingPos.x, YPos); - // ImVec2 Max = ImVec2(TimelineStartingPos.x + TimelineSize.x, YPos); - // draw_list->AddLine(Min, Max, LineColor); - // } - - draw_list->PopClipRect(); - - // ImGui::SetCursorScreenPos(ImVec2(MinPos.x, MinPos.y)); - // ImGui::Button("##SplitMove", ImVec2(TimelineBorderPadding.x, SidebarSizeWithBorder.y)); - // if (ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) - // { - // UI->TimelineSplit += io.MouseDelta.x; - // } - - ImGui::SetCursorScreenPos(ImVec2(MinPos.x, MinPos.y)); - ImGui::InvisibleButton("AnimationCurves", ImVec2(TimelineSize.x - 20, GraphWindowHeight), ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight); - // NOTE(fox): I'm reusing this struct for the other - // channels, so I'm OR'ing it. Also persists across layers. - AnimationCurves.IsItemHovered |= ImGui::IsItemHovered(); - AnimationCurves.IsItemActive |= ImGui::IsItemActive(); - AnimationCurves.IsItemActivated |= ImGui::IsItemActivated(); - AnimationCurves.IsItemDeactivated |= ImGui::IsItemDeactivated(); - AnimationCurves.LeftClick |= ImGui::IsMouseDown(ImGuiMouseButton_Left); - AnimationCurves.RightClick |= ImGui::IsMouseDown(ImGuiMouseButton_Right); - - if (AnimationCurves.IsItemHovered && AnimationCurves.IsItemActivated && - ImGui::IsMouseDown(ImGuiMouseButton_Right)) { - real32 LocalMousePos = io.MousePos.y - MinPos.y - Property->GraphYOffset; - UI->TempZoomRatioGraph = LocalMousePos / Property->GraphLength; - } - // DebugWatchVar("LocalMousePos", &LocalMousePos, d_float); - - if (AnimationCurves.IsItemActive && ImGui::IsMouseDragging(ImGuiMouseButton_Right, -1)) - { - Property->GraphLength += io.MouseDelta.x; - Property->GraphYOffset -= io.MouseDelta.x*UI->TempZoomRatioGraph; - Property->GraphYOffset += io.MouseDelta.y; - } - } - */ - -#if 0 - // Timeline frame ticks - - ImGui::SetCursorScreenPos(TimelineStartingPos); - if (UI->TimelineZoom > 10) { - for (float x = 0; x < File->NumberOfFrames + 2; x += 1) { - uint32 LineColor = IM_COL32(200, 200, 200, 40); - ImVec2 Min = ImVec2(TimelineStartingPos.x + UI->TimelineZoom * x, TimelineStartingPos.y); - ImVec2 Max = ImVec2(Min.x + 2, WindowMaxAbs.y); - if (x == File->CurrentFrame) continue; - draw_list->AddLine(Min, Max, LineColor); - char buf2[6]; - if (((uint32)x % File->FPS) == 0) - sprintf(buf2, "%.2i:%.2i", (uint32)x / File->FPS, (uint32)x % File->FPS); - else - sprintf(buf2, ":%.2i", (uint32)x % File->FPS); - draw_list->AddText(ImVec2(Min.x, TimelineAbsolutePos.y), IM_COL32(200, 200, 200, 130), buf2); - } - } -#else -#endif - -#if 0 - // Playhead line - - uint32 LineColor = IM_COL32(200, 200, 200, 200); - ImVec2 Min = PlayheadPos; - ImVec2 Max = ImVec2(Min.x + 2, Min.y + TimelineSizeWithBorder.y + TopbarSize.y/2); - draw_list->AddLine(Min, Max, LineColor); -#endif - -#if 0 - // Scrollbar - - real32 MaxScrollPos = UI->TimelineZoom * (File->NumberOfFrames + 1); - - real32 ScrollRatio = Normalize(-1 * (UI->ScrollXOffset / MaxScrollPos)); - DebugWatchVar("ScrollXOffset: %.2f", &UI->ScrollXOffset, d_float); - real32 BarRatio = (MaxZoom / UI->TimelineZoom); - DebugWatchVar("BarRatio: %.2f", &BarRatio, d_float); - - DebugWatchVar("Timelinezoom: %.2f", &UI->TimelineZoom, d_float); - - // ImVec2 SMinP = TimelineAbsolutePos + ImVec2(ScrollRatio * TimelineSizeWithBorder.x, TimelineSize.y - 200); - // ImVec2 SMaxP = TimelineAbsolutePos + ImVec2((ScrollRatio + BarRatio) * TimelineSizeWithBorder.x, TimelineSize.y + 200); - // draw_list->AddRectFilled(SMinP, SMaxP, - // IM_COL32(0, 200, 200, 50)); - ImVec2 BarMinPos = ImVec2(ScrollRatio * TimelineSizeWithBorder.x, TimelineSize.y - 50); - ImVec2 BarSize = ImVec2(BarRatio * TimelineSizeWithBorder.x, TimelineSize.y + 10); - - ImVec2 SideSize = ImVec2(FontHeight, 0); - - ImGui::SetCursorScreenPos(TimelineAbsolutePos + BarMinPos); - ImGui::Button("##scrollbarleft", ImVec2(SideSize.x, BarSize.y)); - ImGui::SetCursorScreenPos(TimelineAbsolutePos + BarMinPos + SideSize); - ImGui::Button("##scrollbarhori", BarSize - SideSize*2); - - if (ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) - { - ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); - UI->ScrollXOffset -= io.MouseDelta.x / BarRatio; - } - - ImGui::SetCursorScreenPos(TimelineAbsolutePos + BarMinPos + ImVec2(BarSize.x, 0) - SideSize); - ImGui::Button("##scrollbarright", ImVec2(SideSize.x, BarSize.y)); - - if (ImGui::IsItemActivated()) { - UI->TempZoomRatioTimeline = UI->TimelineZoom; - } - - bool32 asda = false; - if (ImGui::IsKeyPressed(ImGuiKey_F)) { - asda = true; - } - - if ((ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) || asda) - { - ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); - - real32 test = asda ? 0.125 : (-io.MouseDelta.x / TimelineSize.x); - real32 MouseDelta = TimelineSize.x * test; - real32 ZoomAmount = MouseDelta / (TimelineSize.x * (1.0f - test)) * UI->TimelineZoom; - UI->TimelineZoom += ZoomAmount/BarRatio; - // if (asda) - // UI->ScrollXOffset -= MouseDelta / BarRatio; - } - - ImGui::SameLine(); - -#endif - - -#if 0 - for (int i = File->NumberOfLayers - 1; i >= 0; i--) - { - project_layer *Layer = File->Layer[i]; - ImGui::PushID(i); - - ImGui::SetCursorScreenPos(ImVec2(SidebarStartingPos.x, ImGui::GetCursorScreenPos().y)); - - draw_list->PushClipRect(SidebarAbsolutePos, SidebarAbsolutePos + TimelineFullSize, true); - if (Layer->IsSelected) { - real32 Y = ImGui::GetCursorScreenPos().y; - draw_list->AddRectFilled(ImVec2(SidebarAbsolutePos.x, Y), - ImVec2(TimelineAbsolutePos.x + TimelineSize.x, Y + FontHeight + FramePadding.y*2), - IM_COL32(255, 255, 255, 50)); - } - draw_list->PopClipRect(); - - ImGui::Button("V"); ImGui::SameLine(); - ImGui::Button("I"); ImGui::SameLine(); - ImGui::Text(Layer->Name); ImGui::SameLine(); - ImGui::Button(BlendmodeNames[Layer->BlendMode]); - ImGui::OpenPopupOnItemClick("blendmode_picker", ImGuiPopupFlags_MouseButtonLeft); - if (ImGui::BeginPopup("blendmode_picker")) { - for (int16 b = 0; b < AmountOf(BlendmodeNames); b++) { - if (ImGui::MenuItem(BlendmodeNames[b], NULL, false, Layer->BlendMode != b)) { - Layer->BlendMode = (blend_mode)b; - State->UpdateFrame = true; - } - // using IsActivated here instead of above loop doesn't seem to - // work; the popup gets closed instead - if (ImGui::IsItemHovered() && io.KeyCtrl) { - Layer->BlendMode = (blend_mode)b; - State->UpdateFrame = true; - } - } - ImGui::EndPopup(); - } - ImGui::SameLine(); - - ImGui::SetCursorScreenPos(ImVec2(SidebarStartingPos.x, ImGui::GetCursorScreenPos().y)); - ImGui::Button("##mover", ImVec2(SidebarSizeWithBorder.x, FontHeight + FramePadding.y*2)); - - // Layer dragging interaction - - if (ImGui::IsItemActive()) { - if (ImGui::IsItemActivated() && !Layer->IsSelected) - { - if (!io.KeyShift) DeselectAllLayers(File, State); - SelectLayer(Layer, State, i); - } - if (ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1) ) - { - ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); - UI->DraggingLayerThreshold -= io.MouseDelta.y; - real32 Threshold = FontHeight + FramePadding.y*2; - if (abs(UI->DraggingLayerThreshold) >= Threshold) - { - int16 Increment = UI->DraggingLayerThreshold/abs(UI->DraggingLayerThreshold); - MoveLayersByIncrement(File, State, Increment); - UI->DraggingLayerThreshold += -1*Increment*Threshold; - State->UpdateFrame = true; - // Cache.Frame[File->CurrentFrame].Cached = false; - } - } - } - - // Properties gap - - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, ItemSpacing.y * UI->KeyframeSpacing)); - for (int a = 0; a < AmountOf(Layer->Property); a++) { - if (Layer->Property[a].IsToggled) - { - property_channel *Property = &Layer->Property[a]; - ImGui::PushID(Property); - // if (Property->IsSelected) { - // real32 Y = ImGui::GetCursorScreenPos().y; - // draw_list->AddRectFilled(ImVec2(SidebarAbsolutePos.x, Y), - // ImVec2(TimelineAbsolutePos.x, Y + FontHeight + FramePadding.y*2), - // IM_COL32(100, 0, 255, 50)); - // } - ImGui::SetCursorScreenPos(ImVec2(SidebarStartingPos.x, ImGui::GetCursorScreenPos().y)); - ImGui::Text(Property->Name); - real32 YInit = ImGui::GetCursorScreenPos().y; - ImGui::SameLine(); - if (ImGui::Button("K")) - Keyframe_Insert(Property, Memory, File->CurrentFrame, Property->CurrentValue.f); - ImGui::SameLine(); - if (ImGui::Button("G")) { - UI->Graph[UI->NumberOfGraphsEnabled].ChannelViewed = Property; - UI->NumberOfGraphsEnabled++; - } - ImGui::SetCursorScreenPos(ImVec2(ImGui::GetCursorScreenPos().x, YInit)); - ImGui::PopID(); - } - } - ImGui::PopStyleVar(); - - ImGui::PopID(); - } -#endif - - - /* - for (int i = File->NumberOfLayers - 1; i >= 0; i--) - { - // The actual layer bars - - project_layer *Layer = File->Layer[i]; - ImGui::PushID(i); - uint16 LayerTLSpan = Layer->EndFrame - Layer->StartFrame; - - // if (Layer->SourceType == video) { - // video_source *Source = (video_source *)Layer->RenderInfo; - // real32 XMin = TimelineMinX + UI->TimelineZoom*Source->VideoFrameOffset; - // // real32 YMin = StartingCursorPosAbs.y + (FontHeight + FramePadding.y*2 + ItemSpacing.y)*i; - // real32 YMin = ImGui::GetCursorScreenPos().y; - // draw_list->AddRect(ImVec2(WindowMin.x, YMin), - // ImVec2(WindowMaxAbs.x, YMin + FontHeight + FramePadding.y*2), - // IM_COL32(255, 255, 255, 50), 2); - // } - - ImGui::SetCursorScreenPos(ImVec2(TimelineStartingPos.x + UI->TimelineZoom*Layer->StartFrame, ImGui::GetCursorScreenPos().y)); - ImGui::Button("##leftbound", ImVec2(0.5 * UI->TimelineZoom, 0)); ImGui::SameLine(); - if (ImGui::IsItemHovered()) { - ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); - } - ImGui_SlidingLayer(Layer, &UI->DraggingKeyframeThreshold, io.MouseDelta.x, UI->TimelineZoom, 1); - - // TODO(fox): Investigate why this button doesn't get lined up with - // leftbound in certain cases. (i.e. rotation property expanded with keyframes) - - ImGui::Button("##layer", ImVec2((LayerTLSpan * UI->TimelineZoom), 0)); ImGui::SameLine(); - if (ImGui::IsItemClicked()) { - if (!io.KeyShift) DeselectAllLayers(File, State); - SelectLayer(Layer, State, i); - } - if (ImGui_SlidingLayer(Layer, &UI->DraggingLayerThreshold, io.MouseDelta.x, UI->TimelineZoom, 3)) { - // TODO(fox): This will be removed once video caching is implemented. - UI->TemporaryUpdateOverride = true; - } - - ImGui::Button("##rightbound", ImVec2(0.5 * UI->TimelineZoom, 0)); - - if (ImGui::IsItemHovered()) { - ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); - } - ImGui_SlidingLayer(Layer, &UI->DraggingKeyframeThreshold, io.MouseDelta.x, UI->TimelineZoom, 2); - - for (int a = Layer->StartFrame; a < Layer->EndFrame; a++) { - cached_bitmap *Bitmap = Cache_CheckBitmap(Layer->Source, &Layer->BitmapInfo, Memory, a); - if (Bitmap) { - ImVec2 MinPos = ImVec2(TimelineStartingPos.x + UI->TimelineZoom * a, ImGui::GetCursorScreenPos().y); - draw_list->AddRect(MinPos, ImVec2(MinPos.x + UI->TimelineZoom, MinPos.y + 2.0f), ImColor(0, 255, 0, 255)); - } - } - - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, ItemSpacing.y * UI->KeyframeSpacing)); - ImGui::SetCursorPosY(ImGui::GetCursorPos().y + (ItemSpacing.y * UI->KeyframeSpacing / 2)); - - for (int a = 0; a < AmountOf(Layer->Property); a++) { - if (Layer->Property[a].IsToggled) - { - real32 InitialY = ImGui::GetCursorScreenPos().y; - ImGui::NewLine(); - real32 NextY = ImGui::GetCursorScreenPos().y; - - property_channel *Property = &Layer->Property[a]; - ImGui::PushID(Property); - - for (int b = 0; b < Layer->Property[a].NumberOfTotalKeyframes; b++) { - keyframe *Keyframe = KeyframeLookup(Property, b); - real32 KeyframeOrigin = TimelineStartingPos.x + UI->TimelineZoom*Keyframe->FrameNumber; - ImVec2 KeyframePosition = ImVec2(KeyframeOrigin - FontHeight/2, InitialY); - - ImGui::PushID(Keyframe); - - ImGui::SetCursorScreenPos(KeyframePosition); - - // sadly ImGui::Selectable doesn't work here - if (Keyframe->IsSelected) - ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetColorU32(ImGuiCol_ButtonHovered)); - - ImGui::Button("##keyframe", ImVec2(FontHeight, FontHeight)); - ImGui::SameLine(); - - if (Keyframe->IsSelected) - ImGui::PopStyleColor(); - - if (UI->BoxSelectActive && UI->BoxStart.y < NextY) { - if (IsRectTouching(UI->BoxStart, UI->BoxEnd, KeyframePosition, KeyframePosition + KeyframeSize)) { - SelectKeyframe(File, Layer, Property, Keyframe); - State->RecentSelectionType = selection_keyframe; - } else if (!io.KeyShift) { - Keyframe->IsSelected = false; - } - } - - ImGui_KeyframeDragging(File, State, UI, Property, b, io, 0); - - - ImGui::PopID(); - } - - ImGui::SetCursorScreenPos(ImVec2(ImGui::GetCursorScreenPos().x, NextY)); - - ImGui::PopID(); - } - } - - ImGui::SetCursorPosY(ImGui::GetCursorPos().y - (ItemSpacing.y * UI->KeyframeSpacing / 2)); - ImGui::PopStyleVar(); - - ImGui::PopID(); - } - */ - - -#if 0 - -// Old code: - - ImVec2 SideSize = ImVec2(FontHeight, 0); - real32 BarYSize = 50; - real32 BarYPos = TimelineSize.y - BarYSize; - - real32 BarXPos = -TimelineSizeWithBorder.x * UI->TimelinePercentOffset; - real32 BarXSize = TimelineSizeWithBorder.x / (1 / UI->TimelinePercentZoomed); - - real32 MouseDelta = io.MouseDelta.x / TimelineSize.x; - - // A bit of manipulation to clip the bar handles to the edges if they go over. - real32 LeftPos = (BarXPos > 0) ? BarXPos : 0; - ImVec2 BarClippedLeftPos(LeftPos, BarYPos); - - real32 BarOffset = BarXPos - LeftPos; - real32 BarClippedSize = (BarXSize + BarXPos > TimelineSizeWithBorder.x) ? TimelineSizeWithBorder.x - BarXPos : BarXSize + BarOffset; - if (LeftPos == 0 && BarClippedSize > TimelineSizeWithBorder.x) BarClippedSize = TimelineSizeWithBorder.x; - - ImGui::SetCursorScreenPos(TimelineAbsolutePos + BarClippedLeftPos); - ImGui::Button("##scrollbarleft", ImVec2(SideSize.x, BarYSize)); - - if ((ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1))) - { - UI->TimelinePercentZoomed -= MouseDelta; - UI->TimelinePercentOffset -= MouseDelta; - } - - ImGui::SetCursorScreenPos(TimelineAbsolutePos + BarClippedLeftPos + SideSize); - ImGui::Button("##scrollbarhori", ImVec2(BarClippedSize, BarYSize) - SideSize*2); - - if (ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) - { - UI->TimelinePercentOffset -= MouseDelta; - } - - ImGui::SetCursorScreenPos(TimelineAbsolutePos + BarClippedLeftPos + ImVec2(BarClippedSize, 0) - SideSize ); - ImGui::Button("##scrollbarright", ImVec2(SideSize.x, BarYSize)); - - if ((ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1))) - { - UI->TimelinePercentZoomed += MouseDelta; - } - -// New code: - - ImVec2 MouseDelta = io.MouseDelta / TimelineSize; - - real32 BarHandleSize = FontHeight; - real32 BarThickness = 50; - - real32 BarH_XPos = -TimelineSizeWithBorder.x * UI->TimelinePercentOffset; - real32 BarH_Size = TimelineSizeWithBorder.x / (1 / UI->TimelinePercentZoomed); - - // I use "UI" to denote the size/position after clipping the bar so that it - // doesn't go out of bounds and the handles are always selectable at the edges. - - real32 BarH_XOffset = (BarH_XPos > 0) ? BarH_XPos : 0; - ImVec2 BarH_PosUI = TimelineAbsolutePos + ImVec2(BarH_XOffset, TimelineSize.y - BarThickness); - - real32 BarH_SizeUI = (BarH_Size + BarH_XPos > TimelineSizeWithBorder.x) ? - TimelineSizeWithBorder.x - BarH_XPos : - BarH_Size + (BarH_XPos - BarH_XOffset); - - if (BarH_XOffset == 0 && BarH_SizeUI > TimelineSizeWithBorder.x) - BarH_SizeUI = TimelineSizeWithBorder.x; - - BarH_SizeUI = BarH_SizeUI - BarHandleSize*2; - - ImGui::SetCursorScreenPos(BarH_PosUI); - ImGui::Button("##scrollbarleft", ImVec2(BarHandleSize, BarThickness)); - - if ((ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1))) - { - UI->TimelinePercentZoomed -= MouseDelta.x; - UI->TimelinePercentOffset -= MouseDelta.x; - } - - ImGui::SetCursorScreenPos(BarH_PosUI + ImVec2(BarHandleSize, 0)); - ImGui::Button("##scrollbarhori", ImVec2(BarH_SizeUI, BarThickness)); - - if (ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) - { - UI->TimelinePercentOffset -= MouseDelta.x; - } - - ImGui::SetCursorScreenPos(BarH_PosUI + ImVec2(BarHandleSize, 0) + ImVec2(BarH_SizeUI, 0)); - ImGui::Button("##scrollbarright", ImVec2(BarHandleSize, BarThickness)); - - if ((ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1))) - { - UI->TimelinePercentZoomed += MouseDelta.x; - } - -#endif -#endif diff --git a/package.sh b/package.sh new file mode 100755 index 0000000..01868b1 --- /dev/null +++ b/package.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +# simple helper to zip up the builds +cd bin + +# windows +mkdir real2d_windows +cp windows_dll/* real2d_windows +cp real2d.exe real2d_windows +zip -r zip/real2d_x86_windows.zip real2d_windows + +# mac +zip -r zip/real2d_x86_mac.zip real_x86.app +zip -r zip/real2d_m1_mac.zip real_arm.app + +# linux +zip -r zip/real2d_x86_linux.zip real2d_x86_linux +zip -r zip/real2d_arm_linux.zip real2d_arm_linux + +rsync -avz bin/zip/* root@foxcam.net:/var/www/foxcam/bin/ diff --git a/stable_diffusion.cpp b/stable_diffusion.cpp index 022c3c2..3d0c26b 100644 --- a/stable_diffusion.cpp +++ b/stable_diffusion.cpp @@ -33,7 +33,7 @@ SD_JSONToSource(project_data *File, project_state *State, memory *Memory, void * uint64 MaxSize = Width * Height * 4; void *PNGData = Memory_PushScratch(Memory, MaxSize); uint64 PNGSize = 0; - base64_decode(&Data[i], c, (uint8 *)PNGData, &PNGSize); + base64_decode(&Data[i], c, (uint8 *)PNGData, (size_t *)&PNGSize); int x, y, a; void *RawData = stbi_load_from_memory((stbi_uc *)PNGData, PNGSize, &x, &y, &a, 4); Assert(x == Width && y == Height); -- cgit v1.2.3