#slate

1 messages Β· Page 27 of 1

weary egret
#

include DeclarativeSyntaxSupport.h possible

junior glacier
#

Hey folks, I'm having a theory problem here over what's the best way to implement data tables, their structs, and just general data management, I'm afraid I've never properly studied this aspect before.

My issue ultimately is in trying to see the data referenced nested farther down the line, so I figured that's a slate-centric-issue? Apologies if elsewhere is better, please let me know!

The issue: Basically I have a masterlist of data, in a data table.
I want to make a data table that pulls references from that data table at will, and shows me all the data contained on that row in that data table, without me having to go to that data table in the editor and find the reference myself.

But I don't want to double the data just to get it to be visible in the subset data table. The closest I've gotten is if I make a struct with a single variable; "Data Table Reference Row" and then a Data Table containing a bunch of those structs, but it looks like this:

warm vault
#

dear community, I was wondering if anyone here has experience in building the game UI with web tech. I have many years of web based dev experience and would love the creative freedom of it ontop of our project

#

maybe someone could point me in the right direction ?

warm vault
#

Hmm

warm vault
#

@quaint zealot "call us to get a quote" sounds expensive ^^

quaint zealot
#

The web browser is probably usable with some work

#

Usually there's some kind of callback for URLs when web browsers get integrated

#

So you can then plug your own event system

#

Like, SWebBrowser has OnBeforeNavigation etc

#

I'd simply plug every callback with a nice print and experiment to see what gets called with which parameters

#

If you don't need extensive interaction it should work well

warm vault
#

do you have have experience with this stuff ?

#

when taking performace into perspective, I assume Canvas / UMG is the way to go, I just dont know how "custom" it can be which is why we are even discussing the subject

quaint zealot
#

It'll also have a completely separate resource system and won't have materials

#

But like, you asked about Web tech so it's possible

#

Outriders went with UE4+Coherent for example

warm vault
#

@quaint zealot the main question if we go with UMG is how customizable it is - becuase from initial research, it looks like building custom elements is not supposed to be done

#

I sent you a FA where I could show you something we currently have build on a different platform

quaint zealot
warm vault
#

hmm

#

but then I need to do that in C++ right ?

quaint zealot
#

If you're going Blueprint only UMG is pretty much the only choice anyway

warm vault
#

ok thanks

sinful narwhal
#

I'm making a UI that displays data from a dynamic number of assets, which can be toggled in a view similar to the Actors in the scene outliner. I want the toggled states to persist between closing and re-opening the window as well as restarting the editor. Is there a system which I can use to store these states or would a UObject with the Config specifier be my best bet?

tropic isle
#

Im trying to get a dialogue plugin to work, but I'm getting an error error C2440: 'initializing': cannot convert from 'SConstraintCanvas::FSlot::FSlotArguments *' to 'SConstraintCanvas::FSlot *' on the line:
SConstraintCanvas::FSlot* tempSlot = &CanvasPanel->AddSlot()

quaint zealot
#

UE5 right?

tropic isle
#

yeah its a 4.27 and trying to get it to run in 5.0.

quaint zealot
#

The slot syntax and behaviour changed completely

#

Try using auto here

tropic isle
#

AddSlot() seems to be SConstraintCanvas::FScopedWidgetSlotArguments SConstraintCanvas::AddSlot()

#

auto where?

quaint zealot
#

SConstraintCanvas::FSlot* tempSlot = &CanvasPanel->AddSlot()

#

Since the type is the issue

#

Failing that, well, it gets complicated

#

Slots essentially moved to a more Slate-y approach

#

So they're arguments now, not FSlots

tropic isle
#

not really sure how to use auto, but I tried in a few spots and none worked 😦

quaint zealot
#

You should ask the plugin author

tropic isle
#

Hm. Well I postedin the forum thread, but not sure how to get a hold of him directly. There were posts about it working in 5.0 with minimal problems, so the code must have changed since those posts

quaint zealot
#

5EA did not have those changes

#

5.0 does

tropic isle
#

Ahh ok. All this slate stuff is waay beyond my current skill so I guess I'll have to wait till he's able to update the plugin for 5.0

quaint zealot
#

I figure the Slate slot stuff is gonna hurt a lot of people, I do Slate on the daily and I didn't even correctly port them in DLSS to 5.0

tropic isle
#

Thanks for the help πŸ™‚

warm vault
nocturne charm
#

I'm having this error today
Unrecognized type 'FReply' - type must be a UCLASS, USTRUCT or UENUM
I have the Slate and SlateCore modules on build.cs

#

Someone knows why this is happening?

nocturne charm
#

Fixed.. I removed the UFUNCTION()

keen swift
#

How can I create an edit text? Essentially I want to create Slate's version of Qt QLineEdit

#

I found SEditableTextBox, but I think this is multi-lined. I want one line.

#

I feel like Slate is literally based on Qt conceptually lol

#

Looks like it is that

warped kestrel
#

is there a way to get the like, "overall" visibility of a userwidget

#

like, if MyUserWidget's parent is hidden, then it returns hidden regardless MyUserWidget's actual Visibility

median pollen
#

Looking to copy some data from my custom data asset into my slate plugin, is there a simple way of doing this? I've looked into SDetailTree, but I have no idea how to implement it

#

I'm just looking into replicating exactly whats in there into my plugin

warped kestrel
#

and that entire widget gets hidden in a different blueprint...

#

I can't detect that

#
{
    // if this widget is itself already ~hidden, just return that
    switch (this->GetVisibility())
    {
    case ESlateVisibility::Collapsed:
    case ESlateVisibility::Hidden:

        return this->GetVisibility();
    }

    // search up the ownership tree until we find something ~hidden
    UWidget* Current = this;

    while (Current)
    {
        switch (Current->GetVisibility())
        {
        case ESlateVisibility::Collapsed:
        case ESlateVisibility::Hidden:

            return Current->GetVisibility();
        }

        Current = Current->GetParent();
    }

    // if nothing in the tree was ~hidden, return our own visibility (assumed ~visible)
    return this->GetVisibility();
}```
vale solar
#

Probably pretty simple question, but is there a good example for doing ~~StrikeThru ~~on a simple STextBox?

#

I see it has support for a StrikeBrush but Im not entirely sure what that is looking for and how to set that up

azure oasis
#

Hello everyone! Not sure if it's a UI issue, most likely confused about inheritance and don't see an obvious error. UE crashes on any attempt to access WBP widget:
AmmoCrate.h
UCLASS() class PR_API AAmmoCrate : public AActor { GENERATED_BODY() public: AAmmoCrate(); virtual void Tick(float DeltaTime) override; protected: UPROPERTY(EditAnywhere, Category="Components") UHealthBarWidget* WBP; }
AmmoCrate.cpp
AAmmoCrate::AAmmoCrate() { PrimaryActorTick.bCanEverTick = true; WBP->SetHealthPercent(1.0); //**crash here!** ... }
UHealthBarWidget.h
class UProgressBar; UCLASS() class PR_API UHealthBarWidget : public UUserWidget { GENERATED_BODY() public: UFUNCTION() void SetHealthPercent(float Percent); protected: UPROPERTY(meta=(BindWidget)) UProgressBar* HealthProgressBar; }
UHealthBarWidget.cpp
#include "UI/HealthBarWidget.h" #include "Components/ProgressBar.h" void UHealthBarWidget::SetHealthPercent(float Percent) { if (!HealthProgressBar) return; const auto HealthBarVisibility = (Percent > PercentVisibilityThreshold || FMath::IsNearlyZero(Percent) ? ESlateVisibility::Hidden : ESlateVisibility::Visible); HealthProgressBar->SetVisibility(HealthBarVisibility); const auto HealthBarColor = Percent > PercentColorThreshold ? GoodColor : BadColor; HealthProgressBar->SetFillColorAndOpacity(HealthBarColor); HealthProgressBar->SetPercent(Percent); }

azure oasis
#

Oooops.
It was SO stupid xD Thanks! Stuck on this for a couple of hours...
And I'm sorry for mixing up the channels

glad elm
#

I'm working on a 'function dispatcher' system that lists UFUNCTIONs and stores them on an array. I took GAS' attribute system's dropdown menu logic and it's working fine so far. Would it be possible to create new widgets based on listed function's params? Like if the function has an int32 param I want to add new widget dynamically.

split laurel
#

I'm not familiar with the systems you are talking about, but if you have ufunctions and you are able to access a function's signature, you naturally can parse it and add additional widgets based on parameter type in your widgets via one of the many access points to add customized widgets for data

glad elm
#

Alright, thanks a lot

keen swift
#

How do I pass parameters to a SButton's OnClicked() event?

long cypress
#

I see this link everywhere when I try to understand how to make a custom graph editor...but it doesn't really help since there is soooo much code to understand in one go. Is there any tutorial/lesson about custom graph for beginners anywhere ? Best I found so far is this one : https://easycomplex-tech.com/blog/Unreal/AssetEditor/UEAssetEditorDev-AssetEditorGraph/
But it's very incomplete (missing big chunks of code) and very old (some code is deprecated)...so really not ideal xD

Any help would be greatly appreciated.

silk vault
#

But no, Slate and Editor Extentions is like, the least documented part of all of Unreal Engine. Haven't been able to find anything.

quaint zealot
long cypress
long cypress
quaint zealot
#

Very same

long cypress
#

If only I had found your link to the tutorial about custom thumbnail for custom assets, I would have saved a week of work in 10 minutes xD

mild oracle
#

Is there any way to go from a slate widget back up to its parent UUserWidget?

#

There must be, the widget reflector knows what each slate widget is insdie

thin robin
mild oracle
#

It's OK I managed to find a way to do it

sharp lantern
#

Did you ever find a solution to this? I have exactly the same problem ...

keen swift
#

How do I make an SButton change to a little loading spinner when they are clicked, until a delegate fires?

#
// Login and registration buttons
            + SVerticalBox::Slot()
            .Padding(Uniform_Padding)
            .AutoHeight()
            [
                SAssignNew(LoginButton, SButton)
                .Text(NSLOCTEXT("LoginScreen", "LoginButton", "Login"))
                .OnClicked(this, &SUGH1LoginWidget::OnLoginClicked)
            ]
            + SVerticalBox::Slot()
            .Padding(Uniform_Padding)
            .AutoHeight()
            [
                SAssignNew(RegistrationButton, SButton)
                .Text(NSLOCTEXT("LoginScreen", "RegistrationButton", "Register"))
            ]```
#

this is what i have

split laurel
faint sentinel
#

New to slate. Any quick ways to make the add and clear buttons for arrays? Or do I have to make SButton and set everything myself? In the reflector I see they're SPropertyEditorButtons, but not sure how it can be used. Can't even find out how to include it, looks to only exist in a .cpp file.

median pollen
#

no idea if I should post this here or in editor scripting to be honest, but is there a way of hiding categories in a DetailTree?

#

so this is how it looks in my slate

#

I want it to be like this

grave hatch
#

the property editor module has like a MakeSingleWidget (or something) call that might work for you.

grave hatch
median pollen
#

Ah dang alright thanks!
Is there no way of just having a slate widget that changes depending on the variable you make it? Like DetailTree but with single widgets?

#

A bit like what CustomDataAssets and the details panel has

grave hatch
#

I've never used it, so I'm not sure exactly what it'll do, but I figure it has to be something like what you want.

faint sentinel
#

Can I programmatically expand a collapsed (sub)category?

modest minnow
#

that will work for any type of widget btw

grave hatch
#

Or do you mean in the details panel?

#

It's a little harder to navigate that one.

solar cedar
#

Help with some editor tools. Im using SObjectPropertyEntryBox and i can "do" what i need to: Select an animation asset and set a variable value on the class of the component i need to modify

#

but 2 things are broken:

  1. The value doesn't change on the SObjectPropertyEntryBox
  2. The blueprint is not marked as dirty
#

if i do mark it somehow and save everything serialize as expected

