#slate

1 messages ยท Page 8 of 1

grave hatch
#

If you want to limit teh height of the scrollbox, but let the internal content be any size, you should put the sbox outside the scrollbox (sbox -> scrollbox -> anim container)

#

Whether you actually need the sbox's heightoverride is also questionable (you may still need the width override, I'm not sure if the scrollbox has a max width) - the scrollbox's maxheight may sort the height for you.

solemn saffron
#

Thanks for the working example, @hexed jungle. I was searching around a lot, but apparently my Google skills aren't yet at the level of Wizard.

And thanks for the detailed explanation, @grave hatch. When I get home from work, I will implement something following the guidelines you suggested (while also comparing to the example provided by Squize). A lot of what I'm doing right now is pure trial and error, and most of my trials lead to some sort of error. I'm grateful there are people like you around willing to offer some guidance.

grave hatch
#

๐Ÿ‘

grave hatch
#

Not sure then. Debug the source code!

solemn saffron
#

Using the helpful responses [here](#slate message) and [here](#slate message), I rearranged my original code to now be what I show below, and it works as intended. ๐Ÿฅณ

SNew(SBox)
.WidthOverride(150.0f)
.HeightOverride(150.0f)
[
    SNew(SScrollBox)
    .Orientation(Orient_Vertical)
    .Visibility(this, &SMCTDialog::GetVisibility_AngleOfAligningAxis)
    .ScrollBarAlwaysVisible(true)
    .ConsumeMouseWheel(EConsumeMouseWheel::Always)

    + SScrollBox::Slot()
    [
        AnimContainer.ToSharedRef()   
    ]
]

Maybe someone in the future will find my snippet helpful.

Thanks for the help, guys. I'll probably be back with more questions, but we shall see.

EDIT: Removed .MaxSize(500.0f) from the SScrollbox slot.

grave hatch
#

Why do you need a max size on the scrollbox slot?

stray heath
#

Can I somehow set a child of an object at index 0 without having to remove the other children at runtime? Because HorizontalBox->InsertChildAt(Index, Widget) doesn't work without removing another child, if that child is already at 0.

grave hatch
#

It should ๐Ÿ˜ฆ

#

Or do you mean you're inserting a widget at 0 that's already in the tree at 0?

stray heath
grave hatch
#

So you want to display single widget which changes when you hover over it with the mouse?

stray heath
#

Yeah. I might of found a work-around. Instead of calling the same widget that's in the main widget, I'll just create a new widget of that type and display that one when hovering over an icon instead. That way I won't need to reference the one in the main widget at all.

grave hatch
#

Or use a widget switcher?

stray heath
grave hatch
#

It's a widget that displays 1 of its child widgets at a time.

#

SWidgetSwitcher I think?

#

You set teh active widget by index.

stray heath
#

Oh, I'll check into that! Didn't know that was a thing ๐Ÿ˜„ Thank you

wind temple
#

Does anyone know a course or something like that to learn slate?

grave hatch
#

Never heard of one. There are some useful pinned messages in here, though.

solemn saffron
celest locust
#

Is it possible to override the new line behaviour for rich text box?

grave hatch
#

If you find out...

celest locust
#

Do you want me to let you know?

grave hatch
#

Yeah ๐Ÿ‘

tulip otter
#

can you give me some pointers or resource link on reimplementing the stuff ???

grave hatch
#

We don't even know what stuff you're using...

tulip otter
#

i am writing a logic to handle the import of fbx in cpp slate, for which i require ImportTask and Fbc factory funcs.

grave hatch
#

If any of those functions are in Editor or Developer folders, you can't use them. Which I'm assuming they are because of UnrealEd module.

#

So you'd need to completely rewrite all of it.

#

Nobody is gonna help with that.

#

Or find some sort of non-gpl library that does it.

earnest oracle
#

I realize this might be better suited to ask here

#umg message

grave hatch
#

Have you tried TakeWidget()->GetChildren()->InsertWidget I think might be a thing

#

I've no idea what UMG has in that respect.

hollow wasp
#

Hello Everyone,
I am having a problem with SWindow, I create a new window to show the widget(made in UE editor) on the second screen and the widget have 3 sliders, those slider control some property of the project. So the problem that I am is when I move the slider it multiplies it button. but the property changes in the game just fine, Only the Widget looked messed up.
There is one thing that I noticed when I resize the window then it corrects the sliders.

#

Here is the messed up widget Screenshot

grave hatch
#

It sounds like it's not clearing the background

hollow wasp
#

yeah, do you have any suggestion on how to clear this? Or maybe it's not being updated frequently. There must be some boolean variable to fix this.

grave hatch
#

Is there a full-window widget?

#

Like a background.

#

Add one if not.

#

Something that actually renders something - like an SBorder.

#

There migth be an swindow option?

#

Something clear-related.

hollow wasp
#

yeah, At the moment there is nothing in the background

#

let me add and try

grave hatch
#

If you want it black, you can just use a black color block to fill the background.

hollow wasp
#

@grave hatch, You are great man.

#

It was the background issue

#

I added a border and it worked.

grave hatch
#

Great. ๐Ÿ™‚

hollow wasp
#

Thank you so much.

grave hatch
#

Np

devout ginkgo
#

Hey everyone, is there a way that we could modify the shape of a SWidget to something else rather than a rectangle? Or doing modifications like offseting the bounding box of a SWidget? think

grave hatch
#

Everything in slate is square.

#

You can offset the bounding box by using a render transform?

devout ginkgo
#

But doing that will offset the visual as well right? What I want to do is to keep the visual in the same position and only offset the bounding box of it

grave hatch
#

Hmm.

#

Then no idea. ๐Ÿ™‚

solemn saffron
#

How can I modify the width of the black input boxes within the SNumericEntryBox and SVectorInputBox widget?

As you can see in the below picture, the black boxes for input are small, which means they don't display enough digits properly if a large number (three digits) is inputted. I've tried placing the SNumericEntryBox and SVectorInputBox widgets within an SBox, as shown in the example code below, but doing so does not seem to affect the black boxes themselves when I adjust the width.

SNew(SBox)              
.HeightOverride(22.5f)
.Visibility(EVisibility::Visible)
.HAlign(HAlign_Center)
[
    SNew(SVectorInputBox)
    .bColorAxisLabels(true)
    .X(this, &SMCTDialog::GetValue_RootRotationRoll, i)
    .Y(this, &SMCTDialog::GetValue_RootRotationPitch, i)
    .Z(this, &SMCTDialog::GetValue_RootRotationYaw, i)
    .OnXChanged(this, &SMCTDialog::OnValueChanged_RotationRoll, i)
    .OnYChanged(this, &SMCTDialog::OnValueChanged_RotationPitch, i)
    .OnZChanged(this, &SMCTDialog::OnValueChanged_RotationYaw, i)
    .OnXCommitted(this, &SMCTDialog::OnValueCommitted_RotationRoll, i)
    .OnYCommitted(this, &SMCTDialog::OnValueCommitted_RotationPitch, i)
    .OnZCommitted(this, &SMCTDialog::OnValueCommitted_RotationYaw, i)
    .AllowSpin(true)              
]

Any ideas?

grave hatch
#

Try changing that HAlign from Center to Fill.

solemn saffron
#

Yup, that fixed the problem. I can't believe I spent hours trying all kinds of other things... ๐Ÿคฆ๐Ÿปโ€โ™‚๏ธ

grave hatch
#

๐Ÿ™‚

tribal bolt
#

Hey @grave hatch as someone with very little coding knowledge but advanced UMG/scripting side of itโ€ฆ

Is slate easy to get into without that coding foundation or should I start with the basics of c++ and then look at slate once Iโ€™m comfortable?

grave hatch
#

If you don't know c++, you're going to struggle. Even where c++ is concerned, slate is unique and complicated. Not nearly as complicated as some, but it's not simple. You're not going to to learn how to use it with a standard c++ course.

#

Tons of chain methods and operator overloading. Custom macros and such.

#

With a good basic c++ understanding and some research on slate, though, you should be okay.

tribal bolt
#

Okay so it's more complicated than I thought :D. Do you recommend any good slate courses then? I've got the usual stuff like BenUI etc but if theres a stuctured course out there I'd definitely take it

grave hatch
#

I don't know of any. There are pins here with info and guides, but no hand holding afaik.

stray heath
#

I can't figure out how to get the Size here in C++. Once I create the slot, I want to just set the Size to Fill. I literally can't find anything about it ๐Ÿ˜ฆ Anyone that can help?

void UEquipmentWidget::CreateSlots()
{
    int8 AmountOfSlots = static_cast<int8>(EEquipmentSlotType::TotalCount) - 1;

    for (int i = 0; i < AmountOfSlots + 1; ++i)
    {
        SlotWidget = CreateWidget<USlotWidget>(this, SlotWidgetClass);

        SlotWidget->SlotType = static_cast<EEquipmentSlotType>(i);
        VerticalBox->AddChildToVerticalBox(SlotWidget);
        
        // Set Padding
        if(SlotWidget)
        {
            FMargin CurrentPadding = SlotWidget->GetPadding();
            
            CurrentPadding.Top = 5.0f; 
            CurrentPadding.Bottom = 5.0f; 
            CurrentPadding.Left = 5.0f;
            
            SlotWidget->SetPadding(CurrentPadding
        }
    }
}```
orchid nova
stray heath
grave hatch
#

You can add slots to vertical boxes with box->AddSlot()

orchid nova
grave hatch
#

This is very much umg though
Not slate.

stray heath
#

Sorry.

grave hatch
#

And you won't get a size unless there's a layout prepass.

stray heath
#

Thought Size and padding stuff is Slate ๐Ÿ˜›

#

My bad

grave hatch
#

And then you can only get a desired size.

#

You have to actually have it draw first and then you can get the geometry used in the last frame.

orchid nova
#

๐Ÿ‘

grave hatch
#

I totally misread all that on my phone. ๐Ÿ‘

terse shard
#

Hello, I'm a newbie in Slate, but I would like to know how can I check whether a certain input is pressed or not.

I'm trying to make so that pressing Messages/Warnings/Errors would filter out or not the whole thing, but holding Shift would make it make so that it doesn't apply any specific filter to it. I found the piece of code that does that, but I don't know how to check whether shift is held down or not.

grave hatch
#

FSlateApplication::Get().GetModifierKeys().IsShiftDown() or so

terse shard
#

Brilliant, thank you

grave hatch
#

There's also the input events values in certain events like keydown and stuff.

terse shard
#

Yeah, but I don't really want to mess the SOutputLog that much, I want to make it working the way I want with minimal changes ๐Ÿ˜„

manic herald
#

I have a ListView and UserObjectListEntry item which goes into the list and how can i update the value of text block at runtime ?

grave hatch
#

You haven't mentioned a text block.

manic herald
#

i didnt get you

grave hatch
#

I have a ListView and UserObjectListEntry item which goes into the list
has no relation to
how can i update the value of text block at runtime ?

manic herald
#

Item has a bindwidget UTextBlock

grave hatch
manic herald
#

someone says use slate in cpp and now umg, fraustrating.

grave hatch
#

They are wrong.

#

Slate is for stuff starting with S. STextBlock etc

#

UMG is still UMG, even if it's in c++.

#

If somebody said "use slate in cpp" - you are not doing that. You are still using UMG.

paper hamlet
#

are there any good examples of how to implement treeview?

grave hatch
#

There'll be a lot in the engine source.

cursive furnace
#

Hello, which function the Undo arrow calls in c++?
OR
is there a way to tell a UWidget to redraw the style after it was created?

grave hatch
#

That's "ResetToDefault"

#

It's a large pain in the arse to get it to update if you set a value programmatically.

#

The best way to do it is to override the reset to default delegates for that property and remove the caching on the "is default value" check.

cursive furnace
#

Thank you - for the extra tips too

grave hatch
#

Also it's not a UWidget.

late rain
#

Hello there,

I'm trying to show the scene took from SceneCaptureComponent2D on UI using UImage like Picture-in-Picture Image.

However, the UI cannot show SceneTexture from TextureRenderTarget that have a material that post-processed after tone-mapping.

How could I draw the SceneTexture from TextureRenderTarget into UImage(FSlateBrush) using SetBrushFromTexture()?

Btw, when I applied the material domain to "before tonemapping", the scene shows on the UI though. Why the "after tonemapping" does not work?

grave hatch
#

Use an FSlateImgeBrush and just set the texture on it.

#

I don't know why tonemapping is affecting this.

calm quartz
#

Hey folks, I asked this over in Lyra Dev Net as well, but are folks familiar with a way to push a Common Activateable Widget instance instead of pushing the class? EG, Push Content to Layer for Player is awesome, and is able to push the widget class; however, it would also be awesome to be able to construct the widget, passing in needed params to the constructor in order to set variables, and the like.

As it is right now with pushing the widget class, you have to use the returned reference to perform post-constructor initialization. If that is the only way, fine. Just wanted to ask to see if I am overlooking something. Cheers

misty summit
#

If it's a stack/Queue your pushing into, their should be a AddWidgetInstance function for pre-created widgets to add to the stack.

calm quartz
#

Nice, I'll look for that.

grave hatch
#

If that isn't the answer, you should ask in #umg. That isn't a Slate question.

late rain
grave hatch
#

Ah.

#

Yeah, the renderer does weird things like that sometimes!

paper hamlet
#

having an issue with creating STreeView

            .TreeItemsSource(&TreeItems)
            .OnGetChildren(this, &SAssetRenamerToolWindow::OnGetChildren)
            .OnGenerateRow(this, &SAssetRenamerToolWindow::OnGenerateRow)```
Is giving me this error ```10>DeclarativeSyntaxSupport.h(937): Error C2679 : binary '=': no operator found which takes a right-hand operand of type 'TSharedPtr<WidgetType,ESPMode::ThreadSafe>' (or there is no acceptable conversion)
        with
        [
            WidgetType=STreeView<SAssetRenamerToolWindow::FRenameAssetPtr>
        ]```
here's how i'm storing the tree view in the header file
```typedef TSharedPtr<FRenameAsset> FRenameAssetPtr;
    TSharedPtr<STreeView<FRenameAsset>> TreeTest;```

Edit Fixed: NOTE TO SELF If you are going to name your tree item just TreeItemPtr make sure you look at all the places you declare it. This should have been `TSharedPtr<STreeView<FRenameAssetPtr>> TreeTest;` not `TSharedPtr<STreeView<FRenameAsset>> TreeTest;`
grave hatch
#

Have you seen the advanced renamer plugin? ๐Ÿ™‚

paper hamlet
paper hamlet
#

do you know if there is a way to hide the expansion arrow on a treeview?

paper hamlet
#

once again note for self when you are creating the row inside OnGenerateWidget you have access to STableRow::SetExpanderArrowVisibility(EVisiblity InVisibility)

rancid seal
#

I'm having an issue with CommonUI where my activatable widget doesn't respond to the same keybind to close (ie escape for pause), but it will open the menu

#

Not sure whats happenning, I tried using the widget reflector to see if something on top of it was consuming input but idk no dice

#

hmm unchecking this seemed to solve it lol

paper hamlet
#

Iโ€™m having an issue with the code here <#cpp message>. I seem to have made an incorrect assumption but Iโ€™m not sure which it is

  1. When a check box is clicked I will fire MarkItemForRename on the Item tied to that row.
  2. If this is a directory, then all of the children will also be marked. (I believe this is working properly)
  3. When the child has IsMarkedForRename changed then the lambda for that rowโ€™s check state would return a different value and should be shown in the UI

However, when I click it changes only the check state for the clicked value even though all of the children items changed. Iโ€™ve tried running Invalidate() in the OnCheckStateChanged and that didnโ€™t help

vestal spear
#

Hello, since ListView child widget has no slot, how can I control the widget position freely? RenderTransform does not works well with ListView as it does not change layout. Padding does not work well either because it affects child. Is it possible to add slot in HandleGenerateRow? OR I have a way to reuse the FWidgetGenerator in SListView?

#

For context, I am trying to make the UI for "Hand" in a card game and fan out the cards. With the introduction of MVVM in UE 5.3, I would like to integrate with view models and ListView have some kind of native support with MVVM. I would like to reuse that.

grave hatch
grave hatch
#

Or, rather, SOverlay -* SBox -> Card and control the padding on the SBox slot.

#

I've seen it animated pretty well with SHorizontalBox too

#

(instead of SOverlay)

vestal spear
grave hatch
#

Honestly I don't know.

#

You're probably going to end up doing a bit of work to add it yourself.

#

Which features, specifically, are you looking to use in other widgets?

vestal spear
#

Just the FWidgetGenerator thing.

grave hatch
#

You can't use listview's one, but you can certainly replicate it.

vestal spear
#

Cool. Maybe I should not over complicate the issue and solve it at UMG level. Thank you.

iron dirge
#

hello i am using "SVectorInputBox" to make an entry for my vector variable , but when i edit the value on it , it returns to 0 everytime , i set the max vector value to something large and still same results, what i need to do to use this properly

grave hatch
#

Show code

iron dirge
#

sorry totally slipped out of my mind

grave hatch
#

Hmm

#

How are you entering the value? Are you pressing escape or hitting enter? Tabbing away?

iron dirge
#

yeah just normal putting vector values like normally do in unreal engine UI

#

i thought it might be something to do with the max value since it returns to zero no matter what the number i set, or maybe i need to set a variable inside it ?

grave hatch
#

You shouldn't need to

#

What happens if you remove all the stuff and just do SNew(SVectorInputBox) ?

iron dirge
#

humm let me try

#

now it gives this by default , and does the same behaviour , what ever value i put it returns to "multiple values"

#

if i added 3 spin boxes instead of vector now it works , i needed just to edit my logics to now read x y z separatly , but it would be great if i learnt how to use the vector one correctly

grave hatch
#

hmm

#

Maybe you need to bind the value to something

#

.Vector(this, &SValidatorWindow::GetVector) for isntance

elder sequoia
#

im trying to use commonui with world space widgets, the AnalogCursor does not work as expected, it uses GetTickSpaceGeometry().GetAbsolutePositionAtCoordinates(FVector2D(0.5f, 0.5f)) and that returns coordinates in the render target more or less, not viewport as the cursor stuff expects. Seems possible to translate them with actor transform, but it is difficult to get to them in relevant spot. Is there some other way to do that im missing?

warm vault
#

Anybody that knows how i should implement the HUD for a **local **multiplayer join screen?
Something like the image?

How can i make certain parts of the HUDonly react to a certain connected controller?

I Suspect/heard each player controller/player will have some sort of FSlateUser?
If so how can i access that an build around that?

elder sequoia
grave hatch
#

I guess you'd use that?

craggy oxide
#

I have the following slate widget which I'm trying to add to the viewport, but it's not appearing on the screen. Construct does get called since the message is logged.

void SEGDPanel::Construct(const FArguments& InArgs)
{
    UE_LOG(LogTemp, Error, TEXT("Panel construct"));

    ChildSlot
    [
        SNew(SVerticalBox)
        +SVerticalBox::Slot()
        .AutoHeight()
        [
            SNew(STextBlock)
            .Text(FText::FromString("Test text"))
        ]
    ];
}
    if (GEngine)
    {
        TSharedRef<SEGDPanel> Panel = SNew(SEGDPanel);

        GEngine->GameViewport->AddViewportWidgetContent(Panel, 999);
    }
grave hatch
#

Secondly, have you used the widget reflector to check the viewport?

grave hatch
#

I'd have thought the viewport widget would have held a strong reference there...

mystic shell
#

Hello. If i try to add a C++ EditorUtility Widget to my Project i can compile project any more... Any idea what's is wrong?

grave hatch
#

You didn't add the right modules to your build.cs probably.

#

Also that looks suspiciously like #umg

mystic shell
#

@grave hatch

grave hatch
#

And where does it say UMG there?

#

Or whatever module the editor utility widget lives in.

mystic shell
#

@grave hatch no idea.
but i found that warning Warning: C:\UnrealEnigne\Multiplayer\MultiplayerTemplate\Multiplayer.uproject does not list plugin 'EditorScriptingUtilities' as a dependency, but module 'Multiplayer' depends on 'EditorScriptingUtilities'.

#

and my plugin editorscriptingutilities is cheched

grave hatch
mystic shell
#

ok thx

crimson bone
#

from time to time, in the current build, hardware cursors don't work at all (bug rate: 1/6 executions), any advice? thanks!

#

I don't have any clue to follow....

grave hatch
#

Have you overridden all the cursors?

crimson bone
#

no, just the ones in the picture

#

but you know, I set the cursor to Default in the controller at the beggining

#

when the bug happens, the default Windows mouse doesn't change at any point

#

like if all the Hardware Cursor settings wouldnt exist

grave hatch
#

Are you sure they're being applied?

crimson bone
#

what you mean

#

the bug rate is 1/6 executions

#

so it works the majority of the time

grave hatch
#

Honestly I have no idea what the problem could be. :/

#

I would track down, in the engine source, where those settings are applied and check how and when they are applied.

crimson bone
#

if I change the window and go back, it works again..,

#

(so If the mouse leaves the window, unreal detect it properly the next time and hardware cursor get fixed)

#

If anyones figurate out any workaround would be awesome

solemn saffron
#

I decided to attempt to switch over to using SSplitter, but I seem to be having issues regarding resizing the slots. From what my output tells me, the slots are indeed being resized, but there is no visual representation of that resizing. In the attached video, the two values being printed in the log, which represent the slot sizes, should always add to 1. And they do. But slot doesn't seem to visually change size.

Any ideas?

I resize the slots using, for example, OnSlotResized(this, &SMCTDialog::OnSlotResized_PerAnimDetails), which directly changes the values for the widths. And I get the values via Value(GetSlotWidth_BulkAnimDetails()).

For example,

// bulk details
+ SSplitter::Slot()
.Resizable(true)
.Value(GetSlotWidth_BulkAnimDetails())
.MinSize(0.25f)
.OnSlotResized(this, &SMCTDialog::OnSlotResized_BulkAnimDetails)
[
  // content
]

(Ignore the ugly separators and buttons...)

grave hatch
#

OnSlotResized isn't what you call to resize a slot.

#

You'd use an attribute callback on Value() iirc

#

So .Value(this, &SSomeWidget::GetSlotSize, /* first slot */ 0)

#

Something like that.

#

And you'd use OnSlotResized to update the source of that Value

#

.OnSlotResized(this, &SSomeWidget::SetSlotSize, /* first slot */ 0)

#

@solemn saffron

solemn saffron
#

Thanks. I'll look into that and see if that is my issue. I'm currently looking at the DetailsColumnSizeData.h file and how the class is used in the Engine. I'm working to understand how the way that class is used is different than what I'm currently doing.

grave hatch
#

That's how it's used by our classes in the engine ๐Ÿ˜›

solemn saffron
#

Haha. Yeah. I figured. ๐Ÿ˜…

solemn saffron
#

I'm back again with another scrollbox issue. (See below picture.)

I have a resizable SDockTab, within which I have a SBorder, followed by a SSplitter. In the left SSplitter slot, I have placed a SScrollbox. The issue I'm having now is the SScrollbox is not becoming scrollable when I resize the dock tab. I see that Unreal has scrollboxes that respond to changing tab sizes, but I can't seem to figure out how Epic does it.

What am I missing?

My code for the ChildSlot is below. (The parent is the SDockTab I mentioned above.)

SNew(SBorder)
.VAlign(VAlign_Fill)
[
  SNew(SVerticalBox)

  + SVerticalBox::Slot()
  [
      // Apply and Close buttons
  ]
    
  + SVerticalBox::Slot()
  .AutoHeight()
  .VAlign(VAlign_Fill)
  [
    SNew(SBorder)
    .BorderBackgroundColor(FSlateColor(FLinearColor::Black))
    .VAlign(VAlign_Center)
    .Padding(10.0f)
    [
      SNew(SSplitter)
      .Orientation(Orient_Horizontal)
      + SSplitter::Slot()
      .Resizable(true)
      .Value(0.25f) //will fix this later
      [
          SNew(SScrollBox)
          .Orientation(Orient_Vertical)
          .ScrollBarAlwaysVisible(true)
          .ConsumeMouseWheel(EConsumeMouseWheel::Always)
                          
        + SScrollBox::Slot()
        .VAlign(VAlign_Fill)
        [
          SNew(SGridPanel)

          //===========================================
          //    Details On Bulk-Animation Basis
          //===========================================
          + SGridPanel::Slot(0, 1)
          [
            SNew(SHorizontalBox)
                
            + SHorizontalBox::Slot()
            .AutoWidth()
            [
              SNew(SBox)
              .WidthOverride(375.0f)
              [
                  VerticalBoxWidget_VerticalDetails.ToSharedRef()
              ]
            ]
          ]
        ]
      ]
    ]
  ]
]
#

I realize this is similar to the question I asked [here](#slate message), but the difference now is I want the SScrollbox to respond to a SDockTab changing size. I suppose I don't conceptually understand Slate well enough to see anything beyond a shallow similarity.

grave hatch
#

Have you checked to see if the gridview is actually becoming the correct size?

#

And it's not just shrinking?

#

You do have it set to VAlign_Fill, so that's what it might be doing.

#

And just to be sure, you are using the widget reflector to check that?

solemn saffron
grave hatch
#

Tools -> debug -> widget reflector

#

There's a big button at the top-left, I forget what it's called, I just click it. Then whatever you hover, it will show you the widget tree and some very useful information about those widgets.

#

When you've hovered the mouse over your grid view, press escape and go check out the widget tree.

#

The things you're looking for there are the actual size and desired size of your grid widget.

#

Are you saying the SScrollbox should not be set to VAlign_Fill?
Possibly

#

The slot should not be.

solemn saffron
#

Wow. That's quite the debug tool. I'm looking at it now.

#

This is what I see.

DesiredSize:   X=387.000   Y=691.000
ActualSize:    X=385.000  Y=691.000

The desired size should be larger than the actual size, and it's basically the same right now, so I suppose that is my issue. I'm not sure how to resolve that though.

#

The two sizes stay the same regardless of how I resize the SDockTab.

grave hatch
#

And that's for the grid panel?

#

Check the size of the inner panel.

solemn saffron
#

What I showed before was for the SScrollBox itself.

I don't know why there is no SGridPanel showing up inside the SScrollBox. The only thing that shows up is the SHorizontalBox.

grave hatch
#

It'll be inside the scroll panel.

solemn saffron
#

I totally knew that. Totally. ๐Ÿคซ

grave hatch
#

Then go deeper and find out what isn't the right size.

solemn saffron
#

Okay, I see, so I'm looking to find the widget that has a mismatch between the ActualSize and the DesiredSize?

#

I do have mismatches, but those mismatches seem to be due to the fact that the corresponding widgets are conditionally visible/collapsed.

grave hatch
#

That's fine. What I mean more is why is the scrollbar not working.

#

It should be because the contents of that slot is, for some reason, not bigger than the slot.

solemn saffron
#

What I think I'm seeing in my attached picture is the SScrollPanel does not have a shrinking ActualSize in response to the shrinking of its parents. That is, the SScrollPanel has the same ActualSize and DesiredSize regardless of what happens to the parents. I'm guessing the static nature of the sizes is the cause of the visual issue I'm facing. If I'm correct, how would I approach resolving that?

grave hatch
#

I would set whatever contains the SScrollPanel (the slot) to a VAlign_Fill

#

So that it fills the space and doesn't expand past it.

craggy oxide
#

I have a class ManagerSubsystem which creates and stores DebugContainers. DebugContainers store a TMap of properties. For each DebugContainer, I have a slate STable in which I want to display all of the properties and update the displayed properties as their values get updated in DebugContainer. STable can be seen as a visual/widget representation of DebugContainer.

STable has a reference to its corresponding DebugContainer, however I'm unsure how I can capture the new property values as they get updated in DebugContainer to display them in STable.

#

I would need a way to identify the properties in DebugContainer by their key based on STextBlocks in STable

#

I was thinking of storing a reference to the STable in DebugContainer and pushing property values to STable as they get updated, but this would also require me to create STextBlocks in STable dynamically when a new property gets added to DebugContainer. And it would still have the same issue of identifying the STextBlock which the property belongs to

solemn saffron
# grave hatch I would set whatever contains the SScrollPanel (the slot) to a VAlign_Fill

I commented out a single line that contained AutoHeight, which resolved the issue with my vertical SScrollBox, though I don't understand why. But the VAlign_Fill does not seem to have a noticeable effect.

Now I'm trying to figure out how to get my horizontal SScrollBox to work. The approach I took for resolving the vertical SScrollBox issue does not seem to apply in any obvious way to the horizontal SScrollBox. I'm truly having difficulty seeing the rhyme and reason behind why certain things work in Slate, which means debugging is mostly just shooting blindly.

Thanks for sending me down the right path. That Widget Reflector tool is helpful. I realize now that you mention it in your pinned article. ๐Ÿคฆ๐Ÿปโ€โ™‚๏ธ

grave hatch
#

My article?!

grave hatch
craggy oxide
grave hatch
#

How are you currently populating the table?

craggy oxide
#

I'm not

grave hatch
#

I see.

#

Why not just create a TMap of property name -> textblock?

craggy oxide
#

In STable with the id as key and the TextBlock as value?

craggy oxide
grave hatch
#

The property name would be the key.

#

What I'd do there is actually use an SListView

#

That takes an array of data items - in your case an array of FNames.

#

Each FName would be a property in your debugcontainer.

#

Then the SListView sends a row construct event to each row and gives it that FName from your data list.

#

All you have to do is change the SListView's data set (it's a pointer to TArray stored on your debugcontainer)

#

And use each individual row's constructor to work out how to set and keep the value updated.

solemn saffron
#

For some reason, I thought you wrote the article.

craggy oxide
#

With the row's constructor, do you mean OnGenerateRow?

SNew(SListView<TSharedPtr<FString>>).ItemHeight(24).ListItemsSource(&Items) .OnGenerateRow(SListView<TSharedPtr<FString>>::MakeOnGenerateWidget(this, &MyClass::OnGenerateRowForList))
grave hatch
#

Yes

craggy oxide
grave hatch
#

Yes

#

You create an array, Items, and fill it with the fnames of your choice.

#

Make it a class var so it doesn't go out of scope...

craggy oxide
#

When another property gets added to DebugContainer, I assume it will create a new row in the SListView?

#

And final question, should the SListView be in the STable?

void SEGDTable::Construct(const FArguments& InArgs, EGDDebugContainer* InDebugContainer)
{
    ChildSlot
    [
        SNew(SListView<>)
    ];
}
grave hatch
#

You'd have to add it to your Items array yourself and then trigger the regenerate rows method.

#

No. it is a replacement for the STable

#

If you want multiple headers you can use STableView I think

#

There's a specific thing for having a list with multiple headers.

craggy oxide
#

Alright I'll have a look, thank you

grave hatch
#

The row you return has to extend from SMultiColumnTableRow - something like SMultiColumnTableRow<FName>

craggy oxide
#

From the regenerate row method?

grave hatch
#

Yes

#

You'd create your own row subclass based off SMultiColumnTableRow

#

You can also set a header row with the .HeaderRow() property of SListView I believe

#

So you'd create a header row first, then create the list view and pass it your header row.

light dragon
#

Anybody know why I'm having this issue, ( First time using Slate )

grave hatch
#

Remove this:

#

And put the middle line into a new slot.

#

This bit

grave hatch
#

UWidgets are not slate

#

Seems fine, though?

light dragon
grave hatch
#

When are you expecting the background to change?

light dragon
light dragon
grave hatch
#

When

#

Which value?

light dragon
grave hatch
#

Right. Have you checked to see if RebuildWidget is called?

light dragon
grave hatch
#

Then it's something to do with UMG or the SBorder. I'm not sure which honestly.

#

Is the background colour the right value when you're inside RebuildWidget?

light dragon
grave hatch
#

But then you're changing it in the details panel?

#

Check with the debugger what value it is.

light dragon
#

๐Ÿฅฒ Unreal is killing me

grave hatch
#

Then it should be fine. Shrug

light dragon
grave hatch
#

Have you tried removing the blur and seeing what happens?

mortal canopy
#

oh wow there's a full guide in pinned messages

grave hatch
#

I wouldn't say "full guide". Some useful starting pointers, though!

mortal canopy
#

Oh! thank you for correcting me

grave hatch
#

If you do find a full guide, we'd love to get it pinned here!

mortal canopy
#

if i ever do, sure

mystic shell
#

hello, I can add a SDetailSingleItemRow to my EditorUtility widget made in CPP? If yes, how I can do it?

grave hatch
#

Probably private. The property editor module can get you the edit widget with CreateSingleSomethingSomething.

solemn saffron
#

I'm back with another Slate issue.

For some reason, every time I open an Animation Sequence, Unreal attempts to open a tab with my plugin's tab ID. I even get the following message:

LogSlate: The tab "MotionCaptureTools" attempted to spawn in layout 'Standalone_AnimationEditor_Layout_v1.5' but failed for some reason. An "unrecognized tab" will be returned instead.

This only happened after my NomadTab accidentally docked within an Animation Sequence. I then undocked and continued testing. Now, however, every time I open any Animation Sequence, a tab like the one in the below picture pops up. This pop-up tab does not interfere with the behavior of my plugin, but I can't understand why this tab pops up at all. I can close everything, restart the editor, etc., but the issue persists upon opening the editor again.

mint comet
#

You can delete the Saved folder in the project directory, or just find the relevant file within it which I don't remember.

Or since the editor isn't crashing I think there's a button in the toolbar to reset the view layout under window

grave hatch
#

You can also do reset layout.

#

From the window menu.

#

It will reset everything.

solemn saffron
#

Okay, I will try those things when I get home.

From what I'm gathering based on the feedback, does that mean the issue of the window popping up isn't rooted within my plugin (at least not in any obvious sense)?

grave hatch
#

It'll mean some sort of plugin that isn't enabled has its layout saved.

solemn saffron
#

Okay, thanks for the info.

grave hatch
#

Or that the layout name has changed...

reef fox
#

Does this look right to you guys?
Problem at hand: My game thread in ue4 is ~6ms and In ue5.3 fkin 12-17 ๐Ÿคฆโ€โ™‚๏ธ

#

Prepass & Draw children seems to push the numbers up:

reef fox
#

Also in stand-alone... But yes, in the editor. It seems to be no different in cooked builds.

#

at least not by looking at a debug build with stat unit+fps. The fps in ue4 is ~110-120 and now it's down to 55-70

#

this makes no fkin sense, so frustrated rn!

grave hatch
#

The default render settings are way higher in ue5

#

But, yeah, slate in the editor is going to be massively worse.

#

And slate in debug is even more massively worse

reef fox
grave hatch
#

Lol

thick ice
#

Does anybody know if there is a list of Slate button styles, like "PrimaryButton" or "NoBorder"?

grave hatch
#

Check out the starship.cpp file

#

Or something similar

obsidian quest
#

hey ive been trying for two days to get my widget to be returned by visibility trace at cursor and it just isnt

#

id even accept doing a totally separate call to determine the widget under my cursor, though i am doing one already that works for the static mesh component's collision

#

i cant get a widget under any circumstances to be returned.

#

so i have to add a totally separate component somewhere just to do this, maybe?

grave hatch
#

A world space widget?

obsidian quest
#

Thanks i didnt know that existed, also i thought slate was every widget and apparently its not.

mortal canopy
#

When it comes to learning slate, what should I know of Unreal Engine first?

#

I remember you said that it's like learning two separate halves, Daekesh, but I'm not aware of where I start and stop in general with going from learning UE5 itself and learning Slate

grave hatch
mortal canopy
#

I want to be able to do things with parity in slate that I could before in Unity Engine. Custom inspectors, new editor windows for unique object classes and learning the tool creation process for UE4/5

#

I'd need to also generate these files as C++ .h & source files from an application, for my dissertation too, though I've seen UE5 act... uniquely to files not generated by it's own tool

grave hatch
#

It's own tool? Do you mean the editor?

#

If you want to learn that, you'd need to start off well before the slate part. There's a whole editor workflow thing you should look into.

grave hatch
#

Take a look at things extending from FWorkflowCentricApplication

#

Or FBlueprintEditor, I think? (a subclass of WCA) Or just the standard FAssetEditorToolkit.

mortal canopy
#

oh huh

#

thank you

grave hatch
#

OR if you wanna do the it the cheap way, just look at registering a nomad tab with FGlobalTabManager.

#
  • check out the stickies here for actual slate.
mortal canopy
#

what are the risks and benefits of both ways?

grave hatch
#

You can have trouble "finding" nomad tabs if they're docked in the wrong place.

#

And by "finding" I mean with code.

#

You dock one in another editor (e.g. teh blueprint editor) and the global tab manager will no longer be able to find it.

#

Making actual asset editors don't have this issue.

#

There can be layout issues to (saving/loading) with nomad tabs.

mortal canopy
#

thank you, are there any special setup features required for asset editors and plugins that I'd need to be considerate of when trying to generate code files for them?

grave hatch
#

Not really.

#

Just don't do it when the editor is open, I guess.

mortal canopy
#

oh- uh yeah that one would be unwise even in unity sometimes

sinful hollow
#

Hi, where to put FSlateApplication::Get().SetNavigationConfig(...); correctly in the code ?

#

at the game module's startup, it crashes when packaging the game (FSlateApplication::Get() is not initialized yet)

grave hatch
#

You could subscribe to FCoreDelegates::PostEngineInit or whatever it's called

#

(in your module startup)

#

OnPostEngineInit

scarlet monolith
#

Hello I can't compile my code if "TxtBlocContent" variable is refered in the .h . I need a ref to change my text when the user trigger a button.`
The errors :

0>SlateControlledConstruction.h(103): Reference C2248 : voir la dรฉclaration de 'FSlateControlledConstruction::operator new'
0>SlateControlledConstruction.h(81): Reference C2248 : voir la dรฉclaration de 'FSlateControlledConstruction'```
The cpp :
```cpp
void SChatGPTChatWindow::Construct(const FArguments& InArgs)
{
    //UI
    ChildSlot.VAlign(VAlign_Fill).HAlign(HAlign_Fill)
    [
        SNew(SOverlay)
                    + SOverlay::Slot()
                    [
                        SNew(SBox)
                        .HAlign(HAlign_Center)
                        .VAlign(VAlign_Center)
                        [
                            SAssignNew(TxtBlocContent, STextBlock)
                            .Text(FText::FromString("Welcome on copyloteGBP assistant, how can I help you today ?"))
                        ]
                    ]```
#

The .h

#pragma once

#include "CoreMinimal.h"
#include "Widgets/SCompoundWidget.h"
#include "Widgets/Text/STextBlock.h"

class COPYLOTEGBP_API SChatGPTChatWindow : public SCompoundWidget
{
    SLATE_BEGIN_ARGS(SChatGPTChatWindow)
    {
    }

    SLATE_END_ARGS()

    void Construct(const FArguments& InArgs);

public:
    void OnQuestionAskCommited(const FText& InText, ETextCommit::Type CommitInfo)
    {
        UE_LOG(LogTemp, Warning, TEXT("Question asked : %s"), *InText.ToString());
    }
    
    TSharedRef<STextBlock> TxtBlocContent;
};```
#

Oh it fixed my stuff thanks !

barren kayak
#

Is this an engine bug? Was trying to fix weird behavior with my drag widget that has a 90 degree render transform applied, where it would start at an incorrect offset when the drag operation begins. Eventually found out that ScreenDrageePosition seems to be incorrect in this case and should just be MyGeometry.AbsolutePosition instead of MyGeometry.GetAbsolutePosition() (that uses the AccumulatedRenderTransform)

FReply SObjectWidget::OnDragDetected(const FGeometry& MyGeometry, const FPointerEvent& PointerEvent)
{
    if ( CanRouteEvent() )
    {
        UDragDropOperation* Operation = nullptr;
        WidgetObject->NativeOnDragDetected( MyGeometry, PointerEvent, Operation );

        if ( Operation )
        {
            FVector2D ScreenCursorPos = PointerEvent.GetScreenSpacePosition();
            FVector2D ScreenDrageePosition = MyGeometry.GetAbsolutePosition();

            float DPIScale = UWidgetLayoutLibrary::GetViewportScale(WidgetObject);

            TSharedRef<FUMGDragDropOp> DragDropOp = FUMGDragDropOp::New(Operation, PointerEvent.GetPointerIndex(), ScreenCursorPos, ScreenDrageePosition, DPIScale, SharedThis(this));

            return FReply::Handled().BeginDragDrop(DragDropOp);
        }
    }

    return FReply::Unhandled();
}

I'm now just calling this nasty line in my NativeOnDragDetected to fix it ๐Ÿคฎ

const_cast<FGeometry&>(InGeometry).AppendTransform(FSlateLayoutTransform(InGeometry.AbsolutePosition - InGeometry.GetAbsolutePosition()));
obsidian quest
#

oh this is slate anyway. thought i was in umg

grave hatch
#

UMG definitely has drop and dorp built in, though...

stuck jewel
#

what controls the background style of a widget like an editable text box? how come the starship test panel SMultiLineEditableTextBox has a background but mine doesn't? JoyStroke

#

oh, god damn i am a retard

#

i didn't even see the Box vs nonBoxclass

#

i've spent like 20 minutes on this

obsidian quest
#

i spend 3 days implementing a drag operation feature that already existed

stuck jewel
#

[there is no way i actually only spent 20 minutes on that]

obsidian quest
#

the future time that will be spent revisiting how infuriating it was forever

wary totem
#

Created a IPropertyTypeCustomization for a UStruct, and I used it to replace the entire header row using HeaderRow.WholeRowContent() [ ]
But, if I put the customised type into an array, then this breaks the array controls for some reason - I lose that little drop-down menu with insert/duplicate/delete in it.
Any way to use WholeRowContent without breaking the array menu?

#

The handle to drag and drop entries is still there, as is the "reset to default" column, but the little drop-down menu on the right is gone

grave hatch
#

Thsts a problem with arrays I believe.

#

I think you have to customise the container types too. But I'm not 100%.

wary totem
#

Does seem that way. It's a bit silly since the array controls don't really have anything to do with the thing you're customising. Guess it's just the way that little menu is injected

#

Haven't dug into the internal array Slate code properly yet, but my theory is that using WholeRowContent removes the NameContent and ValueContent sections, and the way arrays are set up injects the menu button in the the end of the ValueContent.

grave hatch
#

That sounds highly likely!

terse shard
#

Hello, is it possible to retrieve UWidget out of an SWidget in case the Slate counterpart is wrapped by the UMG?

craggy holly
#

Usually no

#

Some widgets add metadata to the underlying SWidget but most of them don't

grave hatch
#

What you can do is iterate over all the potential uwidgets and check if their swidget is the widget you want to check for.

#
for (UWidgetType* Widget : TObjectRange<UWidgetType>())
{
  if (Widget->TakeWidget() == MyWidget)
  {
    ... stuff
    break;
  }
}```
#

That'll only work if it's the root widget for that uwidget, though. You can check if the taken widget is a parent of your widget too.

terse shard
#

Oh, yeah, sounds like a solution, thank you

grave hatch
#

Np

#

While pretty bad conceptually, if there aren't many specific instances of, say, UButton, then it will actually be relatively quick.

dry kettle
stuck jewel
dry kettle
stuck jewel
#

It's ok github

#

On

#

My dialogue stuff above is (going to be) open source too but it won't be usable for several weeks

glad nest
stuck jewel
#

yes

glad nest
#

Looks great!

proper belfry
#

Shouldn't the variables declared in a UUserWidget show up in the Graph Editor?

UCLASS(Blueprintable)
class ROGUELIKE_API ULifeBarWidget : public UUserWidget
{
    GENERATED_BODY()

public:
    UPROPERTY(BlueprintReadWrite, EditAnywhere)
    float Life;

    UPROPERTY(BlueprintReadWrite, EditAnywhere)
    float MaxLife;

    UPROPERTY(BlueprintReadWrite, EditAnywhere)
    AEntity* OwnerEntity;
};
#

If not, there is a way to declare and expose them?

grave hatch
#

Did you enable inherited variables?

proper belfry
#

I remember that with blueprints it has a gear on the side of the add icon which I can use to show inherited variables, but here I don't see this option, do you know how enable it in User Widget?

#

I kinda already solved the problem, I discovered that the variables are accessible, they just don't show up, still would be nice to see them on the "Variables" menu

grave hatch
#

Is it not on teh cog at the top-right of the details panel, next to the search bar?

proper belfry
#

Oh ok, found it, thank you

grave hatch
#

Np

stuck jewel
#

does anyone happen to know where the orange border is drawn in the engine source code?

#

trying to do something similar to my graph nodes

#

wait am i being a dumbass again, the reflector should pick this up

#

... nope it doesn't

#

my god ok it's SNodePanel::GetShadowBrush graph node highlight select blah blah search keywords

grave hatch
#

Heh

stuck jewel
#

typical "spend 30 minutes looking, ask for help, find it in 5 minutes" ... i need to ask for help more often even if noone is around

grave hatch
#

It does get lonely in here! :tumbleweed:

stuck jewel
grave hatch
#

Neat!

#

The popping is a bit weird, though

stuck jewel
#

Yeah, it took me a while but I made a better solution for that

stuck jewel
#

don't have time to test code right now but still need to plan -- can you create an invisible button in slate and have it register a click but also not capture the mouse click? like a pass-through button to give me an extra layer of detecting if you click within a region?

what i did is start using tick. in tick i check if you've selected the dialogue and if a text box has focus or not. if yes, expand the text box. on top of that, if the widget has focus and you tap CTRL key, fully expand the widget and keep it expanded until you deselect the node.

the obvious "problem" is the widget now updates in two frames - you click on the text box and i have it autoupdate its own size, and then next frame, tick sees that it is selected and opens the rest of the controls. the text block (SMultilineEditableTextBox) does not contain any kind of "OnFocused" event i can bind to do it all immediately, so i'm thinking maybe a pass-through button would?

#

also i know tim would never use the profanity i displayed in that video i'm sorry tim

grave hatch
#

Sure you can.

#

But it'll make interacting with everything behind it a problem...

stuck jewel
#

Yeah that's why I was wondering if there was a way to detect a click and let it pass through Thonk I'll take a look around. Probably need to do some janky manual click detection is my guess

grave hatch
#

If you return FReply::NotHandled() on teh mouse click you're good.

stuck jewel
#

Ooh derp right

grave hatch
#

But, yeah, manual OnMouseDown/Up stuffs.

spare rapids
#

Hey everyone, I have a question. I have only some xp with slate. I have a multiplayer game with a dedicated server. Curious, is there a way to play the audio persistently throughout different levels? Using Wwise. Like I want to initiate that audio when the game loads up the first movie, and then gets into the level and then gets into the game using join server. But curious if it could be done? Any help would be highly appreciated ๐Ÿ™‚

floral moss
#

Hi everybody, I'm hitting a pretty consistent breakpoint issue in UMG

whenever I'm break pointing something that goes on a tick, I get this

LogSlate: Warning: Enter Debugging Mode failed.

followed by a notification, I don't think I've seen this before in other versions, and a search doesn't yield too many results.

I found a thread on Reddit, but it offered offered no solution. Has anyone else come across this and has a workaround?

https://www.reddit.com/r/unrealengine/comments/1cu1ebf/ue_541_widget_blueprint_breakpoints_seem_broken/

Reddit

Explore this post and more from the unrealengine community

grave hatch
spare rapids
# grave hatch Put the player on your game instance?

The player actor gets destroyed when changing levels. I think i might have found something, I had seamless travel turned off. Iโ€™m guessing if I turn that on and play the sound on controller that should work. Iโ€™ll try and update you if it works.

#

Thank you

cinder oriole
#

Anyone ever forced the UComboBox to open programmatically without waiting for user input/click?

grave hatch
#

You can probably fake a click

cinder oriole
#

Eh.. I'll just use a ListView ... wanted to created some menu...

grave hatch
#

FSlateApplication in c++.

cinder oriole
#

I was looking for this behaviour and the list view and anchor did the job. Although it was a bit cumbersome to setup.
Weird , that the ComboBox doesn't have such a feature. The combo box is already simple and more performance, and thats the only option its missing to replace the list view

#

I tried getting the Slate Object with TakeWidget Casting, and then and calling SetIsOpen(true) , and it completely ignored that function call...
Wondering what else it does on click for SetIsOpen() to actually open the ComboBox.

They should expose the function to UMG and blueprints though... it would be nice to have

grave hatch
#

Why not make the little green widget a menu anchor and use it to open a menu? Or a combo button?

cinder oriole
# grave hatch Why not make the little green widget a menu anchor and use it to open a menu? Or...

The little green widget is an Anchor.
It was from the get go.
Now when the Menu Anchor โ€œOpens menuโ€ the menu is(was) a ComboBox. Problem: The ComboBox when triggered by the Menu Anchor , initially appears closed.

So you need to click on it. so 2 clicks to open it and get to the selection part.

So i thought, hm, let me open it automatically from code, thereโ€™s no such function

#

if you instead replace the anchor with just the ComboBox , to get the 1 click requirement, youโ€™ll lose the advantage of using an icon for your dropdown. It will be a string which will take more space.

grave hatch
#

Can you not use the Content() property of SComboBox to set an icon?

#

Does that not replace the usual content?

cinder oriole
#

Maybe that will work.
But iโ€™ve already invested time developing a ListView based menu systemโ€ฆ it works and more flexible since you can use entire widgets for the menu entries like icon next to text. itโ€™s cool, just cumbersome to setup

stuck jewel
#

i used SComboButton for that with an FMenuBuilder

#

like starship does

#

each dropdown menu entry is a full self-defined widget
(but oh well, if it works it works)

cinder oriole
#

I mean i guessโ€ฆ
But i donโ€™t really like non UMG Exposed Widgets with little to no documentation.
I figured it would take me less time to build my own menu system than spend time reading some other code. available through UMG, quick changes and stuffโ€ฆ can give the system to a new-bie and theyll be fine.

The list view is virtualized so doesnโ€™t really waste resources and has both orientations so it really isnโ€™t a bad choice. UComboBox doesnโ€™t seem to have Horizontal orientation. the list view does.

pulsar remnant
#

What is the difference between SScrollBox and SScrollBorder?

grave hatch
#

Good question

#

I think you're meant to use SScrollPanel at any rate.

#

I think? I can never remember which one you should use.

grave hatch
#

Ignore me.

pulsar remnant
#

No. Genuinely, I didn't understand
I saw SScrollBorder in UE source, but idk why they preffered it over SScrollBox (or why it exists)
How many of those we need? There is also SScrollPanel??

grave hatch
#

SScrollPanel is another widget used internally by SScrollBox.

#

I always get them the wrong way around.

#

Have you looked at the class to see what it says it does?

pulsar remnant
#

Yeah, but this doesn't means much to me

Shows a border above and below a scrollable area
#

Nevermind, it just displays this little half transparent black thing

#

It's very hard to see

pulsar remnant
#

How do I access childs of SScrollBox? I keep getting crashes with this

MyScrollBox->GetChildren()->GetChildAt(Index)
grave hatch
#

I think it gets bigger if you scroll to the bottom/top I believe.

pulsar remnant
#

Apparently SScrollBox stores a SHorizontalBox, a SOverlay and a SScrollPanel which contains the childs
Keywords for future search: SScrollBox child, Child SSCrollBox, C++ ScrollBox Child, Slate SScrollBox Child, ScrollBox Child Slate

grave hatch
#

It'd be better to store your own list tbh

pulsar remnant
#

I just store SScrollPanel* once

#

And use it later on

grave hatch
#

I mean store the slots or the widgets you add to them in your own array.

pulsar remnant
#

I mean unless it's expensive to do GetChildAt(), I prefer not to store another array since it changes frequently in my case

grave hatch
#

Fair enough.

#

It's not really, but it could change with engine updates, etc

fossil sparrow
#

I highly recommend not using ScrollBox if you intend to have multiple object in it. Use a ListView or TileView for that. ScrollBox is for monolithic widget that are too big to fit in the space allowed like a textbox or an image . The advantage of ListView over ScrollBox is that the ListView already has a way to get the entry at index and multiple utility function based on a multiple entry scrollable widgets. You can use the OnEntryInitialized, OnEntryGenerated and there's another event that I forgot the name when the entry return to the WidgetPool. The same goes for TileView since it extend the ListView.

grave hatch
#

Or you could simple store a reference to a vertical box and stick it in a scroll box.

#

ListViews come with a load of extra bumpf you just don't want or need for a simple scroll panel.

cinder oriole
fossil sparrow
fossil sparrow
#

Also note that the Views (TableView and it's child) doesn't share the same scrolling capabilities. The ScrollBox implement it's own scrolling rules and capabilities.

grave hatch
#

Because reasons!

pulsar remnant
#

Can I get some more explanation on SScrollBox vs SListView?

fossil sparrow
#

What more do you want?

pulsar remnant
#

To be honest, that's first time I heard about SListView, so I don't even know what I don't know :d

fossil sparrow
#

The best way I can differentiate both of them... ScrollBox is for single, monolithyc Widget. ListView is for a list of Widget (horizontale or verticale).

#

Even if you only have 2 Widgets, the ListView is better as it allow you to control scrolling on an entry base index.

pulsar remnant
#

Hmm, so what it does different than SScrollBox to be a better fit for a list of widgets?

#

Is it only scrolling to specific widget? Because as far as I know you can do same with SScrollBox, but you do it with a pointer to the widget not with index

fossil sparrow
#

Like I said in my previous comment, you can get the Item at index, you get a Widget pooling system that has event OnEntryInitialized, OnEntryGenerated and OnEntryReleased to control how your Widgets behave and to save memory

#

You can do the same with ScrollBox... You can do the same with VerticalBox/HorizontalBot... You can do the Same with any kind of Widget only if you care to implement everything from scratch

pulsar remnant
#

I see, so about creating actual widgets inside of it... As far as I understand you just pass in a list of your data and you get a callback to create child widgets right? There is a few things I don't get here
1-) Why does it wants me to use TSharedPtr to pass in data? Looks wasteful
2-) Why would I pass a callback when I can just generate at constructing widget itself?
3-) What are OnSelectionChanged, SelectionMode and HeaderRow ?

fossil sparrow
#

I don't have my editor open in front of me so I'll go from memory...
1- Not sure what you mean. You need to provide a data type and a way to interact with the data so your list can use it to "load" anyting into your list entries.
2- So you can use the widget pool. Once a widget get out of vision, it return to the pool and let you take action when it does... Same thing when the list generate a new widget and when it initialized the widgets for the first time.
3- I'm not familiar with those as my project might have change the meaning of those. So I'd rather not say anything on that.

Anyway, even if your goal is just to scroll thing, it's WAY easier to scroll a list of Widget using a ListView than a Scrollbox.

pulsar remnant
#

(wtihout some kinda shared pointer)

grave hatch
#

You can pass in an array of shared ptrs to said structs.

#

That's about it.

#

Or pass in a list of fnames which map to keys in a map if you want to avoid sharedptrs like the plague.

#

(not recommended)

pulsar remnant
#

I mean I'm not saying it's gonna be end of the world, but do I really need a shared pointer? Weird thing is it's not an option, it's a requirement to use shared pointer
Does it somehow track changes to the specified data?

#

Only sane reason I can think is it needs to track the data

grave hatch
#

It might be for for template magic.

#

Or to make sure data isn't deleted out from under it.

#

Or to not have multiple sources of data.

#

E.g. you copy your struct into the arary for the list and now you have 2 copies.

fossil sparrow
#

Or to make sure the list is ordered how you want it to. I never tried it, but I guess you could re-order an array and never move the list so it will not get re-drawn and might be out of date visually.

grave hatch
#

It never blood updates anyway unless you call refresh!

pulsar remnant
#

I mean these are valid reasons, if it's gonna go through a pre-defined automatic generation process, but it also asks me to generate the struct itself, so it doesn't needs the data.
Why can't I pass in for example TArray<MyStruct>* ?

fossil sparrow
#

It get invalidate if the list scrolls.

grave hatch
#

UObject*, Enum, FName, TSharedPtr, etc.

pulsar remnant
grave hatch
#

Yes, but the members of the tarray are structs which are data.

#

You'd pass in a pointer to a TArray<UObject*> too

#

(TArray<UObject*>*)

pulsar remnant
#

So what do I do if I have a TArray<FMyStruct> as my data? Do I create a copy with shared pointers or do I redesign my entire dataflow?

grave hatch
#

I have done that in the past.

pulsar remnant
#

Other than that, I don't get this widget pooling thing also. What is it?

#

Sounds like some pre-determined amount of memory shared between widgets?

grave hatch
#

If you really hated yourself you could try having a tarray of structs and giving it a tarray of ints which are hte indices of the structs in the first array

fossil sparrow
#

The widget pool is at the Uwidget level

grave hatch
#

I would probably isntantly fire you if you did.

pulsar remnant
grave hatch
#

Yeah. It would get messy.

pulsar remnant
#

Probably I don't need to state this, but I'm lost ๐Ÿ˜„

fossil sparrow
#

I never tried to create editor tool... So I don'T know, but it should be usefull if you have a scrolling list.

pulsar remnant
#

I mean I don't have a UWidget in that context, how can it work if it's designed to work with UWidgets?

fossil sparrow
#

So my advice about object pooling might only be for usage in game... I was under the assomption that the goal was to use your SWidget in a UWidget... Not sure about how the editor works in that regards.

#

Sorry if I misled you about the pooling system,

pulsar remnant
#

It's fine, I'm just confused about this anyways. I'll dig UE source a bit. Should have something useful

grave hatch
#

You can make a UWidget class that uses your SWidget.

#

All UWidgets work that way in the end.

fossil sparrow
#

Yeah but I don't know how the editor work... Does it only use SWidgets? That's the meaning of my comment.

grave hatch
#

You can even use UWidgets in Slate.

#

c++ only uses SWidgets.

#

SWidgets aren't available "to the editor" (i.e. bp / python) unless you wrap them in uobjects, like UWidgets.

#

You can make everything you want in SWidgets of course.

fossil sparrow
#

So the editor would use the UListView which is made of an SListView?

grave hatch
#

If that's what UListView does, yes.

#

But all the editor tooling uses SWidgets.

#

Nothing that comes with UE uses UWidgets or BP utility widgets.

#

That makes it all hard to access with BP.

fossil sparrow
#

Ok so you can't make a tool using UWidget correct?

grave hatch
#

Teh editor does it somehow with bp utility widgets.

#

But generally you don't...

fossil sparrow
#

Ok... Good to know!

grave hatch
#

I assume it creates a UWidgetTree, takes the backing SWidget and attaches that to soemthign.

#

It's all SWidgets somewhere.

fossil sparrow
#

Well... Every UMG widget is a SWidget under the hood anyway

#

UMG is "just a wrapper" of slate so we can have visual tooling in the editor

#

That's my understanding and it's correct enough for my usage for now

grave hatch
#

Pretty much

warm vault
#

Hello, why cant I see my borders at all here? It seems like they're not even there

#
ChildSlot
    [
        SNew(SBox)
            .WidthOverride(800) 
            .HeightOverride(400)
            [
                SNew(SBorder)
                    .BorderBackgroundColor(FLinearColor(0.82f, 0.71f, 0.55f)) 
                    .Padding(10)
                    [
                        SNew(SVerticalBox)
                            + SVerticalBox::Slot()
                            .HAlign(HAlign_Center)
                            .VAlign(VAlign_Center)
                            .FillHeight(1.0f)
                            
                            [ 
                                SNew(SBorder).BorderBackgroundColor(FLinearColor::Yellow) 
                                    .Padding(10)[
                                SNew(STextBlock)
                                    .Font(CustomFontInfo)
                                    .Text(bodyFText)
                                    .Text(FText::FromName(message))
                                    .Justification(ETextJustify::Center)
                                    .ColorAndOpacity(FLinearColor::Red)
                                    .AutoWrapText(true)
                            ]]
                            + SVerticalBox::Slot()
                            .HAlign(HAlign_Center)
                            .VAlign(VAlign_Bottom)
                            .AutoHeight()
                            [
                                SNew(SButton)
                                    .Text(FText::FromString("Terminate"))
                                    .ButtonColorAndOpacity(FLinearColor(1.f, 0.57f, 0.14f)) 
                                    .OnClicked(this, &SPopup::OnQuitClicked)
                                    .TextStyle(FCoreStyle::Get(), "EmbossedText") 
                                    .ForegroundColor(FLinearColor::Red)
                                    .ContentPadding(FMargin(10)) 
                            ]
                    ]
            ]
    ];```
grave hatch
#

Go to the tools menu -> debug -> widget reflector. Press the button at the top-left, mouse over your widget and then hit escape.

#

You can then examine what's actualyl going on with your widget wrt sizes and stuff.

stuck jewel
#

The super helpful part of it is hovering over the class name and it tells you the widget desired size and actual size

grave hatch
#

Yup.

stuck jewel
stuck jewel
#

ah. SGraphNode::Tick does some work to mostly fix this... i forgot to call base class Tick in my override

pulsar remnant
#

How can I make size of my checkbox bigger?

SNew(SCheckBox)
.Style(FAppStyle::Get(), "RadioButton")
[
    SNew(STextBlock)
    .Text(INVTEXT("Some Text"))
]
#

If I need to register a new style, how do I do that?

stuck jewel
#

i think it should grow to fit its contents

you could wrap the STextBlock in an SBox and give that box a .MinDesiredWidth

you could set the padding of the SCheckBox to grow it around its contents

#

as for a custom style, there's fancypants and ghetto ways

here's a fancypants way https://minifloppy.it/posts/2023/how-to-style-slate-widgets-using-stylesets/

ghetto way/bare minimum functionality: store an FCheckBoxStyle variable somewhere (i.e. your widget), initialize it to some close defaults on construction

CheckBoxStyleName = FAppStyle::Get().GetWidgetStyle<FCheckBoxStyle>("ToggleButtonCheckBox");```
modify it as needed and just use it
pulsar remnant
#

I don't think it resizes itself with text

#

(or it's child)

grave hatch
stuck jewel
#

thanks, stupid new old blogs

grave hatch
#

Whatever the class is.

#

A lot of the avalanche motion design modules have up to date style classes.

pulsar remnant
grave hatch
#

Not overly

pulsar remnant
#

Great, then I'll just hold a copy of style and edit it

stuck jewel
#

to be clear, using FSlateStyleRegistry::RegisterSlateStyle is the bad way? how would you extend FSlateStyleSet? or are you not sure if your terminology is correct?

grave hatch
#
class FAvaEditorStyle final : public FSlateStyleSet
{
public:
    static FAvaEditorStyle& Get()
    {
        static FAvaEditorStyle Instance;
        return Instance;
    }

    FAvaEditorStyle();
    virtual ~FAvaEditorStyle() override;
};``` example new style header
pulsar remnant
stuck jewel
#

thanks, will take a looksie and learnsie

grave hatch
#

You still gotta register it apparently, but it's done in the constructor.

pulsar remnant
stuck jewel
#

oh yeah these look like a bit less boilerplate, cool

grave hatch
stuck jewel
#

search engine source for final : public FSlateStyleSet and you'll get a bunch of examples

pulsar remnant
#

Got it, thanks

grave hatch
#

Or just : public FSlateStyleSet I guess.

pulsar remnant
#

btw, how do I import icons, images, etc to use within editor (from plugins resources folder)
I saw IMAGE_BRUSH and IMAGE_BRUSH_SVG, but I'm not sure if those are correct ones

grave hatch
#

I'd suggest looking at the class I said earlier ๐Ÿ˜›

pulsar remnant
#

Makes sense, they need it for same reasons ๐Ÿ˜„

pulsar remnant
#

Does StyleSetName matters?
AvaEditorStyle registers as AvaEditor, but it also uses some other stuff that doesn't start with AvaEditor

FAvaEditorStyle::FAvaEditorStyle() : FSlateStyleSet(TEXT("AvaEditor"))
{
    Set("Icons.Canvas", new IMAGE_BRUSH("Icons/ToolboxIcons/Canvas", Icon16));
    Set("AvaEditor.PlaneTool", new IMAGE_BRUSH("Icons/ToolboxIcons/plane", Icon20));
}
grave hatch
#

It does.

#

Well, not really.

#

It's just an identifier.

pulsar remnant
#

I mean is it just I don't need to remember it's name as long as I do MyStyle::Get().GetStyleSetName() ?

grave hatch
#

I'm not sure why that even starts with AvaEditor. honestly.

pulsar remnant
#

Great. Also one more question.
These things happens at constructor, right? But who creates an instance of my style class? an automated thing? Because as far as I know CDO only works for UCLASSes

grave hatch
#

The first time you call ::Get() it will create it.

pulsar remnant
#

Also my old code used to call this, but new code doesn't

FSlateApplication::Get().GetRenderer()->ReloadTextureResources();
grave hatch
#

You definitely don't need to call taht.

pulsar remnant
#

Is it necessary?

#

Okay, it came with plugin template. idk why

#

Thanks for help ๐Ÿ™‚

grave hatch
#

Np

iron dirge
stuck jewel
# iron dirge do you have a youtube channel so i can see more long videos about this system , ...

the parent system is FlowGraph, that might be what you want to look up

the thing i'm working on, i'm calling FlowYap, which adds dialogue nodes to FlowGraph, and will add an underlying simple dialogue management system (so that a game can build its own unique dialogue UI and respond to dialogue progression events)

my addon is under dev, probably a couple months before it's worth sharing at all, only been working on it a couple weeks

iron dirge
iron dirge
mortal canopy
#

with Slate, are we just chaining construction and object decoration/styling commands on top of each other?

mortal canopy
#

it's kinda like web-dev languages - HTML/CSS

mortal canopy
#

If I'm inheriting from SCompoundWidget, what's causing a TSharedPtr<SMainMenuWidget> to not cast as TSharedPtr<SWidget>?

I'm using Unreal Engine 5.4 and I believe I've required the correct dependencies and have the right includes

mortal canopy
#

This is pretty much the only error that comes up, outside of the usual UE5 ones for intellisense

#

Trying .ToSharedRef() just changes the type conversion on the left hand, but to the same error

grave hatch
mortal canopy
#

I made sure to check that and I did

grave hatch
#

Do you get a compile error?

#

Or an intellisense one?

mortal canopy
#

yeah, just that it can't cast to SWidget

#

despite the header including SlateBasic and SlateExtras (MainMenuWidget)

grave hatch
mortal canopy
# grave hatch Yes

and each function call after, such as SWidget.HAlign(...).SWidget.VAlign(...) returns the component/object after it's been modified by that function call?

#

reopening the project now

grave hatch
#

Another thing: .OwneringHud(this) - is this an SWidget?

grave hatch
#

It's not actually the widget, though. Fun thing.

mortal canopy
#

would it be the reference to the component being added/modified?

grave hatch
#

It has a cosntruction object which is actually returned. And that works because the . operator is higher priority than << (or is it <=?) it uses to actually create the widget.

grave hatch
mortal canopy
#

so it just modifies the construction object

grave hatch
#

Yes.

mortal canopy
#

and adds new data to it

#

then it constructs the object

grave hatch
#

You'll see plenty of times that stuff is only available on the construction parameter object.

mortal canopy
#

a gigantic, modular instance factory huh

grave hatch
#

And not changeable afterwards.

mortal canopy
#

this is the full menu script right now (ToSharedRef does pretty much nothing)

#

the SMainMenuWidget.h only includes SlateBasics.h and SlateExtras.h

grave hatch
#

It defines the SMainMenuWidget class as well, I hope?

mortal canopy
#

I was trying to follow BenUIs tutorial introduction but it was... a challenge

#

yeah, it does

grave hatch
#

ToSharedRef is definitely not needed.

mortal canopy
#

I wasn't even sure why BenUI was doing TSharedPtr<class SMainMenuWidget> insetad of forward declaring SMainMenuWidget int he header

grave hatch
#

That method takes a SharedPtr

#

Inline type decorators are just a style. A bad one, I feel.

mortal canopy
#

yeah I... don't really get it

grave hatch
#

It's less work.

mortal canopy
#

ah so they do it cause it saves time, but costs maintenance

grave hatch
#

The alternative is that you have a circular dependency and it can't include the header correctly.

#

And thus can't determine what the class is.

mortal canopy
#

are you including the uh forward declares as a whole there?

grave hatch
#

Forward declarations don't cause circular dependencies?

mortal canopy
#

yeah they don't

#

I'm just referring to the specific in-template one. e.g. TSharedPtr<class SMainMenuWidget> instead of TSharedPtr<SMainMenuWidget> (with a forward declare)

grave hatch
#

Makes zero difference.

mortal canopy
#

well yes, just was confused as to why BenUI was doing the former and not the latter at the time

#

this is all I see right now which is weird to me

grave hatch
#

Compile?

mortal canopy
#

everything else above is just verse errors (because verse randomly triggers during compile)

#

SMainMenuWidget is an SCompoundWidget too

grave hatch
#

That's not good.

#

Don't use that view.

#

It's just giving you intellisense errors and hiding the actual error.

#

If that's Rider, you need to toggle on the raw output (it's a button on the left somewhere). In VS it's the output window.

mortal canopy
grave hatch
#

Yeah, so that's definitely the error, okay.

#

And that only happens if the class can't be found to inherit from swidget.

#

I.e. header not included or circular dependency stopping it frm being included.

mortal canopy
#

that is weird

grave hatch
#

Haha.

#

I see it.

mortal canopy
#

is it something dumb?

grave hatch
#

It is. You'll kick yourself.

mortal canopy
#

is it something really dumb

grave hatch
#

Yes.

#

You're missing a public

mortal canopy
#

you're supposed to do it twice???

#

or is it public void construct

grave hatch
mortal canopy
#

wait where

#

ah wait

#

two weeks in C# again does that to you

grave hatch
#

๐Ÿ™‚

mortal canopy
#

im not even mad or kicking myself over it honestly

#

it's just the trials of the trade

#

switching languages is fun

#

I also did end up getting a Udemy course as a backup option

#

not the biggest fan of Udemy but being in a strange land with any help is better than none

#

(and the book i've got doesn't even cover slate- it just advertises me another book for that purpose at the end)

grave hatch
#

lovely.

#

Well, that's what I'm here fro!

#

๐Ÿ˜›

mortal canopy
#

Yeah, thank you

#

I'm not too sure on the course itself, it has things I'm very interested in and seems to be fairly highly rated

#

it's one by Vince Petrelli

grave hatch
#

I don't think I've ever been on udemy lol

mortal canopy
#

yeah i didn't even remember having an account until a few hours ago

#

I'd try get a link to it but it keeps sending me to my own content page on udemy

#

Unreal Engine 5 C++: Create Custom Editor Tools - Vince Petrelli

#

thought it was worth a shot because of the course content being interesting and each session was in easy chunks rather than "SCREW DA RULES I HAVE THE SHIBILIDABALADIBILIDA"

grave hatch
#

Just remember that tutorials are often very bad

mortal canopy
#

yeah, I'm expecting roadblock issues

grave hatch
#

People work out how to do something, the wrong way, think it's the shit and make a tutorial.

mortal canopy
#

That's a concern I have about anything with Slate because there's not nearly as much on it

grave hatch
#

Have you read through the pins in here?

mortal canopy
#

Yeah, to the best of my ability

mint comet
mortal canopy
#

Yeah, I read that too

pulsar remnant
#

Happened to me the other day. Downside of using macros like SNew is, it won't catch things like private access
Instead you'll get some cryptic error message

grave hatch
#

I mean you'd get a similar error if you used Cast or static_cast.

#

(on non-snew stuff)

stuck jewel
#

i just got in the habit of building often and building in very small chunks if i'm writing big layouts. add one or two things at a time and then it's easy to find nonsensical C++ build error causes

grave hatch
#

Same

pulsar remnant
#

I got underline at left square bracket [ for following code

+SWidgetSwitcher::Slot()
[
  SNew(SMyWidget)
}
grave hatch
#

Probably because you mismatched your brackets.

pulsar remnant
#

No, I mean that's when you forget to do public in : public SCompoundWidget

orchid nova
#

Anyone know if it's possible to get a tool menu context for MakeAttributeLambda or such somehow? Besides using AddDynamicEntry and creating the entries with the attributes inside that

#

It seems calling Section.FindContext... within the attribute lambda results in nullptr, maybe the dynamic entry is the only solution here...

#

FToolMenuExecutionAction passes in the context, but as far as I can tell there's no way to get the context passed into the attribute code

grave hatch
#

You'd need to add a context to find it

#

You can't get the context, except in dynamic menus

#

Well, sort of.

#

In fact, just ignore everything there.

#

I think the question is why don't you want to use a dynamic menu entry to create a dynamic menu?

orchid nova
grave hatch
#

Well... a little I guess.

#

It's only 1 lambda or extra method you need though ๐Ÿ˜›

orchid nova
#

Yeah I'm probably overthinking it. I noticed that if you add entries into the asset editor toolbars, it ticks all the functions every single tick which feels a liiiittle bit iffy if the button state isn't changing every frame

#

But in context menus doesn't seem so as those I guess only exist when the actual menu is open.

#

Either way the lambdas I have currently should be fairly cheap anyway so probably not a big deal

grave hatch
#

Yeah the whole binding thing is terrible in slate.

#

Need nice event driven stuff ๐Ÿ˜ฆ

#

I guess you can do it if you included the no update thingy for every signle element...

#

The invalidation thing!

late rain
#

Hi, guys. I got crashed from FDefaultLayoutBlock::GetTextContext() when I triggered my UI visualization button repeatedly. But, I have no idea why it occurred. Which Slate function is related to the GetTextContext()?

Here's the error log.

Unhandled Exception: EXCEPTION_ACCESS_VIOLATION writing address 0x0000008000000008

UnrealEditor_Slate!FDefaultLayoutBlock::GetTextContext() [D:\build\++UE5\Sync\Engine\Source\Runtime\Slate\Public\Framework\Text\DefaultLayoutBlock.h:22]
UnrealEditor_MyModule!AMCustomActor::PostPhysicsInternal() [F:\-\Source\-\Private\-\AMCustomActor.cpp:28]
UnrealEditor_MyModule!UCustomActorManager::PostPhysicsTick() [F:\-\Source\-\Private\-\UCustomActorManager.cpp:26]
UnrealEditor_MyModule!UTimeManager::Tick() [F:\-\Source\-\Private\-\UTimeManager.cpp:22]
UnrealEditor_MyModule!UCustomTickManager::Tick() [F:\-\Source\-\Private\-\UCustomTickManager.cpp:9]
UnrealEditor_Engine!FTickableGameObject::TickObjects() [D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\Tickable.cpp:153]
UnrealEditor_UnrealEd!UEditorEngine::Tick() [D:\build\++UE5\Sync\Engine\Source\Editor\UnrealEd\Private\EditorEngine.cpp:1977]
UnrealEditor_UnrealEd!UUnrealEdEngine::Tick() [D:\build\++UE5\Sync\Engine\Source\Editor\UnrealEd\Private\UnrealEdEngine.cpp:531]
UnrealEditor!FEngineLoop::Tick() [D:\build\++UE5\Sync\Engine\Source\Runtime\Launch\Private\LaunchEngineLoop.cpp:5825]
UnrealEditor!GuardedMain() [D:\build\++UE5\Sync\Engine\Source\Runtime\Launch\Private\Launch.cpp:188]
UnrealEditor!GuardedMainWrapper() [D:\build\++UE5\Sync\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:118]
UnrealEditor!LaunchWindowsStartup() [D:\build\++UE5\Sync\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:258]
UnrealEditor!WinMain() [D:\build\++UE5\Sync\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:298]
UnrealEditor!__scrt_common_main_seh() [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288]
kernel32
ntdll
grave hatch
#

That's really weird.

#

I'm assuming it's some kind of dangling pointer?

#

Because physics should never really be directly interacting with hte UI and if it is, you're doing something wrong.

dusty pecan
grave hatch
#

Sure.

#

Create your own game viewport client or whatever.

pulsar remnant
#

So I have two exact same widget wrapped in a SBox like this:

SNew(SBox)
.HeightOverride(250.0f)
[
    SNew(MyWidget)
]

It works perfectly fine and does as asked. Overrides the size of the specified widget, but as you may notice latter one can't quite fill that space. So it only makes sense to shrink it to hold all the childs

#

The issue is when I convert .HeightOverride to .MaxDesiredHeight, it still takes all 250 units space exact same with previous one

#

It seems like ScrollBox tries to get all the available space, is there any way to limit it?

#

(To size of its content)

grave hatch
#

VAlign(Top)

pulsar remnant
#

on SBox?

#

Well, it did kinda work, SBox and its content doesn't take unnecessary space now, but overall layout still takes the same size

#

I don't know what's taking that space

#

I can't pick it up in widget reflector

#

To give a bit more context all of these is a a child of SVerticalBox which is contained inside another ScrollBox

#

I got it

#

Solution was to make +SVerticalBox::Slot.AutoHeight()

bleak tapir
#

Is there any kind of wysiwyg slate ui editor plugin?

pulsar remnant
#

It doesn't have all the UI elements, but it's pretty useful to demo existing elements

stuck jewel
#

life hack: in your editor style set, use

#if WITH_LIVE_CODING
    if (ILiveCodingModule* LiveCoding = FModuleManager::LoadModulePtr<ILiveCodingModule>(LIVE_CODING_MODULE_NAME))
    {
        OnPatchCompleteHandle = LiveCoding->GetOnPatchCompleteDelegate().AddRaw(this, &FYourSlateStyleSet::OnPatchComplete);
    }
#endif```
to unregister your slate style, build your style set, and reregister your slate style... so you don't have to reboot the farking editor every single test change

(you have to make sure it's not being actively drawn during live coding though or it'll crash ๐Ÿ˜„ )
grave hatch
pulsar remnant
#

Or are we talking about some pre-determined playground?

grave hatch
#

Because slate isn't reflected... you need to create reflection data.

#

Basically I created a set of reflection data and manually reflected useful types and widgets.

pulsar remnant
#

Sure, but still how would you live demo it? Like you'd need some kinda hot reloading, no?

grave hatch
#

No?

#

I used the reflection data to create widgets at runtime.

pulsar remnant
#

Interesting...

grave hatch
#

Ngl, there were a lot of templates!

pulsar remnant
#

So, normally you can do this

TSharedRef<STextBlock> MyFunc()
{
    return SNew(STextBlock);
}

ChildSlot
[
    SNew(SVerticalBox)

    +SVerticalBox::Slot()
    [
        MyFunc()
    ]
]

Can you somehow include +SVerticalBox::Slot() part in your function?

#

I only achieved returning widgets not slots

grave hatch
#

Yes

#

You'd need to return a SVerticalBox::FSlot object

#

Then do + MySlot() or whatever

pulsar remnant
#

Could you give an example? I can't make it work

grave hatch
#

What errors do you get?

#

Oh

#

It's SVerticalBox::FSlot::FSlotArguments

#

Which you create by doing cpp SVerticalBox::FSlot::FSlotArguments(SVerticalBox::FSlot()) .Arg() .Arg2() .Etc()

pulsar remnant
#

It doesn't work

auto MyFunc()
{
    return
        SVerticalBox::FSlot::FSlotArguments(SVerticalBox::FSlot())
        .AutoHeight()
        [
            SNew(STextBlock)
        ];
};

Log:

Error C2440 : '<function-style-cast>': cannot convert from 'SVerticalBox::FSlot' to 'SVerticalBox::FSlot::FSlotArguments'
Reference C2440 : No constructor could take the source type, or constructor overload resolution was ambiguous
pulsar remnant
grave hatch
#

How are doing it?

#

Ah you pasted.

#

Try ```cpp
SVerticalBox::FSlot::FSlotArguments Slot(SVerticalBox::FSlot());
Slot.AutoHeight()
[
SNew(STextBlock)
];
return Slot;

#

There are shenanigans it does.

pulsar remnant
#

Nope, still same log

grave hatch
#

Coped it wrong!

pulsar remnant
#

It doesn't like SVerticalBox::FSlot as a parameter to SVerticalBox::FSlot::FSlotArguments

grave hatch
#
        SHorizontalBox::FSlot::FSlotArguments Slot(SHorizontalBox::Slot());
        Slot
            .Padding(AddButtonPadding)
            /* stuff */ ;
        return Slot;```
#

I know this works.

#

At once point I was doing MoveTemp(Slot) as well.

pulsar remnant
#

Yeah, this one works

#

It works for vertical box as well, but only with exact same syntax

grave hatch
#

It also works if you do return MoveTemp( ..construct here.. );

pulsar remnant
#

Oh yeah, it wants SVerticalBox::Slot, not SVerticalBox::FSlot

#

I got it to work, thanks ๐Ÿ™‚

auto MyFunc()
{
    return MoveTemp(
    SVerticalBox::FSlot::FSlotArguments(SVerticalBox::Slot())
    .AutoHeight()
    [
        SNew(STextBlock)
        .Text(INVTEXT("This slot and it's widget created from a function"))
    ]);
};

Then:

ChildSlot
[
    SNew(SVerticalBox)
    +MyFunc()
];
grave hatch
#

๐Ÿ™‚

stuck jewel
#

That's so gross (to me) ๐Ÿ˜„

#

Just keep the slot def outside and only make the inner widget...

#

It's so much easier to actually lay out that way... I feel like putting both of those responsibilities together is joining things that don't belong together (i am on the internet, and i have an opinion!)

grave hatch
#

Depends.

#

If you have a lot of things which require exactly the same slot and then exactly teh same child, but just 1 difference, it makes sense to create the entire slot and child with a single function.

#

Like a load of different ftexts you want to display in a uniform way or something.

pallid gyro
#

Ooh I was seeing old messages, seems out of context now.

pallid gyro
#

Is there any actual need/advantage to using the 'Slate_Declare_Widget' macro? Do I need it in order to use TSlateAttributes? I tried to implement these macros in one of my widgets and so far I'm mostly getting errors about deleted constructors being referenced, I am obviously doing something wrong but... what do I really get out of this? before making the changes the widget was declared with the module API and worked just fine in other modules, I could use TAttributes and they seemed fine.

#

I read the section in the slate compendium and I'm still not 100% on the differences, the compendium also only includes an example header and doesn't show what's going on in the .cpp file with the 'Slate_Implement_Widget' macro and the required overrides, so... hmm, idk, it seems like the engine slate widgets all use these macros but third party widgets largely don't bother.

#

The moment I have 'TSlateAttribute' members the compiler gets unhappy with me, saying I'm referencing deleted functions. TAttributes no complaints. I must be missing something.

#

I think I got it to work, you need to declare the member and then also pass the args in the super (?) constructor. Still not sure what the advantages of Slate Attributes are but I guess now I can experiment.

grave hatch
#

The Slate Declare Widget macro sets up the "parent" widget for your widget, basically, in teh class hierarchy.

#

I've not really seen any other use for it.

#

You have to add the function it mentions about complaining to your cpp file and just leave it empty if you want to.

#

(this one: void PrivateRegisterAttributes(struct FSlateAttributeDescriptor::FInitializer&))

#

The sad thing is, it's really useful to declare the widget because it generates reflection data about the widget so you can tell what its parent class is and such. Sadly, the if you don't specify it, it will just use the last base class that did so if you've overriden SCompoundWidget 3 classes deep and not used SLATE_DECLARE_WIDGET, then all 3 subclasses will appear as SCompoundWidget.

#

It's just really bad because it's so under-used in the engine.

pallid gyro
#

I think it also implicitly includes the parent widget inargs in the widget's inargs? I need to test that, I was actually annoyed by that in the past.

grave hatch
#

I don't think it does that.

#

But it's entirely possible to do that without it.

#

SLATE_ARGUMENT(SParentWidget::FArguments, ParentArgs)

#

Then SParentWidget::Construct(InArgs._ParentArgs) in the child construct.

pallid gyro
#

Thanks for the answer Daekesh! I have another question!

#

I think in the past you told me in this channel "never use raw pointers" in slate and that's a good cool cause they definitel like to crash but I have some confusion regarding the correct design choice here, my scenario is basically: I made a pianoroll widgets that renders MIDI data, it gotten pretty complex over time and it now basically is linked to the state of a certain UObject.

#

I primarily used this slate app in an asset editor toolkit, when I wanted to create a UMG variant of it things began acting pretty 'crashy', and it was pretty obvious that I coupled too much logic inside the widget with data from the uobject, so, I generally want to fix it but I am not sure what's the proper approach:

#
  1. pass all the data as attributes, don't let the widget even 'see' the external object
#
  1. make a proper 'init sequence' and 'do less' if the data object isn't instantiated?
#
  1. Figure out a way to have some safe default/placeholder object used whenever the widget is initialized without a real data object
pallid gyro
#

went with 2 ๐Ÿ™‚

grave hatch
#

I would move all of your logic not directly related to the widget out of the widget.

#

Respond to button click? Sure. That button click response should forward the call to something else, though. You don't want actionable code in your UI.

#

That would mean your UMG and Slate widgets could also share a codebase.

pallid gyro
#

Thank you for the reply. Yes, I know it's generally the right thing and I'm already in the process of taking out all the actual 'action logic' outside the widget, it's just that with the init sequence of it all, without the UObject to read the data from the widget kinda only draws a background grid, kinda like a movie sequence editor with no asset to edit, I'm sure this isn't the best practice but an early return if the pointer is null seems 'stable' for now.

#

Another example I can think of which I dealt with in recent weeks was the SGraphEditor, if it doesn't receive a UEdGraph object reference it'll throw an assert rather angrily. maybe it's not terrible in some scenarios? I probably still shoudln't use a raw pointer here.

lusty schooner
#

reposting here, since this seems a more appropiate channel:

Hello, I was battling yesterday trying to get an editor mode slate UI (that I'm writing myself) to display asset thumbnails, but they always appear black. I've been able to query the assets alright, but when following the guides I've found on the internet (and chatgpt), they thumbnails appear . but appear black. Does anyone have some experience with this part of slate/editor?

Cannot seem to make threads sadly, here is the code snippet:

    auto hbox = SNew(SHorizontalBox);
    for (const FAssetData& asset : assets) {
        auto thumbnail =
            MakeShared<FAssetThumbnail>(asset,
                                        kWidth,
                                        kHeight,
                                        ThumbnailPool);

        // clang-format off
        hbox->AddSlot()
        [
            SNew(SBox)
            .MaxDesiredWidth(kWidth)
            .MaxDesiredHeight(kHeight)
            .ToolTipText(FText::FromString(asset.ToSoftObjectPath().ToString()))
            .HAlign(HAlign_Left)
            [
                thumbnail->MakeThumbnailWidget()->AsShared()
            ]
        ];
        // clang-format on
    }
grave hatch
#

What are kwidth and kheight set to?

#

Have you used the widget reflector to check what's actually being displayed?

#

Have you checked the thumbnail widget to make sure it's actually getting an image?

lusty schooner
#

kWidth = kHeight = 64

#

I don't have the editor open right now, will have it later today, but it does show the widget like box (with the color underline depending on asset and the little icon to the down-right). Just that the image is black. In the afternoon I will have more reflector data

grave hatch
#

I'd suggest TSharedRef<SWidget> ThumbnailWidget = thumbnail->MakeThumbnailWidget(); and then debugging the values in that widget from your IDE.

#

(after you check the reflector)

lusty schooner
#

I checked with the reflector but didn't find anything super telling. I did step through the thumbnail widget construct and boiled down to the thumbnail pool having an entry for my asset, but the texture data pointer being null. Wonder if there is some pre-population to be done, or if I can use the same pool as the content browser, since I'm creating a new thumbnail pool of my own

#

Fucking Finally! definitively NOT worth the time invested, but I did learn a couple of stuff.

#

For future reference, the trick was to not create your own ThumbnailPool but use the global one that Unreal uses. I guess they do some pre-population of the textures:

UThumbnailManager::Get().GetSharedThumbnailPool()
mortal canopy
bitter cedar
#

what is the meaning of Unable to find Slate Widget Style?? where can i define a style??

grave hatch
#

Slate widget styles are registered with slate style objects.

#

Like button styles, etc.

#

The editor ones are in the starship style cpp file.

pulsar remnant
#

How I can divide my content area into 2 (vertically) where first area has max height of "half of the available space", but could be smaller based on its content?

grave hatch
#

That's good question

pulsar remnant
#

Couldn't I have a VerticalBox which wraps both and fills the available space
Then I would just set MaxSize of first one at tick

#

Or if it has a lambda for it

grave hatch
#

vertical box slots have a maxheight and a fill height.

#

Setting both of those might work.

pulsar remnant
#

For example:

ChildSlot
[
    SNew(SVerticalBox)
    ...
    ...
    +SVerticalBox::Slot()
    [
        SAssignNew(MyVerticalBox, SVerticalBox)
        +SVerticalBox::Slot()
        .AutoHeight()
        [
            SAssigNew(FirstContentWrapper, SBox)
            [ FIRST_CONTENT ]
        }

        +SVerticalbox::Slot()
        [ SECOND_CONTENT ]
    }
    ...
    ...
}

Then at tick, I'd just get CachedGeometry from MyVerticalBox and set half of it as max size of FirstContentWrapper

grave hatch
#

I wonder if AutoHeight and MaxSize work together.

pulsar remnant
#

Probably does, but I need to somehow know available space for both, so I need to wrap them

sinful hollow
#

Is there an appropriate delegate in Unreal that is called when the Content Browser redraws its content (folder and file icons)?

grave hatch
#

I doubt it.

#

There doesn't apepar to be anything in FContentBrowserModule.

#

You can try using the widget reflector on the content browser itself to see the widget and see if it fires any delegates in its code.

sinful hollow
grave hatch
#

No

sinful hollow
#

๐Ÿฅฒ

mortal canopy
#

if you're using the source code (and feel like breaking something)

#

you could probably mod that behaviour to your copy of your UE?

grave hatch
subtle pelican
#

Isnt slate dead

grave hatch
#

Noooooo

#

Without slate there's no umg!

#

Or common ui!

warm vault
#

How do I handle cleanup of a slate widget class? I have some pointers i need to clean up manually

grave hatch
#

If all the tsharedptr/refs that point to a widget are destroyed, the widget is destroyed.

warm vault
#

is there not a function that takes care of that that can be overriden?

grave hatch
#

No.

#

That's not how ref counted things work. You can get the pointer and delete it manually... But whatever is still using the shared ptr will then crash the engine.

cinder oriole
#

What should you call to capture the mouse and focus without relying on FReply?
just programmatically focusing on the chosen widget until its interacted with

grave hatch
#

You mean like keyboard focus?

#

What do you mean "capture" the mouse? Record mouse events? The mouse move event (overrideable method) would probably be the way to go. Not sure if that triggers if the mouse isn't over the widget, though.

#

There's a ton of events like that, button down, up, etc.

cinder oriole
grave hatch
#

If it doesn't work when it's not over the widget, you can use an input preprocessor to worse the widget to process everything.

#

Look at IInputProcessor and FSlateApplication::RegisterInputPreProcessor

pallid gyro
#

Is the first option in a slate combobox expected to the be the 'reset' option? I'm always having weird issues with the slate comboboxes and it feels like I'm missing something in how they're supposed to be set up

#

Like, when the combo box is generated if you select the first option it never does anything unless you change to a different option and then change it back.

grave hatch
#

Combo boxes have no reset option.

#

When you create a combo box, you give it the initially selected thing. It's expected that what you give it is already selected.

#

I.e. it needs no additional selection.

frigid urchin
#

Hello! I would like these two values in my struct to be displayed on the same row in the editor
(Like with TMaps or TMaps which need meta=(ForceInlineRow))
I followed this tutorial: https://benui.ca/unreal/tmap-same-row/ however it doesn't seem to work with array types (I tried it with non-array variable types and it works)
Would really appreciate any help ๐Ÿ™‚

#
USTRUCT(BlueprintType)
struct FTaggables
{
    GENERATED_BODY()

    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    TArray<TObjectPtr<ATaggableBase>> TaggedTaggables;

    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    TArray<TObjectPtr<ATaggableBase>> TaggableChain;

    FTaggables();

    ~FTaggables();

    bool operator==(const FTaggables& Other) const
    {
        return TaggedTaggables == Other.TaggedTaggables
            && TaggableChain == Other.TaggableChain;
    }

};```
#
#include "TaggablesCustomization.h"
#include "Widgets/DeclarativeSyntaxSupport.h"
#include "PropertyHandle.h"
#include "PropertyCustomizationHelpers.h"

void FTaggablesCustomization::CustomizeHeader(TSharedRef<IPropertyHandle> InStructPropertyHandle,
    FDetailWidgetRow& HeaderRow,
    IPropertyTypeCustomizationUtils& StructCustomizationUtils)
{
    StructPropertyHandle = InStructPropertyHandle;

    // Gets TaggedTaggables Key
    TSharedPtr<IPropertyHandle> Key = StructPropertyHandle->GetChildHandle(0);

    // Gets TaggableChain Value
    TSharedPtr<IPropertyHandle> Value = StructPropertyHandle->GetChildHandle(1);

    // Setup in the header row so that we still get the TArray dropdown
    HeaderRow
        .NameContent()
        [
            Key->CreatePropertyValueWidget()
        ]
        .ValueContent()
        .MaxDesiredWidth(0.0f)
        [
            Value->CreatePropertyValueWidget()
        ];

    // This avoids making duplicate reset boxes
    StructPropertyHandle->MarkResetToDefaultCustomized();
}

void FTaggablesCustomization::CustomizeChildren(TSharedRef<IPropertyHandle> InStructPropertyHandle,
    IDetailChildrenBuilder& StructBuilder,
    IPropertyTypeCustomizationUtils& StructCustomizationUtils)
{
}
grave hatch
#

Have you looked atg the array customisation itself? There's probably some kind of extra call to make. Or a different one

frigid urchin
#

https://ikrima.dev/ue4guide/editor-extensions/detail-customization/array-builder/
I took a look at FDetailArrayBuilder but I'm tbh pretty out of my depth here
Might have to look more into it later

light dragon
#

I'm defining a background colour but it doesn't seem to cover the entire content as it should

grave hatch
#

You mean the gap at the very top of the image?

light dragon
light dragon
grave hatch
#

The ones in FAppStyle are in the starship file, I think.

#

Just search for that

light dragon
grave hatch
#

Yes

tribal bolt
#

is there a way in slate to call this details panel (it's the material instance editor) from inside an editor utility widget? (Either C++ way or Python I dont mind). I basically have a custom viewport and would like to call this window up to be parented inside the viewport and would be updated for each material that is selected...

grave hatch
#

So, to be clear, do you want to:

  • Add a details panel to your widget; or,
  • Access the details panel in the material instance editor.
    ?
tribal bolt
#

Add details panel to my own custom widget

#

And the details panel would reflect the material instance editor properties and accessible options

grave hatch
#

I'm not sure how the property groups section works, tbh.

#

You'd have to look at the code.

#

But all the details panels work by taking a set of objects and display their properties, so it's likely some sort of object somewhere.

#

You can create details panels using the property editor module.

grave hatch
tribal bolt
slim mortar
#

Hey does anybody know how to fix Quixel Bridge on mac with unreal because everytime I try to open it it crashes

pulsar remnant
#

Quick question: Do I have to absolutely wrap a slate widget with UWidget just to contain it inside a UMG widget? Or can I somehow do that in-place?

grave hatch
pulsar remnant
#

Thanks tho

slim mortar
grave hatch
frigid gazelle
#

i am trying to create a window with different tabs
but the row where the tabs are displayed is too small for my liking

where would i apply such style so i can add a padding?

grave hatch
#

They aren't regular tabs. How are you making them?

frigid gazelle
#

i have a custom plugin with a window

and a class derived from SCompoundWidget

here i create the tabs

void SMyTestingWidget::Construct(const FArguments& InArgs)
{
    TabManager = InArgs._TabManager;

    TSharedRef<FWorkspaceItem> AppMenuGroup = TabManager->AddLocalWorkspaceMenuCategory(LOCTEXT("WorkspaceMenu_EderTestingApp", "Eder Testing App"));

    TabManager->RegisterTabSpawner(EderTestingTabs::Tab1Name, FOnSpawnTab::CreateRaw(this, &SMyTestingWidget::OnSpawnTab1))
        .SetDisplayName(LOCTEXT("Tab1Title", "Tab 1"))
        .SetGroup(AppMenuGroup);

    TabManager->RegisterTabSpawner(EderTestingTabs::Tab2Name, FOnSpawnTab::CreateRaw(this, &SMyTestingWidget::OnSpawnTab2))
        .SetDisplayName(LOCTEXT("Tab2Title", "Tab 2"))
        .SetGroup(AppMenuGroup);

    TabManager->RegisterTabSpawner(EderTestingTabs::Tab3Name, FOnSpawnTab::CreateRaw(this, &SMyTestingWidget::OnSpawnTab3))
        .SetDisplayName(LOCTEXT("Tab3Title", "Tab 3"))
        .SetGroup(AppMenuGroup);

    const TSharedRef<FTabManager::FLayout> Layout = FTabManager::NewLayout("EderTestingLayout")
        ->AddArea
        (
            FTabManager::NewPrimaryArea()
            ->SetOrientation(Orient_Horizontal)
            ->Split
            (
                FTabManager::NewStack()
                ->AddTab(EderTestingTabs::Tab1Name, ETabState::OpenedTab)
                ->AddTab(EderTestingTabs::Tab2Name, ETabState::OpenedTab)
                ->AddTab(EderTestingTabs::Tab3Name, ETabState::OpenedTab)
            )
        );

    ChildSlot
        [
            TabManager->RestoreFrom(Layout, TSharedPtr<SWindow>()).ToSharedRef()
        ];
}
#

while each tab is

TSharedRef<SDockTab> SMyTestingWidget::OnSpawnTab1(const FSpawnTabArgs& SpawnTabArgs)
{
    return SNew(SDockTab)
        .TabRole(ETabRole::NomadTab)
        .CanEverClose(false)
        [
            SNew(STextBlock)
                .Text(LOCTEXT("Tab1Content", "This is the content of Tab 1"))
        ];
}
#

and in my plugin module i do:

void FEderTestingModule::StartupModule()
{
    // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
    
    FEderTestingStyle::Initialize();
    FEderTestingStyle::ReloadTextures();

    FEderTestingCommands::Register();
    
    PluginCommands = MakeShareable(new FUICommandList);

    PluginCommands->MapAction(
        FEderTestingCommands::Get().OpenPluginWindow,
        FExecuteAction::CreateRaw(this, &FEderTestingModule::PluginButtonClicked),
        FCanExecuteAction());

    UToolMenus::RegisterStartupCallback(FSimpleMulticastDelegate::FDelegate::CreateRaw(this, &FEderTestingModule::RegisterMenus));




    // Register the tab spawner for the main plugin tab
    FGlobalTabmanager::Get()->RegisterNomadTabSpawner(EderTestingTabName, FOnSpawnTab::CreateRaw(this, &FEderTestingModule::OnSpawnPluginTab))
        .SetDisplayName(LOCTEXT("FEderTestingTabTitle", "Eder Testing"))
        .SetMenuType(ETabSpawnerMenuType::Hidden);    
}
TSharedRef<SDockTab> FEderTestingModule::OnSpawnPluginTab(const FSpawnTabArgs& SpawnTabArgs)
{
    TSharedRef<SDockTab> DockTab = SNew(SDockTab)
        .TabRole(ETabRole::NomadTab)
        .ContentPadding(FMargin(5,5));

    TSharedRef<SMyTestingWidget> TestingWidget = SNew(SMyTestingWidget)
        .TabManager(FGlobalTabmanager::Get()->NewTabManager(DockTab));

    DockTab->SetContent(TestingWidget);
    /*DockTab->SetPadding(FMargin(20, 20));*/
    return DockTab;
}
grave hatch
#

Hmm. I'm not sure you can change the style of a tab.

frigid gazelle
#

they just feel really close to the top somehow

#

i thought maybe i have something wrong with the registering of the menus in my plugin entry point?

grave hatch
#

I don't disagree. They do look a little bad.

frigid gazelle
#

with

    TSharedRef<SDockTab> DockTab = SNew(SDockTab)
        .TabRole(ETabRole::NomadTab)
        .ContentPadding(FMargin(5,5));
``` i could make it a bit better but still they i have the feeling something is wrong there
#

slate is really confusing in the beginning

grave hatch
#

It is

#

That isn't padding the tab itself, though, just the tab contents.

#

Or maybe it is?

#

Idk

frigid gazelle
#

no no you are right

#

it also increases the padding of the "border" around the content

split maple
#

Does anyone have a good tutorial on Slate? General explanation of basics such as slate macros etc

grave hatch
#

The pinned qt to slate guide is pretty good.

frigid gazelle
#

can someone help me why i can't bind my static fuction to the onclicked delegate?
inside

TSharedRef<SDockTab> SMyTestingWidget::OnSpawnTab1(const FSpawnTabArgs& SpawnTabArgs)
{
// Other Stuff
            SNew(SButton)
                .Text(LOCTEXT("Button1", "This is a BUTTON"))
                .OnClicked(FOnClicked::BindStatic(SMyTestingWidget::CreateFolder));
}
.hpp
static FReply CreateFolder();

.cpp


FReply SMyTestingWidget::CreateFolder()
{
    UE_LOG(LogTemp, Warning, TEXT("ItWasFired"));

    return FReply::Handled();
}
#

error is:
Error C2352 'TDelegate<FReply (void),FDefaultDelegateUserPolicy>::BindStatic': a call of a non-static member function requires an object

grave hatch
#
  1. You're missing a & on your function pointer!
  2. Have you tried just .OnClicked(&SMyTestingWidget::CreateFolder); ? That might work also.
#

I rarely bind to statics in slate events! ๐Ÿ˜ฆ

fluid jewel
#

I'm trying to make a custom custom graph with nodes.
I'm looking at GenericGraph and trying to re-make a minimalist version for my needs, however I haven't been able to figure out what is actualyl responsible for drawing the pin connections
I'm trying to get something like the behaviour tree nodes / pins where they connect vertically.
This is what i have so far. just trying to see if i can get get pointed in the right direction

limber stump
light oxide
grave hatch
#

I suppose in your example, a static bind might make sense, but they generally don't.

#

If you're using static methods, that generally means you're using static objects/globals/etc. And that's not good.

#

For instance, the entire engine is plagued with GWorld used everywhere. That means that 99% of the systems break if you try to use them for something other than the one editor world that's loaded.

split maple
grave hatch
#

Are you saving strong references to those uobjects you're loading?

split maple
#

You mean are they class members?

grave hatch
#

Are they strong class members.

#

Slate doesn't support UPROPERTYs, even though you can just add them and the compiler won't care.

#

If you want to keep uassets loaded, best to store them in a TStrongObjectPtr in the class. Or use TObjectPtrs and inherit from FGCObject.

frigid gazelle
grave hatch
#

You don't have to use uobjects at all.

#

Using globals or static objects for command context is just really bad. You can read about the pitfalls of it on google.

frigid gazelle
#

so i should rather create non unreal reflection type classes ? or from which class should i derive then?

grave hatch
#

Yeah. You can do that.

#

Or you could create a subsystem?

#

An editor subsystem is basically a global, but it's 1 step up.

frigid gazelle
#

just out of curiosity

when i create a non reflection type class
should the object still be created with NewObject? or standard c++ ?

#

sorry for the stupid question but i had the thought that all classes in unreal should atleast derive from uobject

grave hatch
#

For non-uobjects, I would use the unreal smart pointers

#

TSharedPtr TSharedRef TWeakPtr

#

(and TUniquePtr)

frigid gazelle
#

okay so

TSharedPtr<MyNonUObjectClass> Foo = NewObject<MyNonUObjectClass>(this / nullptr);

?

grave hatch
#

TSharedRef<MyNonUObjectClass> Foo = MakeShared<MyNonUObjectClass>(constructor params)

frigid gazelle
#

oh MakeShared

grave hatch
#

A shared ref is just a sharedptr that can't be null.

#

It's not actually a reference.

frigid gazelle
#

i see so i need to initialize it at declaration

grave hatch
#

For a ref, yeah.

frigid gazelle
#

thank you for the insights! really appreciate it

grave hatch
#

With a ptr you can do TSharedPtr<MyClass> Foo; and it will just be null.

#

Or you can do = nullptr

#

These are ref counted, not proper gc, so you have to be careful with them.

#

If 2 objects hold storng refs to each other, they will never be destroyed, etc. ๐Ÿ™‚

frigid gazelle
#

yeah i thought so that GC won't help me there much but thats okay in my case i will implement a subsystem anyway since i never did and sounds useful but wanted to know how i would create non UObject types

grave hatch
#

You can always use std smart pointers too