You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
New algorithm is in MovieScenCurveChannelImpl where we calculate auto tangents. Since they work off tangents and not key positons, need to make sure to recalc them if the tangent changes now. Since FRichCurve will not support these new auto tangents, they only do 2 key interps with the old auto key algorithm that doesn't average the tangents at all, had to add a SupportedTangentType to FCurveEditor so that we can use that with the curve editor context menu/commands/SCurveEditorPanel since they are all shared between Sequencer and the Curve Asset viewer. Most of the code is making sure we treat smart auto's the same as the old autos #jira UE-171811 #rb max.chen #preflight 6446d596dc71c13446fa361a [CL 25175842 by mike zyracki in ue5-main branch]
252 lines
9.4 KiB
C++
252 lines
9.4 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "CurveEditorContextMenu.h"
|
|
|
|
#include "Containers/Array.h"
|
|
#include "Containers/Set.h"
|
|
#include "CurveEditor.h"
|
|
#include "CurveEditorCommands.h"
|
|
#include "CurveEditorSelection.h"
|
|
#include "CurveEditorTypes.h"
|
|
#include "CurveModel.h"
|
|
#include "Delegates/Delegate.h"
|
|
#include "Framework/Commands/GenericCommands.h"
|
|
#include "Framework/MultiBox/MultiBoxBuilder.h"
|
|
#include "HAL/Platform.h"
|
|
#include "Internationalization/Internationalization.h"
|
|
#include "Internationalization/Text.h"
|
|
#include "Misc/Attribute.h"
|
|
#include "Templates/UniquePtr.h"
|
|
#include "UObject/UnrealNames.h"
|
|
|
|
class IBufferedCurveModel;
|
|
|
|
#define LOCTEXT_NAMESPACE "CurveEditorContextMenu"
|
|
|
|
void FCurveEditorContextMenu::BuildMenu(FMenuBuilder& MenuBuilder, TSharedRef<FCurveEditor> CurveEditor, TOptional<FCurvePointHandle> ClickedPoint, TOptional<FCurveModelID> HoveredCurveID)
|
|
{
|
|
int32 NumSelectedKeys = CurveEditor->GetSelection().Count();
|
|
|
|
TSharedPtr<FCurveEditor> LocalCurveEditor = CurveEditor->AsShared();
|
|
|
|
int32 NumActiveCurves = LocalCurveEditor->GetSelectionFromTreeAndKeys().Num();
|
|
|
|
int32 NumBufferedCurves = 0;
|
|
for (const TUniquePtr<IBufferedCurveModel>& BufferedCurve : LocalCurveEditor->GetBufferedCurves())
|
|
{
|
|
if (LocalCurveEditor->IsActiveBufferedCurve(BufferedCurve))
|
|
{
|
|
++NumBufferedCurves;
|
|
}
|
|
}
|
|
|
|
// We change the name to reflect the current number of curves selected.
|
|
TAttribute<FText> BufferedCurvesText = FText::Format(LOCTEXT("BufferCurvesContextMenu", "Buffer {0} Curves"), NumActiveCurves);
|
|
TAttribute<FText> SwapBufferedCurvesText = FText::Format(LOCTEXT("SwapBufferedCurvesContextMenu", "Swap {0} Buffered Curves onto {1} Selected Curves"), NumBufferedCurves, NumActiveCurves);
|
|
TAttribute<FText> ApplyBufferedCurvesText = FText::Format(LOCTEXT("ApplyBufferedCurvesContextMenu", "Apply {0} Buffered Curves onto {1} Selected Curves"), NumBufferedCurves, NumActiveCurves);
|
|
|
|
const FCurveModel* HoveredCurve = HoveredCurveID.IsSet() ? CurveEditor->FindCurve(HoveredCurveID.GetValue()) : nullptr;
|
|
|
|
// We prioritize key selections over curve selections to reduce the pixel-perfectness needed
|
|
// to edit the keys (which is more common than curves). Right clicking on a key or an empty space
|
|
// should show the key menu, otherwise we show the curve menu (ie: right clicking on a curve, not
|
|
// directly over a key).
|
|
if (NumSelectedKeys > 0 && (!HoveredCurveID.IsSet() || ClickedPoint.IsSet()))
|
|
{
|
|
MenuBuilder.BeginSection("CurveEditorKeySection", FText::Format(LOCTEXT("CurveEditorKeySection", "{0} Selected {0}|plural(one=Key,other=Keys)"), NumSelectedKeys));
|
|
{
|
|
bool bIsReadOnly = false;
|
|
if (HoveredCurve)
|
|
{
|
|
bIsReadOnly = HoveredCurve->IsReadOnly();
|
|
}
|
|
else
|
|
{
|
|
if (ClickedPoint.IsSet())
|
|
{
|
|
if (FCurveModel* ClickedPointCurve = CurveEditor->FindCurve(ClickedPoint->CurveID))
|
|
{
|
|
bIsReadOnly = ClickedPointCurve->IsReadOnly();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!bIsReadOnly)
|
|
{
|
|
// Modify Data
|
|
MenuBuilder.AddMenuEntry(FGenericCommands::Get().Cut);
|
|
MenuBuilder.AddMenuEntry(FGenericCommands::Get().Paste);
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().PasteOverwriteRange);
|
|
MenuBuilder.AddMenuEntry(FGenericCommands::Get().Copy);
|
|
MenuBuilder.AddMenuEntry(FGenericCommands::Get().Delete);
|
|
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().FlattenTangents);
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().StraightenTangents);
|
|
|
|
MenuBuilder.AddMenuSeparator();
|
|
|
|
// Tangent Types
|
|
int32 SupportedTangentTypes = CurveEditor->GetSupportedTangentTypes();
|
|
if (SupportedTangentTypes & (int32)ECurveEditorTangentTypes::InterpolationCubicSmartAuto)
|
|
{
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().InterpolationCubicSmartAuto);
|
|
};
|
|
if (SupportedTangentTypes & (int32)ECurveEditorTangentTypes::InterpolationCubicAuto)
|
|
{
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().InterpolationCubicAuto);
|
|
};
|
|
if (SupportedTangentTypes & (int32)ECurveEditorTangentTypes::InterpolationCubicUser)
|
|
{
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().InterpolationCubicUser);
|
|
}
|
|
if (SupportedTangentTypes & (int32)ECurveEditorTangentTypes::InterpolationCubicBreak)
|
|
{
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().InterpolationCubicBreak);
|
|
}
|
|
if (SupportedTangentTypes & (int32)ECurveEditorTangentTypes::InterpolationLinear)
|
|
{
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().InterpolationLinear);
|
|
}
|
|
if (SupportedTangentTypes & (int32)ECurveEditorTangentTypes::InterpolationConstant)
|
|
{
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().InterpolationConstant);
|
|
}
|
|
if (SupportedTangentTypes & (int32)ECurveEditorTangentTypes::InterpolationCubicWeighted)
|
|
{
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().InterpolationToggleWeighted);
|
|
}
|
|
|
|
MenuBuilder.AddMenuSeparator();
|
|
}
|
|
|
|
// Buffer Curves
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().BufferVisibleCurves, NAME_None, BufferedCurvesText);
|
|
if (!bIsReadOnly)
|
|
{
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().SwapBufferedCurves, NAME_None, SwapBufferedCurvesText);
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().ApplyBufferedCurves, NAME_None, ApplyBufferedCurvesText);
|
|
}
|
|
MenuBuilder.AddSeparator();
|
|
|
|
// Select
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().SelectAllKeys);
|
|
|
|
// Filters
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().OpenUserImplementableFilterWindow);
|
|
|
|
// View
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().ZoomToFit);
|
|
}
|
|
MenuBuilder.EndSection();
|
|
}
|
|
else
|
|
{
|
|
// Test if at least one curve is editable
|
|
bool bIsReadOnly = true;
|
|
TSet<FCurveModelID> CurvesToAddTo;
|
|
for(const FCurveModelID& CurveModelID : CurveEditor->GetEditedCurves())
|
|
{
|
|
if (const FCurveModel* CurveModel = CurveEditor->FindCurve(CurveModelID))
|
|
{
|
|
if (!CurveModel->IsReadOnly())
|
|
{
|
|
bIsReadOnly = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (HoveredCurve)
|
|
{
|
|
MenuBuilder.BeginSection("CurveEditorCurveSection", FText::Format(LOCTEXT("CurveNameFormat", "Curve '{0}'"), HoveredCurve->GetLongDisplayName()));
|
|
{
|
|
// Modify Curve
|
|
if (!HoveredCurve->IsReadOnly())
|
|
{
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().AddKeyHovered);
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().PasteKeysHovered);
|
|
|
|
MenuBuilder.AddMenuSeparator();
|
|
|
|
MenuBuilder.AddSubMenu(LOCTEXT("PreInfinityText", "Pre-Infinity"), FText(), FNewMenuDelegate::CreateLambda(
|
|
[](FMenuBuilder& SubMenu)
|
|
{
|
|
SubMenu.AddMenuEntry(FCurveEditorCommands::Get().SetPreInfinityExtrapCycle);
|
|
SubMenu.AddMenuEntry(FCurveEditorCommands::Get().SetPreInfinityExtrapCycleWithOffset);
|
|
SubMenu.AddMenuEntry(FCurveEditorCommands::Get().SetPreInfinityExtrapOscillate);
|
|
SubMenu.AddMenuEntry(FCurveEditorCommands::Get().SetPreInfinityExtrapLinear);
|
|
SubMenu.AddMenuEntry(FCurveEditorCommands::Get().SetPreInfinityExtrapConstant);
|
|
})
|
|
);
|
|
|
|
MenuBuilder.AddSubMenu(LOCTEXT("PostInfinityText", "Post-Infinity"), FText(), FNewMenuDelegate::CreateLambda(
|
|
[](FMenuBuilder& SubMenu)
|
|
{
|
|
SubMenu.AddMenuEntry(FCurveEditorCommands::Get().SetPostInfinityExtrapCycle);
|
|
SubMenu.AddMenuEntry(FCurveEditorCommands::Get().SetPostInfinityExtrapCycleWithOffset);
|
|
SubMenu.AddMenuEntry(FCurveEditorCommands::Get().SetPostInfinityExtrapOscillate);
|
|
SubMenu.AddMenuEntry(FCurveEditorCommands::Get().SetPostInfinityExtrapLinear);
|
|
SubMenu.AddMenuEntry(FCurveEditorCommands::Get().SetPostInfinityExtrapConstant);
|
|
})
|
|
);
|
|
|
|
MenuBuilder.AddMenuSeparator();
|
|
|
|
// Buffer Curves
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().BufferVisibleCurves, NAME_None, BufferedCurvesText);
|
|
if (!bIsReadOnly)
|
|
{
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().SwapBufferedCurves, NAME_None, SwapBufferedCurvesText);
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().ApplyBufferedCurves, NAME_None, ApplyBufferedCurvesText);
|
|
}
|
|
MenuBuilder.AddSeparator();
|
|
}
|
|
|
|
// Select
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().SelectAllKeys);
|
|
|
|
// Filters
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().OpenUserImplementableFilterWindow);
|
|
|
|
// View
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().ZoomToFit);
|
|
}
|
|
MenuBuilder.EndSection();
|
|
}
|
|
else
|
|
{
|
|
MenuBuilder.BeginSection("CurveEditorAllCurveSections", LOCTEXT("CurveEditorAllCurveSections", "All Curves"));
|
|
{
|
|
if (!bIsReadOnly)
|
|
{
|
|
// Modify Curves
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().AddKeyToAllCurves);
|
|
|
|
MenuBuilder.AddSeparator();
|
|
|
|
// Buffer Curves
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().BufferVisibleCurves, NAME_None, BufferedCurvesText);
|
|
if (!bIsReadOnly)
|
|
{
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().SwapBufferedCurves, NAME_None, SwapBufferedCurvesText);
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().ApplyBufferedCurves, NAME_None, ApplyBufferedCurvesText);
|
|
}
|
|
MenuBuilder.AddSeparator();
|
|
}
|
|
|
|
// Select
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().SelectAllKeys);
|
|
|
|
// Filters
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().OpenUserImplementableFilterWindow);
|
|
|
|
// View
|
|
MenuBuilder.AddMenuEntry(FCurveEditorCommands::Get().ZoomToFit);
|
|
}
|
|
MenuBuilder.EndSection();
|
|
}
|
|
}
|
|
}
|
|
|
|
#undef LOCTEXT_NAMESPACE
|