376 lines
11 KiB
C++
376 lines
11 KiB
C++
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2016.
|
|
|
|
#include "FMODStudioEditorPrivatePCH.h"
|
|
#include "SFMODEventEditorPanel.h"
|
|
#include "FMODStudioModule.h"
|
|
#include "FMODUtils.h"
|
|
#include "Input/Reply.h"
|
|
#include "SNumericEntryBox.h"
|
|
#include "SExpandableArea.h"
|
|
#include "fmod_studio.hpp"
|
|
|
|
#define LOCTEXT_NAMESPACE "FMODEventEditor"
|
|
|
|
SFMODEventEditorPanel::~SFMODEventEditorPanel()
|
|
{
|
|
}
|
|
|
|
void SFMODEventEditorPanel::Construct(const FArguments& InArgs)
|
|
{
|
|
FMODEventEditorPtr = InArgs._FMODEventEditor;
|
|
|
|
FMOD::Studio::EventDescription* EventDescription = FMODEventEditorPtr.Pin()->GetEventDescription();
|
|
|
|
TSharedRef<SBorder> ToolbarBorder = ConstructToolbar(EventDescription);
|
|
TSharedRef<SExpandableArea> InfoArea = ConstructInfo(EventDescription);
|
|
TSharedRef<SExpandableArea> ParametersArea = ConstructParameters(EventDescription);
|
|
TSharedRef<SExpandableArea> UserPropertiesArea = ConstructUserProperties(EventDescription);
|
|
|
|
TSharedRef<SVerticalBox> ChildWidget =
|
|
SNew(SVerticalBox)
|
|
+ SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
.Padding(0.0f, 3.0f)
|
|
[
|
|
InfoArea
|
|
]
|
|
+ SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
.Padding(0.0f, 3.0f)
|
|
[
|
|
ParametersArea
|
|
]
|
|
+ SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
.Padding(0.0f, 3.0f)
|
|
[
|
|
UserPropertiesArea
|
|
];
|
|
|
|
ChildSlot
|
|
[
|
|
SNew(SVerticalBox)
|
|
+ SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
.Padding(0.0f, 3.0f)
|
|
[
|
|
ToolbarBorder
|
|
]
|
|
+ SVerticalBox::Slot()
|
|
.FillHeight(1.0f)
|
|
[
|
|
SNew(SScrollBox)
|
|
+ SScrollBox::Slot()
|
|
.Padding(0.0f)
|
|
[
|
|
SNew(SVerticalBox)
|
|
+ SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
.Padding(0.0f)
|
|
[
|
|
ChildWidget
|
|
]
|
|
]
|
|
]
|
|
];
|
|
}
|
|
|
|
TSharedRef<SBorder> SFMODEventEditorPanel::ConstructToolbar(FMOD::Studio::EventDescription* EventDescription)
|
|
{
|
|
float MinDistance = 0.0f;
|
|
float MaxDistance = 0.0f;
|
|
int32 EventLengthMS = 0;
|
|
bool bIsOneshot = false, bIsStream = false, bIs3D = false;
|
|
if (EventDescription != nullptr)
|
|
{
|
|
EventDescription->getMinimumDistance(&MinDistance);
|
|
EventDescription->getMaximumDistance(&MaxDistance);
|
|
EventDescription->getLength(&EventLengthMS);
|
|
EventDescription->isOneshot(&bIsOneshot);
|
|
EventDescription->isStream(&bIsStream);
|
|
EventDescription->is3D(&bIs3D);
|
|
}
|
|
|
|
const FTimespan EventLength = FTimespan::FromMilliseconds((double)EventLengthMS);
|
|
const FString EventLengthString = EventLength.GetHours() <= 0 ? EventLength.ToString(TEXT("%m:%s.%f")) : EventLength.ToString(TEXT("%h:%m:%s.%f"));
|
|
|
|
const FText RadiusText = FText::Format(LOCTEXT("RadiusFormat", "Distance Attenuation: {0}m to {1}m"), FText::AsNumber(MinDistance), FText::AsNumber(MaxDistance));
|
|
const FText LengthText = FText::Format(LOCTEXT("LengthFormat", "Length: {0}"), FText::FromString(EventLengthString));
|
|
|
|
FText EventInfoText;
|
|
if (bIs3D && bIsOneshot)
|
|
{
|
|
EventInfoText = FText::Format(LOCTEXT("RadiusLengthFormat", "{0} - {1}"), RadiusText, LengthText);
|
|
}
|
|
else if (!bIs3D && bIsOneshot)
|
|
{
|
|
EventInfoText = LengthText;
|
|
}
|
|
else if (bIs3D && !bIsOneshot)
|
|
{
|
|
EventInfoText = RadiusText;
|
|
}
|
|
|
|
return SNew(SBorder)
|
|
.BorderImage(FEditorStyle::Get().GetBrush("ToolPanel.GroupBorder"))
|
|
.Padding(6.0f)
|
|
.Content()
|
|
[
|
|
SNew(SHorizontalBox)
|
|
+ SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.Padding(0.0f, 0.0f, 2.0f, 0.0f)
|
|
.VAlign(VAlign_Center)
|
|
.HAlign(HAlign_Left)
|
|
[
|
|
SNew(SButton)
|
|
.VAlign(VAlign_Center)
|
|
.Text(LOCTEXT("Play", "Play"))
|
|
.ContentPadding(4)
|
|
.OnClicked(this, &SFMODEventEditorPanel::OnClickedPlay)
|
|
]
|
|
+ SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.Padding(2.0f, 0.0f)
|
|
.VAlign(VAlign_Center)
|
|
.HAlign(HAlign_Left)
|
|
[
|
|
SNew(SButton)
|
|
.Text(LOCTEXT("Pause", "Pause"))
|
|
.ContentPadding(4)
|
|
.OnClicked(this, &SFMODEventEditorPanel::OnClickedPause)
|
|
]
|
|
+ SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.Padding(2.0f, 0.0f)
|
|
.VAlign(VAlign_Center)
|
|
.HAlign(HAlign_Left)
|
|
[
|
|
SNew(SButton)
|
|
.VAlign(VAlign_Center)
|
|
.Text(LOCTEXT("Stop", "Stop"))
|
|
.ContentPadding(4)
|
|
.OnClicked(this, &SFMODEventEditorPanel::OnClickedStop)
|
|
]
|
|
+ SHorizontalBox::Slot()
|
|
.FillWidth(1.0f)
|
|
.Padding(2.0f, 0.0f)
|
|
.VAlign(VAlign_Center)
|
|
.HAlign(HAlign_Right)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(EventInfoText)
|
|
]
|
|
];
|
|
}
|
|
|
|
void AddTextField(TSharedRef<SVerticalBox>& InfoBox, const TCHAR* Name, const FText& Value)
|
|
{
|
|
InfoBox->AddSlot()
|
|
.Padding(4.0f, 3.0f)
|
|
[
|
|
SNew(SHorizontalBox)
|
|
+ SHorizontalBox::Slot()
|
|
.FillWidth(0.3f)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(FText::FromString(Name))
|
|
]
|
|
+ SHorizontalBox::Slot()
|
|
[
|
|
SNew(SEditableText)
|
|
.Text(Value)
|
|
.IsReadOnly(true)
|
|
]
|
|
];
|
|
}
|
|
|
|
void AddBoolField(TSharedRef<SVerticalBox>& InfoBox, const TCHAR* Name, bool bValue)
|
|
{
|
|
AddTextField(InfoBox, Name, bValue ? LOCTEXT("True","True") : LOCTEXT("False","False"));
|
|
}
|
|
|
|
void AddFloatField(TSharedRef<SVerticalBox>& InfoBox, const TCHAR* Name, float Value)
|
|
{
|
|
AddTextField(InfoBox, Name, FText::AsNumber(Value));
|
|
}
|
|
|
|
TSharedRef<SExpandableArea> MakeBox(TSharedRef<SVerticalBox>& InfoBox, const FText& Value)
|
|
{
|
|
return SNew(SExpandableArea)
|
|
.AreaTitle(Value)
|
|
.InitiallyCollapsed(false)
|
|
.BodyContent()
|
|
[
|
|
SNew(SBorder)
|
|
.BorderImage(FCoreStyle::Get().GetBrush("NoBorder"))
|
|
.Padding(4.0f)
|
|
.Content()
|
|
[
|
|
InfoBox
|
|
]
|
|
];
|
|
}
|
|
|
|
TSharedRef<SExpandableArea> SFMODEventEditorPanel::ConstructInfo(FMOD::Studio::EventDescription* EventDescription)
|
|
{
|
|
TSharedRef<SVerticalBox> InfoBox = SNew(SVerticalBox);
|
|
|
|
if (EventDescription != nullptr)
|
|
{
|
|
FString EventPath = FMODUtils::GetPath(EventDescription);
|
|
FGuid Guid = FMODUtils::GetID(EventDescription);
|
|
|
|
int Length = 0.0f;
|
|
float MinDist = 0.0f;
|
|
float MaxDist = 0.0f;
|
|
EventDescription->getLength(&Length);
|
|
EventDescription->getMinimumDistance(&MinDist);
|
|
EventDescription->getMaximumDistance(&MaxDist);
|
|
|
|
bool bOneShot = false;
|
|
bool bStream = false;
|
|
bool b3D = false;
|
|
EventDescription->isOneshot(&bOneShot);
|
|
EventDescription->isStream(&bStream);
|
|
EventDescription->is3D(&b3D);
|
|
|
|
AddTextField(InfoBox, TEXT("Path"), FText::FromString(EventPath));
|
|
AddTextField(InfoBox, TEXT("Guid"), FText::FromString(Guid.ToString(EGuidFormats::DigitsWithHyphensInBraces)));
|
|
AddBoolField(InfoBox, TEXT("OneShot"), bOneShot);
|
|
AddBoolField(InfoBox, TEXT("Streaming"), bStream);
|
|
AddBoolField(InfoBox, TEXT("3D"), b3D);
|
|
|
|
AddFloatField(InfoBox, TEXT("Length"), static_cast<float>(Length));
|
|
if (b3D)
|
|
{
|
|
AddFloatField(InfoBox, TEXT("Min Dist"), MinDist);
|
|
AddFloatField(InfoBox, TEXT("Max Dist"), MaxDist);
|
|
}
|
|
}
|
|
|
|
return MakeBox(InfoBox, LOCTEXT("EventInfo", "Event Info"));
|
|
}
|
|
|
|
TSharedRef<SExpandableArea> SFMODEventEditorPanel::ConstructParameters(FMOD::Studio::EventDescription* EventDescription)
|
|
{
|
|
auto EventEditor = FMODEventEditorPtr.Pin();
|
|
TSharedRef<SVerticalBox> ParametersBox = SNew(SVerticalBox);
|
|
|
|
FNumberFormattingOptions Options;
|
|
Options.MinimumFractionalDigits = 1;
|
|
|
|
if (EventDescription != nullptr)
|
|
{
|
|
int32 ParameterCount;
|
|
EventDescription->getParameterCount(&ParameterCount);
|
|
for (int32 ParamIdx = 0; ParamIdx < ParameterCount; ParamIdx++)
|
|
{
|
|
FMOD_STUDIO_PARAMETER_DESCRIPTION Parameter;
|
|
EventDescription->getParameterByIndex(ParamIdx, &Parameter);
|
|
|
|
EventEditor->GetParameterValues().Add(Parameter.minimum);
|
|
|
|
const FString ParameterName = Parameter.type == FMOD_STUDIO_PARAMETER_GAME_CONTROLLED ? FString(UTF8_TO_TCHAR(Parameter.name)) : FMODUtils::ParameterTypeToString(Parameter.type);
|
|
const FText ToolTipText = FText::Format(LOCTEXT("ParameterTooltipFormat", "{0} (Min Value: {1} - Max Value: {2})"),
|
|
FText::FromString(ParameterName), FText::AsNumber(Parameter.minimum, &Options), FText::AsNumber(Parameter.maximum, &Options));
|
|
|
|
ParametersBox->AddSlot()
|
|
.Padding(4.0f, 2.0f)
|
|
[
|
|
SNew(SHorizontalBox)
|
|
.ToolTipText(ToolTipText)
|
|
+ SHorizontalBox::Slot()
|
|
.FillWidth(0.3f)
|
|
[
|
|
SNew(STextBlock)
|
|
.Text(FText::FromString(ParameterName))
|
|
]
|
|
+ SHorizontalBox::Slot()
|
|
.MaxWidth(200.0f)
|
|
[
|
|
SNew(SNumericEntryBox<float>)
|
|
.Value(this, &SFMODEventEditorPanel::GetParameterValue, ParamIdx)
|
|
.OnValueChanged(this, &SFMODEventEditorPanel::OnParameterValueChanged, ParamIdx)
|
|
.AllowSpin(true)
|
|
.MinValue(Parameter.minimum)
|
|
.MaxValue(Parameter.maximum)
|
|
.MinSliderValue(Parameter.minimum)
|
|
.MaxSliderValue(Parameter.maximum)
|
|
.Delta(0.01f)
|
|
]
|
|
];
|
|
}
|
|
}
|
|
|
|
return MakeBox(ParametersBox, LOCTEXT("EventParameters", "Event Parameters"));
|
|
}
|
|
|
|
TSharedRef<SExpandableArea> SFMODEventEditorPanel::ConstructUserProperties(FMOD::Studio::EventDescription* EventDescription)
|
|
{
|
|
TSharedRef<SVerticalBox> UserPropertiesBox = SNew(SVerticalBox);
|
|
|
|
if (EventDescription != nullptr)
|
|
{
|
|
int32 UserPropertyCount;
|
|
EventDescription->getUserPropertyCount(&UserPropertyCount);
|
|
for (int32 PropertyIdx = 0; PropertyIdx < UserPropertyCount; PropertyIdx++)
|
|
{
|
|
FMOD_STUDIO_USER_PROPERTY UserProperty;
|
|
EventDescription->getUserPropertyByIndex(PropertyIdx, &UserProperty);
|
|
|
|
FText PropertyText;
|
|
switch (UserProperty.type)
|
|
{
|
|
case FMOD_STUDIO_USER_PROPERTY_TYPE_INTEGER:
|
|
PropertyText = FText::AsNumber(UserProperty.intValue);
|
|
break;
|
|
case FMOD_STUDIO_USER_PROPERTY_TYPE_BOOLEAN:
|
|
PropertyText = UserProperty.boolValue ? LOCTEXT("True", "True") : LOCTEXT("False", "False");
|
|
break;
|
|
case FMOD_STUDIO_USER_PROPERTY_TYPE_FLOAT:
|
|
PropertyText = FText::AsNumber(UserProperty.floatValue);
|
|
break;
|
|
case FMOD_STUDIO_USER_PROPERTY_TYPE_STRING:
|
|
PropertyText = FText::FromString(UTF8_TO_TCHAR(UserProperty.stringValue));
|
|
break;
|
|
}
|
|
|
|
FString UserName(UTF8_TO_TCHAR(UserProperty.name));
|
|
AddTextField(UserPropertiesBox, *UserName, PropertyText);
|
|
}
|
|
}
|
|
|
|
return MakeBox(UserPropertiesBox, LOCTEXT("EventUserProperties", "Event User Properties"));
|
|
}
|
|
|
|
FReply SFMODEventEditorPanel::OnClickedPlay()
|
|
{
|
|
FMODEventEditorPtr.Pin()->PlayEvent();
|
|
return FReply::Handled();
|
|
}
|
|
|
|
FReply SFMODEventEditorPanel::OnClickedStop()
|
|
{
|
|
FMODEventEditorPtr.Pin()->StopEvent();
|
|
return FReply::Handled();
|
|
}
|
|
|
|
FReply SFMODEventEditorPanel::OnClickedPause()
|
|
{
|
|
FMODEventEditorPtr.Pin()->PauseEvent();
|
|
return FReply::Handled();
|
|
}
|
|
|
|
void SFMODEventEditorPanel::OnParameterValueChanged(float NewValue, int32 ParameterIdx)
|
|
{
|
|
FMODEventEditorPtr.Pin()->SetParameterValue(ParameterIdx, NewValue);
|
|
}
|
|
|
|
TOptional<float> SFMODEventEditorPanel::GetParameterValue(int32 ParameterIdx) const
|
|
{
|
|
return FMODEventEditorPtr.Pin()->GetParameterValues()[ParameterIdx];
|
|
}
|
|
|
|
#undef LOC_NAMESPACE
|