summaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp204
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