Details customization, GetProperty()?

I am using this Wiki page as reference:

The page states that it is for version 4.9, yet it doesn’t seem to be correct. Either that or I am just so tired I am not seeing the obvious. Which is certainly possible.

On that page it mentions using IDetailCategory.GetProperty() to get a property reference. Two big problems with that.

  1. IDetailCategory and IDetailCategoryBuilder are used interchangeably, but the former doesn’t exist. Only IDetailCategoryBuilder exists.
  2. IDetailCategoryBuilder doesn’t have a GetProperty method.

Yeah, that’s either been very poorly updated, or not updated at all and they just stuck a 4.9 flag on it.
Ages ago (4.6 or earlier I think) the GetProperty function was on IDetailCategoryBuilder, but since then was moved to IDetailLayoutBuilder.

It’s a pity because it was one of the most useful and comprehensive pieces of documentation I’d come across back when I first read it. I’ll flag the issue in the documentation forum.

Thanks Kamrann, that seems to be working.

If I might ask, could you maybe give me some guidance on what I am trying to achieve here, since it sounds like you are one of the few people who have delved into this area :slight_smile:

I have properties on my Actor that are of type FString. But instead of being standard text boxes where the user can enter anything, I want to instead present a list of valid choices for that property in a combo box. The documentation seems, like I said above, really incomplete, but it looks like I want to bind the property to a CustomWidget(). The docs mention that I need to provide a function for getting and setting the property value when I do this, but the documentation example doesn’t make sense to me. It shows the method referencing a variable that it shouldn’t have.

  FLOAT GetValueFromProperty()
        // Using the property handle created above, get its value and send it to the spinbox
        INT Value; // note lightmap res is an integer so it must be accessed as such.
        LightMapResValue.GetValue( Value );
        return Value;

How is LightMapResValue getting into that function scope? Is there some magic behind the scenes, or is there something missing in the example?

Yeah it looks like the docs example code has been written more as a rough outline of what to do, it’s clearly not fully functional code.

There are a couple of approaches, but the standard way would be to store the property handle as a member of your customization class.

  float GetValueFromProperty();
  void SetValueOnProperty( float NewValue );

  TSharedPtr< class IPropertyHandle > LightMapResValue;

Assign this inside of CustomizeDetails. Then bind the slate events to methods of your customization class.

SNew( SSpinBox )
              .MinSliderValue( 0 )
              .MaxSliderValue( 1024 )
              .OnValueCommitted_Raw( this, &FMyCustomizationClass::SetValueOnProperty )  
              .Value_Raw( this, &FMyCustomizationClass::GetValueFromProperty )

You can store other stuff as members of your customization class if it helps, for example the IDetailLayoutBuilder pointer, or a pointer to the object(s) being displayed in the details view (you get this from IDetailLayoutBuilder::GetObjectsBeingCustomized, and you should store them in a TWeakObjectPtr).

SComboBox (I’m guessing you may be planning on using it) isn’t exactly the most user friendly. For examples of that and details customization in general, your best bet is to search the engine source code. There are heaps of built in types which have details customizations, and the code for them uses exactly the same process as is used for custom types.

Thanks kamrann, I have it working now.

For anyone in the future who runs into this, a couple gotchas to look at.

If you just build the custom widget in the “obvious” way, you will find that the menu is static. By that I mean the customization will only run once, when the actor is first selected, and then any changes in the properties will not propagate to your custom widget. Obviously you need to hook in functions to be called, as in the SSPinBox example, but it isn’t quite as clear on how to do that with a SComboButton.

The trick is two fold. First for the “ButtonContent” you need to use .Text_Lambda instead of .Text. EG: .Text_Lambda( this->FText {return FText::FromString(Camera->Shot); } )
Secondly, instead of using .MenuContent() to build the menu which appears in the popup, use .OnGetMenuContent(this, &Class::Function) instead.


Sorry to bring up an old post but it’s been 2 years now and the documentation is still saying to use the GetProperty in the IDetailCategoryBuilder

Rebum this issue… nothing has been solved as of this day