haxis/Plugins/FMODStudio/Source/FMODStudioEditor/Private/SFMODEventEditorPanel.cpp

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