#slate
1 messages · Page 26 of 1
make sure there is no implicit cast for outputPin or folderPath. I would try this
FString folderPath = ...; // store them on explicit variables
EDialogResult outputPin = ...;
// more code
.OnClicked_Raw(this, &FC2MModule::OpenDirectoryDialog, outputPin, folderPath)
implicit casts don't work here.
EDialogResult isSuccesful = EDialogResult::Cancelled;
FString folderPath = TEXT("");```
Is TEXT(""); not correct for FString?
that does not matter for code compliation.
ok so there's no implicit cast
I also tried running that function without slate and it worked
so I don't think it's the parameters' type
error C2664: 'SButton::FArguments::WidgetArgsType &SButton::FArguments::OnClicked_Raw<FC2MModule,EDialogResult,FString>(UserClass *,FReply (__cdecl FC2MModule::* )(Var1Type,Var2Type),Var1Type,Var2Type)': cannot convert argument 2 from 'FReply (__cdecl FC2MModule::* )(EDialogResult &,FString &,const FString &,const FString &)' to 'FReply (__cdecl FC2MModule::* )(Var1Type,Var2Type)'
wait, does it want me to give 4 arguments even though 2 of them ahve defaults?
lemme check that
C2M.cpp(92): [C2664] 'SButton::FArguments::WidgetArgsType &SButton::FArguments::OnClicked_Raw<FC2MModule,EDialogResult,FString,FString,FString>(UserClass *,FReply (__cdecl FC2MModule::* )(Var1Type,Var2Type,Var3Type,Var4Type),Var1Type,Var2Type,Var3Type,Var4Type)': cannot convert argument 2 from 'FReply (__cdecl FC2MModule::* )(EDialogResult &,FString &,const FString &,const FString &)' to 'FReply (__cdecl FC2MModule::* )(Var1Type,Var2Type,Var3Type,Var4Type)'
nah that wasnt it
try const function.
FReply OpenDirectoryDialog(
EDialogResult& OutputPin,
FString& FolderPath,
//...
) const;
notice the const at end. you must put this const in both header and cpp.
same error
it keeps saying
cannot convert argument 2 from 'FReply (__cdecl FC2MModule::* )(EDialogResult &,FString &,const FString &,const FString &)' to 'FReply (__cdecl FC2MModule::* )(Var1Type,Var2Type)'
where does const FString & come from?!
FReply OpenDirectoryDialog(
EDialogResult& OutputPin,
FString& FolderPath,
const FString& DialogTitle = TEXT("Open Directory Dialog"),
const FString& DefaultPath = TEXT("C:/")
);```
I tried completely removing both and staying with just outputPin & folderPath
still the same error
cannot convert argument 2 from 'FReply (__cdecl FC2MModule::* )(EDialogResult &,FString &)' to 'FReply (__cdecl FC2MModule::* )(Var1Type,Var2Type)'
FReply OpenDirectoryDialog(EDialogResult& OutputPin, FString& FolderPath) const;
oh I had const there, I just removed it now for testing
same error with it
FReply OpenDirectoryDialog(
EDialogResult& OutputPin,
FString& FolderPath
) const;```
```cpp
FReply FC2MModule::OpenDirectoryDialog(
EDialogResult& OutputPin,
FString& FolderPath
) const
{
//ウィンドウハンドルを取得
void* windowHandle = FC2MModule::GetWindowHandle();
if (windowHandle)
{
IDesktopPlatform* desktopPlatform = FDesktopPlatformModule::Get();
if (desktopPlatform)
{
//ダイアログを開く
bool result = desktopPlatform->OpenDirectoryDialog(
windowHandle,
TEXT("Open Directory Dialog"),
TEXT("C:/"),
FolderPath
);
if (result)
{
//相対パスを絶対パスに変換
FolderPath = FPaths::ConvertRelativePathToFull(FolderPath);
UE_LOG(LogTemp, Log, TEXT("Acquired folder path : %s"), *FolderPath);
UE_LOG(LogTemp, Log, TEXT("Open Directory Dialog : Successful"));
OutputPin = EDialogResult::Successful;
return FReply::Handled();
}
}
}
UE_LOG(LogTemp, Log, TEXT("Open Directory Dialog : Cancelled"));
OutputPin = EDialogResult::Cancelled;
return FReply::Unhandled();
}```
forward declare EDialogResult.
in your header
can you show me the EDialogResult enum?
same error, unless I did not do it right
h - enum class EDialogResult : uint8;
cpp
enum class EDialogResult : uint8
{
Successful, Cancelled
};```
try including header for this enum in your module header
it seems enums can't be forward declared.
I have this in my module header, or is it not what u mean enum class EDialogResult : uint8;
yeah, that's what I had in mind, but it didn't work so I would try including the header instead.
something like #include "DialogResult.h"; in your module header
its part of my plugin module header, which already is included
enum should come before OpenDirectoryDialog
it does
Ok, try removing the &. so don't pass variables by reference. I know that breaks your logic but just to see if it compiles
FReply OpenDirectoryDialog(EDialogResult OutputPin, FString FolderPath);
I just tried removing the EDialogResult argument so we're left with just folderPath, just to see if the issue is EDialogResult and it still doesn't work
cannot convert argument 2 from 'FReply (__cdecl FC2MModule::* )(FString &)' to 'FReply (__cdecl FC2MModule::* )(Var1Type)'
ok, remove the &.
you can remove the const too I think.
apparently you can not pass variables by reference on to slate events.
thank you so much ❤️
A work around would be to declare your variables on the class.
If I want a Details panel which implements a property for assets, for example mesh or a camera. Do I have to look into engine code?
Didn't saw anything in the docs, besides SAssetProperty... Does it matter?
I've created a template Editor popup Window Plugin. I've created a function in this plugin that prints something on screen. I've added an EditableText to my popup window and I want it to call my Print function when OnTextCommited
It seems that the callable function must have certain input parameters like
void FTraceDebugWindowModule::DoSomething(const FText& InText, ETextCommit::Type InCommitType)
my editable text
+SVerticalBox::Slot().HAlign(HAlign_Left)
[
SNew(SEditableText)
.OnTextCommitted(this, &FTraceDebugWindowModule::DoSomething)
]
I get this error
changed to OnTextCommited_Raw and now it works
Hey guys, what’s the best way to GetWorld in a slate class?
GEngine might work?
I’m trying GEngine->GetWorld() but it doesn’t seem to work
Not sure then, I can look later
Thanks
If I call TakeWidget on a UUserWidget how do I get back to the UUserWidget from the resulting SWidget?
Ah I see, if TakeWidget is called on a UUserWidget its wrapped in a SObjectWidget which holds onto the UUserWidget.
🦆
Thanks.
posted this earlier on cpp, with no reply, trying here now.
#cpp message
Hi. If I have a UPROPERTY as an Array of a struct, and only one element of the struct is editable, and the others are transient, can I make it so the struct presents as the widget for the only editable type it contains?
Basically I just want to customize the property editor a little bit.
Ah shit I swear there is a way of doing this
It's one of those undocumented UPROPERTY meta props
figures, it seems like it could just be the default if there's only one property.
but, that's what I'm hoping for. It'd be a lot simpler than having to customize an array property.
You could make a custom editor for it. It'd be a pain in the ass but a good learning experience heh
Just found "meta TitleProperty", and a possible place with the answer, but I'm still waiting on my UDN access =\
That link doesn't work since they re-did UDN earlier this year, and I can't find a question on the new UDN with the same subject
Has anyone ever used the STextComboBox ? Although I can get it to populate from an options source, when I click to open the widget the editor crashes, with an EXCEPTION_ACCESS_VIOLATION. The strings added as content are stored to shared pointers.
Where it does it crash
the moment the box is clicked.
Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x0000000000000019
UE4Editor_Slate!SListView<TSharedPtr<FString,0> >::ScrollIntoView() [D:\Build\++UE4\Sync\Engine\Source\Runtime\Slate\Public\Widgets\Views\SListView.h:1714]
UE4Editor_Slate!STableViewBase::Tick() [D:\Build\++UE4\Sync\Engine\Source\Runtime\Slate\Private\Widgets\Views\STableViewBase.cpp:254]
UE4Editor_SlateCore!SWidget::Paint() [D:\Build\++UE4\Sync\Engine\Source\Runtime\SlateCore\Private\Widgets\SWidget.cpp:1285]
UE4Editor_Slate!SBox::OnPaint() [D:\Build\++UE4\Sync\Engine\Source\Runtime\Slate\Private\Widgets\Layout\SBox.cpp:293]
UE4Editor_SlateCore!SWidget::Paint() [D:\Build\++UE4\Sync\Engine\Source\Runtime\SlateCore\Private\Widgets\SWidget.cpp:1390]
UE4Editor_SlateCore!SCompoundWidget::OnPaint() [D:\Build\++UE4\Sync\Engine\Source\Runtime\SlateCore\Private\Widgets\SCompoundWidget.cpp:35]
UE4Editor_Slate!SBorder::OnPaint() [D:\Build\++UE4\Sync\Engine\Source\Runtime\Slate\Private\Widgets\Layout\SBorder.cpp:120]
UE4Editor_SlateCore!SWidget::Paint() [D:\Build\++UE4\Sync\Engine\Source\Runtime\SlateCore\Private\Widgets\SWidget.cpp:1390]
UE4Editor_SlateCore!FSlateWindowElementList::FDeferredPaint::ExecutePaint() [D:\Build\++UE4\Sync\Engine\Source\Runtime\SlateCore\Private\Rendering\DrawElements.cpp:735]
UE4Editor_SlateCore!FSlateWindowElementList::PaintDeferred() [D:\Build\++UE4\Sync\Engine\Source\Runtime\SlateCore\Private\Rendering\DrawElements.cpp:760]
UE4Editor_SlateCore!SWindow::PaintWindow() [D:\Build\++UE4\Sync\Engine\Source\Runtime\SlateCore\Private\Widgets\SWindow.cpp:2107]
here a part of the call stack
I am adding the options to the cbox like this
TArray<TSharedPtr<FString>> Options;
Options.Add(MakeShareable(new FString("Option1")));
Options.Add(MakeShareable(new FString("Option2")));
SAssignNew(CBox, STextComboBox)
.OptionsSource(&Options)
I guess Options is just a local variable and so is destroyed along with its content as soon as the method exits
oh I see, so I need to cache it
It seems like STextComboBox wants a pointer to the string options and doesn't copy the data over (would need to look inside the source of STextComboBox to make sure), so yes, you need to hold onto the data
Anybody know how to create a Struct customisation, that also retains the customisations of internal properties?
I'm customising a struct and adding an FText property, but it's losing all of the FTextCustomisation
And unfortunately the internal types it uses to do the customisation aren't exposed
You'd think CreatePropertyValueWidget(true) would handle this :/
This surprises me. Can you add a flinearcolor to see if that also loses customization? I believe I did something like this before but it simply worked
Yeah sure
FLinearColour shows nothing at all
It's just blank
Feels like a bug or a massive oversight really.
Hey guys, I am trying to call a function from my game instance when I click a button. Calling GEngine->GetWorld()->GetGameInstance() always returns null since slate doesn’t have a world. Any ideas how I should go about this?
Pass an UObject to your UI and store it as a TWeakPtr
Do you know of a good website or video that has an example of doing this?
No I don't
Slate isn't meant for game development anyway
Look at the editor source for Slate examples
Does DetailsCustomization just not work for instanced objects?
Hmmm Im pretty sure I've done that in the past?
I think the StyleSheet properties stuff here is Instanced
https://github.com/BraceYourselfGames/UE4-BYGRichText
return SNew(SDockTab)
.TabRole(ETabRole::PanelTab)
[
// Put your tab content here!
SNew(SBox)
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
[
SNew(SButton)
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
.ButtonColorAndOpacity(FLinearColor::White)
.ContentPadding(FMargin(12, 4))
.OnClicked_Raw(this, &FC2MModule::OpenDirectoryDialog, importDirName, FString ("Open C2M Directory"), FString ("C:\\"))
]
SNew(SBox)
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
];```
why is my sbox not working
Which SBox and what do you mean not working?
Thanks for that. It doesn't look like it's using the Instanced markup, but doing it manually.
I also found that while it works for an instance (I tested with a light component) placed in a map, it didn't seem to work for an Instanced one is a random data asset. I wonder if it working there is a similar thing where it would work within the UMG details panel but not in a data asset details. I'll have to keep messing with it.
The second one doesn't have any content from what I can see so it would make sense that it's not showing anything
it wont even compile
as u see in image it gives error
There's no image with an error as far as I can tell. It's hard to help debug.
I think your second SBox needs content in [ ] like your first one.
Yep, needs content. For debugging purposes adding SNullWidget::NullWidget works fine
Also there are two SBoxes in the content of the SDockTab. You can’t add multiple children like that - you need to use a widget with slots for multiple children (SOverlay if you want them on top of each other)
TBH, I’m also going to disagree with @mild oracle and @split laurel here - I’m pretty sure that leaving out the content is fine - it should at least compile. Your issue is the two SBoxes not the missing content in the second
I just did a quick test - there is no compile error for having an SBox without content
Huh, didn't look too closely. You are absolutely right. Unless it's a container, you get exactly one slot
In the example you gave, @frosty prawn, if you wanted one over the other using an SOverlay, you'd want to do:
SNew(SDockTab)
.TabRole(ETabRole::PanelTab)
[
SNew(SOverlay)
+SOverlay::Slot()
[
SNew(SBox)
// All the rest of the gubbins from the first SBox
]
+SOverlay::Slot()
[
SNew(SBox)
// All the rest of the gubbins from the second SBox
]
]```
Also, if you look in DeclarativeSyntaxSupport.h, line 407 (on 4.26), where TAlwaysValidWidget is defined, you'll see that it defaults to SNullWidget, so leaving the content empty is the same as adding an SNullWidget
@gritty frigate Thank you!!
You're welcome. One thing to remember with Slate is that there are 3 types of widget:
- No children
- Single child (add [] directly to the widget, like SDockTab in your example)
- Container (add slots with +SWidgetType::Slot() and then add [] to each slot, like SOverlay)
works flawlessly, thanks alot guys ❤️
what is the alternative to SDockTab to get a window like this that has no tabs and the size of the window cannot be adjusted?
unfortunately it doesn't work well with widget reflector (info about it disappears as soon as window closes)
That is an SWindow IIRC
IIRC that widget is in FbxImportUIDetails
FbxMainImport.cpp line 256 in UE 4.25
That's where it creates the Modal Window
Then FSlateApplication::Get().AddModalWindow()
found in 4.27, thanks! 🙂
In any widget that overrides OnPaint, my understanding was that you had to increment LayerId for every draw call you make.
I was looking at SImage::OnPaint(), and I noticed that they don't do this in there - they pass LayerId through to FSlateDrawElement::MakeBox(), and then return the same one that they were given.
Is this an oversight in SImage, or have I misunderstood something?
I am trying to set the style of an STextComboBox. However the downArrow image does not seem to set up correctly, I would say is not set at all. Any ideas on solving this ?
here the code for the style:
CustomStyleSet->Set("CBoxBranches", FComboButtonStyle()
.SetDownArrowImage(BOX_BRUSH(TEXT("branch_64-64"), Icon24x24)));
code for the actual ComboBox
SAssignNew(BranchesCBox, STextComboBox)
.ComboBoxStyle(CustomStyle::Get(), "CBoxBranches")
.OptionsSource(&BranchesCBoxContent)
.OnSelectionChanged(this, &SpecPanel::OnBranchesDropdownChanged)
hey guys, I have this basic window that lets a user select folder, and I'm trying to get the selected folder to the editable textbox. how do I make it update with the selected folder?
return SNew(SWindow)
.SizingRule(ESizingRule::Autosized)
.AutoCenter(EAutoCenter::None)
.ClientSize(C2MImportWindowSize)
.ScreenPosition(WindowPosition)
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(3.0f, 1.0f)
[
// Put your tab content here!
SNew(SBox)
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
.WidthOverride(400)
.HeightOverride(40)
[
SNew(SButton)
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
.ButtonColorAndOpacity(FLinearColor::White)
.ContentPadding(FMargin(12, 4))
.Text(FText::FromString("Load Directory"))
.OnClicked_Raw(this, &FC2MImportUI::OpenDirectoryDialog, folderPath, FString ("Open C2M Directory"), FString ("C:\\"))
]
]
+ SVerticalBox::Slot()
.VAlign(VAlign_Center)
.HAlign(HAlign_Left)
.AutoHeight()
[
SNew(SBox)
.WidthOverride(200)
[
SNew(SHorizontalBox)
+SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SBox)
.WidthOverride(300)
[
SAssignNew(importPathBox, SEditableTextBox)
.BackgroundColor(FSlateColor(FLinearColor(FColor::White)))
.Text(FText::FromString(folderPath))
]
]
]
]
];```
FString folderPath = "<default path>";
Either you create a delegate for the text field so it executes a function each frame to determine the path text, or, if it exists, you need to register to a delegate of the directory window that is executed whenever folder selection changes, and then manually update the text via importPathBox->SetText or the likes
If it's a modal/blocking window you might also be able to retrieve the new path from results and then just update it manually
Hi, can anybody point me to a way to add a localizable FText on a details customization panel?
The simple handle exposure with IPropertyHandle seems not to expose the localizable window with the down arrow that can be seen with the default UPROPERTY(EditAnywhere) specifier.
I can see that the source code mentions TSharedRef<IEditableTextProperty> EditableTextProperty = MakeShareable(new FEditableTextPropertyHandle(Handle, CachedDetailBuilder->GetPropertyUtilities())); but FEditableTextPropertyHandle is in an anonymous namespace so it is not accessible from outside its own file which leads me to think there is another way to do this.
I would also love to know this!
Hello guys!! Maybe someone knows how can i handle Ctrl+C Ctrl+V in my slate widget??
Hi, please specify what this text will be used for ??
And why you can't use LOCTEXT macro
Excuse my ignorance, Im a beginner, but do you mean a get function to the importPath string?
even then how do I make it execute the get function every time the import dialog selects a file? I need to update the textbox to have the path in it
essentially yes.
Slate attributes (attributes as opposed to arguments) can either contain direct values or delegates. In your example you are setting the text directly by simply giving it a text value.
You can however also instead use the following as an argument
.Text(this, &MyClass::FunctionWithReturnFText)
will it update everytime I select a new path?
this will call the function every frame to determine the file path as text
you'd need to get the file path yourself
the alternative is to check what the directory window is giving you yourself
I have a button that opens a file dialog and sends the selected path back to FString var
and Im creating a get func that returns that var as FText
yep that should work
I will test that soon, thanks a lot mate!
sure! Slate is not well covered online and there is a lot of trial & error involved in first learning it
@split laurel Hey mate, I tried what you said now and I'm not sure why it won't compile.
cpp-
return SNew(SWindow)
.SizingRule(ESizingRule::Autosized)
.AutoCenter(EAutoCenter::None)
.ClientSize(C2MImportWindowSize)
.ScreenPosition(WindowPosition)
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(3.0f, 1.0f)
[
// Put your tab content here!
SNew(SBox)
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
.WidthOverride(400)
.HeightOverride(40)
[
SNew(SButton)
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
.ButtonColorAndOpacity(FLinearColor::White)
.ContentPadding(FMargin(12, 4))
.Text(FText::FromString("Load Directory"))
.OnClicked_Raw(this, &FC2MImportUI::OpenDirectoryDialog, folderPath, FString ("Open C2M Directory"), FString ("C:\\"))
]
]
+ SVerticalBox::Slot()
.VAlign(VAlign_Center)
.HAlign(HAlign_Left)
.AutoHeight()
[
SNew(SBox)
.WidthOverride(200)
[
SNew(SHorizontalBox)
+SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SEditableTextBox)
.BackgroundColor(FSlateColor(FLinearColor(FColor::White)))
.Text(this, &FC2MImportUI::GetMyText)
]
]
]
];
}
FText FC2MImportUI::GetMyText() const
{
return FText::FromString(folderPath);
}```
header
```hpp
FString folderPath = "<default path>";
FText GetMyText() const;```
I'll show u the error in 1 moment
Chances are your FCM2ImportUI class doesn't inherit from TSharedFromThis<FCM2ImportUI> is that right?
this is my class -
class FC2MImportUI : public IModuleInterface
{
public:
static void* GetWindowHandle();
enum class EDialogResult : uint8
{
Successful, Cancelled
};
FReply OpenDirectoryDialog(
FString FolderPath,
FString DialogTitle = TEXT("Window Title"),
FString DefaultPath = TEXT("C:/")
);
TSharedRef<class SDockTab> OnSpawnPluginTab(const class FSpawnTabArgs& SpawnTabArgs);
FText GetMyText() const;
TSharedRef<class SWindow> CreateC2MImportWindow();
FString folderPath = "<default path>";
private:
};
yep, can't by default create shared ptrs from that class
I'm not so sure what that means 
It means your class is not setup to be used as a shared pointer. You can probably find online how to do that. Or look at source code of classes that support it.
you can either additionally inherit from TSharedFromThis<FCM2ImportUI> (although I'm not sure if that's a good idea with a module), or you can just create one by using other means. CreateRaw would work for example
wait a sec
I know how to make it use inherit fromTSharedFromThis<FCM2ImportUI>, but what if I need to inherit from IModuleInterface?
you can inherit from both
as an example, the reason why this works by default from inside widgets is because SWidget is defined as shown here. No need to set that inheritance up
oh ok I see now
so in my case it would be class FC2MImportUI : public IModuleInterface, public TSharedFromThis<FC2MImportUI>
alternatively
TAttribute<FText> TextAttribute = TAttribute<FText>::CreateRaw<>(this, &SNiagaraSystemEffectTypeBar::GetText);
PropertyWidget = SNew(STextBlock).Text(TextAttribute);
works as well
same pattern applies for you, just renamed classes and functions
yep, but I wouldn't do that, because sharedptrs are meant to manage lifetime of an object and doing this with module could have unwanted sideeffects
CreateRaw is quite safe here because the lifetime of your module is pretty much not an issue whatsoever
doesn't seem like there's TAttribute<FText>::CreateRaw<>
which version are you using?
only TAttribute<FText>::Create, which teakes FName instead of FText
of unreal? 4.27
yep. I was on ue5 right now. Let me check 4.27 source
but in any case, the process should be similar, but I don't know about that FName one
the Create function is overloaded, you should be able to do the same
I changed my gettext function to return FName and tried using it with Create, but it gives me this
yeah that's not going to help, the FName one is for calling UFunctions via reflection I believe. TAttribute<FText> directly means the function you bind to it returns an FText
have you tried doing my code sample above just with Create instead of CreateRaw<>?
yeah it won't work because &FC2MImportUI::GetMyText is FText and Create expects FName
I don't think that's quite right but okay, then do this
TAttribute<FText> TextAttribute = TAttribute<FText>::Create<>(this, &FC2MImportUI::GetMyText);
TAttribute<FText> TextAttribute;
TextAttribute.BindRaw(this, &FCM2ImportUI::GetMyText);
the static Create functions are just there to help with creation, binding on an existing attribute should be the same
ok it builds and works, now I need to make the textbox update everytime the import dialog is used via the button
return SNew(SWindow)
.SizingRule(ESizingRule::Autosized)
.AutoCenter(EAutoCenter::None)
.ClientSize(C2MImportWindowSize)
.ScreenPosition(WindowPosition)
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(3.0f, 1.0f)
[
// Put your tab content here!
SNew(SBox)
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
.WidthOverride(400)
.HeightOverride(40)
[
SNew(SButton)
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
.ButtonColorAndOpacity(FLinearColor::White)
.ContentPadding(FMargin(12, 4))
.Text(FText::FromString("Load Directory"))
.OnClicked_Raw(this, &FC2MImportUI::OpenDirectoryDialog, folderPath, FString ("Open C2M Directory"), FString ("C:\\"))
]
]
+ SVerticalBox::Slot()
.VAlign(VAlign_Center)
.HAlign(HAlign_Left)
.AutoHeight()
[
SNew(SBox)
.WidthOverride(200)
[
SNew(SHorizontalBox)
+SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SBox)
.WidthOverride(300)
[
SAssignNew(importPathBox, SEditableTextBox)
.BackgroundColor(FSlateColor(FLinearColor(FColor::White)))
.Text(TextAttribute)
]
]
]
]
];```
here's how it currently looks like
looking good. Is your text attribute simply returning folderPath?
If so you only need to update folderPath when the user has selected a directory. So something like:
void FCM2ImportUI::OnDirectoryChosen(FString Path)
{
folderPath = Path;
};
that's it. The text will automatically update then
you see OpenDirectoryDialog function inside the button
that one takes folderPath and updates it
does it actually update the original folderPath variable though? Because if so the text should automatically update as well
can you show me the OpenDirectoryDialog function?
Reply FC2MImportUI::OpenDirectoryDialog(
FString FolderPath,
FString DialogTitle,
FString DefaultPath
)
{
void* windowHandle = GetWindowHandle();
EDialogResult OutputPin = EDialogResult::Cancelled;
if (windowHandle)
{
IDesktopPlatform* desktopPlatform = FDesktopPlatformModule::Get();
if (desktopPlatform)
{
bool result = desktopPlatform->OpenDirectoryDialog(
windowHandle,
DialogTitle,
DefaultPath,
FolderPath
);
if (result)
{
FolderPath = FPaths::ConvertRelativePathToFull(FolderPath);
UE_LOG(LogTemp, Log, TEXT("Acquired folder path : %s"), *FolderPath);
UE_LOG(LogTemp, Log, TEXT("Open Directory Dialog : Successful"));
OutputPin = EDialogResult::Successful;
return FReply::Handled();
}
}
}
UE_LOG(LogTemp, Log, TEXT("Open Directory Dialog : Cancelled"));
OutputPin = EDialogResult::Cancelled;
return FReply::Unhandled();
}```
as u can see in my .OnClicked_Raw, folderPath is the first variable (FolderPath inside the dialog function)
and its the same variable that GetMyText returns as FText
ah yes, you are not properly updating the original though. Your parameter is given by value, not by reference, so the update inside the if (result) will be lost
change the signature to
Reply FC2MImportUI::OpenDirectoryDialog(
FString& FolderPath,
FString DialogTitle,
FString DefaultPath
and it should work
you could also just write to folderPath directly
I didnt do that so I can use that function for other dialogs/values
makes sense, then the reference version is the one you should use
as soon as I changed FString FolderPath to FString& FolderPath, it won't take accept folderPath anymore
what's the error? Also use the output tab instead of the error list
Error C2664 : 'SButton::FArguments::WidgetArgsType &SButton::FArguments::OnClicked_Raw<FC2MImportUI,FString,FString,FString>(UserClass *,FReply (__cdecl FC2MImportUI::* )(Var1Type,Var2Type,Var3Type),Var1Type,Var2Type,Var3Type)': cannot convert argument 2 from 'FReply (__cdecl FC2MImportUI::* )(FString &,FString,FString)' to 'FReply (__cdecl FC2MImportUI::* )(Var1Type,Var2Type,Var3Type)'```
mhhh not entirely sure. Have you changed the signature in both header and cpp?
folderPath is FString
yeah
FReply OpenDirectoryDialog(
FString& FolderPath,
FString DialogTitle = TEXT("Window Title"),
FString DefaultPath = TEXT("C:/")
);```
.OnClicked_Raw(this, &FC2MImportUI::OpenDirectoryDialog, folderPath, FString ("Open C2M Directory"), FString ("C:\\"))
let me try something out real quick
I know a couple ways to go around this but I'd like to know why exactly this isn't working. Perhaps you can't use references with raw delegates because it can't be ensured that the reference will still be valid later
seems references just generally don't work with delegates using variadic arguments. Ok
in that case you can probably do it via pointer instead
so
FReply OpenDirectoryDialog(
FString* FolderPath,
FString DialogTitle = TEXT("Window Title"),
FString DefaultPath = TEXT("C:/")
);
and
.OnClicked_Raw(this, &FC2MImportUI::OpenDirectoryDialog, &folderPath, FString ("Open C2M Directory"), FString ("C:\\"))
put a * in front of that
oh f me
desktopPlatform->OpenDirectoryDialogdoesn't want a a pointer but a value, so we dereference the pointer again
❤️
We're having a really weird crash on SWidget::AssignIndices called from FSlateInvalidationRoot::BuildFastPathList... Has anyone seen this?
Really grasping at straws here
Is there some way to intercept all mouse down/touch events from bp or cpp? If so can somebody point me in the right direction?
Basically I want to know where I would put this code
okay... idk why that is the case... but when i have a leaf widget, and that leaf widget creates draw elements... it looks like those wont get cleaned up causing a memory leak...
is there something i have missed?
Not sure but I would suggest looking at the engine code base to find any examples of leaf widgets. Check what kind of cleanup they do
they kinda do none... at least i cant find anything
Hmm. Slate stuff is part of regular C++ afaik in that it's not garbage collected.
Maybe set a breakpoint in a slate class's destructor to see where it's called?
Hello, I'm trying to make a function that sets and returns SHorizontalBox, so I can add it using SAssignNew(), but it doesn't seem to do anything..
here's the function
TSharedPtr<SHorizontalBox> SC2MOptionsWindow::AddNewLine(FText InKey, FText InValue)
{
return SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.AutoWidth()
[
SNew(STextBlock)
.Font(FEditorStyle::GetFontStyle("CurveEd.LabelFont"))
.Text(InKey)
]
+SHorizontalBox::Slot()
.Padding(5, 0, 0, 0)
.AutoWidth()
.VAlign(VAlign_Center)
[
SNew(STextBlock)
.Font(FEditorStyle::GetFontStyle("CurveEd.InfoFont"))
.Text(InValue)
];
}```
here's how I add it
TSharedPtr<SBox> ImportMapHeaderDisplay;
TSharedPtr<SHorizontalBox> TestBox = SC2MOptionsWindow::AddNewLine(FText::FromString("asd"),FText::FromString("qwe"));
ImportMapHeaderDisplay->SetContent(
SNew(SBorder)
.Padding(FMargin(3))
.BorderImage(FEditorStyle::GetBrush("ToolPanel.GroupBorder"))
[
// Add map name to our info display
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
[
SAssignNew(TestBox, SHorizontalBox)
]
]
);```
it works if I dont use the function and just add it the way I do inside the function, but I wanna avoid copy pasting the same few lines for each line I add
SNew doesn't return anything
Try SAssignNew with a temporary shared ptr to return
And I mean, no, that should work but the SAssignNew(TestBox, SHorizontalBox) line is just wrong
You're literally erasing the function's result here
^
to add to that, if you have a sharedptr to a valid widget already and just want to put into a slot it looks like this:
// Add map name to our info display
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
[
TestBox.ToSharedRef()
]
TestBox.ToSharedRef() does the job, thanks!
yeah I just looked at it again and it made no sense haha
does anyone here have any recent examples of using SMeshWidget?
Is it possible to use SNew and construct your widgets from a UUserWidget?
Does anyone know how I can access the slot offset properties of a UImage from c++? I have a base class already, I just can't seem to find the property to change it
Those are properties on the canvas panel slot, not the Image.
You’d need to call CanvasPanel->AddSlot() with the SImage as a child and store the returned slot
Interesting, I’ll give that a try, thank you!
How do I implement a custom Graph Panel? I made my own SCustomGraphPanel and SCustomGraphEditor but I'm not able to use the graph panel. I'm using the custom graph editor which has a function called GetGraphPanel() which doesn't seem to be called anywhere (I put breakpoint and it never hit after opening the graph editor). It seems SGraphEditorImpl implements graph panel but it is created in a private function which I cannot override.
Most of the useful stuff seems to be locked behind private scope
It might be worth checking out Generic Graph - https://github.com/jinyuliao/GenericGraph - It's pretty much as close to bare minimum implementation of a Custom Graph Editor derived from Behavior Tree Graphs. @wild pumice
How can I just fill with color?
I just want to fill entire overlay slot with white color
SColorBlock
use SBorder maybe?
Also good. Thank you. Prolly SColorBlock works for me
Thank you. I've seen it but there is no custom graph panel implementation in there.
I am trying to get an SScaleBox to not scale larger than the desired size of its content.
I am using .Stretch(EStretch::ScaleToFit)
SButton
[
SNew(SScaleBox)
.Stretch(EStretch::ScaleToFit)
[
.SNew(STextBlock)
]
]
In UMG the default behaviour of these appears different.
With this slate code what happens is that scale box takes up the entire size of the button its in
And the text scales with the scalebox. So a big button results in massive text
This is the default UMG behaviour
this is the slate behaviour
I tried a bunch of different stretch options but whatever the magic combination is that makes it work, I have not yet found it
haven't looked into it but can you change alignment of the SScaleBox to be center? Think it defaults to fill so the scale box will attempt to fill its parent rather than just letting its children elements dictate its size
yeah I tried setting the HAlign and VAlign to center previously.
I think I can delete my own question since I ended up just throwing up my hands and using UMG
no point in deleting, it might be of use to anyone coming across :)
UMG just wraps around Slate though so there is a solution to this problem
completely unrelated, but do you happen to be one of the wizards that understands editor slate?
that's what slate is for so yes I guess so. I do work with it daily
I dont think there is a seperate place for editor slate questions so I guess I might as well ask here.
Do you happen to know if it possible (and roughly how) to have an extra sub group in the details panel of an array of structs? I tried messing around with IDetailBuilder and some other but couldnt make it work at all. That stuff is just slate wrappers right?
I'm curious though, how did you create the 2nd video showcasing the slate behavior? Did you expose that widget to UMG to create it?
the second video is using a duplicate class of UButton
since a few members that I needed access to where protected I decided to just duplicate the UButton.h/cpp in its entirety and add the changes there
I understand
basically you want to insert some widgets between array entries? That's definitely more advanced than the typical details customization needs.
You might be able to do this using an FDetailArrayBuilder subclass
the DetailBuilder accepts multiple ways of customizing property UI, one of them is via a custom builder.
An example can be found in FNiagaraDataInterfaceSkeletalMeshDetails.cpp where the array builder is instantiated and registered, and then the FNiagaraDetailSourcedArrayBuilder
right so basically.
DetailView
-> Struct
-> Array of Structs
-> (0)
-> Value one
-> Value two
-> Some sort of group indent so I can group values, like the way category drop downs work
-> Some other values
Do you happen to know of the top of your head where that is used so I can look at the generated UI in the editor and see if that is what I am after?
I am kinda just theorizing that the names I use to describe what I want is the same thing in slate
this isn't used like you would like it used, that's why I'm not 100% confident that it works for your case
well, it seems like when a struct is part of an array all its categories dont show up
so that is what I am trying to solve essentialy
but if you want to take a look, if you create any niagara system, and add a skeletal mesh user parameter, then go to user parameter defaults in the system node, you get a "filtered bones" array. Internally, it's just a TArray<FName>. The UI is customized per row though, and you might be able to insert custom widgets after a typical row
I will take a look right now
I dont think that is what I am after, at least I can't tell visually
that's what I figured, yes
hmm let me boot up an empty project so I can use screenshots, which is a much better way to explain UI than text could ever be
I realized you want to customize the struct UI inside the array; I thought you want to insert something between elements of the array. In that case customizing the struct itself might work. Using a property row generator for that struct, iterating over the property tree nodes and adding the category widgets back might also work
well in any case, its clearly possible then
and i just need to figure out what I need to do
online resources are kinda scarce on the topic and for some reason never include any images. (UI code reference without screenshots of the result are kinda pointless)
true, this stuff is essentially not covered at all. A couple blogs include some information, some good, some bad, but rare regardless
Thats why I figured I would use this golden opportunity to just ask you while you happen to be here.
Still going to have to bang my head against a proverbial brick wall for the next 20 hours or so before I can make it work most likely but at least I know now that it CAN be made to work
it should be possible but you might run into some troubles. While the property editor module (including the details panel) is fairly flexible there are always some hidden limitations that also aren't clear to me
Huh, I cant find the message you posted anymore. I could swear you mentioned some arraybuilder
this one?
ah yes there it is. FDetailArrayBuilder
so is the DetailArrayBuilder used for the array itself, or the struct inside the array?
that's used to customize the display of an array. But I posted this when I assumed you wanted to insert widgets between array elements
ah right
yeah no thats fine.
The UPROPERTY array can just be displayed as
(0)
(1)
(2)
and I guess meta = (TitleProperty = "Some Name") can be used to modify what is displayed to the right of that easily
i just care about modifying how the
UStruct
and its UPROPERTY members are displayed once you expand the array
is it the IDetailCustomization perhaps?
for struct customization you'd typically use a IPropertyTypeCustomization IIRC
good example here would be the FColorStructCustomization
alright, well its getting pretty late. I will try it out some more tomorrow. Thanks a lot for the help though!
I wish I knew some editor customization wizard sitting somewhere that I could poke all day and who would be happy to share his arcane knowledge
I feel the same way about some seniors on my team but alas we all have things to do hahah
and glad to help, I frequently check this channel but I don't necessarily post frequently
I sometimes post here and then leave for a day or two. I think #cpp is where all the action is. Barely any slate people around
by the way, while I haven't tested the slate version, I have tested your scalebox setup in UMG and when the scale box alignment is set to fill rather than center it does behave like your slate video, and from looking at source code the default alignment seems to be the only difference I could spot at a glance.
UScaleBoxSlot is initialized to use center-alignment whereas SScaleBox will initialize to use fill alignment, so maybe your test was off somehow?
hi!
I add a SImage to my slate ui and get the checkerbaord image. When I call SetImage() on it with a brush created like this slatebrush = new FSlateMaterialBrush(*mat, FVector2D(32, 32));, that material gets shown instead. but after 60 s it disappears. if I don't assign the brush, the checkerboard stays forever
how to I assign a material/brush in a way it does not get garbage collected?
Short answer, using UMG
Longer answer, using any persistent UObject with UPROPERTY
hmm. what exactly gets garbage colelcted? The SImage? The brush?
oh the material of the brush
so I additionally put it as a uproperty in a UObject so it doesn't get collected?
Or use UMG which is designed to handle materials
Hey, I was hoping to get some advice. I'm trying to make a crosshair for my game, and I want to avoid using a rasterized texture/icon for it, and instead use vector graphics.
Initially I read a little bit about "SMeshWidget", but I read something saying that "FSlateDrawElement" is what I should be using for drawing a specific geometric shape.
You could use SDFs as they are math generated shapes that can scale like vectors but not really bezier based. No need to quite program your own geometry. But I am curious if you do end up with drawing something in the SMeshWidget how it turns out
Or just use materials directly
I tried doing a quick google to see if I can find any examples of people using SDFs but I didn't find anything. Do you know of any resources I could look at to learn about them?
I did try using materials to make shapes with math, but it was a bit painful to get any complicated shapes, and I was getting really bad aliasing on my edges
You can do the shapes by queuing Slate primitives (quad spline etc)
The aliasing will be a problem with Slate meshes too since it's post-antialiasing
Only textures or pixel-perfect geometry can get clean unaliased results in UI
Okay, so that means that realistically, if I want to get an unaliased UI then I need to use a texture, as I don't think I can make pixel-perfect geometry all the time.
How does the text renderer in umg get around this issue? because it seems to not be an issue for text. Does that mean SDFs also can't lead to unaliased results?
First, note that by default in UMG and Slate everything is pixel snapped (so a 0.5px high line will be sometimes 0, sometimes 1px high) so it's always pixel perfect, though the rounding may be offputting in some cases, and can be disabled per object at least in Slate
Text rendering is a dedicated system, with its own AA
And text is specifically rasterized too, it doesn't show up as geometry
SDFs can and will produce unaliased results, since usually they're essentially textures, with mipmapping and filtering
so then what options do I have?
I wrote something a while ago but SDFs in theory don't have aliasing if you just adjust the smooth step
For a crosshair, the simplest option is to use a texture ! If your crosshair cross is 2px wide, it will work perfectly with no effort at all
If you need it to be say, 1px wide, you can see that there can be no perfect solution
It'll boil down to filtered textures, or SDFs
If you have animated or parametric shapes, you can have multiple crosshair elements using textures
Or you can use a single SDF too
thanks a lot for the help! I think I think I'm gonna go with using an SDF. And if that doesn't work then I'm just gonna use textures.
Hi guys i am making inventory but i have no ideas about the inventory with different items size like this picture .
anyone have any ideas? Thanks
I have some uproperties and I want to create a widgets to edit them manually, what is the best way to do this? is there some kind of a function that will return me a widget if I pass it a uproperty? that would be handy
@fossil kayak IPropertyHandle has CreatePropertyValueWidget and CreatePropertyNameWidget. you have to create a detail customization.
oh thanks, do you know how could I get the IPropertyHandle out of FProperty?
Unfortunately you can't. IPropertyHandle is only accessible from IDetailLayoutBuilder. These are editor only by the way.
oh so yeah, I checked out the source code and it turns out those property widgets are strongly bound to the object that these properties come from, so unless I want to copy paste the entire property widget generation code from source code I will need to do it some other way, I think if I spawn some sort of a shadow object and use IDetailsView with customization to show only properties that im interested in that will do the trick
There are a couple ways you can approach this. All of those ways work via the propertyeditormodule that exposes accessors for UI generation. Be it a details panel that you customize via arguments, general details customisation that will customize all details panels, property row generators to build widgets for individual properties.. the latter you can make work with just a UObject or UStruct.
The property row generator will let you access the detail tree node structure, and for each of these you can individually create widgets however it seems fit.
If you basically want a details panel that only shows specific properties, you can create a new details panel and give it a custom filter. That filter lets you check fproperties for inclusion or exclusion
You can then either hardcode the included properties via name, or just give the relevant properties a meta tag that you can check for
You can do completely custom widgets too, just need a way to instantiate the widgets (in a new window or tab for example) and a pointer or reference to the data that should get modified. The disadvantage here is that you aren't doing this via propertyhandles so you lose default functionality like the revert to default button, or undo redo support
oh okay, I see it now, unfortunately none of these will work for me since what I wanted to achieve is to collect the properties with meta flag from the CDO, then create widgets for those properties, set some values in them and then copy those values when placing instances of the object
but thanks anyway, I learned something, didn't know that IPropertyGenerator was a thing
could you elaborate what filter do you have in mind?
since you only wanted to show specific properties, put some markup on them via meta tag, and then check inside the filter for that tag. This way you only get those properties and since it's using the details panel you get all the default functionality @fossil kayak
yeah, that is what I have already, I have details panel created and I also created IDetailCustomization for it but in only allows me to HideProperty and that would be tedious to do but you were talking about some sort of inclusion of properties it the details view, so is there any other way to do it?
yes. If you don't use customizations, but instead create a new details panel via fpropertyeditormodule, the creation function takes arguments and you can register a custom filter with that details panel
if not, imma just iterate over all of the properties and hide them
if you do it via details customization, then yes, you can also just hide all of them by default and then only show the ones with the meta tag
yeah, could you elaborate a bit? I only see this filter in detail view args
/** Optional object filter to use for more complex handling of what a details panel is viewing. */
TSharedPtr<FDetailsViewObjectFilter> ObjectFilter;
im not sure which filter you are talking about
let me open up unreal
it's not in the args, it's a function you can call on the created details view object
SetIsPropertyVisibleDelegate
omg, how could I miss it
yeah, there it is, I was checking this class a few times and found only the version for custom rows and somehow missed this one, thank you very much and sorry for bothering you
don't stress it, if I didn't want to help I wouldn't
do you know by any chance how to hide the Transform category? i hid everything else using this delegate and only the Actor and Transfrom categories were left, so I hid the Actor category using customization but it unfortunately doesn't work for transform
hmmm I don't really know. What I do know is that customized categories can show up despite that custom filter correctly disregarding a property (I was confused for a whole while while debugging this). Turns out overriding a customization for that details panel for that property basically reset that customization so internally it was no longer considered "customized", and would be filtered out correctly.
I believe I've done this by calling something like
DetailsView->RegisterInstancedCustomizationType(StructName, DetailsView->GetGenericCustomization());
or something along those lines
it could also be that transform is such an important special case that you just can't get rid of it
hmm, okay, thanks, i will try that
okay, so I looked at the source code and found how the transform category is added
if (!HideCategories.Contains(TEXT("Transform")))
{
AddTransformCategory(DetailLayout);
}
so I managed to hide it by doing this in my customization that is applied only to my particular details view
DetailBuilder.GetBaseClass()->SetMetaData(TEXT("HideCategories"), TEXT("Transform"));
that's great! Does DetailBuilder.GetBaseClass() return the class of the object that is being modified? It irks me a little to set meta data on a class object because the CDO is being modified. On the other hand, if it's only a specific class or set of classes that you want to display in the details view, you could also probably just add the HideCategories meta data to the UCLASS itself, no?
but even if so, not a big deal. Good job on finding this 👍
Does DetailBuilder.GetBaseClass() return the class of the object that is being modified
yeah it seems so
On the other hand, if it's only a specific class or set of classes that you want to display in the details view, you could also probably just add the HideCategories meta data to the UCLASS itself, no?
TArray<TWeakObjectPtr<UObject>> Objects;
DetailBuilder.GetObjectsBeingCustomized(Objects);
for (TWeakObjectPtr<UObject>& It : Objects)
{
It->GetClass()->SetMetaData(TEXT("HideCategories"), TEXT("Transform"));
}
yeah, if it is what you meant it works as well and is probably a better way to do it, didn't think of the CDO, thanks
Sorry, I wasn't being clear. That right there would be the same thing as your previous solution because you are still modifying the class CDO.
What I meant is going into your actor class that you want to display, and quite literally writing down the hide categories transform flag into the UCLASS() macro so you will only set that meta data for the classes you want to display
On the other hand, can't you just call hidecategory in the detailsbuilder itself? This way you don't need to change meta data at all
unfortunately no, that is the first thing I tried and it works for other things but not for transform, from what I see, this hides this category only in my details panel so that's good since I want to use those object in a normal way as well
you can hide transform, it's just unusual category name. you need to hide TransformCommon category. @fossil kayak @split laurel
Hah, interesting. Good to know. Thank you!
oh, yeah it worked, thanks mate
Hello, I heard I can achieve this type of thumbnail with a SMeshWidget. Currently I'm using a scene capture component and render target and an UImage. I read SMeshWidget is not something to easy to work with from #slate 's message history. That'll be my first time with Slate framework, can anyone recommend some resources about SMeshWidget and Slate?
SMeshWidget isn't for drawing actual meshes - it's for drawing a lot of the same thing.
The only way to achieve that is via scene capture and an image
Hi, I got a question about SlateStyle in CPP.
The style class always consists of static member methods, and functions. My understanding is that the style definitions only, so that's why the class consists of statics. Am I right?
not sure if I understand your question correctly, but typical slate style classes don't specifically contain slate resources. That's what the FSlateStyleSet is for, and the typical static Initialize or Create function in a style class merely creates an FSlateSlateSet object, registers slate resources and then registers itself to the slate style registry
Hi!
I sometimes have this error:
"The requested size for SRetainerWidget is 0" in the SRetainerWidget
Which leads to rendering an image on the screen which was inside of a RetainerBox. The image can be removed by changing viewport size.
Does anyone know how can I fix this?
Hard to tell what it could be without more info. Is the desired size really zero? What's inside the retainer box, can you post the tree?
how would you go about hiding properties that are registered for a custom property layout but are "disabled"? It seems that the meta specifier for EditCondition still works because the properties are being disabled, but they're not hiding (EditConditionHides is being ignored)
I believe you have to add this as well HideEditConditionToggle
Hi! There was an overusage of sizeboxes in the layou, I fixed the problem, but still have errors.
LogUMG: Error: The requested size for SRetainerWidget is too large. W:-1073741824 H:-1073741824 LogUMG: Error: The requested size for SRetainerWidget is 0. W:0 H:0
Currently it is:
Canvas->ScaleBox->Overlay->Canvas->ScaleBox->Overlay->RetainerBox->NamedSlot->Image
Maybe the problem is happening before the named slot contents are initialized?
🤔 How can I ensure Slot Content to be initialized beforehand?
does a checkbox slider slate widget exists?
SCheckbox maybe
Slider or not is just a visual thing. That's on you to skin
I don't know sorry
Anyway, thank you for your suggestions! I'll try to debug this particular case
Hello 🙂
How do you go about displaying the elements of an array within a struct? I currently have the following in the CustomizeHeader and CustomizeChildren for my property customization. The array shows up and you can add elements to it, but none of the elements are displayed.
// Customize Header
void FMyCustomStructCustomization::CustomizeHeader(TSharedRef<IPropertyHandle> StructPropertyHandle, FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& StructCustomizationUtils) {
HeaderRow
.NameContent() [ StructPropertyHandle->CreatePropertyNameWidget() ]
.ValueContent() [ StructPropertyHandle->CreatePropertyValueWidget() ];
}
// Customize Children
void FMyCustomStructCustomization::CustomizeChildren(TSharedRef<IPropertyHandle> StructPropertyHandle, IDetailChildrenBuilder& StructBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils) {
MyArrayPropertyHandle = StructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FMyCustomStruct, MyArray), false);
StructBuilder.AddCustomRow(LOCTEXT("My Array", "My Array"))
.NameContent() [ MyArrayPropertyHandle->CreatePropertyNameWidget() ]
.ValueContent() [ MyArrayPropertyHandle->CreatePropertyValueWidget() ]; // doesn't show any array items
}
Would anyone be able to help me troubleshoot why my widget blueprint passed to the MoviePlayer's FLoadingScreenAttributes.WidgetLoadingScreen renders slightly different than when I just add the widget blueprint straight to the viewport?
I even tried wrapping my widget in a slate object identical to the one the MoviePlayer uses and it still isn't right (the text and throbber are smaller in size when using the MoviePlayer, but the background image looks consistent)
So if I set the DPI scaling on the widget that I manually create to .75, it will match perfectly the MoviePlayer's rendering of my widget. But as soon as I change my windows scaling, my magic .75 DPI scaling stops working (as expected). I just need to figure out how to calculate that correct DPI scaling. The .75 scaling works when my Windows display scaling is set to 150% at a resolution of 2560x1440.
How can I do an opacity gradient in Slate when using FSlateDrawElement, or on the final composited geometry at the end of OnPaint?
Hello. How would I go about making a "copy" of a RichTextBlock but "remove" it's ability to change it's text size based on resolution. I want text to always be the same size I set it at. Then I want to just but the textblock in a scale box and have it scale proportionally.
It's not just rich text blocks that scale with resolution, that's a DPI scaling thing isn't it?
@mild oracle , I assume it is, but I want to scale my text absolutely manually because it causes overflows and it beaks my layout.
When I say manually I really mean scale it as if it were an image. No need for fancy row rearrangements as a result of desired size or whatever that is
Ohhh I've seen that behaviour too. I thought it was because it was using a different font size for each resolution, and fonts at different sizes can have different proportions. That plus all the complicated text layout logic for keeping characters looking clear and crisp can mean that the text takes up more or less horizontal space.
To change this behaviour you might have to dig pretty deep into Unreal's text layout code...
I wonder if there's a way you could do something like this with Retainer Box, manual invalidation or something :S
I can show you some video footage to be sure.
@mild oracle , sent a private message with video footage
wondering if anyone would know something about line tracing in a custom editor viewport preview scene.
as i cannot seem to be able to hit anything and made sure the plane mesh is block on all collision channel responses.
Anyone familiar with the new changes in UE5-main re: slots ? FSlot vs FSlot::FSlotArguments specifically, seems to break DLSS and also my own code
More specifically, how do I get actual args values from say, InArgs._Slots - assuming I have SLATE_SLOT_ARGUMENT(FSlot, Slots) ?
Alright, fixed it
@quaint zealot Whoa stuff has changed in UE5 with slots?
Yeah, essentially slot arguments / slot creation now works around the FYourSlotType::FArguments rather than the slot type directly
For reference, working ue5-main (as of yesterday) source code for widget slots
// Widget slot
class FSlot : public TSlotBase<FSlot>
{
public:
SLATE_SLOT_BEGIN_ARGS(FSlot, TSlotBase<FSlot>)
SLATE_ATTRIBUTE(SomeType, SomeAttribute)
SLATE_SLOT_END_ARGS()
FSlot() : TSlotBase<FSlot>()
{}
void Construct(const FChildren& SlotOwner, FSlotArguments&& InArgs)
{
TSlotBase<FSlot>::Construct(SlotOwner, MoveTemp(InArgs));
if (InArgs._SomeAttribute.IsSet())
{
SomeAttributeAttr = MoveTemp(_SomeAttribute._Header);
}
}
TAttribute<SomeType> SomeAttributeAttr;
};
// Widget header
SLATE_SLOT_ARGUMENT(FSlot, Slots)
static FSlot::FSlotArguments Slot()
{
return FSlot::FSlotArguments(MakeUnique<FSlot>());
}
// Widget construct
for (const FSlot::FSlotArguments& Arg : InArgs._Slots)
{
const FSlot* Slot = Arg.GetSlot();
SomeWidgetType* SlotWidget = static_cast<SomeWidgetType*>(Arg.GetAttachedWidget().Get());
}```
make sure lines do penetrate the plane and not just touch it. (I might be wrong but this seems to be unrelated to slate)
They do penetrate figured out what the issue was
On the preview scene i disabled physics earlier and totally forgot about it
Enabling that again made line traces work
FPreviewScene::ConstructionValues ConstructValues;
ConstructValues.SetCreatePhysicsScene(true);
ConstructValues.ShouldSimulatePhysics(true);
ConstructValues....
If I want to make a slate button whose icon changes depending on some underlying state, would I make its icon a TAttribute that is bound to a function? Something like TAttribute< FSlateIcon >::FGetter::CreateStatic(&MyFunctionThatReturnsIcon)
it should normally be something similar to this
const FSlateBrush* SSomeClass::GetIcon() const
{
return (Icon);
}
void SSomeClass::Construct(const FArguments& InArgs)
{
...
ChildSlot
[
...
[
SNew(WidgetClass)
...
.LabelIcon(this, &SSomeClass::GetIcon)
...
]
...
]
}
Hi, I was wondering if anyone has modified/extended the Composite font's to support bitmap fonts(or other font's)? I'd like to implement msdf font for ui stuff, and I see umg/slate font's need to be composite's in order to be used.
I haven't but I am very interested in your solution!
well i've decided to abandon modifying composite font. it is pretty hardcoded to expect ttf/otf files as far as I can tell. And changing any header related to them seems to trigger a 40+min recompile, which is too long for the trial and error method of figuring out how everything is pieced together. So my new approach now is basically to build my own font object, and then create my own slate widget and draw text that way instead. I have my font stuff done atm, working on figuring out how slate draws things currently.
Hello.
What is "Atlased Texture Interface" and why Stale Brush can accept Materials and Textures to Image object slot, but Image Object itself - can't?
I see now, it's an UObject, but Slate somehow filters the Textures and Materials.
Hi, does anybody know if there is a callback for when your game's window is resized? I googled and couldn't find anything and I also searched the documentation and couldn't find anything.
someone gave me the answer FViewport::ViewportResizedEvent
You can get it from the game viewpoint client
Question, is it possible to add a slate widget child to a umg widget?
I vaguely remember seeing an UMG widget for containing Slate widgets
Alternatively you could just wrap your widget into a UMG widget which should be relatively straightforward
You'll probably have to put your Slate widget into a UWigdet (Not UUserWidget).
thanks, I found something:
Native Widget Host
This is a container widget that can contain one child Slate widget. This should be used when all you need is to nest a native widget inside a UMG widget.
https://docs.unrealengine.com/4.27/en-US/InteractiveExperiences/UMG/UserGuide/WidgetTypeReference/
A NativeWidgetHost is a container widget that can contain one child slate widget.
So I'm trying to get into slate - the overview i was following said you could click on the links in the widget reflector to open that section of code in visual studio. For me it just switches the window to visual studio and thats it. It wont find the line of code even if the file is already open in visual studio. its not even hanging or anything.
Is this something i can fix or did i just completely misunderstand in the first place
Does clicking on stuff in the editor take you to the right line/function for other stuff? e.g. double-clicking on a node in Blueprints take you to the right function?
Does anyone got working code for UE5-main slots ?
I'm doing something really simple where I just pass slot widgets to a child widget's construct
Somehow I keep getting crashes in the widget's Destroy
I also have no idea when to call the slot's new Construct call
Okay I finally got it.
// Slot
class FSlot : public TSlotBase<FSlot>
{
public:
SLATE_SLOT_BEGIN_ARGS(FSlot, TSlotBase<FSlot>)
SLATE_ATTRIBUTE(FText, Example)
SLATE_SLOT_END_ARGS()
};
// Slot user header
static FSlot::FSlotArguments Slot()
{
return FSlot::FSlotArguments(MakeUnique<FSlot>());
}
// Slot user Construct
for (FSlot::FSlotArguments& Arg : const_cast<TArray<FSlot::FSlotArguments>&>(InArgs._Slots))
{
FText Example = Arg._Example;
TSharedPtr<SWidget> Widget = Arg.GetAttachedWidget();
}```
I’ve only been looking at slate for a few days but is there any documentation that explains the correct way to do local and absolute transforms?
I.e. convert correctly between local absolute space.
When 2 widgets may be in different transform hierarchies.
I’m trying to draw a line between 2 widgets but it’s really unclear if the coordinates are supposed to be in local space or absolute space.
Ok I think I have a better handle on how this works now.
Is there a way to get IPropertyHandle outside of IDetailCustomization? I wanted to put FText edit area outside of details panel (e.g. straight onto a graph node), by using an existing slate class (STextPropertyEditableTextBox).
Is there a proper way to clear out a ComboBox? Ive got a setup where sometimes that box can be be empty and Id like to clear it out, but just calling ClearSelected() before I update the elements leaves what was previously selected in there
I guess as I talk this out though the better option might be to hide that box entirely if theres no valid selection
...which Im not entirely sure how to do either heh
Which I have now resolved by finding the .Visibility_Lambda() option. This chat is great for Rubber Ducking! 🙂
Is it possible to attach a Slate widget to actor? so it would be drawn in 3d space
The easiest way to do that would probably be to use a widget component with a UMG widget which wraps your Slate widget
thnakas
With Apple killing it off I probably wouldn't
^ yeah touchbar is ded. Although it seems it had some fans, nearly everyone I've talked to had issues with it so probably for a good reason 
Where can I find learning resources for Slate?
The editor source code is the main one
After all it's what you're doing with it usually
I've seen this "Display UIExtension Points" option, and when it's enabled it shows a bunch of strings. Does anyone know how to use them?
These are for FExtenders usually. You can specify a section when adding toolbar options, and naming one of these extension points will add your buttons there
does someone have a link to a good description of the different ways to style widgets (including custom widgets)?
like when its best to use args/attributes, when to use that style stuff like FCoreStyle that reference the assets in the VFS, and when to create a Style-Struct and when not....
also is there a better way to do auto-focus for than:
RegisterActiveTimer(0.016f, FWidgetActiveTimerDelegate::CreateLambda([this](double InCurrentTime, float InDeltaTime) {
FWidgetPath FocusMe;
FSlateApplication::Get().GeneratePathToWidgetChecked( SearchBox.ToSharedRef(), FocusMe );
FSlateApplication::Get().SetKeyboardFocus( FocusMe, EFocusCause::SetDirectly );
return EActiveTimerReturnType::Stop;
}));
?
well, I'm getting an error
Here is the problem line
SAssignNew(DescriptionsListViewWidget, SListView<TSharedPtr<FDescriptionsListItem>>)
here is DescriptionsListViewWidget
TSharedPtr<SListView<TSharedPtr<FDescriptionsListItem>>> DescriptionsListViewWidget = nullptr;
and here's FDescriptionsListItem
USTRUCT()
struct LIVERYEDITORTOOL_API FDescriptionsListItem
{
GENERATED_BODY()
FDescriptionsListItem() : Index(0), Name(FString("")), Data()
{}
int Index;
FString Name;
FBMLiveryDescription Data;
};
This is the build error I'm getting
LiveryEditorToolView.cpp(82): [C2664] 'TDecl<SListView<TSharedPtr<FDescriptionsListItem,ESPMode::NotThreadSafe>>,RequiredArgs::T0RequiredArgs> &TDecl<SListView<TSharedPtr<FDescriptionsListItem,ESPMode::NotThreadSafe>>,RequiredArgs::T0RequiredArgs>::Expose<SListView<TSharedPtr<FDescriptionsListItem,ESPMode::NotThreadSafe>>>(TSharedPtr<SListView<TSharedPtr<FDescriptionsListItem,ESPMode::NotThreadSafe>>,ESPMode::NotThreadSafe> &)': cannot convert argument 1 from 'const TSharedPtr<SListView<TSharedPtr<FDescriptionsListItem,ESPMode::NotThreadSafe>>,ESPMode::NotThreadSafe>' to 'TSharedPtr<SListView<TSharedPtr<FDescriptionsListItem,ESPMode::NotThreadSafe>>,ESPMode::NotThreadSafe> &'
LiveryEditorToolView.cpp(82): [C2664] Conversion loses qualifiers
DeclarativeSyntaxSupport.h(1068): [C2664] see declaration of 'TDecl<SListView<TSharedPtr<FDescriptionsListItem,ESPMode::NotThreadSafe>>,RequiredArgs::T0RequiredArgs>::Expose'
and I guess this is FBMLiveryDescription
USTRUCT()
struct FBMLiveryDescription
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, Category = "Description")
TEnumAsByte<EBMLiveryWorkspace> Workspace;
UPROPERTY(EditAnywhere, Category = "Description")
TArray<FBMLiveryGroup> Groups;
};
How do you construct a slate widget to use with Gameplay Tag Container?
I found out what was wrong with mine, the construct function was a const
and here's another error, when trying to spawn an asset entry box in my slate, created a widget function
TSharedRef<SWidget> SLiveryEditorToolView::CreateDataAssetPicker(TSharedPtr<SObjectPropertyEntryBox> PropertyEntryBox)
{
return SAssignNew(PropertyEntryBox, SObjectPropertyEntryBox)
.AllowedClass(UCustomLiveryData::StaticClass())
.ObjectPath(this, &SLiveryEditorToolView::GetDataPath)
.OnObjectChanged(this, &SLiveryEditorToolView::OnDataObjectSelected)
.AllowClear(true)
.DisplayBrowse(true)
.DisplayThumbnail(true)
.ThumbnailPool(AssetThumbnailPool)
.DisplayUseSelected(true)
.DisplayCompactSize(false)
.EnableContentPicker(true);
}
called it here
TSharedRef<SWidget> SLiveryEditorToolView::CreateToolBox()
{
return SNew(SVerticalBox)
+ SVerticalBox::Slot()
.Padding(4.0f)
[
CreateDataAssetPicker(DataAssetEntryBox)
]
and now getting this weird error
unresolved external symbol "__declspec(dllimport) public: void __cdecl SObjectPropertyEntryBox::Construct(struct SObjectPropertyEntryBox::FArguments const &)" (__imp_?Construct@SObjectPropertyEntryBox@@QEAAXAEBUFArguments@1@@Z) referenced in function "public: class TSharedRef<class SObjectPropertyEntryBox,0> __cdecl TDecl<class SObjectPropertyEntryBox,struct RequiredArgs::T0RequiredArgs>::operator<<=(struct SObjectPropertyEntryBox::FArguments const &)const " (??_3?$TDecl@VSObjectPropertyEntryBox@@UT0RequiredArgs@RequiredArgs@@@@QEBA?AV?$TSharedRef@VSObjectPropertyEntryBox@@$0A@@@AEBUFArguments@SObjectPropertyEntryBox@@@Z)
I'm really stumped on it, been trying a few things
did you add module: PropertyEditor?
Hey guys, how do you force a slate widget to redraw itself?
SlatePrepass(FSlateApplication::Get().GetApplicationScale());
I'm not sure but i simply call the invalidate function which sems to work for me
How to call a C++ function or BP function from Javascript that is run in SWebBrowser?
Expose a UObject instance to the browser runtime.
There is no way to evaluate JavaScript in SWebBrowser and receive the output on Blueprint/C++ side? Besides making the UObject with callbacks and calling a JavaScript that returns results via those callbacks?
Something like runJavasript(lambda<T>)
sounds likely since browsers in general aren't designed to expose escape hatches for other applications
Thanks for your reply (sorry it's been a hot minute, I had to shelve this project for a little bit)
I can open any blueprint functions that I create by double clicking. If I try to open one thats built-in it pops up with a "reading c++ symbols" thing on the bottom of the screen and nothing else happens
As a small update, I finally saw that when I try to open anything from the widget reflector I get an error that its looking in the complete wrong place for the code file - there isnt even any "Build" folder in the root of my D drive, or anything else to do with unreal so im not sure where it's getting this path from or how to fix it. Just to be thorough I reinstalled 4.26.2 and nothing changed
That's the source code for when the engine was built @craggy current
IIRC you need debug symbols or something to open from editor ? Easier to just open Visual and search for that file name
Hello, so I'm trying to bind a value to a TAttribute, so that I can change a value in a Custom Data Asset and have it change in my SlateUI, and vice versa
Currently, I have a CreateSP function that does this for me
Val = TAttribute<int>::Create(TAttribute<int>::FGetter::CreateSP(this, &SLiveryEditorToolView::GetTestValue));
but this calls every tick from my understanding
and would not work with TArrays
Why wouldn't it work with arrays ? Also you can make it a lambda, which will likely compile down to literally reading the variable
I'm sorry, quite new to slate, how would we bind it to lambda?
Using CreateLambda instead and passing the code from GetTestValue directly
And updating on tick is perfectly fine, for the record
yeah that's fair, so I could just do this?
Val = TAttribute<int>::Create(TAttribute<int>::FGetter::CreateLambda(this, TestCustomData->Pattern.Colours->R));
assuming that value is the one I return from the getter
Probably more like
Val = TAttribute<int>::Create(TAttribute<int>::FGetter::CreateLambda([this] { return TestCustomData->Pattern.Colours->R);} ));```
Works for any type, dunno how you want to show the array
I'll give it a go, thanks for the help! I appreciate it!
@quaint zealot yeah, it doesn't seem to update correctly when adding new elements to the array in the custom data asset
here is my code
DescriptionsList = TAttribute<TArray<FBMLiveryDescription>>::Create(TAttribute<TArray<FBMLiveryDescription>>::FGetter::CreateLambda([this] { return TestCustomData->Descriptions; }));
Like I said, depends on how you want to show the array. For list views you probably want to use the widget's tick event to copy the array or a hash of it, and refresh the list view any tile it's changed
so the "every time it's changed" part is what I'm having issues with, how do we know when thats happening?
Depends on the array and contents, but it could be a hash of the array contents for example.
yeah, the array's contents is just a struct with a TEnumAsByte and another TArray
Hello, I would like that my plugins uses the same docking system used by the editor. I saw that it's needed to use: SDockingArea and SDockingSplitter but it doesn't seems to work well with slate, doesn't compile:
return SNew(SDockTab)
.TabRole(ETabRole::NomadTab)
[
SNew(SDockingArea)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
]
];
This is the compilation error:
No 'operator []' matches arguments of type 'SDockingArea::FArguments' and 'TSharedRef<SHorizontalBox, ESPMode::Fast>'
It's like the SDockingArea doesn't implement to operator[] function, any idea?
I dont know what dockingarea is but looking at engine code to see how it's used there is probably your best bet.
@limber stump I'm trying doing it, though it doesn't seems to be so obvious or however it doesn't use slate.. at least it doesn't seems so 🤔
Btw, what I'm trying to do is create the plugin UI so that it's possible to change the size of the side menu, exactly like for any window (like the blueprint editor or the skeleton asset editor)
To do it, do I need to use the dock or exist another way?
Hi Slate peeps, how do I change a button's visibility on the fly, I've set the .Visibility to a TAttribute but have no idea how to set the Tattribute to update the button's visibility
sorry, bit of a beginner
What should I google to figure out building my own asset editor window? Specifically, an asset editor window that renders a scene in real-time.
Like the Viewport in the blueprint editor.
Without knowing how much you know or have already done:
- create an editor module
- create a factory and asset type actions class for the class you wanna customize
- create an asset customization for the class
- add a viewport to that customization.
Start by googling which of these you are unfamiliar with first. Little is online about the actual viewport itself. I would try to look at how assets like static meshes or materials add a viewport to their asset and try to copy the basics from there. The other three steps are quite well covered online. Cairan Steverink's blogs are pretty good at covering the bare minimum to set things up
Do I need to use slate to optimize UMG? Can I use plain C++ functions for the BPs using heavy forloops?
It depends on what you're doing. You don't necessarily need to use Slate to move stuff into C++.
sup slate wierdos, cross posting this from main chat:
trying to track a socket off a skeletal mesh w/ a new cpp UUserWidget
basically GetSocketLocation() -> ProjectWorldToScreen()
but - there's a problem w/ scaling? seems like UCanvasPanelSlot::SetPosition() is expecting different coordinates than what PWTS() returns
haven't investigated DPI yet, but converting to widget local coords didn't help
any ideas? for context SetPosition(ViewportSize) puts it about 3/4 the way to the bottom corner iirc, so scaling is off by like 1.3x
Almost certainly going to be DPI scale. Also you probably want to project to the viewport not the screen.
Screen will encompass the whole window, which in editor also means toolbars etc.
I prefer projecting to normalized viewport position then set anchors instead
Using FSceneViewProjectionData::ComputeViewProjectionMatrix() for projection and FSceneViewProjectionData::GetConstrainedViewRect() for viewport size.
@craggy holly could you elaborate? I'm maybe not following
LocalPlayer->GetProjectionData(LocalPlayer->ViewportClient->Viewport, eSSP_FULL, ProjectionData);
FSceneView::ProjectWorldToScreen(SocketWorldLocation, ProjectionData.GetConstrainedViewRect(), ProjectionData.ComputeViewProjectionMatrix(), SocketScreenLocation); should accomplish all that right? it didn't work, same issue
well, except using anchors. I'm confused ab that
never mind, it works when divided by the DPI
Hello there slateheads, I've just assigned a variable to a cpp TSharedPtr<SListView<TSharedPtr<FDescriptionsListItem>>> widget, was wondering if there was a simple way to add an item to that list after pressing a button
this is the FDescriptionListItem struct by the way
USTRUCT()
struct LIVERYEDITORTOOL_API FDescriptionsListItem
{
GENERATED_BODY()
FDescriptionsListItem() : Index(0), Data()
{}
int Index;
FBMLiveryDescription Data;
};
and finally, how I assign the value
+ SVerticalBox::Slot()
.AutoHeight()
.VAlign(VAlign_Fill)
.HAlign(HAlign_Fill)
[
SAssignNew(DescriptionsListViewWidget, SListView<TSharedPtr<FDescriptionsListItem>>)
.ItemHeight(24)
.SelectionMode(ESelectionMode::Single)
.ListItemsSource(&DescriptionsListViewItems)
.OnGenerateRow(this, &SLiveryEditorToolView::OnGenerateDescriptionsRow)
]
Add to DescriptionsListViewItems and refresh DescriptionsListViewWidget
ah smart, thank you for the help again Stranger
FReply SLiveryEditorToolView::OnAddDescriptionClicked()
{
TSharedPtr<FDescriptionsListItem> NewItem = MakeShared<FDescriptionsListItem>();
DescriptionsListViewItems.Add(NewItem);
DescriptionsListViewWidget->RequestListRefresh();
return FReply::Handled();
}
@quaint zealot Would this be the way to do it?
Something like that, yeah
hm thats not liking that at all
error C3867: 'SLiveryEditorToolView::OnAddDescriptionClicked': non-standard syntax; use '&' to create a pointer to member
That's your button code
yeah
Just do what the error says
I wish I knew where it meant really..
I mean the error specifically tells you how to fix the code
And this is a regular C++ function pointer
Might want to read up on C++ if you're writing some
thanks for the help
Oh my goodness, right, it's on the button itself
I thought it was in the function
yeah when you said button code for some reason my head went straight to the definition
hello again! I'm looking to implement a double click renaming text block and found SInLineEditableTextBloxk, which sounds right up my alley, was wondering why it doesn't seem to respond to my double click? It could be the tablerow taking the focus, really... is there any way to allow it to select the item on the first click, but edit the item on the second?
TSharedRef<ITableRow> SLiveryEditorToolView::OnGenerateDescriptionsRow(TSharedPtr<FDescriptionsListItem> Item, const TSharedRef<STableViewBase>& OwnerTable)
{
FString RowName = FString("Description_");
RowName.AppendInt(Item->Index);
TSharedRef<STableRow<TSharedPtr<FString>>> TableRow = SNew(STableRow<TSharedPtr<FString>>, OwnerTable)
.Padding(2.0f)
.SignalSelectionMode(ETableRowSignalSelectionMode::Instantaneous)
[
SNew(SInlineEditableTextBlock)
.Text(FText::FromString(RowName))
];
return TableRow;
}
this is my implementation
maybe theres a way to suppress the table rows double click functionality?
you can check what's taking up input by using the widget reflector to help you debug this
@split laurel thats great to know! Im pretty sure the table rows taking the input since it does get selected on the first click, im just trying to figure out how to get it not to handle the double click only
typically it shouldn't take the input as you didn't click on the row but on the text. Input handlers bubble up, so that the row only attempts to consume the input when the contained widget doesn't handle it
so you are probably right that the row does take the input, but the question is why. Or perhaps you need to forward the selection to the text box
Thats an excellent idea, i'll try and stop the input on the row and call it from the text
So through the widget reflector, I found out both my listview and editableTextBox have focus, but the row itself doesn't have any
focus is something a bit different. You can open up Widget Events (I think?) under windows in the widget reflector, then setup what events "mouse input up/down" you want to look for. In the log it will tell you what widget is eating it specifically
Is there an easy way to get rounded edges with SNew(SBorder)? (or something similar)
Sure, just use a rounded texture
Simple border-type Slate brush with a 9-patch texture
Set all margins to 0.33 in the brush and you're set
(or you can simple use a circle texture and setn0.5 to margins to make it a 4 patch)
thanks 👌
Anyone knows what am I missing?
+ SVerticalBox::Slot()
.AutoHeight()
[
SNew(SSeparator)
.Visibility(EVisibility::Collapsed)
]
I guess its related with declarative syntax support thing?
is this your last slot @glad elm ?
It was not, I added some more #includes and it somehow fixed
#include "UObject/UnrealType.h"
#include "Widgets/Layout/SSeparator.h"
#include "Widgets/Layout/SBox.h"
#include "Widgets/Views/STableViewBase.h"
#include "Widgets/Views/STableRow.h"
#include "Widgets/Views/SListView.h"
#include "Widgets/Input/SComboBox.h"
#include "Widgets/Input/SSearchBox.h"
#include "UObject/UObjectHash.h"
#include "UObject/UObjectIterator.h"
#include "Misc/TextFilter.h"
I only had SSeperator first
Added all of those and compiled
void FSCSRowDragDropOp::HoverTargetChanged()
{
bool bHoverHandled = false;
if (!bHoverHandled)
{
if (FChildActorComponentEditorUtils::ContainsChildActorSubtreeNode(SourceNodes))
{
// @todo - Add support for drag/drop of child actor template components to create variable get nodes in a local Blueprint event/function graph
FText Message = LOCTEXT("ChildActorDragDropAddVariableNode_Unsupported", "This operation is not currently supported for one or more of the selected components.");
SetSimpleFeedbackMessage(ErrorSymbol, IconTint, Message);
}
else if (FProperty* VariableProperty = GetVariableProperty())
{
const FSlateBrush* PrimarySymbol;
const FSlateBrush* SecondarySymbol;
FSlateColor PrimaryColor;
FSlateColor SecondaryColor;
GetDefaultStatusSymbol(/*out*/ PrimarySymbol, /*out*/ PrimaryColor, /*out*/ SecondarySymbol, /*out*/ SecondaryColor);
//Create feedback message with the function name.
SetSimpleFeedbackMessage(PrimarySymbol, PrimaryColor, VariableProperty->GetDisplayNameText(), SecondarySymbol, SecondaryColor);
}
else
{
FText Message = LOCTEXT("CannotFindProperty", "Cannot find corresponding variable (make sure component has been assigned to one)");
SetSimpleFeedbackMessage(ErrorSymbol, IconTint, Message);
}
bHoverHandled = true;
}
if(!bHoverHandled)
{
FKismetVariableDragDropAction::HoverTargetChanged();
}
}
Am I going nuts or does
FKismetVariableDragDropAction::HoverTargetChanged();
never get called?
ah yeah one of them has SBoxPanel.h in them
A Vertical Box Panel. See SBoxPanel for more info.
it's the include file you need to call SVerticalBox
Having a strange issue with slate, I added a new custom treeview to my slate like this
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.VAlign(VAlign_Top)
[
SAssignNew(PaletteListViewWidget, SDragDropTreeView)
.ItemHeight(24)
.TreeItemsSource(&PaletteListViewItems)
]
I have a construct in another file like this
void SDragDropTreeView::Construct(const FArguments& InArgs)
{
Owner = InArgs._Owner;
STreeView<FDragDropTreeNodePtrType>::FArguments BaseArgs;
BaseArgs.OnGenerateRow( InArgs._OnGenerateRow )
.OnItemScrolledIntoView(InArgs._OnItemScrolledIntoView)
.OnGetChildren(InArgs._OnGetChildren)
.OnSetExpansionRecursive(InArgs._OnSetExpansionRecursive)
.TreeItemsSource(InArgs._TreeItemsSource)
.ItemHeight(InArgs._ItemHeight)
.OnContextMenuOpening(InArgs._OnContextMenuOpening)
.OnMouseButtonDoubleClick(InArgs._OnMouseButtonDoubleClick)
.OnSelectionChanged(InArgs._OnSelectionChanged)
.OnExpansionChanged(InArgs._OnExpansionChanged)
.SelectionMode(InArgs._SelectionMode)
.HeaderRow(InArgs._HeaderRow)
.ClearSelectionOnClick(InArgs._ClearSelectionOnClick)
.ExternalScrollbar(InArgs._ExternalScrollbar)
.OnEnteredBadState(InArgs._OnTableViewBadState)
.HighlightParentNodesForSelection(true);
STreeView<FDragDropTreeNodePtrType>::Construct(BaseArgs);
}
and now I'm getting a LNK error
Module.LiveryEditorTool.cpp.obj : error LNK2019: unresolved external symbol "public: void __cdecl SDragDropTreeView::Construct(struct SDragDropTreeView::FArguments const &)" (?Construct@SDragDropTreeView@@QEAAXAEBUFArguments@1@@Z) referenced in function "public: class TSharedRef<class SDragDropTreeView,0> __cdecl TDecl<class SDragDropTreeView,struct RequiredArgs::T0RequiredArgs>::operator<<=(struct SDragDropTreeView::FArguments const &)const " (??_3?$TDecl@VSDragDropTreeView@@UT0RequiredArgs@RequiredArgs@@@@QEBA?AV?$TSharedRef@VSDragDropTreeView@@$0A@@@AEBUFArguments@SDragDropTreeView@@@Z)
no idea what it means
How to change the editor font? I looked at the Editor Style Set, and changed some references, but it did not work.
I'm trying to add an image to my loading screen. The comment line is path of my widget but i'm not sure if it works. I only need a throbber, an image and maybe a text. How i can handle it?
void UGameInstanceBase::Init()
{
Super::Init();
FCoreUObjectDelegates::PreLoadMap.AddUObject(this, &UGameInstanceBase::BeginLoadingScreen);
}
void UGameInstanceBase::BeginLoadingScreen(const FString& InMapName)
{
FLoadingScreenAttributes LoadingScreen;
LoadingScreen.bAutoCompleteWhenLoadingCompletes = false;
//LoadingScreen.WidgetLoadingScreen = "/Game/UI/LoadingScreen";
LoadingScreen.WidgetLoadingScreen = FLoadingScreenAttributes::NewTestLoadingScreenWidget();
GetMoviePlayer()->SetupLoadingScreen(LoadingScreen);
}
Hi! Does anybody know, if there is a console command to toggle slate rendering? For profiling purpose I want to disable all UMG and slate things for a while..
is there a way of getting the ListView variable from the ```cpp
const TSharedRef<STableViewBase>& OwnerTable
can we just cast it?
Hi guys! I wrote a short article, but I believe it is a useful article about standalone Slate apps.
But it was written in Russian. Maybe there are Russian-speaking people in the chat, who can help me with translation into English?
Do you have a link? How bad is Google translate for Ru=>En?
Hey guys I want to change font size of UMG TextBlock during gameplay -> I found that I need to create new FSlateFontInfo and then use SetFont()
- Here is my current code that is not working can you point why ?
- This code is in the UWidget constructor
THE PROBLEM: it does not changes font when start game
const FString FontPath = FString ("/Game/UI_Assets/Fonts/MyFont"); FSlateFontInfo NewFontInfo(FontPath,96); MMCreditsBtnTxt->SetFont(NewFontInfo);
If you right click on the asset and choose "Copy Reference" it should give you the correct path
@mild oracle thanks for reply but still not working, I'm seeing this every time...
And here is the current code .. I guess I'm doing something else wrong..
ok JFYI @mild oracle I made it working with these 2 rows .. I guess I'll try clean new project to see if it will work with the path something smells .. why I can't get the reference by path... Thanks , btw I watched you videos !! Great stuff !!
Hey is it possible to get a specific widget type from a IDetailLayout and somehow customize it?
For example I can get a named property or widget row, and configure it.
I want to get the reference to a spawned overlay SClassViewer, and update the items that are spawned in the combo box.
But I am having trouble getting its handle, and I don't understand how I would go about it.
I have a TArray<UObject*> property;, of which I want to apply a custom filtering.
@spare islandOut of curiosity. Is there any reason you can't just make a map or array of FSlateFontInfo structs to get your data from and set it from blueprint/editor? Hardcoding stuff is a little brutal.
I find I can use property.asArray to get a handle to the array itself.
For example, deleting 0th element.
I still have not found a way to get a handle to the asset picker that is created as a floating window.
I want to target this asset picker with custom filtering.
Its an SListViewSelectorDropdownMenu.
So pretty much its a custom window. I guess I cannot customize this from the property 😦
All I want is custom filtering for a TArray UObject* property.
Follow up question: Is there any way to modify specific widgets, within a property? For example if I wanted to change the button size of the SDetailSingleItemRow in a SListView created via a normal TArray UPROP
I just don't see how to walk down from a property handle down into its children properly.
It says array elements cannot be accessed via "GetChildHandle"
Is there a way to "mask" something in slate?
Like if I'm drawing a square image in "OnPaint" but I want to give it rounded translucent borders?
Or like an opacity mask for slate
You apply a brush to it, i.e. a texture or a material
Hey Slaters!
I'm trying to add an asset's thumbnail to my slate, so I've got
UTexture2D* AssetTexture = *AssetItem;
FAssetThumbnailConfig ThumbnailConfig;
ThumbnailConfig.bAllowFadeIn = true;
ThumbnailConfig.bAllowHintText = false;
TSharedPtr<FAssetThumbnail> AssetThumbnail = MakeShareable(new FAssetThumbnail(AssetTexture, 64, 64, nullptr));
TSharedPtr<SWidget> Thumbnail = AssetThumbnail->MakeThumbnailWidget(ThumbnailConfig);
```But it doesn't render out the thumbnail image from the asset I want, just the Texture type thumbnail. (Here AssetItem is the asset in question)
So, just for clarity, I'm getting this
when I want this
Hi! I was wondering if something like this could be created more or less easily with Slate:
a "slider" of sorts that controls 3 different values
@grave parcel It would be more pleasant making this in UMG tbh
hmm
Is there a reason you want it for slate?
Yeah Slate is for building fundamental widgets
This is just two brushes and three text blocks
I was under the impression that Slate was for more "complicated" things
but I was wrong 😄
hehe
^ this
But this is very doable with UMG
also @quaint zealot would you know anything about the thumbnail problem I'm having?
No, i don't
ah alright, thanks anyway
So, for anyone interested, I didn't specify a thumbnailpool when creating my assetthumbnail
FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked<FLevelEditorModule>("LevelEditor");
TSharedPtr<FAssetThumbnailPool> ThumbnailPool = LevelEditorModule.GetFirstLevelEditor()->GetThumbnailPool();
TSharedPtr<FAssetThumbnail> AssetThumbnail = MakeShareable(new FAssetThumbnail(AssetTexture, 64, 64, ThumbnailPool));
works perfectly now!
Is it possible somehow set "Min row height" for TreeTable ?
What keeps you from adding a box inside the individual row with a minimum height?
Is there an injection point where I can run some code before slate does the layout pass for a given frame? I want to "project" widget position from world-space to screen-space, and possibly change the size of that widget depending on that projection. I've realised Tick etc. runs after layout has been processed for that frame, and I'm doing the work there currently, but there's a frame of latency and I suspect I'm invalidating things a lot by doing that.
The hard part is exposing that to UMG in some way. All I can think of is binding some functions to events exposed by the slot, but dynamic delegates/bindings aren't exactly quick.
Guess I want some kind of "pre layout pass" function for UMG, not sure that exists?
Actually.. doesn't matter 😄
is there an example of how I can add a submenu / menu entries to toolbar button? I only see example for modifying the editor menus or adding a pop up window for plugins.
I was gonna say try on paint... But glad you ended up finding a solution, mind me asking or NDA?
In the Slate Examples(Slate Test Suite) has an example of that
What did you end up doing?
where is that? content examples? or buried in the engine?
@abstract spindle I expect they're talking about Window > Developer Tools > Debug Tools > Test Suite ... you can maybe find some text in it and ctrl-shift-f your way to the actual code
I don't know where a specific example you'd be looking for is though 😄
yeah just found it, and no this doesn't give me that example
this is likely what they're talking about, but I'm looking to modify a toolbar via c++
are you talking about adding things to or modifying e.g. the main toolbar or entries in one of the submenus of a main toolbar button? like here?
made an editor toolbar plugin, want to know how to make this a drop down menu
void FQuestVRToolsModule::RegisterMenus()
{
// Owner will be used for cleanup in call to UToolMenus::UnregisterOwner
FToolMenuOwnerScoped OwnerScoped(this);
{
UToolMenu* Menu = UToolMenus::Get()->ExtendMenu("LevelEditor.MainMenu.Window");
{
FToolMenuSection& Section = Menu->FindOrAddSection("WindowLayout");
Section.AddMenuEntryWithCommandList(FQuestVRToolsCommands::Get().PluginAction, PluginCommands);
}
}
{
UToolMenu* ToolbarMenu = UToolMenus::Get()->ExtendMenu("LevelEditor.LevelEditorToolBar");
{
FToolMenuSection& Section = ToolbarMenu->FindOrAddSection("Settings");
{
FToolMenuEntry& Entry = Section.AddEntry(FToolMenuEntry::InitToolBarButton(FQuestVRToolsCommands::Get().PluginAction));
Entry.SetCommandList(PluginCommands);
}
}
}
}
it should be generated automatically with the right keywords without having to manually create slate stuff
but there's no info anywhere
@stuck jewel
yeah been a long time since I've tried anything in there and IIRC all I did was modify an existing menu... remember some stuff with MenuExtender and AddMenuExtension but not sure if that's the same process needed for a new menu
there's different functions for existing menus vs plugin menus
@mild oracle @narrow terrace still figuring it out really.. currently the idea is to push a slate event in OnArrangeChildren both pre and post projecting each slot, but it's still a bit tricky.
On that subject though, does anybody know why SConstraintCanvas etc. arranges it's children twice? Once during OnArrangeChildren then again during OnPaint
It's doing all that sorting work at least twice a frame
I would honestly need to take a look since it's been a while since I've looked at the canvas, currently returning from a wedding...
There's also no way to get geometry during a custom prepass is there?
Essentially I have a panel whose geometry/desired size is inferred from it's parent - so I want to be able to get the allotted geometry of the parent during the widgets' prepass, so that child widgets can modify their reported desired size during the first prepass.
is there a way to use a variable for richtextstyles? I want to plugin a color variable for the text
You could try caching it and basing it off of the prev frame, but yeah you can't get geo before it's been calculated because it HAS to account for child geo too and such
You could do this using the format function and feed in the correct color style that you want into that, so it works like a normal rich text block but the text would be more dynamic
you mean format text? I'm already doing that, the problem is the color isn't just blue, red, greed etc, it could be any color with RGB values being widely varied, is there a way I can plugin a slate color, to the text?
it's for a chat message, I want the players name to be the same color as their team, and team colors are custom so they could be any color
the reason I'm using rich text, is so the message wraps correctly and doesn't bug chat
Yeah, realised I'm stuck in a loop. The child widgets' desired size may depend on the parents geometry, so I'm stuck really.
Got there in the end...
The crux is that if a widget wants to change size, it just needs to call "Force Layout Prepass", which prevents any 1/2 frame glitches as it switches up.
I COMPLETELY FORGOT ABOUT FORCE LAYOUT PREPASS! I'm glad that fixes it at least
can i have a custom row that obeys that splitter?
nevermind, had a custom row because i wanted the expandable area, making it a group instead was easier
when i have a customize header, my property shows indented and with the "drag item" icon
top one has no header, bottom one has
any way to remove it?
It is a child of an array, but its expanded to not show the array property
[
SNew(STextBlock)
.Text(FText::FromString(AssetName))
.Font(CustomizationUtils.GetRegularFont())
]```
Can anybody confirm that Paint Geometry is in Desktop Space rather than Window Space?
Trying to use FSlateDrawElement::MakeLines(), and I have to subtract FPaintArgs::GetWindowToDesktopTransform() in order for them to draw in the correct plane, which is making my head spin
The coordinates I'm painting are in Viewport-Absolute Space
So this might be a dumb question, but using the Renderdoc plugin and capturing a frame seems to exclude any Slate UI being rendered to screen. It seems to only include the Scene capture. Is there a way to use Renderdoc with Slate/UMG that I'm missing?
I've asked on the Renderdoc discord and have been told its up to the plugin to determine the start/end of capture, so am currently looking through the plugin documentation
Having a bit of a derp. How do I set a Slate's Slot to use Size Fill?
Ah. Got it figured out. Didn't realize I needed autowidth.
I'm trying to work out what code in the engine is responsible for changing which input box is selected in property panels when pressing Tab, but not having much luck.
I've tried searching for all instances of EKeys::Tab but that didn't pull up much. Does anyone have any suggestions?
what about EUINavigation::Next
Ooh, I didn't know about this one, I'll take a look
I just remember setting up my own navigation rules in my game, but maybe its the same for editor
That was it! Thank you so much!
Hey guys, does anybody know of a good youtuber who provides slate tutorials?
The editor source code is a great one
Sorry, not a Youtuber, but the real doc 😛
Slate isn't game stuff so it doesn't get a lot of tutorials
A little confused with SButton. How are you supposed to be able to create a slot for it?
+SButton::Slot() doesn't seem to work.
How do you change the slot properties on that?
There aren't any
Assuming UMG. If I put Text in a button I can set it's padding, and alignments.
Just wondering how to do the same in Slate.
Pretty sure you need another widget for that
Personally I subclass SButton so I can do ChildSlot .VAlign(VAlign_Center) .HAlign(HAlign_Center) [
Just started learning actual Slate. 😄 Maybe it's time to ditch SButton anyhow. Couple things about it I wanna fix.
On a side note though. Apparently you just specify it directly on the button instead of the slot.
SNew(SButton).HAlign(HAlign_Fill).VAlign(VAlign_Fill).ContentPadding(FMargin(6.f))
[
SNew(STextBlock).Text(FText::FromString("X")).Font(Font)
]
Ah, yeah, makes sense
Personally i've got a button class that inherits SButton and reimplements essentially half of it
Does anyone know what is being called when doing this drag and drop interaction in the editor?
https://twitter.com/_benui/status/1469479577646866432
It'd be neat if I could drag a group of assets onto an exposed TArray<TSubclassOf<T>> in #UnrealEngine
Maybe it's another pull request I have to make? https://t.co/KxxwxcCFKF
hmm I believe you would need to take a look at SDropTarget class
There are methods such as:
bool AllowDrop(TSharedPtr<FDragDropOperation> DragDropOperation) const;
virtual bool OnAllowDrop(TSharedPtr<FDragDropOperation> DragDropOperation) const;
virtual bool OnIsRecognized(TSharedPtr<FDragDropOperation> DragDropOperation) const;
Neat, I'll try setting breakpoints there and start poking around
I'm trying to access the selected folders in the world outliner, but I've seen GetSelectedFolderNames in SSceneOutliner is private, is there any other way to access this data or get an equivalent one?
@mild oracle Saw your blog post on List View, nice one! A couple of times I've tried to use it though, I run into the same limitation: headers. If you work around it by having multiple list views, separated by header widgets, you don't get an unbroken scrollbar for scrolling the whole thing.
I've tried 2 methods to get around this. One is to set a bool on the list item object to tell the generated widget to show/hide parts of the widget depending on whether it's a header or not. The other is to have the generated list item be a simple named slot and in On Entry Generated, call a function which tells it to construct a header and slot it, or construct a regular item and slot it. It feels hackish though, and I'm not satisfied. Also, when I tried it with a tree view, the list items would randomly reorder themselves, moving out from under their headers.
What I think I might try next is subclassing listview and instead of Add Child, a new function that receives a header object and entire batch of entry objects at once to draw under that header, so that the association and ordering can be preserved. The other limitation that would have to be removed is all generated entries using the single hardcoded Widget Entry Class property. A TMap of Object Class to Widget Entry Class would allow any passed-in object type to produce a corresponding widget for that object.
I'm developing a custom graph editor following Flow Graph by MothCocoon but when I save the graph, close and reopen Unreal Engine, all connections disappear. What could possibly be the reason the connections not saving with the asset?
After debugging it looks like UEdGraphPin::LinkedTo is empty after reopening editor. But why...🤔
Issue fixed. Was missing these implementations:
// variants of K2Node methods
void RewireOldPinsToNewPins(TArray<UEdGraphPin*>& InOldPins);
void ReconstructSinglePin(UEdGraphPin* NewPin, UEdGraphPin* OldPin);
// --
why is the umg drag drop operation so impenetrable.. i just want to make a slate drag drop operation that is a drop in replacement that doesn't have position lerping at the start of the drag
but UMGDragDropOperation is totally locked down
I think I ended up making my own drag drop operation class that implemented the same interface.
Edit: OK yeah I made my own that subclasses FGameDragDropOperation
I used it to make a drag and drop vertical box that is basically a modified version of SDragAndDropVerticalBox
i'm trying to do this now, just need to figure out how to wire into the creation of drag drop operations
is your code online anywhere?
Sorry no it's made for work and I don't have permission to open-source it (yet)
I can post little bits I guess:
FReply UBYGDragAndDropVerticalBox::HandleDragDetected( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent, int32 SlotIndex, SVerticalBox::FSlot* InSlot )
{
// Find the thing we're trying to drag
// ...
return FReply::Handled().BeginDragDrop( FBYGVerticalBoxDragDropOp::New( /*...*/
Basically I would recommend looking at how HandleDragDetected is used in other places
@cobalt hare SHierarchyViewItem.cpp has some good examples of HandleCanAceptDrop
🙏 thanks ben, this is really helpful
you're welcome! I'll see if I can get our stuff cleaned up and open-sourced over the break maybe... maybe?
<@&213101288538374145> hmm already banned i guess 🤔
:warning: Failed to send a DM. User will not be notified.
:no_entry_sign: ROYALKINGSJ#2266 was banned.
is there a way to remove the arrowhead on the spline that connects 2 node pins?
Is there any way to implement a custom slate for USTRUCT()s?
I have a struct exposed to BPs like this
Weight variable determines the count of the element in the game, when they're utilized in C++. Since its a dynamic value, I want my designers to see something like this:
If total count would be 100, with 0.05 of Weight you would get ~5 enemies in the game
But I don't want to write a something from scratch, if possible I'd like to modify the default USTRUCT() panel
@glad elm Details customization
Is the magic word
You can make one per Object or Struct
And that allows you to design how your struct gets visualized and also react to certain values changing
I think a good candidate for looking at an example is the FDataTableRowHandle
It creates a drop-down from the Datatable property and saves the selection in a name variable iirc
🥳 Great, thanks for explaining eXi
No biggy. Sadly don't have an example at hand. haven't used them in a while
I think your register them in your module
Fwiw
Files in engine are usually called structname+customization or so
You can then just follow around where the use the struct and the customization type
It's straight forward to add it. The slate part is the shitty part
Np, "magic keyword" was enough on its own 🙂 I found some GAS examples (FAttribute etc.) -- they serve as a good documentation right now
Coolio
Property customization for an individual struct, not details customization though. They're different. Very confusing when you're just learning
@glad elm
has anyone tried using UWidget::TakeDerivedWidget()? i'm trying to replace the object widget used by a subclass of UUserWidget with my own subclass of SObjectWidget following this comment in Widget.h:
For extremely special cases where you actually need to change the the GC Root widget of the constructed User Widget - you need to use TakeDerivedWidget you must also take care to not call TakeWidget before calling TakeDerivedWidget, as that would put the wrong expected wrapper around the resulting widget being constructed.
but i can't figure out a reliable place to call TakeDerivedWidget before the UMG blueprint editor starts invoking functions that call TakeWidget
sorry I screwed off but basically a details customization allows you to modify the entire details pane (which basically will always be for a uobject, yes) and a property customization allows you to change how an individual property can be automatically drawn within its assigned row in a details pane (like an FVector, but also IIRC this can be used to affect how an instanced UObject property is drawn when a UObject is used as a property too)
How do I expose slate widget to umg so I can use it in widget blueprint?
You can't put UPROPERTY in slate afaik, so you can't expose it without having to duplicate each Slate property in your UMG wrapper, afaik. Look how UButton and SButton work.
If you're just talking about embedding a Slate widget I think there's a widget called native hosted widget or something like that.
oh thanks a lot!
UNativeWidgetHost saving my life atm ty
Ah that's the name thanks :D
I never tried to use it, I'd be curious what it's like and how it helps
I have problem that my old code have compile error with ue5
MemoryOps.h(217): [C2280] 'SSplitter::FSlot::FSlotArguments::FSlotArguments(const SSplitter::FSlot::FSlotArguments &)': attempting to reference a deleted function
any tips what could have changed in the last commits of ue5 - main?
Slots have been completely remade
Not many examples to use right now
Look in the engine source essentially
i ended up not needing it -- i went around and around trying to figure out a way to do what i wanted 🙂
i wanted a custom drag drop operation (without the position lerping animation at the start of the drag) that i could use on otherwise normal UUserWidgets. FUMGDragDropOp is instantiated when SObjectWidget detects a drag event, so at first i tried replacing that behavior with a subclass of SObjectWidget -- but i couldn't figure out how to replace it in the UUserWidget. you are supposed to use TakeDerivedWidget for this, but the trick is that to use this you need full control of the instantiation of the UUserWidget, which, if you are building a UI in UMG, you don't.
so i went around and around trying different approaches, but ultimately i ended up creating a UUserWidget subclass that inserts an additional SObjectWidget (my subclass with a custom drag drop op) in between its root SObjectWidget and the WidgetTree that contains its actual content. all it does is listen for drag drop events that involve my custom drag drop op and forwards those to my UUserWidget. works great!
Hi, is there any way to get touch position on entire screen or on UMG Element comsumes click event like Button or CheckBox?
I've tried used APlayerController::GetInputTouchState() when touch world, and UUserWidget::NativeOnTouchStarted() when touch UMGs.
But when I tried to get touch position on UButton and UCheckBox, click event was consumed in FSlateApplication::RoutePointerDownEvent().
Is there any way to get touch position on entire screen or on UMG Element comsumes click event like Button or CheckBox?
Is this in VR?
@thick pasture Nope It's on Android
Hello, I am trying to understand how to customize details panel using Slate. I am not able to find any good reference for it. Can anyone help me with some info on it ? Thanks
I would highly recommend looking at the source for references
Was there a way to get the "default" widget for a Property? I'm in the function to return a ListView Row and I would like to use the Item (TSharedPtr<Struct>) with its normal widgets for the properties (a TSoftClassPtr and an int32).
Hmm that comes from IPropertyHandle but I don't know how to create one of those from a bare property
I changed the ListView to just be based on the PropertyHandle of each of my array entries
Seems to work :D
Hm, how does one make sure that the Splitter of the row follows the other splitters ? :<
The 2 next to Count are mine :D
Are you using detail customization or property customization?
Property
I have a Struct (which I'm customizing) with an Array of Structs in it.
The inner Struct has a SoftClass and an int32 in it.
I wanted to change it so I can filter with an SSearchBox
But I fail to create an SListView based on the Array
Usually using the separate methods to create name and value sides should work I think... are you doing that, or are you using the single customrow method?
TSharedRef<ITableRow> FActorPoolDefinitionCustomization::MakeListViewWidget(TSharedPtr<IPropertyHandle> Item, const TSharedRef<STableViewBase>&O wnerTable)
{
const TSharedPtr<IPropertyHandle> classPropertyHandle = Item->GetChildHandle("Class");
const TSharedPtr<IPropertyHandle> countPropertyHandle = Item->GetChildHandle("Count");
return SNew(STableRow<TSharedPtr<IPropertyHandle>>, OwnerTable)[
SNew(SSplitter)
.Style(FEditorStyle::Get(), "DetailsView.Splitter")
.PhysicalSplitterHandleSize(1.0f)
.HitDetectionSplitterHandleSize(5.0f)
+ SSplitter::Slot()
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
[
classPropertyHandle->CreatePropertyNameWidget()
]
+ SHorizontalBox::Slot()
[
classPropertyHandle->CreatePropertyValueWidget()
]
]
+ SSplitter::Slot()
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
[
countPropertyHandle->CreatePropertyNameWidget()
]
+ SHorizontalBox::Slot()
[
countPropertyHandle->CreatePropertyValueWidget()
]
]
];
}
I do this atm
void FActorPoolDefinitionCustomization::CustomizeChildren(TSharedRef<IPropertyHandle> PropertyHandle, IDetailChildrenBuilder& ChildBuilder, IPropertyTypeCustomizationUtils& CustomizationUtils)
{
const TSharedPtr<IPropertyHandle> definitionsHandle = PropertyHandle->GetChildHandle("Definitions");
BuildEntryList(definitionsHandle);
ChildBuilder.AddCustomRow(FText::FromString("Entries"))[
SAssignNew(EntryListView, SListView<TSharedPtr<IPropertyHandle>>)
.OnGenerateRow(this, &FActorPoolDefinitionCustomization::MakeListViewWidget)
.ListItemsSource(&EntryList)
.SelectionMode(ESelectionMode::None)
];
}
Gotta leave office now, but will read when I'm home
so I can see why the problem occurs... you're making your own splitter... but not entirely sure if I know a solution. you have a single struct that defines each row right? but you haven't created a property customization for that particular struct? I think you should try doing that. In the struct's property customization, build its NameWidget and ValueWidget manually (by stacking both the inner Class or Count property's Name and Value widgets inside a single SHorizontalBox for each). And then for your MakeListViewWidget, don't create your own splitter. This way your struct entry (the actual thing being displayed by your list) is a single row with a regular Name and Value widget... I think/hope this will display how you want it then
thinking more, the next problem with what I've just said is that I don't know how the MakeListViewWidget method's return TSharedRef<ITableRow> lets you define a row entry that has Name/Value widget or just draw the widget for the whole struct
I thought there was a method for a property handle to just build the whole thing but can't find it right now
I wonder if you might need to dig into TArray somehow to look for clues first. I'm pretty sure what I described above would render correct if you didn't create a custom listview widget but just displayed the array (ChildBuilder->AddProperty(definitionsHandle) I think)
@stuck jewel THanks for your time, I couldn't find time to read your answer up until now
I would also much prefer just having the singleproperty row
I know that's somewhat the widget
I will probably not be able to render it with one single splitter width for the whole thing, because that is handled by the SDetailsViewBase
There it has the columnWidth and that is passed into all the Splitters it creates
But I would be find if mine are shared within the widget, which should work if my details customization stores a value of how big the column is and passes that into each splitter, similar to the details view
That said, having a proper single row would be nice
--
I might have found a solution
Hm, nvm. Tried to just use the ChildBuilder, but I can't refresh the list like this
I have problem that this fucntion doesn't call for me
TSharedRef<IDetailCustomization> IAUSConsiderationVisualization::MakeInstance()
{
return MakeShareable(new IAUSConsiderationVisualization);
}
and this too
void IAUSConsiderationVisualization::CustomizeDetails(IDetailLayoutBuilder& DetailLayout)
so i wrote in my main game module this and StartupModule() calling any ideas what im missing?
#if WITH_EDITOR
#include "PropertyEditorModule.h"
#endif
#define LOCTEXT_NAMESPACE "FIAUSModule"
IMPLEMENT_PRIMARY_GAME_MODULE(FUEPrototypeModule, UEPrototype, "UEPrototype");
void FUEPrototypeModule::StartupModule()
{
#if WITH_EDITOR
FPropertyEditorModule& PropertyModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor");
PropertyModule.RegisterCustomClassLayout("IAUSConsiderationVisualization", FOnGetDetailCustomizationInstance::CreateStatic(&IAUSConsiderationVisualization::MakeInstance));
PropertyModule.NotifyCustomizationModuleChanged();
#endif
}
void FUEPrototypeModule::ShutdownModule()
{
}
#undef LOCTEXT_NAMESPACE
Usually editor customization is kept in an editor module. It probably won't work in a main game module
hmm thank you, ill try to change it
While the above is mostly true, the issue seems to lie with the first parameter in the register function. It's supposed to be the name of the class you want to customize, not the name of the customization. A better way to do this is to use
UMyClass::StaticClass()->GetFName()
This establishes the link between class and its customization
Thanks a lot for the clarification
Hey there guys! I'm looking around trying to figure out how to delete items in a tile view using the delete key, how would I start?
Not sure what delete key you are talking about, but generally you'd remove the item from the array the view is observing and call a refresh function on the view
yeah it's actually getting the slate to do something when the delete key input is pressed that I'm not getting
Ah, sorry, misunderstood the question. I was thinking of a map key..
Let me boot up my PC and see what I can find
Oh I did find overriding the OnKeyDown virtual function from SWidget works haha
thank you though! I appreciate the help
Haha, I was about to suggest that as I initially figured you had tried that out already
nah I'm only just starting haha, thanks
all good 👍
so I'm using this to delete the items in my STileView
FReply STextureBrowser::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent)
{
if (InKeyEvent.GetKey().ToString() == "Delete")
{
TArray<UTexture2D*> ListItemsSource = *ItemsSource;
for (UTexture2D* ItemToDelete : this->GetSelectedItems())
{
ListItemsSource.Remove(ItemToDelete);
}
SetListItemsSource(ListItemsSource);
RequestListRefresh();
GEngine->AddOnScreenDebugMessage(-1, 5, FColor::Green, InKeyEvent.GetKey().ToString());
}
return FReply::Handled();
}
``` When I now press delete, it throws me a breakpoint
in SListView
apparently the ptr is no longer valid, you'll need to check what and why, i.e., is CurItem pointing to an item you have just deleted or is it something else? The call stack would also be useful
A few things for better form:
- Instead of using
GetKey().ToString()useGetKey() == EKeys::Delete - You shouldn't need
SetListItemsSourceif the source is the same as before. In fact it won't do anything if it's the same source, a refresh is enough. The list view isn't copying the array contents, just a pointer to the array. You have both an ItemsSource and a ListItemsSource so not sure what you are doing here
ah ok, I think I see the problem. Your ListItemsSource has a limited lifetime as it's destroyed when it goes out of scope, but since the list keeps a pointer to the array it points to garbage.
Make the ListItemsSource a member of your widget class instead
ah right!
thank you!
@split laurel So I've added the ListItemsSource in my class and removed the SetListItemsSource
trying it now, but will it fail because it's not copying the contents of the array?
your SListView will need to point to your source a single time unless you want to give it a completely different source (different address in memory)
so ideally you'll give your list view the ListItemsSource as source upon creation and then you'll only modify that array and call Refresh
ah, and how would I remove an element from that source inside the widget itself?
you'd do what you did before, call ListItemsSource.Remove(TextureObjectPtr);
then call View->Refresh()
the only difference being that your ListItemsSource no longer gets destroyed
hmm, no more error, but the texture isn't deleting when I hit delete
set a breakpoint to check if the array is being properly modified etc.
I think ListItemsSource is beeing modified, but not ItemsSource
yeah you need to modify the source that your view is using. Can you show me where you instantiate the view? (the SNew part)
+ SWidgetSwitcher::Slot()
[
SAssignNew(PaletteTileWidget, SPaletteBrowser)
.SelectionMode(ESelectionMode::Single)
.ListItemsSource(&PaletteTextureItems)
.OnGenerateTile(this, &SLiveryEditorToolView::OnGeneratePaletteTextureTile)
.OnSelectionChanged(this, &SLiveryEditorToolView::OnPaletteTextureSelectionChanged)
]
``` this is in another compound widget
that's fine
but yeah so this is pointing to PaletteTextureItems which is now your ItemsSource within the widget
so simply modify ItemsSource itself I guess?
unfortunately, I can't remove from ItemsSource
the reason why I did the whole ListItemsSource thing
ah yeah, it's const. Do you know how delegates work?
as in, how you create them yourself and make use of them
I do, that was my plan B
then I'd do that, it's the cleanest route. There are a couple ways you could do it from within the widget but none of them are pretty
I was hoping to keep it all in this class for now, but I guess it's unavoidable
thanks for the help and your time
if you are 100% confident the only use case you'd ever want here is one specific thing (widgets are made to be reusable) you can also use a const cast
to get rid of the const
but I don't recommend it, it's unclean code
yeah, I'll just use delegates, it's a little safer
👍 I'm thinking of something like a "OnDeleteSelection"
or "OnDeleteKeyPressed", since it's not doing anything
yeah, or that, it really depends on how configurable vs. intentional you want to make this
with OnDeleteKeyPressed you are implying an inherent link to the delete key, but maybe you'll want another action within the widget to do the same (i.e. a "Remove Selected" button) later on. Just something to keep in mind
ah yeah, good point
sorry for getting back on topic, but i still have this problem. I moved PropertyModule initialisation from main game module to separate module. Also changed first param
void FIAUSModule::StartupModule()
{
#if WITH_EDITOR
FPropertyEditorModule& PropertyModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor");
PropertyModule.RegisterCustomClassLayout(UIAUSBaseConsideration::StaticClass()->GetFName(), FOnGetDetailCustomizationInstance::CreateStatic(&IAUSConsiderationVisualization::MakeInstance));
PropertyModule.NotifyCustomizationModuleChanged();
#endif
}
You shouldn't need the with editor stuff if its in an editor module. In your uproject/uplugin file is the new module set to editor type?
you right? but its doesn't matter, this StartupModule() function calling and function inside it, but &IAUSConsiderationVisualization::MakeInstance not
right, but is the module configured as a "Editor" module?
something like:
{
"Name": "IAUSModule",
"Type": "Editor",
"LoadingPhase": "PreDefault"
},
As Editor
if I have a FSlateTexture2DRHIRef or similar... how can I get a UTexture2D to render in a widget? 🥲
I am going insane trying to convert this 🥲
are you showing any objects of type UIAUSBaseConsideration in the details panel or only subclasses thereof?
I believe customizations don't apply to subclasses but only the specified class
just making sure here, but MakeInstance is only called when a details panel is actually shown. So it won't be called at startup. You have to select an object of the type in the details panel first.
this is my class organisation and i want expand UECSIAUSResponseCurve to draw my curves in inspector.
Also MakeInstance didn't call if i choose curve type there
IAUSConsiderationVisualization has TSharedPtr<class IAUSCurvePreviewWidget> PreviewWidget; where IAUSCurvePreviewWidget has TWeakObjectPtr<class UECSIAUSResponseCurve> ResponseCurve;
Your linear curve class won't inherit the customization of its parent is what Herr edgy is saying. Your linear curve class needs to also be added to your editor module with the customization and the polynomial as well
Each class you want to customize needs to be added individually
If you have reusable customizations that makes this needlessly repetitive then you can put those properties in a struct and customize the struct instead, so that any class with that property will get the customization
thanks a lot for clarification and the explanation
Hey. I am looking for OnFocused event on a button. It seems there is none. The slate class SButton for some reason does not even override this callback. Any reason why?
Preferably without changing the engine I would like to fix this.
My first idea was to just inherit SButton but it does not seem to be that simple as there are multiple macros and the constructor is just confusing me.
We have a internal version of Button so I can easily change which slate class it creates.
What about:
virtual FReply OnFocusReceived(const FGeometry& MyGeometry, const FFocusEvent& InFocusEvent);
Part of SWidget
Yes. I know. But I would either have to change the engine implementation of SButton or create a "mirror class" of SButton 😦
Example of a SButton child class here if you want to clear up the syntax: https://github.com/arbonagw/AstralShipwright/blob/master/Source/AstralShipwright/UI/Widget/NovaButton.h
rename the url for the .cpp
Thank you so much for that. Finally a working exampe. I could not find anything no matter the google query 🙏
I'll say upfront that I'm probably overlooking something incredibly stupid, but I'm trying to get a HorizontalBox with 2 columns where the first column expands until it reaches a maximum size and the 2nd column expands to fill the rest of the available width.
If I do this, it kinda works but stops filling at 2 x my limit:
TSharedRef<SHorizontalBox> Preview = SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.FillWidth(1.0f)
.MaxWidth(400.0f)
.Padding(0.0f, 0.0f, 2.0f, 0.0f)
.VAlign(VAlign_Top)
[ PreviewThumbnail ]
+ SHorizontalBox::Slot()
.FillWidth(1.0f)
.Padding(0.0f)
.VAlign(VAlign_Top)
[ PreviewData ];
have you tried dumping .AutoWidth() in either side? (and remove FillWidth)
yeh tried that first
I simplified my example and added some pictures to help explain my issue
TSharedRef<SHorizontalBox> Preview = SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.FillWidth(1.0f)
.MaxWidth(400.0f)
[ SNew(SImage).ColorAndOpacity(FLinearColor::Red) ]
+ SHorizontalBox::Slot()
.FillWidth(1.0)
[ SNew(SImage).ColorAndOpacity(FLinearColor::Blue) ];
the above 2 are examples of it working as I want for sizes under 800, here's what happens over 800
TSharedRef<SHorizontalBox> Preview = SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.MaxWidth(400.0f)
[ SNew(SImage).ColorAndOpacity(FLinearColor::Red) ]
+ SHorizontalBox::Slot()
.AutoWidth()
[ SNew(SImage).ColorAndOpacity(FLinearColor::Blue) ];
TSharedRef<SHorizontalBox> Preview = SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.AutoWidth()
.MaxWidth(400.0f)
[ SNew(SImage).ColorAndOpacity(FLinearColor::Red) ]
+ SHorizontalBox::Slot()
[ SNew(SImage).ColorAndOpacity(FLinearColor::Blue) ];
TSharedRef<SHorizontalBox> Preview = SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.AutoWidth()
.MaxWidth(400.0f)
[ SNew(SImage).ColorAndOpacity(FLinearColor::Red) ]
+ SHorizontalBox::Slot()
.AutoWidth()
[ SNew(SImage).ColorAndOpacity(FLinearColor::Blue) ];
lol i love slate
My goal is for Column A to be (200 - 400) and Column B to fill the rest
I was told it is awesome
This is the easiest thing in the world to do in every other UI so I'm either missing something simple or Slate is worse than I thought
oh did you play with the alignment settings too already? .HAlign(fill) or whatever it is?
yeh btw that is the default value for that prop
also I should say I'm willing to use whatever widgets get me to my goal, this doesn't need to use SHorizontalBox
In some other UI toolkits you can make a grid that allows you to set min/max widths for columns or allow you to set them to fill; something like that would work awesome for me. All I saw was uniform grids and dynamic grids that allow you to weight columns (but not just some columns)
ie
Columns[0].MinWidth = 200.0f;
Columns[0].MaxWidth = 400.0f;
Columns[1].Fill = true;
yeah this does seem to be an oversight, i feel like i've made this for UMG though...
I could only get it to do the same stuff, was using UMG to test ideas
So after looking at ArrangeChildrenAlong in SBoxPanel.cpp it will never work the way I want because children are tracked as either "fixed" or "stretched". If a child is stretched, it needs a non-zero stretch coefficient. That means I'll never be able make it weight 50/50 until max for column A and then just fill with column B
Guess I'm going to need to make my own classes that override this and behaves the way I think they should already, shouldn't be much to change in this function
what you can do without modifying (and it's easy) is a fixed size with a fill; that might be what you were thinking of
yeah i think so too
really thinking of just making the grid style I like and giving it out as a plugin
@stuck jewel Success on my immediate needs btw. Just needed to change the behavior from around SBoxPanel.cpp:125.
Here's the engine version:
// Clamp to the max size if it was specified
float MaxSize = CurChild.MaxSize.Get();
if (MaxSize > 0)
{
ChildSize = FMath::Min(MaxSize, ChildSize);
}
Here's my version:
// Clamp to the max size if it was specified
float MaxSize = CurChild.MaxSize.Get();
if (MaxSize > 0)
{
if(MaxSize < ChildSize)
{
if (CurChild.SizeParam.SizeRule == FSizeParam::SizeRule_Stretch)
{
NonFixedSpace -= MaxSize;
StretchCoefficientTotal -= CurChild.SizeParam.Value.Get();
}
else
{
NonFixedSpace += ChildSize - MaxSize;
}
ChildSize = MaxSize;
}
}
I'm using it with these parameters:
TSharedRef<SHBox> Preview = SNew(SHBox)
+ SHorizontalBox::Slot()
.FillWidth(1.0f)
.MaxWidth(400.0f)
[ SNew(SImage).ColorAndOpacity(FLinearColor::Red) ]
+ SHorizontalBox::Slot()
.FillWidth(1.0f)
[ SNew(SImage).ColorAndOpacity(FLinearColor::Blue) ];
Why are you making this with slate?
Are you making an editor UI element?
I am using slate because I need to and yes I am making an Editor UI element
specifically I am making an Import dialog
I just didn't like how SHorizontalBox was laying out children when some have a max size
anyway I don't know why I forgot about making gifs earlier, but here is what SHorizontalBox does with the exact same parameters
Lol congrats
do you think that's intended behavior or a bug?
even if it is a bug I doubt they'd wanna change this class' behavior
I don't think it's intended, but at the same time I don't think they care very much. XD
You can fix the engine, and make a pull request.
Have you tried wrapping that SHorizontalBox in an SBox and set its WidthOverride to 400?
no because that doesn't even describe what I'm trying to achieve
what I just posted above does exactly what I want
ok
well I'm just saying that doesn't even make any sense based on what I described
don't worry about it, got confused of all those 5-6 code segments that do nothing :))
well none of them do nothing and the only reason there are so many is because I was posting things I knew didn't work that hojo asked me to try
yeah I know I can make a pull request. as you can see I've already found and fixed the issue on my end. My question was about whether or not I should bother.
have you filed any pull requests before? what is your experience with dealing with Epic in this regard?
They responded very fast (in one day) after a pull requrest.
Regardless of the result, your name will be placed on the UE editor credits(Community Developerers Section).
Regardless of the result, your name will be placed on the UE editor credits(Community Developerers Section).
Yeh honestly that's more of a reason to avoid doing so for me. I just want things working, I don't want to be credited or associated
FSlateDrawElement::MakeBox
How do i disable hittest when manually draw Slate?
Depends on the visibility of the widget doing the drawing
The hitbox itself is always rectangular, based on the geometry of the widget.
Is there a function I've missed like MakeCircle or am I best off just drawing a spline?
im trying to use loading screens in 4.26 and i get this slate crash
ue4 Assertion failed: IsInGameThread() || IsInSlateThread() || IsInAsyncLoadingThread() [File:Runtime\Slate\Public\Framework/Application/SlateApplication.h] [Line: 225]
what might i need to look into here?
You'll need to look at the full callstack
Hi all, I'm new to Mac dev with Unreal and having a weird problem with my slate UI. When I click down on a button, then release, the cursor jumps to the same spot on the screen (upper right corner for some, lower left of center for others). This does not happen with my UMG UIs, just the slate ones. It does not happen in windows. It seems to not happen if I step through the code (I think because the editor looses focus), it happens in the editor, standalone, and in packaged game on the Mac. Any ideas on where to start troubleshooting this?
Also, I'm on 4.25.4 Big Sur
Hey guys! I got a question for you. We're trying to run a simulation in one window and show a little log in an SWindow. However, if we click on the Swindow to interact with it at all, it freezes the original application. Is there any way to have both run at the same time? Or disable the freeze on the original window?
is slate better than UMG?
Umg is slate. It's just a object oriented wrapper around slate widgets to expose it to the editor. Therefor slate can do anything umg can do and more. In that way it's better I guess. But you also have to deal with using slate, which is a spine rending pit of madness half the time and incomprehensibly obtuse at its best. That's not to say I don't like it. I do, but I gotta be realistic that it's one of the least untuitive parts of unreal.
My advice, and most people's, is to use umg if you can and use slate if you must. That means that if you really need to add some core underlying functionality to your UI, then slate might be your only option. But 99% of the time there is no need. Save the frustration for that 1%.
thats unfortunate
I was hoping to find an alternative to UMG
I find components like Spacer that has a fill button not filling to be very frustrating
then asking around in several places and nobody knows how to resolve
Well all I can say is that spacers are mostly redundant and serve the same purpose as adding padding to the slot. I never use them. You are probably trying to use it to solve something that it's not meant for
thanks for your insight @limber stump
I was pulling my hair out
chats with you and a few othesr helped point me in the right direction
I appreciate the tip about UI frameworks too
will look into that
as for your Q ... corner
as I didn't wanna waste space and bring everything down a bit
Noice. Slate is fun to play with eventually once your are already fluent in Umg and know how to expose slate widgets to it. Additionally, if you ever get into making editor ui, it's all written in slate, which is why I know how to write it, so then it's a required skill to have. But for gameplay ui it's usually not needed.
getting there
that 1st one ... will lead to a help page
or I could make it invisible just to keep things aligned
that size box is handy
How do i properly close a popup window?
TSharedRef<SWindow> Window = SNew(SWindow)
.IsPopupWindow(true);
FSlateApplication::Get().AddWindow(Window);
It closes when out of focus, but still receives clicks
Are there no examples in the engine?
There are some, but i cant figure out what i'm doing wrong
Also most use Modals which I don't want
used PushMenu instead of AddWindow and now its working perfectly
I'm not sure about internals but I'd suspect adding a window opposed to a menu will mean you need to manually destroy it. You can call something like Window->RequestDestroy() to manually get rid of them. For anyone interested
howdy - what is the correct way to remove SWidgets from containers and destroy them? I have myself SVerticalBox where I put my own widget inheriting from SCompoundWidget and I don't know how to remove them. I see DeleteSlot in the VBox, but that requires me to have TSharedRef to the widget i want to remove, which I don't have since they are added dynamically and can be a lot of them. Is there something like UMG's RemoveFromParent?
Need to make a cursor that inverts its color and the inverted colors are based on the widget(s) below it. Any tips?
Hey, I was wondering if there was such thing as a unreal engine 5 theme for unreal engine 4, to make UE4 look like UE5.
Hey, I was wondering if there is a way to know the size of a Slate widget that is inside a ScaleBox. If the widget is inside a CanvasPanel I can just check the slot size for the widget, but I don't know how to check for the size if it's inside a ScaleBox
There is UdataAsset. Here are classes within classes, etc. I want to write a custom option mapping for a selected class inside a UdataAsset like in the screenshot.
I wrote in the module registration for a specific class UIAUSLinearCurve
PropertyModule.RegisterCustomClassLayout(UIAUSLinearCurve::StaticClass()->GetFName(), FOnGetDetailCustomizationInstance::CreateStatic(&FIAUSSonsiderationVisualization::MakeInstance));
But methods
FIAUSConsiderationVisualization::MakeInstance() and
CustomizeDetails(IDetailLayoutBuilder& DetailLayout) are not called.
They are called if I write a registration for the UdataAsset itself
PropertyModule.RegisterCustomClassLayout(UdataAsset::StaticClass()->GetFName(), FOnGetDetailCustomizationInstance::CreateStatic(&FIAUSConsiderationVisualization::MakeInstance));
and even if i do this way how to get to the data inside such a hierarchy
hello, is there any built-in SWidget for something like "actor list box" to which actors from a level can be drag and drooped?
how do people here understand the slate syntax 😅 What is the brackets [] equivalent in C++ syntax, are these operators overload?
It's all operator overloading
[] is generally a slot, usually the default slot
X->AddSlot() / X->SetContent() may work
Oh I see thanks, is there some sort of visual studio extension that format/lint slate syntax? Having trouble finding something similar