#
void FNPCSplinePointDetails::OnSetAnimationAsset(const FAssetData& assetData)
{
    if (UAnimationAsset* animAsset = Cast<UAnimationAsset>(assetData.GetAsset()))
    {
        const FScopedTransaction Transaction(LOCTEXT("SetAnimationAsset", "Set Animation Asset"));

        const int32 Index = *SelectedKeys.CreateConstIterator();
        if (UNPCSplineData* splineData = SplineComp->GetComplexDataAt<UNPCSplineData>(Index))
        {
            splineData->AnimAssetToPlay = animAsset;
        }

        if (ComplexDataProperty)
            FComponentVisualizer::NotifyPropertyModified(SplineComp, ComplexDataProperty);
        UpdateValues();
    }
}

this is basically what i'm doing

#

it's details for a splinecomponent which has metadata to store aditional values on some points

solar cedar
#

i think the main issue is that im not linking the property handle with the entry box

#

but for some reason i can't really seem to be able to do that

#

the handle is always invalid

grave hatch
#

Have you tried adding a breakpoint and stepping through the code?

#

Blah->Modify() will mark it dirty.

mild oracle
#

What's the "correct" way to tell if a modifier is being pressed in editor code? I see there's a bunch of keybindings for actions in the editor but I'm not really sure how to check in editor code for if shift (or whatever the action is bound to) is being held down

grave hatch
#

Are you implementing your own keybinding system for a widget? Or are you changing behaviour when shift is held down?

tribal fractal
#

Anyone know how to force focus on SMultiLineEditableText? I'm creating new EditableText and when user create it I want to move the focus right into it so he don't need to right click to the widget to start typing. This is editor widget created with slate.

This isn't working:
MultiEditableTextGlobalNote->SetText(FText::FromString("Temp")); MultiEditableTextGlobalNote->Refresh(); MultiEditableTextGlobalNote->GoTo(FTextLocation(1, 0));

This isn't working as well
FVector2D Pos = MultiEditableTextGlobalNote->GetCachedGeometry().GetAbsolutePositionAtCoordinates(FVector2D(1.f, 1.f)); const FPointerEvent& SimulatedPointer = FPointerEvent(uint32(0), uint32(0), Pos, FVector2D::ZeroVector, TSet<FKey>(), EKeys::LeftMouseButton, 0.0f, FModifierKeysState()); MultiEditableTextGlobalNote->OnMouseButtonDown(MultiEditableTextGlobalNote->GetCachedGeometry(), SimulatedPointer);

Edit:
Nvm. This is working:
FSlateApplication::Get().SetUserFocus(0, MultiEditableTextGlobalNote, EFocusCause::SetDirectly);

quaint zealot
#

<@&213101288538374145>

brazen yacht
#

Trying to make a RichText decorator that can display a UserWidget inline in the text and not just an image. I'm really close to make it work, just got one problem:cpp const FRichWidgetRow* RichWidgetData = Decorator->FindRichWidgetRow(*RunInfo.MetaData[TEXT("id")], bWarnIfMissing); UUserWidget* WidgetPtr = CreateWidget((UWidget*)Owner, RichWidgetData->WidgetToDisplay); //Problem is that GetCachedWidget returns NULL... TSharedPtr<SWidget> RichWidget = WidgetPtr->GetCachedWidget();

#

I did it! In this case instead of cpp WidgetPtr->GetCachedWidget(); you should use cpp WidgetPtr->TakeWidget();the functions have comments explaining their usecases

brazen yacht
#

How do I make the inline widget have vertical alignment in center instead of at bottom?

brazen yacht
#

So that the middle of the widget is in the middle of the text vertically, could I perhaps take the the text's lineheight / 2 and offset the widget up as a hax?

warm vault
#

what’s the difference between UMG and slate

#

I’ve only used the umg channel but I thought I’d see what this is too

limber stump
# warm vault what’s the difference between UMG and slate

Umg is the uobject based wrapper around slate. They are not different systems. Slate is just the lower level that you can use if you need it. Since slate is just regular old code, the editor cannot use it, so you are forced to write it in cpp. The primary use case for learning slate it to make editor plugins, or to customize the editor in general. The only reason to use it in game code is if you really need to add something to umg that it cannot do natively. Only worry about that if you already have a good handle on umg, since it can do most things decently if you learn it well.

#

It's also infamously incomprehensibly difficult to use, due to the syntax being especially strange, despite being normal c++, but once you get used to it, it's not that bad really. It just gets a bad rep sometimes.

grave hatch
#

Once you get used to it, it's actually pretty easy to work with.

#

The barrier to entry is very high, though.

wide plaza
#

the barrier is "that looks a bit odd but ok"

grave hatch
#

Compared to the rest of UE, it's pretty high.

quaint zealot
#

The main barrier is more that since it's not for game use, there's little documentation other than 8 year old hacks and the editor source

odd summit
#

Hi,
When you start a blank project, pressing play, it gives you a simple free-camera to go around. This is all i really require for the app I am making; except for that the mouse is locked as soon as you right click.
What I would like to do though, is have a button press that lets you move the mouse (no camera movement) and interact with the UI.

i thought it would be simple but idk where to start

rain heron
#

what are workspaces from the FTabManager?

grave hatch
#

You can use it for games, stranger.

stuck jewel
#

not openly intended* for games. (I know Stranger has used it in games before himself and was just having a slip of words πŸ˜„ )

grave hatch
#

I made a whole game in Slate!

#

It was excruciating. But a good learning experience.

#

(And by whole game, I mean the game was literally 100% slate ui, no actors, etc.)

stuck jewel
#

i guess life itself wasn't depressing enough for you already?

grave hatch
#

πŸ™‚

rain heron
#

._.

#

that doesnt answer my question...

vague skiff
#

so looks like Tile View is quite useless. There is no Multi Toggle selection mode and I don't see way to limit number of selections (it is either none, one or anything in list).

#

can you at least unselect something during selection of that same thing? that would be enough to simulate limited amount of selectable items

grave hatch
#

Couldn't you use the selection changed delegate to do that? Or override Private_SetItemSelection?

zinc reef
#

Could anyone help me understand what the difference is between SLATE_BEGIN_ARGS / SLATE_ATTRIBUTE and regular Construct parameters? E.g., when is it preferred to use one or the other? Does the SLATE_ATTRIBUTE provide any additional magic beyond enabling the builder-style syntax?

mild oracle
zinc reef
keen swift
#

How can I do conditional creation of slate widgets based on argument input in Construct()

#

Like this little edit text, how could i make it so that this only gets created if an argument is true

zinc reef
#

