#slate

1 messages ยท Page 22 of 1

cyan iris
#

With a color

#

But SBox doesnt work somehow

quaint zealot
#

So create a solid color Slate brush and use it

#

Solid white texture + tint, or directly the color in texture

#

Using .Image() or .BorderImage() depending on the class

cyan iris
#

The Main-Goal is just creating a small interface for a login like this

#

just with less details

#

@quaint zealot I tried creating a brush, but i didnt work out

quaint zealot
#

How did you use it in code ?

cyan iris
#

unfortunatly stashed it, let me try to recreate it

quaint zealot
#

The usual way would be to use style assets, just like for fonts

cyan iris
#
SImage
.Image(FSlateBrush::TintColor(FColor::Green))
#

I tried something like that

quaint zealot
#

That's still not a brush

#

You need an actual brush asset in the content browser

#

And you need the styleset system to link the code to it

cyan iris
#

Is there no "simple" way to just create a box with a color?

#

without styling or creating additional assets?
Just a plain box?

quaint zealot
#

SBox is a plain box with no styling

#

You want styling, so you need assets now

cyan iris
#

Ye, but SBox also doesnt seem to work

quaint zealot
#

Look, you're going to need using assets

#

I warned you earlier that Slate styling is not something you set up in a day

#

If you want to quickly create something that looks good, use UMG

cyan iris
#

Ye, it's no problem. I will stick to Slate and try using assets, just wanted to know if it's possible to avoid creating multiple stuff for such a simple problem

#

I Can't understand why Unreal isn't capable of doing stuff like this...
But well, i only have a little bit of coding experience in comparison to the unreal devs that designed unreal

#

So i guess i trust them

#

I was just confused why there is no "drawLine()", "drawBox()", no XML / FXML or something else

quaint zealot
#

Unreal is perfectly capable of doing this simply, but you chose not to use the tools Epic uses for their games, and insisted on using the lower level system

#

Why is there no drawline, or drawbox ? Because you can't have performance that way

#

aka direct mode vs retain mode

#

Like most UI frameworks, UE4 is retain mode

#

So you create a hierarchy of widgets that you then script based on your needs

cyan iris
#

Thanks for the explanation
I'll research about direct and retain mode later this evening, then i can understand why and how. Thanks.
Well as i also mentioned,

i only have a little bit of coding experience in comparison to the unreal devs that designed unreal

quaint zealot
#

Just trying to provide answers here. Game UI is something complicated because it has to tie in with the game code, while being much faster than Web pages for example usually are

#

In my experience as someone who's built UI engines - UE4 is quite good at it

cyan iris
#

Just trying to provide answers here
Ye, thank you very much for that :)

#

Now that I've created a SlateBrush, what would a proper way be to import it?

#

Just empty, right?

quaint zealot
#

You need a valid image if you want to use it for SImage or SBorder

cyan iris
#

Well, isnt "none" with white tint just a white background-image?

quaint zealot
#

No, it is not

cyan iris
#

So i have to import a solid-color-image?

quaint zealot
#

As you just experienced yourself, "none" with tint is the default engine material with tint. Either import your own content, or use one of the engine's solid textures. Pretty sure they'll be a solid white somewhere in that

cyan iris
#

I create a TextureRenderTarget2D and made it white

quaint zealot
#

..... Alright.

#

Next you'll be facing the problem that spawned UMG in the first place : Slate objects are not UObjects, because Slate is originally meant for the editor, and it would be ridiculous to have the editor create hundreds of thousands of UObjects. As non-UObjects, they are unable to hold ownership of content for the purpose of garbage collection.
What does that mean ? It means you can't refer to content the way you would for an Actor or Component - UPROPERTY() texture mytexture, done, assigned in Blueprint to an asset, done.

#

Before UMG added an UObject analog for every Slate widget, Slate solved this issue with Slate style assets : an UObject that you create in C++ with a bunch of UPROPERTY() for all your content, assign in Blueprint with your nice brushes, and then use in Slate widgets.

#

Obviously the whole thing sucks and Epic never used Slate for gamedev AFAIK because was intolerable for UI artists, but technically it's sound enough

#

Notice the struct + UObject container

#

After all of that setup is done, you can "just" do

SNew(SImage).Image(&Theme.SomeBrushHere)```
cyan iris
#

So, just to clarify that i understood you correctly:

1. Create UStruct StyleCatalog, so i can access my Brush
2. Use UPROPERTY to assign my FSlateBrush
3. Create a Class where i can Access my "DefaultTheme"
4. Register Style in StyleRegistry
#

cute text btw:

#

๐Ÿ‘€

quaint zealot
#

Yeah that looks like it. All that code has a lot of unnecessary stuff and I went with per-class style assets rather than a big one on a newer project, but that I can't share

#

There is just a lot to set up here and it's likely going to take you a bit of time to get working

cyan iris
#

I guess that's alright if its not longer then 1-2 weeks

#

Thanks again, great help and also great ressource to work on and understand more

formal patrol
#

hey there,can anyone help me with the dock slate in the slight window,bascically i have a utility widget which i want to spawn on a button click

#

for engine version 4.25

wide plaza
#

is this a plugin that just wraps SObjectWidget for you?

formal patrol
#

s

flat panther
#

Hey! Before I dive into this and create from scratch. Do we have some hidden Date picker ready for usage in slate? Knows someone?

paper hamlet
#

ok so i'm lost on this error

2>          with
2>          [
2>              OtherType=const FSlateBrush *(FName,const ANSICHAR *)
2>          ]
2>          and
2>          [
2>              ObjectType=const FSlateBrush *
2>          ]
2>  U:\Program Files\Epic Games\UE_4.24\Engine\Source\Runtime\Core\Public\Misc/Attribute.h(43): note: There is no context in which this conversion is possible
2>  U:/UnrealProjects/LightbarPluginDev/Plugins/EmergencyVehicleLights/Source/EmergencyVehicleLightsEditor/Private/EditorWidgets/LightGroupPatternEditor.cpp(88): note: see reference to function template instantiation 'TAttribute<const FSlateBrush *>::TAttribute<const FSlateBrush*(FName,const ANSICHAR *)>(OtherType (__cdecl &))' being compiled
2>          with
2>          [
2>              OtherType=const FSlateBrush *(FName,const ANSICHAR *)
2>          ]
2>  U:/UnrealProjects/LightbarPluginDev/Plugins/EmergencyVehicleLights/Source/EmergencyVehicleLightsEditor/Private/EditorWidgets/LightGroupPatternEditor.cpp(87): note: see reference to function template instantiation 'TAttribute<const FSlateBrush *>::TAttribute<const FSlateBrush*(FName,const ANSICHAR *)>(OtherType (__cdecl &))' being compiled
2>          with
2>          [
2>              OtherType=const FSlateBrush *(FName,const ANSICHAR *)
2>          ]
2>U:\Program Files\Epic Games\UE_4.24\Engine\Source\Runtime\Core\Public\Misc/Attribute.h(46): error C2439: 'TAttribute<const FSlateBrush *>::Value': member could not be initialized
2>  U:\Program Files\Epic Games\UE_4.24\Engine\Source\Runtime\Core\Public\Misc/Attribute.h(333): note: see declaration of 'TAttribute<const FSlateBrush *>::Value'```
there are lines 87 and 88
```return SNew(SDockTab)
        .Icon(FEditorStyle::GetBrush)```
royal geode
#

Icon(this, &FMyClass::Function)

paper hamlet
#

tyty turns out that i didn't pass the params for GetBrush()

paper hamlet
#

i'm looking to make a custom asset editor for a light pattern asset. where the user can specify an array of lights and then modify curves to turn lights on and off over a period of time. the big square is wher i would like to be able to arrange the lights in any of the 4 cardinal directions (front, back, left, and right) and preview the pattern. I'm so lost an how to start said editor and i'm looking for any possible guidance on where to look or what i may need to put this together

split laurel
#

@paper hamlet look into the FAssetEditorToolkit class (or the inheriting class FWorkflowCentricApplication IIRC). Also take a look at any kind of editor class, like the one for Sounds. Not sure what the name is. SoundCueEditor perhaps, you'll find it.

Essentially you associate an asset class with your editor (look at what calls the init function of the editor you are referring to), so you do the same, then you create a UI layout and embed tab identifiers in that layout. You register tab creation callbacks that are associated with those tab identifiers so slate knows which tab to spawn where

#

if you want to arrange your lights you'll also need an interactable 3D viewport. For that you'll need the ViewportClient class and the SEditorViewport.

paper hamlet
#

it's not supposed to be 3d it's just a bunch of indepenant 2d views

split laurel
#

there are plenty surrounding classes you'll also need, but that's the central classes I'd look into

#

be that as it may, you'll still need some kind of visual preview so you'll need to figure out what widgets to use or to create

paper hamlet
#

ok thanks a bunch. so far it's been like 9000 steps for minimal payoff just to get the details panel so i'll just keep chugging i guess

split laurel
#

it becomes easier with time but it's always a struggle imo. Or I'm doing something wrong ๐Ÿ˜‚

cyan iris
#

@quaint zealot Hey, sorry if I'm bothering you.
I tried working out your styleSet this morning and i have a few questions if that's ok

#

2.
I really don't know how to access the UPROPERTY to assign my brush to be honest

UPROPERTY(EditAnywhere, Category = Main) FSlateBrush SlateColorBrush;

I thought when it's "EditAnywhere" i could assign my brush in the editor, but i can't seem to find an option. Maybe i missunderstood the principal of that.

quaint zealot
#
  1. No
  2. Create a new styleset asset in content browser inheriting from UFlareWidgetStyleCatalog
  3. Does it inherit ? Is the method static ?
  4. Yes, needs a module implementation, check StartupModule for the style register
cyan iris
#

is there a specific StyleSet-class i can choose to generate / fix the problems in 2. and 3. ?

quaint zealot
#

In my code, FFlareStyleCatalog is what stores UPROPERTY asset elements ; and UFlareWidgetStyleCatalog is the Blueprint container for it

#

Which is a USlateWidgetStyleContainerBase

cyan iris
quaint zealot
#

Maybe it's "Slate style" and not styleset

cyan iris
#

Ye i used SlateWidgetStyle to create the FMuesliSlateStyle

#

But thats the struct with the wrapper class

quaint zealot
#

Then compile, open thne editor and you should be able to create instances of the UClass

cyan iris
quaint zealot
#

Then you're good

cyan iris
#

Ye, but i can't drag and drop it to the viewport or to the level

#

And details also shows no Brush

quaint zealot
#

Create a new asset

cyan iris
#

Which one?

quaint zealot
cyan iris
#

Ye, i did this to create this one:

#

Code:

#
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Styling/SlateWidgetStyle.h"
#include "MuesliSlateWidgetStyle.generated.h"

/**
 * Default Style Class with SlateBrush
 */
USTRUCT()
struct FMuesliSlateStyle : public FSlateWidgetStyle
{
    GENERATED_USTRUCT_BODY()

        static const FName TypeName;
    virtual const FName GetTypeName() const override
    {
        return TypeName;
    };

    static const FMuesliSlateStyle& GetDefault()
    {
        static FMuesliSlateStyle Default;
        return Default;
    }

    // Add Brushes
    virtual void GetResources(TArray<const FSlateBrush*>& OutBrushes) const
    {
        OutBrushes.Add(&SlateColorBrush);
    }

    UPROPERTY(EditAnywhere, Category = Main) FSlateBrush SlateColorBrush;

};

/*
 * Wrapper Class
 */
UCLASS(hidecategories = Object, MinimalAPI)
class UMuesliSlateWidgetStyle : public USlateWidgetStyleContainerBase
{
    GENERATED_BODY()

public:

    virtual const struct FSlateWidgetStyle* const GetStyle() const override
    {
        return static_cast<const struct FSlateWidgetStyle*>(&m_style);
    }

protected:
    UPROPERTY(Category = Appearance, EditAnywhere, meta = (ShowOnlyInnerProperties))
        FMuesliSlateStyle m_style;


};
quaint zealot
#

