diff options
Diffstat (limited to 'src/main.cpp')
-rw-r--r-- | src/main.cpp | 204 |
1 files changed, 189 insertions, 15 deletions
diff --git a/src/main.cpp b/src/main.cpp index c7e4808..f8dd546 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -40,6 +40,7 @@ uint32 BitmapFill = 0x00000001; #include "imgui_helper.cpp" #include "imgui_ui_properties.cpp" #include "imgui_ui_timeline.cpp" + #include "imgui_ui_viewport.cpp" #if DEBUG #include "imgui_ui_debug.cpp" @@ -345,6 +346,158 @@ GL_Test(const ImDrawList* parent_list, const ImDrawCmd* cmd) GL_DeleteHWBuffer(&MSBuffer); } +// TODO(fox): We have five functions that essentially do this same precomp loop +// that carries over transform data; wrap the loop into a function like Block_Loop. + +// Find the precomp the user most likely wants to insert a shape into, the +// precomp that is or contains MostRecentlySelectedLayer. +static void +LayerIterate_DeepestPrecomp(project_state *State, memory *Memory, uint32 CompIndex, layer_transforms ExtraT, v2 Center, + sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, int *SelectionCount, int *SelectedLayerIndex, int *SelectedPrecompIndex) +{ + block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, CompIndex); + sorted_comp_array *SortedCompStart = &SortedCompArray[CompIndex]; + sorted_layer_array *SortedLayerStart = Sorted_GetLayerStart(SortedLayerArray, SortedCompArray, CompIndex); + int LayerCount = SortedCompStart->LayerCount + SortedCompStart->FakeLayerCount; + for (int i = LayerCount - 1; i >= 0; i--) + { + 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); + Assert(Layer->Block_Composition_Index == CompIndex); + int Width = 0, Height = 0; + Layer_GetDimensions(Memory, Layer, &Width, &Height); + if (Layer->IsPrecomp) { + // only like 20% sure how this works... + layer_transforms NewExtraT = Layer_GetTransforms(Layer); + v2 NewCenter = T_CompPosToLayerPos(NewExtraT, Comp->Width, Comp->Height, Width, Height, Center.x, Center.y); + NewExtraT.rotation = ExtraT.rotation - NewExtraT.rotation; + NewExtraT.scale = ExtraT.scale / NewExtraT.scale; + Assert(0); + // LayerIterate_Te(State, Memory, Layer->Block_Source_Index, NewExtraT, NewCenter, SortedCompArray, SortedLayerArray); + } + v2 Position = State->Interact_Transform.Position; + real32 Rad = (ExtraT.rotation * (PI / 180)); + v2 XAxis = Position.x * ExtraT.scale * V2(cos(Rad), sin(Rad)); + v2 YAxis = Position.y * -ExtraT.scale * V2(sin(Rad), -cos(Rad)); + Position = XAxis + YAxis; + layer_transforms T = Layer_GetTransforms(Layer); + v2 UV = T_CompUVToLayerUV(T, Comp->Width, Comp->Height, Width, Height, Center / V2(Comp->Width, Comp->Height)); + if (UV.x <= 1.0f && UV.x >= 0.0f && UV.y <= 1.0f && UV.y >= 0.0f && Layer->IsSelected) + { + *SelectionCount += 1; + *SelectedLayerIndex = i; + *SelectedPrecompIndex = Layer->Block_Composition_Index; + } + } +} + +// We have to loop over the layers a second time when testing selection because +// we want to change the behavior if the mouse is clicking on a layer that is +// already selected. +static void +LayerIterate_SelectionStatus(project_state *State, memory *Memory, uint32 CompIndex, layer_transforms ExtraT, v2 Center, + sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, int *SelectionCount, int *SelectedLayerIndex, int *SelectedPrecompIndex) +{ + block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, CompIndex); + sorted_comp_array *SortedCompStart = &SortedCompArray[CompIndex]; + sorted_layer_array *SortedLayerStart = Sorted_GetLayerStart(SortedLayerArray, SortedCompArray, CompIndex); + int LayerCount = SortedCompStart->LayerCount + SortedCompStart->FakeLayerCount; + for (int i = LayerCount - 1; i >= 0; i--) + { + 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); + Assert(Layer->Block_Composition_Index == CompIndex); + int Width = 0, Height = 0; + Layer_GetDimensions(Memory, Layer, &Width, &Height); + if (Layer->IsPrecomp) { + // only like 20% sure how this works... + layer_transforms NewExtraT = Layer_GetTransforms(Layer); + v2 NewCenter = T_CompPosToLayerPos(NewExtraT, Comp->Width, Comp->Height, Width, Height, Center.x, Center.y); + NewExtraT.rotation = ExtraT.rotation - NewExtraT.rotation; + NewExtraT.scale = ExtraT.scale / NewExtraT.scale; + LayerIterate_SelectionStatus(State, Memory, Layer->Block_Source_Index, NewExtraT, NewCenter, SortedCompArray, SortedLayerArray, SelectionCount, SelectedLayerIndex, SelectedPrecompIndex); + } + v2 Position = State->Interact_Transform.Position; + real32 Rad = (ExtraT.rotation * (PI / 180)); + v2 XAxis = Position.x * ExtraT.scale * V2(cos(Rad), sin(Rad)); + v2 YAxis = Position.y * -ExtraT.scale * V2(sin(Rad), -cos(Rad)); + Position = XAxis + YAxis; + layer_transforms T = Layer_GetTransforms(Layer); + v2 UV = T_CompUVToLayerUV(T, Comp->Width, Comp->Height, Width, Height, Center / V2(Comp->Width, Comp->Height)); + if (UV.x <= 1.0f && UV.x >= 0.0f && UV.y <= 1.0f && UV.y >= 0.0f && Layer->IsSelected && !Layer->IsLocked) + { + *SelectionCount += 1; + *SelectedLayerIndex = i; + *SelectedPrecompIndex = Layer->Block_Composition_Index; + } + } +} + +static int32 +LayerIterate_SelectionAct(project_state *State, memory *Memory, uint32 CompIndex, layer_transforms ExtraT, v2 Center, + sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, int SelectionCount, int SelectedLayerIndex, int SelectedPrecompIndex, bool32 BelowOnly) +{ + int32 LayerIndex = -1; + block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, CompIndex); + sorted_comp_array *SortedCompStart = &SortedCompArray[CompIndex]; + sorted_layer_array *SortedLayerStart = Sorted_GetLayerStart(SortedLayerArray, SortedCompArray, CompIndex); + int LayerCount = SortedCompStart->LayerCount + SortedCompStart->FakeLayerCount; + for (int i = LayerCount - 1; i >= 0; i--) + { + 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); + Assert(Layer->Block_Composition_Index == CompIndex); + int Width = 0, Height = 0; + Layer_GetDimensions(Memory, Layer, &Width, &Height); + if (Layer->IsPrecomp && Layer->IsSelected) { + // only like 20% sure how this works... + layer_transforms NewExtraT = Layer_GetTransforms(Layer); + v2 NewCenter = T_CompPosToLayerPos(NewExtraT, Comp->Width, Comp->Height, Width, Height, Center.x, Center.y); + NewExtraT.rotation = ExtraT.rotation - NewExtraT.rotation; + NewExtraT.scale = ExtraT.scale / NewExtraT.scale; + LayerIndex = LayerIterate_SelectionAct(State, Memory, Layer->Block_Source_Index, NewExtraT, NewCenter, SortedCompArray, SortedLayerArray, SelectionCount, SelectedLayerIndex, SelectedPrecompIndex, BelowOnly); + if (LayerIndex != -1) { + Layer->IsSelected = -1; + return LayerIndex; + } + } + v2 Position = State->Interact_Transform.Position; + real32 Rad = (ExtraT.rotation * (PI / 180)); + v2 XAxis = Position.x * ExtraT.scale * V2(cos(Rad), sin(Rad)); + v2 YAxis = Position.y * -ExtraT.scale * V2(sin(Rad), -cos(Rad)); + Position = XAxis + YAxis; + layer_transforms T = Layer_GetTransforms(Layer); + v2 UV = T_CompUVToLayerUV(T, Comp->Width, Comp->Height, Width, Height, Center / V2(Comp->Width, Comp->Height)); + if (UV.x <= 1.0f && UV.x >= 0.0f && UV.y <= 1.0f && UV.y >= 0.0f && !Layer->IsSelected && !Layer->IsLocked) + { + if (!BelowOnly && SelectionCount == 1) { + if (i < SelectedLayerIndex || SelectedPrecompIndex != CompIndex) { + LayerIndex = Index_Physical; + break; + } + } else { + LayerIndex = Index_Physical; + break; + } + } + } + return LayerIndex; +} + +static int32 +LayerIterate_TestSelection(project_state *State, memory *Memory, uint32 PrincipalIndex, layer_transforms ExtraT, v2 Center, + sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, bool32 BelowOnly) +{ + int SelectionCount = 0; + int SelectedLayerIndex = 0; + int SelectedPrecompIndex = 0; + LayerIterate_SelectionStatus(State, Memory, PrincipalIndex, ExtraT, Center, SortedCompArray, SortedLayerArray, &SelectionCount, &SelectedLayerIndex, &SelectedPrecompIndex); + return LayerIterate_SelectionAct(State, Memory, PrincipalIndex, ExtraT, Center, SortedCompArray, SortedLayerArray, SelectionCount, SelectedLayerIndex, SelectedPrecompIndex, BelowOnly); +} + // Same loop as Render_UI and ImGui_Viewport_SelectedLayerUI except we're // finding the inverse transform-- i.e. transforming the layers locally rather // than transforming them in comp space. @@ -367,17 +520,8 @@ LayerIterate(project_state *State, memory *Memory, uint32 CompIndex, layer_trans // only like 20% sure how this works... layer_transforms NewExtraT = Layer_GetTransforms(Layer); v2 NewCenter = T_CompPosToLayerPos(NewExtraT, Comp->Width, Comp->Height, Width, Height, Center.x, Center.y); - if (State->Interact_Transform.Radians != 0.0f) - NewExtraT.rotation = -NewExtraT.rotation; - if (ExtraT.scale) { - NewExtraT = Transform_Add2(ExtraT, NewExtraT, Comp->Width, Comp->Height); - v2 NewPos = T_CompPosToLayerPos(NewExtraT, Comp->Width, Comp->Height, Width, Height, NewExtraT.x, NewExtraT.y); - NewExtraT.x = NewPos.x; - NewExtraT.y = NewPos.y; - } else { - NewExtraT.rotation = -NewExtraT.rotation; - NewExtraT.scale = 1.0f / NewExtraT.scale; - } + NewExtraT.rotation = ExtraT.rotation - NewExtraT.rotation; + NewExtraT.scale = ExtraT.scale / NewExtraT.scale; LayerIterate(State, Memory, Layer->Block_Source_Index, NewExtraT, NewCenter, SortedCompArray, SortedLayerArray); } if (Layer->IsSelected == 1) { @@ -385,12 +529,17 @@ LayerIterate(project_state *State, memory *Memory, uint32 CompIndex, layer_trans if (Layer->IsPrecomp) PostMsg(State, "DEBUG: Precomp transformed!"); #endif + v2 Position = State->Interact_Transform.Position; + real32 Rad = (ExtraT.rotation * (PI / 180)); + v2 XAxis = Position.x * ExtraT.scale * V2(cos(Rad), sin(Rad)); + v2 YAxis = Position.y * -ExtraT.scale * V2(sin(Rad), -cos(Rad)); + Position = XAxis + YAxis; layer_transforms T = Layer_GetTransforms(Layer); History_Action_Swap(Memory, F_Layers, sizeof(Layer->x.CurrentValue), &Layer->x.CurrentValue); History_Action_Swap(Memory, F_Layers, sizeof(Layer->y.CurrentValue), &Layer->y.CurrentValue); History_Action_Swap(Memory, F_Layers, sizeof(Layer->scale.CurrentValue), &Layer->scale.CurrentValue); History_Action_Swap(Memory, F_Layers, sizeof(Layer->rotation.CurrentValue), &Layer->rotation.CurrentValue); - Transform_ApplyLocal(State->Interact_Transform, T, ExtraT, Center, Comp->Width, Comp->Height, Width, Height, + Transform_ApplyLocal(State->Interact_Transform, Position, Center, &Layer->x.CurrentValue, &Layer->y.CurrentValue, &Layer->rotation.CurrentValue, &Layer->scale.CurrentValue); } } @@ -862,7 +1011,7 @@ int main(int argc, char *argv[]) { MainComp->Frame_Count = 80; MainComp->Frame_End = 79; MainComp->Occupied = 1; - MainComp->Name_String_Index = String_AddToFile(&Memory, "Main comp"); + MainComp->Name_String_Index = String_AddToFile(&Memory, "Main comp", 0); File->Comp_Count = 1; @@ -1014,7 +1163,7 @@ int main(int argc, char *argv[]) { State->UpdateFrame = true; State->MostRecentlySelectedLayer = 0; } - + // File->PrincipalCompIndex = 1; #else // uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/yu.webm"); // block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, SourceIndex); @@ -1082,6 +1231,14 @@ int main(int argc, char *argv[]) { // NOTE(fox): These commands affect sorting, and should not be executed // in any UI or the renderer. + + // TODO(fox): Even though they affect sorting there are some of them + // that _need_ sort info in order to be able to be wrapped in one + // HistoryEntry, so we can either create a new sort info in place or + // execute the command right before the sort info used by the + // UI/renderer is popped, and I'm choosing the latter. + int State_ExecuteAtEnd = 0; + if (State->HotkeyInput) { switch (State->HotkeyInput) { case hotkey_none: @@ -1104,13 +1261,17 @@ int main(int argc, char *argv[]) { } break; case hotkey_newlayer_shape: { - Project_ShapeLayer_New(File, State, &Memory); + State_ExecuteAtEnd = 1; } break; case hotkey_newlayer_source: { Source_UICreateButton(File, State, &Memory); State->UpdateKeyframes = true; } break; + case hotkey_duplicatelayer: + { + State_ExecuteAtEnd = 2; + } break; case hotkey_deletelayer: { Project_Layer_Delete(File, State, &Memory); @@ -1223,6 +1384,19 @@ int main(int argc, char *argv[]) { Arbitrary_Zero((uint8 *)State->Queue.Item, sizeof(State->Queue.Item)); #endif + 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); + State->Interact_Transform = {}; + History_Entry_End(&Memory); + } + State->UpdateFrame = true; + } + File_Sort_Pop(&Memory, Sorted.Layer_SortSize, Sorted.Property_SortSize, Sorted.Source_SortSize); // NOTE(fox): We could theoretically allow scratch to persist between |