Files
Andron666 9c38e93fa4 part7
2022-12-05 20:31:35 +05:00

397 lines
12 KiB
C++

/*
* Copyright (c) <2021> Side Effects Software Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. The name of Side Effects Software may not be used to endorse or
* promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY SIDE EFFECTS SOFTWARE "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL SIDE EFFECTS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "HoudiniHandleDetails.h"
#include "HoudiniEngineRuntimePrivatePCH.h"
#include "HoudiniEngineEditorPrivatePCH.h"
#include "HoudiniHandleComponent.h"
#include "HoudiniHandleTranslator.h"
#include "HoudiniHandleComponentVisualizer.h"
#include "DetailCategoryBuilder.h"
#include "DetailWidgetRow.h"
#include "IDetailGroup.h"
#include "Widgets/Input/SVectorInputBox.h"
#include "Widgets/Input/SButton.h"
#include "Widgets/Images/SImage.h"
#include "UnrealEdGlobals.h"
#include "Editor/UnrealEdEngine.h"
#define LOCTEXT_NAMESPACE HOUDINI_LOCTEXT_NAMESPACE
void
FHoudiniHandleDetails::CreateWidget(IDetailCategoryBuilder & HouHandleCategory, TArray<UHoudiniHandleComponent*> &InHandles)
{
if (InHandles.Num() <= 0)
return;
UHoudiniHandleComponent* MainHandle = InHandles[0];
if (!MainHandle || MainHandle->IsPendingKill())
return;
FString HandleNameStr = MainHandle->GetHandleName() + TEXT(" (") + GetHandleTypeString(MainHandle->GetHandleType()) + TEXT(" )");
FName HandleName = FName(*HandleNameStr);
IDetailGroup& Group = HouHandleCategory.AddGroup(HandleName, FText::FromString(HandleNameStr), false, false);
// Create a widget row for this handle
FDetailWidgetRow& Row = Group.AddWidgetRow();
CreateNameWidget(Row);
// Create value widget
TSharedRef<SVerticalBox> ValueWidgetVerticalBox = SNew(SVerticalBox);
// Translate
auto OnLocationChangedLambda = [MainHandle](float Val, int32 Axis)
{
if (!MainHandle)
return;
FVector Location = MainHandle->GetRelativeTransform().GetLocation();
if (Axis == 0)
Location.X = Val;
else if (Axis == 1)
Location.Y = Val;
else
Location.Z = Val;
MainHandle->SetRelativeLocation(Location);
FHoudiniHandleTranslator::UpdateTransformParameters(MainHandle);
};
auto RevertLocationToDefault = [MainHandle]()
{
if (!MainHandle)
return FReply::Handled();
FVector DefaultLocation = FVector(0.f, 0.f, 0.f);
MainHandle->SetRelativeLocation(DefaultLocation);
FHoudiniHandleTranslator::UpdateTransformParameters(MainHandle);
return FReply::Handled();
};
ValueWidgetVerticalBox->AddSlot().Padding(2.0f, 2.0f, 5.0f, 2.0f).VAlign(VAlign_Top)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot().FillWidth(1.0f)
[
SNew(SVectorInputBox)
.bColorAxisLabels(true)
.X_Lambda([MainHandle]() {return MainHandle->GetRelativeTransform().GetLocation().X; })
.Y_Lambda([MainHandle]() {return MainHandle->GetRelativeTransform().GetLocation().Y; })
.Z_Lambda([MainHandle]() {return MainHandle->GetRelativeTransform().GetLocation().Z; })
.OnXCommitted_Lambda([OnLocationChangedLambda](float Val, ETextCommit::Type TextCommitType)
{
OnLocationChangedLambda(Val, 0);
})
.OnYCommitted_Lambda([OnLocationChangedLambda](float Val, ETextCommit::Type TextCommitType)
{
OnLocationChangedLambda(Val, 1);
})
.OnZCommitted_Lambda([OnLocationChangedLambda](float Val, ETextCommit::Type TextCommitType)
{
OnLocationChangedLambda(Val, 2);
})
]
+ SHorizontalBox::Slot().AutoWidth().Padding(2.0f, 0.0f).VAlign(VAlign_Center)
[
SNew(SButton)
.ToolTipText(LOCTEXT("RevertToDefault", "Revert to default"))
.ButtonStyle(FEditorStyle::Get(), "NoBorder")
.ContentPadding(0)
.Visibility_Lambda([MainHandle]()
{
if (!MainHandle)
return EVisibility::Hidden;
if (MainHandle->GetRelativeLocation() == FVector::ZeroVector)
return EVisibility::Hidden;
return EVisibility::Visible;
})
.OnClicked_Lambda(RevertLocationToDefault)
[
SNew(SImage)
.Image(FEditorStyle::GetBrush("PropertyWindow.DiffersFromDefault"))
]
]
];
// Rotation
auto OnRotationChangedLambda = [MainHandle](float Val, int32 Axis)
{
if (!MainHandle)
return;
FQuat Rotation = MainHandle->GetRelativeTransform().GetRotation();
if (Axis == 0)
Rotation.X = Val;
else if (Axis == 1)
Rotation.Y = Val;
else
Rotation.Z = Val;
MainHandle->SetRelativeRotation(Rotation);
FHoudiniHandleTranslator::UpdateTransformParameters(MainHandle);
};
auto RevertRotationToDefault = [MainHandle]()
{
if (!MainHandle)
return FReply::Handled();
MainHandle->SetRelativeRotation(FQuat::Identity);
FHoudiniHandleTranslator::UpdateTransformParameters(MainHandle);
return FReply::Handled();
};
ValueWidgetVerticalBox->AddSlot().Padding(2.0f, 2.0f, 5.0f, 2.0f).VAlign(VAlign_Top)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot().FillWidth(1.0f)
[
SNew(SVectorInputBox)
.bColorAxisLabels(true)
.X_Lambda([MainHandle]() {return MainHandle->GetRelativeTransform().GetRotation().X; })
.Y_Lambda([MainHandle]() {return MainHandle->GetRelativeTransform().GetRotation().Y; })
.Z_Lambda([MainHandle]() {return MainHandle->GetRelativeTransform().GetRotation().Z; })
.OnXCommitted_Lambda([OnRotationChangedLambda](float Val, ETextCommit::Type TextCommitType)
{
OnRotationChangedLambda(Val, 0);
})
.OnXCommitted_Lambda([OnRotationChangedLambda](float Val, ETextCommit::Type TextCommitType)
{
OnRotationChangedLambda(Val, 1);
})
.OnXCommitted_Lambda([OnRotationChangedLambda](float Val, ETextCommit::Type TextCommitType)
{
OnRotationChangedLambda(Val, 2);
})
]
+ SHorizontalBox::Slot().AutoWidth().Padding(2.0f, 0.0f).VAlign(VAlign_Center)
[
SNew(SButton)
.ToolTipText(LOCTEXT("RevertToDefault", "Revert to default"))
.ButtonStyle(FEditorStyle::Get(), "NoBorder")
.ContentPadding(0)
.Visibility_Lambda([MainHandle]()
{
if (!MainHandle)
return EVisibility::Hidden;
if (MainHandle->GetRelativeTransform().GetRotation() == FQuat::Identity)
return EVisibility::Hidden;
return EVisibility::Visible;
})
.OnClicked_Lambda(RevertRotationToDefault)
[
SNew(SImage)
.Image(FEditorStyle::GetBrush("PropertyWindow.DiffersFromDefault"))
]
]
];
// Scale
auto OnScaleChangedLambda = [MainHandle](float Val, int32 Axis)
{
if (!MainHandle)
return;
FVector Scale = MainHandle->GetRelativeTransform().GetScale3D();
if (Axis == 0)
Scale.X = Val;
else if (Axis == 1)
Scale.Y = Val;
else
Scale.Z = Val;
MainHandle->SetRelativeScale3D(Scale);
FHoudiniHandleTranslator::UpdateTransformParameters(MainHandle);
};
auto RevertScaleToDefault = [MainHandle]()
{
if (!MainHandle)
return FReply::Handled();
MainHandle->SetRelativeScale3D(FVector::OneVector);
return FReply::Handled();
};
ValueWidgetVerticalBox->AddSlot().Padding(2.0f, 2.0f, 5.0f, 2.0f).VAlign(VAlign_Top)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot().FillWidth(1.0f)
[
SNew(SVectorInputBox)
.bColorAxisLabels(true)
.X_Lambda([MainHandle]() {return MainHandle->GetRelativeTransform().GetScale3D().X; })
.Y_Lambda([MainHandle]() {return MainHandle->GetRelativeTransform().GetScale3D().Y; })
.Z_Lambda([MainHandle]() {return MainHandle->GetRelativeTransform().GetScale3D().Z; })
.OnXCommitted_Lambda([OnScaleChangedLambda](float Val, ETextCommit::Type TextCommitType)
{
OnScaleChangedLambda(Val, 0);
})
.OnXCommitted_Lambda([OnScaleChangedLambda](float Val, ETextCommit::Type TextCommitType)
{
OnScaleChangedLambda(Val, 1);
})
.OnXCommitted_Lambda([OnScaleChangedLambda](float Val, ETextCommit::Type TextCommitType)
{
OnScaleChangedLambda(Val, 2);
})
]
+ SHorizontalBox::Slot().AutoWidth().Padding(2.0f, 0.0f).VAlign(VAlign_Center)
[
SNew(SButton)
.ToolTipText(LOCTEXT("RevertToDefault", "Revert to default"))
.ButtonStyle(FEditorStyle::Get(), "NoBorder")
.ContentPadding(0)
.Visibility_Lambda([MainHandle]()
{
if (!MainHandle)
return EVisibility::Hidden;
if (MainHandle->GetRelativeTransform().GetScale3D() == FVector::OneVector)
return EVisibility::Hidden;
return EVisibility::Visible;
})
.OnClicked_Lambda(RevertScaleToDefault)
[
SNew(SImage)
.Image(FEditorStyle::GetBrush("PropertyWindow.DiffersFromDefault"))
]
]
];
Row.ValueWidget.Widget = ValueWidgetVerticalBox;
Row.ValueWidget.MinDesiredWidth(HAPI_UNREAL_DESIRED_ROW_VALUE_WIDGET_WIDTH);
auto OnMouseEnterLambda = [MainHandle](const FGeometry& Geometry, const FPointerEvent& Event)
{
if (!MainHandle)
return;
TSharedPtr<FComponentVisualizer> Visualizer = GUnrealEd->FindComponentVisualizer(UHoudiniHandleComponent::StaticClass()->GetFName());
TSharedPtr<FHoudiniHandleComponentVisualizer> HandleVisualizer = StaticCastSharedPtr<FHoudiniHandleComponentVisualizer>(Visualizer);
if (HandleVisualizer.IsValid())
{
HandleVisualizer->SetEditedComponent(MainHandle);
}
};
auto OnMouseLeaveLambda = [MainHandle](const FPointerEvent& Event)
{
if (!MainHandle)
return;
TSharedPtr<FComponentVisualizer> Visualizer = GUnrealEd->FindComponentVisualizer(UHoudiniHandleComponent::StaticClass()->GetFName());
TSharedPtr<FHoudiniHandleComponentVisualizer> HandleVisualizer = StaticCastSharedPtr<FHoudiniHandleComponentVisualizer>(Visualizer);
if (HandleVisualizer.IsValid())
{
HandleVisualizer->SetEditedComponent(nullptr);
}
};
// Set on mouse leave UI widget callback functions
Row.NameWidget.Widget->SetOnMouseEnter(FNoReplyPointerEventHandler::CreateLambda(OnMouseEnterLambda));
Row.ValueWidget.Widget->SetOnMouseEnter(FNoReplyPointerEventHandler::CreateLambda(OnMouseEnterLambda));
Row.NameWidget.Widget->SetOnMouseLeave(FSimpleNoReplyPointerEventHandler::CreateLambda(OnMouseLeaveLambda));
Row.ValueWidget.Widget->SetOnMouseLeave(FSimpleNoReplyPointerEventHandler::CreateLambda(OnMouseLeaveLambda));
}
void
FHoudiniHandleDetails::CreateNameWidget(FDetailWidgetRow& Row)
{
TSharedRef<SVerticalBox> VerticalBox = SNew(SVerticalBox);
VerticalBox->AddSlot().AutoHeight().Padding(2.0f, 5.0f, 5.0f, 5.0f).VAlign(VAlign_Center)
[
SNew(STextBlock)
.Text(FText::FromString("Translate"))
.Font(FEditorStyle::GetFontStyle(TEXT("PropertyWindow.NormalFont")))
];
VerticalBox->AddSlot().AutoHeight().Padding(2.0f, 5.0f, 5.0f, 5.0f).VAlign(VAlign_Center)
[
SNew(STextBlock)
.Text(FText::FromString("Rotation"))
.Font(FEditorStyle::GetFontStyle(TEXT("PropertyWindow.NormalFont")))
];
VerticalBox->AddSlot().AutoHeight().Padding(2.0f, 5.0f, 5.0f, 5.0f).VAlign(VAlign_Center)
[
SNew(STextBlock)
.Text(FText::FromString("Scale"))
.Font(FEditorStyle::GetFontStyle(TEXT("PropertyWindow.NormalFont")))
];
Row.NameWidget.Widget = VerticalBox;
}
FString
FHoudiniHandleDetails::GetHandleTypeString(const EHoudiniHandleType& HandleType)
{
switch (HandleType)
{
case EHoudiniHandleType::Bounder:
return FString("Bounder");
case EHoudiniHandleType::Xform:
return FString("Xform");
case EHoudiniHandleType::Unsupported:
return FString("Unsupported");
default:
break;
}
return FString("");
}
#undef LOCTEXT_NAMESPACE