You're confusing styles and stylesets.

#

Hell, just copy our files and change the names

quaint zealot
#

Yes

#

.. .alright, nevermind

cyan iris
#

Ye, but to create a styleSet do i have to generate a style again? o.O

quaint zealot
#

So once you've created a new asset inheriting from UMuesliSlateWidgetStyle in the content browser, just double click it and edit it

#

And you can then use the styleset to refer to it

cyan iris
#

created a new asset inheriting from UMuesliSlateWidgetStyle
thats the part where i am stuck i guess

#

I cannot find an option to create a new Asset inheriting it

quaint zealot
cyan iris
#

aaaah

#

now i understood

#

i thought the c++ class was the same option as the style

#

oooh

#

now i got it

quaint zealot
#

3 is a pure C++ issue, just read carefully what the compiler log says

cyan iris
#

Great, i try my best :)
Thanks a lot again

cyan iris
#

Got 3. working now too

#

great

#

@quaint zealot Where can i find or look for check StartupModule for the style register

#

Because the ModuleManagerClass is locked

quaint zealot
#

Keep copying my code. Declare module in project.h, implement in project.cpp

cyan iris
#

aaah so it's a new class, oh great

#

thanks a lot

#

In line 29 in Flare.cpp: c++ FSlateStyleRegistry::UnRegisterSlateStyle("FlareStyle");

#

How does that work if I'm allowed to ask?

#

Am i right @quaint zealot or did i understand something wrong?

quaint zealot
#

yup

cyan iris
#

You are unregistering it in startup, so it's faster to shutdown?

#

or is there any other reason?

#

or in case of a crash, it wouldnt be unregistered?

quaint zealot
#

It has to be unregistered first for hot reload in editor IIRC

cyan iris
#

I'm getting a LNK2019 error on MUESLI.cpp.obj even tho code seems to be fine

#

^ this is the MUESLI.cpp tho not cpp.obj

quaint zealot
#

What's the error

#

Did you declare the module in ehader

cyan iris
quaint zealot
#

Check Flare.h, something's missing

cyan iris
#

static void ReportError? o.O

#

i thought thats just an additional method that you added to track errors

#
  • you added logs
#

hmm

#

is CoreMinimal.h something different than EngineMinimal.h?

quaint zealot
#

Nevermind

#

Looks fine

#

So what's the linker error

cyan iris
#

gimme a sec, i swapped CoreMinimal with EngineMinimal and it's curretly building

#

It's taking way longer than before

#

it may be, that this was the mistake

#

nope

#

@quaint zealot that's the errors i got

#

Unfortunatly in german cryingweeb

#

Verweis = Reference

quaint zealot
#

Alright so for starters, use the Output window of VS, not the error list window

#

And then, the issue is that you declared but didn't implement the two methods listed

#

the styleset ones

cyan iris
#

Sry, only familiar with Jetbrains products

#

but thanks for the hint

#

okay, can't find symbol "FCHECK" in method Shutdown

quaint zealot
#

Ignore it

cyan iris
quaint zealot
#

I mean, remove it

#

or use check() instead

cyan iris
#

Okay, finally, how i can use all i did now in my SMainWidget.cpp ?

#

SNew(SBorder).BorderImage("I guess todo here")

#

Currently searching here

quaint zealot
#

Basically get the style asset (called "theme" in HR code) and profit

cyan iris
#

const FMuesliSlateStyle& Theme = FMuesliStyleSet::GetDefaultTheme();
SNew(SBorder)
.BorderImage(Theme)
quaint zealot
#

.BorderImage(&Theme.SomeSlateBrushHere)

#

SomeSlateBrushHere would be the UPROPERTY FSlateBrush

cyan iris
#

(HR means what btw? :o)

quaint zealot
#

HeliumRain

cyan iris
#

Aaah

#

sry

#

.BorderImage(&Theme.SlateColorBrush)

#

x)

#

Everything works but i have 2 logs

#

Thanks a lot for everything

#

You really helped me out and made my day :)

quaint zealot
#

Ands finally don't forget that brushes (only brushes) need to be addes to the void GetResources(TArray<const FSlateBrush*>& OutBrushes) const thing in style asset

cyan iris
#

You mean this:

#

?

quaint zealot
#

Yep, that's fine

cyan iris
#

it somehow doesnt recognize my brush asset tho

#
TSharedRef<FSlateStyleSet> StyleRef = FSlateGameResources::New(FName("/Style/MuesliStyle"), "/Game/Slate", "/Game/Slate");
#

I thought specifiying the location here is necessary

#

or am i wrong?

quaint zealot
#

First parameter is a name

#

MuesliStyle

#

This is for creating a style set

#

Style set != style asset

#

You have one style set, possibly as many style assets as desired

#

"themes" in HR are style assets

#

you use the singleton style set to fetch style assets from a path

cyan iris
#

and how can i fetch?

#

because i thought the default theme is my style asset

quaint zealot
#

Check what GetDefaultTheme does ๐Ÿ™‚

cyan iris
#
return FMuesliStyleSet::Get().GetWidgetStyle<FMuesliSlateStyle>("/Style/MuesliStyle");
quaint zealot
#

Something like GetStyle().GetWidgetStyle<T>("YourAssetNameInContentStyle");

#

See, that's correct

cyan iris
#

Ye, but somehow still not showing up what i want thinkingwithblobs

quaint zealot
#

FSlateGameResources::New is unrelated

#

TSharedRef<FSlateStyleSet> StyleRef = FSlateGameResources::New(FName("MuesliStyle"), "/Game/Slate", "/Game/Slate");

#

styleset

#

return FMuesliStyleSet::Get().GetWidgetStyle<FMuesliSlateStyle>("MuesliStyle");

#

style asset

#

You shouldn't name them the same

#

The style asset can be named however you like, you can have 50 of them with different classes

#

e.g. return FMuesliStyleSet::Get().GetWidgetStyle<FMuesliButtonStyle>("Button");

#

The asset part is the nice and flexible part where it's just "get me a style of type X from asset called Y in '/Game/Slate'"

cyan iris
#

okay, i changed the name of the MuesliStyle-Asset to MuesliStyleAsset and changed that in the method

#
return FMuesliStyleSet::Get().GetWidgetStyle<FMuesliSlateStyle>("/Style/MuesliStyleAsset");
quaint zealot
#

Drop the path

cyan iris
#

no need for that?

quaint zealot
#

No support

#

FSlateGameResources::New is where you define the root path of all style assets for this styleset

cyan iris
#

so instead of /Game/Slate i add /Style ?

#

or did i understood something wrong?

#
Create a new Slate resource set that is scoped to the ScopeToDirectory.

And in that case it's my folder

quaint zealot
#
return FMuesliStyleSet::Get().GetWidgetStyle<FMuesliSlateStyle>("MuesliStyleAsset");```
#

This is the only version that will work

#

Provided MuesliStyleAsset is under /Slate/ in your content folder

cyan iris
#

Don't i have to change the return type of the function to const FMuesliSlateStyle then?

quaint zealot
#

Sure

cyan iris
#

wait, don't i have to change all "Instances" then too?

quaint zealot
#

What ?

cyan iris
#

If i change the return type i shouldn't be able to call ```
Instance = Create();

quaint zealot
#

Look

#

You don't need to touch anything about the style set ever

#

It's just a nice helper class to fetch style assets

cyan iris
quaint zealot
#

Sigh

cyan iris
#

Ye i tried changing it according to your solution, but when i change the function return-type i cant use Instance=Create() anymore

quaint zealot
#

return FMuesliStyleSet::Get().GetWidgetStyle<FMuesliSlateStyle>("MuesliStyleAsset");is not for Create

#

It's for GetDefaultTheme in HeliumRain and whatever it's called now

cyan iris
#

ooooh

quaint zealot
#

it's what you use to fetch a style asset

#

GetButtonStyle, GetMenuStyle, etc

#

That's the onyl part of styleset that you change over time when you need new style asset classes

cyan iris
#

so i can always adjust MuesliStyleSet.h and add different getters for different-themes.

#

Did i understood that correctly?

quaint zealot
#

Yes

#

Or do a template and never touch it

cyan iris
#

so when i want to create a new style asset i have to create a new style class with a wrapper and create asset again

#

then when i want to reference this asset i need to add a getter in StyleSet

#

Am I right?

quaint zealot
#

Yes

cyan iris
#

I tried using game/Style

#

and this

#

and it stil doesnt change hmmm

quaint zealot
#

Drop styleref from DefaultTheme too...

#

Look, I feel like repeating myself here

cyan iris
#

Look, I feel like repeating myself here
ye i can understand that

quaint zealot
#
TSharedRef<FSlateStyleSet> StyleRef = FSlateGameResources::New(FName("MuesliStyle"), "/Game/Slate", "/Game/Slate");
// in getTheme() or whatever
return FMuesliStyleSet::Get().GetWidgetStyle<FMuesliSlateStyle>("MuesliStyleAsset");```
#

Just literally this

#
{
    TSharedRef<FSlateStyleSet> StyleRef = FSlateGameResources::New(FName("MuesliStyle"), "/Game/Slate", "/Game/Slate");
    FSlateStyleSet& Style = StyleRef.Get();
    
    return StyleRef;
}```
#
    {
        return xxx::Get().GetWidgetStyle<FMuesliSlateStyle>("MuesliStyleAsset");
    }```
cyan iris
#

ye, finally works now :)

#

Thanks

quaint zealot
#

And if you don't want to worry about adding variants of this, ```
template<typename T>
static const T& GetTheme(const FName& Name)
{
return GetStyle().GetWidgetStyle<T>(Name);
}

GetTheme<FMuesliSlateStyle>("MuesliStyleAsset");```

cyan iris
#

Thanks a lot ! :)

quaint zealot
#

I'll leave you to it now, think that was enough help ๐Ÿ˜›

cyan iris
#

I guess i can start working mostly on my own now, since i think that i understood most of this now :)

#

Ye i guess too :)

#

You really helped me out

#

I can't thank you enough

#

I wish there would be just more Slate-Tutorials or something like that cryingweeb

#

But ye, thanks a lot !

quaint zealot
#

The absurd amount of setup here to checks notes show a solid block of color is why UMG is the engine's game UI system and not Slate

#

At this point I'm probably the top Slate expert on this channel, short of Nick Darnell and other vets, and while I'm confortable with it, I also have a framework of tools to make it usable

cyan iris
#

The absurd amount of setup here to checks notes show a solid block of color is why UMG is the engine's game UI system and not Slate

good one, and thats how i kinda feel

#

I would have done the rectangle in 5 secs in UMG i guess

#

Rectangle Speedrun for Slate: 6 days of research and huge problems + nearly 0 tutorials

#

i dont know where i would end without you by now

#

(researched other frameworks for UI too [like html stuff and so])

#

i wish there would be something easier via code

quaint zealot
#

UMG, man

#

UMG is still code friendly

#

If you really want to keep even the layout etc in code like I do, then yeah, Slate

cyan iris
#

well i have to :(
but well, you really helped me out and i guess i learned a lot from you

#

I guess i have a better understanding now of how the styleSet should work and how i can manage the assets

quaint zealot
#

๐Ÿ‘

cyan iris
cyan iris
#

Small question: can / should you resize the ColorBrush in code?
Or is there an other approach that would suit my case better?

#

Should i use different brushes?
Or resize my mainbrush?

#

oh, and of course use .ColorAndOpacity(FColor::DesiredColor)

quaint zealot
#

Use SBox with width/height override to resize a brush

cyan iris
#

I'll try, thanks :)

cyan iris
#

hmm, another question to understand what design choice would be better

#

I actually wanted to overlay the red box over the blue one

#

upps

#

i mean horizontal-box btw

#

Currently i've worked with SOverlay

#

Is it better to stay with H and V-Boxes as a design choice?

pastel phoenix
#

try SOverlay, and V-Box inside it

cyan iris
#

Is it possible to get the width and height from the parent ?
For example:

SNew(SBox)
.WidthOverride(0.9 * ScreenWidth)
.HeightOverride(0.9 * creenHeight)
  [
    SNew(SBox)
    .WidthOverride(0.9 * ParentSize)
    .HeightOverride(0.9 * ParentSize)
  ]```
