From 38bf0102300c97335d8e78b4683cb9b9476dcde0 Mon Sep 17 00:00:00 2001 From: Fox Caminiti Date: Thu, 10 Nov 2022 22:34:17 -0500 Subject: graph implementation --- my_imgui_widgets.cpp | 463 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 318 insertions(+), 145 deletions(-) (limited to 'my_imgui_widgets.cpp') diff --git a/my_imgui_widgets.cpp b/my_imgui_widgets.cpp index e1e9ffc..722ce1e 100644 --- a/my_imgui_widgets.cpp +++ b/my_imgui_widgets.cpp @@ -138,9 +138,7 @@ ImGui_File(project_data *File, project_state *State, memory *Memory, ImGuiIO io, ImGui::Begin("Files"); ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate); - if (!ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) - Source_DeselectAll(File, Memory); - else if (ImGui::IsKeyPressed(ImGuiKey_Backspace)) { + if (ImGui::IsKeyPressed(ImGuiKey_Backspace)) { /* uint64 SortSize = (sizeof(uint16) * File->Comp_Count); @@ -214,6 +212,9 @@ ImGui_File(project_data *File, project_state *State, memory *Memory, ImGuiIO io, ImGui::EndPopup(); } + // if (!ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) + // Source_DeselectAll(File, Memory); + #if DEBUG for (int i = 0; i < Debug.Temp.WatchedProperties; i++) { @@ -603,6 +604,7 @@ ImGui_TransformUI(project_data *File, project_state *State, memory *Memory, ui * } if (ImGui::IsKeyPressed(ImGuiKey_Escape)) { + State->Interact_Active = interact_type_none; State->UpdateFrame = true; } @@ -631,6 +633,106 @@ ImGui_TransformUI(project_data *File, project_state *State, memory *Memory, ui * } +static void +ImGui_LayerViewportUI(project_state *State, memory *Memory, ui *UI, ImDrawList *draw_list, block_composition *MainComp, uint32 CompIndex, block_layer *ParentLayer[4], uint32 Recursions, + sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray) +{ + sorted_comp_info *SortedCompInfo = &SortedCompArray[CompIndex]; + sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, CompIndex); + ImU32 wcol = ImGui::GetColorU32(ImGuiCol_Text); + 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) { + ParentLayer[Recursions] = Layer; + ImGui_LayerViewportUI(State, Memory, UI, draw_list, MainComp, Layer->Block_Source_Index, ParentLayer, Recursions + 1, SortedCompArray, SortedLayerArray); + } + if (Layer->IsSelected) { + uint32 Width = 0, Height = 0; + if (!Layer->IsPrecomp) { + block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index); + Width = Source->Width; + Height = Source->Height; + } else { + block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, Layer->Block_Source_Index); + Width = Comp->Width; + Height = Comp->Height; + } + + v2 Point[5] = { V2(Width*Layer->ax.CurrentValue, Height*Layer->ay.CurrentValue), V2(0, 0), V2(Width, 0), V2(0, Height), V2(Width, Height) }; + + layer_transforms T = Layer_GetTransforms(Layer); + + if (State->Interact_Active == interact_type_viewport_transform && Layer->IsSelected) { + Transform_ApplyInteractive(*(interact_transform *)&State->Interact_Offset[0], &T.x, &T.y, &T.rotation, &T.scale); + } + + v2 NewPos[5]; + for (int i = 0; i < 5; i++) { + NewPos[i] = TransformPoint(T, Width, Height, Point[i]); + } + + int i = 0; + while (i < Recursions) { + T = Layer_GetTransforms(ParentLayer[i]); + block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, ParentLayer[i]->Block_Source_Index); + Width = Comp->Width; + Height = Comp->Height; + for (int i = 0; i < 5; i++) { + NewPos[i] = TransformPoint(T, Width, Height, NewPos[i]); + } + i++; + } + + ImVec2 ScreenPoint[5]; + for (int i = 0; i < 5; i++) { + v2 CompUV = NewPos[i] / V2(MainComp->Width, MainComp->Height); + + ScreenPoint[i] = ImVec2(UI->CompPos.x + CompUV.x * UI->CompZoom.x, + UI->CompPos.y + CompUV.y * UI->CompZoom.y); + + } + draw_list->AddNgon(ScreenPoint[0], 20, wcol, 8, 10.0f); + draw_list->AddLine(ScreenPoint[1], ScreenPoint[2], wcol, 2.0f); + draw_list->AddLine(ScreenPoint[2], ScreenPoint[4], wcol, 2.0f); + draw_list->AddLine(ScreenPoint[1], ScreenPoint[3], wcol, 2.0f); + draw_list->AddLine(ScreenPoint[3], ScreenPoint[4], wcol, 2.0f); + } + /* + if (Layer->IsSelected) { + uint32 Width = 0, Height = 0; + if (!Layer->IsPrecomp) { + block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index); + Width = Source->Width; + Height = Source->Height; + } else { + block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, Layer->Block_Source_Index); + Width = Comp->Width; + Height = Comp->Height; + } + // Anchor point UI + v2 CenterPoint = V2(Width*Layer->ax.CurrentValue, Height*Layer->ay.CurrentValue); + ImVec2 ScreenAP = Layer_LocalToScreenSpace(State, Memory, Layer, UI, File->PrincipalCompIndex, CenterPoint); + draw_list->AddNgon(ScreenAP, 20, wcol, 8, 10.0f); + + // Bounding box UI + ImVec2 P1 = Layer_LocalToScreenSpace(State, Memory, Layer, UI, File->PrincipalCompIndex, V2(0, 0)); + ImVec2 P2 = Layer_LocalToScreenSpace(State, Memory, Layer, UI, File->PrincipalCompIndex, V2(Width, 0)); + ImVec2 P3 = Layer_LocalToScreenSpace(State, Memory, Layer, UI, File->PrincipalCompIndex, V2(0, Height)); + ImVec2 P4 = Layer_LocalToScreenSpace(State, Memory, Layer, UI, File->PrincipalCompIndex, V2(Width, Height)); + draw_list->AddLine(P1, P2, wcol, 2.0f); + draw_list->AddLine(P2, P4, wcol, 2.0f); + draw_list->AddLine(P1, P3, wcol, 2.0f); + draw_list->AddLine(P3, P4, wcol, 2.0f); + + } + */ + + } +} + static void ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io, GLuint textureID, sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray) @@ -668,35 +770,11 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, draw_list->AddImage((void *)(intptr_t)textureID, CompPosMin, CompPosMax); draw_list->PopClipRect(); - ImU32 wcol = ImGui::GetColorU32(ImGuiCol_Text); // UI+interaction for layer if (State->MostRecentlySelectedLayer > -1) { - int h = 0, c = 0, i = 0; - while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) - { - block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); - if (Layer->IsSelected) { - block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index); - - // Anchor point UI - v2 CenterPoint = V2(Source->Width*Layer->ax.CurrentValue, Source->Height*Layer->ay.CurrentValue); - ImVec2 ScreenAP = Layer_LocalToScreenSpace(State, Layer, UI, Source->Width, Source->Height, MainComp->Width, MainComp->Height, CenterPoint); - draw_list->AddNgon(ScreenAP, 20, wcol, 8, 10.0f); - - // Bounding box UI - ImVec2 P1 = Layer_LocalToScreenSpace(State, Layer, UI, Source->Width, Source->Height, MainComp->Width, MainComp->Height, V2(0, 0)); - ImVec2 P2 = Layer_LocalToScreenSpace(State, Layer, UI, Source->Width, Source->Height, MainComp->Width, MainComp->Height, V2(Source->Width, 0)); - ImVec2 P3 = Layer_LocalToScreenSpace(State, Layer, UI, Source->Width, Source->Height, MainComp->Width, MainComp->Height, V2(0, Source->Height)); - ImVec2 P4 = Layer_LocalToScreenSpace(State, Layer, UI, Source->Width, Source->Height, MainComp->Width, MainComp->Height, V2(Source->Width, Source->Height)); - draw_list->AddLine(P1, P2, wcol, 2.0f); - draw_list->AddLine(P2, P4, wcol, 2.0f); - draw_list->AddLine(P1, P3, wcol, 2.0f); - draw_list->AddLine(P3, P4, wcol, 2.0f); - - } - } - + block_layer *ParentLayer[4]; + ImGui_LayerViewportUI(State, Memory, UI, draw_list, MainComp, File->PrincipalCompIndex, ParentLayer, 0, SortedCompArray, SortedLayerArray); if (State->Interact_Active == interact_type_viewport_transform) { ImGui_TransformUI(File, State, Memory, UI, draw_list, io, (interact_transform *)&State->Interact_Offset[0], ViewportMin, MainComp->Width, MainComp->Height); } @@ -916,6 +994,9 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor { UI->Test.Split(draw_list, 2); + TimelineMoveSize.y = TimelineMoveSize.y + (TimelineZoomSize.y * (0.25 / 2)); + TimelineZoomSize.y = TimelineZoomSize.y * 0.75; + int h = 0, c = 0, i = 0; while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) { @@ -924,16 +1005,8 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor continue; int32 Frame_Start = Layer->Frame_Start; - int32 Frame_End = Layer->Frame_End; - real32 Vertical_Offset = GraphInfo.LowestOffset; // Layer->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; + ImVec2 Layer_ScreenPos_Min = TimelineAbsolutePos + TimelineMoveSize; // (* TimelineZoomSize); ImGui::PushID(i); @@ -941,8 +1014,12 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor if (State->Interact_Active == interact_type_keyframe_move) { ImVec2 DragDelta = io.MousePos - ImVec2(State->Interact_Offset[2], State->Interact_Offset[3]); - State->Interact_Offset[0] = (DragDelta.x / TimelineSizeWithBorder.x * UI->TimelinePercentZoomed.x) / Increment.x; - State->Interact_Offset[1] = -1 * (DragDelta.y / TimelineSizeWithBorder.y * UI->TimelinePercentZoomed.y) * ((GraphInfo.MaxVal - GraphInfo.MinVal)); + // State->Interact_Offset[0] = (DragDelta.x / TimelineSizeWithBorder.x * UI->TimelinePercentZoomed.x) / Increment.x; + // State->Interact_Offset[1] = -1 * (DragDelta.y / TimelineSizeWithBorder.y * UI->TimelinePercentZoomed.y) * ((GraphInfo.MaxVal - GraphInfo.MinVal)); + State->Interact_Offset[0] = DragDelta.x; + State->Interact_Offset[1] = DragDelta.y; + DebugWatchVar("DeltaX: ", &DragDelta.x, d_float); + DebugWatchVar("Deltay: ", &DragDelta.y, d_float); } else if (State->Interact_Active == interact_type_keyframe_scale) { ImVec2 DragDelta = io.MousePos - ImVec2(State->Interact_Offset[2], State->Interact_Offset[3]); State->Interact_Offset[0] = (DragDelta.x / TimelineSizeWithBorder.x * UI->TimelinePercentZoomed.x) / Increment.x; @@ -954,7 +1031,6 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor State->Interact_Active == interact_type_keyframe_rotate || State->Interact_Active == interact_type_keyframe_scale)) { - Assert(0); // Memory_Cache_Invalidate(State, Memory, cache_entry_type_comp, Lay } @@ -980,6 +1056,7 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor v2 Keyframe_LocalPos_[3] = { Point->Pos[0], Point->Pos[1], Point->Pos[2] }; if (Point->IsSelected) { + /* if (State->Interact_Active == interact_type_keyframe_rotate) { ImVec2 Keyframe_LocalPos_Ratio = (V2(Keyframe_LocalPos_[0]) - ImVec2(0, GraphInfo.MinVal)) * ImVec2(Increment.x, Y_Increment); ImVec2 Keyframe_ScreenPos = Layer_ScreenPos_Min + ((ImVec2(1, -1) * Keyframe_LocalPos_Ratio + ImVec2(0, 0.5)) * TimelineZoomSize) + ImVec2(0, Layer_ScreenSize.y/2); @@ -988,14 +1065,21 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor State->Interact_Offset[0] = atan((Slope_Old - Slope_New) / (1 + Slope_Old * Slope_New)); DebugWatchVar("Rotation: ", &State->Interact_Offset[0], d_float); } - Keyframe_Interact_Evaluate(Memory, State, Point->IsSelected, Point->Pos, Keyframe_LocalPos_); + */ + v2 Offset = V2(State->Interact_Offset[0], State->Interact_Offset[1]); + if (State->Interact_Active == interact_type_keyframe_move) { + Keyframe_LocalPos_[0].x += (Offset.x / TimelineZoomSize.x) / Increment.x; + Keyframe_LocalPos_[0].y -= ((Offset.y / TimelineZoomSize.y)) * (GraphInfo.MaxVal - GraphInfo.MinVal); + } + // Keyframe_Interact_Evaluate(Memory, State, Point->IsSelected, Point->Pos, Keyframe_LocalPos_); } ImVec2 Keyframe_LocalPos[3] = { V2(Keyframe_LocalPos_[0]), V2(Keyframe_LocalPos_[0] + Keyframe_LocalPos_[1]), V2(Keyframe_LocalPos_[0] + Keyframe_LocalPos_[2]) }; ImVec2 Keyframe_LocalPos_Ratio[3]; for (int b = 0; b < 3; b++) { Keyframe_LocalPos_Ratio[b] = (Keyframe_LocalPos[b] - ImVec2(0, GraphInfo.MinVal)) * ImVec2(Increment.x, Y_Increment); - Keyframe_ScreenPos[NewIdx + b] = Layer_ScreenPos_Min + ((ImVec2(1, -1) * Keyframe_LocalPos_Ratio[b] + ImVec2(0, 0.5)) * TimelineZoomSize) + ImVec2(0, Layer_ScreenSize.y/2); + // Keyframe_ScreenPos[NewIdx + b] = Layer_ScreenPos_Min + ((ImVec2(1, -1) * Keyframe_LocalPos_Ratio[b] + ImVec2(0, 0.5)) * TimelineZoomSize) + ImVec2(0, Layer_ScreenSize.y/2); + Keyframe_ScreenPos[NewIdx + b] = TimelineAbsolutePos + TimelineMoveSize + ((ImVec2(1, -1) * Keyframe_LocalPos_Ratio[b] + ImVec2(0, 1)) * TimelineZoomSize); } if (UI->BoxSelect) { @@ -1098,8 +1182,8 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem int32 Frame_Start = Layer->Frame_Start; int32 Frame_End = Layer->Frame_End; real32 Vertical_Offset = SortEntry.SortedOffset; - // if (Layer->IsSelected) - // Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End, &Vertical_Offset); + if (Layer->IsSelected) + Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End); ImVec2 Layer_LocalPos = ImVec2(Frame_Start, Vertical_Offset); ImVec2 Layer_LocalSize = ImVec2(Frame_End - Frame_Start, Layer->Vertical_Height); @@ -1118,6 +1202,11 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem else Test = (Layer_ScreenPos_Max.y <= io.MouseClickedPos[0].y && Layer_ScreenPos_Max.y >= io.MousePos.y); + if (io.MouseClickedPos[0].x < io.MousePos.x) + Test &= (Layer_ScreenPos_Max.x >= io.MouseClickedPos[0].x && Layer_ScreenPos_Min.x <= io.MousePos.x); + else + Test &= (Layer_ScreenPos_Min.x <= io.MouseClickedPos[0].x && Layer_ScreenPos_Max.x >= io.MousePos.x); + if (Test) { if (!Layer->IsSelected) { Layer->IsSelected = true; @@ -1146,6 +1235,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem } if (ImGui::IsItemActive()) { if (ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) { + Assert(Layer->IsSelected); State->Interact_Active = interact_type_layer_timeadjust; ImVec2 DragDelta = ImGui::GetMouseDragDelta(); DragDelta = DragDelta + (ImVec2(UI->Warp_X, UI->Warp_Y) * TimelineSize); @@ -1157,19 +1247,21 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem } if (ImGui::IsItemDeactivated()) { if (State->Interact_Active == interact_type_layer_timeadjust) { - Assert(0); - /* + History_Entry_Commit(Memory, "Adjust layer timing"); int h = 0, c = 0, i = 0; while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) { block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); - // if (Layer->IsSelected) { - // Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Layer->Frame_Start, &Layer->Frame_End, &Layer->Vertical_Offset); - // } + if (Layer->IsSelected) { + // NOTE(fox): Some data on the tree could be saved here. + History_Action_Swap(Memory, F_File, sizeof(Layer->Frame_Start), &Layer->Frame_Start); + History_Action_Swap(Memory, F_File, sizeof(Layer->Frame_End), &Layer->Frame_End); + Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Layer->Frame_Start, &Layer->Frame_End); + } } + History_Entry_End(Memory); State->Interact_Active = interact_type_none; State->Interact_Offset[0] = 0; State->Interact_Offset[1] = 0; - */ } } @@ -1186,6 +1278,70 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem } } + ImGui::OpenPopupOnItemClick("layerpopup", ImGuiPopupFlags_MouseButtonRight); + if (ImGui::BeginPopup("layerpopup")) { + if (ImGui::MenuItem("Pre-compose layer")) { + History_Entry_Commit(Memory, "Pre-compose layer"); + block_composition *NewComp = Precomp_Init(File, Memory); + NewComp->Width = Comp->Width; + NewComp->Height = Comp->Height; + NewComp->FPS = Comp->FPS; + NewComp->BytesPerPixel = Comp->BytesPerPixel; + NewComp->Frame_Count = Comp->Frame_Count; + NewComp->Frame_Start = Comp->Frame_Start; + NewComp->Frame_End = Comp->Frame_End; + int32 TopOffset = 0; + for (int i = SortedCompInfo.LayerCount - 1; i >= 0; 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->IsSelected) { + TopOffset = Layer->Vertical_Offset; + break; + } + } + for (int i = SortedCompInfo.LayerCount - 1; i >= 0; 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->IsSelected) { + History_Action_Swap(Memory, F_File, sizeof(Layer->Block_Composition_Index), &Layer->Block_Composition_Index); + Layer->Block_Composition_Index = 1; + } + } + block_layer *PrecompLayer = Layer_Init(File, Memory); + PrecompLayer->IsPrecomp = true; + PrecompLayer->Block_Source_Index = 1; + PrecompLayer->Block_Composition_Index = 0; + PrecompLayer->Vertical_Offset = TopOffset; + PrecompLayer->Frame_End = NewComp->Frame_End; + PrecompLayer->ColIndex = 3; + PrecompLayer->x.CurrentValue = Comp->Width/2; + PrecompLayer->y.CurrentValue = Comp->Height/2; + History_Entry_End(Memory); + State->UpdateFrame = true; + } + if (ImGui::BeginMenu("Layer color")) + { + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f)); + for (int c = 0; c < AmountOf(UI->LayerColors); c++) { + ImGui::PushID(c); + ImGui::PushStyleColor(ImGuiCol_Button, UI->LayerColors[c]); + real32 Size = ImGui::GetFontSize() * 2; + ImVec2 ColSize(Size, Size); + ImGui::Button("##test", ColSize); + if ((c+1) % 4) { ImGui::SameLine(); } + ImGui::PopStyleColor(); + ImGui::PopID(); + } + ImGui::PopStyleVar(); + ImGui::EndMenu(); + } + ImGui::EndPopup(); + } + if (ImGui::IsItemActive()) { if (ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) { if (State->Interact_Active == interact_type_none) { @@ -1218,8 +1374,12 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem uint32 Index_Physical = SortEntry.Block_Layer_Index; block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); if (Layer->IsSelected) { + // NOTE(fox): Some data on the tree could be saved here. History_Action_Swap(Memory, F_File, sizeof(Layer->Vertical_Offset), &Layer->Vertical_Offset); + History_Action_Swap(Memory, F_File, sizeof(Layer->Frame_Start), &Layer->Frame_Start); + History_Action_Swap(Memory, F_File, sizeof(Layer->Frame_End), &Layer->Frame_End); Layer->Vertical_Offset = SortEntry.SortedOffset; + Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Layer->Frame_Start, &Layer->Frame_End); } } State->Interact_Active = interact_type_none; @@ -1243,8 +1403,8 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem int32 Frame_Start = Layer->Frame_Start; int32 Frame_End = Layer->Frame_End; real32 Vertical_Offset = SortEntry.SortedOffset; - // if (Layer->IsSelected) - // Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End, &Vertical_Offset); + if (Layer->IsSelected) + Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End); ImVec2 Layer_LocalPos = ImVec2(Frame_Start, Vertical_Offset); ImVec2 Layer_LocalSize = ImVec2(Frame_End - Frame_Start, Layer->Vertical_Height); @@ -1298,8 +1458,8 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem int32 Frame_Start = Layer->Frame_Start; int32 Frame_End = Layer->Frame_End; real32 Vertical_Offset = SortEntry.SortedOffset; - // if (Layer->IsSelected) - // Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End, &Vertical_Offset); + if (Layer->IsSelected) + Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End); ImVec2 Layer_LocalPos = ImVec2(Frame_Start, Vertical_Offset); ImVec2 Layer_LocalSize = ImVec2(Frame_End - Frame_Start, Layer->Vertical_Height); @@ -1311,6 +1471,9 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem ImU32 LayerColor = 0; ImU32 BorderColor = 0; + LayerColor = ImColor(UI->LayerColors[Layer->ColIndex]); + BorderColor = ImColor(0.2, 0.2, 0.2, 1.0f); + /* if (UI->TimelineMode == timeline_mode_graph) { LayerColor = ImColor(UI->LayerColors[Layer->ColIndex]); BorderColor = ImColor(0.3, 0.3, 0.3, 1.0f); @@ -1318,11 +1481,14 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem LayerColor = ImColor(UI->LayerColors[Layer->ColIndex]); BorderColor = ImColor(0.2, 0.2, 0.2, 1.0f); } + */ draw_list->AddRectFilled(Layer_ScreenPos_Min, Layer_ScreenPos_Max, LayerColor); draw_list->AddRect(Layer_ScreenPos_Min, Layer_ScreenPos_Max, BorderColor, 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); + char buf[21]; + sprintf(buf, "%.2f, %.2f", Layer->Vertical_Offset, SortEntry.SortedOffset); + draw_list->AddText(Layer_ScreenPos_Min, 0xFFFFFFFF, buf); if (Layer->IsSelected) { draw_list->AddRectFilled(Layer_ScreenPos_Min, Layer_ScreenPos_Max, ImColor(0.25f, 0.25f, 0.25f, 0.5f), 2); @@ -1392,32 +1558,54 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, ImVec2 Val_Min(0, 0); ImVec2 Val_Max(40, LayerIncrement); - if (UI->TimelinePercentZoomed.x == 0) { - UI->TimelinePercentZoomed = ImVec2(1, 1); + // ImVec2 *ActivePercentZoomed = (UI->TimelineMode != timeline_mode_graph) ? &UI->TimelinePercentZoomed : &UI->GraphPercentZoomed; + // ImVec2 *ActivePercentOffset = (UI->TimelineMode != timeline_mode_graph) ? &UI->TimelinePercentOffset : &UI->GraphPercentOffset; + ImVec2 *ActivePercentZoomed = &UI->TimelinePercentZoomed; + ImVec2 *ActivePercentOffset = &UI->TimelinePercentOffset; + + if (ActivePercentZoomed->x == 0) { + *ActivePercentZoomed = ImVec2(1, 1); } + ImVec2 ActiveZoomSize = TimelineSizeWithBorder / *ActivePercentZoomed; + ImVec2 ActiveMoveSize = TimelineSizeWithBorder * *ActivePercentOffset / *ActivePercentZoomed; + ImVec2 TimelineZoomSize = TimelineSizeWithBorder / UI->TimelinePercentZoomed; ImVec2 TimelineMoveSize = TimelineSizeWithBorder * UI->TimelinePercentOffset / UI->TimelinePercentZoomed; + DebugWatchVar("TimelineY: ", &TimelineMoveSize.y, d_float); + ImGui_TimelineHorizontalIncrementDraw(State, UI, draw_list, TimelineSizeWithBorder, TimelineAbsolutePos, *MainComp, TimelineZoomSize, TimelineMoveSize); ImVec2 Increment = ImVec2((real32)1 / MainComp->Frame_Count, (real32)1 / LayerIncrement); - ImGui_Timeline_DrawPrecomp(File, State, Memory, UI, io, draw_list, File->PrincipalCompIndex, Increment, TimelineAbsolutePos, TimelineMoveSize, TimelineZoomSize, TimelineSize, TimelineSizeWithBorder, LayerIncrement, SortedCompArray, SortedLayerArray); if (UI->TimelineMode == timeline_mode_graph) { - // uint64 Keyframe_SortSize = (sizeof(sorted_comp_info) * File->Comp_Count) + (sizeof(sorted_layer) * File->Layer_Count); - // void *SortedArray = Memory_PushScratch(Memory, Keyframe_SortSize); - // Arbitrary_Zero((uint8 *)SortedArray, SortSize); + + if (UI->GraphMoveSize.y == 0) { + UI->GraphZoomSize = ImVec2(1, UI->TimelinePercentZoomed.y ); + UI->GraphMoveSize = ImVec2(0, -UI->TimelinePercentOffset.y ); + } + + ImVec2 ZoomDifference = (UI->TimelinePercentZoomed / UI->GraphZoomSize); + ImVec2 MoveDifference = (UI->TimelinePercentOffset + (UI->GraphMoveSize)); + 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); + + draw_list->AddRectFilled(WindowMinAbs, WindowMaxAbs, + IM_COL32(50, 50, 50, 150)); graph_info GraphInfo = Graph_GetInfo(File, Memory); ImGui_Timeline_DrawGraph(File, State, Memory, UI, io, draw_list, GraphInfo, - Increment, TimelineAbsolutePos, TimelineMoveSize, TimelineZoomSize, + Increment, TimelineAbsolutePos, GraphMoveSize, GraphZoomSize, TimelineSize, TimelineSizeWithBorder, LayerIncrement); - // Memory_PopScratch(Memory, Keyframe_SortSize); } ImVec2 MouseDelta = io.MouseDelta / TimelineSize; @@ -1426,8 +1614,8 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, real32 BarThickness = 50; real32 BarMinZoom = 0.01; - real32 BarH_Pos = -TimelineSizeWithBorder.x * UI->TimelinePercentOffset.x; - real32 BarH_Size = TimelineSizeWithBorder.x / (1 / UI->TimelinePercentZoomed.x); + real32 BarH_Pos = -TimelineSizeWithBorder.x * ActivePercentOffset->x; + real32 BarH_Size = TimelineSizeWithBorder.x / (1 / ActivePercentZoomed->x); // 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. @@ -1454,9 +1642,9 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, if ((ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1))) { - if ((UI->TimelinePercentZoomed.x - MouseDelta.x) > BarMinZoom) { - UI->TimelinePercentZoomed.x -= MouseDelta.x; - UI->TimelinePercentOffset.x -= MouseDelta.x; + if ((ActivePercentZoomed->x - MouseDelta.x) > BarMinZoom) { + ActivePercentZoomed->x -= MouseDelta.x; + ActivePercentOffset->x -= MouseDelta.x; } BarHeld = true; } @@ -1466,7 +1654,7 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, if (ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) { - UI->TimelinePercentOffset.x -= MouseDelta.x; + ActivePercentOffset->x -= MouseDelta.x; BarHeld = true; } @@ -1475,8 +1663,8 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, if ((ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1))) { - if ((UI->TimelinePercentZoomed.x + MouseDelta.x) > BarMinZoom) { - UI->TimelinePercentZoomed.x += MouseDelta.x; + if ((ActivePercentZoomed->x + MouseDelta.x) > BarMinZoom) { + ActivePercentZoomed->x += MouseDelta.x; } BarHeld = true; } @@ -1485,11 +1673,11 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, ImGui_WarpMouse(UI, io.MousePos, TimelineAbsolutePos, TimelineAbsolutePos + TimelineSizeWithBorder, 1); } - Assert(UI->TimelinePercentZoomed.x > BarMinZoom); + Assert(ActivePercentZoomed->x > BarMinZoom); real32 BarV_MaxSize = TimelineSizeWithBorder.y - BarThickness/2; - real32 BarV_Pos = -BarV_MaxSize * UI->TimelinePercentOffset.y; - real32 BarV_Size = BarV_MaxSize / (1 / UI->TimelinePercentZoomed.y); + real32 BarV_Pos = -BarV_MaxSize * ActivePercentOffset->y; + real32 BarV_Size = BarV_MaxSize / (1 / ActivePercentZoomed->y); BarV_Size = Max(BarV_Size, FontHeight*4); real32 BarV_Offset = Max(BarV_Pos, 0); @@ -1514,8 +1702,8 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, if ((ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1))) { - UI->TimelinePercentZoomed.y -= MouseDelta.y; - UI->TimelinePercentOffset.y -= MouseDelta.y; + ActivePercentZoomed->y -= MouseDelta.y; + ActivePercentOffset->y -= MouseDelta.y; BarHeld = true; } @@ -1524,12 +1712,12 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, if (ImGui::IsItemHovered() && io.MouseWheel) { - UI->TimelinePercentOffset.y -= io.MouseWheel/10; + ActivePercentOffset->y -= io.MouseWheel/10; } if (ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) { - UI->TimelinePercentOffset.y -= MouseDelta.y; + ActivePercentOffset->y -= MouseDelta.y; BarHeld = true; } @@ -1538,11 +1726,11 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, if ((ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1))) { - UI->TimelinePercentZoomed.y += MouseDelta.y; + ActivePercentZoomed->y += MouseDelta.y; BarHeld = true; } - UI->TimelinePercentZoomed.y = Max(UI->TimelinePercentZoomed.y, 0.01); + ActivePercentZoomed->y = Max(ActivePercentZoomed->y, 0.01); if (BarHeld) { ImGui_WarpMouse(UI, io.MousePos, TimelineAbsolutePos, TimelineAbsolutePos + TimelineSizeWithBorder, 2); @@ -1558,91 +1746,74 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, bool32 LeftClick = ImGui::IsMouseDown(ImGuiMouseButton_Left); bool32 RightClick = ImGui::IsMouseDown(ImGuiMouseButton_Right); - ImGui::OpenPopupOnItemClick("layercolor", ImGuiPopupFlags_MouseButtonRight); - if (ImGui::BeginPopup("layercolor")) { - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f)); - for (int c = 0; c < AmountOf(UI->LayerColors); c++) { - ImGui::PushID(c); - ImGui::PushStyleColor(ImGuiCol_Button, UI->LayerColors[c]); - real32 Size = ImGui::GetFontSize() * 2; - ImVec2 ColSize(Size, Size); - ImGui::Button("##test", ColSize); - if ((c+1) % 4) { ImGui::SameLine(); } - ImGui::PopStyleColor(); - ImGui::PopID(); - } - ImGui::PopStyleVar(); - ImGui::EndPopup(); - } - if (IsHovered && io.MouseWheel) { real32 Increment = 0.1; bool32 Direction = (io.MouseWheel > 0) ? 1 : -1; - ImVec2 Offset = (io.MousePos - (TimelineAbsolutePos + TimelineMoveSize)) / TimelineZoomSize; + ImVec2 Offset = (io.MousePos - (TimelineAbsolutePos + ActiveMoveSize)) / ActiveZoomSize; if (io.KeyShift) { - UI->TimelinePercentOffset.y += Increment*Direction; + ActivePercentOffset->y += Increment*Direction; } else if (io.KeyCtrl) { - UI->TimelinePercentOffset.x += Increment*Direction*0.3; + ActivePercentOffset->x += Increment*Direction*0.3; } else { if (Direction == 1) { - UI->TimelinePercentZoomed = UI->TimelinePercentZoomed - (UI->TimelinePercentZoomed * Increment); - UI->TimelinePercentOffset = UI->TimelinePercentOffset - ((UI->TimelinePercentOffset * Increment) + Offset*Increment); + *ActivePercentZoomed = *ActivePercentZoomed - (*ActivePercentZoomed * Increment); + *ActivePercentOffset = *ActivePercentOffset - ((*ActivePercentOffset * Increment) + Offset*Increment); } else { - UI->TimelinePercentOffset = ((UI->TimelinePercentOffset + Offset*Increment) / (1.0f - Increment)); - UI->TimelinePercentZoomed = (UI->TimelinePercentZoomed / (1.0f - Increment)); + *ActivePercentOffset = ((*ActivePercentOffset + Offset*Increment) / (1.0f - Increment)); + *ActivePercentZoomed = (*ActivePercentZoomed / (1.0f - Increment)); } } } - if (IsItemActivated) { - if (!io.KeyShift && UI->TimelineMode == timeline_mode_default) Layer_DeselectAll(Memory, File->Layer_Count); - if (State->Interact_Active == interact_type_keyframe_move || - State->Interact_Active == interact_type_keyframe_rotate || - State->Interact_Active == interact_type_keyframe_scale) { - int h = 0, c = 0, i = 0; - while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) { - block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); - if (!Layer->IsSelected) - continue; - for (int h = 0; h < AmountOf(Layer->Property); h++) { - property_channel *Property = &Layer->Property[h]; - if (Property->Block_Bezier_Count) { - int k = 0; - for (;;) { - bezier_point *Point = Bezier_Lookup(Memory, Property, k); - if (!Point->Occupied) - break; - if (Point->IsSelected) { - Keyframe_Interact_Evaluate(Memory, State, Point->IsSelected, Point->Pos, Point->Pos); + if (LeftClick) { + if (IsItemActivated) { + if (!io.KeyShift && UI->TimelineMode == timeline_mode_default) Layer_DeselectAll(Memory, File->Layer_Count); + if (State->Interact_Active == interact_type_keyframe_move || + State->Interact_Active == interact_type_keyframe_rotate || + State->Interact_Active == interact_type_keyframe_scale) { + int h = 0, c = 0, i = 0; + while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) { + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); + if (!Layer->IsSelected) + continue; + for (int h = 0; h < AmountOf(Layer->Property); h++) { + property_channel *Property = &Layer->Property[h]; + if (Property->Block_Bezier_Count) { + int k = 0; + for (;;) { + bezier_point *Point = Bezier_Lookup(Memory, Property, k); + if (!Point->Occupied) + break; + if (Point->IsSelected) { + Keyframe_Interact_Evaluate(Memory, State, Point->IsSelected, Point->Pos, Point->Pos); + } + k++; } - k++; } } } + State->Interact_Offset[0] = 0; + State->Interact_Offset[1] = 0; + State->Interact_Offset[2] = 0; + State->Interact_Offset[3] = 0; + State->Interact_Active = interact_type_none; } - State->Interact_Offset[0] = 0; - State->Interact_Offset[1] = 0; - State->Interact_Offset[2] = 0; - State->Interact_Offset[3] = 0; - State->Interact_Active = interact_type_none; + UI->BoxSelect = true; } - UI->BoxSelect = true; - } - if (IsItemActive) { - Assert(UI->BoxSelect); - draw_list->AddRectFilled(io.MouseClickedPos[0], io.MousePos, - IM_COL32(0, 0, 200, 50)); + if (IsItemActive) { + Assert(UI->BoxSelect); + draw_list->AddRectFilled(io.MouseClickedPos[0], io.MousePos, + IM_COL32(0, 0, 200, 50)); + } + } else { + UI->Warp_X = 0; + UI->Warp_Y = 0; } if (IsItemDeactivated) { UI->BoxSelect = false; } - if (!ImGui::IsMouseDown(ImGuiMouseButton_Left)) { - UI->Warp_X = 0; - UI->Warp_Y = 0; - } - draw_list->PopClipRect(); ImGui::PopClipRect(); @@ -1684,8 +1855,10 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me if (ImGui::IsKeyPressed(ImGuiKey_B)) { State->Tool = tool_brush; } - if (ImGui::IsKeyPressed(ImGuiKey_T)) { - Interact_Transform_Begin(File, Memory, State, io.MousePos); + if (ImGui::IsKeyPressed(ImGuiKey_Tab)) { + UI->TimelineMode = (UI->TimelineMode == timeline_mode_default) ? timeline_mode_graph : timeline_mode_default; + UI->GraphZoomSize = ImVec2(0, 0); + UI->GraphMoveSize = ImVec2(0, 0); } if (UI->TimelineMode == timeline_mode_graph) { if (ImGui::IsKeyPressed(ImGuiKey_G)) { @@ -1716,7 +1889,7 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me if (ImGui::IsKeyPressed(ImGuiKey_Space)) { State->IsPlaying ^= 1; } - if (ImGui::IsKeyPressed(ImGuiKey_T)) { + if (ImGui::IsKeyPressed(ImGuiKey_2)) { int h = 0, c = 0, i = 0; while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) { block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); -- cgit v1.2.3