diff options
Diffstat (limited to 'my_imgui_widgets.cpp')
-rw-r--r-- | my_imgui_widgets.cpp | 403 |
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++; |