I’m currently working on creating a basic slate list and got to the point of making an OnGenerateRow function. Looking at the examples in the code, which I’m guessing might be outdated, they indicate that converting from an STextBlock to an ITableRow happens automatically. This is the example by the way:
TSharedRef OnGenerateWidgetForList( FString* InItem )
{
return SNew(STextBlock).Text( (*InItem) )
}
I’m trying to adapt this to my code, resulting in this:
TSharedRef OnGenerateRowForList( TSharedPtr InItem)
{
FString testString = TEXT("Temporary Text");
TSharedRef testWidget = SNew(STextBlock).Text(testString);
return testWidget;
}
Intellisense thinks it’s all good, but when I compile I get:
1>C:\Program Files\Rocket\Engine\Source\Runtime\Core\Public\Templates\SharedPointer.h(210): error C2440: 'initializing' : cannot convert from 'STextBlock *const ' to 'ITableRow *'
Any ideas?
Dear Ineni,
You should look through all of the Shootergame UI Source code!
Here is one place where ITableRow is used
// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.
#include "ShooterGame.h"
#include "SShooterLeaderboard.h"
void SShooterLeaderboard::Construct(const FArguments& InArgs)
{
PCOwner = InArgs._PCOwner;
OwnerWidget = InArgs._OwnerWidget;
const int32 BoxWidth = 125;
LeaderboardReadCompleteDelegate = FOnLeaderboardReadCompleteDelegate::CreateRaw(this, &SShooterLeaderboard::OnStatsRead);
ChildSlot
.VAlign(VAlign_Fill)
.HAlign(HAlign_Fill)
[
SNew(SBox)
.WidthOverride(600)
.HeightOverride(600)
[
SAssignNew(RowListWidget, SListView< TSharedPtr >)
.ItemHeight(20)
.ListItemsSource(&StatRows)
.SelectionMode(ESelectionMode::Single)
.OnGenerateRow(this, &SShooterLeaderboard::MakeListViewWidget)
.OnSelectionChanged(this, &SShooterLeaderboard::EntrySelectionChanged)
.OnMouseButtonDoubleClick(this,&SShooterLeaderboard::OnListItemDoubleClicked)
.HeaderRow(
SNew(SHeaderRow)
+ SHeaderRow::Column("Rank").FixedWidth(BoxWidth/3) .DefaultLabel(NSLOCTEXT("LeaderBoard", "PlayerRankColumn", "Rank"))
+ SHeaderRow::Column("PlayerName").FixedWidth(BoxWidth*2) .DefaultLabel(NSLOCTEXT("LeaderBoard", "PlayerNameColumn", "PlayerName"))
+ SHeaderRow::Column("Kills") .DefaultLabel(NSLOCTEXT("LeaderBoard", "KillsColumn", "Kills"))
+ SHeaderRow::Column("Deaths") .DefaultLabel(NSLOCTEXT("LeaderBoard", "DeathsColumn", "Deaths")))
]
];
}
/**
* Get the current game
* @return The current game
*/
AShooterGameMode* SShooterLeaderboard::GetGame() const
{
const APlayerController* const Owner = PCOwner.Get();
if (Owner != NULL)
{
UWorld* const World = Owner->GetWorld();
if (World)
{
return World->GetAuthGameMode();
}
}
return NULL;
}
/**
* Get the current game session
* @return The current game session
*/
AShooterGameSession* SShooterLeaderboard::GetGameSession() const
{
AShooterGameMode* const ShooterGameMode = GetGame();
if (ShooterGameMode)
{
return Cast(ShooterGameMode->GameSession);
}
return NULL;
}
/** Starts reading leaderboards for the game */
void SShooterLeaderboard::ReadStats()
{
StatRows.Reset();
IOnlineSubsystem* const OnlineSub = IOnlineSubsystem::Get();
if(OnlineSub)
{
IOnlineLeaderboardsPtr Leaderboards = OnlineSub->GetLeaderboardsInterface();
if (Leaderboards.IsValid())
{
ReadObject = MakeShareable(new FShooterAllTimeMatchResultsRead());
TSharedRef ReadObjectRef = ReadObject.ToSharedRef();
Leaderboards->AddOnLeaderboardReadCompleteDelegate(LeaderboardReadCompleteDelegate);
Leaderboards->ReadLeaderboardsForFriends(0, ReadObjectRef);
}
else
{
// TODO: message the user?
}
}
}
/** Called on a particular leaderboard read */
void SShooterLeaderboard::OnStatsRead(bool bWasSuccessful)
{
IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get();
if(OnlineSub)
{
IOnlineLeaderboardsPtr Leaderboards = OnlineSub->GetLeaderboardsInterface();
if (Leaderboards.IsValid())
{
Leaderboards->ClearOnLeaderboardReadCompleteDelegate(LeaderboardReadCompleteDelegate);
}
}
if (bWasSuccessful)
{
if (ReadObject.IsValid())
{
for (int Idx=0; Idx < ReadObject->Rows.Num(); ++Idx)
{
TSharedPtr NewLeaderboardRow = MakeShareable(new FLeaderboardRow());
NewLeaderboardRow->Rank = FString::FromInt(ReadObject->Rows[Idx].Rank);
NewLeaderboardRow->PlayerName = ReadObject->Rows[Idx].NickName;
FVariantData * Variant = ReadObject->Rows[Idx].Columns.Find(LEADERBOARD_STAT_KILLS);
if (Variant)
{
int32 Val;
Variant->GetValue(Val);
NewLeaderboardRow->Kills = FString::FromInt(Val);
}
Variant = ReadObject->Rows[Idx].Columns.Find(LEADERBOARD_STAT_DEATHS);
if (Variant)
{
int32 Val;
Variant->GetValue(Val);
NewLeaderboardRow->Deaths = FString::FromInt(Val);
}
StatRows.Add(NewLeaderboardRow);
}
RowListWidget->RequestListRefresh();
ReadObject = NULL;
}
}
}
void SShooterLeaderboard::OnKeyboardFocusLost( const FKeyboardFocusEvent& InKeyboardFocusEvent )
{
if (InKeyboardFocusEvent.GetCause() != EKeyboardFocusCause::SetDirectly)
{
FSlateApplication::Get().SetKeyboardFocus(SharedThis( this ));
}
}
FReply SShooterLeaderboard::OnKeyboardFocusReceived(const FGeometry& MyGeometry, const FKeyboardFocusEvent& InKeyboardFocusEvent)
{
return FReply::Handled().SetKeyboardFocus(RowListWidget.ToSharedRef(),EKeyboardFocusCause::SetDirectly).CaptureJoystick(SharedThis( this ));
}
void SShooterLeaderboard::EntrySelectionChanged(TSharedPtr InItem, ESelectInfo::Type SelectInfo)
{
SelectedItem = InItem;
}
void SShooterLeaderboard::OnListItemDoubleClicked(TSharedPtr InItem)
{
SelectedItem = InItem;
FSlateApplication::Get().SetKeyboardFocus(SharedThis(this));
}
void SShooterLeaderboard::MoveSelection(int32 MoveBy)
{
int32 SelectedItemIndex = StatRows.IndexOfByKey(SelectedItem);
if (SelectedItemIndex+MoveBy > -1 && SelectedItemIndex+MoveBy < StatRows.Num())
{
RowListWidget->SetSelection(StatRows[SelectedItemIndex+MoveBy]);
}
}
FReply SShooterLeaderboard::OnControllerButtonPressed(const FGeometry& MyGeometry, const FControllerEvent& ControllerEvent)
{
FReply Result = FReply::Unhandled();
const EKeys::Type Key = ControllerEvent.GetEffectingButton();
if (Key == EKeys::Gamepad_FaceButton_Bottom)
{
// TODO: show details
Result = FReply::Handled();
FSlateApplication::Get().SetKeyboardFocus(SharedThis(this));
}
else if (Key == EKeys::Gamepad_DPad_Up || Key == EKeys::Gamepad_LeftStick_Up)
{
MoveSelection(-1);
Result = FReply::Handled();
}
else if (Key == EKeys::Gamepad_DPad_Down || Key == EKeys::Gamepad_LeftStick_Down)
{
MoveSelection(1);
Result = FReply::Handled();
}
return Result.IsEventHandled() ? Result : OwnerWidget->OnControllerButtonPressed(MyGeometry,ControllerEvent);
}
FReply SShooterLeaderboard::OnKeyDown(const FGeometry& MyGeometry, const FKeyboardEvent& InKeyboardEvent)
{
FReply Result = FReply::Unhandled();
const EKeys::Type Key = InKeyboardEvent.GetKey();
if (Key == EKeys::Enter)
{
// TODO:
Result = FReply::Handled();
FSlateApplication::Get().SetKeyboardFocus(SharedThis(this));
}
return Result;
}
TSharedRef SShooterLeaderboard::MakeListViewWidget(TSharedPtr Item, const TSharedRef& OwnerTable)
{
class SLeaderboardRowWidget : public SMultiColumnTableRow< TSharedPtr >
{
public:
SLATE_BEGIN_ARGS(SLeaderboardRowWidget){}
SLATE_END_ARGS()
void Construct(const FArguments& InArgs, const TSharedRef& InOwnerTable, TSharedPtr InItem)
{
Item = InItem;
SMultiColumnTableRow< TSharedPtr >::Construct(FSuperRowType::FArguments(), InOwnerTable);
}
TSharedRef GenerateWidgetForColumn(const FName& ColumnName)
{
FString ItemText;
if (ColumnName == "Rank")
{
ItemText = Item->Rank;
}
else if (ColumnName == "PlayerName")
{
ItemText = Item->PlayerName.Left(MAX_PLAYER_NAME_LENGTH);
}
else if (ColumnName == "Kills")
{
ItemText = Item->Kills;
}
else if (ColumnName == "Deaths")
{
ItemText = Item->Deaths;
}
return SNew(STextBlock) .Text(ItemText)
.Font(FEditorStyle::GetFontStyle(TEXT("ShooterGame.MenuServerListFont")))
.ShadowColorAndOpacity(FLinearColor::Black)
.ShadowOffset(FIntPoint(-1,1));
}
TSharedPtr Item;
};
return SNew(SLeaderboardRowWidget, OwnerTable, Item);
}
Here’s another Shooter game use of ITableRow
ShooterGame\Source\ShooterGame\Private\UI\Menu\Widgets\SShooterServerList.cpp
Ah, that helped, thanks Rama (Not sure if it’s really an answer, but I’ll mark it as one anyway).
If anyone else finds this, my OnGenerateRow function ended up looking like this:
TSharedRef SMyGameSlateHUDWidget::OnGenerateWidgetForList(TSharedPtr InItem, const TSharedRef& OwnerTable)
{
//return SNew(STextBlock).Text(**InItem.Get());
STextBlock content;
content.SetText(FString::Printf(TEXT("test string")));
TSharedRef sptrContent(&content);
TSharedRef>> test = SNew(STableRow>,OwnerTable);
test->SetContent(sptrContent);
//test->SetContent(sptrContent);
return test;
}