From ed51dab429e467fc144f0bfbed70a5291c8a0a27 Mon Sep 17 00:00:00 2001 From: Fox Caminiti Date: Sun, 21 Aug 2022 10:20:31 -0400 Subject: multisampled gl masks --- my_imgui_widgets.cpp | 492 ++++++++++++++++++++++++++------------------------- 1 file changed, 252 insertions(+), 240 deletions(-) (limited to 'my_imgui_widgets.cpp') diff --git a/my_imgui_widgets.cpp b/my_imgui_widgets.cpp index 54fa9c1..ea2e314 100644 --- a/my_imgui_widgets.cpp +++ b/my_imgui_widgets.cpp @@ -43,6 +43,7 @@ ImGui_KeyframeDragging(project_data *File, project_state *State, ui *UI, propert // Cache.Frame[File.CurrentFrame].Cached = false; } } + /* if (Type != 0) { if (Type == 1) @@ -66,6 +67,7 @@ ImGui_KeyframeDragging(project_data *File, project_state *State, ui *UI, propert State->UpdateFrame = true; State->UpdateKeyframes = true; } + */ } } } @@ -85,10 +87,10 @@ ImGui_InteractSliderProperty(project_state *State, memory *Memory, property_chan if (ImGui::IsKeyPressed(ImGuiKey_Escape)) { Property->CurrentValue.f = State->InteractCache[0]; } else { - Action_Entry_Commit(Memory, action_entry_default, "Tranforms interact"); - Action_Change_Commit(Memory, &Property->CurrentValue.f, &State->InteractCache[0], - &Property->CurrentValue.f, action_change_r32); - Action_Entry_End(Memory); + History_Entry_Commit(Memory, action_entry_default, "Tranforms interact"); + History_Action_Change(Memory, &Property->CurrentValue.f, &State->InteractCache[0], + &Property->CurrentValue.f, action_type_change_r32); + History_Entry_End(Memory); } State->UpdateFrame = true; } @@ -230,7 +232,7 @@ ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory * property_channel *Property = &Layer->Property[h]; ImGui::PushID(Property); if (ImGui::Button("K")) - ManualKeyframeInsertF(Property, Memory, File->CurrentFrame, Property->CurrentValue.f); + Keyframe_Insert(Property, Memory, File->CurrentFrame, Property->CurrentValue.f); ImGui::SameLine(); ImGui_InteractSliderProperty(State, Memory, Property); ImGui::PopID(); @@ -484,18 +486,18 @@ ImGui_Viewport(project_data File, project_state *State, ui *UI, memory *Memory, } if (ImGui::IsItemActivated() && b == 0) { if (p == 0 && State->Pen.IsActive) { - Action_Entry_Commit(Memory, action_entry_default, "Close mask path"); - Action_Change_Commit_SwapBool(Memory, &State->Pen.IsActive); - Action_Change_Commit_SwapBool(Memory, &Mask->IsClosed); + History_Entry_Commit(Memory, action_entry_default, "Close mask path"); + History_Action_Change_SwapBool(Memory, &State->Pen.IsActive); + History_Action_Change_SwapBool(Memory, &Mask->IsClosed); // State->Pen.IsActive = false; // Mask->IsClosed = true; - Action_Entry_End(Memory); + History_Entry_End(Memory); } else if (io.KeyCtrl) { // TODO(fox): Mask delete! } else if (io.KeyAlt) { - Action_Entry_Commit(Memory, action_entry_default, "Switch handles on point"); - Action_Change_Commit_SwapBool(Memory, &Point0->HandleBezier); - Action_Entry_End(Memory); + History_Entry_Commit(Memory, action_entry_default, "Switch handles on point"); + History_Action_Change_SwapBool(Memory, &Point0->HandleBezier); + History_Entry_End(Memory); } Point0->IsSelected = true; } @@ -651,9 +653,9 @@ ImGui_Viewport(project_data File, project_state *State, ui *UI, memory *Memory, Mask->NumberOfPoints = 0; State->Pen.IsActive = false; } else { - Action_Entry_Commit(Memory, action_entry_default, "Path adding exited"); - Action_Change_Commit_SwapBool(Memory, &State->Pen.IsActive); - Action_Entry_End(Memory); + History_Entry_Commit(Memory, action_entry_default, "Path adding exited"); + History_Action_Change_SwapBool(Memory, &State->Pen.IsActive); + History_Entry_End(Memory); } IsDeactivated = false; // just in case escape and mouse release happen simultaneously } @@ -662,32 +664,32 @@ ImGui_Viewport(project_data File, project_state *State, ui *UI, memory *Memory, if (Mask->NumberOfPoints == 1) { uint16 PreviousNumberOfMasks = Layer->NumberOfMasks - 1; uint16 PreviousNumberOfPoints = Mask->NumberOfPoints - 1; - Action_Entry_Commit(Memory, action_entry_default, "Create mask"); - Action_Change_Commit(Memory, &Layer->NumberOfMasks, &PreviousNumberOfMasks, - &Layer->NumberOfMasks, action_change_u16); - Action_Change_Commit(Memory, &Mask->NumberOfPoints, &PreviousNumberOfPoints, - &Mask->NumberOfPoints, action_change_u16); - Action_Entry_End(Memory); + History_Entry_Commit(Memory, action_entry_default, "Create mask"); + History_Action_Change(Memory, &Layer->NumberOfMasks, &PreviousNumberOfMasks, + &Layer->NumberOfMasks, action_type_change_u16); + History_Action_Change(Memory, &Mask->NumberOfPoints, &PreviousNumberOfPoints, + &Mask->NumberOfPoints, action_type_change_u16); + History_Entry_End(Memory); } else { uint16 PreviousNumberOfPoints = Mask->NumberOfPoints - 1; uint16 Empty = 0; mask_point *CurrentPoint = &Mask->Point[Mask->NumberOfPoints-1]; - Action_Entry_Commit(Memory, action_entry_default, "Add point"); - Action_Change_Commit(Memory, &Mask->NumberOfPoints, &PreviousNumberOfPoints, - &Mask->NumberOfPoints, action_change_u16); - Action_Change_Commit(Memory, &CurrentPoint->Pos.x, &Empty, - &CurrentPoint->Pos.x, action_change_r32); - Action_Change_Commit(Memory, &CurrentPoint->Pos.y, &Empty, - &CurrentPoint->Pos.y, action_change_r32); - Action_Change_Commit(Memory, &CurrentPoint->TangentLeft.x, &Empty, - &CurrentPoint->TangentLeft.x, action_change_r32); - Action_Change_Commit(Memory, &CurrentPoint->TangentLeft.y, &Empty, - &CurrentPoint->TangentLeft.y, action_change_r32); - Action_Change_Commit(Memory, &CurrentPoint->TangentRight.x, &Empty, - &CurrentPoint->TangentRight.x, action_change_r32); - Action_Change_Commit(Memory, &CurrentPoint->TangentRight.y, &Empty, - &CurrentPoint->TangentRight.y, action_change_r32); - Action_Entry_End(Memory); + History_Entry_Commit(Memory, action_entry_default, "Add point"); + History_Action_Change(Memory, &Mask->NumberOfPoints, &PreviousNumberOfPoints, + &Mask->NumberOfPoints, action_type_change_u16); + History_Action_Change(Memory, &CurrentPoint->Pos.x, &Empty, + &CurrentPoint->Pos.x, action_type_change_r32); + History_Action_Change(Memory, &CurrentPoint->Pos.y, &Empty, + &CurrentPoint->Pos.y, action_type_change_r32); + History_Action_Change(Memory, &CurrentPoint->TangentLeft.x, &Empty, + &CurrentPoint->TangentLeft.x, action_type_change_r32); + History_Action_Change(Memory, &CurrentPoint->TangentLeft.y, &Empty, + &CurrentPoint->TangentLeft.y, action_type_change_r32); + History_Action_Change(Memory, &CurrentPoint->TangentRight.x, &Empty, + &CurrentPoint->TangentRight.x, action_type_change_r32); + History_Action_Change(Memory, &CurrentPoint->TangentRight.y, &Empty, + &CurrentPoint->TangentRight.y, action_type_change_r32); + History_Entry_End(Memory); } } if (State->Tool != tool_pen) { @@ -1107,21 +1109,13 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, real32 YInit = ImGui::GetCursorScreenPos().y; ImGui::SameLine(); if (ImGui::Button("K")) - ManualKeyframeInsertF(Property, Memory, File->CurrentFrame, Property->CurrentValue.f); + Keyframe_Insert(Property, Memory, File->CurrentFrame, Property->CurrentValue.f); ImGui::SameLine(); if (ImGui::Button("G")) { - Property->IsGraphToggled ^= 1; - // TODO(fox): Make system to init things like these automatically? - if (!Property->GraphLength) { - Property->GraphLength = 150; - Property->GraphYOffset = (Property->GraphWindowHeight - Property->GraphLength)/2; - } + UI->Graph[UI->NumberOfGraphsEnabled].ChannelViewed = Property; + UI->NumberOfGraphsEnabled++; } ImGui::SetCursorScreenPos(ImVec2(ImGui::GetCursorScreenPos().x, YInit)); - if (Property->IsGraphToggled) - { - ImGui::Dummy(ImVec2(5, Property->GraphWindowHeight)); - } ImGui::PopID(); } } @@ -1158,8 +1152,15 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, ImGui::SetCursorScreenPos(TimelineStartingPos); - ImGui::PushClipRect(TimelineAbsolutePos, TimelineAbsolutePos + TimelineSizeWithBorder, true); - draw_list->PushClipRect(TimelineAbsolutePos, TimelineAbsolutePos + TimelineSizeWithBorder, true); + if (UI->NumberOfGraphsEnabled) + { + ImVec2 Dim = ImVec2(TimelineAbsolutePos.x + TimelineSizeWithBorder.x, TimelineAbsolutePos.y + TimelineSizeWithBorder.y - UI->Graph[0].WindowYOffset); + ImGui::PushClipRect(TimelineAbsolutePos, Dim, true); + draw_list->PushClipRect(TimelineAbsolutePos, Dim, true); + } else { + ImGui::PushClipRect(TimelineAbsolutePos, TimelineAbsolutePos + TimelineSizeWithBorder, true); + draw_list->PushClipRect(TimelineAbsolutePos, TimelineAbsolutePos + TimelineSizeWithBorder, true); + } for (int i = File->NumberOfLayers - 1; i >= 0; i--) { @@ -1263,226 +1264,237 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, ImGui::SetCursorScreenPos(ImVec2(ImGui::GetCursorScreenPos().x, NextY)); - if (Property->IsGraphToggled) - { - uint16 GraphWindowHeight = File->Layer[i]->Property[a].GraphWindowHeight; - real32 GraphWindowLocalYMin = ImGui::GetCursorPosY(); - ImDrawList* draw_list = ImGui::GetWindowDrawList(); - real32 ScreenY = NextY; - ImVec2 MinPos = ImVec2(TimelineAbsolutePos.x, ScreenY); - ImVec2 MaxPos = ImVec2(TimelineAbsolutePos.x + TimelineSizeWithBorder.x, ScreenY + GraphWindowHeight); - draw_list->AddRectFilled(MinPos, MaxPos, - IM_COL32(00, 00, 30, 65)); - - draw_list->PushClipRect(MinPos, MaxPos, true); - - ImVec2 LeftPos[2]; - ImVec2 MidPos[2]; - ImVec2 RightPos[2]; - ImU32 col = ImGui::GetColorU32(ImGuiCol_ScrollbarGrab); + ImGui::PopID(); + } + } - for (int b = 0; b < Property->NumberOfTotalKeyframes; b++) { - keyframe *Keyframe = KeyframeLookup(Property, b); - // int32 Index = KeyframeMemoryToIndex(Property, b); + ImGui::SetCursorPosY(ImGui::GetCursorPos().y - (ItemSpacing.y * UI->KeyframeSpacing / 2)); + ImGui::PopStyleVar(); - ImGui::PushID(Keyframe); + ImGui::PopID(); + } - real32 MinVal = Property->LocalMinVal.f; - real32 MaxVal = Property->LocalMaxVal.f; - // Normalized ratio between the smallest and largest value - real32 HandleYRatio = (Keyframe->Value.f - MaxVal) / (MaxVal - MinVal); - real32 HandleYRatio_L = (Keyframe->Value.f + Keyframe->TangentLeft.y - MaxVal) / (MaxVal - MinVal); - real32 HandleYRatio_R = (Keyframe->Value.f + Keyframe->TangentRight.y - MaxVal) / (MaxVal - MinVal); + // Timeline frame ticks - real32 LocalHandlePosX = UI->TimelineZoom*Keyframe->FrameNumber; - real32 LocalHandlePosX_L = LocalHandlePosX + UI->TimelineZoom*Keyframe->TangentLeft.x; - real32 LocalHandlePosX_R = LocalHandlePosX + UI->TimelineZoom*Keyframe->TangentRight.x; + ImGui::SetCursorScreenPos(TimelineStartingPos); + if (UI->TimelineZoom > 10) { + for (float x = 0; x < File->NumberOfFrames + 2; x += 1) { + uint32 LineColor = IM_COL32(200, 200, 200, 40); + ImVec2 Min = ImVec2(TimelineStartingPos.x + UI->TimelineZoom * x, TimelineStartingPos.y); + ImVec2 Max = ImVec2(Min.x + 2, WindowMaxAbs.y); + if (x == File->CurrentFrame) continue; + draw_list->AddLine(Min, Max, LineColor); + } + } - real32 HandlePosX = TimelineStartingPos.x + LocalHandlePosX - FontHeight*0.5; - real32 HandlePosX_L = TimelineStartingPos.x + LocalHandlePosX_L - FontHeight*0.5; - real32 HandlePosX_R = TimelineStartingPos.x + LocalHandlePosX_R - FontHeight*0.5; - real32 LocalHandlePosY = HandleYRatio * Property->GraphLength; - real32 LocalHandlePosY_L = HandleYRatio_L * Property->GraphLength; - real32 LocalHandlePosY_R = HandleYRatio_R * Property->GraphLength; + draw_list->PopClipRect(); + ImGui::PopClipRect(); - real32 HandlePosY = MinPos.y - LocalHandlePosY + Property->GraphYOffset; - real32 HandlePosY_L = MinPos.y - LocalHandlePosY_L + Property->GraphYOffset; - real32 HandlePosY_R = MinPos.y - LocalHandlePosY_R + Property->GraphYOffset; + // Graph window - ImVec2 HandlePos = ImVec2(HandlePosX, HandlePosY); - ImVec2 HandlePos_L = ImVec2(HandlePosX_L, HandlePosY_L); - ImVec2 HandlePos_R = ImVec2(HandlePosX_R, HandlePosY_R); + if (UI->NumberOfGraphsEnabled) + { + ui_graph Graph = UI->Graph[0]; - if (UI->BoxSelectActive && UI->BoxStart.y >= NextY) { - if (IsRectTouching(UI->BoxStart, UI->BoxEnd, HandlePos, HandlePos + KeyframeSize)) { - Keyframe->IsSelected = true; - State->RecentSelectionType = selection_keyframe; - } else if (!io.KeyShift) { - Keyframe->IsSelected = false; - } - } + ImGui::SetCursorScreenPos(ImVec2(ImGui::GetCursorScreenPos().x, + TimelineAbsolutePos.y + TimelineSizeWithBorder.y - Graph.WindowYOffset)); - ImGui::PushStyleColor(ImGuiCol_Button, col); + ImVec2 GraphMin = ImVec2(TimelineAbsolutePos.x, ImGui::GetCursorScreenPos().y); + ImVec2 GraphSize = ImVec2(TimelineSizeWithBorder.x, Graph.WindowYOffset); - ImGui::SetCursorScreenPos(ImVec2(HandlePosX - FontHeight*1.5, HandlePosY - FontHeight*1.5)); - ImGui::Text("%.02f", Keyframe->Value.f); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + draw_list->AddRectFilled(GraphMin, GraphMin + GraphSize, + IM_COL32(0, 0, 30, 50)); - ImGui::SetCursorScreenPos(ImVec2(HandlePosX - FontHeight*1.0, HandlePosY - FontHeight*1.0)); - ImGui::InvisibleButton("##keyframepoint", ImVec2(FontHeight*2, FontHeight*2), ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight); + // draw_list->PushClipRect(GraphMin, GraphMin + GraphSize, true); + // draw_list->PopClipRect(); - draw_list->AddRect(ImVec2(HandlePosX - FontHeight*0.5, HandlePosY - FontHeight*0.5), - ImVec2(HandlePosX + FontHeight*0.5, HandlePosY + FontHeight*0.5), - ImGui::GetColorU32(ImGuiCol_ButtonHovered)); + /* + ImVec2 LeftPos[2]; + ImVec2 MidPos[2]; + ImVec2 RightPos[2]; + ImU32 col = ImGui::GetColorU32(ImGuiCol_ScrollbarGrab); - ImGui_KeyframeDragging(File, State, UI, Property, b, io, 1); + for (int b = 0; b < Property->NumberOfTotalKeyframes; b++) { + keyframe *Keyframe = KeyframeLookup(Property, b); + // int32 Index = KeyframeMemoryToIndex(Property, b); - if (Keyframe->IsSelected && Keyframe->Type == bezier) { + ImGui::PushID(Keyframe); - ImGui::SetCursorScreenPos(ImVec2(HandlePosX_L, HandlePosY_L)); - draw_list->AddCircle(ImVec2(HandlePosX_L, HandlePosY_L), 2, col, 16, 1); - ImGui::Button("##keyframehandleleft", ImVec2(FontHeight, FontHeight)); + real32 MinVal = Property->LocalMinVal.f; + real32 MaxVal = Property->LocalMaxVal.f; - ImGui_KeyframeDragging(File, State, UI, Property, b, io, 2); + // Normalized ratio between the smallest and largest value + real32 HandleYRatio = (Keyframe->Value.f - MaxVal) / (MaxVal - MinVal); + real32 HandleYRatio_L = (Keyframe->Value.f + Keyframe->TangentLeft.y - MaxVal) / (MaxVal - MinVal); + real32 HandleYRatio_R = (Keyframe->Value.f + Keyframe->TangentRight.y - MaxVal) / (MaxVal - MinVal); - ImGui::SetCursorScreenPos(ImVec2(HandlePosX_R, HandlePosY_R)); - ImGui::Button("##keyframehandleright", ImVec2(FontHeight, FontHeight)); + real32 LocalHandlePosX = UI->TimelineZoom*Keyframe->FrameNumber; + real32 LocalHandlePosX_L = LocalHandlePosX + UI->TimelineZoom*Keyframe->TangentLeft.x; + real32 LocalHandlePosX_R = LocalHandlePosX + UI->TimelineZoom*Keyframe->TangentRight.x; - ImGui_KeyframeDragging(File, State, UI, Property, b, io, 3); + real32 HandlePosX = TimelineStartingPos.x + LocalHandlePosX - FontHeight*0.5; + real32 HandlePosX_L = TimelineStartingPos.x + LocalHandlePosX_L - FontHeight*0.5; + real32 HandlePosX_R = TimelineStartingPos.x + LocalHandlePosX_R - FontHeight*0.5; - draw_list->AddLine(MidPos[b & 1], RightPos[b & 1], col, 1.0f); - draw_list->AddLine(MidPos[b & 1], LeftPos[b & 1], col, 1.0f); - } + real32 LocalHandlePosY = HandleYRatio * Property->GraphLength; + real32 LocalHandlePosY_L = HandleYRatio_L * Property->GraphLength; + real32 LocalHandlePosY_R = HandleYRatio_R * Property->GraphLength; - ImGui::PopStyleColor(); + real32 HandlePosY = MinPos.y - LocalHandlePosY + Property->GraphYOffset; + real32 HandlePosY_L = MinPos.y - LocalHandlePosY_L + Property->GraphYOffset; + real32 HandlePosY_R = MinPos.y - LocalHandlePosY_R + Property->GraphYOffset; - ImGui::PopID(); - } + ImVec2 HandlePos = ImVec2(HandlePosX, HandlePosY); + ImVec2 HandlePos_L = ImVec2(HandlePosX_L, HandlePosY_L); + ImVec2 HandlePos_R = ImVec2(HandlePosX_R, HandlePosY_R); - // TODO(fox): Reformat this so it's all done in one loop. + if (UI->BoxSelectActive && UI->BoxStart.y >= NextY) { + if (IsRectTouching(UI->BoxStart, UI->BoxEnd, HandlePos, HandlePos + KeyframeSize)) { + Keyframe->IsSelected = true; + State->RecentSelectionType = selection_keyframe; + } else if (!io.KeyShift) { + Keyframe->IsSelected = false; + } + } - for (int b = 0; b < Property->NumberOfTotalKeyframes; b++) { - keyframe *Keyframe = KeyframeLookup(Property, b); + ImGui::PushStyleColor(ImGuiCol_Button, col); - real32 MinVal = Property->LocalMinVal.f; - real32 MaxVal = Property->LocalMaxVal.f; + ImGui::SetCursorScreenPos(ImVec2(HandlePosX - FontHeight*1.5, HandlePosY - FontHeight*1.5)); + ImGui::Text("%.02f", Keyframe->Value.f); - real32 HandleYRatio = (Keyframe->Value.f - MaxVal) / (MaxVal - MinVal); - real32 HandleYRatio_L = (Keyframe->Value.f + Keyframe->TangentLeft.y - MaxVal) / (MaxVal - MinVal); - real32 HandleYRatio_R = (Keyframe->Value.f + Keyframe->TangentRight.y - MaxVal) / (MaxVal - MinVal); + ImGui::SetCursorScreenPos(ImVec2(HandlePosX - FontHeight*1.0, HandlePosY - FontHeight*1.0)); + ImGui::InvisibleButton("##keyframepoint", ImVec2(FontHeight*2, FontHeight*2), ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight); - real32 LocalHandlePosX = UI->TimelineZoom*Keyframe->FrameNumber; - real32 LocalHandlePosX_L = LocalHandlePosX + UI->TimelineZoom*Keyframe->TangentLeft.x; - real32 LocalHandlePosX_R = LocalHandlePosX + UI->TimelineZoom*Keyframe->TangentRight.x; + draw_list->AddRect(ImVec2(HandlePosX - FontHeight*0.5, HandlePosY - FontHeight*0.5), + ImVec2(HandlePosX + FontHeight*0.5, HandlePosY + FontHeight*0.5), + ImGui::GetColorU32(ImGuiCol_ButtonHovered)); - real32 HandlePosX = TimelineStartingPos.x + LocalHandlePosX - FontHeight*0.5; - real32 HandlePosX_L = TimelineStartingPos.x + LocalHandlePosX_L - FontHeight*0.5; - real32 HandlePosX_R = TimelineStartingPos.x + LocalHandlePosX_R - FontHeight*0.5; + ImGui_KeyframeDragging(File, State, UI, Property, b, io, 1); - real32 LocalHandlePosY = HandleYRatio * Property->GraphLength; - real32 LocalHandlePosY_L = HandleYRatio_L * Property->GraphLength; - real32 LocalHandlePosY_R = HandleYRatio_R * Property->GraphLength; + if (Keyframe->IsSelected && Keyframe->Type == bezier) { - real32 HandlePosY = MinPos.y - LocalHandlePosY + Property->GraphYOffset; - real32 HandlePosY_L = MinPos.y - LocalHandlePosY_L + Property->GraphYOffset; - real32 HandlePosY_R = MinPos.y - LocalHandlePosY_R + Property->GraphYOffset; + ImGui::SetCursorScreenPos(ImVec2(HandlePosX_L, HandlePosY_L)); + draw_list->AddCircle(ImVec2(HandlePosX_L, HandlePosY_L), 2, col, 16, 1); + ImGui::Button("##keyframehandleleft", ImVec2(FontHeight, FontHeight)); - ImVec2 HandlePos = ImVec2(HandlePosX, HandlePosY); - ImVec2 HandlePos_L = ImVec2(HandlePosX_L, HandlePosY_L); - ImVec2 HandlePos_R = ImVec2(HandlePosX_R, HandlePosY_R); + ImGui_KeyframeDragging(File, State, UI, Property, b, io, 2); - MidPos[b & 1] = HandlePos; - LeftPos[b & 1] = HandlePos_L; - RightPos[b & 1] = HandlePos_R; + ImGui::SetCursorScreenPos(ImVec2(HandlePosX_R, HandlePosY_R)); + ImGui::Button("##keyframehandleright", ImVec2(FontHeight, FontHeight)); - if (b != 0) - { - if (b & 1) { - if (Keyframe->Type == linear) - draw_list->AddLine(MidPos[0], MidPos[1], col, 1.0f); - else if (Keyframe->Type == bezier) - draw_list->AddBezierCubic(MidPos[0], RightPos[0], LeftPos[1], MidPos[1], col, 1.0f, 8); - } else { - if (Keyframe->Type == linear) - draw_list->AddLine(MidPos[1], MidPos[0], col, 1.0f); - else if (Keyframe->Type == bezier) - draw_list->AddBezierCubic(MidPos[1], RightPos[1], LeftPos[0], MidPos[0], col, 1.0f, 8); - } - } - } - // Horiziontal value lines - - // uint32 LineColor = IM_COL32(200, 200, 200, 40); - // for (int i = 0; i < 10; i++) { - // real32 YPos = MinPos.y + (UI->TimelineZoom/2 * i) + 5; - // ImVec2 Min = ImVec2(TimelineStartingPos.x, YPos); - // ImVec2 Max = ImVec2(TimelineStartingPos.x + TimelineSize.x, YPos); - // draw_list->AddLine(Min, Max, LineColor); - // } + ImGui_KeyframeDragging(File, State, UI, Property, b, io, 3); - draw_list->PopClipRect(); + draw_list->AddLine(MidPos[b & 1], RightPos[b & 1], col, 1.0f); + draw_list->AddLine(MidPos[b & 1], LeftPos[b & 1], col, 1.0f); + } - // ImGui::SetCursorScreenPos(ImVec2(MinPos.x, MinPos.y)); - // ImGui::Button("##SplitMove", ImVec2(TimelineBorderPadding.x, SidebarSizeWithBorder.y)); - // if (ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) - // { - // UI->TimelineSplit += io.MouseDelta.x; - // } + ImGui::PopStyleColor(); - ImGui::SetCursorScreenPos(ImVec2(MinPos.x, MinPos.y)); - ImGui::InvisibleButton("AnimationCurves", ImVec2(TimelineSize.x - 20, GraphWindowHeight), ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight); - // NOTE(fox): I'm reusing this struct for the other - // channels, so I'm OR'ing it. Also persists across layers. - AnimationCurves.IsItemHovered |= ImGui::IsItemHovered(); - AnimationCurves.IsItemActive |= ImGui::IsItemActive(); - AnimationCurves.IsItemActivated |= ImGui::IsItemActivated(); - AnimationCurves.IsItemDeactivated |= ImGui::IsItemDeactivated(); - AnimationCurves.LeftClick |= ImGui::IsMouseDown(ImGuiMouseButton_Left); - AnimationCurves.RightClick |= ImGui::IsMouseDown(ImGuiMouseButton_Right); - - if (AnimationCurves.IsItemHovered && AnimationCurves.IsItemActivated && - ImGui::IsMouseDown(ImGuiMouseButton_Right)) { - real32 LocalMousePos = io.MousePos.y - MinPos.y - Property->GraphYOffset; - UI->TempZoomRatioGraph = LocalMousePos / Property->GraphLength; - } - // DebugWatchVar("LocalMousePos", &LocalMousePos, d_float); + ImGui::PopID(); + } - if (AnimationCurves.IsItemActive && ImGui::IsMouseDragging(ImGuiMouseButton_Right, -1)) - { - Property->GraphLength += io.MouseDelta.x; - Property->GraphYOffset -= io.MouseDelta.x*UI->TempZoomRatioGraph; - Property->GraphYOffset += io.MouseDelta.y; - } + // TODO(fox): Reformat this so it's all done in one loop. + + for (int b = 0; b < Property->NumberOfTotalKeyframes; b++) { + keyframe *Keyframe = KeyframeLookup(Property, b); + + real32 MinVal = Property->LocalMinVal.f; + real32 MaxVal = Property->LocalMaxVal.f; + + real32 HandleYRatio = (Keyframe->Value.f - MaxVal) / (MaxVal - MinVal); + real32 HandleYRatio_L = (Keyframe->Value.f + Keyframe->TangentLeft.y - MaxVal) / (MaxVal - MinVal); + real32 HandleYRatio_R = (Keyframe->Value.f + Keyframe->TangentRight.y - MaxVal) / (MaxVal - MinVal); + + real32 LocalHandlePosX = UI->TimelineZoom*Keyframe->FrameNumber; + real32 LocalHandlePosX_L = LocalHandlePosX + UI->TimelineZoom*Keyframe->TangentLeft.x; + real32 LocalHandlePosX_R = LocalHandlePosX + UI->TimelineZoom*Keyframe->TangentRight.x; + + real32 HandlePosX = TimelineStartingPos.x + LocalHandlePosX - FontHeight*0.5; + real32 HandlePosX_L = TimelineStartingPos.x + LocalHandlePosX_L - FontHeight*0.5; + real32 HandlePosX_R = TimelineStartingPos.x + LocalHandlePosX_R - FontHeight*0.5; + + real32 LocalHandlePosY = HandleYRatio * Property->GraphLength; + real32 LocalHandlePosY_L = HandleYRatio_L * Property->GraphLength; + real32 LocalHandlePosY_R = HandleYRatio_R * Property->GraphLength; + + real32 HandlePosY = MinPos.y - LocalHandlePosY + Property->GraphYOffset; + real32 HandlePosY_L = MinPos.y - LocalHandlePosY_L + Property->GraphYOffset; + real32 HandlePosY_R = MinPos.y - LocalHandlePosY_R + Property->GraphYOffset; + + ImVec2 HandlePos = ImVec2(HandlePosX, HandlePosY); + ImVec2 HandlePos_L = ImVec2(HandlePosX_L, HandlePosY_L); + ImVec2 HandlePos_R = ImVec2(HandlePosX_R, HandlePosY_R); + + MidPos[b & 1] = HandlePos; + LeftPos[b & 1] = HandlePos_L; + RightPos[b & 1] = HandlePos_R; + + if (b != 0) + { + if (b & 1) { + if (Keyframe->Type == linear) + draw_list->AddLine(MidPos[0], MidPos[1], col, 1.0f); + else if (Keyframe->Type == bezier) + draw_list->AddBezierCubic(MidPos[0], RightPos[0], LeftPos[1], MidPos[1], col, 1.0f, 8); + } else { + if (Keyframe->Type == linear) + draw_list->AddLine(MidPos[1], MidPos[0], col, 1.0f); + else if (Keyframe->Type == bezier) + draw_list->AddBezierCubic(MidPos[1], RightPos[1], LeftPos[0], MidPos[0], col, 1.0f, 8); } - ImGui::PopID(); } } + // Horiziontal value lines + + // uint32 LineColor = IM_COL32(200, 200, 200, 40); + // for (int i = 0; i < 10; i++) { + // real32 YPos = MinPos.y + (UI->TimelineZoom/2 * i) + 5; + // ImVec2 Min = ImVec2(TimelineStartingPos.x, YPos); + // ImVec2 Max = ImVec2(TimelineStartingPos.x + TimelineSize.x, YPos); + // draw_list->AddLine(Min, Max, LineColor); + // } - ImGui::SetCursorPosY(ImGui::GetCursorPos().y - (ItemSpacing.y * UI->KeyframeSpacing / 2)); - ImGui::PopStyleVar(); + draw_list->PopClipRect(); - ImGui::PopID(); - } + // ImGui::SetCursorScreenPos(ImVec2(MinPos.x, MinPos.y)); + // ImGui::Button("##SplitMove", ImVec2(TimelineBorderPadding.x, SidebarSizeWithBorder.y)); + // if (ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) + // { + // UI->TimelineSplit += io.MouseDelta.x; + // } - // Timeline frame ticks + ImGui::SetCursorScreenPos(ImVec2(MinPos.x, MinPos.y)); + ImGui::InvisibleButton("AnimationCurves", ImVec2(TimelineSize.x - 20, GraphWindowHeight), ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight); + // NOTE(fox): I'm reusing this struct for the other + // channels, so I'm OR'ing it. Also persists across layers. + AnimationCurves.IsItemHovered |= ImGui::IsItemHovered(); + AnimationCurves.IsItemActive |= ImGui::IsItemActive(); + AnimationCurves.IsItemActivated |= ImGui::IsItemActivated(); + AnimationCurves.IsItemDeactivated |= ImGui::IsItemDeactivated(); + AnimationCurves.LeftClick |= ImGui::IsMouseDown(ImGuiMouseButton_Left); + AnimationCurves.RightClick |= ImGui::IsMouseDown(ImGuiMouseButton_Right); + + if (AnimationCurves.IsItemHovered && AnimationCurves.IsItemActivated && + ImGui::IsMouseDown(ImGuiMouseButton_Right)) { + real32 LocalMousePos = io.MousePos.y - MinPos.y - Property->GraphYOffset; + UI->TempZoomRatioGraph = LocalMousePos / Property->GraphLength; + } + // DebugWatchVar("LocalMousePos", &LocalMousePos, d_float); - ImGui::SetCursorScreenPos(TimelineStartingPos); - if (UI->TimelineZoom > 10) { - for (float x = 0; x < File->NumberOfFrames + 2; x += 1) { - uint32 LineColor = IM_COL32(200, 200, 200, 40); - ImVec2 Min = ImVec2(TimelineStartingPos.x + UI->TimelineZoom * x, TimelineStartingPos.y); - ImVec2 Max = ImVec2(Min.x + 2, WindowMaxAbs.y); - if (x == File->CurrentFrame) continue; - draw_list->AddLine(Min, Max, LineColor); + if (AnimationCurves.IsItemActive && ImGui::IsMouseDragging(ImGuiMouseButton_Right, -1)) + { + Property->GraphLength += io.MouseDelta.x; + Property->GraphYOffset -= io.MouseDelta.x*UI->TempZoomRatioGraph; + Property->GraphYOffset += io.MouseDelta.y; } + */ } - draw_list->PopClipRect(); - ImGui::PopClipRect(); - // Playhead line uint32 LineColor = IM_COL32(200, 200, 200, 200); @@ -1596,9 +1608,9 @@ ImGui_ProcessInputs(project_data *File, project_state *State, comp_buffer *CompB if (ImGui::IsKeyPressed(ImGuiKey_Z)) { if (io.KeyCtrl && io.KeyShift) { - Action_Redo(Memory); + History_Redo(Memory); } else if (io.KeyCtrl) { - Action_Undo(Memory); + History_Undo(Memory); } State->UpdateFrame = true; State->UpdateKeyframes = true; @@ -1734,39 +1746,39 @@ ImGui_ProcessInputs(project_data *File, project_state *State, comp_buffer *CompB State->UpdateFrame = true; } if (ImGui::IsMouseDown(ImGuiMouseButton_Left)) { - Action_Entry_Commit(Memory, action_entry_default, "Tranforms interact"); + History_Entry_Commit(Memory, action_entry_default, "Tranforms interact"); switch (State->TransformsHotkeyInteract) { case sliding_position: { - Action_Change_Commit(Memory, &Layer->x.CurrentValue.f, &State->InteractCache[0], - &Layer->x.CurrentValue.f, action_change_r32); - Action_Change_Commit(Memory, &Layer->y.CurrentValue.f, &State->InteractCache[1], - &Layer->y.CurrentValue.f, action_change_r32); + History_Action_Change(Memory, &Layer->x.CurrentValue.f, &State->InteractCache[0], + &Layer->x.CurrentValue.f, action_type_change_r32); + History_Action_Change(Memory, &Layer->y.CurrentValue.f, &State->InteractCache[1], + &Layer->y.CurrentValue.f, action_type_change_r32); } break; case sliding_anchorpoint: { - Action_Change_Commit(Memory, &Layer->x.CurrentValue.f, &State->InteractCache[0], - &Layer->x.CurrentValue.f, action_change_r32); - Action_Change_Commit(Memory, &Layer->y.CurrentValue.f, &State->InteractCache[1], - &Layer->y.CurrentValue.f, action_change_r32); - Action_Change_Commit(Memory, &Layer->ax.CurrentValue.f, &State->InteractCache[2], - &Layer->ax.CurrentValue.f, action_change_r32); - Action_Change_Commit(Memory, &Layer->ay.CurrentValue.f, &State->InteractCache[3], - &Layer->ay.CurrentValue.f, action_change_r32); + History_Action_Change(Memory, &Layer->x.CurrentValue.f, &State->InteractCache[0], + &Layer->x.CurrentValue.f, action_type_change_r32); + History_Action_Change(Memory, &Layer->y.CurrentValue.f, &State->InteractCache[1], + &Layer->y.CurrentValue.f, action_type_change_r32); + History_Action_Change(Memory, &Layer->ax.CurrentValue.f, &State->InteractCache[2], + &Layer->ax.CurrentValue.f, action_type_change_r32); + History_Action_Change(Memory, &Layer->ay.CurrentValue.f, &State->InteractCache[3], + &Layer->ay.CurrentValue.f, action_type_change_r32); } break; case sliding_rotation: { - Action_Change_Commit(Memory, &Layer->rotation.CurrentValue.f, &State->InteractCache[0], - &Layer->rotation.CurrentValue.f, action_change_r32); + History_Action_Change(Memory, &Layer->rotation.CurrentValue.f, &State->InteractCache[0], + &Layer->rotation.CurrentValue.f, action_type_change_r32); } break; case sliding_scale: { - Action_Change_Commit(Memory, &Layer->scale.CurrentValue.f, &State->InteractCache[0], - &Layer->scale.CurrentValue.f, action_change_r32); + History_Action_Change(Memory, &Layer->scale.CurrentValue.f, &State->InteractCache[0], + &Layer->scale.CurrentValue.f, action_type_change_r32); } break; } - Action_Entry_End(Memory); + History_Entry_End(Memory); State->IsInteracting = false; } State->UpdateFrame = true; -- cgit v1.2.3