diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/createcalls.cpp | 86 | ||||
-rw-r--r-- | src/imgui_ui.cpp | 9 | ||||
-rw-r--r-- | src/imgui_ui_viewport.cpp | 2 | ||||
-rw-r--r-- | src/include/all.h | 2 | ||||
-rw-r--r-- | src/include/main.h | 7 | ||||
-rw-r--r-- | src/main.cpp | 18 | ||||
-rw-r--r-- | src/sorted.cpp | 78 |
7 files changed, 136 insertions, 66 deletions
diff --git a/src/createcalls.cpp b/src/createcalls.cpp index d7fb4b7..ffb4c0f 100644 --- a/src/createcalls.cpp +++ b/src/createcalls.cpp @@ -788,32 +788,10 @@ Property_IsGraphSelected(memory *Memory, uint16 *Block_Bezier_Index, uint16 *Arr return 0; } -// TODO(fox): It seems like duping many layers at once causes this to take up -// exponentially more data on the undo tree than it should. Rewrite the loop to -// change the offsets before duping, taking into account all dupes, like what -// the sorting code does. -// TODO(fox): Add different modes (all dupes on top, each dupe above its layer, two for bottom) static void Sort_OffsetDupes(memory *Memory, sorted_layer_array *SortedLayerStart, block_layer *StartLayer, int i, int FauxIncrement, int LayerCount, int Mode) { - block_layer *PrevLayer = StartLayer; - for (int a = i+1; a < LayerCount; a++) { - sorted_layer_array *NextSortEntry = &SortedLayerStart[a]; - uint32 NextIndex_Physical = NextSortEntry->Block_Layer_Index; - block_layer *NextLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, NextIndex_Physical); - if (NextLayer->Vertical_Offset == PrevLayer->Vertical_Offset) { - if (Mode == 0 && !NextSortEntry->IsFake) { - History_Action_Swap(Memory, F_Layers, sizeof(NextLayer->Vertical_Offset), &NextLayer->Vertical_Offset); - NextLayer->Vertical_Offset -= 1; - } else { - NextSortEntry->SortedOffset -= 1; - } - } else { - break; - } - PrevLayer = NextLayer; - } } // NOTE(fox): PrecompLayer is assumed to be untouched from the layer it was duplicated from! @@ -867,21 +845,27 @@ Layer_Precomp_CopyContents(project_data *File, project_state *State, memory *Mem static void Project_Layer_Duplicate(project_data *File, project_state *State, memory *Memory, - sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, v2 Offset, bool32 FakeOnly, bool32 NewPrecomp) + sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, v2 Offset, bool32 NewPrecomp) { for (int c = 0; c < File->Comp_Count; c++) { sorted_comp_array SortedCompStart = SortedCompArray[c]; sorted_layer_array *SortedLayerStart = Sorted_GetLayerStart(SortedLayerArray, SortedCompArray, c); int LayerCount = SortedCompStart.LayerCount + SortedCompStart.FakeLayerCount; - for (int i = 0; i < LayerCount; i++) + int FirstDupe = -1; + int DupeCount = 0; + int Direction = (State->DuplicateMode & sortflag_up) ? 1 : -1; + if (State->DuplicateMode & sortflag_furthest && !(State->DuplicateMode & sortflag_up)) + Direction *= -1; + int i = (Direction > 0) ? 0 : LayerCount - 1; + for (;;) { - sorted_layer_array SortEntry = SortedLayerStart[i]; - uint32 Index_Physical = SortEntry.Block_Layer_Index; + sorted_layer_array *SortEntry = &SortedLayerStart[i]; + uint32 Index_Physical = SortEntry->Block_Layer_Index; block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); - if ((FakeOnly && SortEntry.IsFake) || (!FakeOnly && (Layer->IsSelected & 0x01))) + if (SortEntry->IsFake) { - if (!FakeOnly) - Layer->IsSelected = 0x00; + if (FirstDupe == -1) + FirstDupe = i; block_layer *NewLayer = (block_layer *)Memory_Block_AllocateAddress(Memory, F_Layers); History_Action_Block_Swap(Memory, F_Layers, NewLayer); @@ -894,11 +878,12 @@ Project_Layer_Duplicate(project_data *File, project_state *State, memory *Memory // TODO(fox): Effect duplication Assert(Layer->Block_Effect_Count == 0); + int NewIdx = Memory_Block_LazyIndexAtAddress(Memory, F_Layers, NewLayer); Layer_Select(Memory, State, Memory_Block_LazyIndexAtAddress(Memory, F_Layers, NewLayer)); - NewLayer->Vertical_Offset--; + // NOTE(fox): Sort entry being modified outside initial sort + // call to make undo tree more efficient! + SortEntry->Block_Layer_Index = NewIdx; - Sort_OffsetDupes(Memory, SortedLayerStart, NewLayer, i, 0, LayerCount, 0); - Assert(!NewLayer->x.Keyframe_Count); Assert(!NewLayer->y.Keyframe_Count); NewLayer->x.CurrentValue += Offset.x; @@ -916,6 +901,43 @@ Project_Layer_Duplicate(project_data *File, project_state *State, memory *Memory } else { Layer->IsSelected = 0x00; } + if ((Direction > 0) ? !(i < LayerCount) : (i <= 0)) + break; + i += Direction; + } + if (FirstDupe > -1) { + int FauxIncrement = 0; + int FurthestMark = -1; + { + sorted_layer_array SortEntry = SortedLayerStart[FirstDupe]; + uint32 Index_Physical = SortEntry.Block_Layer_Index; + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); + FurthestMark = Layer->Vertical_Offset; + } + if (State->DuplicateMode & sortflag_furthest && !(State->DuplicateMode & sortflag_up)) + { + FauxIncrement = -SortedCompStart.FakeLayerCount; + } + int i = (Direction > 0) ? 0 : LayerCount - 1; + for (;;) + { + sorted_layer_array SortEntry = SortedLayerStart[i]; + uint32 Index_Physical = SortEntry.Block_Layer_Index; + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); + History_Action_Swap(Memory, F_Layers, sizeof(Layer->Vertical_Offset), &Layer->Vertical_Offset); + if (Layer->IsSelected) { + if (State->DuplicateMode & sortflag_furthest) + Layer->Vertical_Offset = FurthestMark; + FauxIncrement += Direction; + if (State->DuplicateMode & sortflag_furthest && !(State->DuplicateMode & sortflag_up)) + Layer->Vertical_Offset += 1; + } + Layer->Vertical_Offset -= FauxIncrement; + int a = 0; + if ((Direction > 0) ? !(i < LayerCount) : (i <= 0)) + break; + i += Direction; + } } } } diff --git a/src/imgui_ui.cpp b/src/imgui_ui.cpp index 546392a..aa09bfb 100644 --- a/src/imgui_ui.cpp +++ b/src/imgui_ui.cpp @@ -131,6 +131,15 @@ ImGui_ColorPanel(project_data *File, project_state *State, ui *UI, memory *Memor UI->AltColor = Temp; } + const char *Name = (State->DuplicateMode & sortflag_up) ? "Up" : "Down"; + if (ImGui::MenuItem(Name, NULL)) { + State->DuplicateMode ^= sortflag_up; + } + Name = (State->DuplicateMode & sortflag_furthest) ? "Furthest" : "Above"; + if (ImGui::MenuItem(Name, NULL)) { + State->DuplicateMode ^= sortflag_furthest; + } + if (State->Tool == tool_default) { if (ImGui::MenuItem("All", NULL, (State->SelectionMode == 0))) { State->SelectionMode = 0; diff --git a/src/imgui_ui_viewport.cpp b/src/imgui_ui_viewport.cpp index b2830de..0cfc7da 100644 --- a/src/imgui_ui_viewport.cpp +++ b/src/imgui_ui_viewport.cpp @@ -1301,7 +1301,7 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, State->Interact_Active = interact_type_none; State->Interact_Modifier = 0; v2 Offset = V2(State->Interact_Offset[0], State->Interact_Offset[1]); - Project_Layer_Duplicate(File, State, Memory, SortedCompArray, SortedLayerArray, Offset, 1, io.KeyCtrl); + Project_Layer_Duplicate(File, State, Memory, SortedCompArray, SortedLayerArray, Offset, io.KeyCtrl); State->Interact_Dup_Previous[0] = State->Interact_Offset[0]; State->Interact_Dup_Previous[1] = State->Interact_Offset[1]; State->Interact_Offset[0] = 0; diff --git a/src/include/all.h b/src/include/all.h index 603ba1d..8182b26 100644 --- a/src/include/all.h +++ b/src/include/all.h @@ -136,7 +136,7 @@ Property_IsGraphSelected(memory *Memory, uint16 *Block_Bezier_Index, uint16 *Arr static void Project_Layer_Duplicate(project_data *File, project_state *State, memory *Memory, - sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, v2 Offset, bool32 FakeOnly, bool32 NewPrecomp); + sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, v2 Offset, bool32 NewPrecomp); static void Project_ShapeLayer_New(project_data *File, project_state *State, memory *Memory); diff --git a/src/include/main.h b/src/include/main.h index 68df39d..8debbb0 100644 --- a/src/include/main.h +++ b/src/include/main.h @@ -480,6 +480,12 @@ enum imgui_popups popup_keybinds }; +enum option_sortflag +{ + sortflag_up = 1 << 0, + sortflag_furthest = 1 << 1 +}; + struct project_state { bool32 UpdateKeyframes = 0; @@ -488,6 +494,7 @@ struct project_state bool32 DebugDisableCache = 1; // TODO(fox): Group inconsequential state UI into one thing? + bool32 DuplicateMode = sortflag_furthest | sortflag_up; bool32 ShapeMode = 0; bool32 ViewportEnabled = 0; bool32 SelectionMode = 1; diff --git a/src/main.cpp b/src/main.cpp index 894238a..42c07a9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1505,7 +1505,15 @@ int main(int argc, char *argv[]) { } break; case hotkey_duplicatelayer: { - State_ExecuteAtEnd = 2; + State->Interact_Active = interact_type_viewport_duplicate; + sorted_file Sorted = File_Sort_Push(File, State, &Memory); + History_Entry_Commit(&Memory, "Duplicate layers"); + v2 Offset = V2(State->Interact_Dup_Previous[0], State->Interact_Dup_Previous[1]); + Project_Layer_Duplicate(File, State, &Memory, Sorted.CompArray, Sorted.LayerArray, Offset, io.KeyCtrl); + State->Interact_Transform = {}; + History_Entry_End(&Memory); + File_Sort_Pop(&Memory, Sorted.Layer_SortSize, Sorted.Property_SortSize, Sorted.Source_SortSize); + State->Interact_Active = interact_type_none; } break; case hotkey_deletelayer: { @@ -1634,13 +1642,7 @@ int main(int argc, char *argv[]) { if (State_ExecuteAtEnd) { if (State_ExecuteAtEnd == 1) { Project_ShapeLayer_New(File, State, &Memory); - } else if (State_ExecuteAtEnd == 2) { - History_Entry_Commit(&Memory, "Duplicate layers"); - v2 Offset = V2(State->Interact_Dup_Previous[0], State->Interact_Dup_Previous[1]); - Project_Layer_Duplicate(File, State, &Memory, Sorted.CompArray, Sorted.LayerArray, Offset, 0, io.KeyCtrl); - State->Interact_Transform = {}; - History_Entry_End(&Memory); - } + } State->UpdateFrame = true; } diff --git a/src/sorted.cpp b/src/sorted.cpp index 3ecd69e..c039c08 100644 --- a/src/sorted.cpp +++ b/src/sorted.cpp @@ -292,36 +292,66 @@ Layer_SortAll(project_state *State, memory *Memory, if (!SortedCompStart->LayerCount) continue; sorted_layer_array *SortedLayerStart = Sorted_GetLayerStart(LayerArrayStart, CompArrayStart, c); - int i = 0; + int Direction = (State->DuplicateMode & sortflag_up) ? 1 : -1; + int Furthest = (State->DuplicateMode & sortflag_furthest) ? 1 : 0; + if (Furthest) { Direction *= -1; } + int i = (Direction > 0) ? 0 : SortedCompStart->LayerCount - 1; int FauxIncrement = 0; - while (i < SortedCompStart->LayerCount) { - int Idx = i + FauxIncrement; + int FurthestMark = -1; + for (;;) { + int Idx = i + ((Direction > 0) ? FauxIncrement : 0); + if (FauxIncrement && Furthest && (Direction > 0)) { + Idx = i + SortedCompStart->FakeLayerCount; + } sorted_layer_array *LayerEntry = &SortedLayerStart[Idx]; block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, LayerEntry->Block_Layer_Index); if (Layer->IsSelected & 0x01) { - // Sort_OffsetDupes(Memory, SortedLayerStart, Layer, LayerEntry, i, FauxIncrement, SortedCompStart->LayerCount, 1); - uint8 *Address_Start = (uint8 *)(LayerEntry); - uint8 *Address_End = (uint8 *)(&SortedLayerStart[SortedCompStart->LayerCount + FauxIncrement]) - 1; - Assert(SortedCompStart->CurrentSortIndex != (SortedCompStart->LayerCount + SortedCompStart->FakeLayerCount)); - Arbitrary_ShiftData(Address_Start, Address_End, sizeof(sorted_layer_array), 1); - sorted_layer_array *FakeLayerEntry = LayerEntry + 1; - FakeLayerEntry->SortedOffset -= 1; - Assert(FakeLayerEntry->Block_Layer_Index == LayerEntry->Block_Layer_Index); - FakeLayerEntry->IsFake = true; - FauxIncrement++; - - sorted_layer_array *PrevLayerEntry = FakeLayerEntry; - for (int a = i+1; a < SortedCompStart->LayerCount; a++) { - int NextIdx = a + FauxIncrement; - sorted_layer_array *NextLayerEntry = &SortedLayerStart[NextIdx]; - if (NextLayerEntry->SortedOffset == PrevLayerEntry->SortedOffset) - NextLayerEntry->SortedOffset -= 1; - else - break; - PrevLayerEntry = NextLayerEntry; + if (Furthest) { + if (FauxIncrement == 0) { + uint8 *Address_Start = (uint8 *)(LayerEntry); + uint8 *Address_End = (uint8 *)(&SortedLayerStart[SortedCompStart->LayerCount + FauxIncrement]) - 1; + Assert(SortedCompStart->CurrentSortIndex != (SortedCompStart->LayerCount + SortedCompStart->FakeLayerCount)); + Arbitrary_ShiftData(Address_Start, Address_End, sizeof(sorted_layer_array) * SortedCompStart->FakeLayerCount, 1); + FurthestMark = i + ((Direction > 0) ? 0 : -Direction); + } + sorted_layer_array *FakeLayerEntry = &SortedLayerStart[FurthestMark + (FauxIncrement * ((Direction > 0) ? 1 : -Direction))]; + *FakeLayerEntry = *LayerEntry; + FakeLayerEntry->IsFake = true; + FauxIncrement++; + } else { + uint8 *Address_Start = (uint8 *)(LayerEntry); + uint8 *Address_End = (uint8 *)(&SortedLayerStart[SortedCompStart->LayerCount + FauxIncrement]) - 1; + Assert(SortedCompStart->CurrentSortIndex != (SortedCompStart->LayerCount + SortedCompStart->FakeLayerCount)); + Arbitrary_ShiftData(Address_Start, Address_End, sizeof(sorted_layer_array), 1); + sorted_layer_array *FakeLayerEntry = LayerEntry + ((Direction > 0) ? 1 : 0); + Assert(FakeLayerEntry->Block_Layer_Index == LayerEntry->Block_Layer_Index); + FakeLayerEntry->IsFake = true; + FauxIncrement++; } } - i++; + if ((Direction > 0) ? !(i < SortedCompStart->LayerCount) : (i <= 0)) + break; + i += Direction; + } + if (Furthest) { Direction *= -1; } + i = FauxIncrement = 0; + int LayerCount = SortedCompStart->LayerCount + SortedCompStart->FakeLayerCount; + FurthestMark = -1; + i = (Direction > 0) ? 0 : LayerCount - 1; + for (;;) { + sorted_layer_array *LayerEntry = &SortedLayerStart[i]; + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, LayerEntry->Block_Layer_Index); + if (LayerEntry->IsFake) { + if (FurthestMark == -1) + FurthestMark = Layer->Vertical_Offset; + if (Furthest) + LayerEntry->SortedOffset = FurthestMark; + FauxIncrement += Direction; + } + LayerEntry->SortedOffset -= FauxIncrement; + if ((Direction > 0) ? !(i < LayerCount) : (i <= 0)) + break; + i += Direction; } } } |