From bb4d634962cdf97affd041a81b12c3d2c8d46bf7 Mon Sep 17 00:00:00 2001 From: Fox Caminiti Date: Thu, 17 Nov 2022 23:56:43 -0500 Subject: clipboard, simd, sd experiments --- my_imgui_widgets.cpp | 596 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 360 insertions(+), 236 deletions(-) (limited to 'my_imgui_widgets.cpp') diff --git a/my_imgui_widgets.cpp b/my_imgui_widgets.cpp index 04cedb0..bfe114b 100644 --- a/my_imgui_widgets.cpp +++ b/my_imgui_widgets.cpp @@ -52,9 +52,12 @@ ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory * for (int h = 0; h < AmountOf(Layer->Property); h++) { property_channel *Property = &Layer->Property[h]; ImGui::PushID(Property); - ImGui::Button("K"); - // if (ImGui::Button("K")) - // Keyframe_Insert(Property, Memory, File->CurrentFrame, Property->CurrentValue.f); + if (ImGui::Button("K")) { + History_Entry_Commit(Memory, "Add keyframe"); + bezier_point Point = { 1, {(real32)State->Frame_Current, Property->CurrentValue, -1, 0, 1, 0}, interpolation_type_linear, 0, {0, 0, 0}, 0 }; + Bezier_Add(Memory, Property, Point); + History_Entry_End(Memory); + } ImGui::SameLine(); ImGui_InteractSliderProperty(State, Memory, Property); ImGui::PopID(); @@ -83,15 +86,19 @@ ImGui_DebugMemoryViewer(memory *Memory, project_state *State) cache_entry *EntryArray = State->Render.Entry; char *Type[4] = { "unassigned", "comp", "source", "layer" }; - int c = 0; uint32 Blocks_Total = Memory->Slot[B_CachedBitmaps].Size / BitmapBlockSize; uint32 PerRow = sqrt(Blocks_Total); real32 BlockSize = ViewportScale.x / PerRow; - while (EntryArray[c+1].CycleTime != 0) { + for (int c = 0; c < Memory->EntryCount; c++) { ImGui::PushID(c); cache_entry Entry = EntryArray[c]; - cache_entry NextEntry = EntryArray[c+1]; - uint32 BlockSpan = NextEntry.Block_StartIndex - Entry.Block_StartIndex; + uint32 BlockSpan; + if (c+1 != Memory->EntryCount) { + cache_entry NextEntry = EntryArray[c+1]; + BlockSpan = NextEntry.Block_StartIndex - Entry.Block_StartIndex; + } else { + BlockSpan = 1; + } ImVec2 ButtonPos = ViewportMin + ImVec2((Entry.Block_StartIndex % PerRow) * BlockSize, BlockSize * (Entry.Block_StartIndex / PerRow)); ImVec2 ButtonSize = ImVec2(BlockSpan * BlockSize, BlockSize); ImGui::SetCursorScreenPos(ButtonPos); @@ -111,7 +118,6 @@ ImGui_DebugMemoryViewer(memory *Memory, project_state *State) ImGui::Text("Type - %s, Start - %i, Info - %i, %i", Type[EntryArray[c].Type], EntryArray[c].Block_StartIndex, EntryArray[c].TypeInfo, EntryArray[c].TypeInfo_Sub); ImGui::EndTooltip(); } - c++; ImGui::PopID(); } // ImGui::PopStyleVar(2); @@ -230,6 +236,54 @@ ImGui_File(project_data *File, project_state *State, memory *Memory, ImGuiIO io, ImGui::End(); } +static void +ImGui_StableDiffusion(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io) +{ + ImGui::Begin("SD prompt input"); + sd_state *SD = &State->SD; + int Size = ImGui::GetFontSize(); + ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(200, 80, 0, 255)); + if (ImGui::Button("Generate!", ImVec2(Size*8, Size*2))) { + /* + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, 0); + block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index); + cache_entry *Entry = Memory_Cache_Search(State, Memory, cache_entry_type_source, Layer->Block_Source_Index, 0); + Assert(Entry->IsCached); + void *BitmapAddress = Memory_Block_Bitmap_AddressAtIndex(Memory, Entry->Block_StartIndex); + uint64 Size = Source->Width * Source->Height * Source->BytesPerPixel; + uint64 EncodedLength = 0; + uint64 EncodedAllocSize = base64_encode_size(Size); + void *EncodedOutput = Memory_PushScratch(Memory, EncodedSize); + uint64 EncodedTrueSize; + base64_encode((uint8 *)BitmapAddress, Size, (uint8 *)EncodedOutput, &EncodedTrueSize); + Memory_PopScratch(Memory, EncodedSize); + */ + SD_Txt2Txt(SD); + } + ImGui::InputText("Address", SD->ServerAddress, SD_LEN_ADDRESS); + if (State->Initializing && (SD->ServerAddress[0] == '\0')) { + sprintf(SD->Prompt, "%s", "1girl, looking at viewer, smile, hakurei reimu, cowboy shot"); + sprintf(SD->NegPrompt, "%s", "nsfw, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark"); + sprintf(SD->ServerAddress, "%s", "http://127.0.0.1:7860"); + } + ImGui::PopStyleColor(); + ImGui::InputTextMultiline("Prompt", SD->Prompt, SD_LEN_PROMPT); + ImGui::InputTextMultiline("Negative prompt", SD->NegPrompt, SD_LEN_PROMPT); + ImGui::SliderInt("Steps", &SD->Steps, 0, 150); + ImGui::SliderInt("Width", &SD->Width, 64, 2048, "%i px"); + if (ImGui::IsItemDeactivatedAfterEdit()) { + SD->Width = SD->Width + (64 - (SD->Width % 64)); + } + ImGui::SliderInt("Height", &SD->Height, 64, 2048, "%i px"); + if (ImGui::IsItemDeactivatedAfterEdit()) { + SD->Height = SD->Height + (64 - (SD->Height % 64)); + } + ImGui::SliderFloat("CFG scale", &SD->CFG, 1, 30, "%.2f"); + ImGui::SliderFloat("Denoising strength", &SD->DenoisingStrength, 0, 1, "%.2f"); + ImGui::InputInt("Seed", &SD->Seed); + ImGui::End(); +} + static void ImGui_ColorPanel(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io) { @@ -444,7 +498,7 @@ ImGui_TransformUI(project_data *File, project_state *State, memory *Memory, ui * // real32 LocalX = ((io.MousePos.x - UI->CompPos.x) - Center.x) ; // real32 LocalY = ((io.MousePos.y - UI->CompPos.y) - Center.y) ; layer_transforms BoxTransforms = { Center.x, Center.y, 0.5, 0.5, (real32)(Interact->Radians / (PI / 180)), Interact->Scale }; - v2 LayerPoint = Transform_ScreenSpaceToLocal(BoxTransforms, CompWidth, CompHeight, BoxLength.x, BoxLength.y, *UI, ViewportMin, io.MousePos); + v2 LayerPoint = Transform_ScreenSpaceToLocal(BoxTransforms, CompWidth, CompHeight, BoxLength.x, BoxLength.y, UI->CompPos, UI->CompZoom, ViewportMin, io.MousePos); real32 U = LayerPoint.x / BoxLength.x; real32 V = LayerPoint.y / BoxLength.y; @@ -744,7 +798,6 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, UI->FocusedWindow = focus_viewport; block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex); - block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, 0); ImVec2 ViewportMin = ImGui::GetCursorScreenPos(); @@ -763,7 +816,7 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, 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)); - draw_list->AddRect(CompPosMin, CompPosMax, IM_COL32(255, 255, 255, 55)); + // draw_list->AddRect(CompPosMin, CompPosMax, IM_COL32(255, 255, 255, 55)); // Actual composition texture draw_list->PushClipRect(ViewportMin, ViewportMax, true); @@ -787,29 +840,67 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, ImGui::InvisibleButton("canvas", ViewportScale, ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight); bool32 IsHovered = ImGui::IsItemHovered(); +#if 0 bool32 IsActive = ImGui::IsItemActive(); bool32 IsActivated = ImGui::IsItemActivated(); +#else + bool32 IsActive = ImGui::IsKeyDown(ImGuiKey_3); + bool32 IsActivated = ImGui::IsKeyPressed(ImGuiKey_3); +#endif bool32 IsDeactivated = ImGui::IsItemDeactivated(); - if (IsHovered && IsActivated && ImGui::IsMouseDown(ImGuiMouseButton_Left)) + if (IsHovered && IsActivated && !ImGui::IsMouseDown(ImGuiMouseButton_Right)) { // Point to zoom in on if Z is held UI->TempZoomRatio = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, io.MousePos); - if (State->Tool == tool_brush && File->Layer_Count != 2) { - State->Interact_Active = interact_type_newlayer_paint; - History_Entry_Commit(Memory,"Paint new layer"); - uint16 SourceIndex = Source_Generate_Blank(File, State, Memory, MainComp->Width, MainComp->Height, MainComp->BytesPerPixel); - Assert(0); - // Layer_CreateFromSource(File, State, Memory, SourceIndex, MainComp->Frame_End); - History_Entry_End(Memory); + if (State->Tool == tool_brush) { + sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, File->PrincipalCompIndex); + sorted_comp_info SortedCompInfo = SortedCompArray[File->PrincipalCompIndex]; + 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); + block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index); + if (Layer->IsSelected && Source->Type == source_type_principal) { + State->Interact_Active = interact_type_brush; + State->Brush.LayerToPaint_Index = Layer->Block_Source_Index; + } + } + if (State->Brush.LayerToPaint_Index == -1) { + State->Interact_Active = interact_type_brush; + Layer_DeselectAll(File, State, Memory); + Arbitrary_Zero((uint8 *)State->Brush.TransientBitmap, 2048*2048*4); + History_Entry_Commit(Memory,"Paint new layer"); + uint16 i = Source_Generate_Blank(File, State, Memory, MainComp->Width, MainComp->Height, MainComp->BytesPerPixel); + block_layer *Layer = Layer_Init(File, Memory); + block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index); + State->Brush.LayerToPaint_Index = Memory_Block_LazyIndexAtAddress(Memory, F_Layers, (void *)Layer); + Layer->Block_Source_Index = i; + Layer->x.CurrentValue = MainComp->Width / 2; + Layer->y.CurrentValue = MainComp->Height / 2; + int TopOffset = 0; + sorted_comp_info SortedCompInfo = SortedCompArray[File->PrincipalCompIndex]; + if (SortedCompInfo.LayerCount) + { + sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, File->PrincipalCompIndex); + block_layer *TopLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, SortedLayerInfo[SortedCompInfo.LayerCount - 1].Block_Layer_Index); + TopOffset = TopLayer->Vertical_Offset; + } + Layer->Vertical_Offset = TopOffset - 1; + Layer->Frame_Start = MainComp->Frame_Start; + Layer->Frame_End = MainComp->Frame_End; + Layer->IsSelected = true; + History_Entry_End(Memory); + State->UpdateFrame = true; + } } // Layer selection if (!ImGui::IsKeyDown(ImGuiKey_Z) && State->Tool == tool_default && State->Interact_Active == interact_type_none) { int32 Selection = Layer_TestSelection(Memory, State, UI, SortedCompArray, SortedLayerArray, File->PrincipalCompIndex); if (!io.KeyShift && State->Interact_Active == interact_type_none) - Layer_DeselectAll(Memory, File->Layer_Count); + Layer_DeselectAll(File, State, Memory); if (Selection != -1) Layer_Select(Memory, State, Selection); } @@ -832,9 +923,10 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, } bool32 OtherActions = ImGui::IsKeyDown(ImGuiKey_Z) || ImGui::IsMouseDown(ImGuiMouseButton_Right); - if (State->Tool == tool_brush) { + if (State->Tool == tool_brush && State->Interact_Active == interact_type_brush) { + Assert(State->Brush.LayerToPaint_Index != -1); if (IsActive && !OtherActions) { - block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, 0); + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, State->Brush.LayerToPaint_Index); layer_transforms T_Layer = Layer_GetTransforms(Layer); block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index); void *SourceBitmapAddress = Memory_Block_AddressAtIndex(Memory, F_PrincipalBitmaps, Source->Bitmap_Index); @@ -844,31 +936,19 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, real32 DeltaDistance = sqrt(MouseDelta.x * MouseDelta.x + MouseDelta.y * MouseDelta.y); real32 DeltaSlope = MouseDelta.y / MouseDelta.x; for (real32 i = 0; i < DeltaDistance; i += State->Brush.Spacing) { - ImVec2 MousePos; - if (State->Brush.Type == brush_normal) { - MousePos = io.MousePos - (MouseDelta * (i / DeltaDistance)); - } else if (State->Brush.Type == brush_wacky1) { - MousePos = io.MousePos + (io.MousePos * (i / MouseDelta)); - } else if (State->Brush.Type == brush_wacky2) { - MousePos = io.MousePos - (MouseDelta / (i / DeltaDistance)); - } else if (State->Brush.Type == brush_wacky3) { - MousePos = io.MousePos - (MouseDelta * (i / ImVec2(MouseDelta.y, MouseDelta.x))); - } else { - Assert(0); - } - v2 LayerPos = Transform_ScreenSpaceToLocal(T_Layer, MainComp->Width, MainComp->Height, Source->Width, Source->Height, *UI, ViewportMin, MousePos); - PaintTest(Memory, Source, &State->Brush, SourceBitmapAddress, LayerPos, 4, UI->Color); + ImVec2 MousePos = ImGui_Brush_CalcMousePos(State, io, MouseDelta, i, DeltaDistance, DeltaSlope); + Brush_Render(State, UI, T_Layer, MainComp, Source, SourceBitmapAddress, ViewportMin, MousePos); } } else if (IsActivated) { ImVec2 MousePos = io.MousePos; - v2 LayerPos = Transform_ScreenSpaceToLocal(T_Layer, MainComp->Width, MainComp->Height, Source->Width, Source->Height, *UI, ViewportMin, MousePos); - PaintTest(Memory, Source, &State->Brush, SourceBitmapAddress, LayerPos, 4, UI->Color); + Brush_Render(State, UI, T_Layer, MainComp, Source, SourceBitmapAddress, ViewportMin, MousePos); } - Memory_Cache_Invalidate(State, Memory, cache_entry_type_comp, Layer->Block_Composition_Index, 0); + // Memory_Cache_Invalidate(State, Memory, cache_entry_type_comp, Layer->Block_Composition_Index, 0); State->UpdateFrame = true; } if (IsDeactivated) { + State->Brush.LayerToPaint_Index = -1; State->Interact_Active = interact_type_none; } } @@ -956,7 +1036,7 @@ ImGui_TimelineHorizontalIncrementDraw(project_state *State, ui *UI, ImDrawList * static void -ImGui_GraphInfo(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io) +ImGui_GraphInfo(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io, sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray) { bool open = true; ImGui::Begin("Graph info", &open, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse); @@ -975,8 +1055,14 @@ ImGui_GraphInfo(project_data *File, project_state *State, memory *Memory, ui *UI for (int h = 0; h < AmountOf(Layer->Property); h++) { property_channel *Property = &Layer->Property[h]; if (Property->Block_Bezier_Count) { + sorted_property_info *InfoLocation = SortedPropertyInfo + (i * 7) + h; + uint16 *ArrayLocation = SortedPropertyArray + (i * 7 * MAX_KEYFRAMES_PER_BLOCK) + (h * MAX_KEYFRAMES_PER_BLOCK); ImGui::PushID(Property); - ImGui::Text(Property->Name); + if (ImGui::Selectable(Property->Name, InfoLocation->IsGraphSelected)) { + Property_DeselectAll(File, Memory, SortedPropertyArray); + bezier_point *FirstPointAddress = Bezier_LookupAddress(Memory, Property, ArrayLocation[0]); + FirstPointAddress->IsSelected = true; + } ImGui::PopID(); } } @@ -987,16 +1073,78 @@ ImGui_GraphInfo(project_data *File, project_state *State, memory *Memory, ui *UI ImGui::End(); } +static void +ImGui_Timeline_DrawKeySheet(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io, ImDrawList *draw_list, property_channel *Property, uint16 *ArrayLocation, + ImVec2 Increment, ImVec2 TimelineAbsolutePos, ImVec2 TimelineMoveSize, ImVec2 TimelineZoomSize, + ImVec2 TimelineSize, ImVec2 TimelineSizeWithBorder, real32 LayerIncrement) +{ + ImGui::PushID(Property); + for (int p = 0; p < Property->Keyframe_Count; p++) { + int k = ArrayLocation[p]; + bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, k); + + v2 PointPos[3]; + Bezier_EvaluateValue(State, PointAddress, PointPos); + + real32 LocalPos_Ratio_X = PointPos[0].x * Increment.x; + real32 Keyframe_ScreenPos_X = TimelineAbsolutePos.x + TimelineMoveSize.x + LocalPos_Ratio_X * TimelineZoomSize.x; + + ImVec2 Keyframe_ScreenPos(Keyframe_ScreenPos_X, TimelineAbsolutePos.y); + + if (UI->BoxSelect) { + real32 Y_Top = (io.MouseClickedPos[0].y < io.MousePos.y) ? io.MouseClickedPos[0].y : io.MousePos.y; + real32 Y_Bottom = (io.MouseClickedPos[0].y > io.MousePos.y) ? io.MouseClickedPos[0].y : io.MousePos.y; + real32 X_Left = (io.MouseClickedPos[0].x < io.MousePos.x) ? io.MouseClickedPos[0].x : io.MousePos.x; + real32 X_Right = (io.MouseClickedPos[0].x > io.MousePos.x) ? io.MouseClickedPos[0].x : io.MousePos.x; + + if (Keyframe_ScreenPos.y >= Y_Top && Keyframe_ScreenPos.y <= Y_Bottom && + Keyframe_ScreenPos.x >= X_Left && Keyframe_ScreenPos.x <= X_Right) + { + if (!PointAddress->IsSelected) { + PointAddress->IsSelected = 1; + } + } else if (!io.KeyShift) { + PointAddress->IsSelected = 0; + } + } + + ImVec2 ButtonSize(16, 16); + + ImGui::PushID(p); + + ImU32 PointCol = (PointAddress->IsSelected) ? ImColor(0.8f, 0.5f, 0.0f, 1.0f) : ImColor(0.1f, 0.1f, 0.1f, 1.0f); + ImU32 LineCol = (PointAddress->IsSelected) ? ImColor(0.8f, 0.5f, 0.5f, 1.0f) : ImColor(0.4f, 0.4f, 0.4f, 1.0f); + ImGui::SetCursorScreenPos(Keyframe_ScreenPos - (ButtonSize * 0.5)); + ImGui::InvisibleButton("##keyframemover", ButtonSize, ImGuiMouseButton_Left); + bool32 IsHovered = ImGui::IsItemHovered(); + bool32 IsItemActive = ImGui::IsItemActive(); + bool32 IsItemActivated = ImGui::IsItemActivated(); + bool32 IsItemDeactivated = ImGui::IsItemDeactivated(); + bool32 LeftClick = ImGui::IsMouseDown(ImGuiMouseButton_Left); + bool32 RightClick = ImGui::IsMouseDown(ImGuiMouseButton_Right); + + if (IsHovered) + PointCol = ImColor(1.0f, 0.8f, 0.8f, 1.0f); + + if (IsItemActivated) { + PointAddress->IsSelected = 1; + } + + draw_list->AddCircleFilled(Keyframe_ScreenPos, 4, PointCol); + + ImGui::PopID(); + } + ImGui::PopID(); +} + static void ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io, ImDrawList *draw_list, ImVec2 Increment, ImVec2 TimelineAbsolutePos, ImVec2 TimelineMoveSize, ImVec2 TimelineZoomSize, - ImVec2 TimelineSize, ImVec2 TimelineSizeWithBorder, real32 LayerIncrement, uint16 *SortedPropertyArray) + ImVec2 TimelineSize, ImVec2 TimelineSizeWithBorder, real32 LayerIncrement, sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray) { + // I'm using the draw splitter here to be able to draw the dots on top of the graph lines. UI->Test.Split(draw_list, 2); - TimelineMoveSize.y = TimelineMoveSize.y + (TimelineZoomSize.y * (0.25 / 4)); - TimelineZoomSize.y = TimelineZoomSize.y * 0.6; - int h = 0, c = 0, i = 0; while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) { @@ -1006,44 +1154,63 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor int32 Frame_Start = Layer->Frame_Start; - ImVec2 Layer_ScreenPos_Min = TimelineAbsolutePos + TimelineMoveSize; // (* TimelineZoomSize); - ImGui::PushID(i); - ImU32 col = IM_COL32(255, 255, 255, 255); - - if (State->Interact_Active == interact_type_keyframe_move) { - ImVec2 DragDelta = io.MousePos - ImVec2(State->Interact_Offset[2], State->Interact_Offset[3]); - // NOTE(fox): I'm setting the X (time) to the transformed value and - // the Y (value) to the raw drag delta, because the Y units can be - // normalized while the X units are always universal across all the - // graphs (and it has to be passed into the sorter). - State->Interact_Offset[0] = (DragDelta.x / TimelineZoomSize.x) / Increment.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; - // TODO(fox): Pass min/max to sort to calculate this better! - } - - if ((io.MouseDelta.x || io.MouseDelta.y) && - (State->Interact_Active == interact_type_keyframe_move || + if ((State->Interact_Active == interact_type_keyframe_move || State->Interact_Active == interact_type_keyframe_rotate || State->Interact_Active == interact_type_keyframe_scale)) { - // Memory_Cache_Invalidate(State, Memory, cache_entry_type_comp, Lay + ImGui_WarpMouse(UI, io.MousePos, TimelineAbsolutePos, TimelineAbsolutePos + TimelineSizeWithBorder); + ImVec2 DragDelta = io.MousePos - ImVec2(State->Interact_Offset[2], State->Interact_Offset[3]); + DragDelta = DragDelta + (ImVec2(UI->Warp_X, UI->Warp_Y) * TimelineSize); + if (io.MouseDelta.x || io.MouseDelta.y) { + State->UpdateFrame = true; + } + if (State->Interact_Active == interact_type_keyframe_move) { + // The Y increment varies between graphs, so we have to do it in the Bezier_EvaluateValue call. + State->Interact_Offset[0] = (DragDelta.x / TimelineZoomSize.x) / Increment.x; + State->Interact_Offset[1] = DragDelta.y; + } else if (State->Interact_Active == interact_type_keyframe_scale) { + State->Interact_Offset[0] = (DragDelta.x / TimelineSizeWithBorder.x * UI->TimelinePercentZoomed.x) / Increment.x; + } else if (State->Interact_Active == interact_type_keyframe_rotate) { + State->Interact_Offset[0] = (DragDelta.x / TimelineZoomSize.x); + /* + real32 Slope_Old = (Keyframe_ScreenPos.y - State->Interact_Offset[3]) / (Keyframe_ScreenPos.x - State->Interact_Offset[2]); + real32 Slope_New = (Keyframe_ScreenPos.y - io.MousePos.y) / (Keyframe_ScreenPos.x - io.MousePos.x); + State->Interact_Offset[0] = atan((Slope_Old - Slope_New) / (1 + Slope_Old * Slope_New)); + */ + } } for (int h = 0; h < AmountOf(Layer->Property); h++) { property_channel *Property = &Layer->Property[h]; + sorted_property_info *InfoLocation = SortedPropertyInfo + (i * 7) + h; uint16 *ArrayLocation = SortedPropertyArray + (i * 7 * MAX_KEYFRAMES_PER_BLOCK) + (h * MAX_KEYFRAMES_PER_BLOCK); ImGui::PushID(Property); if (Property->Block_Bezier_Count) { - v2 Min, Max; - Property_MinMax(Memory, State, Property, ArrayLocation, &Min, &Max); - real32 Y_Increment = 1 / (Max.y - Min.y); + real32 MinY, MaxY; + Property_MinMax_Y(Memory, State, Property, InfoLocation, &MinY, &MaxY, 0); + real32 Y_Increment = 1 / (MaxY - MinY); + + real32 GraphScale = 0; + real32 GraphPos = 0; + if ((1 / Y_Increment) < 5) { + GraphScale = 0.2; + GraphPos = 0.3; + } else if ((1 / Y_Increment) > 700) { + GraphScale = 0.6; + GraphPos = 0.06; + } else { + GraphScale = 0.4; + GraphPos = 0.2; + } + + + real32 GraphMoveHeight = TimelineMoveSize.y + (TimelineZoomSize.y * GraphPos); + real32 GraphZoomHeight = TimelineZoomSize.y * GraphScale; + + uint32 GraphCol = InfoLocation->IsGraphSelected ? IM_COL32(255, 180, 150, 255) : IM_COL32(255, 255, 255, 70); + bezier_point *PointAddress[2] = {}; ImVec2 Keyframe_ScreenPos[6] = {}; for (int p = 0; p < Property->Keyframe_Count; p++) { @@ -1054,14 +1221,14 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor PointAddress[Idx] = Bezier_LookupAddress(Memory, Property, k); v2 PointPos[3]; - Bezier_EvaluateValue(State, PointAddress[Idx], PointPos); + Bezier_EvaluateValue(State, PointAddress[Idx], PointPos, GraphZoomHeight, Y_Increment); ImVec2 Keyframe_LocalPos[3] = { V2(PointPos[0]), V2(PointPos[0] + PointPos[1]), V2(PointPos[0] + PointPos[2]) }; ImVec2 Keyframe_LocalPos_Ratio[3]; for (int b = 0; b < 3; b++) { - Keyframe_LocalPos_Ratio[b] = (Keyframe_LocalPos[b] - ImVec2(0, Min.y)) * ImVec2(Increment.x, Y_Increment); - Keyframe_ScreenPos[NewIdx + b] = TimelineAbsolutePos + TimelineMoveSize + ((ImVec2(1, 1) * Keyframe_LocalPos_Ratio[b]) * TimelineZoomSize); + Keyframe_LocalPos_Ratio[b] = (Keyframe_LocalPos[b] - ImVec2(0, MinY)) * ImVec2(Increment.x, Y_Increment); + Keyframe_ScreenPos[NewIdx + b] = TimelineAbsolutePos + ImVec2(TimelineMoveSize.x, GraphMoveHeight) + ((ImVec2(1, -1) * Keyframe_LocalPos_Ratio[b] + ImVec2(0, 1)) * ImVec2(TimelineZoomSize.x, GraphZoomHeight)); } if (UI->BoxSelect) { @@ -1110,10 +1277,16 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor if (b != 0 && PointAddress[Idx]->IsSelected) draw_list->AddLine(Keyframe_ScreenPos[NewIdx], Keyframe_ScreenPos[NewIdx + b], LineCol, 2.0f); - if (b == 0) + if (b == 0) { draw_list->AddCircleFilled(Keyframe_ScreenPos[NewIdx + b], 4, PointCol); - else + if (InfoLocation->IsGraphSelected) { + char buf[8]; + sprintf(buf, "%.2f", Keyframe_LocalPos[0].y); + draw_list->AddText(Keyframe_ScreenPos[NewIdx + b], 0xFFFFFFFF, buf); + } + } else { draw_list->AddCircle(Keyframe_ScreenPos[NewIdx + b], 6, PointCol, 0, 2); + } ImGui::PopID(); } @@ -1124,9 +1297,9 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor if (p != 0) { if (PointAddress[0]->Type == interpolation_type_bezier && PointAddress[1]->Type == interpolation_type_bezier) { draw_list->AddBezierCubic(Keyframe_ScreenPos[OldIdx], Keyframe_ScreenPos[OldIdx + 2], - Keyframe_ScreenPos[NewIdx + 1], Keyframe_ScreenPos[NewIdx], col, 1.0f, 0); + Keyframe_ScreenPos[NewIdx + 1], Keyframe_ScreenPos[NewIdx], GraphCol, 1.0f, 0); } else { - draw_list->AddLine(Keyframe_ScreenPos[0], Keyframe_ScreenPos[3], col, 1.0f); + draw_list->AddLine(Keyframe_ScreenPos[0], Keyframe_ScreenPos[3], GraphCol, 1.0f); } } } @@ -1144,7 +1317,7 @@ static void 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) + sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray, sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray) { block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, CompIndex); sorted_comp_info SortedCompInfo = SortedCompArray[CompIndex]; @@ -1152,29 +1325,60 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem ImGui::PushID(CompIndex); - if (UI->TimelineMode == timeline_mode_default) { + // Layers are drawn from top to bottom, so we can account for opened precomps/keyframes + // without needing another loop. + real32 DisplayOffset = 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); + + int32 Frame_Start = Layer->Frame_Start; + int32 Frame_End = Layer->Frame_End; + real32 Vertical_Offset = SortEntry.SortedOffset + DisplayOffset; + + Layer_Evaluate_Display(Layer, SortedLayerArray, SortedCompArray, SortedLayerInfo, i, &DisplayOffset); - 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); - - 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); - 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; - - ImGui::PushID(i); + 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); + + 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; + + // UI + + ImU32 LayerColor = 0; + ImU32 BorderColor = 0; + 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); + char buf[21]; + sprintf(buf, "%.2f, %.2f", Layer->Vertical_Offset, SortEntry.SortedOffset); + // draw_list->AddText(Layer_ScreenPos_Min, 0xFFFFFFFF, buf); + if (UI->TimelinePercentZoomed.y <= 1.0f) + draw_list->AddText(Layer_ScreenPos_Min, 0xFFFFFFFF, String->Char); + + 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); + } + + // + + // Main interaction + + ImGui::PushID(i); + if (UI->TimelineMode == timeline_mode_default) { if (UI->BoxSelect && UI->TimelineMode == timeline_mode_default) { bool32 Test = 0; @@ -1190,7 +1394,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem if (Test) { if (!Layer->IsSelected) { - Layer->IsSelected = true; + Layer_Select(Memory, State, Index_Physical); } } else if (!io.KeyShift) { Layer->IsSelected = false; @@ -1210,7 +1414,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem } if (ImGui::IsItemActivated()) { if (!Layer->IsSelected) { - if (!io.KeyShift) Layer_DeselectAll(Memory, File->Layer_Count); + if (!io.KeyShift) Layer_DeselectAll(File, State, Memory); Layer_Select(Memory, State, Index_Physical); } } @@ -1254,7 +1458,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem if (ImGui::IsItemActivated()) { if (!Layer->IsSelected) { - if (!io.KeyShift) Layer_DeselectAll(Memory, File->Layer_Count); + if (!io.KeyShift) Layer_DeselectAll(File, State, Memory); Layer_Select(Memory, State, Index_Physical); } } @@ -1262,47 +1466,7 @@ 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; + Precomp_UICreateButton(File, State, Memory, CompIndex, SortedCompInfo, SortedLayerInfo); } if (ImGui::BeginMenu("Layer color")) { @@ -1354,12 +1518,12 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem 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); + // NOTE(fox): Some data on the tree could be saved here. + History_Action_Swap(Memory, F_File, sizeof(Layer->Vertical_Offset), &Layer->Vertical_Offset); + Layer->Vertical_Offset = SortEntry.SortedOffset; 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); } } @@ -1367,33 +1531,26 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem History_Entry_End(Memory); } } - ImGui::PopID(); - } - - } - - // 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); + // Keyframe view + uint32 Channel = 0; + for (int h = 0; h < AmountOf(Layer->Property); h++) { + property_channel *Property = &Layer->Property[h]; + if (Property->IsToggled) { + // sorted_property_info *InfoLocation = SortedPropertyInfo + (i * 7) + h; + ImVec2 GraphPos(TimelineAbsolutePos.x, Layer_ScreenPos_Min.y + (Layer_ScreenSize.y * 2) + (Layer_ScreenSize.y * Channel)); + uint16 *ArrayLocation = SortedPropertyArray + (i * 7 * MAX_KEYFRAMES_PER_BLOCK) + (h * MAX_KEYFRAMES_PER_BLOCK); + ImGui_Timeline_DrawKeySheet(File, State, Memory, UI, io, draw_list, Property, ArrayLocation, + Increment, GraphPos, TimelineMoveSize, TimelineZoomSize, + TimelineSize, TimelineSizeWithBorder, LayerIncrement); + Channel++; + } + } + } - 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); - 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; + // Precomp recursion if (Layer->IsPrecomp && Layer->Precomp_Toggled) { @@ -1404,7 +1561,9 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem 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; + // Layer_Evaluate_Display(Layer_Top, SortedLayerArray, SortedCompArray, Precomp_SortedLayerInfo, Precomp_SortedCompInfo.LayerCount - 1, &SmallestY); + // Layer_Evaluate_Display(Layer_Bottom, SortedLayerArray, SortedCompArray, Precomp_SortedLayerInfo, 0, &LargestY); + real32 PrecompHeight = LargestY - SmallestY + 2; 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)); @@ -1412,79 +1571,33 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem 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); + ImVec2 NestedTimelineAbsolutePos = TimelineAbsolutePos + Layer_LocalPos_Screen - ImVec2(0, SmallestY * Increment.y * TimelineZoomSize.y) + ImVec2(0, Layer_ScreenSize.y * 1.5); 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); + SortedCompArray, SortedLayerArray, SortedPropertyInfo, SortedPropertyArray); draw_list->PopClipRect(); ImGui::PopClipRect(); } - ImGui::PopID(); - } - - // 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++) - { - 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 = SortEntry.SortedOffset; - 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); - - 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 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); - } else { - 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); - 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); - draw_list->AddRect(Layer_ScreenPos_Min, Layer_ScreenPos_Max, ImColor(1.0f, 1.0f, 1.0f, 0.5f), 2); - } + ImGui::PopID(); } ImGui::PopID(); } static void -ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io, sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray, uint16 *SortedPropertyArray) +ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io, + sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray, sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray) { if (UI->TimelineMode == timeline_mode_graph) - ImGui_GraphInfo(File, State, Memory, UI, io); + ImGui_GraphInfo(File, State, Memory, UI, io, SortedPropertyInfo, SortedPropertyArray); ImVec2 FramePadding = ImGui::GetStyle().FramePadding; ImVec2 ItemSpacing = ImGui::GetStyle().ItemSpacing; @@ -1556,14 +1669,12 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, 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); + SortedCompArray, SortedLayerArray, SortedPropertyInfo, SortedPropertyArray); if (UI->TimelineMode == timeline_mode_graph) { @@ -1582,12 +1693,15 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, DebugWatchVar("movesize: ", &GraphMoveSize.y, d_float); draw_list->AddRectFilled(WindowMinAbs, WindowMaxAbs, - IM_COL32(50, 50, 50, 150)); + IM_COL32(50, 50, 50, 230)); ImGui_Timeline_DrawGraph(File, State, Memory, UI, io, draw_list, Increment, TimelineAbsolutePos, GraphMoveSize, GraphZoomSize, - TimelineSize, TimelineSizeWithBorder, LayerIncrement, SortedPropertyArray); + TimelineSize, TimelineSizeWithBorder, LayerIncrement, SortedPropertyInfo, SortedPropertyArray); } + ImGui_TimelineHorizontalIncrementDraw(State, UI, draw_list, TimelineSizeWithBorder, TimelineAbsolutePos, *MainComp, TimelineZoomSize, TimelineMoveSize); + + ImVec2 MouseDelta = io.MouseDelta / TimelineSize; real32 BarHandleSize = FontHeight; @@ -1747,10 +1861,15 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, if (LeftClick) { if (IsItemActivated) { - if (!io.KeyShift && UI->TimelineMode == timeline_mode_default) Layer_DeselectAll(Memory, File->Layer_Count); + if (!io.KeyShift && UI->TimelineMode == timeline_mode_default) Layer_DeselectAll(File, State, Memory); if (State->Interact_Active == interact_type_keyframe_move || State->Interact_Active == interact_type_keyframe_rotate || State->Interact_Active == interact_type_keyframe_scale) { + // bool32 CommitAction = 0; + // if (!CommitAction) { + // History_Entry_Commit(Memory, "Delete source"); + // CommitAction = 1; + History_Entry_Commit(Memory, "Add keyframe"); 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); @@ -1765,11 +1884,15 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, if (PointAddress->IsSelected) { v2 NewPos[3]; Bezier_EvaluateValue(State, PointAddress, NewPos); - PointAddress->Pos[0].x = NewPos[0].x; + History_Action_Swap(Memory, F_Bezier, sizeof(PointAddress->Pos), &PointAddress->Pos); + PointAddress->Pos[0] = NewPos[0]; + PointAddress->Pos[1] = NewPos[1]; + PointAddress->Pos[2] = NewPos[2]; } } } } + History_Entry_End(Memory); State->Interact_Offset[0] = 0; State->Interact_Offset[1] = 0; State->Interact_Offset[2] = 0; @@ -1844,9 +1967,9 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me State->Interact_Offset[3] = io.MousePos.y; State->Interact_Active = interact_type_keyframe_move; } else if (ImGui::IsKeyPressed(ImGuiKey_R)) { - State->Interact_Offset[2] = io.MousePos.x; - State->Interact_Offset[3] = io.MousePos.y; - State->Interact_Active = interact_type_keyframe_rotate; + // State->Interact_Offset[2] = io.MousePos.x; + // State->Interact_Offset[3] = io.MousePos.y; + // State->Interact_Active = interact_type_keyframe_rotate; } else if (ImGui::IsKeyPressed(ImGuiKey_S)) { State->Interact_Offset[2] = io.MousePos.x; State->Interact_Offset[3] = io.MousePos.y; @@ -1862,6 +1985,7 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me State->Interact_Offset[2] = 0; State->Interact_Offset[3] = 0; State->Interact_Active = interact_type_none; + State->UpdateFrame = true; } } if (ImGui::IsKeyPressed(ImGuiKey_Space)) { -- cgit v1.2.3