Here you go. Actually, if you see messy code, please feel free to critique.
The GenerateShipEngineList function does change the list properly on each selection change (seen in the debug output), it is just the widget that does not visually update half the time.
EngineListView is the slave list, which is filtered according to propulsion type.
//GameDialog.h
//declarations
private:
TArray< TSharedPtr< FShipPropulsionData > > ShipPropulsionItems;
TArray< TSharedPtr< FShipEngineData > > ShipEngineItems;
TSharedPtr<SListView< TSharedPtr<FShipPropulsionData> >> EngineListView;
//GameDialog.cpp
// on selection changed function
void GameDialog::PropulsionEntrySelectionChanged(TSharedPtr<FShipPropulsionData> InItem, ESelectInfo::Type SelectInfo) {
UE_LOG(LogClass, Log, TEXT("GameDialog::PropulsionEntrySelectionChanged %s"),*InItem->PropulsionID);
GenerateShipEngineList(InItem->PropulsionID);
SelectedPropulsionItem = InItem;
EngineListView->RequestListRefresh();
}
//list update function
void GameDialog::GenerateShipEngineList(FString type) {
UE_LOG(LogClass, Log, TEXT("GameDialog::GenerateShipEngineList %s"),*type);
if (EngineListView.IsValid() && EngineListView->IsPendingRefresh()) {
UE_LOG(LogClass, Log, TEXT("GameDialog::GenerateShipEngineList %s PENDING"),*type);
return;
}
ShipEngineItems.Empty();
TWeakObjectPtr<UDataTable> dataTable = GameShipData::Get()->ShipEngineDataTable;
if (dataTable.IsValid()) {
TArray<FName> rowNames;
dataTable->RowMap.GetKeys(rowNames);
for(const auto& row : rowNames) {
FShipEngineData* ptr = dataTable.Get()->FindRow<FShipEngineData>(row,row.ToString());
if (ptr != nullptr && ptr->PropulsionID == type) {
UE_LOG(LogClass, Log, TEXT("GameDialog::GenerateShipEngineList %s %s"),*type,*ptr->LongName);
TSharedPtr<FShipEngineData> spd = MakeShareable(new FShipEngineData(*ptr));
ShipEngineItems.Add(spd);
}
}
}
}
//list creation
TSharedPtr<SCompoundWidget> GameDialog::CreateShipDesignParameters(UWorld* world) {
UE_LOG(LogClass, Log, TEXT("GameDialog::CreateShipDesignParameters"));
FString startType;
ShipPropulsionItems.Empty();
TWeakObjectPtr<UDataTable> dataTable = GameShipData::Get()->ShipPropulsionDataTable;
if (dataTable.IsValid()) {
TArray<FName> rowNames;
dataTable->RowMap.GetKeys(rowNames);
for(const auto& row : rowNames) {
FShipPropulsionData* ptr = dataTable.Get()->FindRow<FShipPropulsionData>(row,row.ToString());
if (ptr != nullptr) {
if (startType.IsEmpty()) startType = ptr->PropulsionID;
TSharedPtr<FShipPropulsionData> spd = MakeShareable(new FShipPropulsionData(*ptr));
ShipPropulsionItems.Add(spd);
}
}
}
GenerateShipEngineList(startType);
TSharedRef<SScrollBar> ExternalScrollbar1 = SNew(SScrollBar);
TSharedRef<SScrollBar> ExternalScrollbar2 = SNew(SScrollBar);
return
(...)
SAssignNew(EngineListView, SListView< TSharedPtr<FShipPropulsionData> >)
.ExternalScrollbar( ExternalScrollbar1 )
.ItemHeight(24)
.ListItemsSource( &ShipPropulsionItems )
.OnGenerateRow( this, &GameDialog::OnGeneratePropulsionList )
.SelectionMode( ESelectionMode::Single )
.OnSelectionChanged(this, &GameDialog::PropulsionEntrySelectionChanged)
.HeaderRow (
(...)
}