#slate

1 messages · Page 26 of 1

lavish carbon
#

you should look at the Output log. the Error window is practically useless for unreal engine developement.

#

make sure there is no implicit cast for outputPin or folderPath. I would try this

FString folderPath = ...; // store them on explicit variables 
EDialogResult outputPin = ...;
// more code
.OnClicked_Raw(this, &FC2MModule::OpenDirectoryDialog, outputPin, folderPath)
#

implicit casts don't work here.

frosty prawn
#
EDialogResult isSuccesful = EDialogResult::Cancelled;
FString folderPath = TEXT("");```
#

Is TEXT(""); not correct for FString?

lavish carbon
#

that does not matter for code compliation.

frosty prawn
#

ok so there's no implicit cast

#

I also tried running that function without slate and it worked

#

so I don't think it's the parameters' type

#

error C2664: 'SButton::FArguments::WidgetArgsType &SButton::FArguments::OnClicked_Raw<FC2MModule,EDialogResult,FString>(UserClass *,FReply (__cdecl FC2MModule::* )(Var1Type,Var2Type),Var1Type,Var2Type)': cannot convert argument 2 from 'FReply (__cdecl FC2MModule::* )(EDialogResult &,FString &,const FString &,const FString &)' to 'FReply (__cdecl FC2MModule::* )(Var1Type,Var2Type)'

#

wait, does it want me to give 4 arguments even though 2 of them ahve defaults?

#

lemme check that

#

C2M.cpp(92): [C2664] 'SButton::FArguments::WidgetArgsType &SButton::FArguments::OnClicked_Raw<FC2MModule,EDialogResult,FString,FString,FString>(UserClass *,FReply (__cdecl FC2MModule::* )(Var1Type,Var2Type,Var3Type,Var4Type),Var1Type,Var2Type,Var3Type,Var4Type)': cannot convert argument 2 from 'FReply (__cdecl FC2MModule::* )(EDialogResult &,FString &,const FString &,const FString &)' to 'FReply (__cdecl FC2MModule::* )(Var1Type,Var2Type,Var3Type,Var4Type)'

#

nah that wasnt it

lavish carbon
#

try const function.

FReply OpenDirectoryDialog(
    EDialogResult& OutputPin, 
    FString& FolderPath,
 //...
) const;
#

notice the const at end. you must put this const in both header and cpp.

frosty prawn
#

same error

#

it keeps saying

cannot convert argument 2 from 'FReply (__cdecl FC2MModule::* )(EDialogResult &,FString &,const FString &,const FString &)' to 'FReply (__cdecl FC2MModule::* )(Var1Type,Var2Type)'
lavish carbon
#

where does const FString & come from?!

frosty prawn
#
FReply OpenDirectoryDialog(
    EDialogResult& OutputPin, 
    FString& FolderPath,
    const FString& DialogTitle = TEXT("Open Directory Dialog"),
    const FString& DefaultPath = TEXT("C:/")
);```
lavish carbon
#

Ah, I see. that's wrong

#

why did i not see that in the first place

frosty prawn
#

I tried completely removing both and staying with just outputPin & folderPath

#

still the same error

#

cannot convert argument 2 from 'FReply (__cdecl FC2MModule::* )(EDialogResult &,FString &)' to 'FReply (__cdecl FC2MModule::* )(Var1Type,Var2Type)'

lavish carbon
#
FReply OpenDirectoryDialog(EDialogResult& OutputPin, FString& FolderPath) const;
frosty prawn
#

oh I had const there, I just removed it now for testing

#

same error with it

#
FReply OpenDirectoryDialog(
            EDialogResult& OutputPin, 
            FString& FolderPath
        ) const;```
```cpp
FReply FC2MModule::OpenDirectoryDialog(
    EDialogResult& OutputPin,
    FString& FolderPath
) const
{
    //ウィンドウハンドルを取得
    void* windowHandle = FC2MModule::GetWindowHandle();

    if (windowHandle)
    {
        IDesktopPlatform* desktopPlatform = FDesktopPlatformModule::Get();
        if (desktopPlatform)
        {
            //ダイアログを開く
            bool result = desktopPlatform->OpenDirectoryDialog(
                windowHandle,
                TEXT("Open Directory Dialog"),
                TEXT("C:/"),
                FolderPath
            );

            if (result)
            {
                //相対パスを絶対パスに変換
                FolderPath = FPaths::ConvertRelativePathToFull(FolderPath);
                UE_LOG(LogTemp, Log, TEXT("Acquired folder path : %s"), *FolderPath);

                UE_LOG(LogTemp, Log, TEXT("Open Directory Dialog : Successful"));
                OutputPin = EDialogResult::Successful;
                return FReply::Handled();
            }
        }
    }

    UE_LOG(LogTemp, Log, TEXT("Open Directory Dialog : Cancelled"));
    OutputPin = EDialogResult::Cancelled;
    return FReply::Unhandled();
}```
lavish carbon
#

forward declare EDialogResult.

#

in your header

#

can you show me the EDialogResult enum?

frosty prawn
#

same error, unless I did not do it right

#

h - enum class EDialogResult : uint8;
cpp

enum class EDialogResult : uint8
{
    Successful, Cancelled
};```
lavish carbon
#

try including header for this enum in your module header

#

it seems enums can't be forward declared.

frosty prawn
#

I have this in my module header, or is it not what u mean enum class EDialogResult : uint8;

lavish carbon
#

yeah, that's what I had in mind, but it didn't work so I would try including the header instead.

#

something like #include "DialogResult.h"; in your module header

frosty prawn
#

its part of my plugin module header, which already is included

lavish carbon
#

enum should come before OpenDirectoryDialog

frosty prawn
#

it does

lavish carbon
#

Ok, try removing the &. so don't pass variables by reference. I know that breaks your logic but just to see if it compiles

#

FReply OpenDirectoryDialog(EDialogResult OutputPin, FString FolderPath);

frosty prawn
#

I just tried removing the EDialogResult argument so we're left with just folderPath, just to see if the issue is EDialogResult and it still doesn't work

#

cannot convert argument 2 from 'FReply (__cdecl FC2MModule::* )(FString &)' to 'FReply (__cdecl FC2MModule::* )(Var1Type)'

lavish carbon
#

ok, remove the &.

frosty prawn
#

oh ok, sec

#

omg I think it worked

lavish carbon
#

you can remove the const too I think.

frosty prawn
#

yeah I did that

#

It worked!!!

lavish carbon
#

apparently you can not pass variables by reference on to slate events.

frosty prawn
#

thank you so much ❤️

lavish carbon
#

A work around would be to declare your variables on the class.

proven pilot
#

If I want a Details panel which implements a property for assets, for example mesh or a camera. Do I have to look into engine code?

Didn't saw anything in the docs, besides SAssetProperty... Does it matter?

deft yacht
#

I've created a template Editor popup Window Plugin. I've created a function in this plugin that prints something on screen. I've added an EditableText to my popup window and I want it to call my Print function when OnTextCommited

#

It seems that the callable function must have certain input parameters like
void FTraceDebugWindowModule::DoSomething(const FText& InText, ETextCommit::Type InCommitType)

#

my editable text
+SVerticalBox::Slot().HAlign(HAlign_Left)
[
SNew(SEditableText)
.OnTextCommitted(this, &FTraceDebugWindowModule::DoSomething)
]

#

changed to OnTextCommited_Raw and now it works

harsh kraken
#

Hey guys, what’s the best way to GetWorld in a slate class?

mild oracle
harsh kraken
#

I’m trying GEngine->GetWorld() but it doesn’t seem to work

mild oracle
harsh kraken
#

Thanks

spring frost
#

If I call TakeWidget on a UUserWidget how do I get back to the UUserWidget from the resulting SWidget?

#

Ah I see, if TakeWidget is called on a UUserWidget its wrapped in a SObjectWidget which holds onto the UUserWidget.

#

🦆

#

Thanks.

devout copper
#

posted this earlier on cpp, with no reply, trying here now.
#cpp message

devout copper
mild oracle
#

It's one of those undocumented UPROPERTY meta props

devout copper
#

figures, it seems like it could just be the default if there's only one property.

#

but, that's what I'm hoping for. It'd be a lot simpler than having to customize an array property.

mild oracle
devout copper
#

Just found "meta TitleProperty", and a possible place with the answer, but I'm still waiting on my UDN access =\

gritty frigate
#

That link doesn't work since they re-did UDN earlier this year, and I can't find a question on the new UDN with the same subject

ionic thunder
#

Has anyone ever used the STextComboBox ? Although I can get it to populate from an options source, when I click to open the widget the editor crashes, with an EXCEPTION_ACCESS_VIOLATION. The strings added as content are stored to shared pointers.

quaint zealot
#

Where it does it crash

ionic thunder
#

the moment the box is clicked.

Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x0000000000000019

UE4Editor_Slate!SListView<TSharedPtr<FString,0> >::ScrollIntoView() [D:\Build\++UE4\Sync\Engine\Source\Runtime\Slate\Public\Widgets\Views\SListView.h:1714]
UE4Editor_Slate!STableViewBase::Tick() [D:\Build\++UE4\Sync\Engine\Source\Runtime\Slate\Private\Widgets\Views\STableViewBase.cpp:254]
UE4Editor_SlateCore!SWidget::Paint() [D:\Build\++UE4\Sync\Engine\Source\Runtime\SlateCore\Private\Widgets\SWidget.cpp:1285]
UE4Editor_Slate!SBox::OnPaint() [D:\Build\++UE4\Sync\Engine\Source\Runtime\Slate\Private\Widgets\Layout\SBox.cpp:293]
UE4Editor_SlateCore!SWidget::Paint() [D:\Build\++UE4\Sync\Engine\Source\Runtime\SlateCore\Private\Widgets\SWidget.cpp:1390]
UE4Editor_SlateCore!SCompoundWidget::OnPaint() [D:\Build\++UE4\Sync\Engine\Source\Runtime\SlateCore\Private\Widgets\SCompoundWidget.cpp:35]
UE4Editor_Slate!SBorder::OnPaint() [D:\Build\++UE4\Sync\Engine\Source\Runtime\Slate\Private\Widgets\Layout\SBorder.cpp:120]
UE4Editor_SlateCore!SWidget::Paint() [D:\Build\++UE4\Sync\Engine\Source\Runtime\SlateCore\Private\Widgets\SWidget.cpp:1390]
UE4Editor_SlateCore!FSlateWindowElementList::FDeferredPaint::ExecutePaint() [D:\Build\++UE4\Sync\Engine\Source\Runtime\SlateCore\Private\Rendering\DrawElements.cpp:735]
UE4Editor_SlateCore!FSlateWindowElementList::PaintDeferred() [D:\Build\++UE4\Sync\Engine\Source\Runtime\SlateCore\Private\Rendering\DrawElements.cpp:760]
UE4Editor_SlateCore!SWindow::PaintWindow() [D:\Build\++UE4\Sync\Engine\Source\Runtime\SlateCore\Private\Widgets\SWindow.cpp:2107]

here a part of the call stack

#

I am adding the options to the cbox like this

  TArray<TSharedPtr<FString>> Options;
  Options.Add(MakeShareable(new FString("Option1")));
  Options.Add(MakeShareable(new FString("Option2")));

  SAssignNew(CBox, STextComboBox)
  .OptionsSource(&Options)
quaint zealot
#

I guess Options is just a local variable and so is destroyed along with its content as soon as the method exits

ionic thunder
#

oh I see, so I need to cache it

split laurel
#

It seems like STextComboBox wants a pointer to the string options and doesn't copy the data over (would need to look inside the source of STextComboBox to make sure), so yes, you need to hold onto the data

craggy holly
#

Anybody know how to create a Struct customisation, that also retains the customisations of internal properties?

#

I'm customising a struct and adding an FText property, but it's losing all of the FTextCustomisation

#

And unfortunately the internal types it uses to do the customisation aren't exposed

#

You'd think CreatePropertyValueWidget(true) would handle this :/

split laurel
#

This surprises me. Can you add a flinearcolor to see if that also loses customization? I believe I did something like this before but it simply worked

craggy holly
#

Yeah sure

#

FLinearColour shows nothing at all

#

It's just blank

#

Feels like a bug or a massive oversight really.

harsh kraken
#

Hey guys, I am trying to call a function from my game instance when I click a button. Calling GEngine->GetWorld()->GetGameInstance() always returns null since slate doesn’t have a world. Any ideas how I should go about this?

quaint zealot
#

Pass an UObject to your UI and store it as a TWeakPtr

harsh kraken
quaint zealot
#

No I don't

#

Slate isn't meant for game development anyway

#

Look at the editor source for Slate examples

mortal echo
#

Does DetailsCustomization just not work for instanced objects?

mild oracle
frosty prawn
#
return SNew(SDockTab)
    .TabRole(ETabRole::PanelTab)
    [
        // Put your tab content here!
        SNew(SBox)
        .HAlign(HAlign_Center)
        .VAlign(VAlign_Center)
        [
            SNew(SButton)
            .HAlign(HAlign_Center)
            .VAlign(VAlign_Center)
            .ButtonColorAndOpacity(FLinearColor::White)
            .ContentPadding(FMargin(12, 4))
            .OnClicked_Raw(this, &FC2MModule::OpenDirectoryDialog, importDirName, FString ("Open C2M Directory"), FString ("C:\\"))
        ]
        SNew(SBox)
        .HAlign(HAlign_Center)
        .VAlign(VAlign_Center)
    ];```
#

why is my sbox not working

mild oracle
mortal echo
# mild oracle Hmmm Im pretty sure I've done that in the past? I think the StyleSheet propertie...

Thanks for that. It doesn't look like it's using the Instanced markup, but doing it manually.
I also found that while it works for an instance (I tested with a light component) placed in a map, it didn't seem to work for an Instanced one is a random data asset. I wonder if it working there is a similar thing where it would work within the UMG details panel but not in a data asset details. I'll have to keep messing with it.

frosty prawn
mild oracle
frosty prawn
#

it wont even compile

frosty prawn
mild oracle
split laurel
#

Yep, needs content. For debugging purposes adding SNullWidget::NullWidget works fine

gritty frigate
#

Also there are two SBoxes in the content of the SDockTab. You can’t add multiple children like that - you need to use a widget with slots for multiple children (SOverlay if you want them on top of each other)

#

TBH, I’m also going to disagree with @mild oracle and @split laurel here - I’m pretty sure that leaving out the content is fine - it should at least compile. Your issue is the two SBoxes not the missing content in the second

gritty frigate
#

I just did a quick test - there is no compile error for having an SBox without content

split laurel
gritty frigate
#

In the example you gave, @frosty prawn, if you wanted one over the other using an SOverlay, you'd want to do:

#
SNew(SDockTab)
.TabRole(ETabRole::PanelTab)
[
  SNew(SOverlay)
  +SOverlay::Slot()
  [
    SNew(SBox)
    // All the rest of the gubbins from the first SBox
  ]
  +SOverlay::Slot()
  [
    SNew(SBox)
    // All the rest of the gubbins from the second SBox
  ]
]```
#

Also, if you look in DeclarativeSyntaxSupport.h, line 407 (on 4.26), where TAlwaysValidWidget is defined, you'll see that it defaults to SNullWidget, so leaving the content empty is the same as adding an SNullWidget

frosty prawn
#

@gritty frigate Thank you!!

gritty frigate
#

You're welcome. One thing to remember with Slate is that there are 3 types of widget:

  • No children
  • Single child (add [] directly to the widget, like SDockTab in your example)
  • Container (add slots with +SWidgetType::Slot() and then add [] to each slot, like SOverlay)
frosty prawn
#

works flawlessly, thanks alot guys ❤️

#

what is the alternative to SDockTab to get a window like this that has no tabs and the size of the window cannot be adjusted?

#

unfortunately it doesn't work well with widget reflector (info about it disappears as soon as window closes)

craggy holly
#

That is an SWindow IIRC

#

IIRC that widget is in FbxImportUIDetails

#

FbxMainImport.cpp line 256 in UE 4.25

#

That's where it creates the Modal Window

#

Then FSlateApplication::Get().AddModalWindow()

frosty prawn
#

found in 4.27, thanks! 🙂

gritty frigate
#

In any widget that overrides OnPaint, my understanding was that you had to increment LayerId for every draw call you make.
I was looking at SImage::OnPaint(), and I noticed that they don't do this in there - they pass LayerId through to FSlateDrawElement::MakeBox(), and then return the same one that they were given.
Is this an oversight in SImage, or have I misunderstood something?

ionic thunder
#

I am trying to set the style of an STextComboBox. However the downArrow image does not seem to set up correctly, I would say is not set at all. Any ideas on solving this ?

here the code for the style:

CustomStyleSet->Set("CBoxBranches", FComboButtonStyle()
    .SetDownArrowImage(BOX_BRUSH(TEXT("branch_64-64"), Icon24x24)));

