You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
========================== MAJOR FEATURES + CHANGES ========================== Change 2858603 on 2016/02/08 by Tim.Hobson #jira UE-26550 - checked in new art assets for buttons and symbols Change 2858665 on 2016/02/08 by Taizyd.Korambayil #jira UE-25797 Added TextureLODSettings for Ipad Mini set all LODBias to 2. Change 2858668 on 2016/02/08 by Matthew.Griffin Added InfiltratorDemo back into Rocket samples #jira UEB-591 Change 2858743 on 2016/02/08 by Taizyd.Korambayil #jira UE-25996 Fixed Import Error in TopDOwn Code Change 2858776 on 2016/02/08 by Matthew.Griffin Added UnrealMatch3 to packaged projects #jira UEB-589 Change 2858900 on 2016/02/08 by Taizyd.Korambayil #jira UE-15234 Switched all Mask Textures to use the (Mask,No sRGB) Compression Change 2858947 on 2016/02/08 by Mike.Beach Controlling more when VerifyImport() is ran - trying to prevent Verify() from running when DeferDependencyLoads is on, and instead trying to fully verify every import upfront (where it's meant to happen) before serializing in the package's contents (to alleviate cyclic dependency complications). #jira UE-21098 Change 2858954 on 2016/02/08 by Taizyd.Korambayil #jira UE-25524 Resaved Sound Assets to Fix NodeGuid Warnings Change 2859126 on 2016/02/08 by Max.Chen Sequencer: Release track editors when destroying sequencer #jira UE-26423 Change 2859147 on 2016/02/08 by Martin.Wilson Fix uninitialized variable bug #jira UE-26606 Change 2859237 on 2016/02/08 by Lauren.Ridge Bumping Match 3 Version Number for iTunes Connect #jira UE-26648 Change 2859434 on 2016/02/08 by Chad.Taylor Handle the quit and focus message pipe from the SteamVR SDK #jira UEBP-142 Change 2859562 on 2016/02/08 by Chad.Taylor Mac/Android compile fix #jira UEBP-142 Change 2859633 on 2016/02/08 by Dan.Oconnor Transaction buffer uniformly address subobjects and SCS created components via an array of names and a root object. This allows undo/redo to work reliably to any depth of object hierarchy. Removed FReferencedObject and replaced it with the robust FPersistentObjectRef. DefaultSubObjects of the CDO are now tagged as RF_Archetype at construction (logic in PropertyHandleImpl.cpp probably no longer required) Actors reinstanced due to blueprint compilation now have stable names, so that this name can be used to reference their subobjects. This is also part of the fix needed for UE-23335, completely fixes UE-26045 This version of the fix is less aggressive about searching all the way up an object's outer chain before stopping. Fixes issues with parts of outer chain changing on PIE. Also doesn't add objects referenced by subobject name to any AddReference calls which fixes race conditions with GC. Also fixes bad logic in CopyPropertiesForUnrelatedObjects, which would create copies of subobjects that already existed because we were populating the ReferenceReplacementMap before adding all existing subobjects (always components in this case) #jira UE-26045 Change 2859640 on 2016/02/08 by Dan.Oconnor Removed debugging code.. #jira UE-26045 Change 2859668 on 2016/02/08 by Aaron.McLeran #jira UE-26503 A Mixer with a Concatenator node won't loop with a Looping node - issue was the looping nodes weren't properly reseting all the child wave instances - also looping nodes weren't reporting the correct GetNumSounds() count for use with sequencer node Change 2859688 on 2016/02/08 by Chris.Babcock Allow external access to runtime modifications to OpenGL shaders #jira UE-26679 #ue4 Change 2859739 on 2016/02/08 by Chad.Taylor UE4_Win64_Mono compile fix #jira UEBP-142 Change 2859962 on 2016/02/09 by Chris.Wood Passing command line to Crash Report Client without stripping the project name. [UE-24959] - "Send and Restart" brings up the Project Browser #jira UE-24959 Reimplement changes from Orion in UE 4.11 Reimplementing the command line logging filtering over from Dev-Core (same change as CL 2821359 that moved this change into Orion) Reimplementing passing full command line to Crash Report Client (same change as CL 2858617 in Orion) Change 2859966 on 2016/02/09 by Matthew.Griffin Fixed shadow variable issue that was causing build failure in NonUnity mode on Mac [CL 2873884 by Ben Marsh in Main branch]
496 lines
15 KiB
C++
496 lines
15 KiB
C++
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "GraphEditorCommon.h"
|
|
#include "Materials/MaterialExpression.h"
|
|
#include "Materials/MaterialFunction.h"
|
|
#include "SGraphNodeMaterialBase.h"
|
|
#include "ScopedTransaction.h"
|
|
#include "Runtime/Engine/Public/Slate/SceneViewport.h"
|
|
#include "TutorialMetaData.h"
|
|
#include "CanvasTypes.h"
|
|
#include "CanvasItem.h"
|
|
#include "Materials/MaterialExpressionMakeMaterialAttributes.h"
|
|
#include "Materials/MaterialExpressionBreakMaterialAttributes.h"
|
|
|
|
|
|
|
|
/**
|
|
* Simple representation of the backbuffer that the preview canvas renders to
|
|
* This class may only be accessed from the render thread
|
|
*/
|
|
class FSlateMaterialPreviewRenderTarget : public FRenderTarget
|
|
{
|
|
public:
|
|
/** FRenderTarget interface */
|
|
virtual FIntPoint GetSizeXY() const
|
|
{
|
|
return ClippingRect.Size();
|
|
}
|
|
|
|
/** Sets the texture that this target renders to */
|
|
void SetRenderTargetTexture( FTexture2DRHIRef& InRHIRef )
|
|
{
|
|
RenderTargetTextureRHI = InRHIRef;
|
|
}
|
|
|
|
/** Clears the render target texture */
|
|
void ClearRenderTargetTexture()
|
|
{
|
|
RenderTargetTextureRHI.SafeRelease();
|
|
}
|
|
|
|
/** Sets the viewport rect for the render target */
|
|
void SetViewRect( const FIntRect& InViewRect )
|
|
{
|
|
ViewRect = InViewRect;
|
|
}
|
|
|
|
/** Gets the viewport rect for the render target */
|
|
const FIntRect& GetViewRect() const
|
|
{
|
|
return ViewRect;
|
|
}
|
|
|
|
/** Sets the clipping rect for the render target */
|
|
void SetClippingRect( const FIntRect& InClippingRect )
|
|
{
|
|
ClippingRect = InClippingRect;
|
|
}
|
|
|
|
/** Gets the clipping rect for the render target */
|
|
const FIntRect& GetClippingRect() const
|
|
{
|
|
return ClippingRect;
|
|
}
|
|
private:
|
|
FIntRect ViewRect;
|
|
FIntRect ClippingRect;
|
|
};
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
FPreviewViewport
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
FPreviewViewport::FPreviewViewport(class UMaterialGraphNode* InNode)
|
|
: MaterialNode(InNode)
|
|
, PreviewElement( new FPreviewElement )
|
|
{
|
|
}
|
|
|
|
FPreviewViewport::~FPreviewViewport()
|
|
{
|
|
// Pass the preview element to the render thread so that it's deleted after it's shown for the last time
|
|
ENQUEUE_UNIQUE_RENDER_COMMAND_ONEPARAMETER
|
|
(
|
|
SafeDeletePreviewElement,
|
|
FThreadSafePreviewPtr, PreviewElementPtr, PreviewElement,
|
|
{
|
|
PreviewElementPtr.Reset();
|
|
}
|
|
);
|
|
}
|
|
|
|
void FPreviewViewport::OnDrawViewport( const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, class FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled )
|
|
{
|
|
FSlateRect SlateCanvasRect = AllottedGeometry.GetClippingRect();
|
|
FSlateRect ClippedCanvasRect = SlateCanvasRect.IntersectionWith(MyClippingRect);
|
|
|
|
FIntRect CanvasRect(
|
|
FMath::TruncToInt( FMath::Max(0.0f, SlateCanvasRect.Left) ),
|
|
FMath::TruncToInt( FMath::Max(0.0f, SlateCanvasRect.Top) ),
|
|
FMath::TruncToInt( FMath::Max(0.0f, SlateCanvasRect.Right) ),
|
|
FMath::TruncToInt( FMath::Max(0.0f, SlateCanvasRect.Bottom) ) );
|
|
|
|
FIntRect ClippingRect(
|
|
FMath::TruncToInt( FMath::Max(0.0f, ClippedCanvasRect.Left) ),
|
|
FMath::TruncToInt( FMath::Max(0.0f, ClippedCanvasRect.Top) ),
|
|
FMath::TruncToInt( FMath::Max(0.0f, ClippedCanvasRect.Right) ),
|
|
FMath::TruncToInt( FMath::Max(0.0f, ClippedCanvasRect.Bottom) ) );
|
|
|
|
bool bIsRealtime = MaterialNode->RealtimeDelegate.IsBound() ? MaterialNode->RealtimeDelegate.Execute() : false;
|
|
|
|
if (PreviewElement->BeginRenderingCanvas( CanvasRect, ClippingRect, MaterialNode->GetExpressionPreview(), bIsRealtime ))
|
|
{
|
|
// Draw above everything else
|
|
uint32 PreviewLayer = LayerId+1;
|
|
FSlateDrawElement::MakeCustom( OutDrawElements, PreviewLayer, PreviewElement );
|
|
}
|
|
}
|
|
|
|
FIntPoint FPreviewViewport::GetSize() const
|
|
{
|
|
return FIntPoint(96,96);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////
|
|
// FPreviewElement
|
|
|
|
FPreviewElement::FPreviewElement()
|
|
: RenderTarget(new FSlateMaterialPreviewRenderTarget)
|
|
, ExpressionPreview(NULL)
|
|
, bIsRealtime(false)
|
|
{
|
|
}
|
|
|
|
FPreviewElement::~FPreviewElement()
|
|
{
|
|
delete RenderTarget;
|
|
}
|
|
|
|
bool FPreviewElement::BeginRenderingCanvas( const FIntRect& InCanvasRect, const FIntRect& InClippingRect, FMaterialRenderProxy* InExpressionPreview, bool bInIsRealtime )
|
|
{
|
|
if(InCanvasRect.Size().X > 0 && InCanvasRect.Size().Y > 0 && InClippingRect.Size().X > 0 && InClippingRect.Size().Y > 0 && InExpressionPreview != NULL)
|
|
{
|
|
/**
|
|
* Struct to contain all info that needs to be passed to the render thread
|
|
*/
|
|
struct FPreviewRenderInfo
|
|
{
|
|
/** Size of the Canvas tile */
|
|
FIntRect CanvasRect;
|
|
/** How to clip the canvas tile */
|
|
FIntRect ClippingRect;
|
|
/** Render proxy for the expression preview */
|
|
FMaterialRenderProxy* ExpressionPreview;
|
|
/** Whether preview is using realtime values */
|
|
bool bIsRealtime;
|
|
};
|
|
|
|
FPreviewRenderInfo RenderInfo;
|
|
RenderInfo.CanvasRect = InCanvasRect;
|
|
RenderInfo.ClippingRect = InClippingRect;
|
|
RenderInfo.ExpressionPreview = InExpressionPreview;
|
|
RenderInfo.bIsRealtime = bInIsRealtime;
|
|
|
|
ENQUEUE_UNIQUE_RENDER_COMMAND_TWOPARAMETER
|
|
(
|
|
BeginRenderingPreviewCanvas,
|
|
FPreviewElement*, PreviewElement, this,
|
|
FPreviewRenderInfo, InRenderInfo, RenderInfo,
|
|
{
|
|
PreviewElement->RenderTarget->SetViewRect(InRenderInfo.CanvasRect);
|
|
PreviewElement->RenderTarget->SetClippingRect(InRenderInfo.ClippingRect);
|
|
PreviewElement->ExpressionPreview = InRenderInfo.ExpressionPreview;
|
|
PreviewElement->bIsRealtime = InRenderInfo.bIsRealtime;
|
|
}
|
|
);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void FPreviewElement::DrawRenderThread(FRHICommandListImmediate& RHICmdList, const void* InWindowBackBuffer)
|
|
{
|
|
// Clip the canvas to avoid having to set UV values
|
|
FIntRect ClippingRect = RenderTarget->GetClippingRect();
|
|
|
|
RHICmdList.SetScissorRect(true,
|
|
ClippingRect.Min.X,
|
|
ClippingRect.Min.Y,
|
|
ClippingRect.Max.X,
|
|
ClippingRect.Max.Y);
|
|
RenderTarget->SetRenderTargetTexture( *(FTexture2DRHIRef*)InWindowBackBuffer );
|
|
{
|
|
// Check realtime mode for whether to pass current time to canvas
|
|
float CurrentTime = bIsRealtime ? (FApp::GetCurrentTime() - GStartTime) : 0.0f;
|
|
float DeltaTime = bIsRealtime ? FApp::GetDeltaTime() : 0.0f;
|
|
|
|
FCanvas Canvas(RenderTarget, NULL, CurrentTime, CurrentTime, DeltaTime, GMaxRHIFeatureLevel);
|
|
{
|
|
Canvas.SetAllowedModes( 0 );
|
|
Canvas.SetRenderTargetRect( RenderTarget->GetViewRect() );
|
|
|
|
FCanvasTileItem TileItem( FVector2D::ZeroVector, ExpressionPreview , RenderTarget->GetSizeXY());
|
|
Canvas.DrawItem( TileItem );
|
|
}
|
|
Canvas.Flush_RenderThread(RHICmdList, true);
|
|
}
|
|
RenderTarget->ClearRenderTargetTexture();
|
|
RHICmdList.SetScissorRect(false, 0, 0, 0, 0);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////
|
|
// SGraphNodeMaterialBase
|
|
|
|
void SGraphNodeMaterialBase::Construct(const FArguments& InArgs, UMaterialGraphNode* InNode)
|
|
{
|
|
this->GraphNode = InNode;
|
|
this->MaterialNode = InNode;
|
|
|
|
this->SetCursor(EMouseCursor::CardinalCross);
|
|
|
|
this->UpdateGraphNode();
|
|
}
|
|
|
|
void SGraphNodeMaterialBase::CreatePinWidgets()
|
|
{
|
|
// Create Pin widgets for each of the pins.
|
|
for( int32 PinIndex=0; PinIndex < GraphNode->Pins.Num(); ++PinIndex )
|
|
{
|
|
UEdGraphPin* CurPin = GraphNode->Pins[PinIndex];
|
|
|
|
bool bHideNoConnectionPins = false;
|
|
|
|
if (OwnerGraphPanelPtr.IsValid())
|
|
{
|
|
bHideNoConnectionPins = OwnerGraphPanelPtr.Pin()->GetPinVisibility() == SGraphEditor::Pin_HideNoConnection;
|
|
}
|
|
|
|
const bool bPinHasConections = CurPin->LinkedTo.Num() > 0;
|
|
|
|
bool bPinDesiresToBeHidden = CurPin->bHidden || (bHideNoConnectionPins && !bPinHasConections);
|
|
|
|
UMaterialGraph* MaterialGraph = CastChecked<UMaterialGraph>(GraphNode->GetGraph());
|
|
if (MaterialNode && MaterialNode->MaterialExpression && MaterialGraph->MaterialFunction == nullptr)
|
|
{
|
|
bool bIsAMakeAttrNode = MaterialNode->MaterialExpression->IsA(UMaterialExpressionMakeMaterialAttributes::StaticClass());
|
|
bool bIsABreakAttrNode = MaterialNode->MaterialExpression->IsA(UMaterialExpressionBreakMaterialAttributes::StaticClass());
|
|
|
|
if ((bIsABreakAttrNode && CurPin->Direction == EGPD_Output) || (bIsAMakeAttrNode && CurPin->Direction == EGPD_Input))
|
|
{
|
|
int32 ResultNodeIndex = bIsAMakeAttrNode ? MaterialNode->GetInputIndex(CurPin) : MaterialNode->GetOutputIndex(CurPin);
|
|
bPinDesiresToBeHidden |= !MaterialGraph->MaterialInputs[ResultNodeIndex].IsVisiblePin(MaterialGraph->Material, true);
|
|
}
|
|
}
|
|
|
|
if (!bPinDesiresToBeHidden)
|
|
{
|
|
TSharedPtr<SGraphPin> NewPin = CreatePinWidget(CurPin);
|
|
check(NewPin.IsValid());
|
|
|
|
this->AddPin(NewPin.ToSharedRef());
|
|
}
|
|
}
|
|
}
|
|
|
|
void SGraphNodeMaterialBase::MoveTo(const FVector2D& NewPosition, FNodeSet& NodeFilter)
|
|
{
|
|
SGraphNode::MoveTo(NewPosition, NodeFilter);
|
|
|
|
MaterialNode->MaterialExpression->MaterialExpressionEditorX = MaterialNode->NodePosX;
|
|
MaterialNode->MaterialExpression->MaterialExpressionEditorY = MaterialNode->NodePosY;
|
|
MaterialNode->MaterialExpression->MarkPackageDirty();
|
|
MaterialNode->MaterialDirtyDelegate.ExecuteIfBound();
|
|
}
|
|
|
|
void SGraphNodeMaterialBase::AddPin( const TSharedRef<SGraphPin>& PinToAdd )
|
|
{
|
|
PinToAdd->SetOwner( SharedThis(this) );
|
|
|
|
if (PinToAdd->GetDirection() == EEdGraphPinDirection::EGPD_Input)
|
|
{
|
|
FMargin Padding = Settings->GetInputPinPadding();
|
|
Padding.Left *= 0.5f;
|
|
Padding.Right = 0.0f;
|
|
|
|
LeftNodeBox->AddSlot()
|
|
.AutoHeight()
|
|
.HAlign(HAlign_Left)
|
|
.VAlign(VAlign_Center)
|
|
.Padding(Padding)
|
|
[
|
|
PinToAdd
|
|
];
|
|
InputPins.Add(PinToAdd);
|
|
}
|
|
else // Direction == EEdGraphPinDirection::EGPD_Output
|
|
{
|
|
FMargin Padding = Settings->GetOutputPinPadding();
|
|
Padding.Left = 0.0f;
|
|
Padding.Right *= 0.5f;
|
|
|
|
RightNodeBox->AddSlot()
|
|
.AutoHeight()
|
|
.HAlign(HAlign_Right)
|
|
.VAlign(VAlign_Center)
|
|
.Padding(Padding)
|
|
[
|
|
PinToAdd
|
|
];
|
|
OutputPins.Add(PinToAdd);
|
|
}
|
|
}
|
|
|
|
void SGraphNodeMaterialBase::CreateBelowPinControls(TSharedPtr<SVerticalBox> MainBox)
|
|
{
|
|
if (GraphNode && MainBox.IsValid())
|
|
{
|
|
int32 LeftPinCount = InputPins.Num();
|
|
int32 RightPinCount = OutputPins.Num();
|
|
|
|
const float NegativeHPad = FMath::Max<float>(-Settings->PaddingTowardsNodeEdge, 0.0f);
|
|
const float ExtraPad = 0.0f;
|
|
|
|
// Place preview widget based on where the least pins are
|
|
if ((LeftPinCount < RightPinCount) || (RightPinCount == 0))
|
|
{
|
|
LeftNodeBox->AddSlot()
|
|
.Padding(FMargin(NegativeHPad + ExtraPad, 0.0f, 0.0f, 0.0f))
|
|
.AutoHeight()
|
|
[
|
|
CreatePreviewWidget()
|
|
];
|
|
}
|
|
else if (LeftPinCount > RightPinCount)
|
|
{
|
|
RightNodeBox->AddSlot()
|
|
.Padding(FMargin(NegativeHPad + ExtraPad, 0.0f, 0.0f, 0.0f))
|
|
.AutoHeight()
|
|
[
|
|
CreatePreviewWidget()
|
|
];
|
|
}
|
|
else
|
|
{
|
|
MainBox->AddSlot()
|
|
.Padding(Settings->GetNonPinNodeBodyPadding())
|
|
.AutoHeight()
|
|
[
|
|
SNew(SHorizontalBox)
|
|
+SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
[
|
|
CreatePreviewWidget()
|
|
]
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
void SGraphNodeMaterialBase::SetDefaultTitleAreaWidget(TSharedRef<SOverlay> DefaultTitleAreaWidget)
|
|
{
|
|
if (!MaterialNode->MaterialExpression->bHidePreviewWindow)
|
|
{
|
|
DefaultTitleAreaWidget->AddSlot()
|
|
.HAlign(HAlign_Right)
|
|
.VAlign(VAlign_Center)
|
|
.Padding(FMargin(5))
|
|
[
|
|
SNew(SCheckBox)
|
|
.OnCheckStateChanged( this, &SGraphNodeMaterialBase::OnExpressionPreviewChanged )
|
|
.IsChecked( IsExpressionPreviewChecked() )
|
|
.Cursor(EMouseCursor::Default)
|
|
.Style(FEditorStyle::Get(), "Graph.Node.AdvancedView")
|
|
[
|
|
SNew(SHorizontalBox)
|
|
+SHorizontalBox::Slot()
|
|
.VAlign(VAlign_Center)
|
|
.HAlign(HAlign_Center)
|
|
[
|
|
SNew(SImage)
|
|
. Image(GetExpressionPreviewArrow())
|
|
]
|
|
]
|
|
];
|
|
}
|
|
}
|
|
|
|
TSharedRef<SWidget> SGraphNodeMaterialBase::CreateNodeContentArea()
|
|
{
|
|
// NODE CONTENT AREA
|
|
return SNew(SBorder)
|
|
.BorderImage( FEditorStyle::GetBrush("NoBorder") )
|
|
.HAlign(HAlign_Fill)
|
|
.VAlign(VAlign_Fill)
|
|
[
|
|
SNew(SHorizontalBox)
|
|
+SHorizontalBox::Slot()
|
|
.HAlign(HAlign_Left)
|
|
.FillWidth(1.0f)
|
|
[
|
|
// LEFT
|
|
SAssignNew(LeftNodeBox, SVerticalBox)
|
|
]
|
|
+SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.HAlign(HAlign_Right)
|
|
[
|
|
// RIGHT
|
|
SAssignNew(RightNodeBox, SVerticalBox)
|
|
]
|
|
];
|
|
}
|
|
|
|
TSharedRef<SWidget> SGraphNodeMaterialBase::CreatePreviewWidget()
|
|
{
|
|
PreviewViewport.Reset();
|
|
|
|
// if this node should currently show a preview
|
|
if (!MaterialNode->MaterialExpression->bHidePreviewWindow && !MaterialNode->MaterialExpression->bCollapsed)
|
|
{
|
|
const float ExpressionPreviewSize = 106.0f;
|
|
const float CentralPadding = 5.0f;
|
|
|
|
TSharedPtr<SViewport> ViewportWidget =
|
|
SNew( SViewport )
|
|
.EnableGammaCorrection(false);
|
|
|
|
PreviewViewport = MakeShareable(new FPreviewViewport(MaterialNode));
|
|
|
|
// The viewport widget needs an interface so it knows what should render
|
|
ViewportWidget->SetViewportInterface( PreviewViewport.ToSharedRef() );
|
|
|
|
return SNew(SBox)
|
|
.WidthOverride(ExpressionPreviewSize)
|
|
.HeightOverride(ExpressionPreviewSize)
|
|
.Visibility(ExpressionPreviewVisibility())
|
|
[
|
|
SNew(SBorder)
|
|
.Padding(CentralPadding)
|
|
.BorderImage( FEditorStyle::GetBrush("NoBorder") )
|
|
[
|
|
ViewportWidget.ToSharedRef()
|
|
]
|
|
];
|
|
}
|
|
|
|
return SNullWidget::NullWidget;
|
|
}
|
|
|
|
EVisibility SGraphNodeMaterialBase::ExpressionPreviewVisibility() const
|
|
{
|
|
UMaterialExpression* MaterialExpression = MaterialNode->MaterialExpression;
|
|
const bool bShowPreview = !MaterialExpression->bHidePreviewWindow && !MaterialExpression->bCollapsed;
|
|
return bShowPreview ? EVisibility::Visible : EVisibility::Collapsed;
|
|
}
|
|
|
|
void SGraphNodeMaterialBase::OnExpressionPreviewChanged( const ECheckBoxState NewCheckedState )
|
|
{
|
|
UMaterialExpression* MaterialExpression = MaterialNode->MaterialExpression;
|
|
const bool bCollapsed = (NewCheckedState != ECheckBoxState::Checked);
|
|
if (MaterialExpression->bCollapsed != bCollapsed)
|
|
{
|
|
UMaterialGraph* MaterialGraph = CastChecked<UMaterialGraph>(MaterialNode->GetGraph());
|
|
MaterialGraph->ToggleCollapsedDelegate.ExecuteIfBound(MaterialExpression);
|
|
|
|
// Update the graph node so that preview viewport is created
|
|
UpdateGraphNode();
|
|
}
|
|
}
|
|
|
|
ECheckBoxState SGraphNodeMaterialBase::IsExpressionPreviewChecked() const
|
|
{
|
|
return MaterialNode->MaterialExpression->bCollapsed ? ECheckBoxState::Unchecked : ECheckBoxState::Checked;
|
|
}
|
|
|
|
const FSlateBrush* SGraphNodeMaterialBase::GetExpressionPreviewArrow() const
|
|
{
|
|
return FEditorStyle::GetBrush(MaterialNode->MaterialExpression->bCollapsed ? TEXT("Kismet.TitleBarEditor.ArrowDown") : TEXT("Kismet.TitleBarEditor.ArrowUp"));
|
|
}
|
|
|
|
void SGraphNodeMaterialBase::PopulateMetaTag(FGraphNodeMetaData* TagMeta) const
|
|
{
|
|
if (GraphNode != nullptr)
|
|
{
|
|
UMaterialGraph* OuterGraph = MaterialNode->GetTypedOuter<UMaterialGraph>();
|
|
if ((OuterGraph != nullptr) && (MaterialNode->MaterialExpression != nullptr) )
|
|
{
|
|
TagMeta->OuterName = OuterGraph->OriginalMaterialFullName;
|
|
TagMeta->GUID = MaterialNode->MaterialExpression->MaterialExpressionGuid;
|
|
TagMeta->Tag = FName(*FString::Printf(TEXT("MaterialExprNode_%s_%s"), *TagMeta->OuterName, *TagMeta->GUID.ToString()));
|
|
}
|
|
TagMeta->FriendlyName = FString::Printf(TEXT("%s expression node in %s"), *GraphNode->GetNodeTitle(ENodeTitleType::FullTitle).ToString(), *TagMeta->OuterName);
|
|
}
|
|
}
|