quaint zealot
#

It is, but it's not exactly simple

cyan iris
#

What would you suggest instead?

quaint zealot
#

You'd need to make both of these callbacks, get the parent's cached geometry, and return the values

#

My suggestion would be to use .Padding() with a margin in pixels

#

What I do - not that you have to do the same - is a design for 1080p only, with a custom scaling rule so that all other resolutions are proportional to that

cyan iris
#

ye, i set one in theme too

#

My suggestion would be to use .Padding() with a margin in pixels
I'm not sure if i understand you

#

Because i thought that Padding โ‰  Margin

#

oh wait, i can specify a margin inside the padding? o.O

#

maybe i understood something wrong lulz

quaint zealot
#

Yeah, itr's confusing.

#

Slate objects have paddings, not margins

#

Because each object controls only its own size

#

But the .padding() parameters wants an FMargin structure

#

That will only ever be used for paddings

cyan iris
#

seems weird to me, but i guess it's just another thing people will understand more than i do ๐Ÿ‘€

#

but thanks for the clarification

#

Why not name it .margin() instead of padding tho?

#

I mean it can be used for padding too, but in my case it's more of a margin than a padding

quaint zealot
#

.Padding is always inside the current widget

#

An SBox with 200 width and Padding(10) will be 200px, and the inside widget will be 180

cyan iris
#

I found Input Widgets in the Documentation

#

But i can't use them

#

am i missing a header or something?

#

I would like to use a TextBox where a user can input his username

#

<SEditableText> Seems to be fitting my case, but i can't use it in code

quaint zealot
#

Works fine here.

cyan iris
#

I'm only getting SEditableComboBox

quaint zealot
#

Whats the compile error for SEditableText ?

cyan iris
#

Can't resolve

quaint zealot
#

That's not the compiler, is it ?

#

That's just Intellisense, which is always wrong, and is pointless

#

Though you might also have forgotten the include here

cyan iris
#

" D:\Programming Projects\MUESLI\Source\MUESLI\Private\SMyWidget.cpp(99) : error C2653: "SEditableText": Keine Klasse oder Namespace
"

#

No class or namespace

quaint zealot
#

Sounds like missing include then

cyan iris
#

I tried adding SlateEditableTextWidget because that was the only suggested include when i tipped in "Edit"

quaint zealot
#

See, no include.

cyan iris
#

oooh

#

there it is

#

i thought all "input" widgets have the same include

#

just a collection of input widgets

#

great, thanks :)

cyan iris
#

For SEditableTextBox i need a FText and assign it in SAssignNew(FText, SEditableTextBox)
Then i can read the data later from my FText, am i correct?

quaint zealot
#

No that's not what SAssignNew does

cyan iris
#

wait, it's the other way around, isn't it?
I can assign my Widget to a variable

#
SAssignNew(WidgetPtr, Widget)
quaint zealot
#
SAssignNew(MyWidget, SButton);```
cyan iris
#

Oh and i have a more general question, if i want to modify my MuesliGameModeBase to use a MouseCursor, is there actually a way to do this?
My problem is, that many tutorials use a Blueprint for that

#

Should i post it in an other text-channel?

quaint zealot
#

Mouse cursor is a project settings option

#

Except for the showing it part

cyan iris
#

^ ye i mean that one

#

bc i thought it belongs to a PlayerControllerClass

quaint zealot
#

Yeah it does

cyan iris
#

That controlls if it's shown or not

#

Is it possible to add this to the ProjectGameModeBase.cpp

#

Because, i cannot edit settings (greyed out)

#

I would know how to do it with BluePrints

quaint zealot
#

It's a PlayerController setting, so create a C++ or Blueprint for that new PC class and then set the PC class to that in your GameMode Blueprint or C++

cyan iris
#

1>MousePlayerController.gen.cpp.obj : error LNK2019: Verweis auf nicht aufgel๏ฟฝstes externes Symbol ""public: __cdecl AMousePlayerController::AMousePlayerController(class FObjectInitializer const &)" (??0AMousePlayerController@@QEAA@AEBVFObjectInitializer@@@Z)" in Funktion ""void __cdecl InternalConstructor<class AMousePlayerController>(class FObjectInitializer const &)" (??$InternalConstructor@VAMousePlayerController@@@@YAXAEBVFObjectInitializer@@@Z)".

#

I'm not really sure how to interpret this error

#
AMousePlayerController::AMousePlayerController(const class FObjectInitializer& PCIP)
    : Super(PCIP){}

do i have to add this constructor that you used sometimes @quaint zealot ?
because when i do, i get no compile errors anymore

quaint zealot
#

GENERATED_BODY

#

And this isn't a Slate question

cyan iris
#

sure, i make sure to post it in #cpp next time

cyan iris
#

Okay, so i've managed to set a hint-text and everything
Now my problem is, that i can't find an option to change the TextColor of the normal Text

#

(Also my boxes are changing sizes, but it's not a bug, it's a feature pepejamsad )

#

oh, nevermind

#

found the option :)

ancient hazel
#

anyone know how to create an STreeView that starts recursively expanded by default?

main mesa
#

Anyone know if you can using materials during loading screen?

spring island
#

i have tried for several days trying to set a font to my text rendered in slate. im trying something like this: ``` SNew(STextBlock)
.Font(InArgs.TextFont)

#

where TextFont is FSlateFontInfo* TextFont; and assigned trough FArguments& SetTextFont(const decltype(TextFont) InArg) { TextFont->FontObject = InArg->FontObject; return this->Me(); } I get InArg from a constructorhelper that finds a UFont, am i going at this the completely wrong way? i cant find any documentation on how to set a font

quaint zealot
#

You're not really supposed to

#

Use UMG if you want styling

#

You can read the past few weeks of discussion here where I explained how to set up Slate styles

spring island
#

how come theres a .Font if youre not supposed to style it? wierd

quaint zealot
#

You are supposed to use it

#

But you have to understand how that font is going to be loaded & kept in memory

#

So you need an UObject, but Slate widgets cannot keep ownership of UObjects

#

So you need a Slate style and well, that's just not easy to set up, feel free to copy the Helium Rain source code like I usually suggest doing

#

OR use UMG which was actually designed to have styling

spring island
#

yeah ofc, but i want to learn how to do UI in code =P

quaint zealot
#

Then I hope you are ready to rewrite every single basic widget

spring island
#

i absolutely am! but i cant find how to set the damn font XD

quaint zealot
#

I literally explained

#

You need a Slate styleset, which will alow you to load Slate Style Assets (assets in the content browser), basically blueprints where you'll add your font as a UPROPERTY

#

Register the styleset in the module, make it a singleton, use it on your widgets to fetch style assets, and then it's just .Font(&Asset.MyFont)

#

Enjoy

spring island
#

oh, i tought the Slate styleset was the blueprint thing UserInterface - Font

quaint zealot
#

I had to explain this entire thing right here days ago so I suggest you re-read the entire discussion with distrustLP

spring island
#

allright

spring island
#

i think it got renamed to "SlateWidgetStyleAsset" or its not available to pick from-editor?

ancient hazel
#

Is there a recommended way to save state with slate widgets? Specifically for editor widgets, not in-game

paper hamlet
#

does anyone have experience with making tables in slate

#

looking to put one in my assets detail panel

paper hamlet
#

IDetailCategory.AddWidget() doesn't exist anymore

paper hamlet
#

if i just want to use the default property editors and change the layout am i still not allowed to use SPropertyEditorNumeric? I'm getting an error in that file when i try to include it

cyan iris
#

I just wanted to say thanks @quaint zealot. Thanks to you i guess i understood how to work with Slate and what the workflow is :)

quaint zealot
#

You're welcome !

cyan iris
#

So that's my progress currently:

#

I'm still having problems making the Checkbox size larger, tried it with padding, but somehow doesnt work yet

#

What is the best way to scale a checkbox up by 1-2 sizes?

quaint zealot
#

Probably the checkbox class takes a style struct that you can put in your style asset.

#

Usually the size of Slate widgets is determined by the brushes used

cyan iris
#

Thanks, i will try changing that :)

paper hamlet
#