code for the actual ComboBox

SAssignNew(BranchesCBox, STextComboBox)
.ComboBoxStyle(CustomStyle::Get(), "CBoxBranches")
.OptionsSource(&BranchesCBoxContent)
.OnSelectionChanged(this, &SpecPanel::OnBranchesDropdownChanged)
frosty prawn
#

hey guys, I have this basic window that lets a user select folder, and I'm trying to get the selected folder to the editable textbox. how do I make it update with the selected folder?

return SNew(SWindow)
    .SizingRule(ESizingRule::Autosized)
    .AutoCenter(EAutoCenter::None)
    .ClientSize(C2MImportWindowSize)
    .ScreenPosition(WindowPosition)
    [
        SNew(SVerticalBox)
        + SVerticalBox::Slot()
        .AutoHeight()
        .Padding(3.0f, 1.0f)
        [
        // Put your tab content here!
            SNew(SBox)
            .HAlign(HAlign_Center)
            .VAlign(VAlign_Center)
            .WidthOverride(400)
            .HeightOverride(40)
            [
                SNew(SButton)
                .HAlign(HAlign_Center)
                .VAlign(VAlign_Center)
                .ButtonColorAndOpacity(FLinearColor::White)
                .ContentPadding(FMargin(12, 4))
                .Text(FText::FromString("Load Directory"))
                .OnClicked_Raw(this, &FC2MImportUI::OpenDirectoryDialog, folderPath, FString ("Open C2M Directory"), FString ("C:\\"))
            ]
        ]
        + SVerticalBox::Slot()
        .VAlign(VAlign_Center)
        .HAlign(HAlign_Left)
        .AutoHeight()
        [
            SNew(SBox)
            .WidthOverride(200)
            [
                SNew(SHorizontalBox)
                +SHorizontalBox::Slot()
                .AutoWidth()
                [
                    SNew(SBox)
                    .WidthOverride(300)
                    [
                    SAssignNew(importPathBox, SEditableTextBox)
                    .BackgroundColor(FSlateColor(FLinearColor(FColor::White)))
                    .Text(FText::FromString(folderPath))
                    ]
                ]
            ]
        ]
    ];```
#

FString folderPath = "<default path>";

split laurel
#

Either you create a delegate for the text field so it executes a function each frame to determine the path text, or, if it exists, you need to register to a delegate of the directory window that is executed whenever folder selection changes, and then manually update the text via importPathBox->SetText or the likes

#

If it's a modal/blocking window you might also be able to retrieve the new path from results and then just update it manually

sharp zinc
#

Hi, can anybody point me to a way to add a localizable FText on a details customization panel?
The simple handle exposure with IPropertyHandle seems not to expose the localizable window with the down arrow that can be seen with the default UPROPERTY(EditAnywhere) specifier.

#

I can see that the source code mentions TSharedRef<IEditableTextProperty> EditableTextProperty = MakeShareable(new FEditableTextPropertyHandle(Handle, CachedDetailBuilder->GetPropertyUtilities())); but FEditableTextPropertyHandle is in an anonymous namespace so it is not accessible from outside its own file which leads me to think there is another way to do this.

mild oracle
prisma lark
#

Hello guys!! Maybe someone knows how can i handle Ctrl+C Ctrl+V in my slate widget??

prisma lark
#

And why you can't use LOCTEXT macro

frosty prawn
#

even then how do I make it execute the get function every time the import dialog selects a file? I need to update the textbox to have the path in it

split laurel
#

essentially yes.
Slate attributes (attributes as opposed to arguments) can either contain direct values or delegates. In your example you are setting the text directly by simply giving it a text value.
You can however also instead use the following as an argument

.Text(this, &MyClass::FunctionWithReturnFText)
frosty prawn
#

will it update everytime I select a new path?

split laurel
#

this will call the function every frame to determine the file path as text

#

you'd need to get the file path yourself

#

the alternative is to check what the directory window is giving you yourself

frosty prawn
#

I have a button that opens a file dialog and sends the selected path back to FString var

#

and Im creating a get func that returns that var as FText

split laurel
#

yep that should work

frosty prawn
#

I will test that soon, thanks a lot mate!

split laurel
#

sure! Slate is not well covered online and there is a lot of trial & error involved in first learning it

frosty prawn
#

@split laurel Hey mate, I tried what you said now and I'm not sure why it won't compile.
cpp-

return SNew(SWindow)
    .SizingRule(ESizingRule::Autosized)
    .AutoCenter(EAutoCenter::None)
    .ClientSize(C2MImportWindowSize)
    .ScreenPosition(WindowPosition)
    [
        SNew(SVerticalBox)
        + SVerticalBox::Slot()
        .AutoHeight()
        .Padding(3.0f, 1.0f)
        [
        // Put your tab content here!
            SNew(SBox)
            .HAlign(HAlign_Center)
            .VAlign(VAlign_Center)
            .WidthOverride(400)
            .HeightOverride(40)
            [
                SNew(SButton)
                .HAlign(HAlign_Center)
                .VAlign(VAlign_Center)
                .ButtonColorAndOpacity(FLinearColor::White)
                .ContentPadding(FMargin(12, 4))
                .Text(FText::FromString("Load Directory"))
                .OnClicked_Raw(this, &FC2MImportUI::OpenDirectoryDialog, folderPath, FString ("Open C2M Directory"), FString ("C:\\"))
            ]
        ]
        + SVerticalBox::Slot()
        .VAlign(VAlign_Center)
        .HAlign(HAlign_Left)
        .AutoHeight()
        [
            SNew(SBox)
            .WidthOverride(200)
            [
                SNew(SHorizontalBox)
                +SHorizontalBox::Slot()
                .AutoWidth()
                [
                    SNew(SEditableTextBox)
                    .BackgroundColor(FSlateColor(FLinearColor(FColor::White)))
                    .Text(this, &FC2MImportUI::GetMyText)
                ]
            ]
        ]
    ];
}

FText FC2MImportUI::GetMyText() const
{
    return FText::FromString(folderPath);
}```
header
```hpp
FString folderPath = "<default path>";
FText GetMyText() const;```
#

I'll show u the error in 1 moment

split laurel
#

Chances are your FCM2ImportUI class doesn't inherit from TSharedFromThis<FCM2ImportUI> is that right?

frosty prawn
#

this is my class -

class FC2MImportUI : public IModuleInterface
{
public:
    static void* GetWindowHandle();
    enum class EDialogResult : uint8
    {
        Successful, Cancelled
    };
    FReply OpenDirectoryDialog(
        FString FolderPath,
        FString DialogTitle = TEXT("Window Title"),
        FString DefaultPath = TEXT("C:/")
        );
    TSharedRef<class SDockTab> OnSpawnPluginTab(const class FSpawnTabArgs& SpawnTabArgs);
    FText GetMyText() const;
    TSharedRef<class SWindow> CreateC2MImportWindow();
    FString folderPath = "<default path>";
private:
};
split laurel
#

yep, can't by default create shared ptrs from that class

frosty prawn
#

I'm not so sure what that means pepoDetective

low bluff
#

It means your class is not setup to be used as a shared pointer. You can probably find online how to do that. Or look at source code of classes that support it.

split laurel
#

you can either additionally inherit from TSharedFromThis<FCM2ImportUI> (although I'm not sure if that's a good idea with a module), or you can just create one by using other means. CreateRaw would work for example

#

wait a sec

frosty prawn
#

I know how to make it use inherit fromTSharedFromThis<FCM2ImportUI>, but what if I need to inherit from IModuleInterface?

split laurel
#

you can inherit from both

#

as an example, the reason why this works by default from inside widgets is because SWidget is defined as shown here. No need to set that inheritance up

frosty prawn
#

oh ok I see now

#

so in my case it would be class FC2MImportUI : public IModuleInterface, public TSharedFromThis<FC2MImportUI>

split laurel
#

alternatively

TAttribute<FText> TextAttribute = TAttribute<FText>::CreateRaw<>(this, &SNiagaraSystemEffectTypeBar::GetText);
PropertyWidget = SNew(STextBlock).Text(TextAttribute);

works as well

#

same pattern applies for you, just renamed classes and functions

#

yep, but I wouldn't do that, because sharedptrs are meant to manage lifetime of an object and doing this with module could have unwanted sideeffects

#

CreateRaw is quite safe here because the lifetime of your module is pretty much not an issue whatsoever

frosty prawn
#

doesn't seem like there's TAttribute<FText>::CreateRaw<>

split laurel
#

which version are you using?

frosty prawn
#

only TAttribute<FText>::Create, which teakes FName instead of FText

#

of unreal? 4.27

split laurel
#

yep. I was on ue5 right now. Let me check 4.27 source

#

but in any case, the process should be similar, but I don't know about that FName one

#

the Create function is overloaded, you should be able to do the same

frosty prawn
#

I changed my gettext function to return FName and tried using it with Create, but it gives me this

split laurel
#

yeah that's not going to help, the FName one is for calling UFunctions via reflection I believe. TAttribute<FText> directly means the function you bind to it returns an FText

#

have you tried doing my code sample above just with Create instead of CreateRaw<>?

frosty prawn
#

yeah it won't work because &FC2MImportUI::GetMyText is FText and Create expects FName

split laurel
#

I don't think that's quite right but okay, then do this

frosty prawn
#

TAttribute<FText> TextAttribute = TAttribute<FText>::Create<>(this, &FC2MImportUI::GetMyText);

split laurel
#
TAttribute<FText> TextAttribute;
TextAttribute.BindRaw(this, &FCM2ImportUI::GetMyText);
#

the static Create functions are just there to help with creation, binding on an existing attribute should be the same

frosty prawn
#

ok it builds and works, now I need to make the textbox update everytime the import dialog is used via the button

#
return SNew(SWindow)
    .SizingRule(ESizingRule::Autosized)
    .AutoCenter(EAutoCenter::None)
    .ClientSize(C2MImportWindowSize)
    .ScreenPosition(WindowPosition)
    [
        SNew(SVerticalBox)
        + SVerticalBox::Slot()
        .AutoHeight()
        .Padding(3.0f, 1.0f)
        [
        // Put your tab content here!
            SNew(SBox)
            .HAlign(HAlign_Center)
            .VAlign(VAlign_Center)
            .WidthOverride(400)
            .HeightOverride(40)
            [
                SNew(SButton)
                .HAlign(HAlign_Center)
                .VAlign(VAlign_Center)
                .ButtonColorAndOpacity(FLinearColor::White)
                .ContentPadding(FMargin(12, 4))
                .Text(FText::FromString("Load Directory"))
                .OnClicked_Raw(this, &FC2MImportUI::OpenDirectoryDialog, folderPath, FString ("Open C2M Directory"), FString ("C:\\"))
            ]
        ]
        + SVerticalBox::Slot()
        .VAlign(VAlign_Center)
        .HAlign(HAlign_Left)
        .AutoHeight()
        [
            SNew(SBox)
            .WidthOverride(200)
            [
                SNew(SHorizontalBox)
                +SHorizontalBox::Slot()
                .AutoWidth()
                [
                    SNew(SBox)
                    .WidthOverride(300)
                    [
                    SAssignNew(importPathBox, SEditableTextBox)
                    .BackgroundColor(FSlateColor(FLinearColor(FColor::White)))
                    .Text(TextAttribute)
                    ]
                ]
            ]
        ]
    ];```
#

here's how it currently looks like

split laurel
#

looking good. Is your text attribute simply returning folderPath?

#

If so you only need to update folderPath when the user has selected a directory. So something like:

void FCM2ImportUI::OnDirectoryChosen(FString Path)
{
  folderPath = Path;
};

that's it. The text will automatically update then

frosty prawn
#

you see OpenDirectoryDialog function inside the button

#

that one takes folderPath and updates it

split laurel
#

does it actually update the original folderPath variable though? Because if so the text should automatically update as well

#

can you show me the OpenDirectoryDialog function?

frosty prawn
#
Reply FC2MImportUI::OpenDirectoryDialog(
    FString FolderPath,
    FString DialogTitle,
    FString DefaultPath
)
{
    void* windowHandle = GetWindowHandle();
    EDialogResult OutputPin = EDialogResult::Cancelled;
    if (windowHandle)
    {
        IDesktopPlatform* desktopPlatform = FDesktopPlatformModule::Get();
        if (desktopPlatform)
        {
            bool result = desktopPlatform->OpenDirectoryDialog(
                windowHandle,
                DialogTitle,
                DefaultPath,
                FolderPath
            );

            if (result)
            {
                FolderPath = FPaths::ConvertRelativePathToFull(FolderPath);
                UE_LOG(LogTemp, Log, TEXT("Acquired folder path : %s"), *FolderPath);
                UE_LOG(LogTemp, Log, TEXT("Open Directory Dialog : Successful"));
                OutputPin = EDialogResult::Successful;
                return FReply::Handled();
            }
        }
    }

    UE_LOG(LogTemp, Log, TEXT("Open Directory Dialog : Cancelled"));
    OutputPin = EDialogResult::Cancelled;
    return FReply::Unhandled();
}```
#

as u can see in my .OnClicked_Raw, folderPath is the first variable (FolderPath inside the dialog function)

#

and its the same variable that GetMyText returns as FText

split laurel
#

ah yes, you are not properly updating the original though. Your parameter is given by value, not by reference, so the update inside the if (result) will be lost

#

change the signature to

Reply FC2MImportUI::OpenDirectoryDialog(
    FString& FolderPath,
    FString DialogTitle,
    FString DefaultPath

and it should work

#

you could also just write to folderPath directly

frosty prawn
#

I didnt do that so I can use that function for other dialogs/values

split laurel
#

makes sense, then the reference version is the one you should use

frosty prawn
#

as soon as I changed FString FolderPath to FString& FolderPath, it won't take accept folderPath anymore

split laurel
#

what's the error? Also use the output tab instead of the error list

frosty prawn
#
Error C2664 : 'SButton::FArguments::WidgetArgsType &SButton::FArguments::OnClicked_Raw<FC2MImportUI,FString,FString,FString>(UserClass *,FReply (__cdecl FC2MImportUI::* )(Var1Type,Var2Type,Var3Type),Var1Type,Var2Type,Var3Type)': cannot convert argument 2 from 'FReply (__cdecl FC2MImportUI::* )(FString &,FString,FString)' to 'FReply (__cdecl FC2MImportUI::* )(Var1Type,Var2Type,Var3Type)'```
split laurel
#

mhhh not entirely sure. Have you changed the signature in both header and cpp?

frosty prawn
#

folderPath is FString

#

yeah

#
FReply OpenDirectoryDialog(
    FString& FolderPath,
    FString DialogTitle = TEXT("Window Title"),
    FString DefaultPath = TEXT("C:/")
    );```
#

.OnClicked_Raw(this, &FC2MImportUI::OpenDirectoryDialog, folderPath, FString ("Open C2M Directory"), FString ("C:\\"))

split laurel
#

let me try something out real quick

#

I know a couple ways to go around this but I'd like to know why exactly this isn't working. Perhaps you can't use references with raw delegates because it can't be ensured that the reference will still be valid later

#

seems references just generally don't work with delegates using variadic arguments. Ok

#

in that case you can probably do it via pointer instead

#

so

FReply OpenDirectoryDialog(
    FString* FolderPath,
    FString DialogTitle = TEXT("Window Title"),
    FString DefaultPath = TEXT("C:/")
    );

and

.OnClicked_Raw(this, &FC2MImportUI::OpenDirectoryDialog, &folderPath, FString ("Open C2M Directory"), FString ("C:\\"))
frosty prawn
split laurel
#

put a * in front of that

frosty prawn
#

oh f me

split laurel
#

desktopPlatform->OpenDirectoryDialogdoesn't want a a pointer but a value, so we dereference the pointer again

frosty prawn
#

it works !!!

#

thank you for your time mate, I really appreciate it!

split laurel
#

finally! :)

#

glad it worked out in the end

frosty prawn
#

❤️

mild oracle
#

We're having a really weird crash on SWidget::AssignIndices called from FSlateInvalidationRoot::BuildFastPathList... Has anyone seen this?
Really grasping at straws here

upbeat pebble
#

Is there some way to intercept all mouse down/touch events from bp or cpp? If so can somebody point me in the right direction?

#

Basically I want to know where I would put this code

rain heron
#

okay... idk why that is the case... but when i have a leaf widget, and that leaf widget creates draw elements... it looks like those wont get cleaned up causing a memory leak...
is there something i have missed?

mild oracle
rain heron
mild oracle
frosty prawn
#

Hello, I'm trying to make a function that sets and returns SHorizontalBox, so I can add it using SAssignNew(), but it doesn't seem to do anything..
here's the function

