#slate
1 messages ยท Page 22 of 1
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
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
How did you use it in code ?
unfortunatly stashed it, let me try to recreate it
The usual way would be to use style assets, just like for fonts
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
Is there no "simple" way to just create a box with a color?
without styling or creating additional assets?
Just a plain box?
Ye, but SBox also doesnt seem to work
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
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
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
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
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
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?
You need a valid image if you want to use it for SImage or SBorder
Well, isnt "none" with white tint just a white background-image?
No, it is not
So i have to import a solid-color-image?
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
..... 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
This is what our stylesheet looked like : https://github.com/arbonagw/HeliumRain/blob/master/Source/HeliumRain/UI/Style/FlareWidgetStyleCatalog.h
Notice the struct + UObject container
And this is the styleset that actually interacts with Slate code : https://github.com/arbonagw/HeliumRain/blob/master/Source/HeliumRain/UI/Style/FlareStyleSet.h
And here is how the styleset is set up : https://github.com/arbonagw/HeliumRain/blob/master/Source/HeliumRain/Flare.cpp
After all of that setup is done, you can "just" do
SNew(SImage).Image(&Theme.SomeBrushHere)```
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:
๐
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
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
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
Want to use a UMG widget in Slate? Here's a nice little plugin that allows you to do so easily!
DOWNLOAD: https://kitatus.itch.io/umg-to-slate
โโโโโโโโโ
Like what weโre doing? Want to see more? Want to help others with cool projects, tutorials and more โ All for the price ...
for engine version 4.25
is this a plugin that just wraps SObjectWidget for you?
s
Hey! Before I dive into this and create from scratch. Do we have some hidden Date picker ready for usage in slate? Knows someone?
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)```
Icon(this, &FMyClass::Function)
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
@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.
it's not supposed to be 3d it's just a bunch of indepenant 2d views
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
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
it becomes easier with time but it's always a struggle imo. Or I'm doing something wrong ๐
@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
1.
I created a SlateWidgetStyleClass with a UProperty for the Brush according to your StyleCatalog.h
https://github.com/arbonagw/HeliumRain/blob/master/Source/HeliumRain/UI/Style/FlareWidgetStyleCatalog.h
I somehow cannot manage the line:
https://github.com/arbonagw/HeliumRain/blob/master/Source/HeliumRain/UI/Style/FlareWidgetStyleCatalog.cpp
in the .cpp file.
UFlareWidgetStyleCatalog::UFlareWidgetStyleCatalog(const class FObjectInitializer& PCIP)
: Super(PCIP)
{
}
is it necessary?
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.
3.
In https://github.com/arbonagw/HeliumRain/blob/master/Source/HeliumRain/UI/Style/FlareStyleSet.h#L15 you used ISlateStyle&, but when i try it on my StyleSet i get the following error:
4.
At my last problem is:
I'm totally lost at your https://github.com/arbonagw/HeliumRain/blob/master/Source/HeliumRain/Flare.cpp
FFlareStyleSet* FFlareModule::StyleInstance = NULL;
Needs a Module, so i have to create a new Module instead of FDefaultGameModuleImpl, because otherwise i won't be able to set a StyleInstance
- No
- Create a new styleset asset in content browser inheriting from UFlareWidgetStyleCatalog
- Does it inherit ? Is the method static ?
- Yes, needs a module implementation, check StartupModule for the style register
@quaint zealot
is there a specific StyleSet-class i can choose to generate / fix the problems in 2. and 3. ?
I used this to replicate your "FlareStyleSet.h"
In my code, FFlareStyleCatalog is what stores UPROPERTY asset elements ; and UFlareWidgetStyleCatalog is the Blueprint container for it
Which is a USlateWidgetStyleContainerBase
Maybe it's "Slate style" and not styleset
Ye i used SlateWidgetStyle to create the FMuesliSlateStyle
But thats the struct with the wrapper class
Then compile, open thne editor and you should be able to create instances of the UClass
Then you're good
Ye, but i can't drag and drop it to the viewport or to the level
And details also shows no Brush
Create a new asset
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;
};
You're confusing styles and stylesets.
Hell, just copy our files and change the names
https://github.com/arbonagw/HeliumRain/blob/master/Source/HeliumRain/UI/Style/FlareWidgetStyleCatalog.h
I thought this is a style
Ye, but to create a styleSet do i have to generate a style again? o.O
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
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
aaaah
now i understood
i thought the c++ class was the same option as the style
oooh
now i got it
https://discordapp.com/channels/187217643009212416/375021750393634826/712268321503838308
Now only 3. is left and then i try 4. again for myself if you still got the time and i'm not bugging you
3 is a pure C++ issue, just read carefully what the compiler log says
Great, i try my best :)
Thanks a lot again
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
Keep copying my code. Declare module in project.h, implement in project.cpp
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?
yup
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?
It has to be unregistered first for hot reload in editor IIRC
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
Check Flare.h, something's missing
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?
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 
Verweis = Reference
I also got those 2, but i read, that fixing LNK2019 fixes LNK1120
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
Sry, only familiar with Jetbrains products

