summaryrefslogtreecommitdiff
path: root/src/createcalls.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/createcalls.cpp')
-rw-r--r--src/createcalls.cpp86
1 files changed, 54 insertions, 32 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;
+ }
}
}
}