TSharedPtr<SHorizontalBox> SC2MOptionsWindow::AddNewLine(FText InKey, FText InValue)
{
    return SNew(SHorizontalBox)
                + SHorizontalBox::Slot()
                .AutoWidth()
                [
                    SNew(STextBlock)
                    .Font(FEditorStyle::GetFontStyle("CurveEd.LabelFont"))
                    .Text(InKey)
                ]
                +SHorizontalBox::Slot()
                .Padding(5, 0, 0, 0)
                .AutoWidth()
                .VAlign(VAlign_Center)
                [
                    SNew(STextBlock)
                    .Font(FEditorStyle::GetFontStyle("CurveEd.InfoFont"))
                    .Text(InValue)
                ];
}```
#

here's how I add it

TSharedPtr<SBox> ImportMapHeaderDisplay;
TSharedPtr<SHorizontalBox> TestBox = SC2MOptionsWindow::AddNewLine(FText::FromString("asd"),FText::FromString("qwe"));

ImportMapHeaderDisplay->SetContent(
    SNew(SBorder)
    .Padding(FMargin(3))
    .BorderImage(FEditorStyle::GetBrush("ToolPanel.GroupBorder"))
    [
        // Add map name to our info display
        SNew(SVerticalBox)
        + SVerticalBox::Slot()
        .AutoHeight()
        [
            SAssignNew(TestBox, SHorizontalBox)
        ]
    ]
);```
#

it works if I dont use the function and just add it the way I do inside the function, but I wanna avoid copy pasting the same few lines for each line I add

quaint zealot
#

SNew doesn't return anything

#

Try SAssignNew with a temporary shared ptr to return

#

And I mean, no, that should work but the SAssignNew(TestBox, SHorizontalBox) line is just wrong

#

You're literally erasing the function's result here

split laurel
#

^

#

to add to that, if you have a sharedptr to a valid widget already and just want to put into a slot it looks like this:

 // Add map name to our info display
        SNew(SVerticalBox)
        + SVerticalBox::Slot()
        .AutoHeight()
        [
            TestBox.ToSharedRef()
        ]
frosty prawn
#

TestBox.ToSharedRef() does the job, thanks!

frosty prawn
tired valley
#

does anyone here have any recent examples of using SMeshWidget?

warm vault
#

Is it possible to use SNew and construct your widgets from a UUserWidget?

trim kestrel
#

Does anyone know how I can access the slot offset properties of a UImage from c++? I have a base class already, I just can't seem to find the property to change it

gritty frigate
#

Those are properties on the canvas panel slot, not the Image.

#

You’d need to call CanvasPanel->AddSlot() with the SImage as a child and store the returned slot

trim kestrel
wild pumice
#

How do I implement a custom Graph Panel? I made my own SCustomGraphPanel and SCustomGraphEditor but I'm not able to use the graph panel. I'm using the custom graph editor which has a function called GetGraphPanel() which doesn't seem to be called anywhere (I put breakpoint and it never hit after opening the graph editor). It seems SGraphEditorImpl implements graph panel but it is created in a private function which I cannot override.

#

Most of the useful stuff seems to be locked behind private scope

silk vault
molten widget
#

How can I just fill with color?

#

I just want to fill entire overlay slot with white color

#

SColorBlock

fossil kayak
#

use SBorder maybe?

molten widget
#

Also good. Thank you. Prolly SColorBlock works for me

wild pumice
tired harness
#

I am trying to get an SScaleBox to not scale larger than the desired size of its content.
I am using .Stretch(EStretch::ScaleToFit)

SButton
[
    SNew(SScaleBox)
    .Stretch(EStretch::ScaleToFit)
    [
         .SNew(STextBlock)
    ]
]
#

In UMG the default behaviour of these appears different.
With this slate code what happens is that scale box takes up the entire size of the button its in

#

And the text scales with the scalebox. So a big button results in massive text

#

I tried a bunch of different stretch options but whatever the magic combination is that makes it work, I have not yet found it

split laurel
#

haven't looked into it but can you change alignment of the SScaleBox to be center? Think it defaults to fill so the scale box will attempt to fill its parent rather than just letting its children elements dictate its size

tired harness
#

yeah I tried setting the HAlign and VAlign to center previously.

#

I think I can delete my own question since I ended up just throwing up my hands and using UMG

split laurel
#

no point in deleting, it might be of use to anyone coming across :)

#

UMG just wraps around Slate though so there is a solution to this problem

tired harness
#

completely unrelated, but do you happen to be one of the wizards that understands editor slate?

split laurel
#

that's what slate is for so yes I guess so. I do work with it daily

tired harness
#

I dont think there is a seperate place for editor slate questions so I guess I might as well ask here.
Do you happen to know if it possible (and roughly how) to have an extra sub group in the details panel of an array of structs? I tried messing around with IDetailBuilder and some other but couldnt make it work at all. That stuff is just slate wrappers right?

split laurel
#

I'm curious though, how did you create the 2nd video showcasing the slate behavior? Did you expose that widget to UMG to create it?

tired harness
#

the second video is using a duplicate class of UButton

#

since a few members that I needed access to where protected I decided to just duplicate the UButton.h/cpp in its entirety and add the changes there

split laurel
#

I understand

#

basically you want to insert some widgets between array entries? That's definitely more advanced than the typical details customization needs.
You might be able to do this using an FDetailArrayBuilder subclass

#

the DetailBuilder accepts multiple ways of customizing property UI, one of them is via a custom builder.
An example can be found in FNiagaraDataInterfaceSkeletalMeshDetails.cpp where the array builder is instantiated and registered, and then the FNiagaraDetailSourcedArrayBuilder

tired harness
#

right so basically.

DetailView
-> Struct
    -> Array of Structs
        -> (0)
            -> Value one
            -> Value two
              -> Some sort of group indent so I can group values, like the way category drop downs work
            -> Some other values
#

Do you happen to know of the top of your head where that is used so I can look at the generated UI in the editor and see if that is what I am after?

#

I am kinda just theorizing that the names I use to describe what I want is the same thing in slate

split laurel
#

this isn't used like you would like it used, that's why I'm not 100% confident that it works for your case

tired harness
#

well, it seems like when a struct is part of an array all its categories dont show up

#

so that is what I am trying to solve essentialy

split laurel
#

but if you want to take a look, if you create any niagara system, and add a skeletal mesh user parameter, then go to user parameter defaults in the system node, you get a "filtered bones" array. Internally, it's just a TArray<FName>. The UI is customized per row though, and you might be able to insert custom widgets after a typical row

tired harness
#

I will take a look right now

#

I dont think that is what I am after, at least I can't tell visually

split laurel
#

that's what I figured, yes

tired harness
#

hmm let me boot up an empty project so I can use screenshots, which is a much better way to explain UI than text could ever be

split laurel
#

I realized you want to customize the struct UI inside the array; I thought you want to insert something between elements of the array. In that case customizing the struct itself might work. Using a property row generator for that struct, iterating over the property tree nodes and adding the category widgets back might also work

tired harness
#

well in any case, its clearly possible then

#

and i just need to figure out what I need to do

#

online resources are kinda scarce on the topic and for some reason never include any images. (UI code reference without screenshots of the result are kinda pointless)

split laurel
#

true, this stuff is essentially not covered at all. A couple blogs include some information, some good, some bad, but rare regardless

tired harness
#

Thats why I figured I would use this golden opportunity to just ask you while you happen to be here.
Still going to have to bang my head against a proverbial brick wall for the next 20 hours or so before I can make it work most likely but at least I know now that it CAN be made to work

split laurel
#

it should be possible but you might run into some troubles. While the property editor module (including the details panel) is fairly flexible there are always some hidden limitations that also aren't clear to me

tired harness
#

Huh, I cant find the message you posted anymore. I could swear you mentioned some arraybuilder

tired harness
#

ah yes there it is. FDetailArrayBuilder

#

so is the DetailArrayBuilder used for the array itself, or the struct inside the array?

split laurel
#

that's used to customize the display of an array. But I posted this when I assumed you wanted to insert widgets between array elements

tired harness
#

ah right

#

yeah no thats fine.
The UPROPERTY array can just be displayed as
(0)
(1)
(2)
and I guess meta = (TitleProperty = "Some Name") can be used to modify what is displayed to the right of that easily

#

i just care about modifying how the
UStruct
and its UPROPERTY members are displayed once you expand the array

#

is it the IDetailCustomization perhaps?

split laurel
#

for struct customization you'd typically use a IPropertyTypeCustomization IIRC

#

good example here would be the FColorStructCustomization

tired harness
#

alright, well its getting pretty late. I will try it out some more tomorrow. Thanks a lot for the help though!
I wish I knew some editor customization wizard sitting somewhere that I could poke all day and who would be happy to share his arcane knowledge

split laurel
#

I feel the same way about some seniors on my team but alas we all have things to do hahah

#

and glad to help, I frequently check this channel but I don't necessarily post frequently

tired harness
#

I sometimes post here and then leave for a day or two. I think #cpp is where all the action is. Barely any slate people around

split laurel
#

by the way, while I haven't tested the slate version, I have tested your scalebox setup in UMG and when the scale box alignment is set to fill rather than center it does behave like your slate video, and from looking at source code the default alignment seems to be the only difference I could spot at a glance.
UScaleBoxSlot is initialized to use center-alignment whereas SScaleBox will initialize to use fill alignment, so maybe your test was off somehow?

pseudo patrol
#

hi!

#

I add a SImage to my slate ui and get the checkerbaord image. When I call SetImage() on it with a brush created like this slatebrush = new FSlateMaterialBrush(*mat, FVector2D(32, 32));, that material gets shown instead. but after 60 s it disappears. if I don't assign the brush, the checkerboard stays forever

#

how to I assign a material/brush in a way it does not get garbage collected?

quaint zealot
#

Longer answer, using any persistent UObject with UPROPERTY

pseudo patrol
#

hmm. what exactly gets garbage colelcted? The SImage? The brush?

quaint zealot
#

The material

#

Slate brushes and images are not UObjects and thus cannot be GC

pseudo patrol
#

oh the material of the brush

#

so I additionally put it as a uproperty in a UObject so it doesn't get collected?

quaint zealot
#

Or use UMG which is designed to handle materials

dry ice
#

Hey, I was hoping to get some advice. I'm trying to make a crosshair for my game, and I want to avoid using a rasterized texture/icon for it, and instead use vector graphics.

Initially I read a little bit about "SMeshWidget", but I read something saying that "FSlateDrawElement" is what I should be using for drawing a specific geometric shape.

rocky abyss
#

You could use SDFs as they are math generated shapes that can scale like vectors but not really bezier based. No need to quite program your own geometry. But I am curious if you do end up with drawing something in the SMeshWidget how it turns out

quaint zealot
#

Or just use materials directly

dry ice
dry ice
quaint zealot
#

The aliasing will be a problem with Slate meshes too since it's post-antialiasing

#

Only textures or pixel-perfect geometry can get clean unaliased results in UI

dry ice
quaint zealot
#

First, note that by default in UMG and Slate everything is pixel snapped (so a 0.5px high line will be sometimes 0, sometimes 1px high) so it's always pixel perfect, though the rounding may be offputting in some cases, and can be disabled per object at least in Slate

#

Text rendering is a dedicated system, with its own AA

#

And text is specifically rasterized too, it doesn't show up as geometry

#

SDFs can and will produce unaliased results, since usually they're essentially textures, with mipmapping and filtering

dry ice
#

so then what options do I have?

rocky abyss
#

I wrote something a while ago but SDFs in theory don't have aliasing if you just adjust the smooth step

quaint zealot
#

For a crosshair, the simplest option is to use a texture ! If your crosshair cross is 2px wide, it will work perfectly with no effort at all

#

If you need it to be say, 1px wide, you can see that there can be no perfect solution

#

It'll boil down to filtered textures, or SDFs

#

If you have animated or parametric shapes, you can have multiple crosshair elements using textures

#

Or you can use a single SDF too

dry ice
#

thanks a lot for the help! I think I think I'm gonna go with using an SDF. And if that doesn't work then I'm just gonna use textures.

zenith cedar
#

Hi guys i am making inventory but i have no ideas about the inventory with different items size like this picture .

anyone have any ideas? Thanks

fossil kayak
#

I have some uproperties and I want to create a widgets to edit them manually, what is the best way to do this? is there some kind of a function that will return me a widget if I pass it a uproperty? that would be handy

lavish carbon
#

@fossil kayak IPropertyHandle has CreatePropertyValueWidget and CreatePropertyNameWidget. you have to create a detail customization.

fossil kayak
lavish carbon
#

Unfortunately you can't. IPropertyHandle is only accessible from IDetailLayoutBuilder. These are editor only by the way.

fossil kayak
#

oh so yeah, I checked out the source code and it turns out those property widgets are strongly bound to the object that these properties come from, so unless I want to copy paste the entire property widget generation code from source code I will need to do it some other way, I think if I spawn some sort of a shadow object and use IDetailsView with customization to show only properties that im interested in that will do the trick

split laurel
#

There are a couple ways you can approach this. All of those ways work via the propertyeditormodule that exposes accessors for UI generation. Be it a details panel that you customize via arguments, general details customisation that will customize all details panels, property row generators to build widgets for individual properties.. the latter you can make work with just a UObject or UStruct.
The property row generator will let you access the detail tree node structure, and for each of these you can individually create widgets however it seems fit.

#

If you basically want a details panel that only shows specific properties, you can create a new details panel and give it a custom filter. That filter lets you check fproperties for inclusion or exclusion

#

You can then either hardcode the included properties via name, or just give the relevant properties a meta tag that you can check for

#

You can do completely custom widgets too, just need a way to instantiate the widgets (in a new window or tab for example) and a pointer or reference to the data that should get modified. The disadvantage here is that you aren't doing this via propertyhandles so you lose default functionality like the revert to default button, or undo redo support

fossil kayak
#

oh okay, I see it now, unfortunately none of these will work for me since what I wanted to achieve is to collect the properties with meta flag from the CDO, then create widgets for those properties, set some values in them and then copy those values when placing instances of the object

fossil kayak
fossil kayak
split laurel
#

since you only wanted to show specific properties, put some markup on them via meta tag, and then check inside the filter for that tag. This way you only get those properties and since it's using the details panel you get all the default functionality @fossil kayak

fossil kayak
split laurel
#

yes. If you don't use customizations, but instead create a new details panel via fpropertyeditormodule, the creation function takes arguments and you can register a custom filter with that details panel

fossil kayak
#

if not, imma just iterate over all of the properties and hide them

split laurel
#

if you do it via details customization, then yes, you can also just hide all of them by default and then only show the ones with the meta tag

fossil kayak
#

yeah, could you elaborate a bit? I only see this filter in detail view args

    /** Optional object filter to use for more complex handling of what a details panel is viewing. */
    TSharedPtr<FDetailsViewObjectFilter> ObjectFilter;
#

im not sure which filter you are talking about

split laurel
#

let me open up unreal

#

it's not in the args, it's a function you can call on the created details view object

#

SetIsPropertyVisibleDelegate

fossil kayak
#

omg, how could I miss it

#

yeah, there it is, I was checking this class a few times and found only the version for custom rows and somehow missed this one, thank you very much and sorry for bothering you

split laurel
#

don't stress it, if I didn't want to help I wouldn't

fossil kayak
# split laurel SetIsPropertyVisibleDelegate

do you know by any chance how to hide the Transform category? i hid everything else using this delegate and only the Actor and Transfrom categories were left, so I hid the Actor category using customization but it unfortunately doesn't work for transform

split laurel
# fossil kayak do you know by any chance how to hide the Transform category? i hid everything e...

hmmm I don't really know. What I do know is that customized categories can show up despite that custom filter correctly disregarding a property (I was confused for a whole while while debugging this). Turns out overriding a customization for that details panel for that property basically reset that customization so internally it was no longer considered "customized", and would be filtered out correctly.

I believe I've done this by calling something like

DetailsView->RegisterInstancedCustomizationType(StructName, DetailsView->GetGenericCustomization());

or something along those lines

#

it could also be that transform is such an important special case that you just can't get rid of it

fossil kayak
#

hmm, okay, thanks, i will try that

fossil kayak
#

okay, so I looked at the source code and found how the transform category is added

if (!HideCategories.Contains(TEXT("Transform")))
{
    AddTransformCategory(DetailLayout);
}

so I managed to hide it by doing this in my customization that is applied only to my particular details view

DetailBuilder.GetBaseClass()->SetMetaData(TEXT("HideCategories"), TEXT("Transform"));
split laurel
#

that's great! Does DetailBuilder.GetBaseClass() return the class of the object that is being modified? It irks me a little to set meta data on a class object because the CDO is being modified. On the other hand, if it's only a specific class or set of classes that you want to display in the details view, you could also probably just add the HideCategories meta data to the UCLASS itself, no?

#

but even if so, not a big deal. Good job on finding this 👍

fossil kayak
#