but thanks for the hint
okay, can't find symbol "FCHECK" in method Shutdown
Ignore it
Okay, finally, how i can use all i did now in my SMainWidget.cpp ?
SNew(SBorder).BorderImage("I guess todo here")
Currently searching here
Basically get the style asset (called "theme" in HR code) and profit
const FMuesliSlateStyle& Theme = FMuesliStyleSet::GetDefaultTheme();
SNew(SBorder)
.BorderImage(Theme)
.BorderImage(&Theme.SomeSlateBrushHere)
SomeSlateBrushHere would be the UPROPERTY FSlateBrush
(HR means what btw? :o)
HeliumRain
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 :)
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
Yep, that's fine
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?
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
Check what GetDefaultTheme does ๐
return FMuesliStyleSet::Get().GetWidgetStyle<FMuesliSlateStyle>("/Style/MuesliStyle");
Something like GetStyle().GetWidgetStyle<T>("YourAssetNameInContentStyle");
See, that's correct
Ye, but somehow still not showing up what i want 
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'"
okay, i changed the name of the MuesliStyle-Asset to MuesliStyleAsset and changed that in the method
return FMuesliStyleSet::Get().GetWidgetStyle<FMuesliSlateStyle>("/Style/MuesliStyleAsset");
Drop the path
no need for that?
No support
FSlateGameResources::New is where you define the root path of all style assets for this styleset
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
return FMuesliStyleSet::Get().GetWidgetStyle<FMuesliSlateStyle>("MuesliStyleAsset");```
This is the only version that will work
Provided MuesliStyleAsset is under /Slate/ in your content folder
Don't i have to change the return type of the function to const FMuesliSlateStyle then?
Sure
wait, don't i have to change all "Instances" then too?
What ?
If i change the return type i shouldn't be able to call ```
Instance = Create();
Look
You don't need to touch anything about the style set ever
It's just a nice helper class to fetch style assets
Sigh
Ye i tried changing it according to your solution, but when i change the function return-type i cant use Instance=Create() anymore
return FMuesliStyleSet::Get().GetWidgetStyle<FMuesliSlateStyle>("MuesliStyleAsset");is not for Create
It's for GetDefaultTheme in HeliumRain and whatever it's called now
ooooh
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
so i can always adjust MuesliStyleSet.h and add different getters for different-themes.
Did i understood that correctly?
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?
Yes
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");
}```
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");```
I'll leave you to it now, think that was enough help ๐
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 
Couldn't find much and the tutorials i found used Blueprints x)
But ye, thanks a lot !

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
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
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
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
๐

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)
Use SBox with width/height override to resize a brush
I'll try, thanks :)
hmm, another question to understand what design choice would be better
Should i use a vertical box here?
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?
try SOverlay, and V-Box inside it
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)
]```
It is, but it's not exactly simple
What would you suggest instead?
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
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
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
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
.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
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
Works fine here.
Whats the compile error for SEditableText ?
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
" D:\Programming Projects\MUESLI\Source\MUESLI\Private\SMyWidget.cpp(99) : error C2653: "SEditableText": Keine Klasse oder Namespace
"
No class or namespace
Sounds like missing include then
I tried adding SlateEditableTextWidget because that was the only suggested include when i tipped in "Edit"
See, no include.
protip : https://docs.unrealengine.com/en-US/API/Runtime/Slate/Widgets/Input/SEditableTextBox/index.html tells you what to include
Editable text box widget
oooh
there it is
i thought all "input" widgets have the same include
just a collection of input widgets
great, thanks :)
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?
No that's not what SAssignNew does
wait, it's the other way around, isn't it?
I can assign my Widget to a variable
SAssignNew(WidgetPtr, Widget)
SAssignNew(MyWidget, SButton);```
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?
Yeah it does
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
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++
But yeah, #cpp or #blueprint
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
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
)
oh, nevermind
found the option :)

