Skip to content

Commit

Permalink
sequencer Keyframe selection & copy'n'paste
Browse files Browse the repository at this point in the history
  • Loading branch information
Panakotta00 committed Apr 6, 2023
1 parent e6cb31a commit 61fdc7d
Show file tree
Hide file tree
Showing 14 changed files with 151 additions and 24 deletions.
4 changes: 4 additions & 0 deletions Source/FicsItCam/Private/Data/Attributes/FICAttributeBool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ FICValue FFICAttributeBool::GetFloatValue(FICFrameFloat Time) {
return GetValue(Time) ? 1.0f : 0.0f;
}

bool FFICAttributeBool::HasKeyframe(FICFrame Time) const {
return Keyframes.Contains(Time);
}

void FFICAttributeBool::Set(TSharedRef<FFICAttribute> InAttrib) {
FOnUpdate OnUpdateBuf = OnUpdate;
if (InAttrib->GetAttributeType() == GetAttributeType()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ FICValue FFICFloatAttribute::GetFloatValue(FICFrameFloat Time) {
return GetValue(Time);
}

bool FFICFloatAttribute::HasKeyframe(FICFrame Time) const {
return Keyframes.Contains(Time);
}

void FFICFloatAttribute::Set(TSharedRef<FFICAttribute> InAttrib) {
FOnUpdate OnUpdateBuf = OnUpdate;
if (InAttrib->GetAttributeType() == GetAttributeType()) {
Expand Down
11 changes: 11 additions & 0 deletions Source/FicsItCam/Private/Data/Attributes/FICAttributeGroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ void FFICGroupAttribute::RecalculateKeyframe(FICFrame Time) {
}
}

bool FFICGroupAttribute::HasKeyframe(FICFrame Time) const {
for (TTuple<FString, FFICAttribute*> Child : Children) {
if (Child.Value->HasKeyframe(Time)) return true;
}
return false;
}

void FFICGroupAttribute::Set(TSharedRef<FFICAttribute> InAttrib) {
TSharedRef<FFICGroupAttribute> Attrib = StaticCastSharedRef<FFICGroupAttribute>(InAttrib);
for (const TPair<FString, FFICAttribute*>& Attr : Children) {
Expand All @@ -77,6 +84,10 @@ TSharedRef<FFICEditorAttributeBase> FFICGroupAttribute::CreateEditorAttribute()
return MakeShared<FFICEditorAttributeGroup>(*this);
}

const TMap<FString, FFICAttribute*>& FFICGroupAttribute::GetChildAttributes() const {
return Children;
}

void FFICGroupAttribute::AddChildAttribute(FString Name, FFICAttribute* Attribute) {
Children.Add(Name, Attribute);
UpdateDelegateHandles.Add(Name, Attribute->OnUpdate.AddLambda([this]() {
Expand Down
32 changes: 32 additions & 0 deletions Source/FicsItCam/Private/Editor/UI/FICSequencer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,38 @@ FReply SFICSequencer::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& In
}
SelectionManager.SetSelection({});
return FReply::Handled();
} else if (InKeyEvent.GetKey() == EKeys::C && InKeyEvent.GetModifierKeys().IsControlDown()) {
CopiedKeyframes.Empty();
CopiedKeyframesSceneObject = FSoftObjectPtr(Context->GetSelectedSceneObject());
if (CopiedKeyframesSceneObject.IsValid()) {
FICFrame MaxFrame = TNumericLimits<FICFrame>::Min();
FICFrame MinFrame = TNumericLimits<FICFrame>::Max();
for (TTuple<FFICAttribute*, FICFrame> Keyframe : SelectionManager.GetSelection()) {
MaxFrame = FMath::Max(MaxFrame, Keyframe.Value);
MinFrame = FMath::Min(MinFrame, Keyframe.Value);
TSharedRef<FFICKeyframe> KF = Keyframe.Key->GetKeyframes()[Keyframe.Value];
CopiedKeyframes.Add(TTuple<FICFrame, FFICAttribute*, FFICKeyframeData>{Keyframe.Value, Keyframe.Key, KF->GetKeyframeData()});
}
FICFrame Offset = MinFrame + (MaxFrame - MinFrame)/2;
for (TTuple<FICFrame, FFICAttribute*, FFICKeyframeData>& Keyframe : CopiedKeyframes) {
Keyframe.Get<0>() -= Offset;
}
}
return FReply::Handled();
} else if (InKeyEvent.GetKey() == EKeys::V && InKeyEvent.GetModifierKeys().IsControlDown()) {
UObject* CopiedKeyframesFromSceneObject = CopiedKeyframesSceneObject.Get();
if (CopiedKeyframesFromSceneObject && CopiedKeyframesFromSceneObject == Context->GetSelectedSceneObject()) {
FICFrame Offset = Context->GetCurrentFrame();
SelectionManager.SetSelection({});
for (const TTuple<FICFrame, FFICAttribute*, FFICKeyframeData>& Keyframe : CopiedKeyframes) {
FICFrame Time = Keyframe.Get<0>() + Offset;
TSharedRef<FFICKeyframe> KF = Keyframe.Get<1>()->AddKeyframe(Time);
KF->SetKeyframeData(Keyframe.Get<2>());
SelectionManager.AddKeyframeToSelection(*Keyframe.Get<1>(), Time , false);
}
auto _ = SelectionManager.OnSelectionChanged.ExecuteIfBound();
}
return FReply::Handled();
}
return SPanel::OnKeyDown(MyGeometry, InKeyEvent);
}
Expand Down
10 changes: 9 additions & 1 deletion Source/FicsItCam/Private/Editor/UI/FICTimeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ void SFICTimelinePanel::Construct(const FArguments& InArgs, UFICEditorContext* I
+SGridPanel::Slot(1, 2)
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)[
SNew(SWidgetSwitcher)
SAssignNew(Switcher, SWidgetSwitcher)
.WidgetIndex_Lambda([this]() {
return Mode;
})
Expand Down Expand Up @@ -562,6 +562,14 @@ void SFICTimelinePanel::Tick(const FGeometry& AllottedGeometry, const double InC
SCompoundWidget::Tick(AllottedGeometry, InCurrentTime, InDeltaTime);
}

bool SFICTimelinePanel::SupportsKeyboardFocus() const {
return true;
}

FReply SFICTimelinePanel::OnFocusReceived(const FGeometry& MyGeometry, const FFocusEvent& InFocusEvent) {
return FReply::Handled().SetUserFocus(Switcher->GetActiveWidget().ToSharedRef());
}

void SFICTimelinePanel::UpdateEditorAttributes() {
Attributes.Empty();
for (TTuple<UObject*, TSharedRef<FFICEditorAttributeBase>> Attribute : Context->GetEditorAttributes()) {
Expand Down
42 changes: 36 additions & 6 deletions Source/FicsItCam/Private/Editor/UI/SelectionManager.cpp
Original file line number Diff line number Diff line change
@@ -1,27 +1,57 @@
#include "Editor/UI/SelectionManager.h"

#include "Data/Attributes/FICAttributeGroup.h"

const TSet<TPair<FFICAttribute*, int64>>& FSelectionManager::GetSelection() const {
return SelectedKeyframes;
}

void FSelectionManager::SetSelection(const TSet<TPair<FFICAttribute*, FICFrame>>& InSelection) {
SelectedKeyframes = InSelection;
SelectedKeyframes.Empty();
for (const TPair<FFICAttribute*, FICFrame>& Keyframe : InSelection) {
AddKeyframeToSelection(*Keyframe.Key, Keyframe.Value, false);
}
SelectedWithBox = SelectedKeyframes;
auto _ = OnSelectionChanged.ExecuteIfBound();
}

void FSelectionManager::AddKeyframeToSelection(FFICAttribute& InAttribute, FICFrame InFrame) {
SelectedKeyframes.Add(TPair<FFICAttribute*, FICFrame>(&InAttribute, InFrame));
auto _ = OnSelectionChanged.ExecuteIfBound();
void FSelectionManager::AddKeyframeToSelection(FFICAttribute& InAttribute, FICFrame InFrame, bool TriggerUpdate) {
const TMap<FString, FFICAttribute*>& Children = InAttribute.GetChildAttributes();
if (Children.Num() > 0) {
for (const TTuple<FString, FFICAttribute*>& Attr : Children) {
AddKeyframeToSelection(*Attr.Value, InFrame);
}
} else {
SelectedKeyframes.Add(TPair<FFICAttribute*, FICFrame>(&InAttribute, InFrame));
}
if (TriggerUpdate) auto _ = OnSelectionChanged.ExecuteIfBound();
}

void FSelectionManager::RemoveKeyframeFromSelection(FFICAttribute& InAttribute, FICFrame InFrame) {
SelectedKeyframes.Remove(TPair<FFICAttribute*, FICFrame>(&InAttribute, InFrame));
const TMap<FString, FFICAttribute*>& Children = InAttribute.GetChildAttributes();
if (Children.Num() > 0) {
for (const TTuple<FString, FFICAttribute*>& Attr : Children) {
RemoveKeyframeFromSelection(*Attr.Value, InFrame);
}
} else {
SelectedKeyframes.Remove(TPair<FFICAttribute*, FICFrame>(&InAttribute, InFrame));
}
auto _ = OnSelectionChanged.ExecuteIfBound();
}

bool FSelectionManager::IsKeyframeSelected(FFICAttribute& InAttribute, FICFrame InFrame) const {
return GetSelection().Contains(TPair<FFICAttribute*, FICFrame>(&InAttribute, InFrame));
const TMap<FString, FFICAttribute*>& Children = InAttribute.GetChildAttributes();
if (Children.Num() > 0) {
bool IsGroupSelected = true;
for (const TTuple<FString, FFICAttribute*>& Attr : Children) {
if (Attr.Value->HasKeyframe(InFrame)) {
IsGroupSelected = IsGroupSelected & IsKeyframeSelected(*Attr.Value, InFrame);
}
}
return IsGroupSelected;
} else {
return GetSelection().Contains(TPair<FFICAttribute*, FICFrame>(&InAttribute, InFrame));
}
}

void FSelectionManager::ToggleKeyframeSelection(FFICAttribute& InAttribute, FICFrame InFrame, const FModifierKeysState* InModifiers) {
Expand Down
6 changes: 6 additions & 0 deletions Source/FicsItCam/Public/Data/Attributes/FICAttribute.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,18 @@ struct FFICAttribute {
virtual void MoveKeyframe(FICFrame From, FICFrame To) { checkf(false, TEXT("Not Implemented!")); }
virtual void RecalculateKeyframe(FICFrame Time) { checkf(false, TEXT("Not Implemented!")); }
virtual FICValue GetFloatValue(FICFrameFloat Time) { checkf(false, TEXT("Not Implemented!")); return 0.0f; }
virtual bool HasKeyframe(FICFrame Time) const { checkf(false, TEXT("Not Implemented!")); return false; }

virtual void Set(TSharedRef<FFICAttribute> InAttrib) { checkf(false, TEXT("Not Implemented!")); }
virtual TSharedRef<FFICAttribute> Get() { checkf(false, TEXT("Not Implemented!")); return MakeShareable<FFICAttribute>(nullptr); }

virtual TSharedRef<FFICEditorAttributeBase> CreateEditorAttribute() { checkf(false, TEXT("Not Implemented!")); return MakeShareable<FFICEditorAttributeBase>(nullptr); }

virtual const TMap<FString, FFICAttribute*>& GetChildAttributes() const {
static TMap<FString, FFICAttribute*> Keyframes;
return Keyframes;
}

void RecalculateAllKeyframes();

// TODO: Use Binary-Search
Expand Down
11 changes: 6 additions & 5 deletions Source/FicsItCam/Public/Data/Attributes/FICAttributeBool.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ struct FFICKeyframeBool : public FFICKeyframe {

virtual FICValue GetValue() const override { return Value ? 1.0f : 0.0f; }
virtual void SetValue(FICValue InValue) override { Value = !FMath::IsNearlyZero(FMath::Clamp(InValue, 0.0f, 1.0f)); }
virtual FFICValueTimeFloat GetInControl() override { return FFICValueTimeFloat(0, 0); }
virtual FFICValueTimeFloat GetInControl() const override { return FFICValueTimeFloat(0, 0); }
virtual void SetInControl(const FFICValueTimeFloat& InInControl) override { }
virtual FFICValueTimeFloat GetOutControl() { return FFICValueTimeFloat(0, 0); }
virtual FFICValueTimeFloat GetOutControl() const { return FFICValueTimeFloat(0, 0); }
virtual void SetOutControl(const FFICValueTimeFloat& InOutControl) override { }
};

Expand Down Expand Up @@ -45,6 +45,7 @@ struct FFICAttributeBool : public FFICAttribute {
virtual void MoveKeyframe(FICFrame From, FICFrame To) override;
virtual void RecalculateKeyframe(FICFrame Time) override;
virtual FICValue GetFloatValue(FICFrameFloat Time) override;
virtual bool HasKeyframe(FICFrame Time) const override;

virtual void Set(TSharedRef<FFICAttribute> InAttrib) override;
virtual TSharedRef<FFICAttribute> Get() override;
Expand All @@ -71,18 +72,18 @@ class FFICKeyframeBoolTrampoline : public FFICKeyframe {

virtual FICValue GetValue() const override { return GetKeyframe()->GetValue(); }
virtual void SetValue(FICValue InValue) override { GetKeyframe()->SetValue(InValue); }
virtual FFICValueTimeFloat GetInControl() override {
virtual FFICValueTimeFloat GetInControl() const override {
return GetKeyframe()->GetInControl();
}
virtual void SetInControl(const FFICValueTimeFloat& InInControl) override {
GetKeyframe()->SetInControl(InInControl);
}
virtual FFICValueTimeFloat GetOutControl() {
virtual FFICValueTimeFloat GetOutControl() const {
return GetKeyframe()->GetOutControl();
}
virtual void SetOutControl(const FFICValueTimeFloat& InOutControl) override {
GetKeyframe()->SetOutControl(InOutControl);
}
virtual EFICKeyframeType GetType() override { return GetKeyframe()->GetType(); }
virtual EFICKeyframeType GetType() const override { return GetKeyframe()->GetType(); }
virtual void SetType(EFICKeyframeType InType) override { return GetKeyframe()->SetType(InType); }
};
11 changes: 6 additions & 5 deletions Source/FicsItCam/Public/Data/Attributes/FICAttributeFloat.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ struct FFICFloatKeyframe : public FFICKeyframe {

virtual FICValue GetValue() const override { return Value; }
virtual void SetValue(FICValue InValue) override { Value = InValue; }
virtual FFICValueTimeFloat GetInControl() override { return FFICValueTimeFloat(InTanTime, InTanValue); }
virtual FFICValueTimeFloat GetInControl() const override { return FFICValueTimeFloat(InTanTime, InTanValue); }
virtual void SetInControl(const FFICValueTimeFloat& InInControl) override { InTanTime = FMath::Max(InInControl.Frame, 0.f); InTanValue = InInControl.Value; }
virtual FFICValueTimeFloat GetOutControl() { return FFICValueTimeFloat(OutTanTime, OutTanValue); }
virtual FFICValueTimeFloat GetOutControl() const { return FFICValueTimeFloat(OutTanTime, OutTanValue); }
virtual void SetOutControl(const FFICValueTimeFloat& InOutControl) override { OutTanTime = FMath::Max(InOutControl.Frame, 0.f); OutTanValue = InOutControl.Value; }
};

Expand Down Expand Up @@ -62,6 +62,7 @@ struct FFICFloatAttribute : public FFICAttribute {
virtual void MoveKeyframe(FICFrame From, FICFrame To) override;
virtual void RecalculateKeyframe(FICFrame Time) override;
virtual FICValue GetFloatValue(FICFrameFloat Time) override;
virtual bool HasKeyframe(FICFrame Time) const override;

virtual void Set(TSharedRef<FFICAttribute> InAttrib) override;
virtual TSharedRef<FFICAttribute> Get() override;
Expand All @@ -88,18 +89,18 @@ class FFICFloatKeyframeTrampoline : public FFICKeyframe {

virtual FICValue GetValue() const override { return GetKeyframe()->GetValue(); }
virtual void SetValue(FICValue InValue) override { GetKeyframe()->SetValue(InValue); }
virtual FFICValueTimeFloat GetInControl() override {
virtual FFICValueTimeFloat GetInControl() const override {
return GetKeyframe()->GetInControl();
}
virtual void SetInControl(const FFICValueTimeFloat& InInControl) override {
GetKeyframe()->SetInControl(InInControl);
}
virtual FFICValueTimeFloat GetOutControl() {
virtual FFICValueTimeFloat GetOutControl() const {
return GetKeyframe()->GetOutControl();
}
virtual void SetOutControl(const FFICValueTimeFloat& InOutControl) override {
GetKeyframe()->SetOutControl(InOutControl);
}
virtual EFICKeyframeType GetType() override { return GetKeyframe()->GetType(); }
virtual EFICKeyframeType GetType() const override { return GetKeyframe()->GetType(); }
virtual void SetType(EFICKeyframeType InType) override { return GetKeyframe()->SetType(InType); }
};
9 changes: 6 additions & 3 deletions Source/FicsItCam/Public/Data/Attributes/FICAttributeGroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ struct FFICKeyframeGroup : public FFICKeyframe {
FFICKeyframeGroup(struct FFICGroupAttribute* InAttribute = nullptr, FICFrame InFrame = 0) : Attribute(InAttribute), Frame(InFrame) {}

virtual FICValue GetValue() const { return FICValue(); }
virtual FFICValueTimeFloat GetInControl() { return FFICValueTimeFloat(); }
virtual FFICValueTimeFloat GetOutControl() { return FFICValueTimeFloat(); }
virtual EFICKeyframeType GetType() { return EFICKeyframeType::FIC_KF_CUSTOM; }
virtual FFICValueTimeFloat GetInControl() const { return FFICValueTimeFloat(); }
virtual FFICValueTimeFloat GetOutControl() const { return FFICValueTimeFloat(); }
virtual EFICKeyframeType GetType() const { return EFICKeyframeType::FIC_KF_CUSTOM; }
virtual void SetValue(FICValue InValue) { }
virtual void SetInControl(const FFICValueTimeFloat& InInControl) { }
virtual void SetOutControl(const FFICValueTimeFloat& InOutControl) { }
Expand Down Expand Up @@ -49,11 +49,14 @@ struct FFICGroupAttribute : public FFICAttribute {
virtual void MoveKeyframe(FICFrame From, FICFrame To) override;
virtual void RecalculateKeyframe(FICFrame Time) override;
virtual FICValue GetFloatValue(FICFrameFloat Time) override { return 0.0f; }
virtual bool HasKeyframe(FICFrame Time) const override;

virtual void Set(TSharedRef<FFICAttribute> InAttrib) override;
virtual TSharedRef<FFICAttribute> Get() override;

virtual TSharedRef<FFICEditorAttributeBase> CreateEditorAttribute() override;

virtual const TMap<FString, FFICAttribute*>& GetChildAttributes() const override;
// End FFICAttribute

void AddChildAttribute(FString Name, FFICAttribute* Attribute);
Expand Down
27 changes: 24 additions & 3 deletions Source/FicsItCam/Public/Data/Attributes/FICKeyframe.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ enum EFICKeyframeType {
FIC_KF_ALL = 0b0111111,
};

USTRUCT()
struct FFICKeyframeData {
GENERATED_BODY()

FICValue Value;
FFICValueTimeFloat InControl;
FFICValueTimeFloat OutControl;
EFICKeyframeType Type;
};

USTRUCT(BlueprintType)
struct FFICKeyframe {
GENERATED_BODY()
Expand All @@ -30,14 +40,25 @@ struct FFICKeyframe {
* Intended to be used for attibute viewers like graph view.
*/
virtual FICValue GetValue() const { checkf(false, TEXT("Not Implemented!")); return FICValue(); }
virtual FFICValueTimeFloat GetInControl() { checkf(false, TEXT("Not Implemented!")); return FFICValueTimeFloat(); }
virtual FFICValueTimeFloat GetOutControl() { checkf(false, TEXT("Not Implemented!")); return FFICValueTimeFloat(); }
virtual EFICKeyframeType GetType() { return KeyframeType; }
virtual FFICValueTimeFloat GetInControl() const { checkf(false, TEXT("Not Implemented!")); return FFICValueTimeFloat(); }
virtual FFICValueTimeFloat GetOutControl() const { checkf(false, TEXT("Not Implemented!")); return FFICValueTimeFloat(); }
virtual EFICKeyframeType GetType() const { return KeyframeType; }
virtual void SetValue(FICValue InValue) { checkf(false, TEXT("Not Implemented!")); }
virtual void SetInControl(const FFICValueTimeFloat& InInControl) { checkf(false, TEXT("Not Implemented!")); }
virtual void SetOutControl(const FFICValueTimeFloat& InOutControl) { checkf(false, TEXT("Not Implemented!")); }
virtual void SetType(EFICKeyframeType Type) { KeyframeType = Type; }

FFICKeyframeData GetKeyframeData() const {
return FFICKeyframeData{GetValue(), GetInControl(), GetOutControl(), GetType()};
}

void SetKeyframeData(const FFICKeyframeData& Data) {
SetValue(Data.Value);
SetInControl(Data.InControl);
SetOutControl(Data.OutControl);
SetType(Data.Type);
}

UPROPERTY(SaveGame)
TEnumAsByte<EFICKeyframeType> KeyframeType = FIC_KF_EASE;
};
3 changes: 3 additions & 0 deletions Source/FicsItCam/Public/Editor/UI/FICSequencer.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ class SFICSequencer : public SPanel {
TMap<TSharedPtr<SFICSequencerRow>, TSharedPtr<FFICSequencerRowMeta>> WidgetToMeta;

FFICFrameRange OldFrameRange;

FSoftObjectPtr CopiedKeyframesSceneObject;
TArray<TTuple<FICFrame, FFICAttribute*, FFICKeyframeData>> CopiedKeyframes;

public:
UFICEditorContext* Context = nullptr;
Expand Down
3 changes: 3 additions & 0 deletions Source/FicsItCam/Public/Editor/UI/FICTimeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class SFICTimelinePanel : public SCompoundWidget {
TSharedPtr<SFICTimelineScrubber> Scrubber;
TSharedPtr<STreeView<TSharedPtr<FFICEditorAttributeReference>>> AttributeTree;
TSharedPtr<SFICGraphView> Graph;
TSharedPtr<SWidgetSwitcher> Switcher;

TSharedPtr<SFICSequencer> Sequencer;
TSharedPtr<SFICSequencerTreeView> SequencerTreeView;
Expand All @@ -100,6 +101,8 @@ class SFICTimelinePanel : public SCompoundWidget {

// Begin SWidget
virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override;
virtual bool SupportsKeyboardFocus() const override;
virtual FReply OnFocusReceived(const FGeometry& MyGeometry, const FFocusEvent& InFocusEvent) override;
// End SWidget

void UpdateEditorAttributes();
Expand Down
2 changes: 1 addition & 1 deletion Source/FicsItCam/Public/Editor/UI/SelectionManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class FSelectionManager {

const TSet<TPair<FFICAttribute*, int64>>& GetSelection() const;
void SetSelection(const TSet<TPair<FFICAttribute*, FICFrame>>& InSelection);
void AddKeyframeToSelection(FFICAttribute& InAttribute, FICFrame InFrame);
void AddKeyframeToSelection(FFICAttribute& InAttribute, FICFrame InFrame, bool TriggerUpdate = true);
void RemoveKeyframeFromSelection(FFICAttribute& InAttribute, FICFrame InFrame);
bool IsKeyframeSelected(FFICAttribute& InAttribute, FICFrame InFrame) const;
void ToggleKeyframeSelection(FFICAttribute& InAttribute, FICFrame InFrame, const FModifierKeysState* InModifiers = nullptr);
Expand Down

0 comments on commit 61fdc7d

Please sign in to comment.