Does DetailBuilder.GetBaseClass() return the class of the object that is being modified
yeah it seems so
On the other hand, if it's only a specific class or set of classes that you want to display in the details view, you could also probably just add the HideCategories meta data to the UCLASS itself, no?

    TArray<TWeakObjectPtr<UObject>> Objects;
    DetailBuilder.GetObjectsBeingCustomized(Objects);
    for (TWeakObjectPtr<UObject>& It : Objects)
    {
        It->GetClass()->SetMetaData(TEXT("HideCategories"), TEXT("Transform"));
    }

yeah, if it is what you meant it works as well and is probably a better way to do it, didn't think of the CDO, thanks

split laurel
#

Sorry, I wasn't being clear. That right there would be the same thing as your previous solution because you are still modifying the class CDO.
What I meant is going into your actor class that you want to display, and quite literally writing down the hide categories transform flag into the UCLASS() macro so you will only set that meta data for the classes you want to display

#

On the other hand, can't you just call hidecategory in the detailsbuilder itself? This way you don't need to change meta data at all

fossil kayak
lavish carbon
#

you can hide transform, it's just unusual category name. you need to hide TransformCommon category. @fossil kayak @split laurel

split laurel
#

Hah, interesting. Good to know. Thank you!

fossil kayak
#

oh, yeah it worked, thanks mate

glad elm
#

Hello, I heard I can achieve this type of thumbnail with a SMeshWidget. Currently I'm using a scene capture component and render target and an UImage. I read SMeshWidget is not something to easy to work with from #slate 's message history. That'll be my first time with Slate framework, can anyone recommend some resources about SMeshWidget and Slate?

craggy holly
#

SMeshWidget isn't for drawing actual meshes - it's for drawing a lot of the same thing.

#

The only way to achieve that is via scene capture and an image

tribal venture
#

Hi, I got a question about SlateStyle in CPP.
The style class always consists of static member methods, and functions. My understanding is that the style definitions only, so that's why the class consists of statics. Am I right?

split laurel
#

not sure if I understand your question correctly, but typical slate style classes don't specifically contain slate resources. That's what the FSlateStyleSet is for, and the typical static Initialize or Create function in a style class merely creates an FSlateSlateSet object, registers slate resources and then registers itself to the slate style registry

novel ice
#

Hi!
I sometimes have this error:
"The requested size for SRetainerWidget is 0" in the SRetainerWidget
Which leads to rendering an image on the screen which was inside of a RetainerBox. The image can be removed by changing viewport size.
Does anyone know how can I fix this?

mild oracle
amber bison
#

how would you go about hiding properties that are registered for a custom property layout but are "disabled"? It seems that the meta specifier for EditCondition still works because the properties are being disabled, but they're not hiding (EditConditionHides is being ignored)

ocean mason
novel ice
mild oracle
novel ice
jolly prawn
#

does a checkbox slider slate widget exists?

mild oracle
mild oracle
novel ice
restive sapphire
#

Hello 🙂

How do you go about displaying the elements of an array within a struct? I currently have the following in the CustomizeHeader and CustomizeChildren for my property customization. The array shows up and you can add elements to it, but none of the elements are displayed.

// Customize Header
void FMyCustomStructCustomization::CustomizeHeader(TSharedRef<IPropertyHandle> StructPropertyHandle, FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& StructCustomizationUtils) {
 
  HeaderRow
  .NameContent()  [ StructPropertyHandle->CreatePropertyNameWidget() ]
  .ValueContent() [ StructPropertyHandle->CreatePropertyValueWidget() ];

}
// Customize Children
void FMyCustomStructCustomization::CustomizeChildren(TSharedRef<IPropertyHandle> StructPropertyHandle, IDetailChildrenBuilder& StructBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils) {

  MyArrayPropertyHandle = StructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FMyCustomStruct, MyArray), false);

  StructBuilder.AddCustomRow(LOCTEXT("My Array", "My Array"))
  .NameContent()  [ MyArrayPropertyHandle->CreatePropertyNameWidget()  ]
  .ValueContent() [ MyArrayPropertyHandle->CreatePropertyValueWidget() ]; // doesn't show any array items

}
grim glen
#

Would anyone be able to help me troubleshoot why my widget blueprint passed to the MoviePlayer's FLoadingScreenAttributes.WidgetLoadingScreen renders slightly different than when I just add the widget blueprint straight to the viewport?

#

I even tried wrapping my widget in a slate object identical to the one the MoviePlayer uses and it still isn't right (the text and throbber are smaller in size when using the MoviePlayer, but the background image looks consistent)

grim glen
#

So if I set the DPI scaling on the widget that I manually create to .75, it will match perfectly the MoviePlayer's rendering of my widget. But as soon as I change my windows scaling, my magic .75 DPI scaling stops working (as expected). I just need to figure out how to calculate that correct DPI scaling. The .75 scaling works when my Windows display scaling is set to 150% at a resolution of 2560x1440.

inland flower
#

How can I do an opacity gradient in Slate when using FSlateDrawElement, or on the final composited geometry at the end of OnPaint?

sharp zinc
#

Hello. How would I go about making a "copy" of a RichTextBlock but "remove" it's ability to change it's text size based on resolution. I want text to always be the same size I set it at. Then I want to just but the textblock in a scale box and have it scale proportionally.

mild oracle
sharp zinc
#

@mild oracle , I assume it is, but I want to scale my text absolutely manually because it causes overflows and it beaks my layout.

#

When I say manually I really mean scale it as if it were an image. No need for fancy row rearrangements as a result of desired size or whatever that is

mild oracle
# sharp zinc <@!253043784231682049> , I assume it is, but I want to scale my text absolutely ...

Ohhh I've seen that behaviour too. I thought it was because it was using a different font size for each resolution, and fonts at different sizes can have different proportions. That plus all the complicated text layout logic for keeping characters looking clear and crisp can mean that the text takes up more or less horizontal space.

To change this behaviour you might have to dig pretty deep into Unreal's text layout code...

mild oracle
sharp zinc
#

I can show you some video footage to be sure.

#

@mild oracle , sent a private message with video footage

frail rover
#

wondering if anyone would know something about line tracing in a custom editor viewport preview scene.
as i cannot seem to be able to hit anything and made sure the plane mesh is block on all collision channel responses.

quaint zealot
#

Anyone familiar with the new changes in UE5-main re: slots ? FSlot vs FSlot::FSlotArguments specifically, seems to break DLSS and also my own code

#

More specifically, how do I get actual args values from say, InArgs._Slots - assuming I have SLATE_SLOT_ARGUMENT(FSlot, Slots) ?

quaint zealot
#

Alright, fixed it

mild oracle
#

@quaint zealot Whoa stuff has changed in UE5 with slots?

quaint zealot
#

For reference, working ue5-main (as of yesterday) source code for widget slots

// Widget slot
class FSlot : public TSlotBase<FSlot>
{
public:
    SLATE_SLOT_BEGIN_ARGS(FSlot, TSlotBase<FSlot>)

    SLATE_ATTRIBUTE(SomeType, SomeAttribute)

    SLATE_SLOT_END_ARGS()

    FSlot() : TSlotBase<FSlot>()
    {}

    void Construct(const FChildren& SlotOwner, FSlotArguments&& InArgs)
    {
        TSlotBase<FSlot>::Construct(SlotOwner, MoveTemp(InArgs));
        if (InArgs._SomeAttribute.IsSet())
        {
            SomeAttributeAttr = MoveTemp(_SomeAttribute._Header);
        }
    }

    TAttribute<SomeType> SomeAttributeAttr;
};

// Widget header
SLATE_SLOT_ARGUMENT(FSlot, Slots)
static FSlot::FSlotArguments Slot()
{
    return FSlot::FSlotArguments(MakeUnique<FSlot>());
}

// Widget construct
for (const FSlot::FSlotArguments& Arg : InArgs._Slots)
{
    const FSlot* Slot = Arg.GetSlot();
    SomeWidgetType* SlotWidget = static_cast<SomeWidgetType*>(Arg.GetAttachedWidget().Get());
}```
lavish carbon
frail rover
fluid bobcat
#

If I want to make a slate button whose icon changes depending on some underlying state, would I make its icon a TAttribute that is bound to a function? Something like TAttribute< FSlateIcon >::FGetter::CreateStatic(&MyFunctionThatReturnsIcon)

frail rover
misty summit
#

Hi, I was wondering if anyone has modified/extended the Composite font's to support bitmap fonts(or other font's)? I'd like to implement msdf font for ui stuff, and I see umg/slate font's need to be composite's in order to be used.

mild oracle
misty summit
#

well i've decided to abandon modifying composite font. it is pretty hardcoded to expect ttf/otf files as far as I can tell. And changing any header related to them seems to trigger a 40+min recompile, which is too long for the trial and error method of figuring out how everything is pieced together. So my new approach now is basically to build my own font object, and then create my own slate widget and draw text that way instead. I have my font stuff done atm, working on figuring out how slate draws things currently.

pastel basin
#

Hello.

What is "Atlased Texture Interface" and why Stale Brush can accept Materials and Textures to Image object slot, but Image Object itself - can't?
I see now, it's an UObject, but Slate somehow filters the Textures and Materials.

quaint compass
#

Hi, does anybody know if there is a callback for when your game's window is resized? I googled and couldn't find anything and I also searched the documentation and couldn't find anything.

quaint compass
#

someone gave me the answer FViewport::ViewportResizedEvent

narrow terrace
random void
#

Question, is it possible to add a slate widget child to a umg widget?

orchid nova
#

I vaguely remember seeing an UMG widget for containing Slate widgets

#

Alternatively you could just wrap your widget into a UMG widget which should be relatively straightforward

low bluff
#

You'll probably have to put your Slate widget into a UWigdet (Not UUserWidget).

random void
craggy current
#

So I'm trying to get into slate - the overview i was following said you could click on the links in the widget reflector to open that section of code in visual studio. For me it just switches the window to visual studio and thats it. It wont find the line of code even if the file is already open in visual studio. its not even hanging or anything.
Is this something i can fix or did i just completely misunderstand in the first place

mild oracle
quaint zealot
#

Does anyone got working code for UE5-main slots ?

#

I'm doing something really simple where I just pass slot widgets to a child widget's construct

#

Somehow I keep getting crashes in the widget's Destroy

#

I also have no idea when to call the slot's new Construct call

quaint zealot
#

Okay I finally got it.

// Slot
class FSlot : public TSlotBase<FSlot>
{
public:
    SLATE_SLOT_BEGIN_ARGS(FSlot, TSlotBase<FSlot>)
    SLATE_ATTRIBUTE(FText, Example)
    SLATE_SLOT_END_ARGS()
};
// Slot user header
static FSlot::FSlotArguments Slot()
{
    return FSlot::FSlotArguments(MakeUnique<FSlot>());
}
// Slot user Construct
for (FSlot::FSlotArguments& Arg : const_cast<TArray<FSlot::FSlotArguments>&>(InArgs._Slots))
{
    FText Example = Arg._Example;
        TSharedPtr<SWidget> Widget = Arg.GetAttachedWidget();
}```
viral sundial
#

I’ve only been looking at slate for a few days but is there any documentation that explains the correct way to do local and absolute transforms?

#

I.e. convert correctly between local absolute space.

#

When 2 widgets may be in different transform hierarchies.

viral sundial
#

I’m trying to draw a line between 2 widgets but it’s really unclear if the coordinates are supposed to be in local space or absolute space.

#

Ok I think I have a better handle on how this works now.

sand frigate
#

Is there a way to get IPropertyHandle outside of IDetailCustomization? I wanted to put FText edit area outside of details panel (e.g. straight onto a graph node), by using an existing slate class (STextPropertyEditableTextBox).

vale solar
#

Is there a proper way to clear out a ComboBox? Ive got a setup where sometimes that box can be be empty and Id like to clear it out, but just calling ClearSelected() before I update the elements leaves what was previously selected in there

#

I guess as I talk this out though the better option might be to hide that box entirely if theres no valid selection

#

...which Im not entirely sure how to do either heh

vale solar
#

Which I have now resolved by finding the .Visibility_Lambda() option. This chat is great for Rubber Ducking! 🙂

warm vault
#

Is it possible to attach a Slate widget to actor? so it would be drawn in 3d space

orchid nova
#

The easiest way to do that would probably be to use a widget component with a UMG widget which wraps your Slate widget

warm vault
#

thnakas

warm vault
#

can slate widget be rendered on MacBook Pro touchbar?

#

id buy this plugin

quaint zealot
#

With Apple killing it off I probably wouldn't

orchid nova
#

^ yeah touchbar is ded. Although it seems it had some fans, nearly everyone I've talked to had issues with it so probably for a good reason lul

balmy vortex
#

Where can I find learning resources for Slate?

quaint zealot
#

The editor source code is the main one

#

After all it's what you're doing with it usually

mild oracle
#

I've seen this "Display UIExtension Points" option, and when it's enabled it shows a bunch of strings. Does anyone know how to use them?

split laurel
rain heron
#

does someone have a link to a good description of the different ways to style widgets (including custom widgets)?
like when its best to use args/attributes, when to use that style stuff like FCoreStyle that reference the assets in the VFS, and when to create a Style-Struct and when not....

#

also is there a better way to do auto-focus for than:

RegisterActiveTimer(0.016f, FWidgetActiveTimerDelegate::CreateLambda([this](double InCurrentTime, float InDeltaTime) {
    FWidgetPath FocusMe;
    FSlateApplication::Get().GeneratePathToWidgetChecked( SearchBox.ToSharedRef(), FocusMe );
    FSlateApplication::Get().SetKeyboardFocus( FocusMe, EFocusCause::SetDirectly );
    return EActiveTimerReturnType::Stop;
}));

?

median pollen
#

well, I'm getting an error
Here is the problem line

SAssignNew(DescriptionsListViewWidget, SListView<TSharedPtr<FDescriptionsListItem>>)

here is DescriptionsListViewWidget

TSharedPtr<SListView<TSharedPtr<FDescriptionsListItem>>> DescriptionsListViewWidget = nullptr;

and here's FDescriptionsListItem

USTRUCT()
struct LIVERYEDITORTOOL_API FDescriptionsListItem
{
    GENERATED_BODY()

    FDescriptionsListItem() : Index(0), Name(FString("")), Data()
    {}

    int Index;
    FString Name;
    FBMLiveryDescription Data;
};

This is the build error I'm getting

  LiveryEditorToolView.cpp(82): [C2664] 'TDecl<SListView<TSharedPtr<FDescriptionsListItem,ESPMode::NotThreadSafe>>,RequiredArgs::T0RequiredArgs> &TDecl<SListView<TSharedPtr<FDescriptionsListItem,ESPMode::NotThreadSafe>>,RequiredArgs::T0RequiredArgs>::Expose<SListView<TSharedPtr<FDescriptionsListItem,ESPMode::NotThreadSafe>>>(TSharedPtr<SListView<TSharedPtr<FDescriptionsListItem,ESPMode::NotThreadSafe>>,ESPMode::NotThreadSafe> &)': cannot convert argument 1 from 'const TSharedPtr<SListView<TSharedPtr<FDescriptionsListItem,ESPMode::NotThreadSafe>>,ESPMode::NotThreadSafe>' to 'TSharedPtr<SListView<TSharedPtr<FDescriptionsListItem,ESPMode::NotThreadSafe>>,ESPMode::NotThreadSafe> &'
  LiveryEditorToolView.cpp(82): [C2664] Conversion loses qualifiers
  DeclarativeSyntaxSupport.h(1068): [C2664] see declaration of 'TDecl<SListView<TSharedPtr<FDescriptionsListItem,ESPMode::NotThreadSafe>>,RequiredArgs::T0RequiredArgs>::Expose'
#

and I guess this is FBMLiveryDescription

USTRUCT()
struct FBMLiveryDescription
{
    GENERATED_BODY()

    UPROPERTY(EditAnywhere, Category = "Description")
    TEnumAsByte<EBMLiveryWorkspace> Workspace;

    UPROPERTY(EditAnywhere, Category = "Description")
    TArray<FBMLiveryGroup>            Groups;
};
wild pumice
#

How do you construct a slate widget to use with Gameplay Tag Container?

median pollen
#

I found out what was wrong with mine, the construct function was a const

median pollen
#

and here's another error, when trying to spawn an asset entry box in my slate, created a widget function

TSharedRef<SWidget> SLiveryEditorToolView::CreateDataAssetPicker(TSharedPtr<SObjectPropertyEntryBox> PropertyEntryBox)
{
    return SAssignNew(PropertyEntryBox, SObjectPropertyEntryBox)
        .AllowedClass(UCustomLiveryData::StaticClass())
        .ObjectPath(this, &SLiveryEditorToolView::GetDataPath)
        .OnObjectChanged(this, &SLiveryEditorToolView::OnDataObjectSelected)
        .AllowClear(true)
        .DisplayBrowse(true)
        .DisplayThumbnail(true)
        .ThumbnailPool(AssetThumbnailPool)
        .DisplayUseSelected(true)
        .DisplayCompactSize(false)
        .EnableContentPicker(true);
}