anyone know how to create an STreeView that starts recursively expanded by default?
Anyone know if you can using materials during loading screen?
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
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
how come theres a .Font if youre not supposed to style it? wierd
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
yeah ofc, but i want to learn how to do UI in code =P
Then I hope you are ready to rewrite every single basic widget
i absolutely am! but i cant find how to set the damn font XD
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
oh, i tought the Slate styleset was the blueprint thing UserInterface - Font
I had to explain this entire thing right here days ago so I suggest you re-read the entire discussion with distrustLP
allright
i think it got renamed to "SlateWidgetStyleAsset" or its not available to pick from-editor?
Is there a recommended way to save state with slate widgets? Specifically for editor widgets, not in-game
does anyone have experience with making tables in slate
looking to put one in my assets detail panel
IDetailCategory.AddWidget() doesn't exist anymore
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
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 :)
You're welcome !
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?
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
Thanks, i will try changing that :)
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
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
seems to be exclusively the s
probably it is font problem. try another
if i have a TSharedPtr<IPropertyHandle> that is for a UCurveFloat* property how do i unwrap it to get the asset
@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?

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
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.
Sounds like SRetainerWidget
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
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.
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
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!
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?
is it possible to add a button to toolbar, and use slate with Python?
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
SObjectPropertyEntryBox is the answer, in case someone finds this question.
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 
Maybe i did something wrong?
it looks like it only matches the middle color
i wanted to achieve a linear gradient like this one here
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.
Yeah, material would work fine here.
hey guys, is there some tutorial on creating a very basic and minimal window using Python?
Thanks for the help @craggy holly @quaint zealot :)
does anyone here have experience with the FFrameGrabber class ?
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?
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 :/
Not sure, but have you tried extending the Extension Hook name for JKelly Utilities rather than "WindowGlobalTabSpawners"?
@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
It's likely you'll need to get a reference to the other extender.
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
Also might be plugin order in loading. I believe there is a parameter in uprojects where you can specify required dependencies.
Uplugins*
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 ๐ฆ
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 ๐
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
it depends of your team. if they are mostly designers, better to make ui in umg. slate is better for programmers
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
Thanks for your thoughts. I was thinking the same.
Is there a way to edit an object with slate without having to create every property widget by hand?
you can create a details view
@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);
}
};```
@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
@quaint zealot it should go away when an FGCObject is destroyed
on next collection cycle
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
yeah I'm just showing how it can be done not saying UMG is an invalid tool
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
I use mostly UMG, slate mainly just to interoperate with some stuff from shootergame and even there embed umg into slate where possible
I'm really struggling to size things in Slate, is there anyway to have a button's size automatically fit the text inside? https://puu.sh/FUKw2/dcbd51cd56.png
@pastel phoenix Oh okay thank you ๐
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
Anyone know if there is a helper function to create property widget? I would like to add GameplayTagContainer to my custom table view
trying to do it like this but have linker issues about SGameplayTagWidget even when GameplayTagsEditor is added do build.cs
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
@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
https://puu.sh/FWzoi/3cd97eb806.png And this is how cramped it looks ๐
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
@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) ๐
horizontal and vertical boxes are definitely in UMG
wouldn't be able to do much without those...
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
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.
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
@gritty frigate I couldn't see anything obvious, did you try implementing the destructor?
Yeah, it didnโt like that!
I donโt actually need that any more, now that my slate class also subclasses FGCObject
Anyone know how to inherit farguments or if it is practical?
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
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.
@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
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
Heh I've been doing the same, but creating centralized style assets
How do you mean?
@gritty frigate I DMed you the details
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 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.
where did you find this?
I'm just guessing that's what's happening
my favourite kind of debugging: baseless speculation
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")) ]
did you use the widget reflector to investigate?
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);
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.
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
i see the nested SImage visually dip down and back up a couple pixels

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?
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
new test result: interestingly OnClicked_Static() is working, but my OnClicked_Lambda() continues fail silently.
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
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.

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 [&]
that's quite dangerous when you add the lambda to a delegate
That screwed me over recently - I passed a delegate to a lambda by reference and, then got confused why it called the wrong lambda!
capture weak ptrs by value and pin/check their validity
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...
ok, I managed to do it:
FChildren* children = ValueWidget->GetChildren();
TSharedPtr<SWidget> horizontalBox = children->GetChildAt(0);
TSharedPtr<SHorizontalBox> hb = StaticCastSharedPtr<SHorizontalBox>(horizontalBox);
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?
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.
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
Yes you can.
Oh okay, thank you. I'm still pretty new to Unreal. Trying to wrap my head around how slate works.
whole UE Editor made by Slate
@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
I think we're leaning towards c++. We're actually making a tool instead of a game. UMG does look a lot easier though
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
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.
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.
hi guys. any ideas how to get UWorld* in Slate widget? GEngine->GetWorld(); returning NULL
UGameplayStatics::PlaySound2D() need it
FSlateApplication::PlaySound ?
NewSound.SetResourceObject(/*USoundBase*/);
FSlateApplication::Get().PlaySound(NewSound);```
not fit, i'm playing USoundWaveProcedural
or...
it based on USoundBase
thank you, i'll try
Can you ensure that your Slate widget has a world context?
Slate widgets don't have a concept of a world context
They are entirely outside the UObject world
If you're wanting to do it in C++, UMG is horrible
I don't know, how worse than Slate is it really ? ๐
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
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
interesting. I had thought that UMG was just a way to get UI elements blueprintable
It's also that, but basically, creating a material instance for a button to use in Slate requires some serious boilerplate
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
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
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
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
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?
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.
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
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!
@pastel phoenix InputProcessor looks interesting, what's the typical use case for that?
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;
}```
@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;
}
@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
@pastel phoenix @coral schooner Thanks!
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
I rolled my own in the end, and didnโt discover MenuBuilder until it was too late, unfortunately
I started doing that but then saw menu builder lol
@civic pasture Is there a reason you're using Slate and not UMG? Is this for an editor plugin? I'm just curious
@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.
@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
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
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
Ah okay, I'll look into that
Widget Reflector has saved my arse on a number of occasions. I just wish you could see properties too!
Windows->DeveloperTools->WidgetRelector
I also found out that there are some slate example files under Engine\Source\Runtime\AppFramework\Private\Framework\Testing
@civic pasture Unreal is a monstrosity, but the code is clean and comparably easy to get into. If you think Unreal bad, try OpenMesh
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
If you ever try to use it, be aware that it does not support LeftHandedCoordinate systems
oh, that's lame
I have an altered version here: https://github.com/RumbleballTheReal/OpenMesh
Oh cool, thanks for the heads up
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?
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
look for transparency may be
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
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!
cool ๐
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?
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
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
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
make it not local variable, pass [this]
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
raw pointers are dangerous
only if you own them
you can avoid SAssignNew btw by TSharedPtr<SButton> myButton = SNew(SButton);
yeah
and .ToSharedRef() it
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
@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
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
@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.
@limpid atlas thats my general take on them. As I mentioned, in non UE4 code I try to be pretty good with pointers
@limpid atlas in what way do you think them unsafe?
@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.
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"?
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
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
It's definitely worth figuring out what's still referencing it then
Do you have any other references to it in your code?
Most likely it's what we were discussing above, you maybe capture the shared pointer in a lambda/delegate somewhere?
the whole code. no lambdas
i want to remove mTestWWidget->Stop();
because i can't call ->Stop(); here -
Can you put a breakpoint in your code for when it's removed and check the reference count?
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...
destructor is not called, debugged and logged
Right. Yeah SharedFromThis is the only thing I can think of that could cause it then, if there's no other code using mTestWidget
SharedFromThis seems is evil
It mostly is, yeah. But convenient sometimes...
i have an idea to set breakpoint inside it, and catch who referenced
SharedFromThis is a class or template. need to research
TSharedFromThis is a template class
Yeah, the method doing the conversion is either SharedThis or AsShared
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
But it could be awkward to isolate, I imagine it gets called a whole lot of times by general Slate code
and the winner is...
class SLATECORE_API SWidget
: public FSlateControlledConstruction,
public TSharedFromThis<SWidget> // Enables 'this->AsShared()'
All Slate widgets have that
it used in SWidget::Paint
it doesn't necessarily mean that AsShared or SharedThis is called
it is called in every paint of widget
It looks like that's only used on a local variable there
So it should be decremented at the end of every Paint() call
Is that the bit that's definitely incrementing your ref count?
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
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
I'm not sure, I'm afraid. This feels like it could be a huge rabbit hole!
๐ธ
nevermind, thanks for trying
When I call Invalidate() on a widget, what does that cause it to call to regenerate itself?
Separate question, has anyone ever come across an SCompoundWidget subclass which uses Slots?
but why
boxes have slots, they comes one after another, overlays have slots, they comes one on another
I'm trying to create a widget that is a tab panel. Buttons across the top, and a WidgetSwitcher below
Yeah I did that
make box
cool - how'd you put it together?
SHorizontalBox
I'd like to be able to do:
SNew( SMyTabPanel )
+SMyTabPanel::Slot()
.Label( LOCTEXT( "Label", "Label" )
[
// Content
]
+SMyTabPanel::Slot()
.Label( LOCTEXT( "Label2", "Label2" )
[
// Content
]```
Yeah I did just that, let me give you some boilerplate
Awesome ๐ thanks!
Might have a lot of missing stuff but the slot system is there
Including the .Label thing
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)
// 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++;
}```
Ah - I think I see where we might be doing this differently
Basically iterate the InArgs.Slots
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!
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
Sure
When TabPanel::AddSlot() is called, there isn't anything in the slot yet, though, so I can't do anything in that method
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(....)
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
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
My understanding is that the slot is a Slate widget in itself
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
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
@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.
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
I see. Then use TWeakPtr
yup, that certainly works. I think what @limpid atlas was getting at was that using TSharedPtr everywhere has issues
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
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
what is observer?
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
yeah thats true. The term "observer" only came up for me in Observer Pattern, until now
Although Bjarne Stroustrup wrote this recommending to abandon it and just use raw pointers: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1408r0.pdf
"I learned C++ at school, I'm a programmer" ... I once saw basically an essay about why to use size_t over unsigned int.
๐
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.
Yeah, thats definitely a problem. Not a memory leak, but a clear deadlock in clearing the memory. Never thought about that.
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
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
For this or just for other objects?
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;
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
๐๐ป
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.
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.
@gritty frigate what widget is it? I'd start by sniffing around in its OnPaint, looking at InWidgetStyle
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
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
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.
instantiate the slot outside
cache the raw ptr
and then you can refer to it later and keep adding to it, etc.
Righto, was hoping that wasn't the only way but I guess so.
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.
Hey, long time no see.
o7
Been hyper busy with personal life things - home ownership, flooding, the end of the world, that sort of stuff.
Sounds bad
Anyone know why UWidget doesn't have tick or anything else that have DeltaTime?
Doesn't need to, I guess
The underlying Slate widgets have tick already
UUSerWidget ticks IIRC
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 ๐
i don't think mouse will pass to something invisible
i think it will be passed to parent
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
]```
so the second layout worked @gritty frigate ?
that's interesting that on top didn't get passed through but nested did, thanks for sharing!
๐
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?
you could use FSlateApplication::Get().SetUserFocus(); on SEditableText, previously assigned to variable inside MyCompoundWidget
That's what I've done
But if I can, I'd like to hide that MyCompoundWidget has an SEditableText inside it
you can try to use OnFocusReceived
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
I remember looking hard for such an event and finding nothing at all
Iโve put something in tick to compare the current and previous geometry, but that feels horrible to me
you could always extend slate and add this event
Iโm not changing the engine, as this is a plugin that we need to be able to work with the engine as-is.
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?
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
Found it. I had missed a .FillRow() on the SGridPanel
@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
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.
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
Not sure what fixed it, but it's showing up now
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)
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 ?
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
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
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 :
And I have 2 assets of that class :
Not sure what that is about. Might be some UCLASS keyword. This might be better asked in #cpp
Sure, sorry, it's just that you seemed comfortable with it ๐
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
Isn't the dropdown showed above, an asset picker equivalent ?
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.
I see, thanks for the reply, about your trouble, I'm not quite sure to understand
it's fine, and no problem
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...
it's something very old that there's not much of a reason to use it now
just use UMG for game UI
lol yeah was just wondering if it was one of those magical hidden things in the engine
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 ๐
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
^ 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 ๐คฆ
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
Update on above: calling DrawWidget twice fixes it. Seems like a massive massive ridiculous hack but I guess it'll do for now lol
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.
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 result is basically this https://cdn.discordapp.com/attachments/221799439008923648/742530937497321522/UMGjump1.mp4
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
