FLinearColor SPropertyEditorColor::OnGetColor() const { const TSharedRef< FPropertyNode > PropertyNode = PropertyEditor->GetPropertyNode(); const UProperty* Property = PropertyEditor->GetProperty(); check(Property); FLinearColor Color; FReadAddressList ReadAddresses; PropertyNode->GetReadAddress( false, ReadAddresses, false ); if( ReadAddresses.Num() ) { const uint8* Addr = ReadAddresses.GetAddress(0); if( Addr ) { if( Cast<const UStructProperty>(Property)->Struct->GetFName() == NAME_Color ) { Color = (*(FColor*)Addr).ReinterpretAsLinear(); } else { check( Cast<const UStructProperty>(Property)->Struct->GetFName() == NAME_LinearColor ); Color = *(FLinearColor*)Addr; } } } return Color; }
/** * Creates the color picker window for this property view. * * @param Node The slate property node to edit. * @param bUseAlpha Whether or not alpha is supported */ void SDetailsViewBase::CreateColorPickerWindow(const TSharedRef< FPropertyEditor >& PropertyEditor, bool bUseAlpha) { const TSharedRef< FPropertyNode > PinnedColorPropertyNode = PropertyEditor->GetPropertyNode(); ColorPropertyNode = PinnedColorPropertyNode; UProperty* Property = PinnedColorPropertyNode->GetProperty(); check(Property); FReadAddressList ReadAddresses; PinnedColorPropertyNode->GetReadAddress(false, ReadAddresses, false); TArray<FLinearColor*> LinearColor; TArray<FColor*> DWORDColor; for (int32 ColorIndex = 0; ColorIndex < ReadAddresses.Num(); ++ColorIndex) { const uint8* Addr = ReadAddresses.GetAddress(ColorIndex); if (Addr) { if (Cast<UStructProperty>(Property)->Struct->GetFName() == NAME_Color) { DWORDColor.Add((FColor*)Addr); } else { check(Cast<UStructProperty>(Property)->Struct->GetFName() == NAME_LinearColor); LinearColor.Add((FLinearColor*)Addr); } } } bHasOpenColorPicker = true; FColorPickerArgs PickerArgs; PickerArgs.ParentWidget = AsShared(); PickerArgs.bUseAlpha = bUseAlpha; PickerArgs.DisplayGamma = TAttribute<float>::Create(TAttribute<float>::FGetter::CreateUObject(GEngine, &UEngine::GetDisplayGamma)); PickerArgs.ColorArray = &DWORDColor; PickerArgs.LinearColorArray = &LinearColor; PickerArgs.OnColorCommitted = FOnLinearColorValueChanged::CreateSP(this, &SDetailsViewBase::SetColorPropertyFromColorPicker); PickerArgs.OnColorPickerWindowClosed = FOnWindowClosed::CreateSP(this, &SDetailsViewBase::OnColorPickerWindowClosed); OpenColorPicker(PickerArgs); }
void SSingleProperty::CreateColorPickerWindow( const TSharedRef< class FPropertyEditor >& PropertyEditor, bool bUseAlpha ) { if( HasValidProperty() ) { auto Node = PropertyEditor->GetPropertyNode(); check( &Node.Get() == ValueNode.Get() ); UProperty* Property = Node->GetProperty(); check(Property); FReadAddressList ReadAddresses; Node->GetReadAddress( false, ReadAddresses, false ); TArray<FLinearColor*> LinearColor; TArray<FColor*> DWORDColor; if( ReadAddresses.Num() ) { const uint8* Addr = ReadAddresses.GetAddress(0); if( Addr ) { if( Cast<UStructProperty>(Property)->Struct->GetFName() == NAME_Color ) { DWORDColor.Add((FColor*)Addr); } else { check( Cast<UStructProperty>(Property)->Struct->GetFName() == NAME_LinearColor ); LinearColor.Add((FLinearColor*)Addr); } } } FColorPickerArgs PickerArgs; PickerArgs.ParentWidget = AsShared(); PickerArgs.bUseAlpha = bUseAlpha; PickerArgs.DisplayGamma = TAttribute<float>::Create( TAttribute<float>::FGetter::CreateUObject(GEngine, &UEngine::GetDisplayGamma) ); PickerArgs.ColorArray = &DWORDColor; PickerArgs.LinearColorArray = &LinearColor; PickerArgs.OnColorCommitted = FOnLinearColorValueChanged::CreateSP( this, &SSingleProperty::SetColorPropertyFromColorPicker); OpenColorPicker(PickerArgs); } }
void SPropertyEditorColor::OnColorPickerCancelled( FLinearColor OriginalColor ) { const TSharedRef< FPropertyNode > PropertyNode = PropertyEditor->GetPropertyNode(); UProperty* Property = PropertyNode->GetProperty(); check(Property); FReadAddressList ReadAddresses; PropertyNode->GetReadAddress( false, ReadAddresses, false ); if( ReadAddresses.Num() ) { check( OriginalColors.Num() == ReadAddresses.Num() ); PropertyNode->NotifyPreChange(Property, PropertyUtilities->GetNotifyHook()); for( int32 AddrIndex = 0; AddrIndex < ReadAddresses.Num(); ++AddrIndex ) { const uint8* Addr = ReadAddresses.GetAddress(AddrIndex); if( Addr ) { if( Cast<UStructProperty>(Property)->Struct->GetFName() == NAME_Color ) { *(FColor*)Addr = OriginalColors[AddrIndex].ToFColor(false); } else { check( Cast<UStructProperty>(Property)->Struct->GetFName() == NAME_LinearColor ); *(FLinearColor*)Addr = OriginalColors[AddrIndex]; } } } FPropertyChangedEvent ChangeEvent(Property, EPropertyChangeType::ValueSet); PropertyNode->NotifyPostChange( ChangeEvent, PropertyUtilities->GetNotifyHook() ); } OriginalColors.Empty(); }
void SPropertyEditorColor::SetColor(FLinearColor NewColor) { const TSharedRef< FPropertyNode > PropertyNode = PropertyEditor->GetPropertyNode(); UProperty* Property = PropertyNode->GetProperty(); check(Property); FReadAddressList ReadAddresses; PropertyNode->GetReadAddress( false, ReadAddresses, false ); if( ReadAddresses.Num() ) { GEditor->BeginTransaction( NSLOCTEXT("UnrealEd", "SetColorProperty", "Set Color Property") ); PropertyNode->NotifyPreChange(Property, PropertyUtilities->GetNotifyHook()); for( int32 AddrIndex = 0; AddrIndex < ReadAddresses.Num(); ++AddrIndex ) { const uint8* Addr = ReadAddresses.GetAddress(AddrIndex); if( Addr ) { if( Cast<UStructProperty>(Property)->Struct->GetFName() == NAME_Color ) { *(FColor*)Addr = NewColor.ToFColor(false); } else { check( Cast<UStructProperty>(Property)->Struct->GetFName() == NAME_LinearColor ); *(FLinearColor*)Addr = NewColor; } } } FPropertyChangedEvent ChangeEvent(Property, EPropertyChangeType::ValueSet); PropertyNode->NotifyPostChange( ChangeEvent, PropertyUtilities->GetNotifyHook() ); GEditor->EndTransaction(); } }
void SPropertyEditorColor::CreateColorPickerWindow(const TSharedRef< class FPropertyEditor >& InPropertyEditor, bool bUseAlpha, bool bOnlyRefreshOnOk) { const TSharedRef< FPropertyNode > PropertyNode = InPropertyEditor->GetPropertyNode(); UProperty* Property = PropertyNode->GetProperty(); check(Property); FReadAddressList ReadAddresses; PropertyNode->GetReadAddress( false, ReadAddresses, false ); FLinearColor InitialColor = FLinearColor(ForceInit); if( ReadAddresses.Num() ) { OriginalColors.Empty( ReadAddresses.Num() ); OriginalColors.AddUninitialized( ReadAddresses.Num() ); // Store off the original colors in the case that the user cancels the color picker. We'll revert to the original colors in that case for( int32 AddrIndex = 0; AddrIndex < ReadAddresses.Num(); ++AddrIndex ) { const uint8* Addr = ReadAddresses.GetAddress(AddrIndex); if( Addr ) { if( Cast<UStructProperty>(Property)->Struct->GetFName() == NAME_Color ) { OriginalColors[AddrIndex] = ((FColor*)Addr)->ReinterpretAsLinear(); } else { check( Cast<UStructProperty>(Property)->Struct->GetFName() == NAME_LinearColor ); OriginalColors[AddrIndex] = *(FLinearColor*)Addr; } } } // Only one color can be the initial color. Just use the first color property InitialColor = OriginalColors[0]; FColorPickerArgs PickerArgs; PickerArgs.bOnlyRefreshOnMouseUp = true; PickerArgs.ParentWidget = AsShared(); PickerArgs.bUseAlpha = bUseAlpha; PickerArgs.bOnlyRefreshOnOk = bOnlyRefreshOnOk; PickerArgs.DisplayGamma = TAttribute<float>::Create( TAttribute<float>::FGetter::CreateUObject(GEngine, &UEngine::GetDisplayGamma) ); PickerArgs.OnColorCommitted = FOnLinearColorValueChanged::CreateSP( this, &SPropertyEditorColor::SetColor); PickerArgs.OnColorPickerCancelled = FOnColorPickerCancelled::CreateSP( this, &SPropertyEditorColor::OnColorPickerCancelled ); PickerArgs.InitialColorOverride = InitialColor; OpenColorPicker(PickerArgs); } }
void FPropertyEditor::SyncToObjectsInNode( const TWeakPtr< FPropertyNode >& WeakPropertyNode ) { #if WITH_EDITOR if ( !GUnrealEd ) { return; } TSharedPtr< FPropertyNode > PropertyNode = WeakPropertyNode.Pin(); check(PropertyNode.IsValid()); UProperty* NodeProperty = PropertyNode->GetProperty(); UObjectPropertyBase* ObjectProperty = Cast<UObjectPropertyBase>( NodeProperty ); UInterfaceProperty* IntProp = Cast<UInterfaceProperty>( NodeProperty ); { UClass* PropertyClass = UObject::StaticClass(); if( ObjectProperty ) { PropertyClass = ObjectProperty->PropertyClass; } else if( IntProp ) { PropertyClass = IntProp->InterfaceClass; } // Get a list of addresses for objects handled by the property window. FReadAddressList ReadAddresses; PropertyNode->GetReadAddress( !!PropertyNode->HasNodeFlags(EPropertyNodeFlags::SingleSelectOnly), ReadAddresses, false ); // GetReadAddresses will only provide a list of addresses if the property was properly formed, objects were selected, and only one object was selected if the node has the SingleSelectOnly flag. // If a list of addresses is provided, GetReadAddress may still return false but we can operate on the property addresses even if they have different values. check( ReadAddresses.Num() > 0 ); // Create a list of object names. TArray<FString> ObjectNames; ObjectNames.Empty( ReadAddresses.Num() ); // Copy each object's object property name off into the name list. for ( int32 AddrIndex = 0 ; AddrIndex < ReadAddresses.Num() ; ++AddrIndex ) { new( ObjectNames ) FString(); uint8* Address = ReadAddresses.GetAddress(AddrIndex); if( Address ) { NodeProperty->ExportText_Direct(ObjectNames[AddrIndex], Address, Address, NULL, PPF_Localized ); } } // Create a list of objects to sync the generic browser to. TArray<UObject*> Objects; for ( int32 ObjectIndex = 0 ; ObjectIndex < ObjectNames.Num() ; ++ObjectIndex ) { UObject* Package = ANY_PACKAGE; if( ObjectNames[ObjectIndex].Contains( TEXT(".")) ) { // Formatted text string, use the exact path instead of any package Package = NULL; } UObject* Object = StaticFindObject( PropertyClass, Package, *ObjectNames[ObjectIndex] ); if( !Object && Package != ANY_PACKAGE ) { Object = StaticLoadObject(PropertyClass, Package, *ObjectNames[ObjectIndex]); } if ( Object ) { // If the selected object is a blueprint generated class, then browsing to it in the content browser should instead point to the blueprint // Note: This code needs to change once classes are the top level asset in the content browser and/or blueprint classes are displayed in the content browser if (UClass* ObjectAsClass = Cast<UClass>(Object)) { if (ObjectAsClass->ClassGeneratedBy != NULL) { Object = ObjectAsClass->ClassGeneratedBy; } } Objects.Add( Object ); } } // If a single actor is selected, sync to its location in the level editor viewport instead of the content browser. if( Objects.Num() == 1 && Objects[0]->IsA(AActor::StaticClass()) ) { TArray<AActor*> Actors; Actors.Add(Cast<AActor>(Objects[0])); GEditor->SelectNone(/*bNoteSelectionChange=*/false, /*bDeselectBSPSurfs=*/true); GEditor->SelectActor(Actors[0], /*InSelected=*/true, /*bNotify=*/true, /*bSelectEvenIfHidden=*/true); // Jump to the location of the actor GEditor->MoveViewportCamerasToActor( Actors, /*bActiveViewportOnly=*/false ); } else if ( Objects.Num() > 0 ) { GEditor->SyncBrowserToObjects(Objects); } } #endif }