called it here

TSharedRef<SWidget> SLiveryEditorToolView::CreateToolBox()
{
    return SNew(SVerticalBox)

        + SVerticalBox::Slot()
        .Padding(4.0f)
        [
            CreateDataAssetPicker(DataAssetEntryBox)
        ]

and now getting this weird error

  unresolved external symbol "__declspec(dllimport) public: void __cdecl SObjectPropertyEntryBox::Construct(struct SObjectPropertyEntryBox::FArguments const &)" (__imp_?Construct@SObjectPropertyEntryBox@@QEAAXAEBUFArguments@1@@Z) referenced in function "public: class TSharedRef<class SObjectPropertyEntryBox,0> __cdecl TDecl<class SObjectPropertyEntryBox,struct RequiredArgs::T0RequiredArgs>::operator<<=(struct SObjectPropertyEntryBox::FArguments const &)const " (??_3?$TDecl@VSObjectPropertyEntryBox@@UT0RequiredArgs@RequiredArgs@@@@QEBA?AV?$TSharedRef@VSObjectPropertyEntryBox@@$0A@@@AEBUFArguments@SObjectPropertyEntryBox@@@Z)
#

I'm really stumped on it, been trying a few things

weary egret
#

did you add module: PropertyEditor?

grim radish
#

Hey guys, how do you force a slate widget to redraw itself?

quaint zealot
rain heron
warm vault
#

How to call a C++ function or BP function from Javascript that is run in SWebBrowser?

warm vault
#

There is no way to evaluate JavaScript in SWebBrowser and receive the output on Blueprint/C++ side? Besides making the UObject with callbacks and calling a JavaScript that returns results via those callbacks?

#

Something like runJavasript(lambda<T>)

orchid nova
#

sounds likely since browsers in general aren't designed to expose escape hatches for other applications

craggy current
# mild oracle Does clicking on stuff in the editor take you to the right line/function for oth...

Thanks for your reply (sorry it's been a hot minute, I had to shelve this project for a little bit)

I can open any blueprint functions that I create by double clicking. If I try to open one thats built-in it pops up with a "reading c++ symbols" thing on the bottom of the screen and nothing else happens

As a small update, I finally saw that when I try to open anything from the widget reflector I get an error that its looking in the complete wrong place for the code file - there isnt even any "Build" folder in the root of my D drive, or anything else to do with unreal so im not sure where it's getting this path from or how to fix it. Just to be thorough I reinstalled 4.26.2 and nothing changed

quaint zealot
#

That's the source code for when the engine was built @craggy current

#

IIRC you need debug symbols or something to open from editor ? Easier to just open Visual and search for that file name

median pollen
#

Hello, so I'm trying to bind a value to a TAttribute, so that I can change a value in a Custom Data Asset and have it change in my SlateUI, and vice versa

#

Currently, I have a CreateSP function that does this for me

#
Val = TAttribute<int>::Create(TAttribute<int>::FGetter::CreateSP(this, &SLiveryEditorToolView::GetTestValue));
#

but this calls every tick from my understanding

#

and would not work with TArrays

quaint zealot
#

Why wouldn't it work with arrays ? Also you can make it a lambda, which will likely compile down to literally reading the variable

median pollen
#

I'm sorry, quite new to slate, how would we bind it to lambda?

quaint zealot
#

Using CreateLambda instead and passing the code from GetTestValue directly

#

And updating on tick is perfectly fine, for the record

median pollen
#

yeah that's fair, so I could just do this?

Val = TAttribute<int>::Create(TAttribute<int>::FGetter::CreateLambda(this, TestCustomData->Pattern.Colours->R));
#

assuming that value is the one I return from the getter

quaint zealot
#

Probably more like

Val = TAttribute<int>::Create(TAttribute<int>::FGetter::CreateLambda([this] { return TestCustomData->Pattern.Colours->R);} ));```
median pollen
#

oh nice! Thank you kindly

#

and would this be the same for TArrays?

quaint zealot
#

Works for any type, dunno how you want to show the array

median pollen
#

I'll give it a go, thanks for the help! I appreciate it!

#

@quaint zealot yeah, it doesn't seem to update correctly when adding new elements to the array in the custom data asset

#

here is my code

DescriptionsList = TAttribute<TArray<FBMLiveryDescription>>::Create(TAttribute<TArray<FBMLiveryDescription>>::FGetter::CreateLambda([this] { return TestCustomData->Descriptions; }));
quaint zealot
#

Like I said, depends on how you want to show the array. For list views you probably want to use the widget's tick event to copy the array or a hash of it, and refresh the list view any tile it's changed

median pollen
#

so the "every time it's changed" part is what I'm having issues with, how do we know when thats happening?

quaint zealot
#

Depends on the array and contents, but it could be a hash of the array contents for example.

median pollen
#

yeah, the array's contents is just a struct with a TEnumAsByte and another TArray

blazing oak
#

Hello, I would like that my plugins uses the same docking system used by the editor. I saw that it's needed to use: SDockingArea and SDockingSplitter but it doesn't seems to work well with slate, doesn't compile:

    return SNew(SDockTab)
        .TabRole(ETabRole::NomadTab)
        [
            SNew(SDockingArea)
            [
                SNew(SHorizontalBox)
                    + SHorizontalBox::Slot()
            ]
        ];

This is the compilation error:

No 'operator []' matches arguments of type 'SDockingArea::FArguments' and 'TSharedRef<SHorizontalBox, ESPMode::Fast>'

It's like the SDockingArea doesn't implement to operator[] function, any idea?

limber stump
blazing oak
#

@limber stump I'm trying doing it, though it doesn't seems to be so obvious or however it doesn't use slate.. at least it doesn't seems so 🤔

#

Btw, what I'm trying to do is create the plugin UI so that it's possible to change the size of the side menu, exactly like for any window (like the blueprint editor or the skeleton asset editor)

#

To do it, do I need to use the dock or exist another way?

median pollen
#

Hi Slate peeps, how do I change a button's visibility on the fly, I've set the .Visibility to a TAttribute but have no idea how to set the Tattribute to update the button's visibility

#

sorry, bit of a beginner

wide dragon
#

What should I google to figure out building my own asset editor window? Specifically, an asset editor window that renders a scene in real-time.

#

Like the Viewport in the blueprint editor.

limber stump
# wide dragon What should I google to figure out building my own asset editor window? Specifi...

Without knowing how much you know or have already done:

  • create an editor module
  • create a factory and asset type actions class for the class you wanna customize
  • create an asset customization for the class
  • add a viewport to that customization.
    Start by googling which of these you are unfamiliar with first. Little is online about the actual viewport itself. I would try to look at how assets like static meshes or materials add a viewport to their asset and try to copy the basics from there. The other three steps are quite well covered online. Cairan Steverink's blogs are pretty good at covering the bare minimum to set things up
signal raven
#

Do I need to use slate to optimize UMG? Can I use plain C++ functions for the BPs using heavy forloops?

mild oracle
warped kestrel
#

sup slate wierdos, cross posting this from main chat:
trying to track a socket off a skeletal mesh w/ a new cpp UUserWidget
basically GetSocketLocation() -> ProjectWorldToScreen()
but - there's a problem w/ scaling? seems like UCanvasPanelSlot::SetPosition() is expecting different coordinates than what PWTS() returns
haven't investigated DPI yet, but converting to widget local coords didn't help
any ideas? for context SetPosition(ViewportSize) puts it about 3/4 the way to the bottom corner iirc, so scaling is off by like 1.3x

craggy holly
#

Almost certainly going to be DPI scale. Also you probably want to project to the viewport not the screen.

#

Screen will encompass the whole window, which in editor also means toolbars etc.

#

I prefer projecting to normalized viewport position then set anchors instead

#

Using FSceneViewProjectionData::ComputeViewProjectionMatrix() for projection and FSceneViewProjectionData::GetConstrainedViewRect() for viewport size.

warped kestrel
#

@craggy holly could you elaborate? I'm maybe not following
LocalPlayer->GetProjectionData(LocalPlayer->ViewportClient->Viewport, eSSP_FULL, ProjectionData);
FSceneView::ProjectWorldToScreen(SocketWorldLocation, ProjectionData.GetConstrainedViewRect(), ProjectionData.ComputeViewProjectionMatrix(), SocketScreenLocation); should accomplish all that right? it didn't work, same issue

#

well, except using anchors. I'm confused ab that

warped kestrel
#

never mind, it works when divided by the DPI

median pollen
#

Hello there slateheads, I've just assigned a variable to a cpp TSharedPtr<SListView<TSharedPtr<FDescriptionsListItem>>> widget, was wondering if there was a simple way to add an item to that list after pressing a button

#

this is the FDescriptionListItem struct by the way

USTRUCT()
struct LIVERYEDITORTOOL_API FDescriptionsListItem
{
    GENERATED_BODY()

    FDescriptionsListItem() : Index(0), Data()
    {}

    int Index;
    FBMLiveryDescription Data;
};
#

and finally, how I assign the value

+ SVerticalBox::Slot()
.AutoHeight()
.VAlign(VAlign_Fill)
.HAlign(HAlign_Fill)
[
    SAssignNew(DescriptionsListViewWidget, SListView<TSharedPtr<FDescriptionsListItem>>)
    .ItemHeight(24)
    .SelectionMode(ESelectionMode::Single)
        .ListItemsSource(&DescriptionsListViewItems)
    .OnGenerateRow(this, &SLiveryEditorToolView::OnGenerateDescriptionsRow)
]
quaint zealot
#

Add to DescriptionsListViewItems and refresh DescriptionsListViewWidget

median pollen
#

ah smart, thank you for the help again Stranger

#
FReply SLiveryEditorToolView::OnAddDescriptionClicked()
{
    TSharedPtr<FDescriptionsListItem> NewItem = MakeShared<FDescriptionsListItem>();
    DescriptionsListViewItems.Add(NewItem);
    DescriptionsListViewWidget->RequestListRefresh();
    return FReply::Handled();
}

@quaint zealot Would this be the way to do it?

quaint zealot
#

Something like that, yeah

median pollen
#

hm thats not liking that at all

#
error C3867: 'SLiveryEditorToolView::OnAddDescriptionClicked': non-standard syntax; use '&' to create a pointer to member
quaint zealot
#

That's your button code

median pollen
#

yeah

quaint zealot
#

Just do what the error says

median pollen
#

I wish I knew where it meant really..

quaint zealot
#

I mean the error specifically tells you how to fix the code

#

And this is a regular C++ function pointer

#

Might want to read up on C++ if you're writing some

median pollen
#

thanks for the help

#

Oh my goodness, right, it's on the button itself

#

I thought it was in the function

quaint zealot
#

Yeah I told you that

#

Look at the lines on errors

median pollen
#

yeah when you said button code for some reason my head went straight to the definition

median pollen
#

hello again! I'm looking to implement a double click renaming text block and found SInLineEditableTextBloxk, which sounds right up my alley, was wondering why it doesn't seem to respond to my double click? It could be the tablerow taking the focus, really... is there any way to allow it to select the item on the first click, but edit the item on the second?

#
TSharedRef<ITableRow> SLiveryEditorToolView::OnGenerateDescriptionsRow(TSharedPtr<FDescriptionsListItem> Item, const TSharedRef<STableViewBase>& OwnerTable)
{
    FString RowName = FString("Description_");
    RowName.AppendInt(Item->Index);

    TSharedRef<STableRow<TSharedPtr<FString>>> TableRow = SNew(STableRow<TSharedPtr<FString>>, OwnerTable)
        .Padding(2.0f)
        .SignalSelectionMode(ETableRowSignalSelectionMode::Instantaneous)
        [
            SNew(SInlineEditableTextBlock)
            .Text(FText::FromString(RowName))
        ];

    return TableRow;
}
#

this is my implementation

#

maybe theres a way to suppress the table rows double click functionality?

split laurel
#

you can check what's taking up input by using the widget reflector to help you debug this

median pollen
#

@split laurel thats great to know! Im pretty sure the table rows taking the input since it does get selected on the first click, im just trying to figure out how to get it not to handle the double click only

split laurel
#

typically it shouldn't take the input as you didn't click on the row but on the text. Input handlers bubble up, so that the row only attempts to consume the input when the contained widget doesn't handle it

#

so you are probably right that the row does take the input, but the question is why. Or perhaps you need to forward the selection to the text box

median pollen
#

Thats an excellent idea, i'll try and stop the input on the row and call it from the text

median pollen
#

So through the widget reflector, I found out both my listview and editableTextBox have focus, but the row itself doesn't have any

split laurel
#

focus is something a bit different. You can open up Widget Events (I think?) under windows in the widget reflector, then setup what events "mouse input up/down" you want to look for. In the log it will tell you what widget is eating it specifically

jolly prawn
#

Is there an easy way to get rounded edges with SNew(SBorder)? (or something similar)

quaint zealot
#

Sure, just use a rounded texture

#

Simple border-type Slate brush with a 9-patch texture

#

Set all margins to 0.33 in the brush and you're set

#

(or you can simple use a circle texture and setn0.5 to margins to make it a 4 patch)

jolly prawn
#

thanks 👌

glad elm
#

Anyone knows what am I missing?

    + SVerticalBox::Slot()
        .AutoHeight()
        [
            SNew(SSeparator)
            .Visibility(EVisibility::Collapsed)
        ]
#

I guess its related with declarative syntax support thing?

median pollen
#

is this your last slot @glad elm ?

glad elm
#

It was not, I added some more #includes and it somehow fixed

median pollen
#

ah could be that yeah, which includes were they?

#

ah DeclarativeSyntax

glad elm
#
#include "UObject/UnrealType.h"
#include "Widgets/Layout/SSeparator.h"
#include "Widgets/Layout/SBox.h"
#include "Widgets/Views/STableViewBase.h"
#include "Widgets/Views/STableRow.h"
#include "Widgets/Views/SListView.h"
#include "Widgets/Input/SComboBox.h"

#include "Widgets/Input/SSearchBox.h"
#include "UObject/UObjectHash.h"
#include "UObject/UObjectIterator.h"
#include "Misc/TextFilter.h"
#

I only had SSeperator first

#

Added all of those and compiled

median pollen
#
void FSCSRowDragDropOp::HoverTargetChanged()
{
    bool bHoverHandled = false;

    if (!bHoverHandled)
    {
        if (FChildActorComponentEditorUtils::ContainsChildActorSubtreeNode(SourceNodes))
        {
            // @todo - Add support for drag/drop of child actor template components to create variable get nodes in a local Blueprint event/function graph
            FText Message = LOCTEXT("ChildActorDragDropAddVariableNode_Unsupported", "This operation is not currently supported for one or more of the selected components.");
            SetSimpleFeedbackMessage(ErrorSymbol, IconTint, Message);
        }
        else if (FProperty* VariableProperty = GetVariableProperty())
        {
            const FSlateBrush* PrimarySymbol;
            const FSlateBrush* SecondarySymbol;
            FSlateColor PrimaryColor;
            FSlateColor SecondaryColor;
            GetDefaultStatusSymbol(/*out*/ PrimarySymbol, /*out*/ PrimaryColor, /*out*/ SecondarySymbol, /*out*/ SecondaryColor);

            //Create feedback message with the function name.
            SetSimpleFeedbackMessage(PrimarySymbol, PrimaryColor, VariableProperty->GetDisplayNameText(), SecondarySymbol, SecondaryColor);
        }
        else
        {
            FText Message = LOCTEXT("CannotFindProperty", "Cannot find corresponding variable (make sure component has been assigned to one)");
            SetSimpleFeedbackMessage(ErrorSymbol, IconTint, Message);
        }
        bHoverHandled = true;
    }

    if(!bHoverHandled)
    {
        FKismetVariableDragDropAction::HoverTargetChanged();
    }
}

Am I going nuts or does

FKismetVariableDragDropAction::HoverTargetChanged();

never get called?

median pollen
#

it's the include file you need to call SVerticalBox

median pollen
#

Having a strange issue with slate, I added a new custom treeview to my slate like this

SNew(SVerticalBox)
                + SVerticalBox::Slot()
                .VAlign(VAlign_Top)
                [
                    SAssignNew(PaletteListViewWidget, SDragDropTreeView)
                    .ItemHeight(24)
                    .TreeItemsSource(&PaletteListViewItems)
                ]

I have a construct in another file like this

void SDragDropTreeView::Construct(const FArguments& InArgs)
{
    Owner = InArgs._Owner;

    STreeView<FDragDropTreeNodePtrType>::FArguments BaseArgs;
    BaseArgs.OnGenerateRow( InArgs._OnGenerateRow )
            .OnItemScrolledIntoView(InArgs._OnItemScrolledIntoView)
            .OnGetChildren(InArgs._OnGetChildren)
            .OnSetExpansionRecursive(InArgs._OnSetExpansionRecursive)
            .TreeItemsSource(InArgs._TreeItemsSource)
            .ItemHeight(InArgs._ItemHeight)
            .OnContextMenuOpening(InArgs._OnContextMenuOpening)
            .OnMouseButtonDoubleClick(InArgs._OnMouseButtonDoubleClick)
            .OnSelectionChanged(InArgs._OnSelectionChanged)
            .OnExpansionChanged(InArgs._OnExpansionChanged)
            .SelectionMode(InArgs._SelectionMode)
            .HeaderRow(InArgs._HeaderRow)
            .ClearSelectionOnClick(InArgs._ClearSelectionOnClick)
            .ExternalScrollbar(InArgs._ExternalScrollbar)
            .OnEnteredBadState(InArgs._OnTableViewBadState)
            .HighlightParentNodesForSelection(true);

    STreeView<FDragDropTreeNodePtrType>::Construct(BaseArgs);
}
#

and now I'm getting a LNK error

#

Module.LiveryEditorTool.cpp.obj : error LNK2019: unresolved external symbol "public: void __cdecl SDragDropTreeView::Construct(struct SDragDropTreeView::FArguments const &)" (?Construct@SDragDropTreeView@@QEAAXAEBUFArguments@1@@Z) referenced in function "public: class TSharedRef<class SDragDropTreeView,0> __cdecl TDecl<class SDragDropTreeView,struct RequiredArgs::T0RequiredArgs>::operator<<=(struct SDragDropTreeView::FArguments const &)const " (??_3?$TDecl@VSDragDropTreeView@@UT0RequiredArgs@RequiredArgs@@@@QEBA?AV?$TSharedRef@VSDragDropTreeView@@$0A@@@AEBUFArguments@SDragDropTreeView@@@Z)

#

no idea what it means

wide dragon
#

How to change the editor font? I looked at the Editor Style Set, and changed some references, but it did not work.

pulsar remnant
#

I'm trying to add an image to my loading screen. The comment line is path of my widget but i'm not sure if it works. I only need a throbber, an image and maybe a text. How i can handle it?

void UGameInstanceBase::Init()
{
    Super::Init();

    FCoreUObjectDelegates::PreLoadMap.AddUObject(this, &UGameInstanceBase::BeginLoadingScreen);
}

void UGameInstanceBase::BeginLoadingScreen(const FString& InMapName)
{
        FLoadingScreenAttributes LoadingScreen;
        LoadingScreen.bAutoCompleteWhenLoadingCompletes = false;
        //LoadingScreen.WidgetLoadingScreen = "/Game/UI/LoadingScreen";
        LoadingScreen.WidgetLoadingScreen = FLoadingScreenAttributes::NewTestLoadingScreenWidget();
 
        GetMoviePlayer()->SetupLoadingScreen(LoadingScreen);
}
thick ice
#

Hi! Does anybody know, if there is a console command to toggle slate rendering? For profiling purpose I want to disable all UMG and slate things for a while..

median pollen
#

is there a way of getting the ListView variable from the ```cpp
const TSharedRef<STableViewBase>& OwnerTable

#

can we just cast it?

topaz stag
#

Hi guys! I wrote a short article, but I believe it is a useful article about standalone Slate apps.
But it was written in Russian. Maybe there are Russian-speaking people in the chat, who can help me with translation into English?

mild oracle
spare island
#

Hey guys I want to change font size of UMG TextBlock during gameplay -> I found that I need to create new FSlateFontInfo and then use SetFont()

  • Here is my current code that is not working can you point why ?
  • This code is in the UWidget constructor

THE PROBLEM: it does not changes font when start game

const FString FontPath = FString ("/Game/UI_Assets/Fonts/MyFont"); FSlateFontInfo NewFontInfo(FontPath,96); MMCreditsBtnTxt->SetFont(NewFontInfo);

mild oracle
spare island
#

@mild oracle thanks for reply but still not working, I'm seeing this every time...

#

And here is the current code .. I guess I'm doing something else wrong..

spare island
#

ok JFYI @mild oracle I made it working with these 2 rows .. I guess I'll try clean new project to see if it will work with the path something smells .. why I can't get the reference by path... Thanks , btw I watched you videos !! Great stuff !!

young sleet
#

Hey is it possible to get a specific widget type from a IDetailLayout and somehow customize it?

#

For example I can get a named property or widget row, and configure it.

#

I want to get the reference to a spawned overlay SClassViewer, and update the items that are spawned in the combo box.

#

But I am having trouble getting its handle, and I don't understand how I would go about it.

#

I have a TArray<UObject*> property;, of which I want to apply a custom filtering.

hot notch
#

@spare islandOut of curiosity. Is there any reason you can't just make a map or array of FSlateFontInfo structs to get your data from and set it from blueprint/editor? Hardcoding stuff is a little brutal.

young sleet
#

I find I can use property.asArray to get a handle to the array itself.

#

For example, deleting 0th element.

#

I still have not found a way to get a handle to the asset picker that is created as a floating window.

#

I want to target this asset picker with custom filtering.

#

Its an SListViewSelectorDropdownMenu.

young sleet
#

So pretty much its a custom window. I guess I cannot customize this from the property 😦

#

All I want is custom filtering for a TArray UObject* property.

young sleet
#

Follow up question: Is there any way to modify specific widgets, within a property? For example if I wanted to change the button size of the SDetailSingleItemRow in a SListView created via a normal TArray UPROP

#

I just don't see how to walk down from a property handle down into its children properly.

#

It says array elements cannot be accessed via "GetChildHandle"

hexed plank
#

Is there a way to "mask" something in slate?

#

Like if I'm drawing a square image in "OnPaint" but I want to give it rounded translucent borders?

#

Or like an opacity mask for slate

craggy holly
#

You apply a brush to it, i.e. a texture or a material

median pollen
#

Hey Slaters!
I'm trying to add an asset's thumbnail to my slate, so I've got

    UTexture2D* AssetTexture = *AssetItem;
    FAssetThumbnailConfig ThumbnailConfig;

    ThumbnailConfig.bAllowFadeIn = true;
    ThumbnailConfig.bAllowHintText = false;

    TSharedPtr<FAssetThumbnail> AssetThumbnail = MakeShareable(new FAssetThumbnail(AssetTexture, 64, 64, nullptr));

    TSharedPtr<SWidget> Thumbnail = AssetThumbnail->MakeThumbnailWidget(ThumbnailConfig);
```But it doesn't render out the thumbnail image from the asset I want, just the Texture type thumbnail. (Here AssetItem is the asset in question)
#

So, just for clarity, I'm getting this

#

when I want this

grave parcel
#

Hi! I was wondering if something like this could be created more or less easily with Slate:

#

a "slider" of sorts that controls 3 different values

median pollen
#

@grave parcel It would be more pleasant making this in UMG tbh

grave parcel
#

hmm

median pollen
#

Is there a reason you want it for slate?

quaint zealot
#

Yeah Slate is for building fundamental widgets

#

This is just two brushes and three text blocks

grave parcel
#

I was under the impression that Slate was for more "complicated" things

#

but I was wrong 😄

quaint zealot
#

Slate is for things you can't build with UMG

#

So yeah

grave parcel
#

hehe

median pollen
#

^ this

quaint zealot
#

But this is very doable with UMG

grave parcel
#

thank you

#

I will try 🙂

median pollen
#

also @quaint zealot would you know anything about the thumbnail problem I'm having?

quaint zealot
#

No, i don't

median pollen
#

ah alright, thanks anyway

median pollen
#

So, for anyone interested, I didn't specify a thumbnailpool when creating my assetthumbnail

FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked<FLevelEditorModule>("LevelEditor");
TSharedPtr<FAssetThumbnailPool> ThumbnailPool = LevelEditorModule.GetFirstLevelEditor()->GetThumbnailPool();
TSharedPtr<FAssetThumbnail> AssetThumbnail = MakeShareable(new FAssetThumbnail(AssetTexture, 64, 64, ThumbnailPool));
#

works perfectly now!

kindred nova
#

Is it possible somehow set "Min row height" for TreeTable ?

split laurel
#

What keeps you from adding a box inside the individual row with a minimum height?

craggy holly
#

Is there an injection point where I can run some code before slate does the layout pass for a given frame? I want to "project" widget position from world-space to screen-space, and possibly change the size of that widget depending on that projection. I've realised Tick etc. runs after layout has been processed for that frame, and I'm doing the work there currently, but there's a frame of latency and I suspect I'm invalidating things a lot by doing that.

#

The hard part is exposing that to UMG in some way. All I can think of is binding some functions to events exposed by the slot, but dynamic delegates/bindings aren't exactly quick.

#

Guess I want some kind of "pre layout pass" function for UMG, not sure that exists?

craggy holly
#

Actually.. doesn't matter 😄

abstract spindle
#

is there an example of how I can add a submenu / menu entries to toolbar button? I only see example for modifying the editor menus or adding a pop up window for plugins.

narrow terrace
narrow terrace
mild oracle
abstract spindle
stuck jewel
#

@abstract spindle I expect they're talking about Window > Developer Tools > Debug Tools > Test Suite ... you can maybe find some text in it and ctrl-shift-f your way to the actual code

#

I don't know where a specific example you'd be looking for is though 😄

abstract spindle
#

this is likely what they're talking about, but I'm looking to modify a toolbar via c++

stuck jewel
#

are you talking about adding things to or modifying e.g. the main toolbar or entries in one of the submenus of a main toolbar button? like here?

abstract spindle
#

made an editor toolbar plugin, want to know how to make this a drop down menu

#
void FQuestVRToolsModule::RegisterMenus()
{
    // Owner will be used for cleanup in call to UToolMenus::UnregisterOwner
    FToolMenuOwnerScoped OwnerScoped(this);

    {
        UToolMenu* Menu = UToolMenus::Get()->ExtendMenu("LevelEditor.MainMenu.Window");
        {
            FToolMenuSection& Section = Menu->FindOrAddSection("WindowLayout");
            Section.AddMenuEntryWithCommandList(FQuestVRToolsCommands::Get().PluginAction, PluginCommands);
        }
    }

    {
        UToolMenu* ToolbarMenu = UToolMenus::Get()->ExtendMenu("LevelEditor.LevelEditorToolBar");
        {
            FToolMenuSection& Section = ToolbarMenu->FindOrAddSection("Settings");
            {
                FToolMenuEntry& Entry = Section.AddEntry(FToolMenuEntry::InitToolBarButton(FQuestVRToolsCommands::Get().PluginAction));
                Entry.SetCommandList(PluginCommands);
            }
        }
    }
}
#

it should be generated automatically with the right keywords without having to manually create slate stuff

#

but there's no info anywhere

#

@stuck jewel

stuck jewel
#

yeah been a long time since I've tried anything in there and IIRC all I did was modify an existing menu... remember some stuff with MenuExtender and AddMenuExtension but not sure if that's the same process needed for a new menu

abstract spindle
#

there's different functions for existing menus vs plugin menus

craggy holly
#

@mild oracle @narrow terrace still figuring it out really.. currently the idea is to push a slate event in OnArrangeChildren both pre and post projecting each slot, but it's still a bit tricky.

#

On that subject though, does anybody know why SConstraintCanvas etc. arranges it's children twice? Once during OnArrangeChildren then again during OnPaint

#

It's doing all that sorting work at least twice a frame

narrow terrace
#

I would honestly need to take a look since it's been a while since I've looked at the canvas, currently returning from a wedding...

craggy holly
#

There's also no way to get geometry during a custom prepass is there?

Essentially I have a panel whose geometry/desired size is inferred from it's parent - so I want to be able to get the allotted geometry of the parent during the widgets' prepass, so that child widgets can modify their reported desired size during the first prepass.

spare bane
#

is there a way to use a variable for richtextstyles? I want to plugin a color variable for the text

narrow terrace
narrow terrace
spare bane
#

it's for a chat message, I want the players name to be the same color as their team, and team colors are custom so they could be any color

#

the reason I'm using rich text, is so the message wraps correctly and doesn't bug chat

craggy holly
craggy holly
#

The crux is that if a widget wants to change size, it just needs to call "Force Layout Prepass", which prevents any 1/2 frame glitches as it switches up.

narrow terrace
sacred venture
#

can i have a custom row that obeys that splitter?

#

nevermind, had a custom row because i wanted the expandable area, making it a group instead was easier

sacred venture
#

when i have a customize header, my property shows indented and with the "drag item" icon

#

top one has no header, bottom one has

#

any way to remove it?

#

It is a child of an array, but its expanded to not show the array property

#
        [
            SNew(STextBlock)
            .Text(FText::FromString(AssetName))
            .Font(CustomizationUtils.GetRegularFont())
        ]```
craggy holly
#

Can anybody confirm that Paint Geometry is in Desktop Space rather than Window Space?

#

Trying to use FSlateDrawElement::MakeLines(), and I have to subtract FPaintArgs::GetWindowToDesktopTransform() in order for them to draw in the correct plane, which is making my head spin

#

The coordinates I'm painting are in Viewport-Absolute Space

maiden tapir
#

So this might be a dumb question, but using the Renderdoc plugin and capturing a frame seems to exclude any Slate UI being rendered to screen. It seems to only include the Scene capture. Is there a way to use Renderdoc with Slate/UMG that I'm missing?

maiden tapir
#

I've asked on the Renderdoc discord and have been told its up to the plugin to determine the start/end of capture, so am currently looking through the plugin documentation

hot notch
#

Having a bit of a derp. How do I set a Slate's Slot to use Size Fill?

hot notch
#

Ah. Got it figured out. Didn't realize I needed autowidth.

mild oracle
#

I'm trying to work out what code in the engine is responsible for changing which input box is selected in property panels when pressing Tab, but not having much luck.

I've tried searching for all instances of EKeys::Tab but that didn't pull up much. Does anyone have any suggestions?

sacred venture
mild oracle
sacred venture
#

I just remember setting up my own navigation rules in my game, but maybe its the same for editor

undone knoll
#

Hey guys, does anybody know of a good youtuber who provides slate tutorials?

quaint zealot
#

The editor source code is a great one

#

Sorry, not a Youtuber, but the real doc 😛

#

Slate isn't game stuff so it doesn't get a lot of tutorials

hot notch
#

A little confused with SButton. How are you supposed to be able to create a slot for it?

#

+SButton::Slot() doesn't seem to work.

quaint zealot
#

It only has one

#

So []

hot notch
#

How do you change the slot properties on that?

quaint zealot
#

There aren't any

hot notch
#

Assuming UMG. If I put Text in a button I can set it's padding, and alignments.

#

Just wondering how to do the same in Slate.

quaint zealot
#

Pretty sure you need another widget for that

#

Personally I subclass SButton so I can do ChildSlot .VAlign(VAlign_Center) .HAlign(HAlign_Center) [

hot notch
#

Just started learning actual Slate. 😄 Maybe it's time to ditch SButton anyhow. Couple things about it I wanna fix.

hot notch
#

On a side note though. Apparently you just specify it directly on the button instead of the slot.

SNew(SButton).HAlign(HAlign_Fill).VAlign(VAlign_Fill).ContentPadding(FMargin(6.f))
[
  SNew(STextBlock).Text(FText::FromString("X")).Font(Font)
]
quaint zealot
#

Ah, yeah, makes sense

#

Personally i've got a button class that inherits SButton and reimplements essentially half of it

mild oracle
obsidian surge
#

There are methods such as:

    bool AllowDrop(TSharedPtr<FDragDropOperation> DragDropOperation) const;

    virtual bool OnAllowDrop(TSharedPtr<FDragDropOperation> DragDropOperation) const;
    virtual bool OnIsRecognized(TSharedPtr<FDragDropOperation> DragDropOperation) const;

mild oracle
nocturne marsh
#

I'm trying to access the selected folders in the world outliner, but I've seen GetSelectedFolderNames in SSceneOutliner is private, is there any other way to access this data or get an equivalent one?

inland flower
#

@mild oracle Saw your blog post on List View, nice one! A couple of times I've tried to use it though, I run into the same limitation: headers. If you work around it by having multiple list views, separated by header widgets, you don't get an unbroken scrollbar for scrolling the whole thing.

I've tried 2 methods to get around this. One is to set a bool on the list item object to tell the generated widget to show/hide parts of the widget depending on whether it's a header or not. The other is to have the generated list item be a simple named slot and in On Entry Generated, call a function which tells it to construct a header and slot it, or construct a regular item and slot it. It feels hackish though, and I'm not satisfied. Also, when I tried it with a tree view, the list items would randomly reorder themselves, moving out from under their headers.

What I think I might try next is subclassing listview and instead of Add Child, a new function that receives a header object and entire batch of entry objects at once to draw under that header, so that the association and ordering can be preserved. The other limitation that would have to be removed is all generated entries using the single hardcoded Widget Entry Class property. A TMap of Object Class to Widget Entry Class would allow any passed-in object type to produce a corresponding widget for that object.

wild pumice
#

I'm developing a custom graph editor following Flow Graph by MothCocoon but when I save the graph, close and reopen Unreal Engine, all connections disappear. What could possibly be the reason the connections not saving with the asset?

wild pumice
#

After debugging it looks like UEdGraphPin::LinkedTo is empty after reopening editor. But why...🤔

wild pumice
cobalt hare
#

why is the umg drag drop operation so impenetrable.. i just want to make a slate drag drop operation that is a drop in replacement that doesn't have position lerping at the start of the drag

#

but UMGDragDropOperation is totally locked down

mild oracle
#

I used it to make a drag and drop vertical box that is basically a modified version of SDragAndDropVerticalBox

cobalt hare
#

is your code online anywhere?

mild oracle
#

I can post little bits I guess:

FReply UBYGDragAndDropVerticalBox::HandleDragDetected( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent, int32 SlotIndex, SVerticalBox::FSlot* InSlot )
{
    // Find the thing we're trying to drag
    // ...
    return FReply::Handled().BeginDragDrop( FBYGVerticalBoxDragDropOp::New( /*...*/

Basically I would recommend looking at how HandleDragDetected is used in other places

#

@cobalt hare SHierarchyViewItem.cpp has some good examples of HandleCanAceptDrop

cobalt hare
#

🙏 thanks ben, this is really helpful

mild oracle
formal fossil
#

<@&213101288538374145> hmm already banned i guess 🤔

tawny badgerBOT
#

:warning: Failed to send a DM. User will not be notified.

#

:no_entry_sign: ROYALKINGSJ#2266 was banned.

celest locust
#

is there a way to remove the arrowhead on the spline that connects 2 node pins?

glad elm
#

Is there any way to implement a custom slate for USTRUCT()s?

#

I have a struct exposed to BPs like this

#

Weight variable determines the count of the element in the game, when they're utilized in C++. Since its a dynamic value, I want my designers to see something like this:
If total count would be 100, with 0.05 of Weight you would get ~5 enemies in the game

#

But I don't want to write a something from scratch, if possible I'd like to modify the default USTRUCT() panel

low bluff
#

@glad elm Details customization

#

Is the magic word

#

You can make one per Object or Struct

#

And that allows you to design how your struct gets visualized and also react to certain values changing

#

I think a good candidate for looking at an example is the FDataTableRowHandle

#

It creates a drop-down from the Datatable property and saves the selection in a name variable iirc

glad elm
#

🥳 Great, thanks for explaining eXi

low bluff
#

No biggy. Sadly don't have an example at hand. haven't used them in a while

#

I think your register them in your module

#

Fwiw

#

Files in engine are usually called structname+customization or so

#

You can then just follow around where the use the struct and the customization type

#

It's straight forward to add it. The slate part is the shitty part

glad elm
#

Np, "magic keyword" was enough on its own 🙂 I found some GAS examples (FAttribute etc.) -- they serve as a good documentation right now

low bluff
#

Coolio

stuck jewel
#

Property customization for an individual struct, not details customization though. They're different. Very confusing when you're just learning

#

@glad elm

glad elm
#

I guess 'detail' customization is for UObjects, right?

#

or for "assets" to be clear

cobalt hare
#

has anyone tried using UWidget::TakeDerivedWidget()? i'm trying to replace the object widget used by a subclass of UUserWidget with my own subclass of SObjectWidget following this comment in Widget.h:
For extremely special cases where you actually need to change the the GC Root widget of the constructed User Widget - you need to use TakeDerivedWidget you must also take care to not call TakeWidget before calling TakeDerivedWidget, as that would put the wrong expected wrapper around the resulting widget being constructed.

#

but i can't figure out a reliable place to call TakeDerivedWidget before the UMG blueprint editor starts invoking functions that call TakeWidget

stuck jewel
# glad elm I guess 'detail' customization is for UObjects, right?

sorry I screwed off but basically a details customization allows you to modify the entire details pane (which basically will always be for a uobject, yes) and a property customization allows you to change how an individual property can be automatically drawn within its assigned row in a details pane (like an FVector, but also IIRC this can be used to affect how an instanced UObject property is drawn when a UObject is used as a property too)

fossil kayak
#

How do I expose slate widget to umg so I can use it in widget blueprint?

mild oracle
fossil kayak
#

oh thanks a lot!

cobalt hare
mild oracle
mild oracle
fair verge
#

I have problem that my old code have compile error with ue5

  MemoryOps.h(217): [C2280] 'SSplitter::FSlot::FSlotArguments::FSlotArguments(const SSplitter::FSlot::FSlotArguments &)': attempting to reference a deleted function

any tips what could have changed in the last commits of ue5 - main?

quaint zealot
#

Not many examples to use right now

#

Look in the engine source essentially

cobalt hare
# mild oracle I never tried to use it, I'd be curious what it's like and how it helps

i ended up not needing it -- i went around and around trying to figure out a way to do what i wanted 🙂
i wanted a custom drag drop operation (without the position lerping animation at the start of the drag) that i could use on otherwise normal UUserWidgets. FUMGDragDropOp is instantiated when SObjectWidget detects a drag event, so at first i tried replacing that behavior with a subclass of SObjectWidget -- but i couldn't figure out how to replace it in the UUserWidget. you are supposed to use TakeDerivedWidget for this, but the trick is that to use this you need full control of the instantiation of the UUserWidget, which, if you are building a UI in UMG, you don't.
so i went around and around trying different approaches, but ultimately i ended up creating a UUserWidget subclass that inserts an additional SObjectWidget (my subclass with a custom drag drop op) in between its root SObjectWidget and the WidgetTree that contains its actual content. all it does is listen for drag drop events that involve my custom drag drop op and forwards those to my UUserWidget. works great!

warm vault
#

Hi, is there any way to get touch position on entire screen or on UMG Element comsumes click event like Button or CheckBox?
I've tried used APlayerController::GetInputTouchState() when touch world, and UUserWidget::NativeOnTouchStarted() when touch UMGs.
But when I tried to get touch position on UButton and UCheckBox, click event was consumed in FSlateApplication::RoutePointerDownEvent().
Is there any way to get touch position on entire screen or on UMG Element comsumes click event like Button or CheckBox?

warm vault
#

@thick pasture Nope It's on Android

hybrid wedge
#

Hello, I am trying to understand how to customize details panel using Slate. I am not able to find any good reference for it. Can anyone help me with some info on it ? Thanks

thick pasture
low bluff
#

Was there a way to get the "default" widget for a Property? I'm in the function to return a ListView Row and I would like to use the Item (TSharedPtr<Struct>) with its normal widgets for the properties (a TSoftClassPtr and an int32).

stuck jewel
#

Hmm that comes from IPropertyHandle but I don't know how to create one of those from a bare property

low bluff
#

I changed the ListView to just be based on the PropertyHandle of each of my array entries

#

Seems to work :D

#

Hm, how does one make sure that the Splitter of the row follows the other splitters ? :<

#

The 2 next to Count are mine :D

stuck jewel
#

Are you using detail customization or property customization?

low bluff
#

Property

#

I have a Struct (which I'm customizing) with an Array of Structs in it.
The inner Struct has a SoftClass and an int32 in it.

#

I wanted to change it so I can filter with an SSearchBox

#

But I fail to create an SListView based on the Array

stuck jewel
#

Usually using the separate methods to create name and value sides should work I think... are you doing that, or are you using the single customrow method?

low bluff
#
TSharedRef<ITableRow> FActorPoolDefinitionCustomization::MakeListViewWidget(TSharedPtr<IPropertyHandle> Item, const TSharedRef<STableViewBase>&O wnerTable)
{
    const TSharedPtr<IPropertyHandle> classPropertyHandle = Item->GetChildHandle("Class");
    const TSharedPtr<IPropertyHandle> countPropertyHandle = Item->GetChildHandle("Count");

    return SNew(STableRow<TSharedPtr<IPropertyHandle>>, OwnerTable)[
        SNew(SSplitter)
        .Style(FEditorStyle::Get(), "DetailsView.Splitter")
        .PhysicalSplitterHandleSize(1.0f)
        .HitDetectionSplitterHandleSize(5.0f)
        + SSplitter::Slot()
        [
            SNew(SHorizontalBox)
            + SHorizontalBox::Slot()
            [
                classPropertyHandle->CreatePropertyNameWidget()
            ]
            + SHorizontalBox::Slot()
            [
                classPropertyHandle->CreatePropertyValueWidget()
            ]
        ]
        + SSplitter::Slot()
        [
            SNew(SHorizontalBox)
            + SHorizontalBox::Slot()
            [
                countPropertyHandle->CreatePropertyNameWidget()
            ]
            + SHorizontalBox::Slot()
            [
                countPropertyHandle->CreatePropertyValueWidget()
            ]
        ]
    ];
}
#

I do this atm

#
void FActorPoolDefinitionCustomization::CustomizeChildren(TSharedRef<IPropertyHandle> PropertyHandle, IDetailChildrenBuilder& ChildBuilder, IPropertyTypeCustomizationUtils& CustomizationUtils)
{
    const TSharedPtr<IPropertyHandle> definitionsHandle = PropertyHandle->GetChildHandle("Definitions");

    BuildEntryList(definitionsHandle);

    ChildBuilder.AddCustomRow(FText::FromString("Entries"))[
        SAssignNew(EntryListView, SListView<TSharedPtr<IPropertyHandle>>)
            .OnGenerateRow(this, &FActorPoolDefinitionCustomization::MakeListViewWidget)
            .ListItemsSource(&EntryList)
            .SelectionMode(ESelectionMode::None)
    ];
}
#

Gotta leave office now, but will read when I'm home

stuck jewel
#

so I can see why the problem occurs... you're making your own splitter... but not entirely sure if I know a solution. you have a single struct that defines each row right? but you haven't created a property customization for that particular struct? I think you should try doing that. In the struct's property customization, build its NameWidget and ValueWidget manually (by stacking both the inner Class or Count property's Name and Value widgets inside a single SHorizontalBox for each). And then for your MakeListViewWidget, don't create your own splitter. This way your struct entry (the actual thing being displayed by your list) is a single row with a regular Name and Value widget... I think/hope this will display how you want it then

#

thinking more, the next problem with what I've just said is that I don't know how the MakeListViewWidget method's return TSharedRef<ITableRow> lets you define a row entry that has Name/Value widget or just draw the widget for the whole struct noobthonk I thought there was a method for a property handle to just build the whole thing but can't find it right now

#

I wonder if you might need to dig into TArray somehow to look for clues first. I'm pretty sure what I described above would render correct if you didn't create a custom listview widget but just displayed the array (ChildBuilder->AddProperty(definitionsHandle) I think)

low bluff
#

@stuck jewel THanks for your time, I couldn't find time to read your answer up until now

#

I would also much prefer just having the singleproperty row

#

I know that's somewhat the widget

#

I will probably not be able to render it with one single splitter width for the whole thing, because that is handled by the SDetailsViewBase

#

There it has the columnWidth and that is passed into all the Splitters it creates

#

But I would be find if mine are shared within the widget, which should work if my details customization stores a value of how big the column is and passes that into each splitter, similar to the details view

#

That said, having a proper single row would be nice

low bluff
#

--
I might have found a solution

low bluff
#

Hm, nvm. Tried to just use the ChildBuilder, but I can't refresh the list like this

low bluff
#

Welp, close enough, that works for me haha

fair verge
#

I have problem that this fucntion doesn't call for me

TSharedRef<IDetailCustomization> IAUSConsiderationVisualization::MakeInstance()
{
    return MakeShareable(new IAUSConsiderationVisualization);
}

and this too

void IAUSConsiderationVisualization::CustomizeDetails(IDetailLayoutBuilder& DetailLayout)

so i wrote in my main game module this and StartupModule() calling any ideas what im missing?

#if WITH_EDITOR
#include "PropertyEditorModule.h"
#endif

#define LOCTEXT_NAMESPACE "FIAUSModule"
IMPLEMENT_PRIMARY_GAME_MODULE(FUEPrototypeModule, UEPrototype, "UEPrototype");

void FUEPrototypeModule::StartupModule()
{
#if WITH_EDITOR
    FPropertyEditorModule& PropertyModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor");
    PropertyModule.RegisterCustomClassLayout("IAUSConsiderationVisualization", FOnGetDetailCustomizationInstance::CreateStatic(&IAUSConsiderationVisualization::MakeInstance));
    PropertyModule.NotifyCustomizationModuleChanged();
#endif
}

void FUEPrototypeModule::ShutdownModule()
{    
}
#undef LOCTEXT_NAMESPACE
limber stump
fair verge
split laurel
# fair verge hmm thank you, ill try to change it

While the above is mostly true, the issue seems to lie with the first parameter in the register function. It's supposed to be the name of the class you want to customize, not the name of the customization. A better way to do this is to use
UMyClass::StaticClass()->GetFName()

#

This establishes the link between class and its customization

fair verge
#

Thanks a lot for the clarification

median pollen
#

Hey there guys! I'm looking around trying to figure out how to delete items in a tile view using the delete key, how would I start?

split laurel
median pollen
#

yeah it's actually getting the slate to do something when the delete key input is pressed that I'm not getting

split laurel
#

Ah, sorry, misunderstood the question. I was thinking of a map key..
Let me boot up my PC and see what I can find

median pollen
#

Oh I did find overriding the OnKeyDown virtual function from SWidget works haha

#

thank you though! I appreciate the help

split laurel
#

Haha, I was about to suggest that as I initially figured you had tried that out already

median pollen
#

nah I'm only just starting haha, thanks

split laurel
#

all good 👍

median pollen
#

so I'm using this to delete the items in my STileView

FReply STextureBrowser::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent)
{
    if (InKeyEvent.GetKey().ToString() == "Delete")
    {
        TArray<UTexture2D*> ListItemsSource = *ItemsSource;
        for (UTexture2D* ItemToDelete : this->GetSelectedItems())
        {
            ListItemsSource.Remove(ItemToDelete);
        }
        SetListItemsSource(ListItemsSource);
        RequestListRefresh();

        GEngine->AddOnScreenDebugMessage(-1, 5, FColor::Green, InKeyEvent.GetKey().ToString());
    }
    return FReply::Handled();
}
``` When I now press delete, it throws me a breakpoint
#

in SListView

split laurel
#

apparently the ptr is no longer valid, you'll need to check what and why, i.e., is CurItem pointing to an item you have just deleted or is it something else? The call stack would also be useful
A few things for better form:

  • Instead of using GetKey().ToString() use GetKey() == EKeys::Delete
  • You shouldn't need SetListItemsSourceif the source is the same as before. In fact it won't do anything if it's the same source, a refresh is enough. The list view isn't copying the array contents, just a pointer to the array. You have both an ItemsSource and a ListItemsSource so not sure what you are doing here
#

ah ok, I think I see the problem. Your ListItemsSource has a limited lifetime as it's destroyed when it goes out of scope, but since the list keeps a pointer to the array it points to garbage.
Make the ListItemsSource a member of your widget class instead

median pollen
#

ah right!

#

thank you!

#

@split laurel So I've added the ListItemsSource in my class and removed the SetListItemsSource

#

trying it now, but will it fail because it's not copying the contents of the array?

split laurel
#

your SListView will need to point to your source a single time unless you want to give it a completely different source (different address in memory)

#

so ideally you'll give your list view the ListItemsSource as source upon creation and then you'll only modify that array and call Refresh

median pollen
#

ah, and how would I remove an element from that source inside the widget itself?

split laurel
#

you'd do what you did before, call ListItemsSource.Remove(TextureObjectPtr);
then call View->Refresh()

#

the only difference being that your ListItemsSource no longer gets destroyed

median pollen
#

hmm, no more error, but the texture isn't deleting when I hit delete

split laurel
#

set a breakpoint to check if the array is being properly modified etc.

median pollen
#

I think ListItemsSource is beeing modified, but not ItemsSource

split laurel
#

yeah you need to modify the source that your view is using. Can you show me where you instantiate the view? (the SNew part)

median pollen
#
            + SWidgetSwitcher::Slot()
                [
                    SAssignNew(PaletteTileWidget, SPaletteBrowser)
                    .SelectionMode(ESelectionMode::Single)
                    .ListItemsSource(&PaletteTextureItems)
                    .OnGenerateTile(this, &SLiveryEditorToolView::OnGeneratePaletteTextureTile)
                    .OnSelectionChanged(this, &SLiveryEditorToolView::OnPaletteTextureSelectionChanged)
                ]
``` this is in another compound widget
split laurel
#

that's fine
but yeah so this is pointing to PaletteTextureItems which is now your ItemsSource within the widget

#

so simply modify ItemsSource itself I guess?

median pollen
#

unfortunately, I can't remove from ItemsSource

#

the reason why I did the whole ListItemsSource thing

split laurel
#

ah yeah, it's const. Do you know how delegates work?

#

as in, how you create them yourself and make use of them

median pollen
#

I do, that was my plan B

split laurel
#

then I'd do that, it's the cleanest route. There are a couple ways you could do it from within the widget but none of them are pretty

median pollen
#

I was hoping to keep it all in this class for now, but I guess it's unavoidable

#

thanks for the help and your time

split laurel
#

if you are 100% confident the only use case you'd ever want here is one specific thing (widgets are made to be reusable) you can also use a const cast

#

to get rid of the const

#

but I don't recommend it, it's unclean code

median pollen
#

yeah, I'll just use delegates, it's a little safer

split laurel
#

👍 I'm thinking of something like a "OnDeleteSelection"

median pollen
#

or "OnDeleteKeyPressed", since it's not doing anything

split laurel
#

yeah, or that, it really depends on how configurable vs. intentional you want to make this

#

with OnDeleteKeyPressed you are implying an inherent link to the delete key, but maybe you'll want another action within the widget to do the same (i.e. a "Remove Selected" button) later on. Just something to keep in mind

median pollen
#

ah yeah, good point

fair verge
# fair verge I have problem that this fucntion doesn't call for me ```c TSharedRef<IDetailCus...

sorry for getting back on topic, but i still have this problem. I moved PropertyModule initialisation from main game module to separate module. Also changed first param

void FIAUSModule::StartupModule()
{
#if WITH_EDITOR
    FPropertyEditorModule& PropertyModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor");
    PropertyModule.RegisterCustomClassLayout(UIAUSBaseConsideration::StaticClass()->GetFName(), FOnGetDetailCustomizationInstance::CreateStatic(&IAUSConsiderationVisualization::MakeInstance));
    PropertyModule.NotifyCustomizationModuleChanged();
#endif
}
limber stump
#

You shouldn't need the with editor stuff if its in an editor module. In your uproject/uplugin file is the new module set to editor type?

fair verge
limber stump
fair verge
#

As Editor

delicate marsh
#

if I have a FSlateTexture2DRHIRef or similar... how can I get a UTexture2D to render in a widget? 🥲
I am going insane trying to convert this 🥲

split laurel
#

just making sure here, but MakeInstance is only called when a details panel is actually shown. So it won't be called at startup. You have to select an object of the type in the details panel first.

fair verge
#

this is my class organisation and i want expand UECSIAUSResponseCurve to draw my curves in inspector.

#

Also MakeInstance didn't call if i choose curve type there

#

IAUSConsiderationVisualization has TSharedPtr<class IAUSCurvePreviewWidget> PreviewWidget; where IAUSCurvePreviewWidget has TWeakObjectPtr<class UECSIAUSResponseCurve> ResponseCurve;

limber stump
#

Your linear curve class won't inherit the customization of its parent is what Herr edgy is saying. Your linear curve class needs to also be added to your editor module with the customization and the polynomial as well

#

Each class you want to customize needs to be added individually

#

If you have reusable customizations that makes this needlessly repetitive then you can put those properties in a struct and customize the struct instead, so that any class with that property will get the customization

fair verge
#

thanks a lot for clarification and the explanation

shrewd wedge
#

Hey. I am looking for OnFocused event on a button. It seems there is none. The slate class SButton for some reason does not even override this callback. Any reason why?
Preferably without changing the engine I would like to fix this.
My first idea was to just inherit SButton but it does not seem to be that simple as there are multiple macros and the constructor is just confusing me.
We have a internal version of Button so I can easily change which slate class it creates.

craggy holly
#

What about:
virtual FReply OnFocusReceived(const FGeometry& MyGeometry, const FFocusEvent& InFocusEvent);

#

Part of SWidget

shrewd wedge
#

Yes. I know. But I would either have to change the engine implementation of SButton or create a "mirror class" of SButton 😦

quaint zealot
# shrewd wedge Hey. I am looking for OnFocused event on a button. It seems there is none. The s...

Example of a SButton child class here if you want to clear up the syntax: https://github.com/arbonagw/AstralShipwright/blob/master/Source/AstralShipwright/UI/Widget/NovaButton.h

GitHub

ASTRAL SHIPWRIGHT / Full game sources for Astral Shipwright, a space sim made with Unreal Engine 5. - AstralShipwright/NovaButton.h at master · arbonagw/AstralShipwright

#

rename the url for the .cpp

shrewd wedge
#

Thank you so much for that. Finally a working exampe. I could not find anything no matter the google query 🙏

modest minnow
#

I'll say upfront that I'm probably overlooking something incredibly stupid, but I'm trying to get a HorizontalBox with 2 columns where the first column expands until it reaches a maximum size and the 2nd column expands to fill the rest of the available width.

If I do this, it kinda works but stops filling at 2 x my limit:

TSharedRef<SHorizontalBox> Preview = SNew(SHorizontalBox)
        + SHorizontalBox::Slot()
        .FillWidth(1.0f)
        .MaxWidth(400.0f)
        .Padding(0.0f, 0.0f, 2.0f, 0.0f)
        .VAlign(VAlign_Top)
        [ PreviewThumbnail ]
        + SHorizontalBox::Slot()
        .FillWidth(1.0f)
        .Padding(0.0f)
        .VAlign(VAlign_Top)
        [ PreviewData ];
stuck jewel
#

have you tried dumping .AutoWidth() in either side? (and remove FillWidth)

modest minnow
#

I simplified my example and added some pictures to help explain my issue

TSharedRef<SHorizontalBox> Preview = SNew(SHorizontalBox)
        + SHorizontalBox::Slot()
        .FillWidth(1.0f)
        .MaxWidth(400.0f)
        [ SNew(SImage).ColorAndOpacity(FLinearColor::Red) ]
        + SHorizontalBox::Slot()
        .FillWidth(1.0)
        [ SNew(SImage).ColorAndOpacity(FLinearColor::Blue) ];
#

the above 2 are examples of it working as I want for sizes under 800, here's what happens over 800

modest minnow
#
TSharedRef<SHorizontalBox> Preview = SNew(SHorizontalBox)
        + SHorizontalBox::Slot()
        .AutoWidth()
        .MaxWidth(400.0f)
        [ SNew(SImage).ColorAndOpacity(FLinearColor::Red) ]
        + SHorizontalBox::Slot()
        [ SNew(SImage).ColorAndOpacity(FLinearColor::Blue) ];
#
TSharedRef<SHorizontalBox> Preview = SNew(SHorizontalBox)
        + SHorizontalBox::Slot()
        .AutoWidth()
        .MaxWidth(400.0f)
        [ SNew(SImage).ColorAndOpacity(FLinearColor::Red) ]
        + SHorizontalBox::Slot()
        .AutoWidth()
        [ SNew(SImage).ColorAndOpacity(FLinearColor::Blue) ];
stuck jewel
#

lol i love slate

modest minnow
#

My goal is for Column A to be (200 - 400) and Column B to fill the rest

modest minnow
#

This is the easiest thing in the world to do in every other UI so I'm either missing something simple or Slate is worse than I thought

stuck jewel
#

oh did you play with the alignment settings too already? .HAlign(fill) or whatever it is?

modest minnow
modest minnow
#

also I should say I'm willing to use whatever widgets get me to my goal, this doesn't need to use SHorizontalBox

#

In some other UI toolkits you can make a grid that allows you to set min/max widths for columns or allow you to set them to fill; something like that would work awesome for me. All I saw was uniform grids and dynamic grids that allow you to weight columns (but not just some columns)

#

ie

Columns[0].MinWidth = 200.0f;
Columns[0].MaxWidth = 400.0f;

Columns[1].Fill = true;
stuck jewel
#

yeah this does seem to be an oversight, i feel like i've made this for UMG though...

modest minnow
modest minnow
#

So after looking at ArrangeChildrenAlong in SBoxPanel.cpp it will never work the way I want because children are tracked as either "fixed" or "stretched". If a child is stretched, it needs a non-zero stretch coefficient. That means I'll never be able make it weight 50/50 until max for column A and then just fill with column B

#

Guess I'm going to need to make my own classes that override this and behaves the way I think they should already, shouldn't be much to change in this function

modest minnow
#

what you can do without modifying (and it's easy) is a fixed size with a fill; that might be what you were thinking of

stuck jewel
#

yeah i think so too

modest minnow
#

really thinking of just making the grid style I like and giving it out as a plugin

modest minnow
#

@stuck jewel Success on my immediate needs btw. Just needed to change the behavior from around SBoxPanel.cpp:125.

Here's the engine version:

// Clamp to the max size if it was specified
float MaxSize = CurChild.MaxSize.Get();
if (MaxSize > 0)
{
    ChildSize = FMath::Min(MaxSize, ChildSize);
}

Here's my version:

// Clamp to the max size if it was specified
float MaxSize = CurChild.MaxSize.Get();
if (MaxSize > 0)
{
    if(MaxSize < ChildSize)
    {
        if (CurChild.SizeParam.SizeRule == FSizeParam::SizeRule_Stretch)
        {
            NonFixedSpace -= MaxSize;
            StretchCoefficientTotal -= CurChild.SizeParam.Value.Get();
        }
        else
        {
            NonFixedSpace += ChildSize - MaxSize;
        }

        ChildSize = MaxSize;
    }
}

I'm using it with these parameters:

TSharedRef<SHBox> Preview = SNew(SHBox)
        + SHorizontalBox::Slot()
        .FillWidth(1.0f)
        .MaxWidth(400.0f)
        [ SNew(SImage).ColorAndOpacity(FLinearColor::Red) ]
        + SHorizontalBox::Slot()
        .FillWidth(1.0f)
        [ SNew(SImage).ColorAndOpacity(FLinearColor::Blue) ];
astral berry
#

Why are you making this with slate?
Are you making an editor UI element?

modest minnow
#

I am using slate because I need to and yes I am making an Editor UI element

#

specifically I am making an Import dialog

#

I just didn't like how SHorizontalBox was laying out children when some have a max size

#

anyway I don't know why I forgot about making gifs earlier, but here is what SHorizontalBox does with the exact same parameters

stuck jewel
#

Lol congrats

modest minnow
#

even if it is a bug I doubt they'd wanna change this class' behavior

astral berry
#

I don't think it's intended, but at the same time I don't think they care very much. XD
You can fix the engine, and make a pull request.

ocean mason
modest minnow
#

what I just posted above does exactly what I want

ocean mason
#

ok

modest minnow
# ocean mason ok

well I'm just saying that doesn't even make any sense based on what I described

ocean mason
#

don't worry about it, got confused of all those 5-6 code segments that do nothing :))

modest minnow
modest minnow
astral berry
modest minnow
analog cradle
#

FSlateDrawElement::MakeBox
How do i disable hittest when manually draw Slate?

craggy holly
#

Depends on the visibility of the widget doing the drawing

#

The hitbox itself is always rectangular, based on the geometry of the widget.

keen owl
#

Is there a function I've missed like MakeCircle or am I best off just drawing a spline?

sweet steppe
#

im trying to use loading screens in 4.26 and i get this slate crash
ue4 Assertion failed: IsInGameThread() || IsInSlateThread() || IsInAsyncLoadingThread() [File:Runtime\Slate\Public\Framework/Application/SlateApplication.h] [Line: 225]
what might i need to look into here?

craggy holly
#

You'll need to look at the full callstack

stiff scaffold
#

Hi all, I'm new to Mac dev with Unreal and having a weird problem with my slate UI. When I click down on a button, then release, the cursor jumps to the same spot on the screen (upper right corner for some, lower left of center for others). This does not happen with my UMG UIs, just the slate ones. It does not happen in windows. It seems to not happen if I step through the code (I think because the editor looses focus), it happens in the editor, standalone, and in packaged game on the Mac. Any ideas on where to start troubleshooting this?

merry notch
#

Hey guys! I got a question for you. We're trying to run a simulation in one window and show a little log in an SWindow. However, if we click on the Swindow to interact with it at all, it freezes the original application. Is there any way to have both run at the same time? Or disable the freeze on the original window?

desert oxide
#

is slate better than UMG?

limber stump
# desert oxide is slate better than UMG?

Umg is slate. It's just a object oriented wrapper around slate widgets to expose it to the editor. Therefor slate can do anything umg can do and more. In that way it's better I guess. But you also have to deal with using slate, which is a spine rending pit of madness half the time and incomprehensibly obtuse at its best. That's not to say I don't like it. I do, but I gotta be realistic that it's one of the least untuitive parts of unreal.
My advice, and most people's, is to use umg if you can and use slate if you must. That means that if you really need to add some core underlying functionality to your UI, then slate might be your only option. But 99% of the time there is no need. Save the frustration for that 1%.

desert oxide
#

thats unfortunate

#

I was hoping to find an alternative to UMG

#

I find components like Spacer that has a fill button not filling to be very frustrating

#

then asking around in several places and nobody knows how to resolve

limber stump
#

Well all I can say is that spacers are mostly redundant and serve the same purpose as adding padding to the slot. I never use them. You are probably trying to use it to solve something that it's not meant for

desert oxide
#

indeed

#

all I wanna do is pop a close button on the top of this form

limber stump
#

Where do you want the button to be?

#

Above the other buttons or in the corner?

desert oxide
#

thanks for your insight @limber stump

#

I was pulling my hair out

#

chats with you and a few othesr helped point me in the right direction

#

I appreciate the tip about UI frameworks too

#

will look into that

#

as for your Q ... corner

#

as I didn't wanna waste space and bring everything down a bit

limber stump
desert oxide
#

getting there

#

that 1st one ... will lead to a help page

#

or I could make it invisible just to keep things aligned

#

that size box is handy

sacred venture
#

How do i properly close a popup window?

    TSharedRef<SWindow> Window = SNew(SWindow)
        .IsPopupWindow(true);

    FSlateApplication::Get().AddWindow(Window);

It closes when out of focus, but still receives clicks

mild oracle
sacred venture
#

There are some, but i cant figure out what i'm doing wrong
Also most use Modals which I don't want

sacred venture
#

used PushMenu instead of AddWindow and now its working perfectly

split laurel
#

I'm not sure about internals but I'd suspect adding a window opposed to a menu will mean you need to manually destroy it. You can call something like Window->RequestDestroy() to manually get rid of them. For anyone interested

mental drift
#

howdy - what is the correct way to remove SWidgets from containers and destroy them? I have myself SVerticalBox where I put my own widget inheriting from SCompoundWidget and I don't know how to remove them. I see DeleteSlot in the VBox, but that requires me to have TSharedRef to the widget i want to remove, which I don't have since they are added dynamically and can be a lot of them. Is there something like UMG's RemoveFromParent?

verbal flume
#

Need to make a cursor that inverts its color and the inverted colors are based on the widget(s) below it. Any tips?

warm vault
#

Hey, I was wondering if there was such thing as a unreal engine 5 theme for unreal engine 4, to make UE4 look like UE5.

grave parcel
#

Hey, I was wondering if there is a way to know the size of a Slate widget that is inside a ScaleBox. If the widget is inside a CanvasPanel I can just check the slot size for the widget, but I don't know how to check for the size if it's inside a ScaleBox

fair verge
#

There is UdataAsset. Here are classes within classes, etc. I want to write a custom option mapping for a selected class inside a UdataAsset like in the screenshot.
I wrote in the module registration for a specific class UIAUSLinearCurve

PropertyModule.RegisterCustomClassLayout(UIAUSLinearCurve::StaticClass()->GetFName(), FOnGetDetailCustomizationInstance::CreateStatic(&FIAUSSonsiderationVisualization::MakeInstance));

But methods
FIAUSConsiderationVisualization::MakeInstance() and
CustomizeDetails(IDetailLayoutBuilder& DetailLayout) are not called.

They are called if I write a registration for the UdataAsset itself
PropertyModule.RegisterCustomClassLayout(UdataAsset::StaticClass()->GetFName(), FOnGetDetailCustomizationInstance::CreateStatic(&FIAUSConsiderationVisualization::MakeInstance));

and even if i do this way how to get to the data inside such a hierarchy

tidal mango
#

hello, is there any built-in SWidget for something like "actor list box" to which actors from a level can be drag and drooped?

raven tulip
#

how do people here understand the slate syntax 😅 What is the brackets [] equivalent in C++ syntax, are these operators overload?

quaint zealot
#

[] is generally a slot, usually the default slot

#

X->AddSlot() / X->SetContent() may work

raven tulip
#

Oh I see thanks, is there some sort of visual studio extension that format/lint slate syntax? Having trouble finding something similar