// Copyright Epic Games, Inc. All Rights Reserved. #include "CameraCropSettingsCustomization.h" #include "PropertyHandle.h" #include "IDetailChildrenBuilder.h" #include "DetailWidgetRow.h" #include "DetailLayoutBuilder.h" #include "ScopedTransaction.h" #include "CineCameraSettings.h" #define LOCTEXT_NAMESPACE "CameraCropSettingsCustomization" FCameraCropSettingsCustomization::FCameraCropSettingsCustomization() { TArray const& Presets = UCineCameraSettings::GetCropPresets(); int32 const NumPresets = Presets.Num(); // first create preset combo list PresetComboList.Empty(NumPresets + 1); // put all presets in the list for (FNamedPlateCropPreset const& P : Presets) { PresetComboList.Add(MakeShareable(new FString(P.Name))); } PresetComboList.Add(MakeShareable(new FString(TEXT("Custom...")))); } TSharedRef FCameraCropSettingsCustomization::MakeInstance() { return MakeShareable(new FCameraCropSettingsCustomization); } void FCameraCropSettingsCustomization::CustomizeHeader(TSharedRef StructPropertyHandle, FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& CustomizationUtils) { // We only want the dropdown list outside of the settings class as the settings class is the thing // defining the presets we use for the dropdown const bool bInSettingsClass = StructPropertyHandle->GetOuterBaseClass() == UCineCameraSettings::StaticClass(); if (!bInSettingsClass) { HeaderRow. NameContent() [ StructPropertyHandle->CreatePropertyNameWidget() ] .ValueContent() .MaxDesiredWidth(0.f) [ SAssignNew(PresetComboBox, SComboBox< TSharedPtr >) .OptionsSource(&PresetComboList) .OnGenerateWidget(this, &FCameraCropSettingsCustomization::MakePresetComboWidget) .OnSelectionChanged(this, &FCameraCropSettingsCustomization::OnPresetChanged) .IsEnabled(FSlateApplication::Get().GetNormalExecutionAttribute()) .ContentPadding(2.f) .Content() [ SNew(STextBlock) .Text(this, &FCameraCropSettingsCustomization::GetPresetComboBoxContent) .Font(IDetailLayoutBuilder::GetDetailFont()) .ToolTipText(this, &FCameraCropSettingsCustomization::GetPresetComboBoxContent) ] ]; } } void FCameraCropSettingsCustomization::CustomizeChildren(TSharedRef StructPropertyHandle, class IDetailChildrenBuilder& ChildBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils) { // Retrieve structure's child properties uint32 NumChildren; StructPropertyHandle->GetNumChildren(NumChildren); TMap > PropertyHandles; for (uint32 ChildIndex = 0; ChildIndex < NumChildren; ++ChildIndex) { TSharedRef ChildHandle = StructPropertyHandle->GetChildHandle(ChildIndex).ToSharedRef(); const FName PropertyName = ChildHandle->GetProperty()->GetFName(); PropertyHandles.Add(PropertyName, ChildHandle); } // Retrieve special case properties AspectRatioHandle = PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FPlateCropSettings, AspectRatio)); for (auto Iter(PropertyHandles.CreateConstIterator()); Iter; ++Iter) { IDetailPropertyRow& SettingsRow = ChildBuilder.AddProperty(Iter.Value().ToSharedRef()); } } TSharedRef FCameraCropSettingsCustomization::MakePresetComboWidget(TSharedPtr InItem) { return SNew(STextBlock) .Text(FText::FromString(*InItem)) .Font(IDetailLayoutBuilder::GetDetailFont()); } void FCameraCropSettingsCustomization::OnPresetChanged(TSharedPtr NewSelection, ESelectInfo::Type SelectInfo) { // if it's set from code, we did that on purpose if (SelectInfo != ESelectInfo::Direct) { FString const NewPresetName = *NewSelection.Get(); // search presets for one that matches TArray const& Presets = UCineCameraSettings::GetCropPresets(); int32 const NumPresets = Presets.Num(); for (int32 PresetIdx = 0; PresetIdx < NumPresets; ++PresetIdx) { FNamedPlateCropPreset const& P = Presets[PresetIdx]; if (P.Name == NewPresetName) { const FScopedTransaction Transaction(LOCTEXT("ChangeCropPreset", "Change Crop Preset")); // copy data from preset into properties // all SetValues except the last set to Interactive so we don't rerun construction scripts and invalidate subsequent property handles ensure(AspectRatioHandle->SetValue(P.CropSettings.AspectRatio, EPropertyValueSetFlags::InteractiveChange | EPropertyValueSetFlags::NotTransactable) == FPropertyAccess::Result::Success); break; } } // if none of them found, do nothing } } FText FCameraCropSettingsCustomization::GetPresetComboBoxContent() const { return FText::FromString(*GetPresetString().Get()); } TSharedPtr FCameraCropSettingsCustomization::GetPresetString() const { float AspectRatio; AspectRatioHandle->GetValue(AspectRatio); // search presets for one that matches TArray const& Presets = UCineCameraSettings::GetCropPresets(); int32 const NumPresets = Presets.Num(); for (int32 PresetIdx = 0; PresetIdx < NumPresets; ++PresetIdx) { FNamedPlateCropPreset const& P = Presets[PresetIdx]; if (P.CropSettings.AspectRatio == AspectRatio) { // this is the one if (PresetComboList.IsValidIndex(PresetIdx)) { return PresetComboList[PresetIdx]; } } } return PresetComboList.Last(); } #undef LOCTEXT_NAMESPACE // CameraCropSettingsCustomization