ok so i have a combobox that won't display it's options

        .OptionsSource(&LightColorOptions)
        .OnGenerateWidget(this, &FLightPatternTrackCustomization::OnGenerateLightColorWidget)
        .OnSelectionChanged(this, &FLightPatternTrackCustomization::OnLightColorOptionSelected)
        [
            SNew(STextBlock)
            .Text(LightColorEnum->GetDisplayNameTextByIndex(CurrentOption))
        ];```
LightColorPtr is `TSharedPtr<ELightColors>` and `FLightPatternTrackCustomization::OnGenerateLightColorWidget` is ```TSharedRef<SWidget> FLightPatternTrackCustomization::OnGenerateLightColorWidget(LightColorPtr OptionIndex) {
    return SNew(STextBlock)
        .Text(LightColorEnum->GetDisplayNameTextByValue(static_cast<uint8>(*OptionIndex.Get())));
}```
I have a breakpoint right after the first chuck that confirms that it is getting all 6 options however the breakpoint for OnGenerateLightColorWidget never triggers. Anyone have any ideas?
#

changing to cast to int64 instead doesn't change anything and neither does just setting the text to a static value.

#

combobox with enums is a nightmare i legit copy what they did for the engine and it either crashes or doesn't display the values

main hedge
#

did anyone else notice how slate sucks at drawing outlines for some specific characters?

#

like the s here (everything else works fine......?)

#

I'm wondering if there are any known solutions

pastel phoenix
#

probably it is font problem. try another

paper hamlet
#

if i have a TSharedPtr<IPropertyHandle> that is for a UCurveFloat* property how do i unwrap it to get the asset

cyan iris
#

@quaint zealot i managed to add a style for the checkbox, but it doesnt show my Checkmark

#

it overrides the old style

#

Means, that the "โœ”๏ธ" is gone <- that icon is nearly invisible in dark-mode x)

#

do i really have to import a new image?

cyan iris
#

well, i've did the image-variant

paper hamlet
#

any ideas for how to synch slate widget animations

#

right now i have an issue where scrolling them other the screen causes the animations to start at different times and desynch

#

however current time is a double

green maple
#

Is there a way to trigger a slate UI element update using separate timers for each UI element? My idea was too use events sine slate only supports one timer for all elements to be triggered.

#

elements may update every frame while others only need to every minute or when a touch input is detected.

echo venture
#

Sounds like SRetainerWidget

green maple
#

hmm interesting. definitely can make use of it, but i also need more control on a per element basis. I don't want to have to have a separate render target for each element. maybe im misinterpreting what the docs are saying

elfin gazelle
#

Has anyone worked with selection logic of Instanced Static Meshes in a custom AssetEditor ViewPort/ViewPortClient? I'm patterning my custom one off SCSSEditor/StaticMeshEditor - I can confirm I have HitProxies for each instance, (mouse over effects in the viewport), and I get a HInstancedStaticMeshInstance HitProxy back in FMyAssetEditorViewportClient::ProcessClick.
I'm calling SelectInstance/MarkRenderStateDirty on the ISM component that's been clicked (which seems to be what's happening in the SCSSEditorClient).
However at that point the trail runs cold, as selecting an instance doesn't appear to cause a selection outline. I'm not sure what steps I might be missing (flag to set? something to invalidate?) between selecting the instance in process click and making sure the outline is actually rendered. I see the outline rendering should take place in PostProcesSelectionOutline.cpp but I'm having trouble back tracking to how the buffer it's using is actually getting populated.
I also haven't been able to find a lot of documentation/tutorials on this, so if anyone has handy topical links those would also be appreciated.

split laurel
#

I had a viewport recently that more or less worked out of the box, including outlines and actor tools iirc.
Nothing special to do other than some flag maybe. Can't look into it right now sadly but it should be relatively simple unless it being instances interferes in some way

elfin gazelle
#

That's good to know - I'm wondering if I'm making things more complicating things by working with ISM (in my use case I could just as easily use StaticMeshes within the AssetEditor itself) and perhaps my choice of base class. My ViewPortClient is extending 'FEditorViewportClient' - if you do get a chance to look later, did you by chance extend one of the other existing ViewportClient for more out of the box functionality? It seems like I'd need to overload quite a few things to get basics working. Thanks again!

glass nimbus
#

hi, i'm wiring up some slate controls from c++.

basic question: How do i get a reference to the widget that is the target of the event? i.e. in an OnValueChanged or OnValueCommitted callback, I only seem to have the new value but no way to source where it came from? i want to lookup a metadata tag on the target to know context for the new value.

#

is my only option to use a different InUserObject when registering the callback?

frosty prawn
#

is it possible to add a button to toolbar, and use slate with Python?

low bluff
#

What's the easiest way to get my hands on an AssetPicker Widget for some custom editor toolbar menu?
There is way too many similar sounding class names.

#

Preferably one where I can limit it to a specific class and children

low bluff
#

SObjectPropertyEntryBox is the answer, in case someone finds this question.

cyan iris
#

Hey, I'm trying to implement a Linear Gradient in Unreal with Slate.
Currently i used FLinearColor, and tried implementing it with .ColorAndOpacity on an SImage.
The result is no Linear gradient tho think

#

Maybe i did something wrong?

#

it looks like it only matches the middle color

craggy holly
#

You'll need to use a pre-authored texture or a material to do something like that.

#

A simple gradient could be done with a very basic material, and would fit any element size.

quaint zealot
#

Yeah, material would work fine here.

frosty prawn
#

hey guys, is there some tutorial on creating a very basic and minimal window using Python?

cyan iris
#

Thanks for the help @craggy holly @quaint zealot :)

viscid shoal
#

does anyone here have experience with the FFrameGrabber class ?

keen crane
#

So I've not got much experience with slate and I'm having an issue adding a submenu to an existing menu extension. What's the correct way to add to an existing extension rather than creating a new one?

https://i.imgur.com/D4PsnBv.png

#

I know this code specifically adds a new extension but I was hoping there was some background function that would auto merge menus with the same name instead of giving me a duplicate as show above :/

silk vault
#

Not sure, but have you tried extending the Extension Hook name for JKelly Utilities rather than "WindowGlobalTabSpawners"?

keen crane
#

@silk vault yeah I did try that and it just vanished all together :/

#

I also worry that it wouldn't work unless the other plugin that first registered the new menu wasn't installed

silk vault
#

It's likely you'll need to get a reference to the other extender.

keen crane
#

I guessed as much but I've no idea how to do it, C++ is hard enough to learn but slate seems like a whole other beast too

silk vault
#

Also might be plugin order in loading. I believe there is a parameter in uprojects where you can specify required dependencies.

#

Uplugins*

keen crane
#

Hmm didn't think to add the previous module as a dependency, but that again introduces the issue of needing the other plugin. Would having a module for adding that menu in each seperate plugin be a bad idea? Surely if I include that module in each plugin and have a check for if it's already loaded I could get around the issue?

#

Damn, the "New C++ Module tool" plugin is only available in 4.25 ๐Ÿ˜ฆ

fading musk
#

Hello people!

I have kind of a general question: in which case would one create the entire UI in c++ instead of using UMG UI Designer?
As far as I understand, it is alot easier to make tweaks or changes when you work via blueprints - thus the workflow is faster, but I just finished a book "Unreal Engine 4.x Scripting with C++ Cookbook - Second Edition", which fully focused on describing everything in c++ and I didn't fully understand the benefits of that. One benefit I could see is that you have more control, but do you actually need that?

Any experience with that?

With regards ๐Ÿ™‚

quaint zealot
#

UMG is very much an easier time, C++ or not

#

You can use C++ in UMG

#

UMG widgets also are able to hold UObjects, for example... dynamic material instances

#

Slate widgets cannot, and integrating content in Slate requires some tinkering

pastel phoenix
#

it depends of your team. if they are mostly designers, better to make ui in umg. slate is better for programmers

quaint zealot
#

How is not being able to create and store a material instance better for programmers, though ?

#

You can use full C++ with UMG

#

UMG is very much the way forward for UE4 game UI

#

And I say that with 6 years of experience in Slate

fading musk
#

Thanks for your thoughts. I was thinking the same.

bleak tapir
#

Is there a way to edit an object with slate without having to create every property widget by hand?

main hedge
#

you can create a details view

tame granite
#

@quaint zealot slate widgets can hold uobjects through FGCObject AddReferencedObjects

#

shooter game example:


struct FShooterGameLoadingScreenBrush : public FSlateDynamicImageBrush, public FGCObject
{
    FShooterGameLoadingScreenBrush( const FName InTextureName, const FVector2D& InImageSize )
        : FSlateDynamicImageBrush( InTextureName, InImageSize )
    {
        SetResourceObject(LoadObject<UObject>( nullptr, *InTextureName.ToString() ));
    }

    virtual void AddReferencedObjects(FReferenceCollector& Collector)
    {
        FSlateBrush::AddReferencedObjects(Collector);
    }
};```
quaint zealot
#

@tame granite And then you need to manually remove them when the widget is gone

#

The very reason UMG exists is to solve this problem

tame granite
#

@quaint zealot it should go away when an FGCObject is destroyed

#

on next collection cycle

quaint zealot
#

Look, this just isn't serious at all compared to just using your material the same way you do in regular UE4 code using UPROPERTY

tame granite
#

yeah I'm just showing how it can be done not saying UMG is an invalid tool

quaint zealot
#

Of course it can be done, i'm also using Slater and I have another approach for garbage collection that works too

#

The point is, Slate is very much not built for game content at all

tame granite
#

I use mostly UMG, slate mainly just to interoperate with some stuff from shootergame and even there embed umg into slate where possible

deft wren
pastel phoenix
#

make a box inside button, and text inside box

#

box have option for autosize

deft wren
#

@pastel phoenix Oh okay thank you ๐Ÿ™‚

royal geode
#

That's not the issue here - text should auto size the button

#

It looks like w/e layout you are using is forcing the button to be scaled down

tribal fractal
#

Anyone know if there is a helper function to create property widget? I would like to add GameplayTagContainer to my custom table view

tribal fractal
#

trying to do it like this but have linker issues about SGameplayTagWidget even when GameplayTagsEditor is added do build.cs

glass lynx
#

when i hover to texbox my mouse cursor changed, but i want to keep my cursor always in default mode even if i click in textbox

deft wren
#

@royal geode Sorry for very late ping, didn't notice someone answered. This is a minimal portion of the code, where the button doesn't scale with text (I've commented out the horizontal box inside the button, which didn't seem to help).

