diff options
author | Fox Caminiti <fox@foxcam.net> | 2022-10-24 22:58:07 -0400 |
---|---|---|
committer | Fox Caminiti <fox@foxcam.net> | 2022-10-24 22:58:07 -0400 |
commit | 87c3fbb37141827622eeadb89189c267ed4baf87 (patch) | |
tree | 74fabb5e25881ce319a513ee2d4f8700a582e30e | |
parent | 7804c6a96d26c2e757d09f1864eb73fb81eb280f (diff) |
development
-rw-r--r-- | createcalls.cpp | 84 | ||||
-rw-r--r-- | defines.h | 1 | ||||
-rw-r--r-- | imgui_ops.h | 2 | ||||
-rw-r--r-- | main.cpp | 174 | ||||
-rw-r--r-- | main.h | 29 | ||||
-rw-r--r-- | memory.h | 3 | ||||
-rw-r--r-- | my_imgui_widgets.cpp | 399 | ||||
-rw-r--r-- | my_math.h | 10 |
8 files changed, 512 insertions, 190 deletions
diff --git a/createcalls.cpp b/createcalls.cpp index 6a830b5..c2122c2 100644 --- a/createcalls.cpp +++ b/createcalls.cpp @@ -35,6 +35,14 @@ Source_Generate(project_data *File, project_state *State, memory *Memory, void * return -1; } +static bezier_point * +Bezier_Lookup(memory *Memory, property_channel *Property, uint16 Index) +{ + Assert(Index < MAX_KEYFRAMES_PER_BLOCK); + block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Property->Block_Bezier_Index[0]); + return &Bezier->Point[Index]; +} + static property_channel Property_InitFloat(char *Name, real32 Val, real32 ScrubVal, real32 MinVal = PROPERTY_REAL_MIN, real32 MaxVal = PROPERTY_REAL_MAX) { property_channel Property = {}; Property.Name = Name; @@ -45,19 +53,55 @@ Property_InitFloat(char *Name, real32 Val, real32 ScrubVal, real32 MinVal = PROP return Property; } +static property_info +Property_GetInfo(memory *Memory, property_channel *Property) +{ + property_info PropertyInfo = {}; + for (int k = 0; k < Property->Keyframe_Count; k++) { + bezier_point *Point = Bezier_Lookup(Memory, Property, k); + PropertyInfo.MinVal = (Point->Pos[0].y < PropertyInfo.MinVal) ? Point->Pos[0].y : PropertyInfo.MinVal; + PropertyInfo.MaxVal = (Point->Pos[0].y > PropertyInfo.MaxVal) ? Point->Pos[0].y : PropertyInfo.MaxVal; + } + return PropertyInfo; +} + static void -Layer_Interact_Evaluate(memory *Memory, project_state *State, int32 *Frame_Start, int32 *Frame_End, real32 *Vertical_Offset) +Layer_Interact_Evaluate(memory *Memory, project_state *State, uint16 Layer_Index_Physical, sorted_comp_info SortedCompInfo, sorted_layer *SortedLayerInfo, + int32 *Frame_Start, int32 *Frame_End, real32 *Vertical_Offset) { if (State->Interact_Active == interact_type_layer_move) { *Frame_Start += (int32)(State->Interact_Offset[0] + 0); *Frame_End += (int32)(State->Interact_Offset[0] + 0); - *Vertical_Offset += (int32)State->Interact_Offset[1]; - } else if (State->Interact_Active == interact_type_layer_timeadjust) { + + real32 DesiredOffset = *Vertical_Offset + (int32)State->Interact_Offset[1]; + bool32 Direction = ((int32)State->Interact_Offset[1] > 0) ? 1 : -1; + int i = (Direction > 0) ? SortedCompInfo.LayerCount - 1 : 0; + bool32 Case = 1; + while (Case) { + sorted_layer SortEntry = SortedLayerInfo[i]; + uint32 Index_Physical = SortEntry.Block_Layer_Index; + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); + bool32 Test = (Direction > 0) ? + ((Layer->Vertical_Offset <= DesiredOffset) && (Layer->Vertical_Offset > *Vertical_Offset)) : + ((Layer->Vertical_Offset >= DesiredOffset) && (Layer->Vertical_Offset < *Vertical_Offset)); + if (!Layer->IsSelected && Test) { + DesiredOffset += Direction; + } + i -= Direction; + Case = (Direction > 0) ? (i >= 0) : (i < SortedCompInfo.LayerCount); + } + *Vertical_Offset = DesiredOffset; + } + else if (State->Interact_Active == interact_type_layer_timeadjust) { int Side[2] = {0}; Assert(State->Interact_Offset[1] == 0 || State->Interact_Offset[1] == 1); Side[(int)State->Interact_Offset[1]] = 1; *Frame_Start += (int32)(State->Interact_Offset[0] * Side[0]); + if (*Frame_Start >= *Frame_End) + *Frame_Start = *Frame_End - 1; *Frame_End += (int32)(State->Interact_Offset[0] * Side[1]); + if (*Frame_End <= *Frame_Start) + *Frame_End = *Frame_Start + 1; } } @@ -81,6 +125,24 @@ Layer_GetSortedArray(sorted_layer *LayerArrayStart, sorted_comp_info *SortedComp return LayerArrayStart + LayerOffset; } +void Layer_RecursiveDeselect(memory *Memory, sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray, uint16 TargetIndex, uint16 PrincipalIndex) +{ + block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, PrincipalIndex); + sorted_comp_info SortedCompInfo = SortedCompArray[PrincipalIndex]; + sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, PrincipalIndex); + for (int i = 0; i < SortedCompInfo.LayerCount; i++) { + sorted_layer SortEntry = SortedLayerInfo[i]; + uint32 Index_Physical = SortEntry.Block_Layer_Index; + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); + if (Layer->IsPrecomp) { + Layer_RecursiveDeselect(Memory, SortedCompArray, SortedLayerArray, TargetIndex, Layer->Block_Source_Index); + } + if (Layer->Block_Composition_Index != TargetIndex) { + Layer->IsSelected = false; + } + } +} + void Layer_SortAll(memory *Memory, sorted_layer *LayerArrayStart, sorted_comp_info *CompStart, uint32 LayerCount, uint32 CompCount) { for (uint32 i = 0; i < LayerCount; i++) { @@ -98,7 +160,7 @@ void Layer_SortAll(memory *Memory, sorted_layer *LayerArrayStart, sorted_comp_in while (SortedIndex_Playhead < SortedCompInfo->CurrentSortIndex) { sorted_layer LayerEntry = SortedLayerInfo[SortedIndex_Playhead]; block_layer *TestLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, LayerEntry.Block_Layer_Index); - if (Layer->Vertical_Offset < TestLayer->Vertical_Offset) { + if (-Layer->Vertical_Offset < -TestLayer->Vertical_Offset) { break; } else { SortedIndex_Playhead++; @@ -106,19 +168,21 @@ void Layer_SortAll(memory *Memory, sorted_layer *LayerArrayStart, sorted_comp_in } if (SortedIndex_Playhead != SortedCompInfo->CurrentSortIndex) { uint8 *Address_Start = (uint8 *)(SortedLayerInfo + SortedIndex_Playhead); - uint8 *Address_End = (uint8 *)(SortedLayerInfo + i); + uint8 *Address_End = (uint8 *)(SortedLayerInfo + SortedCompInfo->CurrentSortIndex) - 1; + Assert(SortedCompInfo->CurrentSortIndex != SortedCompInfo->LayerCount); Arbitrary_ShiftData(Address_Start, Address_End, sizeof(sorted_layer), 1); } sorted_layer *LayerEntry = SortedLayerInfo + SortedIndex_Playhead; LayerEntry->Block_Layer_Index = i; SortedCompInfo->CurrentSortIndex++; } - Assert(CompStart[0].LayerCount == 2); - Assert(CompStart[1].LayerCount == 2); + // Assert(CompStart[0].LayerCount == 3); + // Assert(CompStart[1].LayerCount == 2); // Assert(LayerArrayStart[0].Block_Layer_Index == 0); - // Assert(LayerArrayStart[1].Block_Layer_Index == 1); - // Assert(LayerArrayStart[2].Block_Layer_Index == 2); - // Assert(LayerArrayStart[3].Block_Layer_Index == 3); + // Assert(LayerArrayStart[1].Block_Layer_Index == 2); + // Assert(LayerArrayStart[2].Block_Layer_Index == 4); + // Assert(LayerArrayStart[4].Block_Layer_Index == 1); + // Assert(LayerArrayStart[5].Block_Layer_Index == 3); } block_layer * Layer_Init(project_data *File, memory *Memory) @@ -35,7 +35,6 @@ typedef uint64 ptrsize; // is there a compiler variable for 32 vs 64 bit like #define MAX_PROPERTIES_PER_EFFECT 16 #define MAX_KEYFRAME_BLOCKS 64 #define MAX_KEYFRAMES_PER_BLOCK 32 // max keyframes on a single channel is 2048 -#define STRING_SIZE 1024 // TODO(fox): Paths above STRING_SIZE length aren't handled properly. #define MAX_SELECTED_PROPERTIES 16 diff --git a/imgui_ops.h b/imgui_ops.h index 2249de3..e2627ab 100644 --- a/imgui_ops.h +++ b/imgui_ops.h @@ -1,3 +1,5 @@ + + ImVec2 operator+(ImVec2 A, ImVec2 B) { ImVec2 Result; @@ -82,14 +82,11 @@ static uint32 RandomGlobalIncrement = 0; static void Main_RenderUI(ImGuiIO io, ImVec4 clear_color, SDL_Window *window) { - printf("Call ImGui::Render\n"); ImGui::Render(); glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y); glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w); glClear(GL_COLOR_BUFFER_BIT); - printf("Call GL renderer\n"); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); - printf("Call window swap\n"); SDL_GL_SwapWindow(window); } @@ -131,7 +128,7 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, ui *UI, ImGui::DockSpaceOverViewport(); if (!io.WantCaptureKeyboard) - ImGui_ProcessInputs(State, io); + ImGui_ProcessInputs(File, State, Memory, io); #if 0 @@ -147,10 +144,6 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, ui *UI, #if DEBUG ImGui_DebugUndoTree(&File, &Memory); - if (Debug.ToggleWindow) { - ImGui::ShowDemoWindow(); - ImGui_DebugMemoryViewer(&File, &Memory); - } #endif #endif @@ -159,7 +152,10 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, ui *UI, ImGui_Timeline(File, State, Memory, UI, io); ImGui_File(File, State, Memory, io); - ImGui_DebugMemoryViewer(State); + if (Debug.ToggleWindow) { + ImGui::ShowDemoWindow(); + ImGui_DebugMemoryViewer(State); + } // ImGui::ShowDemoWindow(); #if DEBUG @@ -305,15 +301,13 @@ int main(int argc, char *argv[]) { Memory_InitTable(&GlobalMemory, &Memory, 40 * 1024 * 1024, P_MiscCache, "Misc persistent"); Memory_InitTable(&GlobalMemory, &Memory, sizeof(project_data), F_File, "File", sizeof(project_data)); - Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Precomps, "Precomps", sizeof(block_composition)); - Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Layers, "Layers", sizeof(block_layer)); - Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Sources, "Sources", sizeof(block_source)); - // Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Effects, "Effects"); - // Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Keyframes, "Keyframe blocks"); + Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Precomps, "Precomps", sizeof(block_composition)); + Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Layers, "Layers", sizeof(block_layer)); + Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Sources, "Sources", sizeof(block_source)); + Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Bezier, "Bezier paths (keyframes, masks)", sizeof(block_bezier)); Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Strings, "Strings", sizeof(block_string)); Memory_InitTable(&GlobalMemory, &Memory, (uint64)64 * 1024 * 1024, B_ScratchSpace, "Scratch"); - // Memory_InitTable(&GlobalMemory, &Memory, (uint64)1 * 1024 * 1024, B_CachedBitmapInfo, "Cached bitmap info"); Memory_InitTable(&GlobalMemory, &Memory, (uint64)50 * 1024 * 1024, B_CachedBitmaps, "Cached bitmap buffer"); #if ARM @@ -367,44 +361,141 @@ int main(int argc, char *argv[]) { uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/a.jpg"); block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, 0); - Layer_CreateFromSource(File, State, &Memory, SourceIndex, MainComp->Frame_End); + { + Layer_CreateFromSource(File, State, &Memory, SourceIndex, MainComp->Frame_End); + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, File->Layer_Count - 1); + Layer->Vertical_Offset = 6; + Layer->Col[0] = 1; + Layer->Col[1] = 0; + Layer->Col[2] = 0; + Layer->Block_Composition_Index = 0; + + property_channel *Property = &Layer->x; + Property->Block_Bezier_Index[0] = Memory_Block_AllocateNew(&Memory, F_Bezier); + Property->Block_Bezier_Count = 1; + + block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(&Memory, F_Bezier, Property->Block_Bezier_Index[0]); + Bezier->Occupied = 1; + + Bezier->Point[0].Pos[0] = V2(0, 0); + Bezier->Point[1].Pos[0] = V2(10, 50); + Bezier->Point[2].Pos[0] = V2(20, -50); + Bezier->Point[0].Pos[1] = V2(-4, 0); + Bezier->Point[1].Pos[1] = V2(-4, 0); + Bezier->Point[2].Pos[1] = V2(-4, 0); + Bezier->Point[0].Pos[2] = V2(4, 0); + Bezier->Point[1].Pos[2] = V2(4, 0); + Bezier->Point[2].Pos[2] = V2(4, 0); + Bezier->Point[0].Type = interpolation_type_bezier; + Bezier->Point[1].Type = interpolation_type_bezier; + Bezier->Point[2].Type = interpolation_type_bezier; + Property->Keyframe_Count = 3; + + property_channel *Property2 = &Layer->opacity; + Property2->Block_Bezier_Index[0] = Memory_Block_AllocateNew(&Memory, F_Bezier); + Property2->Block_Bezier_Count = 1; + + block_bezier *Bezier2 = (block_bezier *)Memory_Block_AddressAtIndex(&Memory, F_Bezier, Property2->Block_Bezier_Index[0]); + Bezier2->Occupied = 1; + + Bezier2->Point[0].Pos[0] = V2(0, 0); + Bezier2->Point[1].Pos[0] = V2(20, 1); + Property2->Keyframe_Count = 2; + + /* + property_channel *Property3 = &Layer->y; + Property3->Block_Bezier_Index[0] = Memory_Block_AllocateNew(&Memory, F_Bezier); + Property3->Block_Bezier_Count = 1; + + block_bezier *Bezier3 = (block_bezier *)Memory_Block_AddressAtIndex(&Memory, F_Bezier, Property3->Block_Bezier_Index[0]); + Bezier3->Occupied = 1; + + Bezier3->Point[0].Pos[0] = V2(0, -20); + Bezier3->Point[1].Pos[0] = V2(10, 300); + Bezier3->Point[2].Pos[0] = V2(20, 100); + Bezier3->Point[0].Pos[1] = V2(-4, 0); + Bezier3->Point[1].Pos[1] = V2(-4, 0); + Bezier3->Point[2].Pos[1] = V2(-4, 0); + Bezier3->Point[0].Pos[2] = V2(4, 0); + Bezier3->Point[1].Pos[2] = V2(4, 0); + Bezier3->Point[2].Pos[2] = V2(4, 0); + Bezier3->Point[0].Type = interpolation_type_bezier; + Bezier3->Point[1].Type = interpolation_type_bezier; + Bezier3->Point[2].Type = interpolation_type_bezier; + Property3->Keyframe_Count = 3; + */ + } + // { + // Layer_CreateFromSource(File, State, &Memory, SourceIndex, MainComp->Frame_End); + // block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, File->Layer_Count - 1); + // Layer->Vertical_Offset = 1; + // Layer->Col[0] = 1; + // Layer->Col[1] = 0; + // Layer->Col[2] = 0; + // Layer->Block_Composition_Index = 1; + // } } - block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, 0); - { uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/b.jpg"); block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, 1); - - Layer_CreateFromSource(File, State, &Memory, 1, MainComp->Frame_End); - Layer_CreateFromSource(File, State, &Memory, SourceIndex, MainComp->Frame_End); + // { + // Layer_CreateFromSource(File, State, &Memory, SourceIndex, MainComp->Frame_End); + // block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, File->Layer_Count - 1); + // Layer->Vertical_Offset = 5; + // Layer->Col[0] = 0; + // Layer->Col[1] = 0; + // Layer->Col[2] = 1; + // Layer->Block_Composition_Index = 0; + // } } { uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/c.jpg"); block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, 2); - - Layer_CreateFromSource(File, State, &Memory, SourceIndex, MainComp->Frame_End); + // { + // Layer_CreateFromSource(File, State, &Memory, SourceIndex, MainComp->Frame_End); + // block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, File->Layer_Count - 1); + // Layer->Vertical_Offset = 0; + // Layer->Col[0] = 0; + // Layer->Col[1] = 1; + // Layer->Col[2] = 0; + // Layer->Block_Composition_Index = 1; + // } + // { + // Layer_CreateFromSource(File, State, &Memory, SourceIndex, MainComp->Frame_End); + // block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, File->Layer_Count - 1); + // Layer->Vertical_Offset = 4; + // Layer->Col[0] = 0; + // Layer->Col[1] = 1; + // Layer->Col[2] = 1; + // Layer->Block_Composition_Index = 1; + // } } - block_layer *Layer1 = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, 0); - Layer1->Vertical_Offset = 0; - - block_layer *Layer2 = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, 1); - Layer2->IsPrecomp = true; - Layer2->Vertical_Offset = 1; - Layer2->Col[0] = 1; - - block_layer *Layer3 = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, 2); - Layer3->Vertical_Offset = 0; - Layer3->Col[1] = 1; - Layer3->Block_Composition_Index = 1; - - block_layer *Layer4 = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, 3); - Layer4->Vertical_Offset = 1; - Layer4->Col[2] = 1; - Layer4->Block_Composition_Index = 1; + /* + { + Layer_CreateFromSource(File, State, &Memory, 1, MainComp->Frame_End); + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, File->Layer_Count - 1); + Layer->IsPrecomp = true; + Layer->Vertical_Offset = 9; + Layer->Col[0] = 1; + Layer->Col[1] = 1; + Layer->Col[2] = 1; + Layer->Block_Composition_Index = 0; + } + { + Layer_CreateFromSource(File, State, &Memory, 1, MainComp->Frame_End); + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, File->Layer_Count - 1); + Layer->IsPrecomp = true; + Layer->Vertical_Offset = 10; + Layer->Col[0] = 1; + Layer->Col[1] = 1; + Layer->Col[2] = 1; + Layer->Block_Composition_Index = 0; + } + */ // History_Undo(&Memory); // History_Redo(&Memory); @@ -516,17 +607,14 @@ int main(int argc, char *argv[]) { while (State->IsRunning) { - printf("Call UI\n"); Main_InputTest(File, State, &Memory, &UI, window, textureID); if (State->UpdateFrame) { - printf("Call renderer\n"); Main_Renderer(File, State, &Memory, window, textureID, io); } Assert(Debug.ScratchState == 0); - printf("Call render UI\n"); Main_RenderUI(io, clear_color, window); // TODO(fox): Fix things that rely on this. @@ -39,9 +39,10 @@ enum blend_mode blend_difference }; +#define STRING_SIZE (1024 - sizeof(uint8)) // TODO(fox): Paths above STRING_SIZE length aren't handled properly. struct block_string { uint8 Occupied; - char Char[1024 - sizeof(uint8)]; + char Char[STRING_SIZE]; }; struct bitmap_cache_status @@ -146,6 +147,25 @@ struct ui ImVec2 Warp_PositionToSet; real32 Warp_PositionInitial; int32 Warp_Direction; + + ImU32 LayerColors[16] = { + 0x00050506, + 0x00806754, + 0x002d3f66, + 0x0044546e, + 0x00556780, + 0x005d7392, + 0x007e7b7e, + 0x00828282, + 0x00434344, + 0x00AB8A71, + 0x003C5588, + 0x005B7193, + 0x00728AAB, + 0x007C9AC3, + 0x00A9A5A8, + 0x00c0c0c0 + }; }; struct pen_state { @@ -247,6 +267,12 @@ struct property_header real32 MaxVal; }; +struct property_info +{ + real32 MinVal = FLT_MAX; + real32 MaxVal = FLT_MIN; +}; + struct property_channel { char *Name; uint16 Block_Bezier_Index[MAX_KEYFRAME_BLOCKS]; @@ -265,6 +291,7 @@ struct block_layer { uint8 Occupied; bool32 IsPrecomp; + bool32 Precomp_Toggled; uint16 Block_Source_Index; // also used for precomp uint16 Block_String_Index; uint16 Block_Composition_Index; @@ -9,9 +9,8 @@ enum memory_table_list { F_Layers, F_Sources, F_Properties, - F_Keyframes, + F_Bezier, F_Effects, - F_Nodes, F_Strings, B_ScratchSpace, diff --git a/my_imgui_widgets.cpp b/my_imgui_widgets.cpp index 179dff2..9589abd 100644 --- a/my_imgui_widgets.cpp +++ b/my_imgui_widgets.cpp @@ -1,4 +1,3 @@ -#include "imgui/imgui.h" #include "my_imgui_internal_widgets.h" #include "imgui_ops.h" @@ -196,85 +195,148 @@ ImGui_TimelineHorizontalIncrementDraw(ui *UI, ImDrawList *draw_list, ImVec2 Time } } + + static void -ImGui_Timeline_DrawLayer(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io, ImDrawList *draw_list, block_layer *Layer, block_composition *MainComp, uint16 i, - ImVec2 Increment, ImVec2 TimelineAbsolutePos, ImVec2 TimelineMoveSize, ImVec2 TimelineZoomSize, - ImVec2 TimelineSize, ImVec2 TimelineSizeWithBorder, real32 LayerIncrement, - sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray) +ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io, ImDrawList *draw_list, uint16 CompIndex, + ImVec2 Increment, ImVec2 TimelineAbsolutePos, ImVec2 TimelineMoveSize, ImVec2 TimelineZoomSize, + ImVec2 TimelineSize, ImVec2 TimelineSizeWithBorder, real32 LayerIncrement, + sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray) { - int32 Frame_Start = Layer->Frame_Start; - int32 Frame_End = Layer->Frame_End; - real32 Vertical_Offset = Layer->Vertical_Offset; - if (Layer->IsSelected) - Layer_Interact_Evaluate(Memory, State, &Frame_Start, &Frame_End, &Vertical_Offset); - ImVec2 Layer_LocalPos = ImVec2(Frame_Start, Vertical_Offset); - ImVec2 Layer_LocalSize = ImVec2(Frame_End - Frame_Start, Layer->Vertical_Height); - - ImVec2 Layer_LocalPos_Ratio = (Layer_LocalPos * Increment); - ImVec2 Layer_LocalSize_Ratio = Layer_LocalSize * Increment; - ImVec2 Layer_ScreenPos_Min = TimelineAbsolutePos + TimelineMoveSize + (Layer_LocalPos_Ratio * TimelineZoomSize); - ImVec2 Layer_ScreenPos_Max = TimelineAbsolutePos + TimelineMoveSize + ((Layer_LocalPos_Ratio + Layer_LocalSize_Ratio) * TimelineZoomSize); - ImVec2 Layer_ScreenSize = Layer_ScreenPos_Max - Layer_ScreenPos_Min; - - if (UI->BoxSelect) { - bool32 Test = 0; - if (io.MouseClickedPos[0].y < io.MousePos.y) - Test = (Layer_ScreenPos_Min.y >= io.MouseClickedPos[0].y && Layer_ScreenPos_Min.y <= io.MousePos.y); - else - Test = (Layer_ScreenPos_Max.y <= io.MouseClickedPos[0].y && Layer_ScreenPos_Max.y >= io.MousePos.y); + block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, CompIndex); + sorted_comp_info SortedCompInfo = SortedCompArray[CompIndex]; + sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, CompIndex); - if (Test) { - if (!Layer->IsSelected) { - Layer->IsSelected = true; + ImGui::PushID(CompIndex); + + for (int i = 0; i < SortedCompInfo.LayerCount; i++) + { + ImGui::PushID(i); + + sorted_layer SortEntry = SortedLayerInfo[i]; + uint32 Index_Physical = SortEntry.Block_Layer_Index; + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); + + int32 Frame_Start = Layer->Frame_Start; + int32 Frame_End = Layer->Frame_End; + real32 Vertical_Offset = Layer->Vertical_Offset; + if (Layer->IsSelected) + Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End, &Vertical_Offset); + ImVec2 Layer_LocalPos = ImVec2(Frame_Start, Vertical_Offset); + ImVec2 Layer_LocalSize = ImVec2(Frame_End - Frame_Start, Layer->Vertical_Height); + + ImVec2 Layer_LocalPos_Ratio = (Layer_LocalPos * Increment); + ImVec2 Layer_LocalSize_Ratio = Layer_LocalSize * Increment; + ImVec2 Layer_ScreenPos_Min = TimelineAbsolutePos + TimelineMoveSize + (Layer_LocalPos_Ratio * TimelineZoomSize); + ImVec2 Layer_ScreenPos_Max = TimelineAbsolutePos + TimelineMoveSize + ((Layer_LocalPos_Ratio + Layer_LocalSize_Ratio) * TimelineZoomSize); + ImVec2 Layer_ScreenSize = Layer_ScreenPos_Max - Layer_ScreenPos_Min; + + if (UI->BoxSelect) { + bool32 Test = 0; + if (io.MouseClickedPos[0].y < io.MousePos.y) + Test = (Layer_ScreenPos_Min.y >= io.MouseClickedPos[0].y && Layer_ScreenPos_Min.y <= io.MousePos.y); + else + Test = (Layer_ScreenPos_Max.y <= io.MouseClickedPos[0].y && Layer_ScreenPos_Max.y >= io.MousePos.y); + + if (Test) { + if (!Layer->IsSelected) { + Layer->IsSelected = true; + } + } else if (!io.KeyShift) { + Layer->IsSelected = false; } - } else if (!io.KeyShift) { - Layer->IsSelected = false; } - } - draw_list->AddRectFilled(Layer_ScreenPos_Min, Layer_ScreenPos_Max, - ImColor(Layer->Col[0], Layer->Col[1], Layer->Col[2], 1.0f)); - draw_list->AddRect(Layer_ScreenPos_Min, Layer_ScreenPos_Max, ImColor(1.0f, 1.0f, 1.0f, 0.5f), 2); + ImVec2 ResizeSize = ImVec2(Increment.x * 0.45 * TimelineZoomSize.x, Layer_ScreenSize.y); + ImVec2 ResizePos[2] = { Layer_ScreenPos_Min, ImVec2(Layer_ScreenPos_Max.x - ResizeSize.x, Layer_ScreenPos_Min.y) }; + for (int b = 0; b < 2; b++) { + ImGui::PushID(b); + ImGui::SetCursorScreenPos(ResizePos[b]); + ImGui::Button("##layer_resize", ResizeSize); - if (Layer->IsSelected) { - draw_list->AddRectFilled(Layer_ScreenPos_Min, Layer_ScreenPos_Max, ImColor(0.25f, 0.25f, 0.25f, 0.5f), 2); - draw_list->AddRect(Layer_ScreenPos_Min, Layer_ScreenPos_Max, ImColor(1.0f, 1.0f, 1.0f, 0.5f), 2); - } + if (ImGui::IsItemHovered()) { + ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); + } + if (ImGui::IsItemActivated()) { + if (!Layer->IsSelected) { + if (!io.KeyShift) Layer_DeselectAll(Memory, File->Layer_Count); + State->MostRecentlySelectedLayer = i; + Layer->IsSelected = true; + } + } + if (ImGui::IsItemActive()) { + if (ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) { + State->Interact_Active = interact_type_layer_timeadjust; + ImVec2 DragDelta = ImGui::GetMouseDragDelta(); + DragDelta = DragDelta + (ImVec2(UI->Warp_X, UI->Warp_Y) * TimelineSize); - ImVec2 ResizeSize = ImVec2(Increment.x * 0.45 * TimelineZoomSize.x, Layer_ScreenSize.y); - ImVec2 ResizePos[2] = { Layer_ScreenPos_Min, ImVec2(Layer_ScreenPos_Max.x - ResizeSize.x, Layer_ScreenPos_Min.y) }; - for (int b = 0; b < 2; b++) { - ImGui::PushID(b); - ImGui::SetCursorScreenPos(ResizePos[b]); - ImGui::Button("##layer_resize", ResizeSize); + 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); + } + } + if (ImGui::IsItemDeactivated()) { + if (State->Interact_Active == interact_type_layer_timeadjust) { + for (int a = 0; a < File->Layer_Count; a++) { + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, a); + if (Layer->IsSelected) { + Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Layer->Frame_Start, &Layer->Frame_End, &Layer->Vertical_Offset); + } + } + State->Interact_Active = interact_type_none; + State->Interact_Offset[0] = 0; + State->Interact_Offset[1] = 0; + } + } - if (ImGui::IsItemHovered()) { - ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); + ImGui::PopID(); } + + ImGui::SetCursorScreenPos(Layer_ScreenPos_Min); + ImGui::InvisibleButton("##layer_mid", Layer_ScreenSize, ImGuiMouseButton_Left); + if (ImGui::IsItemActivated()) { if (!Layer->IsSelected) { + if (!io.KeyShift) Layer_DeselectAll(Memory, File->Layer_Count); State->MostRecentlySelectedLayer = i; Layer->IsSelected = true; } } + if (ImGui::IsItemActive()) { if (ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) { - State->Interact_Active = interact_type_layer_timeadjust; + if (State->Interact_Active == interact_type_none) { + State->Interact_Active = interact_type_layer_move; + // TODO(fox): Selected layers inside precomps will have interactions doubled, + // so I'm forcing interaction to only be with members of the same precomp. + // Could be made more intuitive later. + Layer_RecursiveDeselect(Memory, SortedCompArray, SortedLayerArray, Layer->Block_Composition_Index, File->PrincipalCompIndex); + } ImVec2 DragDelta = ImGui::GetMouseDragDelta(); DragDelta = DragDelta + (ImVec2(UI->Warp_X, UI->Warp_Y) * TimelineSize); - State->Interact_Offset[0] = (DragDelta.x / TimelineSizeWithBorder.x * UI->TimelinePercentZoomed.x) * MainComp->Frame_Count; - State->Interact_Offset[1] = b; - DebugWatchVar("Offset1", &State->Interact_Offset[0], d_float); + State->Interact_Offset[0] = (DragDelta.x / TimelineSizeWithBorder.x * UI->TimelinePercentZoomed.x) * Comp->Frame_Count; + State->Interact_Offset[1] = (DragDelta.y / TimelineSizeWithBorder.y * UI->TimelinePercentZoomed.y) * LayerIncrement; + + /* + if (UI->DragDelta_Prev.x != 0) { + ImVec2 Offset_Old = (UI->DragDelta_Prev / TimelineSizeWithBorder * UI->TimelinePercentZoomed) * ImVec2(MainComp->Frame_Count, LayerIncrement); + if ((int32)State->Interact_Offset[1] != (int32)Offset_Old.y) + State->UpdateFrame = true; + } + + UI->DragDelta_Prev = DragDelta; + */ } } + if (ImGui::IsItemDeactivated()) { - if (State->Interact_Active == interact_type_layer_timeadjust) { + if (State->Interact_Active == interact_type_layer_move) { for (int a = 0; a < File->Layer_Count; a++) { block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, a); if (Layer->IsSelected) { - Layer_Interact_Evaluate(Memory, State, &Layer->Frame_Start, &Layer->Frame_End, &Layer->Vertical_Offset); + Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Layer->Frame_Start, &Layer->Frame_End, &Layer->Vertical_Offset); } } State->Interact_Active = interact_type_none; @@ -282,80 +344,151 @@ ImGui_Timeline_DrawLayer(project_data *File, project_state *State, memory *Memor State->Interact_Offset[1] = 0; } } - ImGui::PopID(); } - ImGui::SetCursorScreenPos(Layer_ScreenPos_Min); - ImGui::InvisibleButton("##layer_mid", Layer_ScreenSize, ImGuiMouseButton_Left); + // Check if any layers are precomps; we want to test hit detection for them _after_ the layers in front. + for (int i = 0; i < SortedCompInfo.LayerCount; i++) + { + ImGui::PushID(i); + + sorted_layer SortEntry = SortedLayerInfo[i]; + uint32 Index_Physical = SortEntry.Block_Layer_Index; + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); + + int32 Frame_Start = Layer->Frame_Start; + int32 Frame_End = Layer->Frame_End; + real32 Vertical_Offset = Layer->Vertical_Offset; + if (Layer->IsSelected) + Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End, &Vertical_Offset); + ImVec2 Layer_LocalPos = ImVec2(Frame_Start, Vertical_Offset); + ImVec2 Layer_LocalSize = ImVec2(Frame_End - Frame_Start, Layer->Vertical_Height); + + ImVec2 Layer_LocalPos_Ratio = (Layer_LocalPos * Increment); + ImVec2 Layer_LocalSize_Ratio = Layer_LocalSize * Increment; + ImVec2 Layer_ScreenPos_Min = TimelineAbsolutePos + TimelineMoveSize + (Layer_LocalPos_Ratio * TimelineZoomSize); + ImVec2 Layer_ScreenPos_Max = TimelineAbsolutePos + TimelineMoveSize + ((Layer_LocalPos_Ratio + Layer_LocalSize_Ratio) * TimelineZoomSize); + ImVec2 Layer_ScreenSize = Layer_ScreenPos_Max - Layer_ScreenPos_Min; + + if (Layer->IsPrecomp && Layer->Precomp_Toggled) { + + sorted_layer *Precomp_SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, Layer->Block_Source_Index); + sorted_comp_info Precomp_SortedCompInfo = SortedCompArray[Layer->Block_Source_Index]; + + block_layer *Layer_Top = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Precomp_SortedLayerInfo[Precomp_SortedCompInfo.LayerCount - 1].Block_Layer_Index); + block_layer *Layer_Bottom = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Precomp_SortedLayerInfo[0].Block_Layer_Index); + real32 SmallestY = Layer_Top->Vertical_Offset; + real32 LargestY = Layer_Bottom->Vertical_Offset; + real32 PrecompHeight = LargestY - SmallestY + 1; + + ImVec2 MinClipPos = ImVec2(Layer_ScreenPos_Min.x, Layer_ScreenPos_Max.y); + ImVec2 MaxClipPos = ImVec2(Layer_ScreenPos_Max.x, MinClipPos.y + (PrecompHeight * Increment.y * TimelineZoomSize.y)); + draw_list->AddRectFilled(MinClipPos, MaxClipPos, ImColor(0.2f, 0.2f, 0.2f, 1.0f)); + + + ImVec2 Layer_LocalPos_Screen = Layer_LocalPos_Ratio * TimelineZoomSize; + ImVec2 NestedTimelineAbsolutePos = TimelineAbsolutePos + Layer_LocalPos_Screen - ImVec2(0, SmallestY * Increment.y * TimelineZoomSize.y) + ImVec2(0, Layer_ScreenSize.y); + + ImGui::PushClipRect(MinClipPos, MaxClipPos, true); + draw_list->PushClipRect(MinClipPos, MaxClipPos, true); + ImGui_Timeline_DrawPrecomp(File, State, Memory, UI, io, draw_list, Layer->Block_Source_Index, + Increment, NestedTimelineAbsolutePos, TimelineMoveSize, TimelineZoomSize, + TimelineSize, TimelineSizeWithBorder, LayerIncrement, + SortedCompArray, SortedLayerArray); + draw_list->PopClipRect(); + ImGui::PopClipRect(); - if (ImGui::IsItemActivated()) { - if (!Layer->IsSelected) { - if (!io.KeyShift) Layer_DeselectAll(Memory, File->Layer_Count); - State->MostRecentlySelectedLayer = i; - Layer->IsSelected = true; } + ImGui::PopID(); } - if (ImGui::IsItemActive()) { - if (ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) { - State->Interact_Active = interact_type_layer_move; - ImVec2 DragDelta = ImGui::GetMouseDragDelta(); - DragDelta = DragDelta + (ImVec2(UI->Warp_X, UI->Warp_Y) * TimelineSize); + // TODO(fox): Draw calls are executed in reverse order, so we need another iteration to draw layers on top of precomps. + // The ImDrawListSplitter API can probably do this without another iteration. + for (int i = 0; i < SortedCompInfo.LayerCount; i++) + { + ImGui::PushID(i); - State->Interact_Offset[0] = (DragDelta.x / TimelineSizeWithBorder.x * UI->TimelinePercentZoomed.x) * MainComp->Frame_Count; - State->Interact_Offset[1] = (DragDelta.y / TimelineSizeWithBorder.y * UI->TimelinePercentZoomed.y) * LayerIncrement; + sorted_layer SortEntry = SortedLayerInfo[i]; + uint32 Index_Physical = SortEntry.Block_Layer_Index; + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); - /* - if (UI->DragDelta_Prev.x != 0) { - ImVec2 Offset_Old = (UI->DragDelta_Prev / TimelineSizeWithBorder * UI->TimelinePercentZoomed) * ImVec2(MainComp->Frame_Count, LayerIncrement); - if ((int32)State->Interact_Offset[1] != (int32)Offset_Old.y) - State->UpdateFrame = true; - } + int32 Frame_Start = Layer->Frame_Start; + int32 Frame_End = Layer->Frame_End; + real32 Vertical_Offset = Layer->Vertical_Offset; + if (Layer->IsSelected) + Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End, &Vertical_Offset); + ImVec2 Layer_LocalPos = ImVec2(Frame_Start, Vertical_Offset); + ImVec2 Layer_LocalSize = ImVec2(Frame_End - Frame_Start, Layer->Vertical_Height); - UI->DragDelta_Prev = DragDelta; - */ + ImVec2 Layer_LocalPos_Ratio = (Layer_LocalPos * Increment); + ImVec2 Layer_LocalSize_Ratio = Layer_LocalSize * Increment; + ImVec2 Layer_ScreenPos_Min = TimelineAbsolutePos + TimelineMoveSize + (Layer_LocalPos_Ratio * TimelineZoomSize); + ImVec2 Layer_ScreenPos_Max = TimelineAbsolutePos + TimelineMoveSize + ((Layer_LocalPos_Ratio + Layer_LocalSize_Ratio) * TimelineZoomSize); + ImVec2 Layer_ScreenSize = Layer_ScreenPos_Max - Layer_ScreenPos_Min; + + ImU32 col = IM_COL32(255, 255, 255, 255); + + int NumberOfActiveProperties = 0; + for (int h = 0; h < AmountOf(Layer->Property); h++) { + property_channel *Property = &Layer->Property[h]; + if (Property->Keyframe_Count) + NumberOfActiveProperties++; } - } - if (ImGui::IsItemDeactivated()) { - if (State->Interact_Active == interact_type_layer_move) { - for (int a = 0; a < File->Layer_Count; a++) { - block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, a); - if (Layer->IsSelected) { - Layer_Interact_Evaluate(Memory, State, &Layer->Frame_Start, &Layer->Frame_End, &Layer->Vertical_Offset); + for (int h = 0; h < AmountOf(Layer->Property); h++) { + property_channel *Property = &Layer->Property[h]; + ImGui::PushID(Property); + if (Property->Keyframe_Count) { + property_info PropertyInfo = Property_GetInfo(Memory, Property); + real32 Y_Increment = 1 / (PropertyInfo.MaxVal - PropertyInfo.MinVal); + bezier_point *PointAddress[2] = {}; + ImVec2 Keyframe_ScreenPos[2] = {}; + ImVec2 Keyframe_ScreenPos_L[2] = {}; + ImVec2 Keyframe_ScreenPos_R[2] = {}; + for (int k = 0; k < (Property->Keyframe_Count + 1); k++) { + int Idx = k % 2; + PointAddress[Idx] = Bezier_Lookup(Memory, Property, k); + bezier_point *Point = PointAddress[Idx]; + + ImVec2 Keyframe_LocalPos[3] = { V2(Point->Pos[0]), V2(Point->Pos[0] + Point->Pos[1]), V2(Point->Pos[0] + Point->Pos[2]) }; + ImVec2 Keyframe_LocalPos_Ratio[3]; + for (int b = 0; b < 3; b++) { + Keyframe_LocalPos_Ratio[b] = (Keyframe_LocalPos[b] - ImVec2(0, PropertyInfo.MinVal)) * ImVec2(Increment.x, Y_Increment); + } + + Keyframe_ScreenPos[Idx] = Layer_ScreenPos_Min + ((Keyframe_LocalPos_Ratio[0] - ImVec2(0, 0.5)) * TimelineZoomSize) + ImVec2(0, Layer_ScreenSize.y/2); + Keyframe_ScreenPos_L[Idx] = Layer_ScreenPos_Min + ((Keyframe_LocalPos_Ratio[1] - ImVec2(0, 0.5)) * TimelineZoomSize) + ImVec2(0, Layer_ScreenSize.y/2); + Keyframe_ScreenPos_R[Idx] = Layer_ScreenPos_Min + ((Keyframe_LocalPos_Ratio[2] - ImVec2(0, 0.5)) * TimelineZoomSize) + ImVec2(0, Layer_ScreenSize.y/2); + + draw_list->AddCircle(Keyframe_ScreenPos[Idx], 2, col, 16, 1); + if (k != 0 && k != Property->Keyframe_Count) { + if (PointAddress[0]->Type == interpolation_type_bezier && PointAddress[1]->Type == interpolation_type_bezier) { + draw_list->AddBezierCubic(Keyframe_ScreenPos[!Idx], Keyframe_ScreenPos_R[!Idx], + Keyframe_ScreenPos_L[Idx], Keyframe_ScreenPos[Idx], col, 1.0f, 0); + } else { + draw_list->AddLine(Keyframe_ScreenPos[0], Keyframe_ScreenPos[1], col, 1.0f); + } + } } } - State->Interact_Active = interact_type_none; - State->Interact_Offset[0] = 0; - State->Interact_Offset[1] = 0; + ImGui::PopID(); } - } - if (Layer->IsPrecomp) { - ImVec2 MinClipPos = ImVec2(Layer_ScreenPos_Min.x, Layer_ScreenPos_Max.y); - ImVec2 MaxClipPos = ImVec2(Layer_ScreenPos_Max.x, MinClipPos.y + TimelineZoomSize.y); - draw_list->AddRectFilled(MinClipPos, MaxClipPos, ImColor(0.2f, 0.2f, 0.2f, 1.0f)); + draw_list->AddRectFilled(Layer_ScreenPos_Min, Layer_ScreenPos_Max, + ImColor(Layer->Col[0], Layer->Col[1], Layer->Col[2], 1.0f)); + draw_list->AddRect(Layer_ScreenPos_Min, Layer_ScreenPos_Max, ImColor(1.0f, 1.0f, 1.0f, 0.5f), 2); + // block_string *String = (block_string *)Memory_Block_AddressAtIndex(Memory, F_Strings, Layer->Block_String_Index); + // draw_list->AddText(Layer_ScreenPos_Min, 0xFFFFFFFF, String->Char); - sorted_comp_info SortedCompInfo = SortedCompArray[Layer->Block_Source_Index]; - sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, Layer->Block_Source_Index); + if (Layer->IsSelected) { + draw_list->AddRectFilled(Layer_ScreenPos_Min, Layer_ScreenPos_Max, ImColor(0.25f, 0.25f, 0.25f, 0.5f), 2); + draw_list->AddRect(Layer_ScreenPos_Min, Layer_ScreenPos_Max, ImColor(1.0f, 1.0f, 1.0f, 0.5f), 2); + } - for (int a = 0; a < SortedCompInfo.LayerCount; a++) - { - ImGui::PushID(a); - sorted_layer SortEntry = SortedLayerInfo[a]; - uint32 Index_Physical = SortEntry.Block_Layer_Index; - block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); - ImVec2 Layer_LocalPos_Screen = Layer_LocalPos_Ratio * TimelineZoomSize; - ImVec2 NestedTimelineAbsolutePos = TimelineAbsolutePos + Layer_LocalPos_Screen + ImVec2(0, Layer_ScreenSize.y); - ImGui_Timeline_DrawLayer(File, State, Memory, UI, io, draw_list, Layer, MainComp, a, - Increment, NestedTimelineAbsolutePos, TimelineMoveSize, TimelineZoomSize, - TimelineSize, TimelineSizeWithBorder, LayerIncrement, - SortedCompArray, SortedLayerArray); - ImGui::PopID(); - } + ImGui::PopID(); } + ImGui::PopID(); } static void @@ -432,23 +565,10 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, sorted_layer *SortedLayerArray = (sorted_layer *)((uint8 *)SortedArray + (sizeof(sorted_comp_info) * File->Comp_Count)); Layer_SortAll(Memory, SortedLayerArray, SortedCompArray, File->Layer_Count, File->Comp_Count); - sorted_comp_info SortedCompInfo = SortedCompArray[File->PrincipalCompIndex]; - sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, File->PrincipalCompIndex); - - for (int i = 0; i < SortedCompInfo.LayerCount; i++) - { - ImGui::PushID(i); - sorted_layer SortEntry = SortedLayerInfo[i]; - uint32 Index_Physical = SortEntry.Block_Layer_Index; - block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); - - ImGui_Timeline_DrawLayer(File, State, Memory, UI, io, draw_list, Layer, MainComp, i, - Increment, TimelineAbsolutePos, TimelineMoveSize, TimelineZoomSize, - TimelineSize, TimelineSizeWithBorder, LayerIncrement, - SortedCompArray, SortedLayerArray); - - ImGui::PopID(); - } + ImGui_Timeline_DrawPrecomp(File, State, Memory, UI, io, draw_list, File->PrincipalCompIndex, + Increment, TimelineAbsolutePos, TimelineMoveSize, TimelineZoomSize, + TimelineSize, TimelineSizeWithBorder, LayerIncrement, + SortedCompArray, SortedLayerArray); Memory_PopScratch(Memory, SortSize); @@ -619,6 +739,11 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, IM_COL32(0, 0, 200, 50)); } + if (!ImGui::IsMouseDown(ImGuiMouseButton_Left)) { + UI->Warp_X = 0; + UI->Warp_Y = 0; + } + if (IsItemDeactivated) { UI->BoxSelect = false; } @@ -637,14 +762,29 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, } static void -ImGui_ProcessInputs(project_state *State, ImGuiIO io) +ImGui_ProcessInputs(project_data *File, project_state *State, memory *Memory, ImGuiIO io) { - if (io.KeysData[ImGuiKey_Q].Down) { + if (ImGui::IsKeyPressed(ImGuiKey_Q)) { State->IsRunning = false; } - if (io.KeysData[ImGuiKey_A].Down) { + if (ImGui::IsKeyPressed(ImGuiKey_A)) { State->UpdateFrame = true; } + if (ImGui::IsKeyPressed(ImGuiKey_T)) { + for (int a = 0; a < File->Layer_Count; a++) { + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, a); + if (Layer->IsSelected && Layer->IsPrecomp) { + Layer->Precomp_Toggled ^= 1; + } + } + } +#if DEBUG + if (ImGui::IsKeyPressed(ImGuiKey_W)) + { + Debug.ToggleWindow ^= 1; + } +#endif + } #if 0 @@ -2193,13 +2333,6 @@ ImGui_ProcessInputs(project_data *File, project_state *State, comp_buffer *CompB } } -#if DEBUG - if (ImGui::IsKeyPressed(ImGuiKey_W)) - { - Debug.ToggleWindow ^= 1; - } -#endif - if (State->IsInteracting) { ImVec2 MouseIncrement = io.MouseDelta * (ImVec2(CompBuffer->Width, CompBuffer->Height) / UI->CompZoom); project_layer *Layer = File->Layer[State->MostRecentlySelectedLayer]; @@ -66,6 +66,16 @@ inline v2 V2(ImVec2 A) return(Result); } +inline ImVec2 V2(v2 A) +{ + struct ImVec2 Result; + + Result.x = A.x; + Result.y = A.y; + + return(Result); +} + inline v2i V2i(int32 x, int32 y) { v2i Result; |