Files
UnrealEngineUWP/Engine/Source/Developer/LogVisualizer/Private/SVisualLoggerTimelinesContainer.cpp
Matthew Griffin 20be235fa6 Merging //UE4/Release-4.11 to //UE4/Main (Up to 2874930)
#lockdown Nick.Penwarden

==========================
MAJOR FEATURES + CHANGES
==========================

Change 2868448 on 2016/02/16 by Mark.Satterthwaite

	Bring MetalRHI & MetalShaderFormat mostly up to Dev-Platform CL #2867146 to address JIRA UE-26181 and as the first part of addressing JIRA UE-23208. Only CL #2854142 has been omitted for compatibility with the 4.11 branch.
	#jira UE-26181

Change 2868454 on 2016/02/16 by Mark.Satterthwaite

	Shader changes necessary to properly fix Mobile Preview under Mac Metal (JIRA UE-23208) - Mac ES 3.1 doesn't support framebuffer fetch & is in fact a Mobile Emulation shader platform.
	#jira UE-23208

Change 2868650 on 2016/02/16 by Matthew.Griffin

	Allow Developer modules to be pre-compiled when the target is editor.
	#jira UE-26802

Change 2868859 on 2016/02/16 by Nick.Whiting

	Merging StereoPanorama fixes from Main to Release-4.11 (CL 2811839)

	#jira UE-25066

Change 2868927 on 2016/02/16 by Mieszko.Zielinski

	Fixed some regular-use crashes in LogVisualizer #UE4

	#rb Lukasz.Furman
	#jira UE-27003

Change 2868994 on 2016/02/16 by Lina.Halper

	Fix refresh UI issue with remove joint

	#jira : UE-26529
	#rb: Martin.Wilson

Change 2868996 on 2016/02/16 by Lina.Halper

	Fix node stop working when negative value of LODThreshold

	#jira: UE-26828
	#rb:Martin.Wilson

Change 2868998 on 2016/02/16 by Lina.Halper

	Fix with crash when invalid index has entered

	#jira : UE-26715
	#rb : Martin.Wilson

Change 2869003 on 2016/02/16 by Ori.Cohen

	- Fix thread safety issue when cloth child collision or environment collision is used.
	- Fix cloth bounds growing when stale transform data is used.

	#JIRA OR-14990
	#rb James.Golding

Change 2869109 on 2016/02/16 by mason.seay

	Updated test assets for Restitution testing

	#jira UE-24473

Change 2869223 on 2016/02/16 by Taizyd.Korambayil

	#jira UE-19083 Disabled LOD on SkySphere BP

Change 2869558 on 2016/02/16 by Dan.Oconnor

	Conservative fix for crash that occurs when adding a weak object ptr to an array of object ptrs in a blueprint
	#jira UE-25893

Change 2869891 on 2016/02/17 by Thomas.Sarkanen

	Fix crash when re-compiling anim BPs that are dependencies of 'parent' Blueprints

	Force a re-initialzation of nodes when initializing the whole anim instance. The bInitialized flag was intended as a runtime optimization - we assume our function will not change for the lifetime of the UAnimInstance. While parts of the graph will be re-initialized we dont need to re-acquire our UFunction ptrs (etc.) unless the whole instance is getting re-initialized.

	#rb Martin.Wilson
	#jira UE-26642 - Switch Skeletal Mesh node crashes the editor if the blueprint is compiled.

Change 2869956 on 2016/02/17 by Tim.Hobson

	#Jira UE-26550 - Added three new icons for Arrow, Locked, and Unlocked per request from IanS.

Change 2869965 on 2016/02/17 by Gareth.Martin

	Fix check() being hit when loading KiteDemo x1_y1 (and other old foliage maps)
	#jira UE-26930

Change 2870007 on 2016/02/17 by Richard.TalbotWatkin

	Merging from //UE4/Dev-Editor CL 2867609

	Fixed auto-generation of unique object/package names when duplicating, so they generate the same names if they the source object was named the same as its package.
	#jira UE-25769 - Crash when Copy+Pasting numbered umaps in the content browser
	#RB Bob.Tellez

