summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFox Caminiti <fox@foxcam.net>2023-01-27 22:49:03 -0500
committerFox Caminiti <fox@foxcam.net>2023-01-27 22:49:03 -0500
commitc40fb7c82be088db4166e92f131865f72b975f56 (patch)
tree309e03fe6e23c87f3d70928abfef26a355a033a3
parentd6e916319a050070c53eb283470a3fd4833392a0 (diff)
selection improvements
-rw-r--r--src/createcalls.cpp9
-rw-r--r--src/imgui_ui.cpp9
-rw-r--r--src/imgui_ui_timeline.cpp16
-rw-r--r--src/imgui_ui_viewport.cpp124
-rw-r--r--src/include/all.h4
-rw-r--r--src/include/functions.h2
-rw-r--r--src/include/main.h1
7 files changed, 123 insertions, 42 deletions
diff --git a/src/createcalls.cpp b/src/createcalls.cpp
index adb6ff5..fd60b4e 100644
--- a/src/createcalls.cpp
+++ b/src/createcalls.cpp
@@ -264,7 +264,7 @@ Effect_Add(project_data *File, project_state *State, memory *Memory, uint32 Effe
block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
if (Layer->IsSelected) {
Layer->Block_Effect_Index[Layer->Block_Effect_Count] = Effect_Init(State, Memory, EffectEntryIndex, Layer->Block_Effect_Count);
- History_Action_Swap(Memory, F_File, sizeof(Layer->Block_Effect_Count), &Layer->Block_Effect_Count);
+ History_Action_Swap(Memory, F_Layers, sizeof(Layer->Block_Effect_Count), &Layer->Block_Effect_Count);
Layer->Block_Effect_Count++;
Selected++;
}
@@ -675,6 +675,9 @@ Project_Layer_Duplicate(project_data *File, project_state *State, memory *Memory
block_layer *NewLayer = (block_layer *)Memory_Block_AllocateAddress(Memory, F_Layers);
History_Action_Block_Swap(Memory, F_Layers, NewLayer);
*NewLayer = *Layer;
+
+ Assert(Layer->Block_Effect_Count == 0);
+
NewLayer->IsSelected = true;
NewLayer->Vertical_Offset--;
@@ -832,7 +835,7 @@ void Source_UICreateButton(project_data *File, project_state *State, memory *Mem
CommitAction = 1;
}
if (Source->Type == source_type_principal_temp) {
- History_Action_Swap(Memory, F_File, sizeof(Source->Type), &Source->Type);
+ History_Action_Swap(Memory, F_Sources, sizeof(Source->Type), &Source->Type);
Source->Type = source_type_principal;
}
block_layer *Layer = Layer_Init(File, Memory);
@@ -932,7 +935,7 @@ void Precomp_UICreateButton(project_data *File, project_state *State, memory *Me
uint32 Index_Physical = SortEntry.Block_Layer_Index;
block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
if (Layer->IsSelected) {
- History_Action_Swap(Memory, F_File, sizeof(Layer->Block_Composition_Index), &Layer->Block_Composition_Index);
+ History_Action_Swap(Memory, F_Layers, sizeof(Layer->Block_Composition_Index), &Layer->Block_Composition_Index);
Layer->Block_Composition_Index = File->Comp_Count - 1;
}
}
diff --git a/src/imgui_ui.cpp b/src/imgui_ui.cpp
index 7c8adf9..871c69d 100644
--- a/src/imgui_ui.cpp
+++ b/src/imgui_ui.cpp
@@ -192,6 +192,14 @@ ImGui_Key_GetUIInfo(key_entry KeyEntry, real32 KeySize, ImVec2 *Offset_ScreenPos
*KeyScreenSize = (KeyEntry.WidthRatio > 0.0f) ? ImVec2(KeySize * KeyEntry.WidthRatio, KeySize) : ImVec2(KeySize, KeySize * -KeyEntry.WidthRatio);
}
+inline void
+ImGui_DrawCenteredRect(ImDrawList *draw_list, ImVec2 Point, real32 Width, uint32 col)
+{
+ ImVec2 MinPos = Point - ImVec2(Width/2, Width/2);
+ ImVec2 MaxPos = Point + ImVec2(Width/2, Width/2);
+ draw_list->AddRectFilled(MinPos, MaxPos, col);
+}
+
static void
ImGui_KeybindUI(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io)
{
@@ -433,6 +441,7 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me
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);
} else {
State->Tool = tool_pen;
diff --git a/src/imgui_ui_timeline.cpp b/src/imgui_ui_timeline.cpp
index a85d58e..29b2835 100644
--- a/src/imgui_ui_timeline.cpp
+++ b/src/imgui_ui_timeline.cpp
@@ -466,8 +466,10 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
#else
sprintf(buf, "%s", String->Char);
#endif
- if (UI->TimelinePercentZoomed.y <= 1.0f)
- draw_list->AddText(Layer_ScreenPos_Min, 0xFFFFFFFF, buf);
+ if (UI->TimelinePercentZoomed.y <= 1.0f) {
+ real32 TextX = (Layer_ScreenPos_Min.x > TimelineAbsolutePos.x) ? Layer_ScreenPos_Min.x : TimelineAbsolutePos.x;
+ draw_list->AddText(ImVec2(TextX, Layer_ScreenPos_Min.y), 0xFFFFFFFF, buf);
+ }
if (Layer->IsSelected == 1) {
draw_list->AddRectFilled(Layer_ScreenPos_Min, Layer_ScreenPos_Max, ImColor(0.25f, 0.25f, 0.25f, 0.5f), 2);
@@ -541,8 +543,8 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
if (Layer->IsSelected) {
// NOTE(fox): Some data on the tree could be saved here.
- History_Action_Swap(Memory, F_File, sizeof(Layer->Frame_Start), &Layer->Frame_Start);
- History_Action_Swap(Memory, F_File, sizeof(Layer->Frame_End), &Layer->Frame_End);
+ History_Action_Swap(Memory, F_Layers, sizeof(Layer->Frame_Start), &Layer->Frame_Start);
+ History_Action_Swap(Memory, F_Layers, sizeof(Layer->Frame_End), &Layer->Frame_End);
Interact_Evaluate_Layer(Memory, State, Index_Physical, SortedCompStart, SortedLayerStart, &Layer->Frame_Start, &Layer->Frame_End, &Layer->Frame_Offset);
}
}
@@ -580,7 +582,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
History_Entry_Commit(Memory, "Toggle visibility");
Commit = true;
}
- History_Action_Swap(Memory, F_File, sizeof(Layer->IsVisible), &Layer->IsVisible);
+ History_Action_Swap(Memory, F_Layers, sizeof(Layer->IsVisible), &Layer->IsVisible);
Layer->IsVisible ^= 1;
}
}
@@ -681,10 +683,10 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
uint32 Index_Physical = SortEntry.Block_Layer_Index;
block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
// NOTE(fox): Some data on the tree could be saved here.
- History_Action_Swap(Memory, F_File, sizeof(Layer->Vertical_Offset), &Layer->Vertical_Offset);
+ History_Action_Swap(Memory, F_Layers, sizeof(Layer->Vertical_Offset), &Layer->Vertical_Offset);
Layer->Vertical_Offset = SortEntry.SortedOffset;
if (Layer->IsSelected) {
- History_Action_Swap(Memory, F_File, sizeof(Layer->Frame_Offset), &Layer->Frame_Offset);
+ History_Action_Swap(Memory, F_Layers, sizeof(Layer->Frame_Offset), &Layer->Frame_Offset);
Interact_Evaluate_Layer(Memory, State, Index_Physical, SortedCompStart, SortedLayerStart, &Layer->Frame_Start, &Layer->Frame_End, &Layer->Frame_Offset);
}
}
diff --git a/src/imgui_ui_viewport.cpp b/src/imgui_ui_viewport.cpp
index c846c7e..749999d 100644
--- a/src/imgui_ui_viewport.cpp
+++ b/src/imgui_ui_viewport.cpp
@@ -3,7 +3,6 @@
#include "main.h"
#endif
-
static void
ImGui_Viewport_Toolbar(project_state *State, ImDrawList *draw_list)
{
@@ -133,6 +132,8 @@ ImGui_Viewport_ShapeUI(project_state *State, memory *Memory, ui *UI, ImGuiIO &io
if (IsItemDeactivated) {
if (Layer == NULL && a == 0 && i == 0 && Shape->IsClosed == false) {
History_Entry_Commit(Memory, "Close shape");
+ Assert(0);
+ // which one??
History_Action_Swap(Memory, F_File, sizeof(Shape->IsClosed), &Shape->IsClosed);
Shape->IsClosed = true;
History_Entry_End(Memory);
@@ -261,7 +262,7 @@ T_FindBestFit(int PointCount, v2 *PointData, v2 *Center, v2 *NewCenter, v2 *Best
*BestMin = Min;
*BestMax = Max;
*BestRadians = 0;
- // real32 Angles[4] = { 15, 30, 45, 60 };
+ // TODO(fox): Make more efficient and more precise.
for (real32 i = 0; i < 90; i+= 1) {
v2 NewMin = {}, NewMax = {};
real32 NewArea = T_AreaAtAngle(PointCount, PointData, *Center, i, &NewMin, &NewMax);
@@ -294,7 +295,8 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me
real32 Scale = 1;
if (Interact->Min.x == 0.0f) {
- T_FindBestFit(*PointCount, PointData, &Interact->OGCenter, &Interact->NewCenter, &Interact->Min, &Interact->Max, &Interact->RadianOffset);
+ if (*PointCount > 0)
+ T_FindBestFit(*PointCount, PointData, &Interact->OGCenter, &Interact->NewCenter, &Interact->Min, &Interact->Max, &Interact->RadianOffset);
// Interact->RadianOffset +=
Interact->Scale = 1.0f;
}
@@ -394,8 +396,8 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me
real32 U = LayerPoint.x / BoxLength.x;
real32 V = LayerPoint.y / BoxLength.y;
- DebugWatchVar("U", &U, d_float);
- DebugWatchVar("V", &V, d_float);
+ // DebugWatchVar("U", &U, d_float);
+ // DebugWatchVar("V", &V, d_float);
ImVec2 ScaleHandleSize(50, 50);
@@ -407,9 +409,18 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me
ImGui::PushID(i);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::ColorConvertFloat4ToU32(ImVec4(0.6f, 0.0f, 0.3f, 1.0f)));
- ImGui::Button("##ScaleMids", ScaleHandleSize);
+ ImGui::InvisibleButton("##ScaleMids", ScaleHandleSize);
ImGui::PopStyleColor();
+ ImGui_DrawCenteredRect(draw_list, Mid_P[i], 12, IM_COL32(20, 20, 20, 255));
+ ImGui_DrawCenteredRect(draw_list, Mid_P[i], 10, IM_COL32(20, 20, 220, 255));
+ ImGui_DrawCenteredRect(draw_list, Mid_P[i], 6, IM_COL32(255, 255, 225, 50));
+
+
+ if (ImGui::GetMouseCursor() != ImGuiMouseCursor_None && ImGui::IsItemHovered() && !OtherActions) {
+ ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeNS);
+ }
+
if (ImGui::IsItemActivated() && !OtherActions) {
State->Interact_Active = interact_type_viewport_transform_gizmo;
State->InteractTransformMode = 1;
@@ -420,36 +431,56 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me
uint32 side = i;
v2 Dir = {};
if (i == 0) {
- Dir = V2(-1, 1);
+ Dir = V2(1, -1);
} else if (i == 1) {
- Dir = V2(1, 1);
+ Dir = V2(-1, -1);
} else if (i == 2) {
- Dir = V2(1, -1);
+ Dir = V2(-1, 0);
} else if (i == 3) {
- Dir = V2(-1, -1);
+ Dir = V2(1, 0);
} else {
Assert(0);
}
+ // InteractMin + V2(BoxLength.x * 0.5, 0), InteractMin + V2(0, BoxLength.y * 0.5),
+ // InteractMax - V2(BoxLength.x * 0.5, 0), InteractMax - V2(0, BoxLength.y * 0.5) };
+
+
ImVec2 LengthVec = (io.MousePos - io.MouseClickedPos[0]) / CompScale;
real32 NegRad = -Rad;
v2 UnrotatedLengthVec = {};
{
v2 XAxis = (LengthVec.x * 1.0f)*V2(cos(NegRad), sin(NegRad));
v2 YAxis = (LengthVec.y * -1.0f)*V2(sin(NegRad), -cos(NegRad));
- v2 UnrotatedLengthVec = XAxis + YAxis;
+ UnrotatedLengthVec = XAxis + YAxis;
}
real32 Length = UnrotatedLengthVec.x * Dir.x;
- DebugWatchVar("Len", &Length, d_float);
real32 BoxAxis = BoxLength.x;
Interact->Scale = 1.0f + Length / BoxAxis;
v2 MovePos = V2((Length / 2), -(Length / 2) * (BoxLength.y / BoxLength.x));
v2 XAxis = (MovePos.x * Dir.x)*V2(cos(Rad), sin(Rad));
v2 YAxis = (MovePos.y * Dir.y)*V2(sin(Rad), -cos(Rad));
v2 Pos = XAxis + YAxis;
- Interact->Position.x = Pos.x;
- Interact->Position.y = Pos.y;
+
+ Interact->Position.x = Pos.x;
+ Interact->Position.y = Pos.y;
+#if 0
+ if (i == 0) {
+ Interact->Position.x = Pos.x;
+ Interact->Position.y = Pos.y;
+ } else if (i == 1) {
+ Interact->Position.x = Pos.x;
+ Interact->Position.y = Pos.y;
+ } else if (i == 2) {
+ Interact->Position.x = Pos.x;
+ Interact->Position.y = Pos.y;
+ } else if (i == 3) {
+ Interact->Position.x = Pos.x;
+ Interact->Position.y = Pos.y;
+ }
+#endif
+
}
ImGui::PopID();
@@ -459,7 +490,7 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me
// Scale if cursor is on button within the UV, rotate if outside UV, and position if a non-button is dragged.
if (U >= 0.0f && U <= 1.0f && V >= 0.0f && V <= 1.0f)
{
- ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::ColorConvertFloat4ToU32(ImVec4(0.6f, 0.0f, 0.3f, 1.0f)));
+ // ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::ColorConvertFloat4ToU32(ImVec4(0.6f, 0.0f, 0.3f, 1.0f)));
InBounds = true;
}
@@ -467,7 +498,19 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me
for (int i = 0; i < 4; i++) {
ImGui::SetCursorScreenPos(P[i] - ScaleHandleSize/2);
ImGui::PushID(i);
- ImGui::Button("##ScaleRotateCorners", ScaleHandleSize);
+ ImGui::InvisibleButton("##ScaleRotateCorners", ScaleHandleSize);
+
+ ImGui_DrawCenteredRect(draw_list, P[i], 12, IM_COL32(80, 80, 80, 255));
+ ImGui_DrawCenteredRect(draw_list, P[i], 10, IM_COL32(20, 20, 220, 255));
+ ImGui_DrawCenteredRect(draw_list, P[i], 6, IM_COL32(255, 255, 225, 50));
+
+ if (ImGui::GetMouseCursor() != ImGuiMouseCursor_None && ImGui::IsItemHovered() && !OtherActions) {
+ if (InBounds) {
+ ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeNESW);
+ } else {
+ ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeAll);
+ }
+ }
if (ImGui::IsItemActivated() && !OtherActions) {
if (InBounds)
@@ -545,6 +588,10 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me
MouseRadians = 0.0f;
Interact->Radians = Direction * MouseRadians;
+ if (io.KeyShift) {
+ real32 Angle = (Interact->Radians / (PI / 180));
+ Interact->Radians = (int)(Angle / 15.0f) * 15.0f * (PI / 180);
+ }
}
ImGui::PopID();
}
@@ -553,8 +600,11 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me
v2 MouseLocalUV = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, io.MousePos);
bool32 LayerHovered = Layer_TestForPoint(Memory, State, UI, SortedCompArray, SortedLayerArray, File->PrincipalCompIndex, MouseLocalUV);
if (LayerHovered) {
+ if (ImGui::GetMouseCursor() == ImGuiMouseCursor_None) {
+ ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
+ }
ImGui::SetCursorScreenPos(io.MousePos - ScaleHandleSize/2);
- ImGui::Button("##mover", ScaleHandleSize);
+ ImGui::InvisibleButton("##mover", ScaleHandleSize);
if (!State->InteractTransformMode && ImGui::IsItemActivated() && !OtherActions) {
State->Interact_Active = interact_type_viewport_transform_gizmo;
State->InteractTransformMode = 3;
@@ -598,7 +648,7 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me
}
if (InBounds == true) {
- ImGui::PopStyleColor();
+ // ImGui::PopStyleColor();
}
}
@@ -1159,7 +1209,7 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
BoxMin.y = (MousePos.y < ClickedPos.y) ? MousePos.y : ClickedPos.y;
BoxMax.x = (MousePos.x > ClickedPos.x) ? MousePos.x : ClickedPos.x;
BoxMax.y = (MousePos.y > ClickedPos.y) ? MousePos.y : ClickedPos.y;
- if (BoxMax.x - BoxMin.x > 2.0f && BoxMax.y - BoxMin.y > 2.0f) {
+ if (BoxMax.x - BoxMin.x > 0.1f && BoxMax.y - BoxMin.y > 0.1f) {
Assert(BoxMax.x > BoxMin.x &&
BoxMax.y > BoxMin.y)
BoxMax.y = (MousePos.y > ClickedPos.y) ? MousePos.y : ClickedPos.y;
@@ -1167,15 +1217,16 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
if (State->Tool == tool_default && State->Interact_Active == interact_type_none) {
int32 Selection = Layer_TestSelection(Memory, State, UI, SortedCompArray, SortedLayerArray, File->PrincipalCompIndex);
if (!State->InteractTransformMode && Selection != -1) {
+ Layer_DeselectAll(File, State, Memory);
Layer_Select(Memory, State, Selection);
State->Interact_Active = interact_type_viewport_transform_gizmo;
+ State->Interact_OutOfDrag = true;
State->InteractTransformMode = 3;
} else {
State->Interact_Active = interact_type_viewport_selection;
}
}
if (State->Interact_Active == interact_type_viewport_selection) {
-
Layer_DeselectAll(File, State, Memory);
v2 MinPos_Comp = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, BoxMin) * V2(MainComp->Width, MainComp->Height);
v2 MaxPos_Comp = ImGui_ScreenPointToCompUV(ViewportMax, UI->CompPos, UI->CompZoom, BoxMax) * V2(MainComp->Width, MainComp->Height);
@@ -1191,18 +1242,27 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
}
}
- if (((io.KeyAlt && IsActivated && State->MostRecentlySelectedLayer == -1) ||
- (IsHovered && IsDeactivated && !io.KeyCtrl && !io.KeyAlt)) &&
- !ImGui::IsMouseDown(ImGuiMouseButton_Right) && !ImGui::IsKeyDown(ImGuiKey_Z))
- {
- // Layer selection
- if (State->Tool == tool_default && State->Interact_Active == interact_type_none) {
- int32 Selection = Layer_TestSelection(Memory, State, UI, SortedCompArray, SortedLayerArray, File->PrincipalCompIndex);
- if (!io.KeyShift && State->Interact_Active == interact_type_none)
- Layer_DeselectAll(File, State, Memory);
- if (Selection != -1)
- Layer_Select(Memory, State, Selection);
- }
+ bool32 Delta = (io.MouseDelta.x || io.MouseDelta.y);
+ if (IsActivated || IsDeactivated) {
+ if (((io.KeyAlt && IsActivated && State->MostRecentlySelectedLayer == -1) ||
+ (IsHovered && IsDeactivated && !Delta && !io.KeyCtrl && !io.KeyAlt)) &&
+ !ImGui::IsMouseDown(ImGuiMouseButton_Right) && !ImGui::IsKeyDown(ImGuiKey_Z))
+ {
+ if (State->Interact_OutOfDrag) {
+ State->Interact_OutOfDrag = 0;
+ } else {
+ // Layer selection
+ int32 Selection = Layer_TestSelection(Memory, State, UI, SortedCompArray, SortedLayerArray, File->PrincipalCompIndex);
+ if (State->Tool == tool_default && State->Interact_Active == interact_type_none) {
+ if (!io.KeyShift && State->Interact_Active == interact_type_none) {
+ Layer_DeselectAll(File, State, Memory);
+ State->Interact_Transform = {};
+ }
+ if (Selection != -1)
+ Layer_Select(Memory, State, Selection);
+ }
+ }
+ }
}
if (IsDeactivated && State->Interact_Active == interact_type_viewport_selection) {
diff --git a/src/include/all.h b/src/include/all.h
index e2a2a2f..08a96e6 100644
--- a/src/include/all.h
+++ b/src/include/all.h
@@ -507,6 +507,10 @@ Transform_Recurse(project_state *State, memory *Memory, block_composition *MainC
sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray,
real32 *MinX, real32 *MinY, real32 *MaxX, real32 *MaxY);
+
+inline void
+ImGui_DrawCenteredRect(ImDrawList *draw_list, ImVec2 Point, real32 Width, uint32 col);
+
static bool32
Layer_TestForPoint(memory *Memory, project_state *State, ui *UI, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 PrincipalIndex, v2 CompUV);
diff --git a/src/include/functions.h b/src/include/functions.h
index 4ded552..4c4ea2d 100644
--- a/src/include/functions.h
+++ b/src/include/functions.h
@@ -44,6 +44,8 @@ static layer_transforms Transform_Inverse(layer_transforms T);
static v2 T_CompPosToLayerPos(layer_transforms T, uint32 FileWidth, uint32 FileHeight, uint32 SourceWidth, uint32 SourceHeight, real32 X, real32 Y);
+inline void
+ImGui_DrawCenteredRect(ImDrawList *draw_list, ImVec2 Point, real32 Width, uint32 col)
static void ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io, sorted_file Sorted);
static void ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, sorted_property_array *SortedPropertyStart, uint16 *SortedKeyframeArray);
diff --git a/src/include/main.h b/src/include/main.h
index 38e9105..e1d1787 100644
--- a/src/include/main.h
+++ b/src/include/main.h
@@ -490,6 +490,7 @@ struct project_state
interact_transform Interact_Transform;
interact_type Interact_Active;
int32 Interact_Modifier;
+ bool32 Interact_OutOfDrag; // TODO(fox): replace this
real32 Interact_Offset[12];
real32 Interact_Dup_Previous[2];
void *Interact_Address;