To get more specific, I'm trying to build a tree view. And currently I'm just passing a const reference to a flat array as a second Construct param, and then building the nested data structure inside Construct. But if the array isn't populated when I first construct the widget, it doesn't update when the array changes (no surprises there, since I'm not reconstructing the widget). I could sort of cowboy-code it by just adding an update method to my widget that I can call with the new data, but I guess what I'm wondering is if there's a more idiomatic or built-in way to handle that sort of thing.

#

I did notice that when you create a SLATE_ATTRIBUTE it wraps your data in a TAttribute with a Get method, so I was thinking... maybe that creates some sort of dynamic/observed binding? Somehow? But I really have no idea, that's just a wild guess. So I figured I'd ask to see what it actually does.

grave hatch
#

@keen swift you don't have to add slots and such within a giant slate constructor, you can do ->AddSlot() at a later point

#

That's basically what it does, @zinc reef

#

TAttribute allows you to either specify a value, bind to a function or not specify it at all.

keen swift
#
        .HAlign(HAlign_Right)
        .VAlign(VAlign_Bottom)
        [
            SNew(SVerticalBox)
            + SVerticalBox::Slot()
            [
                SNew(SBox)
                .WidthOverride(600)
                .HeightOverride(300)
                [
                    SNew(SImage)
                    .ColorAndOpacity(FColor::Black)
                    
                ]
            ]
        ]```

How can I add items to be within the SBox? It's only letting me add the SImage and nothing else. I'm just trying to make a small chat box on the bottom right of my screen which should have a tinted black background (black is fine for now) and a SEditText and a list of chat messages, not sure if there's a SListView or something
#

If I add a new vertical box slot it's putting the text ousdie of the black background

#

i want it to be inside of the black background lol

#

SBox doesn't have a Slot sadly

grave hatch
#

If something only has a single child slot, you need to add a widget rthat has multiple slots into that single child slot

#

Like an SCanvas or SConstraintCanvas

keen swift
#

How do I do that?

grave hatch
#

Things with a single slot usaully have a ChildSlot

#

What you can do as well is use SAssignNew instead of SNew too

#

TSharedPtr<SMyWidget> MyWidget; (before your layout code)

#

Then SAssignNew( MyWidget, SMyWidget ) (inside your layout code)

#

Then you can manipulate the widget however you like after layout

#

Like adding dynamic content

grave hatch
#

(dynamic based on your construct vars)

keen swift
#

I understand how SAssignNew works, just creates the new slate object and assigns it to the variable you pass, right?

grave hatch
#

replace SMyWidget in the above example with SConstraintCanvas

#

Then later you can do MyWidget->AddSlot() [ details here ]

#

Or whatever your layout widget of choice is

keen swift
#

i'm not sure which slate widget only has one child slot

grave hatch
#

SBox?

#

In fact, I'm not sure why you're using SVerticalBox right now. It's not necessary for that black box, it should be deeper in your layout

#

Go prototype your layout in UMG and then convert it to slate.

keen swift
#

How do I make it repaint a SCompoundWidget? It seems like it's not repainting my widget when I add a new slot to the SConstraintCanvas

SConstraintCanvas::FSlot* tempSlot = &ChatConstraintCanvas->AddSlot()
    [
        SNew(STextBlock).Text(NSLOCTEXT("MenuWidget", "PublicChatBox", "Public Chat"))
    ];```
#

nevermind looks like it was created but its super small

shrewd wedge
#

Hey people, I am losing a button down/clicked event. I tracked it down to SlateApplication.cpp line 4341
But I cannot trace along that lambda. The click event gets "handled" somewhere there but even after I placed a breakpoint on every single OnKeyDown implementation I do not get a breakpoint hit.
Anyway. It occurs when I launch the game and click the confirm button on the face of my controller. When I press it quickly the button that is focused in UMG is not clicked. Instead only on the second try will I get a click callback.
It would seem like the switch from keyboard/mouse to controller consumes the input πŸ€”
But when I long press the button the clicked event gets sent out as normal.
Any ideas on how to fix this inconsistency?

eternal wave
#

how do I get local cursor position in OnMouseMove event of my custom widget ?

toxic rock
#

Are you using a node "SetInputModeUIOnly"?

I had same issue when only 2nd click was recognized correctly and that node was causing the issue, even if my Project was UMG based only

If you're using this node - remove it and replace with "SetInputModeGameAndUI", I used it to restrict the mouse within Viewport and after change the issue was gone

#

and just btw - I am working with UE 4.27

toxic rock
#

or maybe you have focus on something different at the beginplay and you have to make focus on a part you want to click and then it's being recognized afterwards

grave hatch
#

@eternal wave use the GetScreenSpacePosition() from the pointer event and the GetAbsolutePosition() of the geometry thing, that's how I usually do it anyway.

#

You may need to adjust for UI scale and such if you want coordinates accurate (compare GetAbsoluteSize() with GetLocalSize()) in local space

#

so ( PointerEvent.GetScreenSpacePosition() - Geometry.GetAbsolutePosition() ) * Geometry().GetLocalSize() / Geometry().GetAbsoluteSize() unless I've missed a handy function for this.

weak fiber
#

i'm running into an issue where invisible/disabled widgets are slipping through here despite checking for it, is there something i'm missing?

grave hatch
#

What are the visibility states of the visible invisible widgets?

weak fiber
grave hatch
#

"Technically", yeah.

#

What are you trying to do?

weak fiber
grave hatch
#

Are you trying to find the widget under the cursor or anything?

weak fiber
#

to be specific, the nearest SButton to the cursor (getting the cached widget from the found widget and checking SWidget type)

grave hatch
#

You could try IsFastPathVisible

weak fiber
grave hatch
#

It's a base SWidget function

weak fiber
grave hatch
#

->

weak fiber
grave hatch
#

Try to compile it.

#

Never trust intellisense without trying that frist.

weak fiber
grave hatch
#

Well it definitely is.

#

Maybe not on your version?

weak fiber
#

might be able to backport the change if it's new in 4.27

grave hatch
#

Yeah, isn't on 4.26.

weak fiber
grave hatch
#

I'd just check each parent widget until you hit a specified root widget.

weak fiber
#

thanks again for the help, was pretty lost with this one

grave hatch
#

Np

#

I'm sure there's a better way, you could, for instance, set a "group" on your widgets and then check if that group's parent widget is visible to speed things up. Depends how deep your widget hierarchy goes.

weak fiber
grave hatch
#

😦

iron kayak
#

how to pass FArguments& Arguments to an SCompoundWidget when building it through SNew?

#

its constructor is void Construct(const FArguments& Arguments, const TSharedRef<IEditableTextProperty>& InEditableTextProperty);

but I only see examples of usage:
SNew(STextPropertyEditableTextBox, EditableTextProperty) with no FArguments

grave hatch
#
  .SomeProperty( value )
  .SomeOtherProperty( othervalue )```
eternal wave
grave hatch
#

Fantastic. πŸ™‚

lilac inlet
#

Something is eating my inputs.
How can I find out what is consuming inputs?
Something is putting my game into a state where it ignores VR controller inputs.
They don't make it to the player controller, and they don't even make it to UGameViewportClient::InputKey . They are definitely making it to FSlateApplication::ProcessKeyDownEvent, I do hit a break point in that function.
Once I click on the game viewport, the VR controls respond normally again.

#

(At this point I'm tempted to just find a way to force input back to the main viewport)

lilac inlet
#

Got it! If anyone's curious,

  1. To figure out what had the focus, I called "Set Focus to Game Viewport" in BP, and put a break point in FSlateApplication::SetAllUserFocusToGameViewport . It runs a function to get the OldFocus and OldFocusPath, which helped me figure out where the focus was.
  2. The offending widget had a call of UWidget::SetKeyboardFocus . Worked fine when not using VR, but in VR would take the focus away from the game viewport.
weak fiber
#

same with inputs, etc

lilac inlet
#

Nifty, thanks for the tip @weak fiber !

mortal echo
#

Does the OnIsSelectableOrNavigable delegate for STreeView or SListView actually do anything? I've set it but it doesn't seem to properly limit item selections in my tree. A breakpoint would seem to indicate that it's not even being called as I click around my tree.

grave hatch
#

Check where it's called in the source and figure out the conditions for it.

#

It may not behaving exactly as you expect.

unkempt moss
#

Hi everyone, how can i make my slate widget not fullscreen? I have this code:
`ChildSlot
.VAlign(VAlign_Center)
.HAlign(HAlign_Center)
[

        SNew(SBox)
        .WidthOverride(256)
        .HeightOverride(100)
        [

....`

grave hatch
#

You could use a constraint canvas with the anchors set to 0.5f, 0.5f, 0.5f, 0.5f and the alignment set to 0.5, 0.5f, then the offset set to half size (width/2, height/2, width/2, height/2.)

#

(I overuse constraint canvases, I think)

unkempt moss
#

Thanks @grave hatch , now I have
`ChildSlot
.VAlign(VAlign_Center)
.HAlign(HAlign_Center)

    [

        SNew(SConstraintCanvas)
        + SConstraintCanvas::Slot()
        .Anchors(FAnchors(0.5,0.5,0.5,0.5))
        .Alignment(FVector2D(0.5,0.5))
        .Offset(FMargin(50,50))

...but it's still fullscreen. in the HUD I haveRightDistanceWidget = SNew(SDistanceWidget).OwningHud(this).Space(0);

GEngine->GameViewport->AddViewportWidgetContent(SAssignNew(RightDistanceContainer, SWeakWidget).PossiblyNullContent(RightDistanceWidget.ToSharedRef()));
`
Is this correct?

grave hatch
#

You wouldn't need the valign and halign

#

That's handled by the constraint canvas.

#

Looks about right. 😦

#

The anchors anchor it to the centre of the screen, at zero size, the alignment makes it use the centre of the widget to calculate its location and the offset should make it 100x100 :/

#

Oh, the offset should be negative for left and top.

#

-128,-50,128,50 or so

#

But that isn't your problem right now!

#

The constraint canvas will still cover the entire screen, but the slot should only be in the middle.

unkempt moss
#

what if i use .AutoSize(true) con SConstrainCanvas?

grave hatch
#

Maybe?

#

But it's the constraint canvas's parent that's the issue. That's going to cover the entire screen regardless.

#

(it will just do it transparently)

grave hatch
#

@unkempt moss any luck?

unkempt moss
#

I'm still trying. I'm having lunch right now, I'll let you know.

glad elm
#

So I'm having a weird callstack like this and dont know where to start debugging. Engine crashes at SImage::ComputeDesiredSize when I place a node to my custom graph

#

Probably this is invalid but..

#

Alright fixed, I was using invalid Pin class

rain heron
#

When using style sets... how can i probably use other styles as attributes of a new style?

So what i want is following:
I have a SlateStyle-Struct that will be used in two other Styles, its called "NumericKeyframeIcons"
One of those other styles is called "KeyframeControl"
How Can I tell in the Cpp code, that the default KeyframeControl should use the NumircKeyframeIcons from the style set?

The image shows the "Numeric Keyframe Icons" Attribute of the "Keyframe Control" style in the style set doesnt have the same values as the "Numeric Keyframe Icons" style in the style set...

I dont want to have to manually copy it over, because if i have later multiple styles that rely on the "numeric keyframe icons" style in the style set, and i change it, it would cause inconsistencies... so best would be if the system somehow understands that it should do the C&P automatically

forest bough
#

Hi,

How do I get the UUserWidget from a SWidget?

grave hatch
#

Good question.

#

Get all objects of class and check the swidget on each of them?

#

I don't see an easy way to do it.

#

If you're using a custom uuserwidget, you could extend the swidget you're using to add a reference to the uuserwidget. But that's not really a general solution.

forest bough
grave hatch
#

Kinda of only works if you already have a UWidget reference, though...

bold forge
#

your UUSerWidget should always have an SObjectWidget backing it I believe

quaint zealot
modest minnow
#

I have a property customization that's basically a header with a SExpandableArea (containing whatever) and I'm using it to render the value in a UPROPERTY(meta=(ForceInLine)) TMap.

It works fine except sometimes the outer containers doesn't know it should render a scroll bar.

What is the best way of having it notify/invalidate an unknown ancestor OnAreaExpansionChanged (or is there a better approach)?

modest minnow
#

@warm vault πŸ‘‹

keen halo
#

I'm trying to create a plugin with C++ that pops up a window with some basic slate UI components such as text boxes, drop down lists and buttons. Any particular slate tutorial I can refer to that covers all the basics?

grave hatch
#

Slate... tutorial?! Are you mad?!

#

Sorry, Slate is notoriously bad at documentation. I don't know a tutorial off hand!

quaint zealot
keen halo
keen halo
limber stump
keen halo
#

I got it, gonna check the source out 😬

forest bough
quaint rain
# keen halo I'm trying to create a plugin with C++ that pops up a window with some basic sla...

If you use qt I wrote this qt to slate guide a while back
https://minimaleffort.tech/qt-to-slate-transition-guide/
I'm new myself too but there isn't a lot out there

This is a casual guide for those who know Qt and C++ and are looking to get started writing custom Editor Plugins for UnrealEngine. Quick Disclaimer: I am not an Unreal developer and am still quite…

keen halo
grave hatch
#

That's really good!

green maple
#

Hey all. Im trying to figure out how slate works with the garbage collection system these days. Any insight?

weary egret
#

slate is not managed by the GC

#

that's why you see it wrapped in TSharedPtr

green maple
#

I see. That makes sense. If I have a UProperty for a UObject inside a slate widget that should be garbage collected though right?

weary egret
#

slate can't have UPROPERTY

minor geyser
#

Hey guys, how would I either, draw slate over the UMG, so that I can draw my dynamic crosshair over the widget or Create some sort of slate object in UMG

grave hatch
#

It can have a UPROPERTY, but the UPROPERTY will just not do anything.

quaint zealot
#

UMG objects are just a Blueprint layer over Slate objects for GC support, UPROPERTY, content linking

split laurel
narrow scroll
#

Hola πŸ‘‹

I'm pretty sure I had this figured out a year ago or two, but I can't find the code and now I cannot for the life of me get a widget redraw to work. I spawn an editorwindow OnSpawnPluginTab and add a custom widget. The custom widget has some buttons that calls a childprocess. Upon exit of the childprocess I change the state of the widget.

So far so good, but now I would like to draw the updated state (layout and values) within the editorwindow. Is there any way to flag the widget dirty, force the editor to redraw etc?

Cheers, Daniel

quaint rain
# narrow scroll Hola πŸ‘‹ I'm pretty sure I had this figured out a year ago or two, but I can't ...

Is this for a custom painted component?
You can trigger Invalidate when you need to clear the cache, if it's for existing components then just setting the data should do the trick (not always but I don't have much context)
https://docs.unrealengine.com/4.27/en-US/API/Runtime/SlateCore/Widgets/SWidget/Invalidate/

Invalidates the widget from the view of a layout caching widget that may own this widget.

narrow scroll
# quaint rain Is this for a custom painted component? You can trigger Invalidate when you need...

Thanks for the pointer πŸš€ I believe I got it working πŸ˜„

To double check my workings (as I'm new to UE4) is the following considered a decent approach?

  • Create SMyWidget inheriting from SCompoundWidget
  • Build widget ChildSlot in Construct method with some buttons and bind to class methods
  • methods access and rebuild ChildSlot
  • call Invalidate()

Is this the way to go? I was expecting a virtual method along the lines of "OnStructureLayout", but directly editing the childslot seems to work for me so far.

grave hatch
#

Seems about right.

#

Is there any specific reason you need to completely rebuild the childslot?

narrow scroll
#

I am launching a childprocess and pushing/receiving data to that process through stdin and stdout. Every stdout is a complete state, formatted as json. The widget should reflect the state of the childprocess. Hence, I don't want to be too clever with caching any "frontend" and just rebuild the widget whenever I receive data πŸ˜ƒ

grave hatch
#

Fair

modest minnow
# modest minnow I have a property customization that's basically a header with a `SExpandableAre...

Still looking for help if anybody has some clues....
#slate message

It seems the issue happens with any property customization that can change size (header row or child row) if it's used in a map (with or without meta=(ForceInLine)).

What is happening is when the SExpandableArea (or whatever size changing element) in the customization changes size, the parent SDetailsView won't properly calculate the scrollbar.

modest minnow
#

There's even more weirdness going on with scroll just having items expanded. And sometimes cannot make it through the full map. Here's some gifs and an example!

Hopefully it peaks somebody's interest cause I'm stumped πŸ™ƒ

keen halo
#

To get a dropdown list like below using slate, should I use listview?

quaint zealot
#

SComboBox

keen halo
#

Thank you!

#

Got it

silent swan
#

Hello folks!

#

I have a weird issue hehe

#

we implemented a loading screen with a umg widget , using the video module. It's a basic widget that has a simple throbber. The throbbers all work... excepting on the 1st loading screen (the one where the engine loads I guess?)

#

/UE_LOG(LogTemp, Warning, TEXT("OnPreLoadMap: %s"), *mapName);
bIsLoadingLevel = true;

if (!IsRunningDedicatedServer())
{
    FLoadingScreenAttributes LoadingScreen;
    LoadingScreen.bAutoCompleteWhenLoadingCompletes = false;
    LoadingScreen.PlaybackType = EMoviePlaybackType::MT_LoadingLoop;
    LoadingScreen.bMoviesAreSkippable = false;
    LoadingScreen.bAllowEngineTick = true;
    
    UUserWidget*loadingWidget;
    if(bStartupVideoShown)
    {
        loadingWidget = CreateWidget<UUserWidget, UGameInstance>(this, LoadingWidgets[FMath::RandRange(0,6)]);
    }
    else
    {
        loadingWidget = CreateWidget<UUserWidget, UGameInstance>(this, LoadingWidgets[7]);
        bStartupVideoShown = true;
    }

    if (loadingWidget!=nullptr)
    {
        //LoadingScreen.WidgetLoadingScreen = FLoadingScreenAttributes::NewTestLoadingScreenWidget();
        LoadingScreen.WidgetLoadingScreen = loadingWidget->TakeWidget( );
        GetMoviePlayer()->SetupLoadingScreen(LoadingScreen);
    }

}
#

is there a particular reason why the first loading doesn't animate the throbber and all other widgets do?

grave hatch
#

Did you mean if (!bStartupVideoShown) ?

pearl tiger
#

So In CoreStyle.cpp there is this.

Style->Set( "ToolBar.Button", FButtonStyle(Button)
.SetNormal ( FSlateNoResource() )
.SetPressed( BOX_BRUSH( "Common/RoundedSelection_16x", 4.0f/16.0f, SelectionColor_Pressed ) )
.SetHovered( BOX_BRUSH( "Common/RoundedSelection_16x", 4.0f/16.0f, SelectionColor ))
.SetNormalForeground(FSlateColor::UseForeground())
.SetPressedForeground(FSlateColor::UseForeground())
.SetHoveredForeground(FSlateColor::UseForeground())
.SetDisabledForeground(FSlateColor::UseForeground())
);

I am trying to use this style but it's not working. I just want the style of button that toolbars use

const auto Widget = SNew(SButton)
                .ButtonStyle(&FCoreStyle::Get().GetWidgetStyle<FButtonStyle>("ToolBar.Button"))
                //.TextStyle( FEditorStyle::Get(), "FlatButton.DefaultTextStyle")
                //.OnPressed( &FluidNarratorLocalizationEditor::HandelToolbarNamespaceComboBoxAdd)
                [
                  ...
                  ...
                  ...
                ]
grave hatch
#

Define "not working"

#

There's also FAppStyle or the Starship styles you could try.

pearl tiger
pearl tiger
grave hatch
#

That'd be the FSlateNoResource() I imagine.

pearl tiger
#

Ok

keen halo
#

Okay, I understand that when creating a slate combobox, it takes an argument for type data. I want to use the combo box to display some names that I have inside a TArray, what would my ComboBox declaration look like then?

#

Should I use FAssetData since the TArray type is also FAssetData?

#

So my ComboBox declaration would look like SNew(SComboBox<TSharedPtr<FAssetData>>)

keen halo
#

Okay tried the combobox, my popup window remains empty, at first I thought maybe the combobox wasn't populated so I just put a piece of text, that didn't work either

keen halo
#

Nothing in Unreal Engine has ever pissed me off before

#

Slate : So I took that personally

grave hatch
#

Lol

#

If I'd used them before. :(

#

Have you tried looking at how the engine uses them?

#

Or a plug in?

pearl tiger
#

.h

TSharedRef<SWidget> HandelNamespaceComboBoxMakeWidget(TSharedPtr<FString> InOption) const;
void HandelNamespaceComboBoxSelectionChanged(TSharedPtr<FString> SelectedValue, ESelectInfo::Type);
FText HandelNamespaceComboBoxCurrentItemLabel() const;

TSharedPtr<SComboBox<TSharedPtr<FString>>> NamespaceComboBox;
TArray<TSharedPtr<FString>> NamespaceComboBoxOptions;
TSharedPtr<FString> NamespaceComboBoxOptionSelected;
#

.cpp

#
SAssignNew(NamespaceComboBox,SComboBox<TSharedPtr<FString>>)
                .OptionsSource(&NamespaceComboBoxOptions)
                .OnSelectionChanged(this, &SFluidNarratorLocalizationTextsSlateWidget::HandelNamespaceComboBoxSelectionChanged)
                .OnGenerateWidget(this, &SFluidNarratorLocalizationTextsSlateWidget::HandelNamespaceComboBoxMakeWidget)
                .InitiallySelectedItem(NamespaceComboBoxOptionSelected)
                [
                    SNew(STextBlock)
                    .Text(this, &SFluidNarratorLocalizationTextsSlateWidget::HandelNamespaceComboBoxCurrentItemLabel)
                ]
grave hatch
#

Why would you need a sharedptr to an fstring?

#

Is that just a combo box thing?

pearl tiger
#
TSharedRef<SWidget> SFluidNarratorLocalizationTextsSlateWidget::HandelNamespaceComboBoxMakeWidget(TSharedPtr<FString> InOption) const
{
    return SNew(STextBlock).Text(FText::FromString(*InOption));
}

void SFluidNarratorLocalizationTextsSlateWidget::HandelNamespaceComboBoxSelectionChanged(TSharedPtr<FString> SelectedValue, ESelectInfo::Type)
{
    NamespaceComboBoxOptionSelected = SelectedValue;
    HandelRows();
}

FText SFluidNarratorLocalizationTextsSlateWidget::HandelNamespaceComboBoxCurrentItemLabel() const
{
    if (NamespaceComboBoxOptionSelected.IsValid())
    {
        return FText::FromString(*NamespaceComboBoxOptionSelected);
    }

    return FText::FromString("NULL");
}
grave hatch
#

Also why not use FText directly?!

#

Anyway...

pearl tiger
pearl tiger
#

Here is example from my code

//Add Namespaces
NamespaceComboBoxOptions.Empty();
for (int i = 0; i < LocalizationAsset->Namespaces.Num(); i++)
  NamespaceComboBoxOptions.Add((MakeShareable(new FString (LocalizationAsset->Namespaces[i].ToString()))));

//Set Selected
NamespaceComboBoxOptionSelected = NamespaceComboBoxOptions[0];
pearl tiger
grave hatch
#

But you're converting to ftext anyway!

pearl tiger
#

If he wants to use FText than he should be able to.

grave hatch
#

I'm not quite sure you need to worry about memory for a combo box. That's a little overoptimisation!

pearl tiger
grave hatch
#

Oh it's an fname, nvm then!

pearl tiger
#

Yha, this is for my dialogue system and this is part of my localization editor.

grave hatch
#

Ah. You're the one that did the custom localisation stuff?

pearl tiger
#

Yes

grave hatch
#

It still seems weird to me that you're storing text as an fname, instead of just a key.

#

Maybe you're selecting a key there...

pearl tiger
#

I even got google translate working with it to auto translate text

grave hatch
#

It's 2am. I'm going to sleep!

pearl tiger
#

Sure

pearl tiger
keen halo
shrewd finch
#

Hey guys.. Just trying to learn more about PollGameDeviceState

#

right now I'm doing a VR project and i'm spending about 24ms on FEngineLoop_Tick_PollGameDeviceState

#

when I use the CPU profiler.. that's in a packaged build too.. so no editor stuff getting in the way

#

we're in UE4.27

keen halo
#

Not only have you explained Qt and Slate but the surrounding classes as well which will give a hella lot of insight to a complete newbie

grave hatch
#

@shrewd finch it may be that it's blocking somewhere?

shrewd finch
#

yea not sure... I did more reading on PollGameDeviceState and I guess it stalls if you aren't making your device's target frame rate.. so that the input can catch the next frame or something

#

so like.. if you don't make 80 fps.. it drops to 40

#

and that's where it clogs

#

that's what I saw someone saying on Reddit or something.. it was all a haze last night when I was searchign lol

#

thanks though @grave hatch

keen halo
#

Okay when you make changes to a slate component in visual studio, what exactly should you do to make those changes reflect within unreal engine?

#

I made the mistake of rebuilding which took eons

keen halo
#

It's cool, all I had to do was recompile, totally forgot that! πŸ™ˆ

keen halo
#

I have a TArray containing Asset Data but this same TArray is required as the options list in the SComboBox but I get an issue here because I'm using TArray<FAssetData> instead of TArray<TSharedPtr<FAssetData>>

quaint zealot
#

Yup, need to make them into a shared pointer

keen halo
#

On the other hand, the GetAssetsByClass() method from the Assets Registry requires a TArray if I'm not mistaken which is why I cannot include TSharedPtr

quaint zealot
#

Need to keep two separate arrays and convert

keen halo
quaint zealot
#

For loop, MakeShared

keen halo
#

Okay I'm not exactly sure what that is but I shall check it out now

mellow imp
#

Hey! Is there any way to extend this name area to add a button? Ty

grave hatch
#

Have you looked at the property editor module and IDetailView ?

keen halo
#

What is the order for padding in slate? Top, left, right, bottom?

grave hatch
#

The margin is Left, top, right, bottom.

#

Check the FMargin constructor

#

You can also do just 1 number for uniform padding or 2 numbers for different horitzonal and vertical padding

keen halo
mellow imp
grave hatch
#

So you can place something there for a generic details panel, but not on a per-selection basis?

mellow imp
#

Yes, just for one class

grave hatch
#

If you want to place something on the details panel for a specific class, you can add class-specific details customisations and just add something right at hte top (or even to the transform section) of the panel.

#

By at the top, I mean the details property tree!

mellow imp
#

By creating a new category row you mean?

young sleet
#

New row, or editing existing rows.

#

You can get a row by name.

#

My question is actually really similar. What I'm trying to do is customize how a class is displayed, when used as an instance.

#

So right now I have it customizing when the asset is being edited, but instead I want to customize when it's inside of Instanced UPROPERTY field.

#

There seems to be only these three

#

I figured out how to do it on a per-asset bases, but that's not great :/

mellow imp
#

DetailBuilder.GetDetailsView() has this but idk if any of this is what you need

grave hatch
#

You could use a custom property layout.

#

But that would be specific to a property on a class

young sleet
#

I'm just trying to fix an engine bug xD

grave hatch
#

What's the bug?

young sleet
#

One sec, will find link

#
#

Here is what I have:

#
    // This is customizing ClassA, which I know contains ClassB
    for (const ClassB* classB: ClassA->ClassBArray)
    {
        for (TFieldIterator<FProperty> propIt(classB->GetClass()); propIt; ++propIt)
        {
            const FProperty* property = *propIt;
            const FName propertyName = property->GetFName();

            const TSharedPtr<IPropertyHandle> propertyHandle = detailBuilder.GetProperty(propertyName, property->GetOwnerClass());
            
            // Might change this flag later
            if (property->HasAnyPropertyFlags(CPF_AdvancedDisplay))
            {
                detailBuilder.HideProperty(propertyHandle); //hope it works :)
                // propertyHandle->MarkHiddenByCustomization(); //didn't work
            }
        }
    }
#

Neither work to hide the prop :/

#

I get the correct name though

#

@grave hatch Any thoughts on why I can get the handle, but not hide it?

#

detailBuilder.HideCategory doesn't work either.

grave hatch
#

Are you sure it's actually executing?

keen halo
#

Say I want to make a button green in colour, what is zee property I gotta use?

keen halo
#

Both OnClicked and OnClicked_Raw give me the error "no instance of overloaded function matches the argument list"

#

But I used the right code according to an example I saw

#

I got a function named TestMap in the module FTestPluginModule

#

My OnClicked function is as follows

grave hatch
#

Paste function signature and your line of code binding it.

keen halo
#

.OnClicked(this, &FTestPlugin::TestMap)

grave hatch
#

Is "this" an FTestPlugin ?

keen halo
#

Yes

grave hatch
#

And the function signature?

keen halo
#

void FTestPlugin::TestMap()

grave hatch
#

The return type should be FReply

keen halo
#

What does that do?

grave hatch
#

just put return FReply::Handled(); in your function

#

(or Unhandled())

keen halo
#

Okay

#

I think it should be handled for me

grave hatch
#

Welcome to Slate.

keen halo
#

Oh it has been HELL

grave hatch
#

Once you get used to it, it's pretty neat.

#

There's one man, he has a large beard, who is used to Slate. The creator.

keen halo
#

I'm starting to get the hang of it little by little and honestly I don't mind it

#

That Qt to Slate guide has been really helpful too

#

Your solution worked by the way, thanks. Any reason why FReply is a necessity in this occassion?

grave hatch
#

Urgh, reminds me, I need to extend SButton to allow long clicks

#

Because it determines whether the mouse click was handled or not.

#

If it isn't handled, I assume it's passed up the chain to the next widget.

#

You also use FReply to start drag operations.

keen halo
keen halo
#

Using FReply and .OnClicked gives me an error when recompiling but using .OnClicked_Raw is alright

#

You know how we get a small message at the bottom right stating that shaders are compiling with a loading sign? Is it possible to create a loading sign like that for my plugin too? Until whichever function has completed?

grave hatch
#

Yes. How you specifically do it, though, not sure.

#

Plus you'd probably have to implement an asynctask or threading with progress features!

keen halo
#

Great! Sounds like something I won't be doing

#

Not this week at least

#

😈

grave hatch
#

Is there a way to make a subclass of, say, SButton inherit from SButton's FArgs? The standard macros don't seem to allow it.

grave hatch
#

Implemented it, but it's a little shitty!

mellow imp
grave hatch
#

I have to go by a higher standard than that, unfortunately. 😦

split laurel
grave hatch
#

What I did was add an argument with the type SButton::FArguments

#

Then passed then to the button construct

split laurel
#

Aye, I did this recently as well after asking internally if there was some way to make it work properly

#

It starts looking funky if you have content slots as well in the base args, but that's the best way currently possible I believe

grave hatch
#

The alternative seemed to be not using the macros... which seemed wrong.

#

Yeah, that's what I end up having. Looks very weird, but it works.

split laurel
#

You can do that, if it's just needed on your own end

#

The macros only define the fargs struct after all

grave hatch
#

Yeah.

#

I just didn't like the idea of it breaking when the macro changed for some reason.

split laurel
#

However, the problem lies with the fact that the builder pattern will return the base fargs struct once you start configuring it

#

Sure

#

I.e. if you have struct A inheriting from B

And you call SNew(SMyButton).ASomething().BSomething() and you want to add another .ASomethingElse() it won't work since the BSomething will return a B type args that is no longer aware of all the A members

grave hatch
#

Yeah.

#

And that's just not good!

split laurel
#

It is not! πŸ™‚ but sadly nothing can be done now

keen halo
#

How do I get a heading style font size like that?

#

And also that little horizontal rule they've used?

#

I tried most of the other slate components but changing font sizes seemed kinda shady to me 😦

silk vault
#

Search the code base for FEditorStyle or GetFontStyle, you'll find a million sprinkled around the engine, I can't remember exactly where these font styles are defined - but it's definitely in that module.

mellow imp
#

Is it possible to create a new custom "Section" here for my categories?

minor geyser
#

Hi, Do you guys know how I would make a combo box with textures?

quaint zealot
keen halo
minor geyser
#

Sorry new to slate

quaint zealot
#

That's also UMG stuff

young sleet
#

Combo boxes are (I think) notoriously difficult in slate.

minor geyser
#

Yeah, I was actually wanting to have it in UMG, I dunno specifically the difference ><

young sleet
#

UMG is a wrapper around slate.

#

The engine is made with Slate

#

The in-game UI is "UMG", although you can also drop down to slate for that if you want.

#

(by in-game, I mean that UE4 offers a slate-builder-wrapper called UMG, which people use to make their games HUD/menus/etc)

minor geyser
#

Yeah I thought something like that

minor geyser
quaint zealot
#

That's the UMG source code

young sleet
#

I would drop my question quickly as well, in case anyone has an answer: What is the best way to customize the details view of an instanced UObject?

#

I have a class MyClass with an instanced TArray of MyChildClass. I want to customize MyChildClass EVERYWHERE that it appears, but I'm also willing to target MyClass directly.

#

Current approach is customizing MyClass, getting the TArray of MyChildClass, iterating its properties, and then doing stuff w/ them.

#

The issue is that the details view for MyClass isn't letting me hide properties for MyChildClass, even though I have a handle to them.

#

I think I need to somehow get a detailBuilder for MyChildClass, but I don't see how to do that from the scope of MyClass.

#

*customizing MyChildClass is a no-go, since it only customizes the details view of the asset, NOT the instanced view that shows in other classes.

#

TLDR: I have a valid handle to a property of an instanced UClass, but I can't hide it, because I think I don't have a handle to the correct details view.

#

I was hoping propertyHandle->MarkHiddenByCustomization(); would work, but no luck 😦

minor geyser
#

Is SNew slate?

quaint zealot
#

Yes

#

S = Slate

minor geyser
#
        SNew(SComboBox< TSharedPtr<FString> >)
        .ComboBoxStyle(&WidgetStyle)
        .ItemStyle(&ItemStyle)
        .ForegroundColor(ForegroundColor)
        .OptionsSource(&Options)
        .InitiallySelectedItem(CurrentOptionPtr)
        .ContentPadding(ContentPadding)
        .MaxListHeight(MaxListHeight)
        .HasDownArrow(HasDownArrow)
        .EnableGamepadNavigationMode(EnableGamepadNavigationMode)
        .OnGenerateWidget(BIND_UOBJECT_DELEGATE(SComboBox< TSharedPtr<FString> >::FOnGenerateWidget, HandleGenerateWidget))
        .OnSelectionChanged(BIND_UOBJECT_DELEGATE(SComboBox< TSharedPtr<FString> >::FOnSelectionChanged, HandleSelectionChanged))
        .OnComboBoxOpening(BIND_UOBJECT_DELEGATE(FOnComboBoxOpening, HandleOpening))
        .IsFocusable(bIsFocusable)
        [
            SAssignNew(ComboBoxContent, SBox)
        ];```
#

So how would I modify this for textures

young sleet
#

You should get comfortable with the Widget Reflector.

#

Oftentimes you can find something similar in the engine, and therefor find some code example of something you want to do.

#

From what I recall though, most texture selection widgets are not done with dropdown, but rather some other asset selector, which isn't easily broken down into its components.

grave hatch
quaint zealot
mellow imp
keen halo
#

@quaint zealot not really sure how to use makeshared and convert tarray<fassetdata> into tarray<tsharedptr<fassetdata>> like you suggested

#

Tried looking around for an example code but didn't find anything

quaint zealot
#

You can't convert shit, have to create a new array and add pointer-ized entries to it

keen halo
quaint zealot
#

for loop, Add()

keen halo
#

Well damn

#

Both of them having the same type is correct yeah? (FAssetData)

quaint zealot
#

They don't have the same type, one stores instances and one shared pointers

#

That's why you have to copy everything element by element

keen halo
#

Got you, thanks!

keen halo
# quaint zealot for loop, Add()

So I used a for each loop to iterate through the TArray if it isn't null, but the Add() function keeps throwing this error about argument lists not matching πŸ₯Ί

quaint zealot
#

Read the compiler output to understand why they don't

deep tendon
#

I'm trying to add text to a textbox with .Text(TEXT("")) but when I do that I get an error saying 'FText::FText': cannot access private member declared in class 'FText'

#

but if I do LOCTEXT it works fine

quaint zealot
#

Yes, that's normal, TEXT() is just for regular C strings

#

Use LOCTEXT, or add FText::FromString around TEXT

deep tendon
#

if you scroll down to List Views

quaint zealot
#

Gonna guess that this page hasn't been updated since 2013

deep tendon
#

Ah okay lol

#

resources on slate are really bad, wow

#

and non existant

quaint zealot
#

It's purely engine internal so there's no documenting that

#

Study the editor UI to make your own editor UI, essentially

deep tendon
#

Yeah, that's what i'm doing but as a noobie its a lot easier when their are resources showing you the basics. Saves so much time and confusion

#

The docs do help

#

Also I haven't tried getting the engine source code yet so I can't look at the files shown in the Widget Reflector

#

Obviously a me problem. Ill figure that out soon lol

quaint zealot
#

Yeah learning Slate is really just reading the editor code

deep tendon
#

Source code here we come

grave hatch
#

Somebody posted a good qt to slate guide which covered the basics, even if you're not familiar with qt

deep tendon
grave hatch
deep tendon
#

thanks sm!

deep tendon
#

nvm

deep tendon
#

I'm not understanding why the size of a child component will effect the size of other child components when the alignment isn't set to fill or center. It should just effect its own box right??

#

Its like the child component size is effecting the parent box size which is moving each child component farther to the right. Which means the child components content doesn't effect its own size, only the size of its parent. Which makes no sense because why would the default functionality be that each child component has a uniform length / percentage of its owners space and how could you change it to fit the content

grave hatch
#

Some are top-down, some are bottom-up. It's annoying at times.

deep tendon
#

Yeah I had a big hierarchy and it was really confusing me. It wasn't smart as a noob slate user to create a bunch of sections and then try to align / fix them lol. I figured it out now though. Finally.

grave hatch
#

Good!

deep tendon
#

I'm an idiot

grave hatch
#

Oh? What did you do?

deep tendon
#

It took me 2 hours to figure out I needed to put AutoWidth() on every slot to stop sections from clipping each other and have my desired spacing. Just frustrating. Yes I learned a lot about how slate works with all the different things I tried but I’m upset at how long it took me to isolate the problem. I made so many stupid mistakes

grave hatch
#

At least you won't make them in the future!

deep tendon
#

Haha very true

#

:3

stuck jewel
#

until tomorrow

deep tendon
#

cough lol

grave hatch
#

Don't forget, there's also .AutoHeight()

#

(on the things that support it)

deep tendon
#

I don’t think I’ll use that as much because it can look weird if lines aren’t uniform. It does depend on what your trying to do though

grave hatch
#

I'm currently wondering about a layout issue myself, actaully

#

I have a grid panel, 3 columns wide. The second 2 columns are of unknown width (sized to content.)

#

I want to be able to have a mouseover background tint on the row when I mouse over any part of it.

deep tendon
#

Ah I’m going to work on something super similar tomorrow. I haven’t gotten to that yet though sorry.

#

I’d assume theirs a function for hover and then you can bind a delegate?

grave hatch
#

I'm sure I could do some sort of "Check size of parent grid, use that" type of thing, but eh.

deep tendon
#

But that’s total guesswork

grave hatch
#

It's the width size that I'm wondering about and the placement in the hierarchy.

#

Do grid cells even have backgrounds? Or will I have to add something? All that sorta stuff.

deep tendon
#

I’m pretty sure you have to add something

#

Just add a SImage as a child slot for each of the grids

#

Then on hover access that child and change the color

grave hatch
#

Yeah, that's the easy part! Making it not change the size of the gird might be more difficult.

deep tendon
#

If it’s a child slot I think if you set it to FillWidth(1) it will stay in the bounds of its parent

grave hatch
#

But the child slots are all used by other things.

#

I don't want the slot at 0,0, for instance, to use the entire row.

#

I could add something that goes out of the cell bounds to cover the row, but then am I going to hit z-order issues with the contents of the other cells?

#

(that's probably easy to fix)

deep tendon
#

So your grid has an item in it that you want to use to change the width right? its contents? But you dont want anything else effecting the grid width besides that one content item?

grave hatch
#

Moment

#

I can just bind the width of a color block in column 1 (and use an overlay to put the icon on top of it) to the width of the grid

#

It seems a little cheap, though.

deep tendon
#

Have ur grid, set grid to HAlign(HAlign_Fill). Then for each grid slot: Add a SImage child (for background color). Add a SBox child to the SImage. Fill that child with (Icon, or Deskcription, or Keybind)) Set that child to AutoWidth

grave hatch
#

Yes. Use 3 images!

deep tendon
#

I haven't used a grid yet so their might be something im not thinking of

grave hatch
#

(Or color blocks in this case)

#

SColorBlock is your friend.

deep tendon
#

each grid slot should have its own slot hierarchy

#

Definitely use function helpers

deep tendon
#

I'm trying to add .OnClicked to a button but im getting an error that I can't seem to wrap my head around

#
SNew(SButton).OnClicked(this, &FTestPluginModule::CreateMinefieldSection)
#

The errors are a lot of text but they are mostly like this:

#

'SButton::FArguments::WidgetArgsType &SButton::FArguments::OnClicked<FTestPluginModule>(UserClass ,FReply (__cdecl FTestPluginModule:: )(void))' being compiled
with
[
UserClass=FTestPluginModule
]

#

'TDelegate<FReply (void),FDefaultDelegateUserPolicy>::CreateSP': no matching overloaded function found

#

'StaticCastSharedRef': no matching overloaded function found

deep tendon
#

Once I completely separated plugin and slate functionality this got so easy lmao. I didn't know that was allowed.

gusty stirrup
#

Hey people, I was trying to implement GameplayTag to my slate which I use for my struct. I couldn't find an easy way to display GameplayTag as it is, so I had to copy everything in GameplayTagCustomization.h / .cpp and that way I get the same look.

Is this the only solution? Is there a way to let the slate display default slate look? Or I need to create every functionality if I want to have them in my structure?

craggy holly
#

Need some more context to answer that really

#

Where does the tag live? Is it a UPROPERTY? Where are you displaying it etc?

gusty stirrup
# craggy holly Need some more context to answer that really

Of course, the tag lives in my structure. Here's the structure.

USTRUCT(BlueprintType)
    struct BLINDDESCENT_API FBehaviorTreeNodeStruct
{
    GENERATED_BODY()
     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Amount")
    FGameplayTag Amount;
}

I created a customization class which is inherited from IPropertyTypeCustomization

#

I'm basically following a tutorial, I couldn't find a way to display GameplayTag as it is and started copying everthing in GameplayTagCustomization.h and it looks like this now

#

I'm not sure if this is the only way. The customization is already done so there should be a way to pass all of this and display it in my own structure.

craggy holly
#

Yeah you don't need to do that, you can just create the default property widget for that property

gusty stirrup
#

Sounds great, thanks! How can I do that? I've been searching the Discord and the internet for hours now. πŸ˜…

craggy holly
#

Get the property handle, then call 'CreatePropertyValueWidget' or 'CreatePropertyTitleWidget'

#

I do something similar in a detail customisation I have to force struct values to display in non-expandable row

#

You can do that in either CustomizeHeader or CustomizeChildren

gusty stirrup
#

Thanks, I'm trying it right now

craggy holly
#

Snippet if it helps:

{
    // Gather Children
    uint32 NumChildren = 0;
    StructPropertyHandle->GetNumChildren(NumChildren);

    ChildHandles.Reset(NumChildren);
    for (uint32 ChildIndex = 0; ChildIndex < NumChildren; ChildIndex++)
    {
        ChildHandles.Add(StructPropertyHandle->GetChildHandle(ChildIndex).ToSharedRef());
    }

    for (uint32 ChildIndex = 0; ChildIndex < NumChildren; ChildIndex++)
    {
        ValueGrid->AddSlot(Column, Row)
            .VAlign(VAlign_Top)
            .HAlign(HAlign_Fill)
            [
                SNew(SVerticalBox)
                +SVerticalBox::Slot().VAlign(VAlign_Top).HAlign(HAlign_Fill)
                [
                    ChildHandle->CreatePropertyValueWidget(true)
                ]
            ];
    }
};```
gusty stirrup
# craggy holly Snippet if it helps: ```void CustomizeHeader(TSharedRef<IPropertyHandle> StructP...

Thanks! I didn't want to waste your time so I tried to check everything. But unfortunately it doesn't work. Only one what works is the name variable. Here's what I did;
My structure;

{
    GENERATED_BODY()

    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    FGameplayTag MyTag;
    
    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    FTransform Transform;

    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    FName MyName = "MyNameDeneme";
    
};

Customization

{
    const TSharedPtr<IPropertyHandle> GameplayTag = StructPropertyHandle->GetChildHandle(0).ToSharedRef();
    const TSharedPtr<IPropertyHandle> Transform = StructPropertyHandle->GetChildHandle(1).ToSharedRef();
    const TSharedPtr<IPropertyHandle> Name = StructPropertyHandle->GetChildHandle(2).ToSharedRef();
    
    check(GameplayTag.IsValid() && Transform.IsValid() && Name.IsValid());
    
    StructBuilder.AddCustomRow(LOCTEXT("BehaviorTreeNodeStructRow", "BehaviorTreeNodeStruct"))
    [
        SNew(SBorder)
        .BorderImage(FEditorStyle::GetBrush("ToolPanel.GroupBorder"))
        .BorderBackgroundColor(FLinearColor(255.f, 152.f, 0))
        .Content()
        [
            SNew(SWrapBox)
            .UseAllottedWidth(true)
            + SWrapBox::Slot()
            .Padding(5.f, 0.f)
            [
                GameplayTag->CreatePropertyValueWidget(true)
            ]
            + SWrapBox::Slot()
            .Padding(5.f, 0.f)
            [
                Transform->CreatePropertyValueWidget(true)
            ]
            + SWrapBox::Slot()
            .Padding(5.f, 0.f)
            [
                Name->CreatePropertyValueWidget(true)
            ]
        ]
    ];
}
#

Wow, didn't think it would be this huge. Anyway this is the result:

#

Am I missing something?

craggy holly
#

Hmm that's odd. It should go through the usual channels and find the customisation

#

You could try getting the customisation instance from the property editor module

gusty stirrup
#

Not sure if it's related but I'm doing this in a newly created Engine module. MyGameEngine to be specifically. Can that be related to that?

craggy holly
#
PropertyModule.FindPropertyTypeLayoutCallback(FName("GameplayTag"));```
#

Don't think so

#

But from that, you can get the callback and execute the delegate

#

But there shouldn't be any reason to, so it's a bit strange

gusty stirrup
#

Thanks, I will try this! Hopefully this will work

craggy holly
#

You may need to step through and debug it otherwise, but AFAIK it should pick up other customisations so not sure why it isn't in this case

#

Just pass in an empty/default value for the last param of that function

#

IDK, something like this perhaps. Might give you something to debug with anyway

        if (Callback.IsValid())
        {
            const TSharedRef<class IPropertyTypeCustomization> Customisation = Callback.GetCustomizationInstance();
            Customisation->CustomizeHeader(ChildHandle, HeaderRow, StructCustomizationUtils);
        }```
#

Can't help much beyond that I'm afraid

keen halo
#

Will this be correct? @quaint zealot

keen halo
#

Or should I replace "new FAssetData(Level)" with "&Level" ?

gusty stirrup
hot notch
#

I'm curious about something. I have some semi complex UWidgets. I'm wondering if these are usable in slate? I'm more or less wondering about some basic wrapping for some UserWidgets. I know I can create slate directly in a UserWidget's RebuildWidget, but can I use a UWidget in the same manner?

EG, simplifying things a lot. I know that I can wrap a UserWidget's content in an SBorder. Is it possible to use a UWidget, get it's slate, and wrap the UserWidget's content in the UBorder's SBorder?

deep tendon
#

Does anyone know any information on generating slate slots based on cpp / procedurally gererating slate slots? ChildSlot[].AttachWidget(TSharedRef<SWidget>(SNew())) will overite the existing widget, which makes no sense to me. I can't add a widget slot with c++ bc adding an extra ChildSlot[]; will just overwrite the previous one. Also I obviously can't have a cpp function that uses slate syntax because that syntax would need to be outside a Childslot[] to work with c++ so it doesn't overwrite the previous ChildSlot[]

grave hatch
#

If something only has a single slot, you can't add more slots.

#

Add a child with supports more slots and add things to that.

hot notch
#

Hmm. Getting the impression that I can't do what I want. Am probably going to need to recreate my UWidget as an SWidget and just use the SWidget in both cases. :/

deep tendon
deep tendon
#

I dont want to manually write the code is what i'm saying

hot notch
#

Yeah. I'm kinda learning in reverse. πŸ˜„ Know enough to alter and muddle slate, but am used to making UWidget wrappers that extend things rather than actual slate.

grave hatch
#

Store a reference to the child widget (or just get it from the children array) and do ->AddSlot(...) on it.

deep tendon
deep tendon
hot notch
#

What is the WITH_ACCESSIBILITY by the way? The in engine description for it is kinda vague.

deep tendon
#

@grave hatch ```
TSharedRef<SMinefieldStartupWidget> MineWidgetSharedRef = SNew(SMinefieldStartupWidget);

MineWidgetSharedRef.AddSlot

grave hatch
#

Btw, mugs, are you doing ChildSlot[].AttachWidget everywhere?!

deep tendon
#

Can you give me an example? Or resources about this subject? I didn't see anything about it in the documentation

grave hatch
#

Normally it'd be ChildSlot[ SNew(something) ]

#

You can only add slots to container that support adding new slots.

deep tendon
#

So it would be ChildSlot[SNew()].AddSlot()?

grave hatch
#

If something has ChildSlot, it doesn't support multiple slots.

#

You need to put something in that child slot that supports multiple slots.

#

Like a vertical box or constraint canvas

#

TSharedPtr<SVerticalBox> MyVerticalBox; in your header. Then SAssignNew(MyVerticalBox, SVerticalBox); and MyContainer->AddSlot()[ MyVerticalBox ]; Then you can add slots to it with MyVerticalBox += SVerticalBox::Slot() [ some widget here ]; or MyVerticalBox->AddSlot()[ some widget here ];

deep tendon
#

//Ok I know I can do

ChildSlot
[
  SNew(SVerticalBox)
  +SVerticalBox::Slot()
  [
  ]
]

//but I want to do
for(int i = 0; i <= 10; i++)
{
  +SVerticalBox::Slot()
}

#

Does that make sense?

#

Wait let me read what you said lol

grave hatch
#

You could do ChildSlot[ MyVerticalBox ]; too.

#

(instead of code block #3)

deep tendon
#

Yes but id still have to write VerticalBox manually which won't work with data that changes

grave hatch
#

Or combine it up with ChildSlot[ SAssignNew( MyVerticalBox, SVerticalBox ) ];

deep tendon
#

Yeah let me read what you said about SAssignNew

grave hatch
#

That's why you empty the vertical box (remove all teh slots) when your data changes

deep tendon
#

I havent processed it yet

deep tendon
grave hatch
#

Because SCompoundWidget isn't a multi-slot container.

deep tendon
#

I thought as much. Thanks so much for the help!

#

Took me a bit to get what you meant when you said that earlier my b

hot notch
#

I am having some trouble with some nesting. Trying to follow source code. But not having a lot of luck with it. Just trying to do something super simple by nesting a Border inside of a blur, and set the content inside of the border.

    MyBlur = SNew(SBackgroundBlur)
    .Content()
    [
        MyBorder = SNew(SBorder)
        .HAlign(HAlign_Fill)
        .VAlign(VAlign_Fill)
        .Content()
        [
            InArgs._Content.Widget
        ]
    ];```
#

SCompoundWidget inheritor's Construct function.

#

This works with only the border, or only the blur. Unsure of why it isn't working with both?

quaint zealot
#

What's the question here?

grave hatch
#

If you're trying to add 2 widgets to a compound widget, it won't work. Try adding an intermediary SOverlay or something

hot notch
#

I'm trying to add a blur to a compound widget, and add a border inside of the blur. And add the content inside of the border.

grave hatch
#

Add an overlay widget with 3 slots, blur, border, content

#

Unless you want the blur on top of the contents, then add it last?

hot notch
#

But why? Blur has a slot. Border has a slot. Why does this require an overlay?

quaint zealot
#

The syntax with MyBorder here is the only weird thing

#

I'vs only ever seen SAssignNew

#

Do you have any particular issue other than code ?

grave hatch
#

Have you used the widget reflector to check the size of the widgets?

quaint zealot
#

What is the issue ?

hot notch
#

I think I derped that. Creating the border first with the content, then the blur with the border works.

grave hatch
#

I was getting confused with Mugs problem |:

hot notch
#
    .Content()
    [
        InArgs._Content.Widget
    ];
    
    MyBlur = SNew(SBackgroundBlur)
    .Content()
    [
        MyBorder.Get()->AsShared()
    ];

    ChildSlot
    [
        MyBlur.ToSharedRef()
    ];```
#

Ended up at that. Still getting used to using shared refs and pointers.

grave hatch
#

That seems... like it should work with nesting.

#

The main difference I can see is that you've removed your alignment properties.

quaint zealot
#
    SAssignNew(MyBlur, SBackgroundBlur)
    [
        SAssignNew(MyBorder, SBorder)
        .HAlign(HAlign_Fill)
        .VAlign(VAlign_Fill)
        [
            InArgs._Content.Widget
        ]
    ];```
hot notch
#

Oh. That works. πŸ˜„ Thank you. Forgot about that creation macro.

polar olive
#

hey guys idk if you can help me but im trying to make a loading screen for a multiplayer game. I need to do it for the non-seamless travel part when a client connects to a server. I've made a slate and added it to viewport, and when I do a client travel the slate does persist across levels, however it disappears for a few frames right as the client loads into the server then reappears.

hot notch
keen halo
#

I have a combo box, I have a function as well. I want the function to be called each time the selection is changed (using OnSelectionChanged). Let’s say I want to pass the option that is currently chosen in the combo box into the function that I’m calling….how in UE4’s name do I do that πŸ₯Ή

grave hatch
#

I'm not sure how that particular delegate works, but you could, in your first function, set up the call to a second function, passing the select element as a parameter.

#

How you get the selected element, however... Shrug

carmine wave
#

i did something like that with a checkbox. I needed to pass data to know what the checkbox was for. The oiginal callback just says if the checkbox changes, so i overloaded teh callback with a lambda that calls both, the "Normal" callback and my custom callback

#

examples in engine of how they use lambda and combo box to send extra data on change

keen halo
#

Thank you

deep tendon
#

So I understand I can save a slate variable by using AssignNew(). But how can I call that variable again with changes ive made to it?

#
//for example
SAssignNew(SavedVariableWidget, SWidgetType)

SavedVariabled->Slots->AddSlot(SNew(EditableTextBox))

//How can I post this new Saved variabled widget to the screen?
#

If I try to AssignNew() the same variable again, it just overwrites it and everything I modified it with disappears

craggy holly
#

SAssignNew creates a new widget and assigns that pointer property, so that makes sense.

deep tendon
#

The only way I know how to add widgets to a childslot is with SNew() and SAssignNew() but I dont want a new one

craggy holly
#

That's the correct way to do it, you can't have the same widget instance displaying multiple times

deep tendon
#

Well how can I dynamically edit a widget and then post it

#

if it has to be new everytime that means its impossible to add or use variables

craggy holly
#

You just modify the existing instance like you would any other variable/instance

deep tendon
#
FReply SMinefieldGridWidget::CreateMinefieldBaseGrid()
{

    if (OwningWidget != nullptr && OwningWidget->MinefieldHeight && OwningWidget->MinefieldWidth)
    {
        for (int i = 0; i <= OwningWidget->MinefieldHeight; i++)
        {
            for (int j = 0; j <= OwningWidget->MinefieldWidth; i++)
            {
                GridPanelContainer->AddSlot(i, j).AttachWidget(SNew(SButton).ContentPadding(3.f));
            }
        }
    }

    return FReply::Handled();
}
#

I tried this but this doesnt show up at all

craggy holly
#

Okay first of all, why are you making a game-level UI in slate - use UMG

deep tendon
#
void SMinefieldGridWidget::Construct(const FArguments& InArgs)
{
    OwningWidget = InArgs._OwningWidget;

    ChildSlot
        [
            SAssignNew(GridPanelContainer, SGridPanel)
            +SGridPanel::Slot(0,0)
            [
                SNew(SEditableTextBox)
            ]
        ];

    CreateMinefieldBaseGrid();
}
craggy holly
#

Slate is for editor/tooling stuff only - or for very rare cases when you can't do what you need with the existing UMG wrapper widgets

deep tendon
#

this isn't game level UI

#

its editor level UI

#

im making a plugin

#

specifically a tool

craggy holly
#

What you've done there should work just fine

deep tendon
#

thats what I thought.. hmmm

#

let me think some more

#

thnx for the validation

#

Ah obviously my OwningWidget is coming back as a nullptr facepalm

grave hatch
#

Why are you using AttachWidget instead of the [ ] notation?!

deep tendon
#

Because I need to do it dynamically

#

[] doesn't allow for that because its outside c++

grave hatch
#
  [
   ...
  ]```
deep tendon
#

But you would need to put a end line ; at the end of that

#

which you can't

grave hatch
#

No you don't.

deep tendon
#

why wouldnt you?

grave hatch
#

If it's inside another widget, you don't.

#

If it's standalone, sure.

deep tendon
#

its not inside another widget

grave hatch
#

But you're using ; anyway

deep tendon
#

you cant do dynamic allocation inside another widget

grave hatch
#
  [
    SNew(SButton).ContentPadding(3.f)
  ];``` It is identical to this
deep tendon
#

oh wut

grave hatch
#

GridPanelContainer->AddSlot(i, j).AttachWidget(SNew(SButton).ContentPadding(3.f));

#

Same!

deep tendon
#

really!?

#

it definitely looks a lot better

grave hatch
#

To be honest, I have no idea what attachwidget does internally, but it's not how you're meant to do it, I'm sure...

deep tendon
#

let me try that out

#

omg thats so much better lmao

#

okay ill use that then thanks

#

I thought the [] was only for inside ChildSlot[];

grave hatch
#

Nope!

deep tendon
#
//The only function this widget class server is passing in the StartupWidget reference
    ChildSlot
    [
        //I'm getting a nullptr for MinefieldStartupContainer
        SAssignNew(MinefieldStartupContainer, SMinefieldStartupWidget).SelfReference(MinefieldStartupContainer)
    ];

    //this says the class is incomplete and thus can't have a pointer
    MinefieldStartupContainer->SelfReference(MinefieldStartupContainer);

    ChildSlot
    [
            //This won't convert because its not a UObject
            SAssignNew(MinefieldStartupContainer, SMinefieldStartupWidget).SelfReference(this)
    ];
//--------------
    ChildSlot
    [
        SAssignNew(GridPanelContainer, SGridPanel)
    ];
    // this works fine
    GridPanelContainer->AddSlot(0,0)
#

I've tried everything. How can I get a reference to the owning widget???

#

It won't work for custom classes

#

I can't use this to pass it in

grave hatch
#

What are you trying to pass to MinefieldStartupContainer?

#

A reference to its parent widget?

deep tendon
#

I'm trying to pass itself

#

so it has a reference to itself

#

its going to pass that reference again to another widget it calls

grave hatch
#

Er

#

You can just use this to refer to yourself...

deep tendon
#

I tried that

#

it wont pass through

#

I need it on the widget its calling

grave hatch
#

So you want your MinefieldStartupContainer to have a reference to its parent?

deep tendon
#

Basically yes

grave hatch
#

Okay, and what are your slate parameters for SMinefieldStartupContainer?

deep tendon
#

SLATE_ARGUMENT(TSharedPtr<SMinefieldStartupWidget>, OwningWidget)

grave hatch
#

Try passing SharedThis(this)

deep tendon
#

SharedThis?

#

omg

#

Hold on while trying to explain my problem I messed something up

#

gotta fix it real quick before i test

grave hatch
#

Btw, try not to use TSharedPtr to refer to your parent, you'll end up with objectings keeping each other alive.

#

Use TWeakPtr in the child class

deep tendon
#
FReply SMinefieldGridWidget::CreateMinefieldBaseGrid()
{

    if (OwningWidget != nullptr && OwningWidget->MinefieldHeight && OwningWidget->MinefieldWidth)
    {
        for (int i = 0; i <= OwningWidget->MinefieldHeight; i++)
        {
            for (int j = 0; j <= OwningWidget->MinefieldWidth; i++)
            {
                //GridPanelContainer->AddSlot(i, j).AttachWidget(SNew(SButton).ContentPadding(3.f));
                GridPanelContainer->AddSlot(i, j)
                    [
                        SNew(SButton).ContentPadding(3.f)
                    ];
            }
        }
    }

    return FReply::Handled();
}
#

Yeah I was just about to say that this is causing unreal to crash

#

but it is working!

#

Its coming through

#

so let me try changing it to weak ptr

#

im not used to working with the heap so this whole smart pointer thing is a little confusing to me

#

even though I understand the concepts

deep tendon
#

I spent so long trying to get the reference to pass through lol

grave hatch
#

Instead of spending 3 hours on it. Spend 10m. Do some googling and then ask!

deep tendon
#

what would I google though? Information on slate is like non existant

#

I didn't know what the problem was I just knew that it wasnt converting properly

grave hatch
#

Try googling the error message!

deep tendon
#

oh true haha

grave hatch
#

Just take out your class name and put in SImage or SButton or something

deep tendon
#

yeah I shouldn't have assumed I wouldn't be able to find anything. Always good to try. Good point

#

my b

#

Also i'm really trying not to just ask until i've really tried everything I could think of. Tbh I learned a lot trying to solve this problem

hot notch
#

Can I get a Slot that an SWidget is in? I have a TSharedPtr, need to get the SOverlay slot that contains it.

deep tendon
#

I’m not exactly sure on exactly what you mean but to access an SWidget you need to save it as a variable then you can get its slot and replace it or do whatever else

grave hatch
#

Or do GetParentWidget()->GetChildren() etc

hot notch
#

FChildren's slot references are protected. I can't access that in a UserWidget.

hot notch
#

Hmm. Can call remove slot on the overlay with the widget pointer, and then add a new slot with the widget in it. Feels bad to do that just to set VAlign for the slot though. :/

deep tendon
#

You have to dynamically set VAlign?

#

Why not just set it once through the pointer?

hot notch
#

How do I set it through the pointer? That was my original question. I need the slot object that the widget is in to set that.

#

Basically I have a border inside of an overlay. Runtime code needs to dictate it's VAlign, whether it's on top or bottom of the widget. I can't get the overlay slot that the border is in to do this.

deep tendon
#

I know how to do this with grids because you can just get the grid at a specific slot using its column and row numbers

#

but i'm not sure with other widgets

#

I'm trying with vertical box but I don't see a Slot array

#
//if you do this it shows
ChildSlot
[
  SAssignNew(VerticalBoxContainer, SVerticalBox).Slots
];
//Doesn't show here
VerticalBoxContainer->(No Slots Array)
#

I'm not sure why this is

#

Verticalbox should function the same as overlay

#

in terms of getting the slot

deep tendon
#

which is what we said in our first answer

#

but yeah if you cant find the slots array youd have to overwrite it everytime

#

with a new slot

hot notch
#

Yeah, I figured that part out. Feels odd replacing the slot though. :/

#

Still faster than umg πŸ€·β€β™‚οΈ

deep tendon
#

true lol

#

i'm sure theirs probably a way to do it

#

im just new too

grave hatch
deep tendon
#

like this?

#

MinefieldVerticalBoxContainer->GetAllChildren()->GetChildAt(1);

grave hatch
#

Starts at 0, but yeah.

deep tendon
#

oh cool

hot notch
#

I'm still confused as to how to do this. I'm working in a UserWidget. GetChildAt is a protected function in FChildren.

grave hatch
#

Hmm.

#

I definitely did this..

deep tendon
#

The class structure is the same, UserWidgets should just be a wrapper

#

I dont see why it would be different

grave hatch
#

GetChildAt isn't protected in 4.27 at least.

hot notch
#

In FChildren in 4.27.2 it is.

deep tendon
#

no its not

#

I just tried it

grave hatch
#

in 5.0 it's public

deep tendon
#

just post the code your writing

grave hatch
#

In 5.0 GetSlotAt is public too

hot notch
#

Oh. Sorry I said wrong. GetSlotAt is protected.

grave hatch
#

It is.

hot notch
#

GetChildAt doesn't help, it just circles me back around to having a pointer to the child I had when I started. I still can't affect the slot with it.

grave hatch
#

You could access it with some pointer hackery 😦

deep tendon
#

where are you finding GetSlotAt? I can't find that function

hot notch
#

It's in FChildren. In the GetChildren call.

deep tendon
#

Oh it must not be showing bc its protected

#

GetChildAt() returns an SWidget. Your saying that SWidget isnt the slot itself ?

hot notch
#

No, that's the SWidget in the slot.

deep tendon
#

ohhh

#

right

grave hatch
#

What you can do, and tihs is total hackery, is create a class called FChildrenSubClass, inherit from FChildren, add a method that returns GetSlotAt() and then cast FChildren to that (even though it isn't an FChildrenSubClass) and then call your method.

hot notch
#

May look into that. You said that was public in 5.0 though?

grave hatch
#

Something like this: ```class FChildrenSub : public FChildren
{
public:
const FSlotBase& GetSlotAtPublic(int32 ChildIndex) const
{
return GetSlotAt(ChildIndex);
}
};

FSlotBase& MySlot = static_cast<FChildrenSub*>(Blah->GetChildren())->GetSlotAtPublic(Index);

deep tendon
#

I dont think that would work though, because the returned class is still a FChildren?

grave hatch
#

Doesn't matter.

#

You're casting it to a different class, even though it's an FChildren object.

deep tendon
#

woah

grave hatch
#

Virtual function pointers will do the rest for you.

deep tendon
#

my mind is being blown rn

grave hatch
#

It's super hacky, though. And probably bordering on undefined behaviour.

hot notch
#

Yeah. Started messing around with rewriting some major game widgets into actual slate this weekend. Been loving it. But the random private/protected walls are getting old, fast. Pretty on par with creating a new UWidget to slightly alter behavior and having to copy three entire classes just to do it.

deep tendon
#

Be careful about switching from UMG to slate for game UI. Jambax said that slate is really only for editor UI stuff or if you really need some of that extra functionality

craggy holly
#

UMG is basically just a wrapper for Slate, but it also makes it much more convenient to work with

#

It's totally feasible to use Slate for game UI but in most cases it's when you need to do something "special" or because some part of the UMG API is stupid

grave hatch
#

Slate isn't "just" for editor UI. Slate is great (ish.) You can use it for your game if you want. It's just easier to make UI in UMG mostly.

deep tendon
#

Okay yeah that makes sense

hot notch
#

Slate is also a lot faster in some cases even with same implementations. I've cut this one widget's tick and paint time down by half in most frames. I wouldn't bother with this under normal circumstances.

grave hatch
#

Oh absolutely. BP and UMG are atrocious for performance πŸ˜„

thick pasture
grave hatch
#

If you say so.

thick pasture
#

Here's a very good deep dive into it

#

the TLDR is people enjoy jumping on the "Blueprints is bad!" train and they're best used in conjunction

deep tendon
#
GridPanelContainer->AddSlot(i, j)
[                         
      SNew(SButton).ContentPadding(3.f).OnClicked_Lambda([] 
     (TSharedPtr<SGridPanel> GridPanelContainer, int i, int j)
     {
    GridPanelContainer->AddSlot(i, j)
        [
        SNew(SOverlay)
        ];
    return FReply::Handled();
    })
];
#

maybe more of a c++ question but why isn't it allowing me to input parameters into a lambda?

#

errors: 'Invoke': no matching overloaded function found

#

Failed to specialize function template

thick pasture
#

It doesn't look like you passed any inputs into the lambda's capture clause

deep tendon
#

oh I thought the () was the capture clause

#

this is my first lambda lol

#

let me do more research my b

grave hatch
#

No, that'd be the []

#

(...) are the parameters for the lambda.

grave hatch
thick pasture
grave hatch
#

I guess it goes by what you consider "atrocious."

thick pasture
#

of a very poor quality; extremely bad or unpleasant.

I consider it extremely bad, like the definition

deep tendon
#

I'm sure they've improved blueprints over the years but I remember seeing a test done about 5 years ago where blueprints where around 5x less efficient than c++

grave hatch
#

Again, it depends on what you define as "extremely bad."

deep tendon
#

I can't remember the exact results

thick pasture
deep tendon
#

ohh okay ill check that out then thnx

hot notch
# thick pasture I wouldn't say atrocious at all. Blueprints being "bad for performance" is over ...

While I agree with you about this matter in general, this only applies to projects that either don't have a heavy game thread, or have very simple UI. When slate takes up >5ms on your game thread, you have to start cutting all of the corners you can. I just finished rewriting one of our widgets at work into slate. Same identical widget, identical functionality. 230ish micro seconds to 90ish microseconds. Which isn't a ton. 0.14ms. But it adds up. I do that for a couple more of our more complex widgets and I can probably drop a good millisecond off of the game thread on average.

grave hatch
#

The guy cutting his ui processing time by half by converting some of it to c++ is a good example of "bad." Though I'm not sure if that's his BP coding or BPs themselves.

deep tendon
#

blueprint on tick can be so heavy.

#

thats were its the worst

grave hatch
#

And bindings are pretty expensive, too.

thick pasture
#

because we're talking about BP to C++, not UMG to Slate

thick pasture
grave hatch
#

It's an intrinsic problem of blueprints.

thick pasture
#

You could be doing the same binding call in C++ and it would be just as bad. The issue with bindings is they're called every tick

grave hatch
#

And that BP adds overheads to those bindings.

hot notch
#

UMG to Slate. Only blueprint stuff was initial setup that wasn't ran every frame. There was no tick in BP.

thick pasture
#

The bindings were a poor design choice from Unreal. You can do the same alternatives in blueprints as you can in C++ (ie. making it event based, not every tick)

deep tendon
#

I just think that logic should be done in C++ and any variable setting / visual things can be done in blueprint

grave hatch
#

I found it quite funny that just hiding the content browser gave me a 10-20% fps boost in the editor window. I don't wnat to imagine what they'd be like if it were implemented in BP.

#

Mugs: named slots are good for that.

deep tendon
thick pasture
#

Like don't get me wrong, I much prefer writing in C++ than Blueprints.

The issue is there's a huge negative stigma around using blueprints, and all you did was lay a blanket statement down that "blueprint performance is atrocious". If you explained that in some cases it is, but most of the time it's fine, I wouldn't of cared.

I know what you were trying to say, and I know you weren't meaning that Blueprints are just bad in general, but we're in a discord server where people read these channels to learn stuff

#

and they wouldn't know what you meant, which would give them the wrong idea

deep tendon
#

tbh i'm in the blueprints should be mostly avoided camp. So your definitely right about the sentiment lol. But ill definitely check that video out cade

grave hatch
#

Well, there are some cases were performance doesn't matter.

#

BPs are great for that!

#

Setting up input bindings and stuff is great, I imagine. Doing advanced matrix math and processing arrays, probably not.

thick pasture
#

Yeah and like I said, I know what you meant when you said that, but you didn't explain that

hot notch
deep tendon
#

Yeah input bindings / locomotion / animation montages / exposing variables for in editor testing so you dont have to recompile, Creating blueprint child classes where you can again change variables is such a time saver. UMG where you can visually layout button widgets

#

all those things i think blueprints are amazing for

#

also for very quick one time logic

#

everything else I think c++

deep tendon
hot notch
#

Above is the reason I generally don't create widgets in C++. BIE events in AHUD are much easier to both call from C++ and easier to change out widget usage or disable if plans change.

deep tendon
#

Yeah I think its when data from c++ has a hard time being accessed from blueprints or vice versa is where some of the real problems happen. Then you have to do stuff like checking for those variables on tick in blueprint to say, update your animation. Ugh.

thick pasture
#

This is usually how I layout my UI work,

View - UMG
ViewModel - Blueprint
Model - C++

Basically following the MVVM architecture that most software's use, which I think applies to UI in UE4 as well.

#

The Model contains and handles all of the heavy logic and data, and the ViewModel works with the View to display that information

deep tendon
#

I really like that system

#

I think ill try to do the same

craggy holly
#

UMG isn't bad enough for performance that you should punish yourself by writing a game UI in slate though

#

UMG is just slate with some UObject wrappers after all - if you use it purely for the WYSIWYG editor the actual performance is near enough the same. and your UI will almost certainly look better. If you do your UI logic in BP that's a different story - but that's also easily transferrable to C++.

#

Plus, once you start working with designers, Slate is just not an option

#

If it's any consolation, every game I've worked on in UE has been with UMG and there have been some extremely dense/heavy UI's - it was never the bottleneck

deep tendon
#

Super helpful to know, thank you

deep tendon
#
GridPanelContainer->AddSlot(CurrentGridSlotInfo->ColumnNumber, CurrentGridSlotInfo->RowNumber)
[
    SNew(STextBlock)
    .Text(FText::FromString("5"))
];
#

I'm not understanding why this wont show

#
GridPanelContainer->AddSlot(CurrentGridSlotInfo->ColumnNumber, CurrentGridSlotInfo->RowNumber)
[
    SNew(SImage)
];
#

but this will??

#

its just STextBlock that won't show in this slot

grave hatch
#

Try setting a font?

deep tendon
#

Ah, I have a grid. I'm spawning a button for every grid slot. Then I call the functions above. For some reason SImage spawns on top of the button, and STextBlock spawns below the button. Both remove hit testable for the button. Which is fine. I found this out by changing the opacity of the button. Is there a way to move SText to the top of the button?

grave hatch
#

Grid slots have a layer parameter too

#

Try setting the text to a higher layer?!

#

...I think

deep tendon
#

Yes, ty. I'm an idiot. I forgot about that parameter

#

Idk, I think it was some glitch because all i've done is add and remove .RenderOpacity and now its showing fine

grave hatch
#

Hot reload?

deep tendon
#

Ah maybe. I don't think I turned on Live Compile, however im pretty sure ive only been building from the editor.

grave hatch
#

The UE editor?

#

Never do that. Always close the editor.

#

(before rebuilding)

deep tendon
#

Oh I meant visual studio. Sorry my brother was talking to me

#

but its possible I compiled with the editor by accident

#

bc I didn't turn live compile on

deep tendon
#

Yeah nvm. I've only been building using the local windows debugger so that shouldn't be it

deep tendon
#

SNew() won't take SNumericEntryBox as an argument even with its header included. Is this because it inherits from SCompoundWidget? But why can't I used it the same as I can use my custom classes that are made from SCompoundWidget?

#

I'm assuming ill have to make my own SNumericEntryBox subclass

grave hatch
#

Show errors.

deep tendon
#

ok 1 sec

grave hatch
#

It's likely a circular dependency of some kind if you definitely have the header included

deep tendon
#
#include "SlateFwd.h"

+ SHorizontalBox::Slot()
.Padding(0)
.HAlign(HAlign_Left)
.AutoWidth()
.MaxWidth(TextInputWidth)
.Padding(HorizontalContentPadding)
[
SNew(SNumericEntryBox)
]

#

this is all i'm doing though

#

its all inside a ChildSlot

grave hatch
#

Error log, not errors window

deep tendon
#

Why does everyone say this, its always the same lol

#

1 sec

#
error C2672: 'MakeTDecl': no matching overloaded function found

error C3206: 'MakeTDecl': invalid template argument for 'WidgetType', missing template argument list on class template 'SNumericEntryBox'

 error C2955: 'SNumericEntryBox': use of class template requires template argument list
#

In the docs in syntax, the difference it has from other widgets is this line on top:

#

template<typename NumericType>

#

but im not sure what that means

#

Got it SNew(NumericEntryBox<int>) worked. Im just not used to working with templates outside of StaticClass and stuff like TArrays<>

jade hornet
#

How dare you summon me to this barren wasteland insolent fool

#

I know fuck all about slate itself other than masking border boxes with stencil :P don't think I can help here

#

srry

grave hatch
#

I'd take a stab at FGameplayTagContainerCustomization

grave hatch
#

I'm sure there was a widget that provided a collapseable content type thing, like the details panel

#

I can't for the life of me remember what it is, though...

#

SExpandableArea !

twilit halo
#

heya, how does one do tweening in Unreal Engine 4 C++? (Most importantly, using them with Slate)

grave hatch
#

Use Tick?

twilit halo
#

heya, is this the correct way to set up an event handler in slate?

twilit halo
#

sorry for the super late reply btw

grave hatch
#

No worries!

twilit halo
#

heya, for some reason FSlateApplication::Get().SetKeyboardFocus(SharedThis(this)); did not set my keyboard focus. I need to click on the loading screen widget to be able to press any key.

#

I already added bool SupportsKeyboardFocus() const override {return true;} in my header file