Download

Moving widgets in VerticalBox based panel widget

I want to move widgets around in the VerticalBox in-game, but it doesn’t offer that functionality that I know of, so I created my own class base on it. I tried programming the functionality, but it doesn’t seem to work:


//=================================================================
// 
//=================================================================
void UVerticalDynamic::SwitchWidgets(UWidget* Content1, UWidget* Content2)
{
	if (!MyVerticalBox.IsValid())
		return;

	UVerticalBoxSlot *pSlot1 = NULL;
	UVerticalBoxSlot *pSlot2 = NULL;


	for (UPanelSlot* Slot : Slots)
	{
		UVerticalBoxSlot* TypedSlot = Cast<UVerticalBoxSlot>(Slot);
		if (!TypedSlot)
			continue;

		if (Slot->Content == Content1)
			pSlot1 = TypedSlot;

		if (Slot->Content == Content2)
			pSlot2 = TypedSlot;
	}

	if (!pSlot1 || !pSlot2)
	{
		UE_LOG(LogTemp, Warning, TEXT("Could not find slots!"));
		return;
	}

	UWidget *pTemp = pSlot2->Content;
	pSlot2->Content = pSlot1->Content;
	pSlot1->Content = pTemp;

	RebuildWidget();
}

Anyone have any insight what I am doing wrong?

I seem to have it working now. Not sure if this could have been done easier with something already existing, but here’s the code if someone has a need for it.

VerticalDynamic.h



#pragma once

#include "Runtime/UMG/Public/UMG.h"
#include "Runtime/UMG/Public/UMGStyle.h"
#include "Components/PanelWidget.h"
#include "Runtime/UMG/Public/Components/VerticalBox.h"
#include "VerticalDynamic.generated.h"

class UVerticalDynamicSlot;

UCLASS()
class I_AM_HUMAN_API UVerticalDynamic : public UVerticalBox
{
	GENERATED_UCLASS_BODY()

public:
	/*Switch places of widgets*/
	UFUNCTION(BlueprintCallable, Category = "Panel")
	void SwitchWidgets(UWidget* Content1, UWidget* Content2);
};


VerticalDynamic.cpp file



#include "I_Am_Human.h"
#include "Runtime/UMG/Public/Components/VerticalBox.h"
#include "VerticalDynamic.h"
#include "SBoxPanel.h"


/////////////////////////////////////////////////////
// UVerticalBox

UVerticalDynamic::UVerticalDynamic(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{

}

//=================================================================
// 
//=================================================================
void UVerticalDynamic::SwitchWidgets(UWidget* Content1, UWidget* Content2)
{
	if (!MyVerticalBox.IsValid())
		return;

	TPanelChildren<SBoxPanel::FSlot> *pChildren = reinterpret_cast<TPanelChildren<SBoxPanel::FSlot> *>(MyVerticalBox->GetChildren());
	if (!pChildren)
		return;

	int32 iIndex1 = -1;
	int32 iIndex2 = -1;

	for (int32 i = 0; i < MyVerticalBox->GetChildren()->Num(); i++)
	{
		if (pChildren->GetChildAt(i) == Content1->TakeWidget())
		{
			iIndex1 = i;
		}

		if (pChildren->GetChildAt(i) == Content2->TakeWidget())
		{
			iIndex2 = i;
		}
	}

	//UE_LOG(LogTemp, Warning, TEXT("Index 1: %d], Index 2: %d]"), iIndex1, iIndex2);
	if (iIndex1 == -1 || iIndex2 == -1)
		return;

	pChildren->Swap(iIndex1, iIndex2);

	MyVerticalBox->Invalidate(EInvalidateWidget::Layout);
}


Hey Au-heppa,

If you are creating new functionality for the editor / projects, you can submit this code as a Pull Request (https://github.com/EpicGames/UnrealEngine/compare?expand=1) where it will be reviewed by developers and could be added into the engine.

Cheers

Doug

I have never really used GitHub beyond downloading codebases. If I upload it should I include it as a change to VerticalBox or as the new class VerticalDynamic?