From ae94b4b9fc5b4443f6d9eb6bb450de1def108cdb Mon Sep 17 00:00:00 2001 From: Fox Caminiti Date: Wed, 24 Aug 2022 20:40:39 -0400 Subject: fixes for gl core; create/delete developing --- bezier.cpp | 77 ++++++++++++++++++---- createcalls.cpp | 28 +++++--- effects.cpp | 1 + effects.h | 2 + functions.h | 4 ++ gl_calls.cpp | 9 +-- keyframes.cpp | 84 +++++++++++------------- main.cpp | 9 ++- main.h | 14 +++- memory.cpp | 12 ++++ my_imgui_widgets.cpp | 61 ++++++++++++++++-- undo.cpp | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++- 12 files changed, 394 insertions(+), 84 deletions(-) diff --git a/bezier.cpp b/bezier.cpp index f41bd06..e5f9bf9 100644 --- a/bezier.cpp +++ b/bezier.cpp @@ -177,15 +177,52 @@ Mask_PushPoint(mask *Mask, v2 Pos) Mask->NumberOfPoints++; } -// Mask_DeletePoint(mask *Mask, uint32 p) -// { -// } +static void +Mask_ShiftPointers(mask *Mask, int16 Increment, int16 StopAt) { + if (Increment > 0) { + int16 i = Mask->NumberOfPoints - 1; + while (i >= StopAt) { + mask_point *CurrentPoint = &Mask->Point[i]; + mask_point *NextPoint = &Mask->Point[i + Increment]; + *NextPoint = *CurrentPoint; + i--; + } + } else { + int16 i = StopAt; + while (i <= Mask->NumberOfPoints - 1) { + mask_point *CurrentPoint = &Mask->Point[i]; + mask_point *NextPoint = &Mask->Point[i - Increment]; + *CurrentPoint = *NextPoint; + i++; + } + } +} + +static void +Mask_DeletePoint(memory *Memory, mask *Mask, uint16 Index) +{ + History_Entry_Commit(Memory, action_entry_default, "Delete keyframe"); + mask_point *MaskPointIndex = &Mask->Point[Index]; + History_Action_StoreData(Memory, MaskPointIndex, sizeof(mask_point)); + + History_Action_Change_Decrement(Memory, &Mask->NumberOfPoints, action_type_change_u16); + // History_Action_Shift(Memory, action_type_shift_bezier, Mask, -1, Index); + void *StartingAddress = &Mask->Point[0]; + History_Action_Shift_2(Memory, StartingAddress, sizeof(mask_point), Mask->NumberOfPoints, -1, Index); + // Mask_ShiftPointers(Mask, -1, Index); + History_Entry_End(Memory); +} +// It's more useful to input the ratio here instead of the cursor position +// since we have to use it to calculate the four new handle lengths (two on the +// new point and one on each edge). static void -Mask_AddPointToCurve(mask *Mask, uint16 Index, real32 ratio) +Mask_AddPointToCurve(memory *Memory, mask *Mask, uint16 Index, real32 ratio) { mask_point *Point0 = &Mask->Point[Index]; mask_point *Point1 = &Mask->Point[Index+1]; + if (Index + 1 == Mask->NumberOfPoints) + Point1 = &Mask->Point[0]; v2 Point0_Pos_Right = Point0->Pos + Point0->TangentRight; v2 Point1_Pos_Left = Point1->Pos + Point1->TangentLeft; @@ -196,18 +233,32 @@ Mask_AddPointToCurve(mask *Mask, uint16 Index, real32 ratio) v2 NewHandleRight = Line_RatioToPoint(Top_Half, Handle1_Half, ratio); v2 NewPos = Line_RatioToPoint(NewHandleLeft, NewHandleRight, ratio); - Point0->TangentRight = -(Point0->Pos - Handle0_Half); - Point1->TangentLeft = -(Point1->Pos - Handle1_Half); + History_Entry_Commit(Memory, action_entry_default, "Add point to curve"); + + v2 NewPoint0Pos = -(Point0->Pos - Handle0_Half); + v2 NewPoint1Pos = -(Point1->Pos - Handle1_Half); + History_Action_Change_V2(Memory, &Point0->TangentRight, &Point0->TangentRight, &NewPoint0Pos); + History_Action_Change_V2(Memory, &Point1->TangentLeft, &Point1->TangentLeft, &NewPoint1Pos); + + void *StartingAddress = &Mask->Point[0]; + History_Action_Shift_2(Memory, StartingAddress, sizeof(mask_point), Mask->NumberOfPoints, 1, Index); - for (int i = Mask->NumberOfPoints - 1; i > Index; i--) { - Mask->Point[i+1] = Mask->Point[i]; - } mask_point *PointToAdd = &Mask->Point[Index+1]; - PointToAdd->Pos = NewPos; - PointToAdd->TangentLeft = -(NewPos - NewHandleLeft); - PointToAdd->TangentRight = -(NewPos - NewHandleRight); - Mask->NumberOfPoints++; + // NOTE(fox): The above shift duplicates the keyframe at Index into where + // we're writing, Index+1. I'm using the Change action (which is normally + // for changing values that already exist) on this intermediate keyframe + // slot to save having to write a bunch of special actions for shifting and + // adding new data. + + History_Action_Change_V2(Memory, &PointToAdd->Pos, &PointToAdd->Pos, &NewPos); + v2 NewLeftPos = -(NewPos - NewHandleLeft); + v2 NewRightPos = -(NewPos - NewHandleRight); + History_Action_Change_V2(Memory, &PointToAdd->TangentLeft, &PointToAdd->TangentLeft, &NewLeftPos); + History_Action_Change_V2(Memory, &PointToAdd->TangentRight, &PointToAdd->TangentRight, &NewRightPos); + + History_Action_Change_Increment(Memory, &Mask->NumberOfPoints, action_type_change_u16); + History_Entry_End(Memory); } static void diff --git a/createcalls.cpp b/createcalls.cpp index 193deee..b5be361 100644 --- a/createcalls.cpp +++ b/createcalls.cpp @@ -279,9 +279,9 @@ Layer_ScreenSpaceToLocal(project_layer *Layer, ui *UI, comp_buffer CompBuffer, I static void LoadTestFootage(project_data *File, project_state *State, memory *Memory) { - void *SourceString = String_GenerateFromChar(Memory, "../asset/24.mp4"); + void *SourceString = String_GenerateFromChar(Memory, "../asset/a.jpg"); Source_Generate(File, Memory, SourceString); - SourceString = String_GenerateFromChar(Memory, "../asset/a.jpg"); + SourceString = String_GenerateFromChar(Memory, "../asset/24.mp4"); Source_Generate(File, Memory, SourceString); SourceString = String_GenerateFromChar(Memory, "../asset/b.jpg"); Source_Generate(File, Memory, SourceString); @@ -292,28 +292,30 @@ LoadTestFootage(project_data *File, project_state *State, memory *Memory) Layer_CreateFromSource(File, State, Memory, &File->Source[0]); SelectLayer(File->Layer[0], State, 0); + // AddEffect(File->Layer[0], Memory, 1); // property_channel *Property = &File->Layer[0]->x; // for (int i = 0; i < 16; i++) // Keyframe_Insert(Property, Memory, i*2, i*2*100); // Keyframe_Insert(Property, Memory, 1, 100); // Keyframe_Insert(Property, Memory, 15, 1500); + // Keyframe_Insert(Property, Memory, 16, 1600); // Keyframe_Insert(Property, Memory, 31, 3100); + // Keyframe_Delete(Property, Memory, 1); // History_Undo(Memory); // History_Redo(Memory); - // Property->IsToggled = true; + // Property->IsToggled = true; - // AddEffect(File->Layer[0], Memory, 3); /* mask *Mask = &File->Layer[0]->Mask[0]; File->Layer[0]->NumberOfMasks = 1; Mask->Point[0].Pos = V2(200, 200); - Mask->Point[1].Pos = V2(200, 400); - Mask->Point[2].Pos = V2(200, 520); - Mask->Point[3].Pos = V2(1080, 520); - Mask->Point[4].Pos = V2(1080, 200); + Mask->Point[1].Pos = V2(210, 400); + Mask->Point[2].Pos = V2(220, 520); + Mask->Point[3].Pos = V2(1380, 520); + Mask->Point[4].Pos = V2(1480, 200); Mask->Point[0].TangentLeft = V2(-50, 0); Mask->Point[1].TangentLeft = V2(-50, 0); @@ -335,6 +337,16 @@ LoadTestFootage(project_data *File, project_state *State, memory *Memory) Mask->NumberOfPoints = 5; Mask->IsClosed = true; + + Mask_DeletePoint(Memory, Mask, 1); + + History_Undo(Memory); + // History_Redo(Memory); + + Mask_AddPointToCurve(Memory, Mask, 1, 0.5); + + History_Undo(Memory); + History_Redo(Memory); */ // if (!Source_Generate(File, Memory, "../asset/test.png")) diff --git a/effects.cpp b/effects.cpp index 2844d23..ee84c5b 100644 --- a/effects.cpp +++ b/effects.cpp @@ -132,6 +132,7 @@ AddEffect(project_layer *Layer, memory *Memory, uint16 EffectListIndex) Effect->NumberOfProperties = EffectHeader.NumberOfProperties; Effect->DisplayType = EffectHeader.DisplayType; Effect->IsActive = true; + Effect->ImGuiID = RandomGlobalIncrement++; for (int16 i = 0; i < Effect->NumberOfProperties; i++) { Effect->Property[i].Name = EffectHeader.PropertyHeader[i].Name; Effect->Property[i].CurrentValue = EffectHeader.PropertyHeader[i].Value; diff --git a/effects.h b/effects.h index d84bc25..793cadf 100644 --- a/effects.h +++ b/effects.h @@ -32,8 +32,10 @@ struct effect { uint16 NumberOfProperties; effect_display_type DisplayType; property_channel Property[MAX_PROPERTIES_PER_EFFECT]; + bool32 IsSelected = 0; bool32 UIIsCollapsed = 0; bool32 IsActive = 1; + uint32 ImGuiID; }; diff --git a/functions.h b/functions.h index 9b63832..044d877 100644 --- a/functions.h +++ b/functions.h @@ -44,8 +44,12 @@ static void History_Entry_SetPointer(memory *Memory, void *Data); static void History_Action_Change(memory *Memory, void *DataLocation, void *OriginalData, void *NewData, action_type ActionChange); static void History_Action_Change_SwapBool(memory *Memory, bool32 *Bool); +static void History_Action_Change_V2(memory *Memory, v2 *DataAddress, v2 *OriginalData, v2 *NewData); static void History_Action_Change_Increment(memory *Memory, void *Data, action_type); +static void History_Action_Change_Decrement(memory *Memory, void *Data, action_type); static void History_Action_Shift(memory *Memory, action_type ActionChange, void *DataAddress, int16 Direction, int16 Index); +static void History_Action_Shift_2(memory *Memory, void *StartingAddress, uint32 Size, uint16 NumberOf, int16 Direction, int16 Index); +static void History_Action_StoreData(memory *Memory, void *DataAddress, uint64 ByteSize); static void History_Action_Undo(memory *Memory); static void History_Action_Redo(memory *Memory); diff --git a/gl_calls.cpp b/gl_calls.cpp index d791a9c..277b15b 100644 --- a/gl_calls.cpp +++ b/gl_calls.cpp @@ -179,10 +179,6 @@ GL_UpdateTexture(gl_effect_layer *Test, void *Data, uint16 Width, uint16 Height, Target = GL_TEXTURE_2D_MULTISAMPLE; glBindTexture(Target, Test->Texture); - glTexParameteri(Target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(Target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); if (Multisample) { // glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGB, Width, Height, GL_TRUE); @@ -194,6 +190,10 @@ GL_UpdateTexture(gl_effect_layer *Test, void *Data, uint16 Width, uint16 Height, glBindRenderbuffer(GL_RENDERBUFFER, (GLuint)Test->Stencil_Renderbuffer ); glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_STENCIL_INDEX8, Width, Height ); } else { + glTexParameteri(Target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(Target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, // GL_UNSIGNED_BYTE, Data); glBindTexture(GL_TEXTURE_2D, 0); @@ -223,6 +223,7 @@ static void GL_BindDefaultVertexArrays() { // Switch to main buffer + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, DefaultVerts.ElementBufferObject); glBindBuffer(GL_ARRAY_BUFFER, DefaultVerts.VertexBufferObject); glBufferData(GL_ARRAY_BUFFER, sizeof(GL_DefaultVertices), GL_DefaultVertices, GL_STATIC_DRAW); // position attribute diff --git a/keyframes.cpp b/keyframes.cpp index 7fb7c13..451f2b6 100644 --- a/keyframes.cpp +++ b/keyframes.cpp @@ -80,28 +80,6 @@ CheckKeyframeSort(property_channel *Property, int32 Increment, int32 b) */ } -static void -DeleteKeyframeFromMemory(property_channel *Property, int16 Increment, int16 StopAt) { - if (Increment > 0) { - int16 i = Property->NumberOfTotalKeyframes - 1; - while (i > StopAt) { - keyframe *CurrentKeyframe = KeyframeLookup(Property, i); - keyframe *NextKeyframe = KeyframeLookup(Property, i + Increment); - *NextKeyframe = *CurrentKeyframe; - i--; - } - Property->NumberOfTotalKeyframes += Increment; - } else { - int16 i = StopAt; - while (i < Property->NumberOfTotalKeyframes - 1) { - keyframe *CurrentKeyframe = KeyframeLookup(Property, i); - keyframe *NextKeyframe = KeyframeLookup(Property, i - Increment); - *CurrentKeyframe = *NextKeyframe; - i++; - } - Property->NumberOfTotalKeyframes += Increment; - } -} static void ResortPropertyChannel(property_channel *Property) { @@ -129,6 +107,28 @@ ResortPropertyChannel(property_channel *Property) { */ } +static void +Keyframe_ShiftPointers(property_channel *Property, int16 Increment, int16 StopAt) { + if (Increment > 0) { + int16 i = Property->NumberOfTotalKeyframes - 1; + while (i >= StopAt) { + keyframe *CurrentKeyframe = KeyframeLookup(Property, i); + keyframe *NextKeyframe = KeyframeLookup(Property, i + Increment); + *NextKeyframe = *CurrentKeyframe; + i--; + } + } else { + int16 i = StopAt; + while (i <= Property->NumberOfTotalKeyframes - 1) { + keyframe *CurrentKeyframe = KeyframeLookup(Property, i); + keyframe *NextKeyframe = KeyframeLookup(Property, i - Increment); + *CurrentKeyframe = *NextKeyframe; + i++; + } + } +} + + static void DeleteSelectedKeyframes(project_data *File, memory *Memory) { @@ -148,7 +148,7 @@ DeleteSelectedKeyframes(project_data *File, memory *Memory) Until = false; } } - DeleteKeyframeFromMemory(Property, -ToShift, l); + Keyframe_ShiftPointers(Property, -ToShift, l); } } ResortPropertyChannel(Property); @@ -226,28 +226,6 @@ ClampSurroundingKeyframeHandles(property_channel *Property, int16 b) { } } - -static void -ShiftKeyframes(property_channel *Property, int16 Increment, int16 StopAt) { - if (Increment > 0) { - int16 i = Property->NumberOfTotalKeyframes - 1; - while (i >= StopAt) { - keyframe *NextKeyframe = KeyframeLookup(Property, i + Increment); - keyframe *CurrentKeyframe = KeyframeLookup(Property, i); - *NextKeyframe = *CurrentKeyframe; - i--; - } - } else { - int16 i = StopAt; - while (i <= Property->NumberOfTotalKeyframes - 1) { - keyframe *NextKeyframe = KeyframeLookup(Property, i - Increment); - keyframe *CurrentKeyframe = KeyframeLookup(Property, i); - *CurrentKeyframe = *NextKeyframe; - i++; - } - } -} - static uint32 Keyframe_FindClosestIndex(property_channel *Property, int32 CurrentFrame, bool32 *Overlapping) { @@ -301,6 +279,20 @@ Keyframe_FindClosestIndex(property_channel *Property, int32 CurrentFrame, bool32 } } +// NOTE(fox): Delete calls need to increment the total number before shifting! +static void +Keyframe_Delete(property_channel *Property, memory *Memory, uint32 Index) +{ + History_Entry_Commit(Memory, action_entry_default, "Delete keyframe"); + keyframe *KeyframeIndex = KeyframeLookup(Property, Index); + History_Action_StoreData(Memory, KeyframeIndex, sizeof(keyframe)); + + History_Action_Change_Decrement(Memory, &Property->NumberOfTotalKeyframes, action_type_change_u16); + History_Action_Shift(Memory, action_type_shift_keyframe, Property, -1, Index); + Keyframe_ShiftPointers(Property, -1, Index); + History_Entry_End(Memory); +} + static void Keyframe_Insert(property_channel *Property, memory *Memory, int32 CurrentFrame, real32 Val) { @@ -317,7 +309,7 @@ Keyframe_Insert(property_channel *Property, memory *Memory, int32 CurrentFrame, History_Entry_Commit(Memory, action_entry_default, "Insert keyframe"); if (Index != Property->NumberOfTotalKeyframes) { History_Action_Shift(Memory, action_type_shift_keyframe, Property, 1, Index); - ShiftKeyframes(Property, 1, Index); + Keyframe_ShiftPointers(Property, 1, Index); } History_Action_Change_Increment(Memory, &Property->NumberOfTotalKeyframes, action_type_change_u16); diff --git a/main.cpp b/main.cpp index 85f1ed4..52cfae6 100644 --- a/main.cpp +++ b/main.cpp @@ -331,8 +331,11 @@ int main(int argc, char *argv[]) { { ImGui_ImplSDL2_ProcessEvent(&event); if (event.type == SDL_DROPFILE) { - printf("%s", event.drop.file); - // AddSource(File, Memory, event.drop.file); + char *DropFile = event.drop.file; + // TODO(fox): Free failed strings if too many get created! + void *SourceString = String_GenerateFromChar(Memory, DropFile); + Source_Generate(File, Memory, SourceString); + SDL_free(DropFile); } if (event.type == SDL_QUIT) State.IsRunning = false; @@ -356,7 +359,7 @@ int main(int argc, char *argv[]) { ImGui_EffectsPanel(&File, &State, &Memory, &UI, io); - ImGui_PropertiesPanel(&File, &State, &UI, &Memory); + ImGui_PropertiesPanel(&File, &State, &UI, &Memory, io); ImGui_Timeline(&File, &State, &Memory, &UI, io); diff --git a/main.h b/main.h index b0d1a1c..967354f 100644 --- a/main.h +++ b/main.h @@ -53,6 +53,14 @@ struct cached_bitmap { uint32 Frame; // What frame it is. }; +struct action_shift_data { + void *StartingAddress; + uint32 Size; + uint16 NumberOf; + uint16 Index; + int16 Direction; +}; + enum action_type { action_type_change_u16, action_type_change_i16, @@ -62,7 +70,10 @@ enum action_type { action_type_change_u64, action_type_change_ptr, action_type_change_string, - action_type_shift_keyframe + action_type_shift_keyframe, + action_type_shift_bezier, + action_type_shift, + action_type_storedata }; enum action_entry_type { @@ -493,6 +504,7 @@ struct ui real32 DraggingKeyframeThreshold; real32 DraggingLayerThreshold; real32 DraggingTimelineThreshold; + real32 DraggingEffectThreshold; real32 KeyframeSpacing = 6; ImVec2 BoxStart = ImVec2(0,0); diff --git a/memory.cpp b/memory.cpp index 2a9b29b..85c6610 100644 --- a/memory.cpp +++ b/memory.cpp @@ -25,6 +25,18 @@ AllocateMemory(memory *Memory, uint64 Size, memory_table_list TableName) { return Address; } +// Returns the address without advancing +static void* +Memory_GetAddressAt(memory *Memory, uint64 Size, memory_table_list TableName) { + void *Address; + memory_table *Table = &Memory->Slot[TableName]; + if (Table->CurrentPosition + Size > Table->Size) { + return NULL; + } + Address = (ptrsize *)((uint8 *)Table->Address + Table->CurrentPosition + Size); + return Address; +} + // Returns the address and THEN advances static void* Memory_Advance(memory *Memory, uint64 Size, memory_table_list TableName) { diff --git a/my_imgui_widgets.cpp b/my_imgui_widgets.cpp index ac0739e..1ef4d31 100644 --- a/my_imgui_widgets.cpp +++ b/my_imgui_widgets.cpp @@ -216,8 +216,10 @@ ImGui_DebugMemoryViewer(project_data *File, memory *Memory) ImGui::End(); } +static bool32 FU; + static void -ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *Memory) +ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io) { if (State->MostRecentlySelectedLayer > -1) { project_layer *Layer = File->Layer[State->MostRecentlySelectedLayer]; @@ -238,20 +240,33 @@ ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory * } for (int h = 0; h < Layer->NumberOfEffects; h++) { effect *Effect = Layer->Effect[h]; - ImGui::PushID(Effect); + ImGui::PushID(Effect->ImGuiID); + if (FU && h == 0) { + int a = 0; + } // this is stupid if (Effect->IsActive) ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetColorU32(ImGuiCol_ButtonHovered)); else ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetColorU32(ImGuiCol_Button)); if (ImGui::Button("V")) { - Effect->IsActive ^= 1; + History_Entry_Commit(Memory, action_entry_default, "Toggle effect"); + History_Action_Change_SwapBool(Memory, &Effect->IsActive); + History_Entry_End(Memory); State->UpdateFrame = true; } ImGui::SameLine(); ImGui::PopStyleColor(); ImGui::Button("R"); ImGui::SameLine(); - ImGui::Text(Effect->Name); + ImGui::Selectable(Effect->Name, Effect->IsSelected); + // NOTE(fox): The logic for effect dragging has to be after we've + // done the UI for the rest of the effect! + real32 Effect_Top = ImGui::GetCursorScreenPos().y; + bool32 IsHovered = ImGui::IsItemHovered(); + bool32 IsActive = ImGui::IsItemActive(); + bool32 IsActivated = ImGui::IsItemActivated(); + bool32 IsDeactivated = ImGui::IsItemDeactivated(); + if (Effect->DisplayType == standard) { for (int i = 0; i < Effect->NumberOfProperties; i++) { property_channel *Property = &Effect->Property[i]; @@ -355,6 +370,36 @@ ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory * ImGui::Button("K"); } ImGui::PopID(); + + if (IsActive) + { + if (!Effect->IsSelected && IsActivated) { + Effect->IsSelected ^= 1; + } + if (ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) + { + real32 Effect_Bottom = ImGui::GetCursorScreenPos().y; + real32 Effect_Length = Effect_Bottom - Effect_Top; + ImGui::SetMouseCursor(ImGuiMouseCursor_Hand); + UI->DraggingEffectThreshold += io.MouseDelta.y; + if (abs(UI->DraggingEffectThreshold) >= Effect_Length) { + int16 Increment = UI->DraggingEffectThreshold/Effect_Length; + effect *Effect = Layer->Effect[1]; + Layer->Effect[1] = Layer->Effect[0]; + Layer->Effect[0] = Effect; + // History_Entry_Commit(Memory, action_entry_default, "Change effect order"); + // History_Entry_End(Memory); + FU = true; + UI->DraggingEffectThreshold += -1*Increment*Effect_Length; + State->UpdateFrame = true; + State->UpdateKeyframes = true; + } + } + } + if (FU) { + FU = false; + break; + } } } else { char buf[256]; @@ -483,6 +528,10 @@ ImGui_Viewport(project_data File, project_state *State, ui *UI, memory *Memory, if (ImGui::IsItemHovered()) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); } + if (ImGui::IsItemHovered() && ImGui::IsKeyPressed(ImGuiKey_Backspace)) { + Mask_DeletePoint(Memory, Mask, p); + State->UpdateFrame = true; + } if (ImGui::IsItemActivated() && b == 0) { if (p == 0 && State->Pen.IsActive) { History_Entry_Commit(Memory, action_entry_default, "Close mask path"); @@ -491,8 +540,6 @@ ImGui_Viewport(project_data File, project_state *State, ui *UI, memory *Memory, // State->Pen.IsActive = false; // Mask->IsClosed = true; History_Entry_End(Memory); - } else if (io.KeyCtrl) { - // TODO(fox): Mask delete! } else if (io.KeyAlt) { History_Entry_Commit(Memory, action_entry_default, "Switch handles on point"); History_Action_Change_SwapBool(Memory, &Point0->HandleBezier); @@ -570,7 +617,7 @@ ImGui_Viewport(project_data File, project_state *State, ui *UI, memory *Memory, if (ImGui::IsItemActivated() && io.KeyCtrl) { v2 LayerPoint = Layer_ScreenSpaceToLocal(Layer, UI, CompBuffer, ViewportMin, io.MousePos); real32 ratio = Bezier_CubicRatioOfPoint(Point0_Pos, Point0_Pos_Right, Point1_Pos_Left, Point1_Pos, LayerPoint); - Mask_AddPointToCurve(Mask, p, ratio); + Mask_AddPointToCurve(Memory, Mask, p, ratio); } } } else { diff --git a/undo.cpp b/undo.cpp index 6ebdfca..2306db9 100644 --- a/undo.cpp +++ b/undo.cpp @@ -114,6 +114,12 @@ void History_Action_Change_SwapBool(memory *Memory, bool32 *Bool) History_Action_Change(Memory, Bool, Bool, &OppositeBool, action_type_change_i32); } +void History_Action_Change_V2(memory *Memory, v2 *DataAddress, v2 *OriginalData, v2 *NewData) +{ + History_Action_Change(Memory, (void *)&DataAddress->x, (void *)&OriginalData->x, (void *)&NewData->x, action_type_change_r32); + History_Action_Change(Memory, (void *)&DataAddress->y, (void *)&OriginalData->y, (void *)&NewData->y, action_type_change_r32); +} + void History_Action_Change_Increment(memory *Memory, void *Data, action_type ActionChange) { switch (ActionChange) @@ -155,6 +161,93 @@ void History_Action_Change_Increment(memory *Memory, void *Data, action_type Act } } +void History_Action_Change_Decrement(memory *Memory, void *Data, action_type ActionChange) +{ + switch (ActionChange) + { + case action_type_change_u16: + { + uint16 DataPlusOne = (*(uint16 *)Data) - 1; + History_Action_Change(Memory, Data, Data, &DataPlusOne, ActionChange); + } break; + case action_type_change_i16: + { + int16 DataPlusOne = (*(int16 *)Data) - 1; + History_Action_Change(Memory, Data, Data, &DataPlusOne, ActionChange); + } break; + case action_type_change_u32: + { + uint32 DataPlusOne = (*(uint32 *)Data) - 1; + History_Action_Change(Memory, Data, Data, &DataPlusOne, ActionChange); + } break; + case action_type_change_i32: + { + int32 DataPlusOne = (*(int32 *)Data) - 1; + History_Action_Change(Memory, Data, Data, &DataPlusOne, ActionChange); + } break; + case action_type_change_r32: + { + real32 DataPlusOne = (*(real32 *)Data) - 1; + History_Action_Change(Memory, Data, Data, &DataPlusOne, ActionChange); + } break; + case action_type_change_u64: + { + uint64 DataPlusOne = (*(uint64 *)Data) - 1; + History_Action_Change(Memory, Data, Data, &DataPlusOne, ActionChange); + } break; + default: + { + Assert(0); + } + } +} + +static void +Arbitrary_ShiftData(action_shift_data ShiftData) { + int16 StopAt = ShiftData.Index; + if (ShiftData.Direction > 0) { + int16 i = ShiftData.NumberOf - 1; + while (i >= StopAt) { + uint8 *CurrentData = (uint8 *)ShiftData.StartingAddress + (ShiftData.Size * i); + uint8 *NextData = (uint8 *)ShiftData.StartingAddress + (ShiftData.Size * (i + ShiftData.Direction)); + uint32 Bytes = 0; + while (Bytes < ShiftData.Size) { + *NextData++ = *CurrentData++; + Bytes++; + } + i--; + } + } else { + int16 i = StopAt; + while (i <= ShiftData.NumberOf - 1) { + uint8 *CurrentData = (uint8 *)ShiftData.StartingAddress + (ShiftData.Size * i); + uint8 *NextData = (uint8 *)ShiftData.StartingAddress + (ShiftData.Size * (i - ShiftData.Direction)); + uint32 Bytes = 0; + while (Bytes < ShiftData.Size) { + *CurrentData++ = *NextData++; + Bytes++; + } + i++; + } + } +} + +void History_Action_Shift_2(memory *Memory, void *StartingAddress, uint32 Size, uint16 NumberOf, int16 Direction, int16 Index) +{ + Memory->Action.Entry[Memory->Action.Index].NumberOfActions++; + void *Data = Memory_Advance(Memory, sizeof(action_type), P_UndoBuffer); + *(action_type *)Data = action_type_shift; + action_shift_data *ShiftData = (action_shift_data *)Memory_Advance(Memory, sizeof(action_shift_data), P_UndoBuffer); + ShiftData->StartingAddress = StartingAddress; + ShiftData->Size = Size; + ShiftData->NumberOf = NumberOf; + ShiftData->Index = Index; + ShiftData->Direction = Direction; + Data = Memory_Advance(Memory, sizeof(action_type), P_UndoBuffer); + *(action_type *)Data = action_type_shift; + Arbitrary_ShiftData(*ShiftData); +} + void History_Action_Shift(memory *Memory, action_type ActionChange, void *DataAddress, int16 Direction, int16 Index) { Memory->Action.Entry[Memory->Action.Index].NumberOfActions++; @@ -171,6 +264,15 @@ void History_Action_Shift(memory *Memory, action_type ActionChange, void *DataAd void *DataIndex = Memory_Advance(Memory, sizeof(int16), P_UndoBuffer); *(ptrsize *)DataIndex = (ptrsize)Index; } break; + case action_type_shift_bezier: + { + void *DataPropertyAddress = Memory_Advance(Memory, sizeof(void *), P_UndoBuffer); + *(ptrsize *)DataPropertyAddress = (ptrsize)DataAddress; + void *DataDirection = Memory_Advance(Memory, sizeof(int16), P_UndoBuffer); + *(ptrsize *)DataDirection = (ptrsize)Direction; + void *DataIndex = Memory_Advance(Memory, sizeof(int16), P_UndoBuffer); + *(ptrsize *)DataIndex = (ptrsize)Index; + } break; default: { Assert(0); @@ -180,6 +282,30 @@ void History_Action_Shift(memory *Memory, action_type ActionChange, void *DataAd *(action_type *)Data = ActionChange; } +// Overwrite area with arbitrary-sized memory. Only use for creation/deletion, +// not for value changes of things that already exist. +void History_Action_StoreData(memory *Memory, void *DataAddress, uint64 ByteSize) +{ + Memory->Action.Entry[Memory->Action.Index].NumberOfActions++; + void *Data = Memory_Advance(Memory, sizeof(action_type), P_UndoBuffer); + *(action_type *)Data = action_type_storedata; + Data = Memory_Advance(Memory, sizeof(uint64), P_UndoBuffer); + *(uint64 *)Data = ByteSize; + Data = Memory_Advance(Memory, sizeof(void *), P_UndoBuffer); + *(ptrsize *)Data = (ptrsize)DataAddress; + uint64 i = 0; + while (i < ByteSize) { + void *DataIndex = Memory_Advance(Memory, 1, P_UndoBuffer); + *(uint8 *)DataIndex = *((uint8 *)DataAddress + i++); + } + Data = Memory_Advance(Memory, sizeof(void *), P_UndoBuffer); + *(ptrsize *)Data = (ptrsize)DataAddress; + Data = Memory_Advance(Memory, sizeof(uint64), P_UndoBuffer); + *(uint64 *)Data = ByteSize; + Data = Memory_Advance(Memory, sizeof(action_type), P_UndoBuffer); + *(action_type *)Data = action_type_storedata; +} + // This is only called when we're certain the action is going to be taken. void History_Entry_Commit(memory *Memory, action_entry_type Type, char *Name) { @@ -264,7 +390,33 @@ void History_Action_Undo(memory *Memory) { void *DataIndex = Memory_Rewind(Memory, sizeof(int16), P_UndoBuffer); void *DataDirection = Memory_Rewind(Memory, sizeof(int16), P_UndoBuffer); void **DataPropertyAddress = (void **)Memory_Rewind(Memory, sizeof(void *), P_UndoBuffer); - ShiftKeyframes((property_channel *)*DataPropertyAddress, *(int16 *)DataDirection * -1, *(int16 *)DataIndex); + Keyframe_ShiftPointers((property_channel *)*DataPropertyAddress, *(int16 *)DataDirection * -1, *(int16 *)DataIndex); + } break; + case action_type_shift_bezier: + { + void *DataIndex = Memory_Rewind(Memory, sizeof(int16), P_UndoBuffer); + void *DataDirection = Memory_Rewind(Memory, sizeof(int16), P_UndoBuffer); + void **DataPropertyAddress = (void **)Memory_Rewind(Memory, sizeof(void *), P_UndoBuffer); + Mask_ShiftPointers((mask *)*DataPropertyAddress, *(int16 *)DataDirection * -1, *(int16 *)DataIndex); + } break; + case action_type_shift: + { + action_shift_data ShiftData = *(action_shift_data *)Memory_Rewind(Memory, sizeof(action_shift_data), P_UndoBuffer); + ShiftData.Direction *= -1; + Arbitrary_ShiftData(ShiftData); + } break; + case action_type_storedata: + { + uint64 *ByteSize = (uint64 *)Memory_Rewind(Memory, sizeof(uint64), P_UndoBuffer); + void *DataAddress = *(void **)Memory_Rewind(Memory, sizeof(void *), P_UndoBuffer); + void *DataStart = Memory_Rewind(Memory, *ByteSize, P_UndoBuffer); + uint64 i = 0; + while (i < *ByteSize) { + void *DataIndex = Memory_GetAddressAt(Memory, i, P_UndoBuffer); + *((uint8 *)DataAddress + i++) = *(uint8 *)DataIndex; + } + DataStart = Memory_Rewind(Memory, sizeof(void *), P_UndoBuffer); + DataStart = Memory_Rewind(Memory, sizeof(uint64), P_UndoBuffer); } break; default: { @@ -332,7 +484,28 @@ void History_Action_Redo(memory *Memory) { void **DataPropertyAddress = (void **)Memory_Advance(Memory, sizeof(void *), P_UndoBuffer); void *DataDirection = Memory_Advance(Memory, sizeof(int16), P_UndoBuffer); void *DataIndex = Memory_Advance(Memory, sizeof(int16), P_UndoBuffer); - ShiftKeyframes((property_channel *)*DataPropertyAddress, *(int16 *)DataDirection, *(int16 *)DataIndex); + Keyframe_ShiftPointers((property_channel *)*DataPropertyAddress, *(int16 *)DataDirection, *(int16 *)DataIndex); + } break; + case action_type_shift_bezier: + { + void **DataPropertyAddress = (void **)Memory_Advance(Memory, sizeof(void *), P_UndoBuffer); + void *DataDirection = Memory_Advance(Memory, sizeof(int16), P_UndoBuffer); + void *DataIndex = Memory_Advance(Memory, sizeof(int16), P_UndoBuffer); + Mask_ShiftPointers((mask *)*DataPropertyAddress, *(int16 *)DataDirection, *(int16 *)DataIndex); + } break; + case action_type_shift: + { + action_shift_data ShiftData = *(action_shift_data *)Memory_Advance(Memory, sizeof(action_shift_data), P_UndoBuffer); + Arbitrary_ShiftData(ShiftData); + } break; + case action_type_storedata: + { + // NOTE(fox): Right now I'm only using this to overwrite data, so all we need to do is advance. + uint64 *ByteSize = (uint64 *)Memory_Advance(Memory, sizeof(uint64), P_UndoBuffer); + void *DataAddress = *(void **)Memory_Advance(Memory, sizeof(void *), P_UndoBuffer); + void *DataEnd = Memory_Advance(Memory, *ByteSize, P_UndoBuffer); + DataEnd = Memory_Advance(Memory, sizeof(void *), P_UndoBuffer); + DataEnd = Memory_Advance(Memory, sizeof(uint64), P_UndoBuffer); } break; default: { -- cgit v1.2.3