Change 2870072 on 2016/02/17 by Michael.Schoell

	Level Blueprints will no longer preload newly created Blueprints that they reference when they are reloaded.

	#jira UE-23637 - Use of Blueprint delegate in sub-level script causes errors on startup

Change 2870087 on 2016/02/17 by Matthew.Griffin

	Removed Android and IOS from list of platforms to build only for UnrealMatch3, so that they can be cooked and packaged correctly.

Change 2870141 on 2016/02/17 by mason.seay

	Test content for Copy Pose From Mesh

	#jira UE-24473

Change 2870195 on 2016/02/17 by Mieszko.Zielinski

	PR #2052: Added missing Super::BeginPlay() (Contributed by Skylonxe)

	#jira UE-26915

Change 2870325 on 2016/02/17 by Steve.Robb

[CL 2882948 by Matthew Griffin in Main branch]
2016-02-26 05:49:37 -05:00

389 lines
12 KiB
C++

// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
#include "LogVisualizer.h"
#include "SVisualLoggerTimeline.h"
#include "SVisualLoggerReport.h"
#define LOCTEXT_NAMESPACE "STimelinesContainer"
TSharedRef<SWidget> SVisualLoggerTimelinesContainer::GetRightClickMenuContent()
{
FMenuBuilder MenuBuilder(true, NULL);
MenuBuilder.BeginSection("VisualLogReports", LOCTEXT("VisualLogReports", "VisualLog Reports"));
{
MenuBuilder.AddMenuEntry(
LOCTEXT("GenarateReport", "Genarate Report"),
LOCTEXT("GenarateReportTooltip", "Genarate report from Visual Log events."),
FSlateIcon(),
FUIAction(FExecuteAction::CreateSP(this, &SVisualLoggerTimelinesContainer::GenerateReport))
);
}
MenuBuilder.EndSection();
FDisplayMetrics DisplayMetrics;
FSlateApplication::Get().GetDisplayMetrics(DisplayMetrics);
const FVector2D DisplaySize(
DisplayMetrics.PrimaryDisplayWorkAreaRect.Right - DisplayMetrics.PrimaryDisplayWorkAreaRect.Left,
DisplayMetrics.PrimaryDisplayWorkAreaRect.Bottom - DisplayMetrics.PrimaryDisplayWorkAreaRect.Top);
return
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.MaxHeight(DisplaySize.Y * 0.5)
[
MenuBuilder.MakeWidget()
];
}
void SVisualLoggerTimelinesContainer::SetSelectionState(TSharedPtr<SLogVisualizerTimeline> AffectedNode, bool bSelect, bool bDeselectOtherNodes)
{
const FName RowName = AffectedNode->GetName();
const bool bIsSelected = FVisualLoggerDatabase::Get().IsRowSelected(RowName);
if (bSelect && (!bIsSelected || bDeselectOtherNodes))
{
FVisualLoggerDatabase::Get().SelectRow(RowName, bDeselectOtherNodes);
}
else if (!bSelect && bIsSelected && AffectedNode.IsValid())
{
FVisualLoggerDatabase::Get().DeselectRow(RowName);
}
}
void SVisualLoggerTimelinesContainer::OnObjectSelectionChanged(const TArray<FName>& RowNames)
{
CachedSelectedTimelines.Reset();
for (TSharedPtr<SLogVisualizerTimeline>& Timeline : TimelineItems)
{
if (RowNames.Find(Timeline->GetName()) != INDEX_NONE)
{
CachedSelectedTimelines.Add(Timeline);
}
}
if (CachedSelectedTimelines.Num() >= 1)
{
FSlateApplication::Get().SetKeyboardFocus(SharedThis(CachedSelectedTimelines[CachedSelectedTimelines.Num()-1].Get()), EFocusCause::Navigation);
}
}
bool SVisualLoggerTimelinesContainer::IsNodeSelected(TSharedPtr<SLogVisualizerTimeline> Node) const
{
return FVisualLoggerDatabase::Get().IsRowSelected(Node->GetName());// SelectedNodes.Contains(Node);
}
void SVisualLoggerTimelinesContainer::ChangeSelection(TSharedPtr<SLogVisualizerTimeline> InTimeline, const FPointerEvent& MouseEvent)
{
if (MouseEvent.IsLeftShiftDown() == false)
{
if (MouseEvent.IsLeftControlDown())
{
SetSelectionState(InTimeline, !InTimeline->IsSelected(), false);
}
else
{
SetSelectionState(InTimeline, true, true);
}
}
else
{
if (CachedSelectedTimelines.Num() == 0 && TimelineItems.Num())
{
SetSelectionState(TimelineItems[0], true, true);
}
TSharedPtr<SLogVisualizerTimeline> LastSelected = CachedSelectedTimelines.Num() ? CachedSelectedTimelines[CachedSelectedTimelines.Num() - 1] : nullptr;
if (LastSelected.IsValid())
{
bool bStartedSelection = false;
for (TSharedPtr<SLogVisualizerTimeline>& TimelineItem : TimelineItems)
{
if (TimelineItem == LastSelected || InTimeline == TimelineItem)
{
if (!bStartedSelection)
{
bStartedSelection = true;
}
else
{
bStartedSelection = false;
break;
}
}
if (bStartedSelection)
{
SetSelectionState(TimelineItem, true, false);
}
}
}
SetSelectionState(InTimeline, true, false);
}
}
FReply SVisualLoggerTimelinesContainer::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
if (MouseEvent.GetEffectingButton() != EKeys::LeftMouseButton)
{
return TimeSliderController->OnMouseButtonDown(*this, MyGeometry, MouseEvent);
}
return FReply::Unhandled();
}
FReply SVisualLoggerTimelinesContainer::OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
if (MouseEvent.GetEffectingButton() != EKeys::LeftMouseButton)
{
return TimeSliderController->OnMouseButtonUp(*this, MyGeometry, MouseEvent);
}
return FReply::Unhandled();
}
FReply SVisualLoggerTimelinesContainer::OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
if (MouseEvent.GetEffectingButton() != EKeys::LeftMouseButton)
{
return TimeSliderController->OnMouseMove(*this, MyGeometry, MouseEvent);
}
return FReply::Unhandled();
}
FReply SVisualLoggerTimelinesContainer::OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
if (MouseEvent.IsLeftControlDown() || MouseEvent.IsLeftShiftDown())
{
return TimeSliderController->OnMouseWheel(*this, MyGeometry, MouseEvent);
}
return FReply::Unhandled();
}
FReply SVisualLoggerTimelinesContainer::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent)
{
if (InKeyEvent.GetKey() == EKeys::A && InKeyEvent.IsLeftControlDown())
{
for (TSharedPtr<SLogVisualizerTimeline>& Timeline : TimelineItems)
{
SetSelectionState(Timeline, true, false);
}
return FReply::Handled();
}
else if (InKeyEvent.GetKey() == EKeys::Platform_Delete && CachedSelectedTimelines.Num() > 0)
{
TWeakPtr<SLogVisualizerTimeline> NotSelectedOne;
for (TSharedPtr<SLogVisualizerTimeline>& CurrentNode : CachedSelectedTimelines)
{
TSharedPtr<SLogVisualizerTimeline> LastSelected = CachedSelectedTimelines[CachedSelectedTimelines.Num() - 1];
bool bFoundSelectedOne = false;
for (TSharedPtr<SLogVisualizerTimeline>& Timeline : TimelineItems)
{
if (IsNodeSelected(Timeline) == false)
{
NotSelectedOne = Timeline;
}
if (LastSelected == Timeline)
{
if (bFoundSelectedOne && NotSelectedOne.IsValid())
{
break;
}
bFoundSelectedOne = true;
}
}
FVisualLoggerDatabase::Get().RemoveRow(CurrentNode->GetName());
TimelineItems.Remove(CurrentNode);
ContainingBorder->RemoveSlot(CurrentNode.ToSharedRef());
}
if (NotSelectedOne.IsValid())
{
SetSelectionState(NotSelectedOne.Pin(), true, true);
}
return FReply::Handled();
}
else if (InKeyEvent.GetKey() == EKeys::Up || InKeyEvent.GetKey() == EKeys::Down)
{
TSharedPtr<SLogVisualizerTimeline> PreviousTimeline;
TSharedPtr<SLogVisualizerTimeline> LastSelected = CachedSelectedTimelines[CachedSelectedTimelines.Num() - 1];
for (int32 Index = 0; Index < TimelineItems.Num(); ++Index)
{
auto& CurrentItem = TimelineItems[Index];
if (LastSelected == CurrentItem)
{
if (InKeyEvent.GetKey() == EKeys::Up && PreviousTimeline.IsValid())
{
SetSelectionState(PreviousTimeline, true, true);
}
else if (InKeyEvent.GetKey() == EKeys::Down)
{
// let's find next visible time line
if (TimelineItems.IsValidIndex(Index + 1))
{
for (int32 i = Index + 1; i < TimelineItems.Num(); ++i)
{
if (TimelineItems[i]->GetVisibility() == EVisibility::Visible)
{
SetSelectionState(TimelineItems[i], true, true);
break;
}
}
}
}
break;
}
if (CurrentItem->GetVisibility() == EVisibility::Visible)
{
PreviousTimeline = CurrentItem;
}
}
return FReply::Handled();
}
return FReply::Unhandled();
}
void SVisualLoggerTimelinesContainer::ResetData()
{
for (TSharedPtr<SLogVisualizerTimeline>& Timeline : TimelineItems)
{
ContainingBorder->RemoveSlot(Timeline.ToSharedRef());
Timeline.Reset();
}
TimelineItems.Reset();
for (auto& CurrentItem : CachedSelectedTimelines)
{
CurrentItem.Reset();
}
CachedSelectedTimelines.Reset();
CachedMinTime = FLT_MAX;
CachedMaxTime = 0;
TimeSliderController->SetClampRange(0, 5);
TimeSliderController->SetTimeRange(0, 5);
}
void SVisualLoggerTimelinesContainer::Construct(const FArguments& InArgs, TSharedRef<SVisualLoggerView> InVisualLoggerView, TSharedRef<FVisualLoggerTimeSliderController> InTimeSliderController)
{
TimeSliderController = InTimeSliderController;
VisualLoggerView = InVisualLoggerView;
ChildSlot
[
SNew(SBorder)
.Padding(0)
.VAlign(VAlign_Top)
.BorderImage(FLogVisualizerStyle::Get().GetBrush("ToolPanel.GroupBorder"))
[
SAssignNew(ContainingBorder, SVerticalBox)
]
];
CachedMinTime = FLT_MAX;
CachedMaxTime = 0;
FVisualLoggerDatabase::Get().GetEvents().OnNewRow.AddRaw(this, &SVisualLoggerTimelinesContainer::OnNewRowHandler);
FVisualLoggerDatabase::Get().GetEvents().OnNewItem.AddRaw(this, &SVisualLoggerTimelinesContainer::OnNewItemHandler);
FVisualLoggerDatabase::Get().GetEvents().OnRowSelectionChanged.AddRaw(this, &SVisualLoggerTimelinesContainer::OnObjectSelectionChanged);
FVisualLoggerDatabase::Get().GetEvents().OnRowChangedVisibility.AddRaw(this, &SVisualLoggerTimelinesContainer::OnRowChangedVisibility);
}
SVisualLoggerTimelinesContainer::~SVisualLoggerTimelinesContainer()
{
FVisualLoggerDatabase::Get().GetEvents().OnNewRow.RemoveAll(this);
FVisualLoggerDatabase::Get().GetEvents().OnNewItem.RemoveAll(this);
FVisualLoggerDatabase::Get().GetEvents().OnRowSelectionChanged.RemoveAll(this);
FVisualLoggerDatabase::Get().GetEvents().OnRowChangedVisibility.RemoveAll(this);
}
void SVisualLoggerTimelinesContainer::OnNewRowHandler(const FVisualLoggerDBRow& DBRow)
{
TSharedPtr<SLogVisualizerTimeline> NewTimeline;
ContainingBorder->AddSlot()
[
SAssignNew(NewTimeline, SLogVisualizerTimeline, TimeSliderController, SharedThis(this), DBRow.GetOwnerName(), DBRow.GetOwnerClassName())
.OnGetMenuContent(this, &SVisualLoggerTimelinesContainer::GetRightClickMenuContent)
];
TimelineItems.Add(NewTimeline.ToSharedRef());
// make sure the new entry doesn't show if it doesn't match CurrentSearchText
NewTimeline->OnSearchChanged(CurrentSearchText);
}
void SVisualLoggerTimelinesContainer::OnNewItemHandler(const FVisualLoggerDBRow& BDRow, int32 ItemIndex)
{
const FVisualLogDevice::FVisualLogEntryItem& Entry = BDRow.GetItems()[ItemIndex];
CachedMinTime = CachedMinTime < Entry.Entry.TimeStamp ? CachedMinTime : Entry.Entry.TimeStamp;
CachedMaxTime = CachedMaxTime > Entry.Entry.TimeStamp ? CachedMaxTime : Entry.Entry.TimeStamp;
TRange<float> LocalViewRange = TimeSliderController->GetTimeSliderArgs().ViewRange.Get();
TRange<float> ClampRange = TimeSliderController->GetTimeSliderArgs().ClampRange.Get();
float ZoomLevel = LocalViewRange.Size<float>() / ClampRange.Size<float>();
TimeSliderController->GetTimeSliderArgs().ClampRange = TRange<float>(CachedMinTime, CachedMaxTime + 0.1f);
//if ( FMath::Abs(ZoomLevel - 1) <= SMALL_NUMBER)
//{
TimeSliderController->GetTimeSliderArgs().ViewRange = TimeSliderController->GetTimeSliderArgs().ClampRange;
//}
}
void SVisualLoggerTimelinesContainer::OnSearchChanged(const FText& Filter)
{
CurrentSearchText = Filter;
for (TSharedPtr<SLogVisualizerTimeline>& Timeline : TimelineItems)
{
Timeline->OnSearchChanged(Filter);
}
}
void SVisualLoggerTimelinesContainer::OnFiltersChanged()
{
for (TSharedPtr<SLogVisualizerTimeline>& Timeline : TimelineItems)
{
Timeline->OnFiltersChanged();
}
}
void SVisualLoggerTimelinesContainer::OnFiltersSearchChanged(const FText& Filter)
{
for (TSharedPtr<SLogVisualizerTimeline>& Timeline : TimelineItems)
{
Timeline->OnFiltersSearchChanged(Filter);
}
}
void SVisualLoggerTimelinesContainer::GenerateReport()
{
TSharedRef<SWindow> NewWindow = SNew(SWindow)
.ClientSize(FVector2D(720, 768))
.Title(NSLOCTEXT("LogVisualizerReport", "WindowTitle", "Log Visualizer Report"))
[
SNew(SVisualLoggerReport, CachedSelectedTimelines, VisualLoggerView)
];
FSlateApplication::Get().AddWindow(NewWindow);
}
void SVisualLoggerTimelinesContainer::OnRowChangedVisibility(const FName& InName)
{
for (TSharedPtr<SLogVisualizerTimeline>& Timeline : TimelineItems)
{
if (InName == Timeline->GetName())
{
Timeline->SetVisibility(FVisualLoggerDatabase::Get().IsRowVisible(InName) ? EVisibility::Visible : EVisibility::Collapsed);
break;
}
}
}
#undef LOCTEXT_NAMESPACE