SAssignNew(ToolkitWidget, SBorder)
    .HAlign(HAlign_Center)
    .IsEnabled_Static(FSecmaVREdModeToolkit::IsWidgetEnabled)
    [
        SNew(SVerticalBox) + 
        SVerticalBox::Slot()
        .AutoHeight()
        .HAlign(HAlign_Fill)
        .VAlign(VAlign_Fill)
        [
            SNew(SHorizontalBox) + 
            SHorizontalBox::Slot()
            [
                SNew(SButton)
                .OnClicked_Static(FSecmaVREdModeToolkit::OnReplace)
                .ButtonColorAndOpacity(FColor(255, 100, 100))
                .IsEnabled_Static(FSecmaVREdModeToolkit::IsSelectionReplaceable)
                [
                        // SNew(SHorizontalBox) 
                        // +SHorizontalBox::Slot() .HAlign(HAlign_Left)
                        // [
                        SNew(STextBlock)
                        .Text(LOCTEXT("ReplaceButtonLabel", "Replace"))
                        //.MinDesiredWidth(100.)
                        // ]
                ]```
#

I've tried all manners of things, the only thing that actually forces the button to grow horizontally is if I "hardcode" it with MinDesiredWidth

craggy holly
#

It's sometimes better to design this stuff in UMG so that you can see what you're doing easier. I'd first suggest that the border should be V/H aligned to 'Fill' not center, and you may need to set horizontal and vertical box slots to use AutoHeight and AutoWidth

deft wren
#

@craggy holly Oh yeah, setting the border to fill extended it horizontally, I missed that, thank you :)

For designing in UMG, I tried something like that, but quickly discarded the idea after I couldn't find the same building blocks as are in Slate (I couldn't find Hor/Ver boxes for example) ๐Ÿ˜•

craggy holly
#

horizontal and vertical boxes are definitely in UMG

#

wouldn't be able to do much without those...

deft wren
#

Oh yeah... Sorry don't have much experience with UI

#

One thing that confuses me is that in UMG you define alignment on the box, whereas in Slate it seems to be per slot

#

Alignment on slots seem to apply to the content of the slot

#

Oh I suppose that means I need to sort the alignment on the parent of the box instead

craggy holly
#

UMG works the same way, it's just that the slots are shown as properties of the child widget

#

And not as separate elements

#

E.g if you add a widget to a canvas panel, the canvas panel slot properties are shown in the child widgets' details panel, not the canvas details panel.

gritty frigate
#

Does anyone know what the best Destructor-equivalent virtual method should be used on SWidgets? I have some clean-up to do when a widget is destroyed. For now, I've created my own, as I know where the widget is being destroyed from, but I'd prefer to be able to have an equivalent to Construct()

#

Also @craggy holly and I have just been having a conversation in #cpp about garbage collection of UObjects in an SWidget. I didn't think it was overly Slate-related, but he suggested that it might be. If anyone has any thoughts, the conversation is from #cpp message for a few messages

ancient hazel
#

@gritty frigate I couldn't see anything obvious, did you try implementing the destructor?

gritty frigate
#

Yeah, it didnโ€™t like that!

#

I donโ€™t actually need that any more, now that my slate class also subclasses FGCObject

frigid dagger
#

Anyone know how to inherit farguments or if it is practical?

mild oracle
#

Is there an expected way to change the state of something like a CheckBox widget and make it so the delegate is Not fired?
e.g. On setting up a widget, I want to set it checked, but I don't want it to broadcast the on-checked delegate

#

I could unbind, set the state, and re-bind but that sucks

#

I could set a "ignore next broadcast" flag and unset it once the broadcast happens, but that sucks too

gritty frigate
#

When making my own widgets I tend to have a bNotify on the Set method (defaulting to true), and skip the notification of this is false

#

I donโ€™t have a good solution for this for built-in widgets though.

mild oracle
#

@gritty frigate Yeah I've done that for my own widgets, I just wondered if I was missing some expected way of doing with the built-in widgets

gritty frigate
#

On a current project Iโ€™ve been wrapping most of the widgets that I want to use to ensure that the default style is set. I can also add a wrapper around the notification which helps

mild oracle
#

Heh I've been doing the same, but creating centralized style assets

gritty frigate
#

How do you mean?

mild oracle
#

@gritty frigate I DMed you the details

mild oracle
#

Has anyone dealt with text dropshadow not snapping correctly at different resolutions? I set dropshadow distance to 1.0, but as I change my window size it jitters between 1.0 and 2.0 distance, seemingly because it's trying to snap to pixel incorrectly

main hedge
#

outline and shadow positioning is a bit scuffed

mild oracle
#

@main hedge Hmm yeah might be related?
I'm not sure how dropshadow offset is calculcated but it seems to be doing snaptopixel inconsistently

#

It seems like the text is being snapped up to nearest, and shadow is snapped down.

main hedge
#

where did you find this?

mild oracle
#

I'm just guessing that's what's happening

#

my favourite kind of debugging: baseless speculation

glass nimbus
#

hello fellow slate users anonymous. i'm ready to admit i have a problem. my OnClicked (nor OnPressed) never seem to fire, despite incessant clicking and despite the contents visibly dipping down and up. perhaps it is time to quit this terrible habit, unless someone sees a better path enlightenment and fulfilment.

SNew(SButton) .IsFocusable(false) .ToolTipText(FText::FromString("Reset")) .ButtonStyle(FEditorStyle::Get(), "NoBorder") .IsEnabled(true) .ContentPadding(4) .DesiredSizeScale(1) .OnClicked_Lambda( /* never called. why oh why? */ [=]() { OnResetValueClicked(context); return FReply::Handled(); }) .Content() [ SNew(SImage) .Image(FEditorStyle::GetBrush("PropertyWindow.DiffersFromDefault")) ]

main hedge
#

did you use the widget reflector to investigate?

gritty frigate
#

I'm sure I've seen something about this somewhere, but can't remember how/where.
Does anyone know how I can get a call on a widget for something like OnClickedOutside? I want to know when the user has clicked anywhere else (to be able to close a menu)

#

I think I found something in SlateApplication.h, FPopupSupport::RegisterClickNotification

#

FDelegateHandle RegisterClickNotification(const TSharedRef<SWidget>& NotifyWhenClickedOutsideMe, const FOnClickedOutside& InNotification);

glass nimbus
#

did you use the widget reflector to investigate?
@main hedge yes. seems like reasonable values?

#

is there anything here amiss that would prevent OnClicked from firing? it is the hightlighted row's SButton.

main hedge
#

does clicking the button actually work? like does its style change as expected

#

if not something else that is visible might be in front of it, eating the click

glass nimbus
#

i see the nested SImage visually dip down and back up a couple pixels

main hedge
glass nimbus
#

maybe a basic question: is slate's event model based on bubbling up, or propagating down? is it possible a parent is consuming the event?

#

or do events fire first to the leaf node?

main hedge
#

well on clicked is a delegate on the button not a slate event so there is neither of this

#

for events like mouse down it will start at the innermost visible widget and then go up the chain of parents until something handles it

glass nimbus
#

new test result: interestingly OnClicked_Static() is working, but my OnClicked_Lambda() continues fail silently.

main hedge
#

maybe is broken

#

why do you even need a lambda?

#

it's a delegate, so you can pass through extra params through the normal one

glass nimbus
#

i need to capture local values from a for loop block. how do i pass extra args to registering a normal click event?

#

nevermind. visual studio was incorrectly reporting that breakpoints were registered (solid red), when in fact they weren't. i was able to set a bp on a deep function in the call chain and it's hitting. i guess visual studio debugger isn't that smart sometimes with lambdas.

main hedge
pastel phoenix
#

just try switch configuration from Developing Editor to Debug Editor, breakpoints will be more precision

#

and don't pass data to lambdas by values [=], pass it by references [&]

main hedge
#

that's quite dangerous when you add the lambda to a delegate

gritty frigate
#

That screwed me over recently - I passed a delegate to a lambda by reference and, then got confused why it called the wrong lambda!

tame granite
#

capture weak ptrs by value and pin/check their validity

warm vault
#

I'm trying to customize a property value for an internal struct, but if I do that, I lose the small Insert/Delete dropdown menu when it's part of an array

#

does anyone know a good way to add them to custom widgets?

#

I'm currently trying to construct them from the regular value widget with this:
TSharedPtr<SWidget> ValueWidget = InPropertyHandle->CreatePropertyValueWidget();

#

but then I can't figure out how to extract it from there...

warm vault
#

ok, I managed to do it:
FChildren* children = ValueWidget->GetChildren();
TSharedPtr<SWidget> horizontalBox = children->GetChildAt(0);
TSharedPtr<SHorizontalBox> hb = StaticCastSharedPtr<SHorizontalBox>(horizontalBox);

deft wren
#

What's the best practice when it comes to modifying slate widgets defined used the declarative syntax? Can I name my widgets during initialization to access them, or do I have to create them outside and save the element somewhere?

SNew(SHorizontalBox) + 
SHorizontalBox::Slot()
.AutoWidth()
[
    SNew(SButton)
    .OnClicked_Static(FSecmaVREdModeToolkit::OnReplace)
    .ButtonColorAndOpacity(FColor(255, 100, 100))
    .IsEnabled_Static(FSecmaVREdModeToolkit::IsSelectionReplaceable)
    [
        SNew(STextBlock)
        .Text(LOCTEXT("ReplaceButtonLabel", "Replace"))
    ]
] + ```
For example, how would I access and change the text of that innermost STextBlock?
maiden talon
#

you should store it in a var

#

you can use SAssignNew instead of SNew to store it

runic plume
#

Using slate for the first time, but having issue with building yet intellisense doesn't bring up issues. Here's an excerpt from UBT: ```
1> [1/5] SPlayerHUDWidget.cpp
1>\Engine\Source\Runtime\SlateCore\Public\Widgets/DeclarativeSyntaxSupport.h(784): error C2039: 'FArguments': is not a member of 'SCompoundWidget'
1>\Engine\Source\Runtime\SlateCore\Public\Widgets/SCompoundWidget.h(20): note: see declaration of 'SCompoundWidget'
1>\ProjectName\Source\ProjectName\Public\UI/SPlayerHUDWidget.h(13): note: see reference to class template instantiation 'TSlateBaseNamedArgs<SCompoundWidget>' being compiled
1>\Engine\Source\Runtime\SlateCore\Public\Widgets/DeclarativeSyntaxSupport.h(784): error C3646: 'WidgetArgsType': unknown override specifier
1>\Engine\Source\Runtime\SlateCore\Public\Widgets/DeclarativeSyntaxSupport.h(784): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>\Engine\Source\Runtime\SlateCore\Public\Widgets/DeclarativeSyntaxSupport.h(804): error C2143: syntax error: missing ';' before '&'

I'm using a source build of the engine, did I miss to compile a module?
#

UBT really does not like DeclarativeSyntaxSupport.h listing over 100 errors on line 832.

civic pasture
#

Not sure if this is the right place to ask this but.
With slate can I add widgets to my game like a task bar that has dropdown menus like file, edit, view

runic plume
#

Yes you can.

civic pasture
#

Oh okay, thank you. I'm still pretty new to Unreal. Trying to wrap my head around how slate works.

pastel phoenix
#

whole UE Editor made by Slate

gritty frigate
#

@civic pasture is it something that you want to do in c++ or are you open to blueprints? If youโ€™re open to blueprints you might find it more straight forward to do it in UMG

civic pasture
#

I think we're leaning towards c++. We're actually making a tool instead of a game. UMG does look a lot easier though

gritty frigate
#

You can still do UMG for a plugin. If you want to be C++, youโ€™ll definitely want to do it in Slate though

#

Ive been doing exactly that kind of thing in Slate recently myself - including a menu bar, with drop down menus. Havenโ€™t managed to get nested menus working yet though

civic pasture
#

Well it's awesome that it can be done. I'll definitely be back with more questions, haha. @gritty frigate if you have any resources or tutorials on doing that type of project with Slate I'd love to see them.

gritty frigate
#

Iโ€™ve not come across any specific resources - I muddled through when I first got into doing stuff in Slate. Happy to help with any advice I can give, though.

pastel phoenix
#

hi guys. any ideas how to get UWorld* in Slate widget? GEngine->GetWorld(); returning NULL

#

UGameplayStatics::PlaySound2D() need it

quaint zealot
#

FSlateApplication::PlaySound ?

#
NewSound.SetResourceObject(/*USoundBase*/);
FSlateApplication::Get().PlaySound(NewSound);```
pastel phoenix
#

not fit, i'm playing USoundWaveProcedural

#

or...

#

it based on USoundBase

#

thank you, i'll try

gritty frigate
#

Can you ensure that your Slate widget has a world context?

quaint zealot
#

Slate widgets don't have a concept of a world context

#

They are entirely outside the UObject world

gritty frigate
#

They can if you add it yourself

#

(is what I meant)

quaint zealot
#

At this point you should use UMG instead

#

UMG being Slate objects as UObjects

gritty frigate
#

If you're wanting to do it in C++, UMG is horrible

quaint zealot
#

I don't know, how worse than Slate is it really ? ๐Ÿ˜›

gritty frigate
#

haha

#

๐Ÿ™‚

#

I'd never really played with Slate, and I was trying to do some stuff in C++ with UMG, and the line from Epic on UDN was "don't. Use Slate"

#

I have a load of Slate code that interacts with an Actor in my scene. I pass the Actor into the top level Slate widget, which ensures that any sub-widgets that require it have it

quaint zealot
#

The main limitation of Slate widgets for gameplay is that they really aren't designed to interact with UObjects (textures, materials...) at all

#

UMG is designed as a solution for that

gritty frigate
#

interesting. I had thought that UMG was just a way to get UI elements blueprintable

quaint zealot
#

It's also that, but basically, creating a material instance for a button to use in Slate requires some serious boilerplate

narrow terrace
#

Slate was meant to be used for application/very low level purposes, thats what they mean when they say the engine was built in slate. I think the only things they Slate for on fortnite was for populating a list of items on screen quickly, and stuff that's happening outside the game like loading screens, etc

#

Another example is Halo MCC on PC, uses Slate for the menus

quaint zealot
#

Well Fortnite uses Slate in the sense that UMG is entirely based on it, but yes

#

Slate is just the low-level UI library with no gameplay framework support

exotic cypress
#

Greetings! I just created a new plugin using the Editor Window preset, which adds a new button to the editor to open a new slate window

#

I have never worked with Slate, I use Widgets, but I wanted to know if I could insert an Editor Utility Widget in that window and use it as a Widget wrapper

#

I already have most of the functionality created on the Editor Widget, I would just need to have it show when I press the button

pastel phoenix
#

question: how to completely remove widget?

        if (mTestWidget.IsValid())
        {
            GEngine->GameViewport->RemoveViewportWidgetContent(mTestWidget.ToSharedRef());
            mTestWidget.Reset();
        }
        mTestWidget = SNew(STestWidget)
            ;
        mTestWidget->LoadURLs(videoUrl, audioUrl);
        GEngine->GameViewport->AddViewportWidgetContent(mTestWidget.ToSharedRef());

it is removed from screen, but i hear his sound, it is alive somewhere in background

mild oracle
#

As far as I can tell, the only way to get textures in the UI to be smoothly downscaled is to make sure they are power of two, and that they have mipmaps turned on.
But if you have a texture that's not power of two, you would need to turn on padding, and then all your slate desired size calculations for the image would be completely broken.
So I'm thinking of writing a custom Image class that knows its non-padded size and returns the correct desired size.

Is this crazy? Impossible? Not even necessary?

gritty frigate
#

Does anyone know the best way to get the position that a mouse has clicked on a button (normalized) in a Slate widget? All of the helper functions that I've found require a world context object.

pastel phoenix
#
class MyInputProcessor : virtual public IInputProcessor
{
public:
    MyInputProcessor() = default;
    virtual ~MyInputProcessor() = default;
    bool HandleMouseButtonDownEvent(FSlateApplication& SlateApp, const FPointerEvent& MouseEvent) override;
};

should help, no world or worldcontext

#

but you need to know where is your button

gritty frigate
#

I can get the geometry for my button

#

Iโ€™ve just called it for the evening so am not in front of my computer now. Will take a look tomorrow though

#

Thanks!

mild oracle
#

@pastel phoenix InputProcessor looks interesting, what's the typical use case for that?

gritty frigate
#

I didn't end up needing that. It turned out to be much simpler than I had thought. I could get what I wanted with:

FVector2D SMyWidget::GetRelativeMousePositionOnWidget() const
{
    const FGeometry geometry = GetCachedGeometry();
    return geometry.AbsoluteToLocal( FSlateApplication::Get().GetCursorPos() ) / geometry.Size;
}```
pastel phoenix
#

@mild oracle any independent low level input from any input devices. for example it is only one way for input from Steam VR Touch

#
bool MyInputProcessor::HandleKeyDownEvent(FSlateApplication& SlateApp, const FKeyEvent& InKeyEvent)
{
    FKey key = InKeyEvent.GetKey();
    if (key == EKeys::Steam_Touch_0)
    {
        characterInterface->TouchLeftPressed();
        return true;
    }
    if (key == EKeys::Steam_Touch_1)
    {
        characterInterface->TouchRightPressed();
        return true;
    }
coral schooner
#

@mild oracle FSlateApplication::Get().RegisterInputPreprocessor(...)
When the engine queries the operating system for events, these events are passed to the InputProcessors until one processor processed the event by returning "true". You can also process the event and return "false", thats up to you. "Consuming the input"
e.g. ```
bool FSlateApplication::InputPreProcessorsHelper::HandleKeyDownEvent(FSlateApplication& SlateApp, const FKeyEvent& InKeyEvent)
{
for (TSharedPtr<IInputProcessor> InputPreProcessor : InputPreProcessorList)
{
if (InputPreProcessor->HandleKeyDownEvent(SlateApp, InKeyEvent))
{
return true;
}
}

return false;

}

#

In FSlateApplication::ProcessKeyDownEvent you can see an example of processing an input event. InputPreProcessor get the first shot on the event

mild oracle
#

@pastel phoenix @coral schooner Thanks!

civic pasture
#

Hey guys,

I'm trying to make the simplest menu bar in slate but I seem to have gotten stuck right away.
I was wondering if you could see any obvious errors I made.

Code:

static void FillMenuEntries(FMenuBuilder& MenuBuilder) {
    MenuBuilder.AddMenuSeparator();
}

void SMainMenuWidget::Construct(const FArguments& InArgs) {
    TSharedRef<FUICommandList> InCommandList(new FUICommandList());
    FMenuBarBuilder MenuBarBuilder(InCommandList);
    {
        MenuBarBuilder.AddPullDownMenu(TEXT("Menu 1"), TEXT("Opens Menu 1"), FNewMenuDelegate::CreateRaw(&FillMenuEntries));
    }
}

Error:

'TBaseDelegate<TTypeWrapper<void>,FMenuBuilder &>::CreateRaw': no matching overloaded function found

I've basically copied this code from the Unreal API
https://docs.unrealengine.com/en-US/Programming/Slate/Widgets/index.html

Layout and widget complexities not demonstrated in the Slate Viewer Widget Gallery.

#

I'm wondering if I missed an include with the appropriate CreateRaw function or is my FillMenuEntries ill formed

gritty frigate
#

I rolled my own in the end, and didnโ€™t discover MenuBuilder until it was too late, unfortunately

civic pasture
#

I started doing that but then saw menu builder lol

mild oracle
#

@civic pasture Is there a reason you're using Slate and not UMG? Is this for an editor plugin? I'm just curious

civic pasture
#

@mild oracle I'm developing a VR application for exploring 3D medical datasets. The people in charge want me to use Unreal engine so I am trying to recreate the old QT / OpenGL based version of our software in Unreal basically.

coral schooner
#

@civic pasture I never used delegates with global functions. I don't now if that is possible

#

You can use CreateStatic or CreateLambda

#

see DelegateSignatureImpl.inl file

civic pasture
#

Hmm, good point. I'll try it with a member function

#

I know c++ decently well but to be honest a lot of the unreal API is still a mystery to me lol

coral schooner
#

If you work with Slate, the most important thing is to know WidgetReflector in the editor. Look at other stuff how it is build and try to adapt

civic pasture
#

Ah okay, I'll look into that

gritty frigate
#

Widget Reflector has saved my arse on a number of occasions. I just wish you could see properties too!

coral schooner
#

Windows->DeveloperTools->WidgetRelector

civic pasture
#

I also found out that there are some slate example files under Engine\Source\Runtime\AppFramework\Private\Framework\Testing

coral schooner
#

@civic pasture Unreal is a monstrosity, but the code is clean and comparably easy to get into. If you think Unreal bad, try OpenMesh

civic pasture
#

Yea, I think I'm just inexperienced. Luckily this community seems very helpful. I've surprisingly never heard of OpenMesh. I spent a lot of time implementing something similar and it was not trivial to get those mesh operations working properly

coral schooner
#

If you ever try to use it, be aware that it does not support LeftHandedCoordinate systems

civic pasture
#

oh, that's lame

coral schooner
civic pasture
#

Oh cool, thanks for the heads up

lone shoal
#

Are slate args that are not passed in initialised to the default value defined in the base class?

#

i.e if I make an SCompoundWidget that has a child formatted like this

ChildSlot
        .HAlign(InArgs._HAlign)
        .VAlign(InArgs._VAlign)
        [
            SAssignNew(OuterBorder, SBorder)
            .Padding(FMargin(4.0f))
            [
                SAssignNew(InnerBorder, SBorder)
                [
                    InArgs._Content.Widget
                ]
            ]    
        ];```
Should this just create 2 default borders, where the outer one's padding is 4px?
lone shoal
#

So they do seem to default, but I'm having an issue where my slate widget is the child of a transparent widget and won't go back to being opaque. What parameter of border.h actually determines the opacity, because it doesnt appear to be _ColorAndOpacity

pastel phoenix
#

look for transparency may be

gritty frigate
#

Also, take a look at the source code for the UMG Border. See which slate attribute connects to which UMG attribute. That way you can figure out what works in UMG in the UI and then replicate it over to Slate

#

Oh, I just reread your question. If a widget is defined as being transparent (and all its children) then I donโ€™t believe thereโ€™s any way to override this on a child

lone shoal
#

It actually ended up being that the default SBorder FSlateBrush is not the same as what UBorder provides so it looked transparent but was actually just displaying something in bordered mode. I just stored a default FSlateBrush and passed it in to the SBorder construction and it drew opaque again!

gritty frigate
#

cool ๐Ÿ™‚

gritty frigate
#

In a Slate widget, when I press the mouse button, I'm hiding the mouse and moving it to the center of the widget.

I have this at the end of my OnMouseButtonDown()

    return FReply::Handled()
        .CaptureMouse( SharedThis( this ) )
        .LockMouseToWidget( SharedThis( this ) )
        .SetMousePos( WidgetCenter );```

I'm finding that I see a flash of the mouse pointer at the widget center before it disappears. Not always - maybe 10% of the time. Does anyone know how I can avoid this?
#

I'm also using SetCursor( EMouseCursor::None ); to hide the cursor - it may because this isn't read every frame?

pastel phoenix
#

btw, here is another way to catch mouse -

class SIMPLEMPEGVIEWER_API FSimpleMpegViewerViewport : public ISlateViewport
{
public:
    FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
};
#
        SAssignNew(mViewportWidget, SViewport);
    mMpegViewerViewport = MakeShareable(new FSimpleMpegViewerViewport(SharedThis(this)));
    mViewportWidget->SetViewportInterface(mMpegViewerViewport.ToSharedRef());
#

but to complicated

gritty frigate
#

interesting - thanks

#

that may be overkill for what I'm doing

#

I've changed mine so that OnMouseButtonDown() doesn't set the position. It only gets set in OnMouseMove()

#

I very occasionally see a flash of a cursor moving, but I'm willing to live with this for now

gritty frigate
#

Does anyone know if there's a way to do the following:

SAssignNew( myButton, SButton )
.OnClicked_Lambda( [myButton]()
{
  // Do something that requires myButton
} )```
#

It seems that, the way I did the above, myButton is assigned after being copied over to the lambda, so it's invalid in the lambda.,

#

It's also a local variable, otherwise I'd pass it by reference

#

I could do:

myButton->SetOnClicked( FOnClicked::CreateLambda( [myButton]()
{
  // Do something
} ) );```
#

But in my code (I'm not using SButton), OnClicked is passed straight through to an internal, so I haven't added a SetOnClicked method

#

I can certainly add one, but I was wondering if anyone knew of a better way

pastel phoenix
#

make it not local variable, pass [this]

gritty frigate
#

It's an item in an array, which makes that tricky

#

The array is a member variable, but the order can be changed at runtime

#

so when the lambda is created, the index isn't certain

#

I went with using SetOnClicked for now

#

When you're doing Slate stuff, do you generally pass shared pointers around everywhere?

#

I'm trying to avoid too much copying of shared pointers, so if I just need to pass a non-owning pointer, I'm starting to get the raw pointer

pastel phoenix
#

raw pointers are dangerous

gritty frigate
#

only if you own them

pastel phoenix
#

you can avoid SAssignNew btw by TSharedPtr<SButton> myButton = SNew(SButton);

gritty frigate
#

yeah

pastel phoenix
#

and .ToSharedRef() it

gritty frigate
#

I did it that way for a long time, but that was a pain when the widgets were nested

#

Learning about SAssignNew was a revelation

#

In my non-UE4 projects, I'm trying to be good and follow the standard about when to use unique_ptr, shared_ptr and raw pointers

coral schooner
#

@gritty frigate whole slate is build uppon shared pointers. You should stick to it, as at some points you might need to pass your widget to somewhere else, end then they require it as shared

#

and I don't that they add much computative overhead, but tons of savety

gritty frigate
#

Yeah, it makes me feel a little dirty!

In this case, I know that I'm just passing a widget into a method for temporary usage, and it definitely won't be stored

#

But I may just make it a shared pointer anyway

limpid atlas
#

@gritty frigate Don't do that, shared pointers get abused no end by people thinking they're inherently 'safe'. They're not, they're for shared ownership. If you don't want that, don't use them.

#

Case in point, if you capture by shared pointer in that lambda your button will probably never get freed, since you'll have an ownership cycle.

#

Use raw, or weak if you can't guarantee lifetime. Though in truth capturing the button in the first place is a little strange.

gritty frigate
#

@limpid atlas thats my general take on them. As I mentioned, in non UE4 code I try to be pretty good with pointers

coral schooner
#

@limpid atlas in what way do you think them unsafe?

limpid atlas
#

@coral schooner Didn't mean to imply they're unsafe (though the ownership loop above is an example where they can be). More just saying though that the blanket statements like 'shared pointers are safer/better' or 'raw pointers/tick are bad' are not a good way of thinking. They absolve you of any responsibility to understand how things work and what they're intended to be used for.

pastel phoenix
#

i don't understand, why after GEngine->GameViewport->RemoveViewportWidgetContent(mTestWidget.ToSharedRef()); mTestWidget.Reset(); my widget still have references to it and not removing forever. destructor never called. can it will be count as "unsafing"?

gritty frigate
#

something must still have a reference to it somewhere

#

I think Epic probably built Slate with shared pointers everywhere because they knew that developers didn't have to worry about lifetimes in the rest of the engine, because of the garbage collector, so they sacrificed performance for ease-of-use

pastel phoenix
#

most times it works fine, if widget removed from screen you see it as not exist. but my widget have sound, and i heard it forever ๐Ÿ˜ธ

#

and i can't turn off sound, because i can't catch it deleting from the screen

gritty frigate
#

It's definitely worth figuring out what's still referencing it then

#

Do you have any other references to it in your code?

limpid atlas
#

Most likely it's what we were discussing above, you maybe capture the shared pointer in a lambda/delegate somewhere?

pastel phoenix
#

the whole code. no lambdas

#

i want to remove mTestWWidget->Stop();

#

because i can't call ->Stop(); here -

gritty frigate
#

Can you put a breakpoint in your code for when it's removed and check the reference count?

pastel phoenix
#

i tried, it is 1

#

after removing something is still referenced

limpid atlas
#

You've confirmed that the widget destructor is definitely not called? (rather than just whatever is producing the sound continuing after the widget dies)
If so then not sure, looks fine. Though UE4 widgets support SharedFromThis, it's possible something within your SSimpleYouTubeWidget is passing this to something that implicitly converts it to a SharedPtr...

pastel phoenix
#

destructor is not called, debugged and logged

limpid atlas
#

Right. Yeah SharedFromThis is the only thing I can think of that could cause it then, if there's no other code using mTestWidget

pastel phoenix
#

SharedFromThis seems is evil

limpid atlas
#

It mostly is, yeah. But convenient sometimes...

pastel phoenix
#

i have an idea to set breakpoint inside it, and catch who referenced

#

SharedFromThis is a class or template. need to research

gritty frigate
#

TSharedFromThis is a template class

limpid atlas
#

Yeah, the method doing the conversion is either SharedThis or AsShared

gritty frigate
#
class MyClass : public ParentClass, public TSharedFromThis<MyClass>
{
};```
You can then do:
`SharedThis( this )`
and it'll give you a shared pointer to the current class
#

AsShared() gives you a SharedRef

limpid atlas
#

But it could be awkward to isolate, I imagine it gets called a whole lot of times by general Slate code

pastel phoenix
#

and the winner is...

#
class SLATECORE_API SWidget
    : public FSlateControlledConstruction,
    public TSharedFromThis<SWidget>        // Enables 'this->AsShared()'
gritty frigate
#

All Slate widgets have that

pastel phoenix
#

it used in SWidget::Paint

gritty frigate
#

it doesn't necessarily mean that AsShared or SharedThis is called

pastel phoenix
#

it is called in every paint of widget

gritty frigate
#

It looks like that's only used on a local variable there

#

So it should be decremented at the end of every Paint() call

pastel phoenix
gritty frigate
#

Is that the bit that's definitely incrementing your ref count?

pastel phoenix
#

not sure

#

it is hard to say, in debug it is called millions of time every second

gritty frigate
#

yeah...

#

Hmm - give me a sec - let me take a look at something

#

I want to see if it's possible to get a breakpoint on reference count change for a particular widget

#

although every time Paint() is called, it'll be jumping up and down

pastel phoenix
#

yep

#

i think i found who referenced in my code

#
    FSlateRenderer* Renderer = FSlateApplication::Get().GetRenderer();
    if (!Renderer)
    {
        UE_LOG(SimpleMpegViewerLog, Warning, TEXT("No slate renderer"));
        return;
    }
    mUpdatableTexture = Renderer->CreateUpdatableTexture(1, 1);

this guy

#

but i still don't know how

gritty frigate
#

I'm not sure, I'm afraid. This feels like it could be a huge rabbit hole!

pastel phoenix
#

๐Ÿ˜ธ

gritty frigate
#

Sorry!

#

Wish I could stay and help, but work calls

pastel phoenix
#

nevermind, thanks for trying

gritty frigate
#

When I call Invalidate() on a widget, what does that cause it to call to regenerate itself?

gritty frigate
#

Separate question, has anyone ever come across an SCompoundWidget subclass which uses Slots?

pastel phoenix
#

but why

#

boxes have slots, they comes one after another, overlays have slots, they comes one on another

gritty frigate
#

I'm trying to create a widget that is a tab panel. Buttons across the top, and a WidgetSwitcher below

quaint zealot
#

Yeah I did that

pastel phoenix
#

make box

quaint zealot
#

Exactly the same thing too, tab view

#

It's quite easy

gritty frigate
#

cool - how'd you put it together?

pastel phoenix
#

SHorizontalBox

gritty frigate
#

I'd like to be able to do:

SNew( SMyTabPanel )
+SMyTabPanel::Slot()
.Label( LOCTEXT( "Label", "Label" )
[
  // Content
]

+SMyTabPanel::Slot()
.Label( LOCTEXT( "Label2", "Label2" )
[
  // Content
]```
quaint zealot
#

Yeah I did just that, let me give you some boilerplate

gritty frigate
#

Awesome ๐Ÿ™‚ thanks!

quaint zealot
#

Might have a lot of missing stuff but the slot system is there

#

Including the .Label thing

gritty frigate
#

So, looking at that, I've got that far

#

When a new slot is added, at what point are you adding it to the WidgetSwitcher?

#

(and the button to the HorizontalBox)

quaint zealot
#
    // Slot contents
    int32 Index = 0;
    for (SMyTabView::FSlot* TabSlot : InArgs.Slots)
    {
        // Add header entry
        Header->AddSlot()
        .AutoWidth()
        [
            SNew(SmyButton) // No navigation
            .Theme("TabButton")
            .Text(TabSlot->HeaderText)
            .HelpText(TabSlot->HeaderHelpText)
            .OnClicked(this, &SMyTabView::SetTabIndex, Index)
            .Visibility(this, &SMyTabView::GetTabVisibility, Index)
            .Enabled(this, &SMyTabView::IsTabEnabled, Index)
            .Focusable(false)
        ];
        
        // Add content
        static_cast<SMyTabPanel*>(&TabSlot->GetWidget().Get())->Initialize(Index, MakeShareable(this));
        Content->AddSlot()
        [
            TabSlot->GetWidget()
        ];

        Index++;
    }```
gritty frigate
#

Ah - I think I see where we might be doing this differently

quaint zealot
#

Basically iterate the InArgs.Slots

gritty frigate
#

While I want to be able to do it in Construct, I also want to be able to do:

TabPanel->AddSlot()
.Label( LOCTEXT( "Label", "Label" ) )
[
  // Content
];```
#

which is actually my main use case

#

sorry - should have mentioned that one first!

quaint zealot
#

Yeah that's what I do here

#

TabSlot->GetWidget()

#

That's the contents

#

It's a custom button class here but you get the idea

gritty frigate
#

Sure

#

When TabPanel::AddSlot() is called, there isn't anything in the slot yet, though, so I can't do anything in that method

quaint zealot
#

I'm not sure what you're asking but basically this code works for me to do what you ask for

#

Down to the syntax

#

Like your //Content here is a SNew(....)

gritty frigate
#

So you're building it in Construct() in there? Is there anywhere else that you're adding new tab buttons?

#

Because Construct is called before I call TabPanel->AddSlot()

#

I appreciate the help here, btw - I'm just not sure what I'm doing differently

quaint zealot
#

I don't believe that is an issue

#

Now that you ask it does seem weird

gritty frigate
#

The execution flow for mine seems to be:

Construct() // adds any contents defined initially
AddSlot() // how does this content get added?
AddSlot() // how does this content get added?```
#

Right now I have a really hacky method that is working, using a flag and Tick(), but I hate doing it this way

quaint zealot
#

My understanding is that the slot is a Slate widget in itself

gritty frigate
#

ahh, I didn't think of that!

#

will give that a go

quaint zealot
#

Clearly in my case, the slot syntax results in Construct() for the tab view having access to the slots

#

As in, I don't know if I'm copying the slot contents or a slot widget

#

But at least the slot exists and is defined with proper callbacks and user name etc

gritty frigate
#

yup

#

hmm - strange

#

I'm going to stick with what I've currently got for now, and get the rest of it working, and will revisit the building later

#

I asked on UDN about it as well

#

The fun addition I'm going to want to add at some point is to make the contents of the tab buttons customisable... Not sure how I'd do that!

#

I might just hard-code the options

coral schooner
#

@limpid atlas I don't realy understand the ownership loop you are talking about. If you pass the shared ptr to a lambda, you increase the reference counter and as soon as the lambda removed from memory, count down by 1.

gritty frigate
#

If you have widget A, which contains Widget B, which has lambda C, which contains a shared pointer to widget A, you've got a loop.

#

Widget B is not going to be destroyed until Widget A releases it

#

lambda C is not going to be removed from memory until Widget B is destroyed

#

Widget A is not going to be destroyed until lambda C is removed from memory

coral schooner
#

I see. Then use TWeakPtr

gritty frigate
#

yup, that certainly works. I think what @limpid atlas was getting at was that using TSharedPtr everywhere has issues

coral schooner
#

In that case yes. But mixing managed and raw is even worse.

#

e.g. a raw pointer to A in B is passed as shared ptr to C

gritty frigate
#

The C++ standard (and I know that UE4 doesn't follow this) recommends:
shared_ptr for shared ownership
unique_ptr for single ownership
raw pointer for observer

#

There was a suggestion of observer_ptr<T>, which is considered experimental at the moment, but probably won't be added

coral schooner
#

what is observer?

gritty frigate
#

observer is anything that wants to use the pointer, but will definitely finish with it before the pointer is destroyed

#

In my case from yesterday, I have:

SMyWidget::CopyWidgetSettings( SMyWidget* Other )
{
  // Copy things from other to this widget
}```
#

There is no way that Other is going to be destroyed while I'm in that method

#

so it doesn't need to take any ownership of it to protect it

#

I could take it as a TWeakPtr in that function, but then I'd either have to get the raw pointer, or turn it into a TSharedPtr, which would have the hit of incrementing the ref count when I really don't need it

coral schooner
#

yeah thats true. The term "observer" only came up for me in Observer Pattern, until now

gritty frigate
coral schooner
#

"I learned C++ at school, I'm a programmer" ... I once saw basically an essay about why to use size_t over unsigned int.

gritty frigate
#

๐Ÿ™‚

limpid atlas
#

observer_ptr essentially is a raw pointer, if I'm not mistaking what you're referring to. It's literally an empty wrapper for a raw pointer, the only point of which is to make the written code more explicit in intent.

#

And for the ownership loop, you don't even need 2 widgets. Shared ptr capture of button in button's OnClicked is enough. The lambda will be stored inside the button.

coral schooner
#

Yeah, thats definitely a problem. Not a memory leak, but a clear deadlock in clearing the memory. Never thought about that.

gritty frigate
#

I can't imagine a time when you'd ever really try that - I think we would all capture the current object into a lambda as a raw this pointer

#

but it shows off the dangers

coral schooner
#

I would not have passed the shared pointer as raw before this discussion. But still I would not use raw pointer for the lambda now, TWeakPtr instead, as the lambda does not count as "observer" as of your description

gritty frigate
#

For this or just for other objects?

coral schooner
#

ok, this is another thing again^^

#

how you do the inline code?

#

this test

#

ah

gritty frigate
#

It would be a bit weird to pass that as anything other than a raw pointer!

#

single ` for inline

#

Do you know about code formatting with multiline?

#

```cpp
code here
```

#
int a = 1;
coral schooner
#

thats good to know as well. I knew that color coding is possible, but the last syntax I saw to define the color was horrible

#

this is definitely an improvement. thanks

gritty frigate
#

๐Ÿ‘๐Ÿป

limpid atlas
#

The case of capturing a button in its own OnClicked handler, although a bit weird, is an example where raw pointer is best. OnClicked is triggered by the button, so it's not possible for the lambda to be called if the button has been destroyed. There's no lifetime issue, so you don't need either shared or weak, the pointer in the lambda is guaranteed to be valid.

gritty frigate
#

Is there any way to find out what the actual render colour of a widget is? (Including all parent colours that affect their children) I have a widget that seems to be rendering black and really shouldnโ€™t be.

mild oracle
#

@gritty frigate what widget is it? I'd start by sniffing around in its OnPaint, looking at InWidgetStyle

gritty frigate
#

Thatโ€™s a good thought about OnPaint. Itโ€™s a checkbox, and Iโ€™ve used it with the same style elsewhere and itโ€™s been fine

gritty frigate
#

Found it eventually, by tracking back through Paint calls. It turns out it was an SButton which had ForegroundColor left as default, which was InvertedForeground, which is black. Now been overridden to white! Thanks for the tip, @mild oracle

lone shoal
#

How do I get the SConstrainCanvas slot of a slate widget that I added with SAssignNew? There doesn't seem to be a GetSlot function or anything like in umg

#
SAssignNew(OuterCanvas, SConstraintCanvas)
+SConstraintCanvas::Slot()
        [
            SAssignNew(MenuOuterBorder, SCamsoUIBorder)
            [
                SAssignNew(ContentVerticalBox, SVerticalBox)
            ]    
        ]

i.e I want to access this slot, but accessing it from the outer canvas is a bit weird.

toxic dove
#

instantiate the slot outside

#

cache the raw ptr

#

and then you can refer to it later and keep adding to it, etc.

lone shoal
#

Righto, was hoping that wasn't the only way but I guess so.

trim kestrel
#

Welp, I no longer have all the fun of the crazy systems we layered over input/focus in Fortnite...

#

... and there's not really any great documentation on focus or input routing that I can find.

quaint zealot
#

Hey, long time no see.

trim kestrel
#

o7

#

Been hyper busy with personal life things - home ownership, flooding, the end of the world, that sort of stuff.

quaint zealot
#

Sounds bad

tribal fractal
#

Anyone know why UWidget doesn't have tick or anything else that have DeltaTime?

quaint zealot
#

Doesn't need to, I guess

#

The underlying Slate widgets have tick already

#

UUSerWidget ticks IIRC

gritty frigate
#

If I've got 2 widgets, one of which does something with the left mouse button, and one of which does something with the right mouse button, can I overlay them and have each one pick up its mouse button?

#

Both widgets are ones that I've written myself

#

so I have full access

#

I had through that if I returned FReply::Unhandled(), the mouse action would be passed through to the widget underneath

#

Or is it passed to the parent widget? These widgets are both children of the same SOverlay

#

I can make them nested easily enough - I might try that one

#

Nesting it is - if one is the child of the other, it works

#

Thanks for being my rubber duck, channel ๐Ÿ™‚

pastel phoenix
#

i don't think mouse will pass to something invisible

#

i think it will be passed to parent

gritty frigate
#

Yup, that's fine when it's invisible

#

I had, though:

SOverlay
+Slot()
[
  A
]

+Slot()
[
  B
]```
#

And I was hoping that an unhandled click on B would pass through to A, but it doesn't

#

So now it's:

A
[
  B
]```
mild oracle
#

so the second layout worked @gritty frigate ?

gritty frigate
#

yes

#

unhandled mouse events in B were successfully picked up by A

mild oracle
#

that's interesting that on top didn't get passed through but nested did, thanks for sharing!

gritty frigate
#

๐Ÿ‘

gritty frigate
#

If I have a subclass of SCompoundWidget which contains, say, an SEditableText widget, how can I ensure that, when I call FSlateApplication::Get().SetUserFocus( 0, MyCompoundWidget );, the SEditableText internally is actually set to be focused?

pastel phoenix
#

you could use FSlateApplication::Get().SetUserFocus(); on SEditableText, previously assigned to variable inside MyCompoundWidget

gritty frigate
#

That's what I've done

#

But if I can, I'd like to hide that MyCompoundWidget has an SEditableText inside it

pastel phoenix
#

you can try to use OnFocusReceived

gritty frigate
#

I'll have a play - thanks

#

Unrelated note - is there any function that is called when a widget is resized? I need to get some kind of notification on resize

#

There are a lot of methods that take geometry, but I only want to do something when it changes

main hedge
#

I remember looking hard for such an event and finding nothing at all

gritty frigate
#

Iโ€™ve put something in tick to compare the current and previous geometry, but that feels horrible to me

main hedge
#

you could always extend slate and add this event

gritty frigate
#

Iโ€™m not changing the engine, as this is a plugin that we need to be able to work with the engine as-is.

frozen echo
#

I'm trying to setup a debug menu/tuner system. I have it working with AHUD, but it unfortunately appears under the UMG based UI. Is there a way to draw simple 2D boxes and text with a custom widget so I can have it over top?

gritty frigate
#

In my code, I'm using SScrollBox in two places. In one of them, it works as expected. However, in the other, when I add items to the internal SVerticalBox, it just expands outside the area that the SScrollBox should be covering.

The one that doesn't work contains a number of SVerticalBoxes and SHorizontalBoxes, including some that are collapsed/shown based on a button.

The one that does work contains an SVerticalBox which has height-specified SBoxes inside it.

Other than that, I'm not certain what's different and why my latest one isn't working properly

#

The SScrollBox should be contained within the border behind

#

ooh - looking at the widget reflector, it looks like it's a GridPanel higher up the tree that is the one that isn't being restricted

gritty frigate
#

Found it. I had missed a .FillRow() on the SGridPanel

coral schooner
#

@gritty frigate There is/was an issue with Scrollboxes (at least in UMG) not clamping to the max possible size when the scrollbox is set to size=auto

mild walrus
#

Hey guys, im doing some UI work and im trying to figure out the inverse of this method found in SVirtualJoystick.cpp called "ResolveRelativePosition".

Not really sure how i would go about converting values passed through here back to their original format...

static int32 ResolveRelativePosition(float Position, float RelativeTo, float ScaleFactor)
{
    // absolute from edge
    if (Position < -1.0f)
    {
        return RelativeTo + Position * ScaleFactor;
    }
    // relative from edge
    else if (Position < 0.0f)
    {
        return RelativeTo + Position * RelativeTo;
    }
    // relative from 0
    else if (Position <= 1.0f)
    {
        return Position * RelativeTo;
    }
    // absolute from 0
    else
    {
        return Position * ScaleFactor;
    }

}

Heres that function, not sure if theres a "math" channel so if i posted in the wrong place, my bad lol.

frigid dagger
#

I'm having a hard time creating a notification with a cancel button. The notification is being made, but I'm not able to get the button to appear. I've been referencing engine code for how they handled adding buttons to their notification items and as far as I can tell it's being done in the roughly the same manner as I am doing it. My understanding is that it is simply necessary to create FNotificationInfo object and then use the add function in the ButtonDetails array to introduce a new element. Then use the add notification method with the info object as the argument. The info object is definitely being used as the main notification text is defined in there, but it does not seem to be accessing the buttondetails to generate button objects in the notification.

#

For reference, there is engine code for creating a cancel notification in the steam audio module that does this:

#

The only real difference I can see is that they passed in a delegate and that they set the durations for the fadeout and expiration. I don't think those would be correlated to the construction of the button

frigid dagger
#

Not sure what fixed it, but it's showing up now

frigid dagger
#

I did wind up figuring out what change worked, i had to add which state it was visible for (i.e. adding SNotificationItem::CS_None to the arg list)

split meteor
#

Hello guys, do you know the best way to customize a property that is referencing a UDataAsset ? I'd like it to be displayed in my actor class as a series of all its member variables instead of an asset to locate.
More precisly, I'd like to directly edit the properties of my UDataAsset in the details panel of an Actor.

I've already created an Editor Module and I'm able to modify details properties but I can't figure out how to access the asset properties to display them in my CustomizeChildren function, any ideas ?

low bluff
#

Well, an Asset is a very "static" thing (can't find the right words atm). Let's say you ref it in two different places. You would be changing one and the same "Instance".
So I think the keyword here is to mark the UPROPERTY() UDataAsset pointer as Instanced . That should make an instanced copy of it, that lives in the Actor you have, and you should also get a sort of menu to adjust the exposed variables of that DA. @split meteor

split meteor
#

Alright... Yeah, it surely a huge step forward for me, thank you very much. I've never saw that property flag anywhere else and I don't get why it never fell into my researches.
I spent a great amount of time trying to figure out how to do it with custom details displaying and it was juste a flag to put... hahaha

split meteor
#

However @low bluff , now I can't reference my DataAsset from my actor class, and I'd like to do both, to reference it from my main class, but also to be able to modify it from there.
So far, if the asset is referenced before and I make it "Instanced", I'm able to change as many variables as I want. But if I clear it, I can't aim it anymore.
To be more precise, I can't reference any of my existing data assets when I use the "Instanced" specifier, see the screenshot below :

low bluff
#

Not sure what that is about. Might be some UCLASS keyword. This might be better asked in #cpp

split meteor
#

Sure, sorry, it's just that you seemed comfortable with it ๐Ÿ™‚

split laurel
#

I don't think you can have both by default because you'd need both an asset picker but also inlined properties.
You could write some custom widget for that that gets used on the datassetptr properties

split meteor
#

Isn't the dropdown showed above, an asset picker equivalent ?

split laurel
#

nope, that's a class picker

#

@split meteor

#

the Instanced keyword instantiates one object of the class that you pick there, and that's why you can select which type of data asset (inheriting from the one you specified in c++) you want there, and then directly edit the values. It lives in there. You want to be able to pick an asset, and then edit the values. That's why you don't want Instanced

#

here's a question of mine though:
In a details customization, how do I access the properties of a child class?

I have a "DataSet class" that will have multiple child classes that aren't known by default, and those child classes have multiple entries of a set of 3 classes {A, B, C}.
I'm modifying the DataSet details (in reality one of the couple child classes) and want to access the A, B and C elements in there.

split meteor
#

I see, thanks for the reply, about your trouble, I'm not quite sure to understand

split laurel
#

it's fine, and no problem

narrow terrace
#

Hey has anybody here used the engine module: Game Menu Builder? Just trying to get as much information on how this is used, cause I might end up using it myself...

main hedge
#

it's something very old that there's not much of a reason to use it now

#

just use UMG for game UI

narrow terrace
#

lol yeah was just wondering if it was one of those magical hidden things in the engine

gritty frigate
#

In my tool, when the input mode is set to UIOnly, I want my Slate widgets to pick up keyboard key presses

#

I'm finding that my OnKeyDown is never called

#

Ah... it looks like it's looking for the focussed widget, rather than the widget under the mouse

#

I hadn't set SupportsKeyboardFocus() to return true. That solved one issue ๐Ÿ™‚

orchid nova
#

I'm rendering an SWidget into a UTextureRenderTarget2d using FWidgetRenderer->DrawWidget(target, widget...), but it seems the layout does not get correctly calculated. Is there something I need to do to ensure the widget has laid itself out?

#

I'm guessing it's layout-related because if I render multiple textures using this method, some of them get the layout correctly, while others do not

#

I've tried with various settings like prepass needed on/off, setting widgets to volatile, but not much luck so far

#

This is in particular with content that's been anchored and contains text which seems like it requires more calculations

orchid nova
#

^ okay I've managed to isolate it enough to say for fairly certain that it only affects text rendering and nothing else is incorrectly laid out

#

...word wrap, specifically, appears to be causing this ๐Ÿค”

#

or centering

#

why is this so complicated lol

#

yeah okay I think the cause is: Justification center or right, and text has auto wrap enabled... That's when it breaks the layout. It works perfectly fine with left justificated text even with wrapping text

#

But even then, it only happens sometimes ๐Ÿคฆ

orchid nova
#

it feels like a race condition between Slate layout for the text, and the rendering code, since it works sometimes but not every time... but I can't figure out how to force the layout calcs to finish before the widget is drawn

orchid nova
#

Update on above: calling DrawWidget twice fixes it. Seems like a massive massive ridiculous hack but I guess it'll do for now lol

gritty frigate
#

Thanks for the updates. This is really good to know. My current project is going to require this soon

#

Are you on UDN, @orchid nova? This could be a good question for Epic. If not, if you can get a cut-down version that shows the issue, I can post it on there and see if they have any suggestions.

orchid nova
#

All you need to do is put some text into an UMG widget, justify it center or right, enable auto wrap, and then make sure you have enough text that it wraps

#

the example in that video is a bit more complex but it reproduces with just a simple canvas + text type widget as well

#
{
    const TSharedPtr<SWidget> SlateWidget = Widget->TakeWidget();
    
    FWidgetRenderer* WidgetRenderer = new FWidgetRenderer();
    
    WidgetRenderer->DrawWidget(TextureRenderTarget2D, SlateWidget.ToSharedRef(), Scale, DrawSize, 1);
    WidgetRenderer->DrawWidget(TextureRenderTarget2D, SlateWidget.ToSharedRef(), Scale, DrawSize, 1);    
}
#

And this is the code I'm currently using

#

and I don't even know what UDN is so I don't think I'm there - feel free to post it there, I'd be curious to hear as well