summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--createcalls.cpp84
-rw-r--r--defines.h1
-rw-r--r--imgui_ops.h2
-rw-r--r--main.cpp174
-rw-r--r--main.h29
-rw-r--r--memory.h3
-rw-r--r--my_imgui_widgets.cpp399
-rw-r--r--my_math.h10
8 files changed, 512 insertions, 190 deletions
diff --git a/createcalls.cpp b/createcalls.cpp
index 6a830b5..c2122c2 100644
--- a/createcalls.cpp
+++ b/createcalls.cpp
@@ -35,6 +35,14 @@ Source_Generate(project_data *File, project_state *State, memory *Memory, void *
return -1;
}
+static bezier_point *
+Bezier_Lookup(memory *Memory, property_channel *Property, uint16 Index)
+{
+ Assert(Index < MAX_KEYFRAMES_PER_BLOCK);
+ block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Property->Block_Bezier_Index[0]);
+ return &Bezier->Point[Index];
+}
+
static property_channel
Property_InitFloat(char *Name, real32 Val, real32 ScrubVal, real32 MinVal = PROPERTY_REAL_MIN, real32 MaxVal = PROPERTY_REAL_MAX) { property_channel Property = {};
Property.Name = Name;
@@ -45,19 +53,55 @@ Property_InitFloat(char *Name, real32 Val, real32 ScrubVal, real32 MinVal = PROP
return Property;
}
+static property_info
+Property_GetInfo(memory *Memory, property_channel *Property)
+{
+ property_info PropertyInfo = {};
+ for (int k = 0; k < Property->Keyframe_Count; k++) {
+ bezier_point *Point = Bezier_Lookup(Memory, Property, k);
+ PropertyInfo.MinVal = (Point->Pos[0].y < PropertyInfo.MinVal) ? Point->Pos[0].y : PropertyInfo.MinVal;
+ PropertyInfo.MaxVal = (Point->Pos[0].y > PropertyInfo.MaxVal) ? Point->Pos[0].y : PropertyInfo.MaxVal;
+ }
+ return PropertyInfo;
+}
+
static void
-Layer_Interact_Evaluate(memory *Memory, project_state *State, int32 *Frame_Start, int32 *Frame_End, real32 *Vertical_Offset)
+Layer_Interact_Evaluate(memory *Memory, project_state *State, uint16 Layer_Index_Physical, sorted_comp_info SortedCompInfo, sorted_layer *SortedLayerInfo,
+ int32 *Frame_Start, int32 *Frame_End, real32 *Vertical_Offset)
{
if (State->Interact_Active == interact_type_layer_move) {
*Frame_Start += (int32)(State->Interact_Offset[0] + 0);
*Frame_End += (int32)(State->Interact_Offset[0] + 0);
- *Vertical_Offset += (int32)State->Interact_Offset[1];
- } else if (State->Interact_Active == interact_type_layer_timeadjust) {
+
+ real32 DesiredOffset = *Vertical_Offset + (int32)State->Interact_Offset[1];
+ bool32 Direction = ((int32)State->Interact_Offset[1] > 0) ? 1 : -1;
+ int i = (Direction > 0) ? SortedCompInfo.LayerCount - 1 : 0;
+ bool32 Case = 1;
+ while (Case) {
+ sorted_layer SortEntry = SortedLayerInfo[i];
+ uint32 Index_Physical = SortEntry.Block_Layer_Index;
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
+ bool32 Test = (Direction > 0) ?
+ ((Layer->Vertical_Offset <= DesiredOffset) && (Layer->Vertical_Offset > *Vertical_Offset)) :
+ ((Layer->Vertical_Offset >= DesiredOffset) && (Layer->Vertical_Offset < *Vertical_Offset));
+ if (!Layer->IsSelected && Test) {
+ DesiredOffset += Direction;
+ }
+ i -= Direction;
+ Case = (Direction > 0) ? (i >= 0) : (i < SortedCompInfo.LayerCount);
+ }
+ *Vertical_Offset = DesiredOffset;
+ }
+ else if (State->Interact_Active == interact_type_layer_timeadjust) {
int Side[2] = {0};
Assert(State->Interact_Offset[1] == 0 || State->Interact_Offset[1] == 1);
Side[(int)State->Interact_Offset[1]] = 1;
*Frame_Start += (int32)(State->Interact_Offset[0] * Side[0]);
+ if (*Frame_Start >= *Frame_End)
+ *Frame_Start = *Frame_End - 1;
*Frame_End += (int32)(State->Interact_Offset[0] * Side[1]);
+ if (*Frame_End <= *Frame_Start)
+ *Frame_End = *Frame_Start + 1;
}
}
@@ -81,6 +125,24 @@ Layer_GetSortedArray(sorted_layer *LayerArrayStart, sorted_comp_info *SortedComp
return LayerArrayStart + LayerOffset;
}
+void Layer_RecursiveDeselect(memory *Memory, sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray, uint16 TargetIndex, uint16 PrincipalIndex)
+{
+ block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, PrincipalIndex);
+ sorted_comp_info SortedCompInfo = SortedCompArray[PrincipalIndex];
+ sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, PrincipalIndex);
+ for (int i = 0; i < SortedCompInfo.LayerCount; i++) {
+ sorted_layer SortEntry = SortedLayerInfo[i];
+ uint32 Index_Physical = SortEntry.Block_Layer_Index;
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
+ if (Layer->IsPrecomp) {
+ Layer_RecursiveDeselect(Memory, SortedCompArray, SortedLayerArray, TargetIndex, Layer->Block_Source_Index);
+ }
+ if (Layer->Block_Composition_Index != TargetIndex) {
+ Layer->IsSelected = false;
+ }
+ }
+}
+
void Layer_SortAll(memory *Memory, sorted_layer *LayerArrayStart, sorted_comp_info *CompStart, uint32 LayerCount, uint32 CompCount)
{
for (uint32 i = 0; i < LayerCount; i++) {
@@ -98,7 +160,7 @@ void Layer_SortAll(memory *Memory, sorted_layer *LayerArrayStart, sorted_comp_in
while (SortedIndex_Playhead < SortedCompInfo->CurrentSortIndex) {
sorted_layer LayerEntry = SortedLayerInfo[SortedIndex_Playhead];
block_layer *TestLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, LayerEntry.Block_Layer_Index);
- if (Layer->Vertical_Offset < TestLayer->Vertical_Offset) {
+ if (-Layer->Vertical_Offset < -TestLayer->Vertical_Offset) {
break;
} else {
SortedIndex_Playhead++;
@@ -106,19 +168,21 @@ void Layer_SortAll(memory *Memory, sorted_layer *LayerArrayStart, sorted_comp_in
}
if (SortedIndex_Playhead != SortedCompInfo->CurrentSortIndex) {
uint8 *Address_Start = (uint8 *)(SortedLayerInfo + SortedIndex_Playhead);
- uint8 *Address_End = (uint8 *)(SortedLayerInfo + i);
+ uint8 *Address_End = (uint8 *)(SortedLayerInfo + SortedCompInfo->CurrentSortIndex) - 1;
+ Assert(SortedCompInfo->CurrentSortIndex != SortedCompInfo->LayerCount);
Arbitrary_ShiftData(Address_Start, Address_End, sizeof(sorted_layer), 1);
}
sorted_layer *LayerEntry = SortedLayerInfo + SortedIndex_Playhead;
LayerEntry->Block_Layer_Index = i;
SortedCompInfo->CurrentSortIndex++;
}
- Assert(CompStart[0].LayerCount == 2);
- Assert(CompStart[1].LayerCount == 2);
+ // Assert(CompStart[0].LayerCount == 3);
+ // Assert(CompStart[1].LayerCount == 2);
// Assert(LayerArrayStart[0].Block_Layer_Index == 0);
- // Assert(LayerArrayStart[1].Block_Layer_Index == 1);
- // Assert(LayerArrayStart[2].Block_Layer_Index == 2);
- // Assert(LayerArrayStart[3].Block_Layer_Index == 3);
+ // Assert(LayerArrayStart[1].Block_Layer_Index == 2);
+ // Assert(LayerArrayStart[2].Block_Layer_Index == 4);
+ // Assert(LayerArrayStart[4].Block_Layer_Index == 1);
+ // Assert(LayerArrayStart[5].Block_Layer_Index == 3);
}
block_layer * Layer_Init(project_data *File, memory *Memory)
diff --git a/defines.h b/defines.h
index 2ab2ba6..ccadb78 100644
--- a/defines.h
+++ b/defines.h
@@ -35,7 +35,6 @@ typedef uint64 ptrsize; // is there a compiler variable for 32 vs 64 bit like
#define MAX_PROPERTIES_PER_EFFECT 16
#define MAX_KEYFRAME_BLOCKS 64
#define MAX_KEYFRAMES_PER_BLOCK 32 // max keyframes on a single channel is 2048
-#define STRING_SIZE 1024 // TODO(fox): Paths above STRING_SIZE length aren't handled properly.
#define MAX_SELECTED_PROPERTIES 16
diff --git a/imgui_ops.h b/imgui_ops.h
index 2249de3..e2627ab 100644
--- a/imgui_ops.h
+++ b/imgui_ops.h
@@ -1,3 +1,5 @@
+
+
ImVec2 operator+(ImVec2 A, ImVec2 B)
{
ImVec2 Result;
diff --git a/main.cpp b/main.cpp
index d6f9e71..bdd4786 100644
--- a/main.cpp
+++ b/main.cpp
@@ -82,14 +82,11 @@ static uint32 RandomGlobalIncrement = 0;
static void
Main_RenderUI(ImGuiIO io, ImVec4 clear_color, SDL_Window *window)
{
- printf("Call ImGui::Render\n");
ImGui::Render();
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);
glClear(GL_COLOR_BUFFER_BIT);
- printf("Call GL renderer\n");
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
- printf("Call window swap\n");
SDL_GL_SwapWindow(window);
}
@@ -131,7 +128,7 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, ui *UI,
ImGui::DockSpaceOverViewport();
if (!io.WantCaptureKeyboard)
- ImGui_ProcessInputs(State, io);
+ ImGui_ProcessInputs(File, State, Memory, io);
#if 0
@@ -147,10 +144,6 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, ui *UI,
#if DEBUG
ImGui_DebugUndoTree(&File, &Memory);
- if (Debug.ToggleWindow) {
- ImGui::ShowDemoWindow();
- ImGui_DebugMemoryViewer(&File, &Memory);
- }
#endif
#endif
@@ -159,7 +152,10 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, ui *UI,
ImGui_Timeline(File, State, Memory, UI, io);
ImGui_File(File, State, Memory, io);
- ImGui_DebugMemoryViewer(State);
+ if (Debug.ToggleWindow) {
+ ImGui::ShowDemoWindow();
+ ImGui_DebugMemoryViewer(State);
+ }
// ImGui::ShowDemoWindow();
#if DEBUG
@@ -305,15 +301,13 @@ int main(int argc, char *argv[]) {
Memory_InitTable(&GlobalMemory, &Memory, 40 * 1024 * 1024, P_MiscCache, "Misc persistent");
Memory_InitTable(&GlobalMemory, &Memory, sizeof(project_data), F_File, "File", sizeof(project_data));
- Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Precomps, "Precomps", sizeof(block_composition));
- Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Layers, "Layers", sizeof(block_layer));
- Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Sources, "Sources", sizeof(block_source));
- // Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Effects, "Effects");
- // Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Keyframes, "Keyframe blocks");
+ Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Precomps, "Precomps", sizeof(block_composition));
+ Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Layers, "Layers", sizeof(block_layer));
+ Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Sources, "Sources", sizeof(block_source));
+ Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Bezier, "Bezier paths (keyframes, masks)", sizeof(block_bezier));
Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Strings, "Strings", sizeof(block_string));
Memory_InitTable(&GlobalMemory, &Memory, (uint64)64 * 1024 * 1024, B_ScratchSpace, "Scratch");
- // Memory_InitTable(&GlobalMemory, &Memory, (uint64)1 * 1024 * 1024, B_CachedBitmapInfo, "Cached bitmap info");
Memory_InitTable(&GlobalMemory, &Memory, (uint64)50 * 1024 * 1024, B_CachedBitmaps, "Cached bitmap buffer");
#if ARM
@@ -367,44 +361,141 @@ int main(int argc, char *argv[]) {
uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/a.jpg");
block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, 0);
- Layer_CreateFromSource(File, State, &Memory, SourceIndex, MainComp->Frame_End);
+ {
+ Layer_CreateFromSource(File, State, &Memory, SourceIndex, MainComp->Frame_End);
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, File->Layer_Count - 1);
+ Layer->Vertical_Offset = 6;
+ Layer->Col[0] = 1;
+ Layer->Col[1] = 0;
+ Layer->Col[2] = 0;
+ Layer->Block_Composition_Index = 0;
+
+ property_channel *Property = &Layer->x;
+ Property->Block_Bezier_Index[0] = Memory_Block_AllocateNew(&Memory, F_Bezier);
+ Property->Block_Bezier_Count = 1;
+
+ block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(&Memory, F_Bezier, Property->Block_Bezier_Index[0]);
+ Bezier->Occupied = 1;
+
+ Bezier->Point[0].Pos[0] = V2(0, 0);
+ Bezier->Point[1].Pos[0] = V2(10, 50);
+ Bezier->Point[2].Pos[0] = V2(20, -50);
+ Bezier->Point[0].Pos[1] = V2(-4, 0);
+ Bezier->Point[1].Pos[1] = V2(-4, 0);
+ Bezier->Point[2].Pos[1] = V2(-4, 0);
+ Bezier->Point[0].Pos[2] = V2(4, 0);
+ Bezier->Point[1].Pos[2] = V2(4, 0);
+ Bezier->Point[2].Pos[2] = V2(4, 0);
+ Bezier->Point[0].Type = interpolation_type_bezier;
+ Bezier->Point[1].Type = interpolation_type_bezier;
+ Bezier->Point[2].Type = interpolation_type_bezier;
+ Property->Keyframe_Count = 3;
+
+ property_channel *Property2 = &Layer->opacity;
+ Property2->Block_Bezier_Index[0] = Memory_Block_AllocateNew(&Memory, F_Bezier);
+ Property2->Block_Bezier_Count = 1;
+
+ block_bezier *Bezier2 = (block_bezier *)Memory_Block_AddressAtIndex(&Memory, F_Bezier, Property2->Block_Bezier_Index[0]);
+ Bezier2->Occupied = 1;
+
+ Bezier2->Point[0].Pos[0] = V2(0, 0);
+ Bezier2->Point[1].Pos[0] = V2(20, 1);
+ Property2->Keyframe_Count = 2;
+
+ /*
+ property_channel *Property3 = &Layer->y;
+ Property3->Block_Bezier_Index[0] = Memory_Block_AllocateNew(&Memory, F_Bezier);
+ Property3->Block_Bezier_Count = 1;
+
+ block_bezier *Bezier3 = (block_bezier *)Memory_Block_AddressAtIndex(&Memory, F_Bezier, Property3->Block_Bezier_Index[0]);
+ Bezier3->Occupied = 1;
+
+ Bezier3->Point[0].Pos[0] = V2(0, -20);
+ Bezier3->Point[1].Pos[0] = V2(10, 300);
+ Bezier3->Point[2].Pos[0] = V2(20, 100);
+ Bezier3->Point[0].Pos[1] = V2(-4, 0);
+ Bezier3->Point[1].Pos[1] = V2(-4, 0);
+ Bezier3->Point[2].Pos[1] = V2(-4, 0);
+ Bezier3->Point[0].Pos[2] = V2(4, 0);
+ Bezier3->Point[1].Pos[2] = V2(4, 0);
+ Bezier3->Point[2].Pos[2] = V2(4, 0);
+ Bezier3->Point[0].Type = interpolation_type_bezier;
+ Bezier3->Point[1].Type = interpolation_type_bezier;
+ Bezier3->Point[2].Type = interpolation_type_bezier;
+ Property3->Keyframe_Count = 3;
+ */
+ }
+ // {
+ // Layer_CreateFromSource(File, State, &Memory, SourceIndex, MainComp->Frame_End);
+ // block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, File->Layer_Count - 1);
+ // Layer->Vertical_Offset = 1;
+ // Layer->Col[0] = 1;
+ // Layer->Col[1] = 0;
+ // Layer->Col[2] = 0;
+ // Layer->Block_Composition_Index = 1;
+ // }
}
- block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, 0);
-
{
uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/b.jpg");
block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, 1);
-
- Layer_CreateFromSource(File, State, &Memory, 1, MainComp->Frame_End);
- Layer_CreateFromSource(File, State, &Memory, SourceIndex, MainComp->Frame_End);
+ // {
+ // Layer_CreateFromSource(File, State, &Memory, SourceIndex, MainComp->Frame_End);
+ // block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, File->Layer_Count - 1);
+ // Layer->Vertical_Offset = 5;
+ // Layer->Col[0] = 0;
+ // Layer->Col[1] = 0;
+ // Layer->Col[2] = 1;
+ // Layer->Block_Composition_Index = 0;
+ // }
}
{
uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/c.jpg");
block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, 2);
-
- Layer_CreateFromSource(File, State, &Memory, SourceIndex, MainComp->Frame_End);
+ // {
+ // Layer_CreateFromSource(File, State, &Memory, SourceIndex, MainComp->Frame_End);
+ // block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, File->Layer_Count - 1);
+ // Layer->Vertical_Offset = 0;
+ // Layer->Col[0] = 0;
+ // Layer->Col[1] = 1;
+ // Layer->Col[2] = 0;
+ // Layer->Block_Composition_Index = 1;
+ // }
+ // {
+ // Layer_CreateFromSource(File, State, &Memory, SourceIndex, MainComp->Frame_End);
+ // block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, File->Layer_Count - 1);
+ // Layer->Vertical_Offset = 4;
+ // Layer->Col[0] = 0;
+ // Layer->Col[1] = 1;
+ // Layer->Col[2] = 1;
+ // Layer->Block_Composition_Index = 1;
+ // }
}
- block_layer *Layer1 = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, 0);
- Layer1->Vertical_Offset = 0;
-
- block_layer *Layer2 = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, 1);
- Layer2->IsPrecomp = true;
- Layer2->Vertical_Offset = 1;
- Layer2->Col[0] = 1;
-
- block_layer *Layer3 = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, 2);
- Layer3->Vertical_Offset = 0;
- Layer3->Col[1] = 1;
- Layer3->Block_Composition_Index = 1;
-
- block_layer *Layer4 = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, 3);
- Layer4->Vertical_Offset = 1;
- Layer4->Col[2] = 1;
- Layer4->Block_Composition_Index = 1;
+ /*
+ {
+ Layer_CreateFromSource(File, State, &Memory, 1, MainComp->Frame_End);
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, File->Layer_Count - 1);
+ Layer->IsPrecomp = true;
+ Layer->Vertical_Offset = 9;
+ Layer->Col[0] = 1;
+ Layer->Col[1] = 1;
+ Layer->Col[2] = 1;
+ Layer->Block_Composition_Index = 0;
+ }
+ {
+ Layer_CreateFromSource(File, State, &Memory, 1, MainComp->Frame_End);
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, File->Layer_Count - 1);
+ Layer->IsPrecomp = true;
+ Layer->Vertical_Offset = 10;
+ Layer->Col[0] = 1;
+ Layer->Col[1] = 1;
+ Layer->Col[2] = 1;
+ Layer->Block_Composition_Index = 0;
+ }
+ */
// History_Undo(&Memory);
// History_Redo(&Memory);
@@ -516,17 +607,14 @@ int main(int argc, char *argv[]) {
while (State->IsRunning)
{
- printf("Call UI\n");
Main_InputTest(File, State, &Memory, &UI, window, textureID);
if (State->UpdateFrame) {
- printf("Call renderer\n");
Main_Renderer(File, State, &Memory, window, textureID, io);
}
Assert(Debug.ScratchState == 0);
- printf("Call render UI\n");
Main_RenderUI(io, clear_color, window);
// TODO(fox): Fix things that rely on this.
diff --git a/main.h b/main.h
index 9ccb19e..cfdb816 100644
--- a/main.h
+++ b/main.h
@@ -39,9 +39,10 @@ enum blend_mode
blend_difference
};
+#define STRING_SIZE (1024 - sizeof(uint8)) // TODO(fox): Paths above STRING_SIZE length aren't handled properly.
struct block_string {
uint8 Occupied;
- char Char[1024 - sizeof(uint8)];
+ char Char[STRING_SIZE];
};
struct bitmap_cache_status
@@ -146,6 +147,25 @@ struct ui
ImVec2 Warp_PositionToSet;
real32 Warp_PositionInitial;
int32 Warp_Direction;
+
+ ImU32 LayerColors[16] = {
+ 0x00050506,
+ 0x00806754,
+ 0x002d3f66,
+ 0x0044546e,
+ 0x00556780,
+ 0x005d7392,
+ 0x007e7b7e,
+ 0x00828282,
+ 0x00434344,
+ 0x00AB8A71,
+ 0x003C5588,
+ 0x005B7193,
+ 0x00728AAB,
+ 0x007C9AC3,
+ 0x00A9A5A8,
+ 0x00c0c0c0
+ };
};
struct pen_state {
@@ -247,6 +267,12 @@ struct property_header
real32 MaxVal;
};
+struct property_info
+{
+ real32 MinVal = FLT_MAX;
+ real32 MaxVal = FLT_MIN;
+};
+
struct property_channel {
char *Name;
uint16 Block_Bezier_Index[MAX_KEYFRAME_BLOCKS];
@@ -265,6 +291,7 @@ struct block_layer {
uint8 Occupied;
bool32 IsPrecomp;
+ bool32 Precomp_Toggled;
uint16 Block_Source_Index; // also used for precomp
uint16 Block_String_Index;
uint16 Block_Composition_Index;
diff --git a/memory.h b/memory.h
index 6e704bf..3148138 100644
--- a/memory.h
+++ b/memory.h
@@ -9,9 +9,8 @@ enum memory_table_list {
F_Layers,
F_Sources,
F_Properties,
- F_Keyframes,
+ F_Bezier,
F_Effects,
- F_Nodes,
F_Strings,
B_ScratchSpace,
diff --git a/my_imgui_widgets.cpp b/my_imgui_widgets.cpp
index 179dff2..9589abd 100644
--- a/my_imgui_widgets.cpp
+++ b/my_imgui_widgets.cpp
@@ -1,4 +1,3 @@
-#include "imgui/imgui.h"
#include "my_imgui_internal_widgets.h"
#include "imgui_ops.h"
@@ -196,85 +195,148 @@ ImGui_TimelineHorizontalIncrementDraw(ui *UI, ImDrawList *draw_list, ImVec2 Time
}
}
+
+
static void
-ImGui_Timeline_DrawLayer(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io, ImDrawList *draw_list, block_layer *Layer, block_composition *MainComp, uint16 i,
- ImVec2 Increment, ImVec2 TimelineAbsolutePos, ImVec2 TimelineMoveSize, ImVec2 TimelineZoomSize,
- ImVec2 TimelineSize, ImVec2 TimelineSizeWithBorder, real32 LayerIncrement,
- sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray)
+ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io, ImDrawList *draw_list, uint16 CompIndex,
+ ImVec2 Increment, ImVec2 TimelineAbsolutePos, ImVec2 TimelineMoveSize, ImVec2 TimelineZoomSize,
+ ImVec2 TimelineSize, ImVec2 TimelineSizeWithBorder, real32 LayerIncrement,
+ sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray)
{
- int32 Frame_Start = Layer->Frame_Start;
- int32 Frame_End = Layer->Frame_End;
- real32 Vertical_Offset = Layer->Vertical_Offset;
- if (Layer->IsSelected)
- Layer_Interact_Evaluate(Memory, State, &Frame_Start, &Frame_End, &Vertical_Offset);
- ImVec2 Layer_LocalPos = ImVec2(Frame_Start, Vertical_Offset);
- ImVec2 Layer_LocalSize = ImVec2(Frame_End - Frame_Start, Layer->Vertical_Height);
-
- ImVec2 Layer_LocalPos_Ratio = (Layer_LocalPos * Increment);
- ImVec2 Layer_LocalSize_Ratio = Layer_LocalSize * Increment;
- ImVec2 Layer_ScreenPos_Min = TimelineAbsolutePos + TimelineMoveSize + (Layer_LocalPos_Ratio * TimelineZoomSize);
- ImVec2 Layer_ScreenPos_Max = TimelineAbsolutePos + TimelineMoveSize + ((Layer_LocalPos_Ratio + Layer_LocalSize_Ratio) * TimelineZoomSize);
- ImVec2 Layer_ScreenSize = Layer_ScreenPos_Max - Layer_ScreenPos_Min;
-
- if (UI->BoxSelect) {
- bool32 Test = 0;
- if (io.MouseClickedPos[0].y < io.MousePos.y)
- Test = (Layer_ScreenPos_Min.y >= io.MouseClickedPos[0].y && Layer_ScreenPos_Min.y <= io.MousePos.y);
- else
- Test = (Layer_ScreenPos_Max.y <= io.MouseClickedPos[0].y && Layer_ScreenPos_Max.y >= io.MousePos.y);
+ block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, CompIndex);
+ sorted_comp_info SortedCompInfo = SortedCompArray[CompIndex];
+ sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, CompIndex);
- if (Test) {
- if (!Layer->IsSelected) {
- Layer->IsSelected = true;
+ ImGui::PushID(CompIndex);
+
+ for (int i = 0; i < SortedCompInfo.LayerCount; i++)
+ {
+ ImGui::PushID(i);
+
+ sorted_layer SortEntry = SortedLayerInfo[i];
+ uint32 Index_Physical = SortEntry.Block_Layer_Index;
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
+
+ int32 Frame_Start = Layer->Frame_Start;
+ int32 Frame_End = Layer->Frame_End;
+ real32 Vertical_Offset = Layer->Vertical_Offset;
+ if (Layer->IsSelected)
+ Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End, &Vertical_Offset);
+ ImVec2 Layer_LocalPos = ImVec2(Frame_Start, Vertical_Offset);
+ ImVec2 Layer_LocalSize = ImVec2(Frame_End - Frame_Start, Layer->Vertical_Height);
+
+ ImVec2 Layer_LocalPos_Ratio = (Layer_LocalPos * Increment);
+ ImVec2 Layer_LocalSize_Ratio = Layer_LocalSize * Increment;
+ ImVec2 Layer_ScreenPos_Min = TimelineAbsolutePos + TimelineMoveSize + (Layer_LocalPos_Ratio * TimelineZoomSize);
+ ImVec2 Layer_ScreenPos_Max = TimelineAbsolutePos + TimelineMoveSize + ((Layer_LocalPos_Ratio + Layer_LocalSize_Ratio) * TimelineZoomSize);
+ ImVec2 Layer_ScreenSize = Layer_ScreenPos_Max - Layer_ScreenPos_Min;
+
+ if (UI->BoxSelect) {
+ bool32 Test = 0;
+ if (io.MouseClickedPos[0].y < io.MousePos.y)
+ Test = (Layer_ScreenPos_Min.y >= io.MouseClickedPos[0].y && Layer_ScreenPos_Min.y <= io.MousePos.y);
+ else
+ Test = (Layer_ScreenPos_Max.y <= io.MouseClickedPos[0].y && Layer_ScreenPos_Max.y >= io.MousePos.y);
+
+ if (Test) {
+ if (!Layer->IsSelected) {
+ Layer->IsSelected = true;
+ }
+ } else if (!io.KeyShift) {
+ Layer->IsSelected = false;
}
- } else if (!io.KeyShift) {
- Layer->IsSelected = false;
}
- }
- draw_list->AddRectFilled(Layer_ScreenPos_Min, Layer_ScreenPos_Max,
- ImColor(Layer->Col[0], Layer->Col[1], Layer->Col[2], 1.0f));
- draw_list->AddRect(Layer_ScreenPos_Min, Layer_ScreenPos_Max, ImColor(1.0f, 1.0f, 1.0f, 0.5f), 2);
+ ImVec2 ResizeSize = ImVec2(Increment.x * 0.45 * TimelineZoomSize.x, Layer_ScreenSize.y);
+ ImVec2 ResizePos[2] = { Layer_ScreenPos_Min, ImVec2(Layer_ScreenPos_Max.x - ResizeSize.x, Layer_ScreenPos_Min.y) };
+ for (int b = 0; b < 2; b++) {
+ ImGui::PushID(b);
+ ImGui::SetCursorScreenPos(ResizePos[b]);
+ ImGui::Button("##layer_resize", ResizeSize);
- if (Layer->IsSelected) {
- draw_list->AddRectFilled(Layer_ScreenPos_Min, Layer_ScreenPos_Max, ImColor(0.25f, 0.25f, 0.25f, 0.5f), 2);
- draw_list->AddRect(Layer_ScreenPos_Min, Layer_ScreenPos_Max, ImColor(1.0f, 1.0f, 1.0f, 0.5f), 2);
- }
+ if (ImGui::IsItemHovered()) {
+ ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);
+ }
+ if (ImGui::IsItemActivated()) {
+ if (!Layer->IsSelected) {
+ if (!io.KeyShift) Layer_DeselectAll(Memory, File->Layer_Count);
+ State->MostRecentlySelectedLayer = i;
+ Layer->IsSelected = true;
+ }
+ }
+ if (ImGui::IsItemActive()) {
+ if (ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) {
+ State->Interact_Active = interact_type_layer_timeadjust;
+ ImVec2 DragDelta = ImGui::GetMouseDragDelta();
+ DragDelta = DragDelta + (ImVec2(UI->Warp_X, UI->Warp_Y) * TimelineSize);
- ImVec2 ResizeSize = ImVec2(Increment.x * 0.45 * TimelineZoomSize.x, Layer_ScreenSize.y);
- ImVec2 ResizePos[2] = { Layer_ScreenPos_Min, ImVec2(Layer_ScreenPos_Max.x - ResizeSize.x, Layer_ScreenPos_Min.y) };
- for (int b = 0; b < 2; b++) {
- ImGui::PushID(b);
- ImGui::SetCursorScreenPos(ResizePos[b]);
- ImGui::Button("##layer_resize", ResizeSize);
+ State->Interact_Offset[0] = (DragDelta.x / TimelineSizeWithBorder.x * UI->TimelinePercentZoomed.x) * Comp->Frame_Count;
+ State->Interact_Offset[1] = b;
+ DebugWatchVar("Offset1", &State->Interact_Offset[0], d_float);
+ }
+ }
+ if (ImGui::IsItemDeactivated()) {
+ if (State->Interact_Active == interact_type_layer_timeadjust) {
+ for (int a = 0; a < File->Layer_Count; a++) {
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, a);
+ if (Layer->IsSelected) {
+ Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Layer->Frame_Start, &Layer->Frame_End, &Layer->Vertical_Offset);
+ }
+ }
+ State->Interact_Active = interact_type_none;
+ State->Interact_Offset[0] = 0;
+ State->Interact_Offset[1] = 0;
+ }
+ }
- if (ImGui::IsItemHovered()) {
- ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);
+ ImGui::PopID();
}
+
+ ImGui::SetCursorScreenPos(Layer_ScreenPos_Min);
+ ImGui::InvisibleButton("##layer_mid", Layer_ScreenSize, ImGuiMouseButton_Left);
+
if (ImGui::IsItemActivated()) {
if (!Layer->IsSelected) {
+ if (!io.KeyShift) Layer_DeselectAll(Memory, File->Layer_Count);
State->MostRecentlySelectedLayer = i;
Layer->IsSelected = true;
}
}
+
if (ImGui::IsItemActive()) {
if (ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) {
- State->Interact_Active = interact_type_layer_timeadjust;
+ if (State->Interact_Active == interact_type_none) {
+ State->Interact_Active = interact_type_layer_move;
+ // TODO(fox): Selected layers inside precomps will have interactions doubled,
+ // so I'm forcing interaction to only be with members of the same precomp.
+ // Could be made more intuitive later.
+ Layer_RecursiveDeselect(Memory, SortedCompArray, SortedLayerArray, Layer->Block_Composition_Index, File->PrincipalCompIndex);
+ }
ImVec2 DragDelta = ImGui::GetMouseDragDelta();
DragDelta = DragDelta + (ImVec2(UI->Warp_X, UI->Warp_Y) * TimelineSize);
- State->Interact_Offset[0] = (DragDelta.x / TimelineSizeWithBorder.x * UI->TimelinePercentZoomed.x) * MainComp->Frame_Count;
- State->Interact_Offset[1] = b;
- DebugWatchVar("Offset1", &State->Interact_Offset[0], d_float);
+ State->Interact_Offset[0] = (DragDelta.x / TimelineSizeWithBorder.x * UI->TimelinePercentZoomed.x) * Comp->Frame_Count;
+ State->Interact_Offset[1] = (DragDelta.y / TimelineSizeWithBorder.y * UI->TimelinePercentZoomed.y) * LayerIncrement;
+
+ /*
+ if (UI->DragDelta_Prev.x != 0) {
+ ImVec2 Offset_Old = (UI->DragDelta_Prev / TimelineSizeWithBorder * UI->TimelinePercentZoomed) * ImVec2(MainComp->Frame_Count, LayerIncrement);
+ if ((int32)State->Interact_Offset[1] != (int32)Offset_Old.y)
+ State->UpdateFrame = true;
+ }
+
+ UI->DragDelta_Prev = DragDelta;
+ */
}
}
+
if (ImGui::IsItemDeactivated()) {
- if (State->Interact_Active == interact_type_layer_timeadjust) {
+ if (State->Interact_Active == interact_type_layer_move) {
for (int a = 0; a < File->Layer_Count; a++) {
block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, a);
if (Layer->IsSelected) {
- Layer_Interact_Evaluate(Memory, State, &Layer->Frame_Start, &Layer->Frame_End, &Layer->Vertical_Offset);
+ Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Layer->Frame_Start, &Layer->Frame_End, &Layer->Vertical_Offset);
}
}
State->Interact_Active = interact_type_none;
@@ -282,80 +344,151 @@ ImGui_Timeline_DrawLayer(project_data *File, project_state *State, memory *Memor
State->Interact_Offset[1] = 0;
}
}
-
ImGui::PopID();
}
- ImGui::SetCursorScreenPos(Layer_ScreenPos_Min);
- ImGui::InvisibleButton("##layer_mid", Layer_ScreenSize, ImGuiMouseButton_Left);
+ // Check if any layers are precomps; we want to test hit detection for them _after_ the layers in front.
+ for (int i = 0; i < SortedCompInfo.LayerCount; i++)
+ {
+ ImGui::PushID(i);
+
+ sorted_layer SortEntry = SortedLayerInfo[i];
+ uint32 Index_Physical = SortEntry.Block_Layer_Index;
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
+
+ int32 Frame_Start = Layer->Frame_Start;
+ int32 Frame_End = Layer->Frame_End;
+ real32 Vertical_Offset = Layer->Vertical_Offset;
+ if (Layer->IsSelected)
+ Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End, &Vertical_Offset);
+ ImVec2 Layer_LocalPos = ImVec2(Frame_Start, Vertical_Offset);
+ ImVec2 Layer_LocalSize = ImVec2(Frame_End - Frame_Start, Layer->Vertical_Height);
+
+ ImVec2 Layer_LocalPos_Ratio = (Layer_LocalPos * Increment);
+ ImVec2 Layer_LocalSize_Ratio = Layer_LocalSize * Increment;
+ ImVec2 Layer_ScreenPos_Min = TimelineAbsolutePos + TimelineMoveSize + (Layer_LocalPos_Ratio * TimelineZoomSize);
+ ImVec2 Layer_ScreenPos_Max = TimelineAbsolutePos + TimelineMoveSize + ((Layer_LocalPos_Ratio + Layer_LocalSize_Ratio) * TimelineZoomSize);
+ ImVec2 Layer_ScreenSize = Layer_ScreenPos_Max - Layer_ScreenPos_Min;
+
+ if (Layer->IsPrecomp && Layer->Precomp_Toggled) {
+
+ sorted_layer *Precomp_SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, Layer->Block_Source_Index);
+ sorted_comp_info Precomp_SortedCompInfo = SortedCompArray[Layer->Block_Source_Index];
+
+ block_layer *Layer_Top = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Precomp_SortedLayerInfo[Precomp_SortedCompInfo.LayerCount - 1].Block_Layer_Index);
+ block_layer *Layer_Bottom = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Precomp_SortedLayerInfo[0].Block_Layer_Index);
+ real32 SmallestY = Layer_Top->Vertical_Offset;
+ real32 LargestY = Layer_Bottom->Vertical_Offset;
+ real32 PrecompHeight = LargestY - SmallestY + 1;
+
+ ImVec2 MinClipPos = ImVec2(Layer_ScreenPos_Min.x, Layer_ScreenPos_Max.y);
+ ImVec2 MaxClipPos = ImVec2(Layer_ScreenPos_Max.x, MinClipPos.y + (PrecompHeight * Increment.y * TimelineZoomSize.y));
+ draw_list->AddRectFilled(MinClipPos, MaxClipPos, ImColor(0.2f, 0.2f, 0.2f, 1.0f));
+
+
+ ImVec2 Layer_LocalPos_Screen = Layer_LocalPos_Ratio * TimelineZoomSize;
+ ImVec2 NestedTimelineAbsolutePos = TimelineAbsolutePos + Layer_LocalPos_Screen - ImVec2(0, SmallestY * Increment.y * TimelineZoomSize.y) + ImVec2(0, Layer_ScreenSize.y);
+
+ ImGui::PushClipRect(MinClipPos, MaxClipPos, true);
+ draw_list->PushClipRect(MinClipPos, MaxClipPos, true);
+ ImGui_Timeline_DrawPrecomp(File, State, Memory, UI, io, draw_list, Layer->Block_Source_Index,
+ Increment, NestedTimelineAbsolutePos, TimelineMoveSize, TimelineZoomSize,
+ TimelineSize, TimelineSizeWithBorder, LayerIncrement,
+ SortedCompArray, SortedLayerArray);
+ draw_list->PopClipRect();
+ ImGui::PopClipRect();
- if (ImGui::IsItemActivated()) {
- if (!Layer->IsSelected) {
- if (!io.KeyShift) Layer_DeselectAll(Memory, File->Layer_Count);
- State->MostRecentlySelectedLayer = i;
- Layer->IsSelected = true;
}
+ ImGui::PopID();
}
- if (ImGui::IsItemActive()) {
- if (ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) {
- State->Interact_Active = interact_type_layer_move;
- ImVec2 DragDelta = ImGui::GetMouseDragDelta();
- DragDelta = DragDelta + (ImVec2(UI->Warp_X, UI->Warp_Y) * TimelineSize);
+ // TODO(fox): Draw calls are executed in reverse order, so we need another iteration to draw layers on top of precomps.
+ // The ImDrawListSplitter API can probably do this without another iteration.
+ for (int i = 0; i < SortedCompInfo.LayerCount; i++)
+ {
+ ImGui::PushID(i);
- State->Interact_Offset[0] = (DragDelta.x / TimelineSizeWithBorder.x * UI->TimelinePercentZoomed.x) * MainComp->Frame_Count;
- State->Interact_Offset[1] = (DragDelta.y / TimelineSizeWithBorder.y * UI->TimelinePercentZoomed.y) * LayerIncrement;
+ sorted_layer SortEntry = SortedLayerInfo[i];
+ uint32 Index_Physical = SortEntry.Block_Layer_Index;
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
- /*
- if (UI->DragDelta_Prev.x != 0) {
- ImVec2 Offset_Old = (UI->DragDelta_Prev / TimelineSizeWithBorder * UI->TimelinePercentZoomed) * ImVec2(MainComp->Frame_Count, LayerIncrement);
- if ((int32)State->Interact_Offset[1] != (int32)Offset_Old.y)
- State->UpdateFrame = true;
- }
+ int32 Frame_Start = Layer->Frame_Start;
+ int32 Frame_End = Layer->Frame_End;
+ real32 Vertical_Offset = Layer->Vertical_Offset;
+ if (Layer->IsSelected)
+ Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End, &Vertical_Offset);
+ ImVec2 Layer_LocalPos = ImVec2(Frame_Start, Vertical_Offset);
+ ImVec2 Layer_LocalSize = ImVec2(Frame_End - Frame_Start, Layer->Vertical_Height);
- UI->DragDelta_Prev = DragDelta;
- */
+ ImVec2 Layer_LocalPos_Ratio = (Layer_LocalPos * Increment);
+ ImVec2 Layer_LocalSize_Ratio = Layer_LocalSize * Increment;
+ ImVec2 Layer_ScreenPos_Min = TimelineAbsolutePos + TimelineMoveSize + (Layer_LocalPos_Ratio * TimelineZoomSize);
+ ImVec2 Layer_ScreenPos_Max = TimelineAbsolutePos + TimelineMoveSize + ((Layer_LocalPos_Ratio + Layer_LocalSize_Ratio) * TimelineZoomSize);
+ ImVec2 Layer_ScreenSize = Layer_ScreenPos_Max - Layer_ScreenPos_Min;
+
+ ImU32 col = IM_COL32(255, 255, 255, 255);
+
+ int NumberOfActiveProperties = 0;
+ for (int h = 0; h < AmountOf(Layer->Property); h++) {
+ property_channel *Property = &Layer->Property[h];
+ if (Property->Keyframe_Count)
+ NumberOfActiveProperties++;
}
- }
- if (ImGui::IsItemDeactivated()) {
- if (State->Interact_Active == interact_type_layer_move) {
- for (int a = 0; a < File->Layer_Count; a++) {
- block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, a);
- if (Layer->IsSelected) {
- Layer_Interact_Evaluate(Memory, State, &Layer->Frame_Start, &Layer->Frame_End, &Layer->Vertical_Offset);
+ for (int h = 0; h < AmountOf(Layer->Property); h++) {
+ property_channel *Property = &Layer->Property[h];
+ ImGui::PushID(Property);
+ if (Property->Keyframe_Count) {
+ property_info PropertyInfo = Property_GetInfo(Memory, Property);
+ real32 Y_Increment = 1 / (PropertyInfo.MaxVal - PropertyInfo.MinVal);
+ bezier_point *PointAddress[2] = {};
+ ImVec2 Keyframe_ScreenPos[2] = {};
+ ImVec2 Keyframe_ScreenPos_L[2] = {};
+ ImVec2 Keyframe_ScreenPos_R[2] = {};
+ for (int k = 0; k < (Property->Keyframe_Count + 1); k++) {
+ int Idx = k % 2;
+ PointAddress[Idx] = Bezier_Lookup(Memory, Property, k);
+ bezier_point *Point = PointAddress[Idx];
+
+ ImVec2 Keyframe_LocalPos[3] = { V2(Point->Pos[0]), V2(Point->Pos[0] + Point->Pos[1]), V2(Point->Pos[0] + Point->Pos[2]) };
+ ImVec2 Keyframe_LocalPos_Ratio[3];
+ for (int b = 0; b < 3; b++) {
+ Keyframe_LocalPos_Ratio[b] = (Keyframe_LocalPos[b] - ImVec2(0, PropertyInfo.MinVal)) * ImVec2(Increment.x, Y_Increment);
+ }
+
+ Keyframe_ScreenPos[Idx] = Layer_ScreenPos_Min + ((Keyframe_LocalPos_Ratio[0] - ImVec2(0, 0.5)) * TimelineZoomSize) + ImVec2(0, Layer_ScreenSize.y/2);
+ Keyframe_ScreenPos_L[Idx] = Layer_ScreenPos_Min + ((Keyframe_LocalPos_Ratio[1] - ImVec2(0, 0.5)) * TimelineZoomSize) + ImVec2(0, Layer_ScreenSize.y/2);
+ Keyframe_ScreenPos_R[Idx] = Layer_ScreenPos_Min + ((Keyframe_LocalPos_Ratio[2] - ImVec2(0, 0.5)) * TimelineZoomSize) + ImVec2(0, Layer_ScreenSize.y/2);
+
+ draw_list->AddCircle(Keyframe_ScreenPos[Idx], 2, col, 16, 1);
+ if (k != 0 && k != Property->Keyframe_Count) {
+ if (PointAddress[0]->Type == interpolation_type_bezier && PointAddress[1]->Type == interpolation_type_bezier) {
+ draw_list->AddBezierCubic(Keyframe_ScreenPos[!Idx], Keyframe_ScreenPos_R[!Idx],
+ Keyframe_ScreenPos_L[Idx], Keyframe_ScreenPos[Idx], col, 1.0f, 0);
+ } else {
+ draw_list->AddLine(Keyframe_ScreenPos[0], Keyframe_ScreenPos[1], col, 1.0f);
+ }
+ }
}
}
- State->Interact_Active = interact_type_none;
- State->Interact_Offset[0] = 0;
- State->Interact_Offset[1] = 0;
+ ImGui::PopID();
}
- }
- if (Layer->IsPrecomp) {
- ImVec2 MinClipPos = ImVec2(Layer_ScreenPos_Min.x, Layer_ScreenPos_Max.y);
- ImVec2 MaxClipPos = ImVec2(Layer_ScreenPos_Max.x, MinClipPos.y + TimelineZoomSize.y);
- draw_list->AddRectFilled(MinClipPos, MaxClipPos, ImColor(0.2f, 0.2f, 0.2f, 1.0f));
+ draw_list->AddRectFilled(Layer_ScreenPos_Min, Layer_ScreenPos_Max,
+ ImColor(Layer->Col[0], Layer->Col[1], Layer->Col[2], 1.0f));
+ draw_list->AddRect(Layer_ScreenPos_Min, Layer_ScreenPos_Max, ImColor(1.0f, 1.0f, 1.0f, 0.5f), 2);
+ // block_string *String = (block_string *)Memory_Block_AddressAtIndex(Memory, F_Strings, Layer->Block_String_Index);
+ // draw_list->AddText(Layer_ScreenPos_Min, 0xFFFFFFFF, String->Char);
- sorted_comp_info SortedCompInfo = SortedCompArray[Layer->Block_Source_Index];
- sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, Layer->Block_Source_Index);
+ if (Layer->IsSelected) {
+ draw_list->AddRectFilled(Layer_ScreenPos_Min, Layer_ScreenPos_Max, ImColor(0.25f, 0.25f, 0.25f, 0.5f), 2);
+ draw_list->AddRect(Layer_ScreenPos_Min, Layer_ScreenPos_Max, ImColor(1.0f, 1.0f, 1.0f, 0.5f), 2);
+ }
- for (int a = 0; a < SortedCompInfo.LayerCount; a++)
- {
- ImGui::PushID(a);
- sorted_layer SortEntry = SortedLayerInfo[a];
- uint32 Index_Physical = SortEntry.Block_Layer_Index;
- block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
- ImVec2 Layer_LocalPos_Screen = Layer_LocalPos_Ratio * TimelineZoomSize;
- ImVec2 NestedTimelineAbsolutePos = TimelineAbsolutePos + Layer_LocalPos_Screen + ImVec2(0, Layer_ScreenSize.y);
- ImGui_Timeline_DrawLayer(File, State, Memory, UI, io, draw_list, Layer, MainComp, a,
- Increment, NestedTimelineAbsolutePos, TimelineMoveSize, TimelineZoomSize,
- TimelineSize, TimelineSizeWithBorder, LayerIncrement,
- SortedCompArray, SortedLayerArray);
- ImGui::PopID();
- }
+ ImGui::PopID();
}
+ ImGui::PopID();
}
static void
@@ -432,23 +565,10 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
sorted_layer *SortedLayerArray = (sorted_layer *)((uint8 *)SortedArray + (sizeof(sorted_comp_info) * File->Comp_Count));
Layer_SortAll(Memory, SortedLayerArray, SortedCompArray, File->Layer_Count, File->Comp_Count);
- sorted_comp_info SortedCompInfo = SortedCompArray[File->PrincipalCompIndex];
- sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, File->PrincipalCompIndex);
-
- for (int i = 0; i < SortedCompInfo.LayerCount; i++)
- {
- ImGui::PushID(i);
- sorted_layer SortEntry = SortedLayerInfo[i];
- uint32 Index_Physical = SortEntry.Block_Layer_Index;
- block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
-
- ImGui_Timeline_DrawLayer(File, State, Memory, UI, io, draw_list, Layer, MainComp, i,
- Increment, TimelineAbsolutePos, TimelineMoveSize, TimelineZoomSize,
- TimelineSize, TimelineSizeWithBorder, LayerIncrement,
- SortedCompArray, SortedLayerArray);
-
- ImGui::PopID();
- }
+ ImGui_Timeline_DrawPrecomp(File, State, Memory, UI, io, draw_list, File->PrincipalCompIndex,
+ Increment, TimelineAbsolutePos, TimelineMoveSize, TimelineZoomSize,
+ TimelineSize, TimelineSizeWithBorder, LayerIncrement,
+ SortedCompArray, SortedLayerArray);
Memory_PopScratch(Memory, SortSize);
@@ -619,6 +739,11 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
IM_COL32(0, 0, 200, 50));
}
+ if (!ImGui::IsMouseDown(ImGuiMouseButton_Left)) {
+ UI->Warp_X = 0;
+ UI->Warp_Y = 0;
+ }
+
if (IsItemDeactivated) {
UI->BoxSelect = false;
}
@@ -637,14 +762,29 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
}
static void
-ImGui_ProcessInputs(project_state *State, ImGuiIO io)
+ImGui_ProcessInputs(project_data *File, project_state *State, memory *Memory, ImGuiIO io)
{
- if (io.KeysData[ImGuiKey_Q].Down) {
+ if (ImGui::IsKeyPressed(ImGuiKey_Q)) {
State->IsRunning = false;
}
- if (io.KeysData[ImGuiKey_A].Down) {
+ if (ImGui::IsKeyPressed(ImGuiKey_A)) {
State->UpdateFrame = true;
}
+ if (ImGui::IsKeyPressed(ImGuiKey_T)) {
+ for (int a = 0; a < File->Layer_Count; a++) {
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, a);
+ if (Layer->IsSelected && Layer->IsPrecomp) {
+ Layer->Precomp_Toggled ^= 1;
+ }
+ }
+ }
+#if DEBUG
+ if (ImGui::IsKeyPressed(ImGuiKey_W))
+ {
+ Debug.ToggleWindow ^= 1;
+ }
+#endif
+
}
#if 0
@@ -2193,13 +2333,6 @@ ImGui_ProcessInputs(project_data *File, project_state *State, comp_buffer *CompB
}
}
-#if DEBUG
- if (ImGui::IsKeyPressed(ImGuiKey_W))
- {
- Debug.ToggleWindow ^= 1;
- }
-#endif
-
if (State->IsInteracting) {
ImVec2 MouseIncrement = io.MouseDelta * (ImVec2(CompBuffer->Width, CompBuffer->Height) / UI->CompZoom);
project_layer *Layer = File->Layer[State->MostRecentlySelectedLayer];
diff --git a/my_math.h b/my_math.h
index df5f8a6..af6beb1 100644
--- a/my_math.h
+++ b/my_math.h
@@ -66,6 +66,16 @@ inline v2 V2(ImVec2 A)
return(Result);
}
+inline ImVec2 V2(v2 A)
+{
+ struct ImVec2 Result;
+
+ Result.x = A.x;
+ Result.y = A.y;
+
+ return(Result);
+}
+
inline v2i V2i(int32 x, int32 y)
{
v2i Result;