11#include <util/ue-header-guard-begin.h>
13#include "Engine/World.h"
14#include "TimerManager.h"
15#include "Framework/Application/SlateApplication.h"
16#include "Framework/Docking/TabManager.h"
17#include "Styling/AppStyle.h"
18#include "Widgets/Colors/SColorBlock.h"
19#include "Widgets/Colors/SColorPicker.h"
20#include "Widgets/Docking/SDockTab.h"
21#include "Widgets/Input/SButton.h"
22#include "Widgets/Input/SCheckBox.h"
23#include "Widgets/Input/SEditableTextBox.h"
24#include "Widgets/Layout/SBox.h"
25#include "Widgets/SBoxPanel.h"
26#include "Widgets/Text/STextBlock.h"
27#include "Widgets/Views/STableRow.h"
28#include <util/ue-header-guard-end.h>
30#define LOCTEXT_NAMESPACE "SLightDefaultsPanel"
40 class SLightDefaultsRow :
public STableRow<TSharedPtr<FLightAssetSummary>>
43 SLATE_BEGIN_ARGS(SLightDefaultsRow) {}
46 void Construct(const FArguments& InArgs, const TSharedRef<STableViewBase>& OwnerTable, TSharedPtr<
FLightAssetSummary> InItem,
47 TFunction<
void(TSharedPtr<
FLightAssetSummary>)> InOnLiveChanged, TFunction<
void(const FString&,
bool)> InOnToggleSelect,
48 TFunction<
void(const FString&,
bool)> InOnTogglePreviewOn =
nullptr)
51 OnLiveChanged = MoveTemp(InOnLiveChanged);
52 OnToggleSelect = MoveTemp(InOnToggleSelect);
53 OnTogglePreviewOn = MoveTemp(InOnTogglePreviewOn);
64 const bool bIsTrafficRow =
static_cast<bool>(OnTogglePreviewOn);
65 const bool bIsBuildingsRow = Item.IsValid() && Item->ClassName == TEXT(
"ProceduralBuildings");
66 const bool bIsLegacyBuildingsRow = Item.IsValid() && Item->ClassName == TEXT(
"LegacyBuildings");
67 const bool bIsAnyBuildingsRow = bIsBuildingsRow || bIsLegacyBuildingsRow;
68 const bool bShowIntensity = !bIsTrafficRow;
69 const bool bShowColor = !bIsTrafficRow;
71 TSharedRef<SHorizontalBox> RowBox = SNew(SHorizontalBox)
73 + SHorizontalBox::Slot().AutoWidth().Padding(2.0f).VAlign(VAlign_Center)
75 SNew(SBox).WidthOverride(240.0f)
77 SNew(STextBlock).Text(FText::FromString(Item->ClassName))
81 + SHorizontalBox::Slot().AutoWidth().Padding(2.0f).VAlign(VAlign_Center)
83 SNew(SBox).WidthOverride(50.0f)
85 SNew(STextBlock).Text(FText::FromString(FString::FromInt(Item->InstanceCount)))
91 const TCHAR* IntensityHint = bIsAnyBuildingsRow ? TEXT(
"Percent Lit") : TEXT(
"Intensity");
92 RowBox->AddSlot().AutoWidth().Padding(2.0f)
93 [ MakeNumberBox(IntensityHint, Item->Current.Intensity, [
this](
float V) { Item->Current.Intensity = V; NotifyLiveChanged(); }) ];
96 RowBox->AddSlot().AutoWidth().Padding(2.0f)
97 [ MakeNumberBox(TEXT(
"Emissive"), Item->Current.EmissiveIntensity, [
this](
float V) { Item->Current.EmissiveIntensity = V; NotifyLiveChanged(); }) ];
101 RowBox->AddSlot().AutoWidth().Padding(2.0f).VAlign(VAlign_Center)
102 [ MakeColorSwatch(
this) ];
105 RowBox->AddSlot().AutoWidth().Padding(6.0f, 2.0f).VAlign(VAlign_Center)
108 .Style(FAppStyle::Get(),
"ToggleButtonCheckbox")
109 .Padding(FMargin(8.0f, 2.0f))
110 .IsChecked_Lambda([
this]() {
return bIsSelected ? ECheckBoxState::Checked : ECheckBoxState::Unchecked; })
111 .OnCheckStateChanged_Lambda([
this](ECheckBoxState NewState)
113 bIsSelected = (NewState == ECheckBoxState::Checked);
116 OnToggleSelect(Item->ClassName, bIsSelected);
120 SNew(STextBlock).Text(LOCTEXT(
"SelectButton",
"Select"))
124 if (OnTogglePreviewOn)
126 RowBox->AddSlot().AutoWidth().Padding(2.0f, 2.0f).VAlign(VAlign_Center)
129 .Style(FAppStyle::Get(),
"ToggleButtonCheckbox")
130 .Padding(FMargin(8.0f, 2.0f))
131 .IsChecked_Lambda([
this]() {
return bIsPreviewOn ? ECheckBoxState::Checked : ECheckBoxState::Unchecked; })
132 .OnCheckStateChanged_Lambda([
this](ECheckBoxState NewState)
134 bIsPreviewOn = (NewState == ECheckBoxState::Checked);
135 if (OnTogglePreviewOn)
137 OnTogglePreviewOn(Item->ClassName, bIsPreviewOn);
141 SNew(STextBlock).Text(LOCTEXT(
"PreviewOnButton",
"Preview On"))
146 STableRow<TSharedPtr<FLightAssetSummary>>::Construct(
147 STableRow<TSharedPtr<FLightAssetSummary>>::FArguments()
148 .Padding(FMargin(4.0f, 2.0f))
154 TSharedPtr<FLightAssetSummary> Item;
155 TFunction<void(TSharedPtr<FLightAssetSummary>)> OnLiveChanged;
156 TFunction<void(
const FString&,
bool)> OnToggleSelect;
157 TFunction<void(
const FString&,
bool)> OnTogglePreviewOn;
158 bool bIsSelected =
false;
159 bool bIsPreviewOn =
false;
161 void NotifyLiveChanged()
169 static TSharedRef<SWidget> MakeNumberBox(
const TCHAR* Hint,
float InitialValue, TFunction<
void(
float)> OnChanged)
171 return SNew(SBox).WidthOverride(70.0f)
173 SNew(SEditableTextBox)
174 .HintText(FText::FromString(Hint))
175 .ToolTipText(FText::FromString(Hint))
176 .Text(FText::FromString(FString::SanitizeFloat(InitialValue)))
177 .OnTextCommitted_Lambda([OnChanged](
const FText& NewText, ETextCommit::Type)
179 OnChanged(FCString::Atof(*NewText.ToString()));
186 static TSharedRef<SWidget> MakeColorSwatch(SLightDefaultsRow* Row)
188 TSharedPtr<FLightAssetSummary> InItem = Row->Item;
189 return SNew(SBox).WidthOverride(40.0f).HeightOverride(20.0f)
192 .Color_Lambda([InItem]() {
return InItem->Current.Color; })
193 .ShowBackgroundForAlpha(
false)
194 .OnMouseButtonDown_Lambda([InItem, Row](
const FGeometry&,
const FPointerEvent&) -> FReply
196 FColorPickerArgs PickerArgs;
197 PickerArgs.bUseAlpha =
false;
198 PickerArgs.InitialColor = InItem->Current.Color;
199 PickerArgs.OnColorCommitted = FOnLinearColorValueChanged::CreateLambda(
200 [InItem, Row](FLinearColor NewColor) { InItem->Current.Color = NewColor; Row->NotifyLiveChanged(); });
201 OpenColorPicker(PickerArgs);
202 return FReply::Handled();
217 class SVehicleLightRow :
public STableRow<TSharedPtr<FVehicleLightSummary>>
220 SLATE_BEGIN_ARGS(SVehicleLightRow) {}
223 void Construct(const FArguments& InArgs, const TSharedRef<STableViewBase>& OwnerTable, TSharedPtr<
FVehicleLightSummary> InItem,
224 TFunction<
void(TSharedPtr<
FVehicleLightSummary>)> InOnLiveChanged, TFunction<
void(const FString&,
bool)> InOnTogglePreview)
227 OnLiveChanged = MoveTemp(InOnLiveChanged);
228 OnTogglePreview = MoveTemp(InOnTogglePreview);
230 TSharedRef<SHorizontalBox> RowBox = SNew(SHorizontalBox)
232 + SHorizontalBox::Slot().AutoWidth().Padding(2.0f).VAlign(VAlign_Center)
234 SNew(SBox).WidthOverride(200.0f)
236 SNew(STextBlock).Text(FText::FromString(Item->DisplayName)).ToolTipText(FText::FromString(Item->ClassName))
240 + SHorizontalBox::Slot().AutoWidth().Padding(2.0f).VAlign(VAlign_Center)
242 SNew(SBox).WidthOverride(40.0f)
244 SNew(STextBlock).Text(FText::FromString(FString::FromInt(Item->InstanceCount)))
248 + SHorizontalBox::Slot().AutoWidth().Padding(2.0f)
249 [ MakeNumberBox(TEXT(
"Intensity"), 55.0f, Item->Intensity, [
this](
float V) { Item->Intensity = V; NotifyLiveChanged(); }) ];
253 const bool bPresent = Item->GroupPresent.Contains(GroupName) && Item->GroupPresent[GroupName];
254 const float InitialValue = Item->GroupIntensity.Contains(GroupName) ? Item->GroupIntensity[GroupName] : 0.0f;
255 TSharedRef<SWidget> Field = MakeNumberBox(*GroupName, 55.0f, InitialValue, [
this, GroupName](
float V)
257 Item->GroupIntensity.Add(GroupName, V);
260 Field->SetEnabled(bPresent);
261 RowBox->AddSlot().AutoWidth().Padding(1.0f)[ Field ];
264 RowBox->AddSlot().AutoWidth().Padding(6.0f, 2.0f).VAlign(VAlign_Center)
267 .Style(FAppStyle::Get(),
"ToggleButtonCheckbox")
268 .Padding(FMargin(8.0f, 2.0f))
269 .IsChecked_Lambda([
this]() {
return bIsPreviewOn ? ECheckBoxState::Checked : ECheckBoxState::Unchecked; })
270 .OnCheckStateChanged_Lambda([
this](ECheckBoxState NewState)
272 bIsPreviewOn = (NewState == ECheckBoxState::Checked);
275 OnTogglePreview(Item->ClassName, bIsPreviewOn);
287 SNew(STextBlock).Text(LOCTEXT(
"PreviewVehicleButton",
"Preview"))
291 STableRow<TSharedPtr<FVehicleLightSummary>>::Construct(
292 STableRow<TSharedPtr<FVehicleLightSummary>>::FArguments()
293 .Padding(FMargin(4.0f, 2.0f))
299 TSharedPtr<FVehicleLightSummary> Item;
300 TFunction<void(TSharedPtr<FVehicleLightSummary>)> OnLiveChanged;
301 TFunction<void(
const FString&,
bool)> OnTogglePreview;
302 bool bIsPreviewOn =
false;
304 void NotifyLiveChanged()
312 static TSharedRef<SWidget> MakeNumberBox(
const TCHAR* Hint,
float Width,
float InitialValue, TFunction<
void(
float)> OnChanged)
314 return SNew(SBox).WidthOverride(Width)
316 SNew(SEditableTextBox)
317 .HintText(FText::FromString(Hint))
318 .ToolTipText(FText::FromString(Hint))
319 .Text(FText::FromString(FString::SanitizeFloat(InitialValue)))
320 .OnTextCommitted_Lambda([OnChanged](
const FText& NewText, ETextCommit::Type)
322 OnChanged(FCString::Atof(*NewText.ToString()));
329TSharedRef<SWidget> SLightDefaultsPanel::MakeGroupTab(
ELightType Group,
const FText& Label)
331 return SNew(SCheckBox)
332 .Style(FAppStyle::Get(),
"ToggleButtonCheckbox")
333 .Padding(FMargin(10.0f, 4.0f))
334 .IsChecked_Lambda([
this, Group]()
336 return (!bShowingTrafficLights && !bShowingBuildings && !bShowingVehicles && ActiveFilter == Group) ? ECheckBoxState::Checked : ECheckBoxState::Unchecked;
338 .OnCheckStateChanged_Lambda([
this, Group](ECheckBoxState)
340 bShowingTrafficLights =
false;
341 bShowingBuildings =
false;
342 bShowingVehicles =
false;
343 ActiveFilter = Group;
347 SNew(STextBlock).Text(Label)
351TSharedRef<SWidget> SLightDefaultsPanel::MakeTrafficTab()
353 return SNew(SCheckBox)
354 .Style(FAppStyle::Get(),
"ToggleButtonCheckbox")
355 .Padding(FMargin(10.0f, 4.0f))
356 .IsChecked_Lambda([
this]()
358 return bShowingTrafficLights ? ECheckBoxState::Checked : ECheckBoxState::Unchecked;
360 .OnCheckStateChanged_Lambda([
this](ECheckBoxState)
362 bShowingTrafficLights =
true;
363 bShowingBuildings =
false;
364 bShowingVehicles =
false;
368 SNew(STextBlock).Text(LOCTEXT(
"TabTrafficLight",
"Traffic Lights"))
372TSharedRef<SWidget> SLightDefaultsPanel::MakeBuildingsTab()
374 return SNew(SCheckBox)
375 .Style(FAppStyle::Get(),
"ToggleButtonCheckbox")
376 .Padding(FMargin(10.0f, 4.0f))
377 .IsChecked_Lambda([
this]()
379 return bShowingBuildings ? ECheckBoxState::Checked : ECheckBoxState::Unchecked;
381 .OnCheckStateChanged_Lambda([
this](ECheckBoxState)
383 bShowingBuildings =
true;
384 bShowingTrafficLights =
false;
385 bShowingVehicles =
false;
389 SNew(STextBlock).Text(LOCTEXT(
"TabBuildings",
"Buildings"))
393TSharedRef<SWidget> SLightDefaultsPanel::MakeVehiclesTab()
395 return SNew(SCheckBox)
396 .Style(FAppStyle::Get(),
"ToggleButtonCheckbox")
397 .Padding(FMargin(10.0f, 4.0f))
398 .IsChecked_Lambda([
this]()
400 return bShowingVehicles ? ECheckBoxState::Checked : ECheckBoxState::Unchecked;
402 .OnCheckStateChanged_Lambda([
this](ECheckBoxState)
404 bShowingVehicles =
true;
405 bShowingTrafficLights =
false;
406 bShowingBuildings =
false;
410 SNew(STextBlock).Text(LOCTEXT(
"TabVehicles",
"Vehicles"))
414void SLightDefaultsPanel::Construct(
const FArguments& InArgs)
420 + SVerticalBox::Slot().AutoHeight().Padding(4.0f)
424 + SHorizontalBox::Slot().AutoWidth().Padding(2.0f)
427 .Text(LOCTEXT(
"ScanButton",
"Scan Level"))
428 .OnClicked(
this, &SLightDefaultsPanel::OnScanClicked)
431 + SHorizontalBox::Slot().AutoWidth().Padding(2.0f)
434 .Text(LOCTEXT(
"ReapplyButton",
"Reapply To Level"))
435 .ToolTipText(LOCTEXT(
"ReapplyTooltip",
"Reverts any live, unsaved preview edits back to the last saved catalog on disk."))
436 .OnClicked(
this, &SLightDefaultsPanel::OnReapplyClicked)
439 + SHorizontalBox::Slot().AutoWidth().Padding(2.0f)
442 .Text(LOCTEXT(
"SaveAllButton",
"Save All"))
443 .ToolTipText(LOCTEXT(
"SaveAllTooltip",
"Commits every row's current (already live-previewed) values to Config/Lights/Defaults.json."))
444 .OnClicked(
this, &SLightDefaultsPanel::OnSaveAllClicked)
448 + SVerticalBox::Slot().AutoHeight().Padding(4.0f, 0.0f)
452 + SHorizontalBox::Slot().AutoWidth().Padding(2.0f)
455 + SHorizontalBox::Slot().AutoWidth().Padding(2.0f)
458 + SHorizontalBox::Slot().AutoWidth().Padding(2.0f)
459 [ MakeBuildingsTab() ]
461 + SHorizontalBox::Slot().AutoWidth().Padding(2.0f)
464 + SHorizontalBox::Slot().AutoWidth().Padding(2.0f)
465 [ MakeVehiclesTab() ]
468 + SVerticalBox::Slot().AutoHeight().Padding(6.0f, 4.0f, 4.0f, 0.0f)
471 .Visibility_Lambda([
this]() {
return bShowingVehicles ? EVisibility::Collapsed : EVisibility::Visible; })
473 + SHorizontalBox::Slot().AutoWidth().Padding(2.0f)
474 [ SNew(SBox).WidthOverride(240.0f) [ SNew(STextBlock).Text(LOCTEXT(
"HeaderClass",
"Class")) ] ]
476 + SHorizontalBox::Slot().AutoWidth().Padding(2.0f)
477 [ SNew(SBox).WidthOverride(50.0f) [ SNew(STextBlock).Text(LOCTEXT(
"HeaderCount",
"Count")) ] ]
479 + SHorizontalBox::Slot().AutoWidth().Padding(2.0f)
481 SNew(SBox).WidthOverride(70.0f)
483 SNew(STextBlock).Text_Lambda([
this]() -> FText
485 return bShowingBuildings
486 ? LOCTEXT(
"HeaderPercentLit",
"Percent Lit")
487 : LOCTEXT(
"HeaderIntensity",
"Intensity");
492 + SHorizontalBox::Slot().AutoWidth().Padding(2.0f)
493 [ SNew(SBox).WidthOverride(70.0f) [ SNew(STextBlock).Text(LOCTEXT(
"HeaderEmissive",
"Emissive")) ] ]
495 + SHorizontalBox::Slot().AutoWidth().Padding(2.0f)
496 [ SNew(SBox).WidthOverride(40.0f) [ SNew(STextBlock).Text(LOCTEXT(
"HeaderColor",
"Color")) ] ]
498 + SHorizontalBox::Slot().AutoWidth().Padding(6.0f, 2.0f)
499 [ SNew(STextBlock).Text(LOCTEXT(
"HeaderSelect",
"Select")) ]
502 + SVerticalBox::Slot().FillHeight(1.0f).Padding(4.0f)
504 SAssignNew(RowsListView, SListView<TSharedPtr<FLightAssetSummary>>)
505 .Visibility_Lambda([
this]() {
return bShowingVehicles ? EVisibility::Collapsed : EVisibility::Visible; })
506 .ListItemsSource(&Rows)
507 .SelectionMode(ESelectionMode::None)
508 .OnGenerateRow(
this, &SLightDefaultsPanel::OnGenerateRow)
515 + SVerticalBox::Slot().AutoHeight().Padding(6.0f, 4.0f, 4.0f, 0.0f)
518 .Visibility_Lambda([
this]() {
return bShowingVehicles ? EVisibility::Visible : EVisibility::Collapsed; })
520 + SHorizontalBox::Slot().AutoWidth().Padding(2.0f)
521 [ SNew(SBox).WidthOverride(200.0f) [ SNew(STextBlock).Text(LOCTEXT(
"HeaderVehicleClass",
"Vehicle")) ] ]
523 + SHorizontalBox::Slot().AutoWidth().Padding(2.0f)
524 [ SNew(SBox).WidthOverride(40.0f) [ SNew(STextBlock).Text(LOCTEXT(
"HeaderCount2",
"Count")) ] ]
526 + SHorizontalBox::Slot().AutoWidth().Padding(2.0f)
527 [ SNew(SBox).WidthOverride(55.0f) [ SNew(STextBlock).Text(LOCTEXT(
"HeaderVehicleIntensity",
"Intensity")) ] ]
529 + SHorizontalBox::Slot().AutoWidth().Padding(1.0f)
532 + SHorizontalBox::Slot().AutoWidth().Padding(1.0f)
533 [ SNew(SBox).WidthOverride(55.0f) [ SNew(STextBlock).Text(LOCTEXT(
"HeaderPos",
"Position")).ToolTipText(LOCTEXT(
"HeaderPosTT",
"Position")) ] ]
534 + SHorizontalBox::Slot().AutoWidth().Padding(1.0f)
535 [ SNew(SBox).WidthOverride(55.0f) [ SNew(STextBlock).Text(LOCTEXT(
"HeaderLow",
"Low Beam")).ToolTipText(LOCTEXT(
"HeaderLowTT",
"Low Beam")) ] ]
536 + SHorizontalBox::Slot().AutoWidth().Padding(1.0f)
537 [ SNew(SBox).WidthOverride(55.0f) [ SNew(STextBlock).Text(LOCTEXT(
"HeaderHigh",
"High Beam")).ToolTipText(LOCTEXT(
"HeaderHighTT",
"High Beam")) ] ]
538 + SHorizontalBox::Slot().AutoWidth().Padding(1.0f)
539 [ SNew(SBox).WidthOverride(55.0f) [ SNew(STextBlock).Text(LOCTEXT(
"HeaderFog",
"Fog")).ToolTipText(LOCTEXT(
"HeaderFogTT",
"Fog")) ] ]
540 + SHorizontalBox::Slot().AutoWidth().Padding(1.0f)
541 [ SNew(SBox).WidthOverride(55.0f) [ SNew(STextBlock).Text(LOCTEXT(
"HeaderBrake",
"Brake")).ToolTipText(LOCTEXT(
"HeaderBrakeTT",
"Brake")) ] ]
542 + SHorizontalBox::Slot().AutoWidth().Padding(1.0f)
543 [ SNew(SBox).WidthOverride(55.0f) [ SNew(STextBlock).Text(LOCTEXT(
"HeaderReverse",
"Reverse")).ToolTipText(LOCTEXT(
"HeaderReverseTT",
"Reverse")) ] ]
544 + SHorizontalBox::Slot().AutoWidth().Padding(1.0f)
545 [ SNew(SBox).WidthOverride(55.0f) [ SNew(STextBlock).Text(LOCTEXT(
"HeaderLBlink",
"L Blink")).ToolTipText(LOCTEXT(
"HeaderLBlinkTT",
"Left Blinker")) ] ]
546 + SHorizontalBox::Slot().AutoWidth().Padding(1.0f)
547 [ SNew(SBox).WidthOverride(55.0f) [ SNew(STextBlock).Text(LOCTEXT(
"HeaderRBlink",
"R Blink")).ToolTipText(LOCTEXT(
"HeaderRBlinkTT",
"Right Blinker")) ] ]
548 + SHorizontalBox::Slot().AutoWidth().Padding(1.0f)
549 [ SNew(SBox).WidthOverride(55.0f) [ SNew(STextBlock).Text(LOCTEXT(
"HeaderSpecial1",
"Special1")).ToolTipText(LOCTEXT(
"HeaderSpecial1TT",
"Siren/lightbar")) ] ]
552 + SHorizontalBox::Slot().AutoWidth().Padding(6.0f, 2.0f)
553 [ SNew(STextBlock).Text(LOCTEXT(
"HeaderPreview",
"Preview")) ]
556 + SVerticalBox::Slot().FillHeight(1.0f).Padding(4.0f)
558 SAssignNew(VehicleRowsListView, SListView<TSharedPtr<FVehicleLightSummary>>)
559 .Visibility_Lambda([
this]() {
return bShowingVehicles ? EVisibility::Visible : EVisibility::Collapsed; })
560 .ListItemsSource(&AllVehicleRows)
561 .SelectionMode(ESelectionMode::None)
562 .OnGenerateRow(
this, &SLightDefaultsPanel::OnGenerateVehicleRow)
567FReply SLightDefaultsPanel::OnScanClicked()
569 UWorld* World = GEditor ? GEditor->GetEditorWorldContext().World() :
nullptr;
574 AllRows.Add(MakeShared<FLightAssetSummary>(Summary));
577 AllTrafficRows.Reset();
580 AllTrafficRows.Add(MakeShared<FLightAssetSummary>(Summary));
583 AllBuildingRows.Reset();
586 AllBuildingRows.Add(MakeShared<FLightAssetSummary>(Summary));
589 AllLegacyBuildingRows.Reset();
592 AllLegacyBuildingRows.Add(MakeShared<FLightAssetSummary>(Summary));
595 AllVehicleRows.Reset();
598 AllVehicleRows.Add(MakeShared<FVehicleLightSummary>(Summary));
600 if (VehicleRowsListView.IsValid())
602 VehicleRowsListView->RequestListRefresh();
606 return FReply::Handled();
609void SLightDefaultsPanel::ApplyFilter()
611 if (bShowingVehicles)
619 if (bShowingTrafficLights)
621 Rows = AllTrafficRows;
623 else if (bShowingBuildings)
632 Rows = AllBuildingRows;
633 Rows.Append(AllLegacyBuildingRows);
634 for (
const TSharedPtr<FLightAssetSummary>& Item : AllRows)
636 if (Item->bIsBuildingClass)
644 for (
const TSharedPtr<FLightAssetSummary>& Item : AllRows)
646 if (Item->bIsBuildingClass)
653 const bool bMatchesGroup = (Item->LightGroup == ActiveFilter) ||
662 if (RowsListView.IsValid())
664 RowsListView->RequestListRefresh();
668FReply SLightDefaultsPanel::OnReapplyClicked()
670 UWorld* World = GEditor ? GEditor->GetEditorWorldContext().World() :
nullptr;
676 return FReply::Handled();
679FReply SLightDefaultsPanel::OnSaveAllClicked()
686 for (
const TSharedPtr<FLightAssetSummary>& Item : AllRows)
693 for (
const TSharedPtr<FLightAssetSummary>& Item : AllTrafficRows)
700 for (
const TSharedPtr<FLightAssetSummary>& Item : AllBuildingRows)
707 for (
const TSharedPtr<FLightAssetSummary>& Item : AllLegacyBuildingRows)
714 for (
const TSharedPtr<FVehicleLightSummary>& Item : AllVehicleRows)
721 return FReply::Handled();
724void SLightDefaultsPanel::ApplyRowLive(TSharedPtr<FLightAssetSummary> Item)
730 UWorld* World = GEditor ? GEditor->GetEditorWorldContext().World() :
nullptr;
734void SLightDefaultsPanel::SetClassSelected(
const FString& ClassName,
bool bSelected)
736 UWorld* World = GEditor ? GEditor->GetEditorWorldContext().World() :
nullptr;
740void SLightDefaultsPanel::ApplyTrafficRowLive(TSharedPtr<FLightAssetSummary> Item)
746 UWorld* World = GEditor ? GEditor->GetEditorWorldContext().World() :
nullptr;
750void SLightDefaultsPanel::SetTrafficClassSelected(
const FString& ClassName,
bool bSelected)
752 UWorld* World = GEditor ? GEditor->GetEditorWorldContext().World() :
nullptr;
756void SLightDefaultsPanel::SetTrafficClassPreviewOn(
const FString& ClassName,
bool bOn)
758 UWorld* World = GEditor ? GEditor->GetEditorWorldContext().World() :
nullptr;
762void SLightDefaultsPanel::ApplyBuildingRowLive(TSharedPtr<FLightAssetSummary> Item)
768 UWorld* World = GEditor ? GEditor->GetEditorWorldContext().World() :
nullptr;
772void SLightDefaultsPanel::SetBuildingSelected(
bool bSelected)
774 UWorld* World = GEditor ? GEditor->GetEditorWorldContext().World() :
nullptr;
778void SLightDefaultsPanel::ApplyLegacyBuildingRowLive(TSharedPtr<FLightAssetSummary> Item)
784 UWorld* World = GEditor ? GEditor->GetEditorWorldContext().World() :
nullptr;
788void SLightDefaultsPanel::SetLegacyBuildingSelected(
bool bSelected)
790 UWorld* World = GEditor ? GEditor->GetEditorWorldContext().World() :
nullptr;
794void SLightDefaultsPanel::ApplyVehicleRowLive(TSharedPtr<FVehicleLightSummary> Item)
800 UWorld* World = GEditor ? GEditor->GetEditorWorldContext().World() :
nullptr;
804void SLightDefaultsPanel::ToggleVehiclePreview(
const FString& ClassName,
bool bPreviewOn)
806 UWorld* World = GEditor ? GEditor->GetEditorWorldContext().World() :
nullptr;
823TSharedRef<ITableRow> SLightDefaultsPanel::OnGenerateRow(
824 TSharedPtr<FLightAssetSummary> Item,
825 const TSharedRef<STableViewBase>& OwnerTable)
830 if (bShowingTrafficLights)
832 return SNew(SLightDefaultsRow, OwnerTable, Item,
833 [
this](TSharedPtr<FLightAssetSummary> RowItem) { ApplyTrafficRowLive(RowItem); },
834 [
this](
const FString& ClassName,
bool bSelected) { SetTrafficClassSelected(ClassName, bSelected); },
835 [
this](
const FString& ClassName,
bool bOn) { SetTrafficClassPreviewOn(ClassName, bOn); });
837 if (bShowingBuildings)
844 const bool bIsLegacyRow = Item.IsValid() && Item->ClassName == TEXT(
"LegacyBuildings");
845 const bool bIsBakedRow = Item.IsValid() && Item->ClassName == TEXT(
"ProceduralBuildings");
848 return SNew(SLightDefaultsRow, OwnerTable, Item,
849 [
this](TSharedPtr<FLightAssetSummary> RowItem) { ApplyLegacyBuildingRowLive(RowItem); },
850 [
this](
const FString&,
bool bSelected) { SetLegacyBuildingSelected(bSelected); });
854 return SNew(SLightDefaultsRow, OwnerTable, Item,
855 [
this](TSharedPtr<FLightAssetSummary> RowItem) { ApplyBuildingRowLive(RowItem); },
856 [
this](
const FString&,
bool bSelected) { SetBuildingSelected(bSelected); });
858 return SNew(SLightDefaultsRow, OwnerTable, Item,
859 [
this](TSharedPtr<FLightAssetSummary> RowItem) { ApplyRowLive(RowItem); },
860 [
this](
const FString& ClassName,
bool bSelected) { SetClassSelected(ClassName, bSelected); });
862 return SNew(SLightDefaultsRow, OwnerTable, Item,
863 [
this](TSharedPtr<FLightAssetSummary> RowItem) { ApplyRowLive(RowItem); },
864 [
this](
const FString& ClassName,
bool bSelected) { SetClassSelected(ClassName, bSelected); });
867TSharedRef<ITableRow> SLightDefaultsPanel::OnGenerateVehicleRow(
868 TSharedPtr<FVehicleLightSummary> Item,
869 const TSharedRef<STableViewBase>& OwnerTable)
871 return SNew(SVehicleLightRow, OwnerTable, Item,
872 [
this](TSharedPtr<FVehicleLightSummary> RowItem) { ApplyVehicleRowLive(RowItem); },
873 [
this](
const FString& ClassName,
bool bPreviewOn) { ToggleVehiclePreview(ClassName, bPreviewOn); });
878 const FName LightDefaultsTabId(TEXT(
"CarlaLightDefaultsPanel"));
880 TSharedRef<SDockTab> SpawnLightDefaultsTab(
const FSpawnTabArgs&)
882 return SNew(SDockTab)
883 .TabRole(ETabRole::NomadTab)
885 SNew(SLightDefaultsPanel)
890void RegisterLightDefaultsEditorTab()
892 FGlobalTabmanager::Get()->RegisterNomadTabSpawner(LightDefaultsTabId, FOnSpawnTab::CreateStatic(&SpawnLightDefaultsTab))
893 .SetDisplayName(LOCTEXT(
"LightDefaultsTabTitle",
"Light Defaults"))
894 .SetTooltipText(LOCTEXT(
"LightDefaultsTabTooltip",
"Edit per-class light color/intensity/emissive defaults"))
895 .SetMenuType(ETabSpawnerMenuType::Enabled);
898void UnregisterLightDefaultsEditorTab()
900 if (FSlateApplication::IsInitialized())
902 FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(LightDefaultsTabId);
908 FDelegateHandle MapOpenedHandle;
911void RegisterLightDefaultsMapOpenedHook()
913 MapOpenedHandle = FEditorDelegates::OnMapOpened.AddLambda([](
const FString&,
bool)
915 UWorld* World = GEditor ? GEditor->GetEditorWorldContext().World() : nullptr;
916 if (World ==
nullptr)
920 TWeakObjectPtr<UWorld> WeakWorld(World);
922 World->GetTimerManager().SetTimer(Unused, FTimerDelegate::CreateLambda([WeakWorld]()
924 if (WeakWorld.IsValid())
926 ULightDefaultsJsonUtils::ReapplyLightDefaultsToLevel(WeakWorld.Get());
927 ULightDefaultsJsonUtils::ReapplyTrafficLightDefaultsToLevel(WeakWorld.Get());
928 ULightDefaultsJsonUtils::ReapplyProceduralBuildingsToLevel(WeakWorld.Get());
929 ULightDefaultsJsonUtils::ReapplyLegacyBuildingsToLevel(WeakWorld.Get());
930 ULightDefaultsJsonUtils::ReapplyVehicleLightsToLevel(WeakWorld.Get());
936void UnregisterLightDefaultsMapOpenedHook()
938 FEditorDelegates::OnMapOpened.Remove(MapOpenedHandle);
941#undef LOCTEXT_NAMESPACE
static void ReapplyLegacyBuildingsToLevel(const UObject *WorldContextObject)
static void PreviewVehicleBlinkers(const UObject *WorldContextObject)
static AActor * SpawnVehiclePreview(const UObject *WorldContextObject, const FString &ClassName)
static void SetLegacyBuildingsSelected(const UObject *WorldContextObject, bool bSelected)
static void SetTrafficLightClassPreviewOn(const UObject *WorldContextObject, const FString &ClassName, bool bOn)
static bool SaveClassDefault(const FString &ClassName, const FLightAssetDefault &Default)
static void ApplyLightDefaultToClassLive(const UObject *WorldContextObject, const FString &ClassName, const FLightAssetDefault &Value)
static void ReapplyProceduralBuildingsToLevel(const UObject *WorldContextObject)
static void ApplyProceduralBuildingsEmissiveLive(const UObject *WorldContextObject, float EmissiveIntensity, float PercentLit, const FLinearColor &Color)
static void ApplyTrafficLightDefaultToClassLive(const UObject *WorldContextObject, const FString &ClassName, float EmissiveIntensity)
static void SetTrafficLightClassActorsSelected(const UObject *WorldContextObject, const FString &ClassName, bool bSelected)
static void ReapplyLightDefaultsToLevel(const UObject *WorldContextObject)
static void ReapplyTrafficLightDefaultsToLevel(const UObject *WorldContextObject)
static void ClearVehiclePreview(const UObject *WorldContextObject)
static void ApplyLegacyBuildingsEmissiveLive(const UObject *WorldContextObject, float EmissiveIntensity, float PercentLit, const FLinearColor &Color)
static void ReapplyVehicleLightsToLevel(const UObject *WorldContextObject)
static void SetProceduralBuildingsSelected(const UObject *WorldContextObject, bool bSelected)
static void ApplyVehicleLightsLive(const UObject *WorldContextObject, const FString &ClassName, float Intensity, const TMap< FString, float > &GroupIntensity)
static void SetClassActorsSelected(const UObject *WorldContextObject, const FString &ClassName, bool bSelected)
static bool SaveVehicleLightDefault(const FString &ClassName, float Intensity, const TMap< FString, float > &GroupIntensity)