summaryrefslogtreecommitdiff
path: root/my_imgui_widgets.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'my_imgui_widgets.cpp')
-rw-r--r--my_imgui_widgets.cpp403
1 files changed, 362 insertions, 41 deletions
diff --git a/my_imgui_widgets.cpp b/my_imgui_widgets.cpp
index dbadd11..36bc79e 100644
--- a/my_imgui_widgets.cpp
+++ b/my_imgui_widgets.cpp
@@ -36,6 +36,248 @@ ImGui_PropertyInteract_Slider(project_state *State, memory *Memory, property_cha
}
static void
+ImGui_RGBAModeSwitch(project_state *State, memory *Memory, ImGuiIO io, uint32 *Channel)
+{
+ char *Names[5] = {"All", "R", "G", "B", "A" };
+ if (ImGui::BeginListBox("RGB")) {
+ for (int i = 0; i < 5; i++) {
+ if (ImGui::Selectable(Names[i], (*Channel == i))) {
+ *Channel = i;
+ }
+ }
+ ImGui::EndListBox();
+ }
+}
+
+static void
+ImGui_CurvesUI(project_state *State, memory *Memory, ImGuiIO io, block_effect *Effect, property_channel *PropertyStart, uint16 *SortedPointStart)
+{
+
+ real32 Padding = ImGui::GetFontSize()*6;
+ ImVec2 ViewportMin = ImGui::GetCursorScreenPos() + Padding/6;
+ ImVec2 ViewportScale = ImGui::GetContentRegionAvail();
+ ViewportScale.y = ViewportScale.x = ViewportScale.x - Padding; // square seems nice
+ ImVec2 ViewportMax = ViewportMin + ViewportScale;
+
+ ImDrawList* draw_list = ImGui::GetWindowDrawList();
+ draw_list->AddRectFilled(ViewportMin, ViewportMax, IM_COL32(50, 50, 50, 255));
+ draw_list->AddRect(ViewportMin, ViewportMax, IM_COL32(255, 255, 255, 255));
+
+ real32 PointSize = 40;
+
+ ImU32 col = ImGui::GetColorU32(ImGuiCol_Text);
+ ImU32 col_light = ImGui::GetColorU32(ImGuiCol_TextDisabled);
+
+ ImVec2 Point_ScreenPos[4];
+
+ // ocd?
+ draw_list->PushClipRect(ViewportMin + 2, ViewportMax - 2, true);
+
+ for (real32 i = 0.25; i < 1.0; i += 0.25) {
+ ImVec2 Horizontal = ViewportMin + ViewportScale * ImVec2(0, i);
+ ImVec2 Vertical = ViewportMin + ViewportScale * ImVec2(i, 0);
+ draw_list->AddLine(Horizontal, Horizontal + ImVec2(ViewportScale.x, 0), col_light, 1.0f);
+ draw_list->AddLine(Vertical, Vertical + ImVec2(0, ViewportScale.y), col_light, 1.0f);
+ }
+
+ draw_list->PopClipRect();
+
+
+#if 0
+ real32 LUT[5][256] = {};
+
+ for (int a = 0; a < 5; a++) {
+
+ int Num = (a == 0) ? *NumberOfPoints_Main : NumberOfPoints_Col->E[a-1];
+ v2 *CurvePoint = (v2 *)(FileEffectAddress + (a * (sizeof(v2) * 10)));
+
+ for (int i = 0; i < Num; i++) {
+ v2 Point_P1 = CurvePoint[i];
+ v2 Point_P2 = CurvePoint[i + 1];
+ v2 Point_P0 = (i != 0) ? CurvePoint[i - 1] : V2(0, 0);
+ v2 Point_P3 = (i != (Num - 2)) ? CurvePoint[i + 2] : V2(1, 1);
+
+ v2 m1 = (Point_P2 - Point_P0) / (2 * Tau);
+ v2 m2 = (Point_P3 - Point_P1) / (2 * Tau);
+
+ CurvesSolver(LUT[a], Point_P1, Point_P2, m1, m2, i);
+ }
+
+ if (CurvePoint[0].x > 0.0f) {
+ real32 Count_Start = 0;
+ real32 Count_End = (CurvePoint[0].x * 255);
+ real32 Count = Count_Start;
+ while (Count < Count_End) {
+ LUT[a][(uint32)Count] = LUT[a][(uint32)Count_End];
+ Count++;
+ }
+ }
+
+ if (CurvePoint[Num-1].x < 1.0f) {
+ real32 Count_Start = (CurvePoint[Num-1].x * 255) - 0.5;
+ real32 Count_End = 255;
+ real32 Count = Count_Start;
+ while (Count < Count_End) {
+ LUT[a][(uint32)Count] = LUT[a][(uint32)Count_Start];
+ Count++;
+ }
+ }
+
+ for (int i = 0; i < Num; i++) {
+ if (CurvePoint[i].y == 1.0f)
+ LUT[a][255] = 1.0f;
+ }
+ }
+#endif
+
+ real32 *Num = &Effect->ExtraData[0];
+ uint32 *SelectedChannel = (uint32 *)&Effect->ExtraData[5];
+
+ v2 Pos = {};
+ bool32 AddPoint = 0;
+
+ for (uint32 i = 0; i < *(uint32 *)Num; i += 1) {
+
+ v2 Point_P1 = Effect_V2(Memory, Effect, SortedPointStart[i]);
+ v2 Point_P2 = Effect_V2(Memory, Effect, SortedPointStart[i + 1]);
+ v2 Point_P0 = (i != 0) ? Effect_V2(Memory, Effect, SortedPointStart[i - 1]) : V2(0, 0);
+ v2 Point_P3 = (i != (*Num - 2)) ? Effect_V2(Memory, Effect, SortedPointStart[i + 2]) : V2(1, 1);
+
+ ImVec2 Point_P0_ScreenPos = ViewportMin + (ImVec2(Point_P0.x, 1.0f - Point_P0.y) * ViewportScale);
+ ImVec2 Point_P1_ScreenPos = ViewportMin + (ImVec2(Point_P1.x, 1.0f - Point_P1.y) * ViewportScale);
+ ImVec2 Point_P2_ScreenPos = ViewportMin + (ImVec2(Point_P2.x, 1.0f - Point_P2.y) * ViewportScale);
+ ImVec2 Point_P3_ScreenPos = ViewportMin + (ImVec2(Point_P3.x, 1.0f - Point_P3.y) * ViewportScale);
+
+ ImGui::PushID(&PropertyStart[SortedPointStart[i]]);
+
+ draw_list->AddNgon(Point_P1_ScreenPos, 2, col, 8, 5.0f);
+
+ ImGui::SetCursorScreenPos(Point_P1_ScreenPos - ImVec2(PointSize/2, PointSize/2));
+ ImGui::InvisibleButton("##point", ImVec2(PointSize, PointSize), ImGuiButtonFlags_MouseButtonLeft);
+
+ if (ImGui::IsItemHovered()) {
+ ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
+ }
+
+ if (ImGui::IsItemActivated()) {
+ if (io.KeyCtrl && *Num != 2) {
+ property_channel *Property_X = Effect_Property(Memory, Effect, SortedPointStart[i]);
+ Property_X->Identifier = -1;
+ property_channel *Property_Y = Effect_Property(Memory, Effect, SortedPointStart[i]+1);
+ Property_Y->Identifier = -1;
+ Effect->ExtraData[*SelectedChannel]--;
+ }
+ }
+
+ if (ImGui::IsItemActive()) {
+ property_channel *Property_X = Effect_Property(Memory, Effect, SortedPointStart[i]);
+ property_channel *Property_Y = Effect_Property(Memory, Effect, SortedPointStart[i]+1);
+ v2 Point = V2(((io.MousePos - ViewportMin) / ViewportScale));
+ Point.y = 1.0f - Point.y;
+ Point.x = Normalize(Point.x);
+ Point.y = Normalize(Point.y);
+ Property_X->CurrentValue = Point.x;
+ Property_Y->CurrentValue = Point.y;
+ State->UpdateFrame = true;
+ }
+
+ if (i == (*Num - 1)) {
+ ImGui::PopID();
+ break;
+ }
+
+ // Conversion from Catmull-Rom curves to Bezier curves for display,
+ // referencing https://pomax.github.io/bezierinfo/#catmullconv
+
+ ImVec2 bez_m1 = (Point_P2_ScreenPos - Point_P0_ScreenPos) / (6 * Tau);
+ ImVec2 bez_m2 = (Point_P3_ScreenPos - Point_P1_ScreenPos) / (6 * Tau);
+
+ ImVec2 Point_Bez[4];
+ Point_Bez[0] = Point_P1_ScreenPos;
+ Point_Bez[1] = Point_P1_ScreenPos + bez_m1;
+ Point_Bez[2] = Point_P2_ScreenPos - bez_m2;
+ Point_Bez[3] = Point_P2_ScreenPos;
+
+ draw_list->PushClipRect(ViewportMin, ViewportMax, true);
+
+ draw_list->AddBezierCubic(Point_Bez[0], Point_Bez[1], Point_Bez[2], Point_Bez[3], col, 1.0f, 0);
+
+ if (ImGui::BezierInteractive(Point_Bez[0], Point_Bez[1], Point_Bez[2], Point_Bez[3]) &&
+ io.MousePos.x > (Point_P1_ScreenPos.x + PointSize/2) &&
+ io.MousePos.x < (Point_P2_ScreenPos.x - PointSize/2))
+ {
+ ImGui::SetCursorScreenPos(io.MousePos - ImVec2(5,5));
+ ImGui::Button("pointclick", ImVec2(10, 10));
+ if (ImGui::IsItemActivated()) {
+ Pos = V2(((io.MousePos - ViewportMin) / ViewportScale));
+ Pos.y = 1.0f - Pos.y;
+ Pos.x = Normalize(Pos.x);
+ Pos.y = Normalize(Pos.y);
+ AddPoint = true;
+ }
+ }
+
+ if (i == 0)
+ draw_list->AddLine(ImVec2(ViewportMin.x, Point_Bez[0].y), Point_Bez[0], col, 1.0f);
+ if (i == (*Num - 2))
+ draw_list->AddLine(ImVec2(ViewportMax.x, Point_Bez[3].y), Point_Bez[3], col, 1.0f);
+
+ draw_list->PopClipRect();
+
+#if 0
+ for (int x = 0; x < 256; x++) {
+ v2 Point = V2((real32)x/256, LUT[*ChannelIndex][x]);
+ ImVec2 Point_ScreenPos = ViewportMin + (ImVec2(Point.x, 1.0f - Point.y) * ViewportScale);
+ draw_list->AddNgon(Point_ScreenPos, 1, col, 8, 5.0f);
+ }
+#endif
+
+ draw_list->AddNgon(Point_P1_ScreenPos, 2, col, 8, 5.0f);
+
+
+ ImGui::PopID();
+ }
+
+
+ if (AddPoint) {
+ int x = 0;
+ for (;;) {
+ property_channel *Property_X = Effect_Property(Memory, Effect, x);
+ if (Property_X->Identifier == -1) {
+ Property_X->CurrentValue = Pos.x;
+ Property_X->Identifier = *SelectedChannel;
+ property_channel *Property_Y = Effect_Property(Memory, Effect, x+1);
+ Assert(Property_Y->Identifier == -1);
+ Property_Y->CurrentValue = Pos.y;
+ Property_Y->Identifier = *SelectedChannel;
+ x = MAX_PROPERTIES_PER_EFFECT;
+ }
+ if (x > MAX_PROPERTIES_PER_EFFECT)
+ break;
+ x++;
+ }
+ Effect->ExtraData[*SelectedChannel]++;
+ AddPoint = false;
+ }
+
+ // ImVec2 ButtonPos = ImGui::GetCursorScreenPos();
+ ImGui::SetCursorScreenPos(ViewportMin);
+
+ ImGui::InvisibleButton("canvas", ViewportScale, ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight);
+ bool32 IsHovered = ImGui::IsItemHovered();
+ bool32 IsActive = ImGui::IsItemActive();
+ bool32 IsActivated = ImGui::IsItemActivated();
+ bool32 IsDeactivated = ImGui::IsItemDeactivated();
+
+ ImVec2 EndPos = ImGui::GetCursorScreenPos();
+
+ ImGui::SetCursorScreenPos(ViewportMin + ImVec2(ViewportScale.x + 20, 0));
+ ImGui_RGBAModeSwitch(State, Memory, io, SelectedChannel);
+
+ ImGui::SetCursorScreenPos(EndPos);
+}
+
+static void
ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io,
sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray,
sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray)
@@ -73,33 +315,99 @@ ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *
while (Layer_LoopChannels(State, Memory, &InfoLocation, &ArrayLocation, Layer, &Property, &Effect, &h, &c, &p))
{
ImGui::PushID(Property);
- if ((h - 1) < AmountOf(Layer->Property)) {
+ if ((h - 1) < AmountOf(Layer->Property) && c == 0) {
if (ImGui::Button("K")) {
- uint16 *ArrayLocation = Property_GetSortedArray(SortedPropertyArray, State->MostRecentlySelectedLayer, h-1);
- Property_AddKeyframe(Memory, Property, State->Frame_Current, ArrayLocation);
+ Property_AddKeyframe(Memory, F_Layers, Property, State->Frame_Current, ArrayLocation);
}
ImGui::SameLine();
+#if DEBUG
+ char size[64];
+ sprintf(size, "%s, %i", DefaultChannel[h-1], Property->Keyframe_Count);
+ char *Name = size;
+#else
char *Name = DefaultChannel[h-1];
+#endif
ImGui::DragScalar(Name, ImGuiDataType_Float, &Property->CurrentValue, Property->ScrubVal, &Property->MinVal, &Property->MaxVal, "%f");
ImGui_PropertyInteract_Slider(State, Memory, Property, io, WindowMinAbs, WindowMaxAbs, F_Layers);
} else {
Assert(Effect);
header_effect *EffectHeader = Effect_EntryFromID(State, Effect->ID);
header_property ChannelHeader = State->Property[EffectHeader->PropertyStartIndex + c - 1];
- Assert(EffectHeader->DisplayType == effect_display_type_standard);
+#if DEBUG
+ char size[64];
+ sprintf(size, "%s, %i", ChannelHeader.Name, Property->Keyframe_Count);
+ char *Name = size;
+#else
+ char *Name = ChannelHeader.Name;
+#endif
if ((c - 1) == 0) {
ImGui::PushID(Effect->Index);
+#if DEBUG
+ ImGui::Text("%s, %i", EffectHeader->Name, Effect->Index);
+#else
ImGui::Text(EffectHeader->Name);
+#endif
ImGui::PopID();
}
- if (ChannelHeader.DisplayType == property_display_type_standard) {
- if (ImGui::Button("K")) {
- // uint16 *ArrayLocation = Property_GetSortedArray(SortedPropertyArray, State->MostRecentlySelectedLayer, h);
- // Property_AddKeyframe(Memory, Property, State->Frame_Current, ArrayLocation);
+ if (EffectHeader->DisplayType == effect_display_type_standard) {
+ if (ChannelHeader.DisplayType == property_display_type_standard) {
+ if (ImGui::Button("K")) {
+ Property_AddKeyframe(Memory, F_Properties, Property, State->Frame_Current, ArrayLocation);
+ }
+ ImGui::SameLine();
+ ImGui::DragScalar(Name, ImGuiDataType_Float, &Property->CurrentValue, Property->ScrubVal, &Property->MinVal, &Property->MaxVal, "%f");
+ ImGui_PropertyInteract_Slider(State, Memory, Property, io, WindowMinAbs, WindowMaxAbs, F_Properties);
+ } else if (ChannelHeader.DisplayType == property_display_type_color) {
+ if (ImGui::Button("K")) {
+ Property_AddKeyframe(Memory, F_Properties, Property, State->Frame_Current, ArrayLocation);
+ }
+ ImGui::SameLine();
+ ImGui::DragScalar(Name, ImGuiDataType_Float, &Property->CurrentValue, Property->ScrubVal, &Property->MinVal, &Property->MaxVal, "%f");
+ ImGui_PropertyInteract_Slider(State, Memory, Property, io, WindowMinAbs, WindowMaxAbs, F_Properties);
+ // if (c == 3) {
+ // ImGui::ColorEdit4("col", Col, ImGuiColorEditFlags_Float);
+ // }
+ } else {
+ Assert(0);
+ }
+ } else if (EffectHeader->DisplayType == effect_display_type_curves) {
+#if DEBUG
+ ImGui::Text("Points (RGBA): %.02f, Points (indiv): %.02f, %.02f, %.02f, %.02f", Effect->ExtraData[0],
+ Effect->ExtraData[1], Effect->ExtraData[2], Effect->ExtraData[3], Effect->ExtraData[4]);
+#endif
+ if (Property->Identifier == -1) {
+ Effect_Curves_Init(Effect, Property);
+ }
+ uint16 SortedPointStart[MAX_PROPERTIES_PER_EFFECT/5];
+ uint32 VisibleChannel = *(uint32 *)&Effect->ExtraData[5];
+ Effect_Curves_Sort(Memory, Effect, SortedPointStart, VisibleChannel);
+ ImGui_CurvesUI(State, Memory, io, Effect, Property, SortedPointStart);
+ c = EffectHeader->Property_Count; // Causes this loop to only iterate once.
+ } else if (EffectHeader->DisplayType == effect_display_type_levels) {
+ ImGui::Text("Levels!");
+ uint32 VisibleChannel = *(uint32 *)&Effect->ExtraData[0];
+ real32 *P_Left = 0, *P_Mid = 0, *P_Right = 0;
+ if (VisibleChannel == 0) {
+ property_channel *Property0 = (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect->Block_Property_Index[0]);
+ property_channel *Property1 = (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect->Block_Property_Index[1]);
+ property_channel *Property2 = (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect->Block_Property_Index[2]);
+ P_Left = &Property0->CurrentValue;
+ P_Mid = &Property1->CurrentValue;
+ P_Right = &Property2->CurrentValue;
+ } else {
+ property_channel *Property0 = (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect->Block_Property_Index[3+(VisibleChannel-1)]);
+ property_channel *Property1 = (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect->Block_Property_Index[7+(VisibleChannel-1)]);
+ property_channel *Property2 = (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect->Block_Property_Index[11+(VisibleChannel-1)]);
+ P_Left = &Property0->CurrentValue;
+ P_Mid = &Property1->CurrentValue;
+ P_Right = &Property2->CurrentValue;
+ }
+ ImGui::SliderLevels("1", "2,", "3", (void *)P_Mid, (void *)P_Left, (void *)P_Right);
+ if (ImGui::IsItemActive()) {
+ State->UpdateFrame = true;
}
- ImGui::SameLine();
- ImGui::DragScalar(ChannelHeader.Name, ImGuiDataType_Float, &Property->CurrentValue, Property->ScrubVal, &Property->MinVal, &Property->MaxVal, "%f");
- ImGui_PropertyInteract_Slider(State, Memory, Property, io, WindowMinAbs, WindowMaxAbs, F_Properties);
+ ImGui_RGBAModeSwitch(State, Memory, io, (uint32 *)&Effect->ExtraData[0]);
+ c = EffectHeader->Property_Count;
} else {
Assert(0);
}
@@ -959,7 +1267,7 @@ ImGui_TransformUI(project_data *File, project_state *State, memory *Memory, ui *
History_Entry_Commit(Memory, "Add keyframe");
bezier_point Point = { 1, {(real32)State->Frame_Current, Val[a], -1, 0, 1, 0}, interpolation_type_linear, 0, {0, 0, 0}, 0 };
uint16 *ArrayLocation = Property_GetSortedArray(SortedPropertyArray, State->MostRecentlySelectedLayer, h);
- Bezier_Add(Memory, Property[a], Point, ArrayLocation);
+ Bezier_Add(Memory, F_Layers, Property[a], Point, ArrayLocation);
History_Entry_End(Memory);
}
}
@@ -1093,7 +1401,6 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
ImGui::Begin("Viewport", &open, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
if (ImGui::IsWindowHovered(ImGuiFocusedFlags_ChildWindows)) {
- State->SetFocus = true;
State->FocusedWindow = focus_viewport;
}
@@ -1287,7 +1594,7 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
}
}
- if (ImGui::IsKeyDown(ImGuiKey_Z)) {
+ if (ImGui::IsKeyDown(ImGuiKey_Z) && ImGui::IsWindowHovered()) {
if (IsActive)
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeAll);
else
@@ -1420,7 +1727,9 @@ ImGui_Timeline_HorizontalIncrementDraw(project_state *State, ui *UI, ImDrawList
static void
-ImGui_GraphInfo(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io, sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray)
+ImGui_GraphInfo(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io,
+ sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray,
+ sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray)
{
bool open = true;
ImGui::Begin("Graph info");
@@ -1443,7 +1752,7 @@ ImGui_GraphInfo(project_data *File, project_state *State, memory *Memory, ui *UI
uint16 *ArrayLocation = Property_GetSortedArray(SortedPropertyArray, i, h);
ImGui::PushID(Property);
if (ImGui::Selectable(DefaultChannel[h], InfoLocation->IsGraphSelected)) {
- Property_DeselectAll(File, Memory, SortedPropertyArray);
+ Property_DeselectAll(File, State, Memory, SortedCompArray, SortedLayerArray, SortedPropertyInfo, SortedPropertyArray);
for (int p = 0; p < Property->Keyframe_Count; p++) {
int k = ArrayLocation[p];
bezier_point *Point = Bezier_LookupAddress(Memory, Property, k);
@@ -1464,7 +1773,8 @@ ImGui_GraphInfo(project_data *File, project_state *State, memory *Memory, ui *UI
static void
ImGui_Timeline_DrawKeySheet(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io, ImDrawList *draw_list, property_channel *Property, uint16 *ArrayLocation,
ImVec2 Increment, ImVec2 TimelineAbsolutePos, ImVec2 GraphPos, ImVec2 TimelineMoveSize, ImVec2 TimelineZoomSize,
- ImVec2 TimelineSize, ImVec2 TimelineSizeWithBorder, real32 LayerIncrement, uint16 *SortedPropertyArray)
+ ImVec2 TimelineSize, ImVec2 TimelineSizeWithBorder, real32 LayerIncrement,
+ sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray, sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray)
{
ImGui::PushID(Property);
@@ -1531,7 +1841,7 @@ ImGui_Timeline_DrawKeySheet(project_data *File, project_state *State, memory *Me
}
if (IsItemDeactivated) {
- Bezier_Commit(File, State, Memory, SortedPropertyArray);
+ Bezier_Commit(File, State, Memory, SortedCompArray, SortedLayerArray, SortedPropertyInfo, SortedPropertyArray);
}
draw_list->AddCircleFilled(Keyframe_ScreenPos, 4, PointCol);
@@ -1604,8 +1914,6 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor
Assert(InfoLocation->MinYIndex < Property->Keyframe_Count);
Assert(InfoLocation->MaxYIndex < Property->Keyframe_Count);
Assert(MaxY >= MinY);
- if (MaxY <= MinY)
- int p = 0;
real32 Y_Increment = (MaxY - MinY) ? (1 / (MaxY - MinY)) : 0.5;
real32 GraphScale = 0;
@@ -1752,7 +2060,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
int32 Frame_End = Layer->Frame_End;
real32 Vertical_Offset = SortEntry.SortedOffset + DisplayOffset;
- Layer_Evaluate_Display(Layer, SortedLayerArray, SortedCompArray, SortedLayerInfo, i, &DisplayOffset);
+ Layer_Evaluate_Display(State, Memory, Layer, SortedPropertyInfo, SortedPropertyArray, SortedLayerArray, SortedCompArray, SortedLayerInfo, i, &DisplayOffset);
if (Layer->IsSelected)
Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End);
@@ -2004,15 +2312,25 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
// Keyframe view
uint32 Channel = 0;
- for (int h = 0; h < AmountOf(Layer->Property); h++) {
- property_channel *Property = &Layer->Property[h];
+
+ sorted_property_info *InfoLocation = SortedPropertyInfo + SortedLayerInfo->SortedPropertyStart;
+ uint16 *ArrayLocation = SortedPropertyArray + SortedLayerInfo->SortedKeyframeStart;
+ int h = 0, c = 0, p = 0;
+ property_channel *Property = NULL;
+ block_effect *Effect = NULL;
+ while (Layer_LoopChannels(State, Memory, &InfoLocation, &ArrayLocation, Layer, &Property, &Effect, &h, &c, &p))
+ {
if (Property->IsToggled) {
- sorted_property_info *InfoLocation = Property_GetSortedInfo(SortedPropertyInfo, i, h);
- uint16 *ArrayLocation = Property_GetSortedArray(SortedPropertyArray, i, h);
- ImVec2 GraphPos(TimelineAbsolutePos.x, Layer_ScreenPos_Min.y + (Layer_ScreenSize.y * 2) + (Layer_ScreenSize.y * Channel));
+ ImVec2 GraphMinPos = ImVec2(TimelineAbsolutePos.x, Layer_ScreenPos_Min.y + Layer_ScreenSize.y + (Layer_ScreenSize.y * Channel));
+ ImVec2 GraphPos = GraphMinPos + ImVec2(0, Layer_ScreenSize.y);
+ ImVec2 GraphMinBounds = GraphMinPos + ImVec2(0, Layer_ScreenSize.y * 0.5);
+ ImVec2 GraphMaxBounds = GraphMinBounds + ImVec2(TimelineSizeWithBorder.x, Layer_ScreenSize.y);
+ uint32 col = (Channel % 2) ? IM_COL32(50, 50, 50, 255) : IM_COL32(50, 50, 50, 128);
+ draw_list->AddRectFilled(GraphMinBounds, GraphMaxBounds, col);
ImGui_Timeline_DrawKeySheet(File, State, Memory, UI, io, draw_list, Property, ArrayLocation,
Increment, TimelineAbsolutePos, GraphPos, TimelineMoveSize, TimelineZoomSize,
- TimelineSize, TimelineSizeWithBorder, LayerIncrement, SortedPropertyArray);
+ TimelineSize, TimelineSizeWithBorder, LayerIncrement,
+ SortedCompArray, SortedLayerArray, SortedPropertyInfo, SortedPropertyArray);
Channel++;
}
}
@@ -2075,7 +2393,6 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
ImGui::Begin("Timeline", NULL);
if (ImGui::IsWindowHovered(ImGuiFocusedFlags_ChildWindows)) {
- State->SetFocus = true;
State->FocusedWindow = focus_timeline;
}
@@ -2348,7 +2665,7 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
if (State->Interact_Active == interact_type_keyframe_move ||
State->Interact_Active == interact_type_keyframe_rotate ||
State->Interact_Active == interact_type_keyframe_scale) {
- Bezier_Commit(File, State, Memory, SortedPropertyArray);
+ Bezier_Commit(File, State, Memory, SortedCompArray, SortedLayerArray, SortedPropertyInfo, SortedPropertyArray);
}
State->BoxSelect = true;
}
@@ -2520,13 +2837,11 @@ ImGui_Popups(project_data *File, project_state *State, ui *UI, memory *Memory, I
{
ImGui::OpenPopup("Save as");
ImGui::SetKeyboardFocusHere();
- State->SetFocus = 0;
} break;
case popup_keybinds:
{
ImGui::OpenPopup("Keybinds");
ImGui::SetKeyboardFocusHere();
- State->SetFocus = 0;
} break;
default:
{
@@ -2575,6 +2890,9 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me
State->Brush.EraseMode ^= 1;
}
}
+ if (ImGui::IsKeyPressed(ImGuiKey_U)) {
+ State->HotkeyInput = hotkey_togglechannels;
+ }
if (ImGui::IsKeyPressed(ImGuiKey_X)) {
if (State->TimelineMode == timeline_mode_graph && State->Interact_Active == interact_type_keyframe_move) {
if (State->Interact_Modifier != 1)
@@ -2603,14 +2921,15 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me
}
// NOTE(fox): File data not tracked on undo tree!
if (ImGui::IsKeyPressed(ImGuiKey_N)) {
- block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex);
- if (MainComp->Frame_Start < State->Frame_Current)
- MainComp->Frame_End = State->Frame_Current;
- }
- if (ImGui::IsKeyPressed(ImGuiKey_B)) {
- block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex);
- if (MainComp->Frame_End > State->Frame_Current)
- MainComp->Frame_Start = State->Frame_Current;
+ if (io.KeyShift) {
+ block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex);
+ if (MainComp->Frame_Start < State->Frame_Current)
+ MainComp->Frame_End = State->Frame_Current;
+ } else {
+ block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex);
+ if (MainComp->Frame_End > State->Frame_Current)
+ MainComp->Frame_Start = State->Frame_Current;
+ }
}
if (ImGui::IsKeyPressed(ImGuiKey_Tab)) {
State->TimelineMode = (State->TimelineMode == timeline_mode_default) ? timeline_mode_graph : timeline_mode_default;
@@ -2618,6 +2937,9 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me
UI->GraphMoveSize = ImVec2(0, 0);
}
if (!io.KeyCtrl) {
+ // NOTE(fox): Checking IsWindowHovered seems to be all we need to do to
+ // make per-window hotkeys work; setting it as the focused window causes
+ // problems with popups.
if (State->FocusedWindow == focus_timeline) {
if (State->TimelineMode == timeline_mode_default) {
if (ImGui::IsKeyPressed(ImGuiKey_G)) {
@@ -2857,8 +3179,7 @@ ImGui_EffectsPanel(project_data *File, project_state *State, memory *Memory, ui
header_effect *EffectHeader = &State->Effect[i];
if (State->filter.PassFilter(EffectHeader->Name)) {
if (EffectSel == p && State->MostRecentlySelectedLayer != -1) {
- Assert(0);
- // AddEffect(File->Layer[State->MostRecentlySelectedLayer], Memory, i);
+ Effect_Add(File, State, Memory, i);
State->UpdateFrame = true;
}
p++;