// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved. #pragma once #include "STimeline.h" #include "Debug/DebugDrawService.h" class SLogFilterList; struct FLogsListItem { FString Name; float StartTimestamp; float EndTimestamp; int32 LogIndex; FLogsListItem(const FString& InName, float InStart, float InEnd, int32 InLogIndex = INDEX_NONE) : Name(InName), StartTimestamp(InStart), EndTimestamp(InEnd), LogIndex(InLogIndex) { } bool operator==(const FLogsListItem& Other) const { return LogIndex == Other.LogIndex; } }; struct FLogEntryItem { FString Category; FLinearColor CategoryColor; ELogVerbosity::Type Verbosity; FString Line; }; namespace ELogsSortMode { enum Type { ByName, ByStartTime, ByEndTime, }; } struct FLogStatusItem { FString ItemText; FString ValueText; TArray< TSharedPtr< FLogStatusItem > > Children; FLogStatusItem(const FString& InItemText) : ItemText(InItemText) {} FLogStatusItem(const FString& InItemText, const FString& InValueText) : ItemText(InItemText), ValueText(InValueText) {} }; /** Main LogVisualizer UI widget */ class SLogVisualizer : public SCompoundWidget { public: static const FName NAME_LogName; static const FName NAME_StartTime; static const FName NAME_EndTime; static const FName NAME_LogTimeSpan; /** Expressed in Hz */ static const int32 FullUpdateFrequency = 2; DECLARE_MULTICAST_DELEGATE_TwoParams(FOnZoomChanged, float, float); SLATE_BEGIN_ARGS(SLogVisualizer) {} SLATE_END_ARGS() void Construct(const FArguments& InArgs, FLogVisualizer* InAnalyzer); virtual ~SLogVisualizer(); virtual void Tick( const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime ) OVERRIDE; // OVERRIDES virtual FReply OnMouseWheel( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) OVERRIDE; virtual FReply OnKeyDown( const FGeometry& MyGeometry, const FKeyboardEvent& InKeyboardEvent) OVERRIDE; // Get delegates const FSlateBrush* GetRecordButtonBrush() const; FString GetStatusText() const; ESlateCheckBoxState::Type GetPauseState() const; EColumnSortMode::Type GetLogsSortMode() const; // Handler delegates FReply OnRecordButtonClicked(); FReply OnLoad(); FReply OnSave(); FReply OnRemove(); void OnPauseChanged(ESlateCheckBoxState::Type NewState); void FilterTextCommitted(const FText& CommentText, ETextCommit::Type CommitInfo); void OnSortByChanged(const FName& ColumnName, EColumnSortMode::Type NewSortMode); // Table delegates TSharedRef LogsListGenerateRow(TSharedPtr InItem, const TSharedRef& OwnerTable); void LogsListSelectionChanged(TSharedPtr SelectedItem, ESelectInfo::Type SelectInfo); TSharedRef LogEntryLinesGenerateRow(TSharedPtr Item, const TSharedRef& OwnerTable); FOnZoomChanged& OnZoomChanged() { return ZoomChangedNotify; } void OnListDoubleClick(TSharedPtr); void DoFullUpdate(); void RequestFullUpdate() { TimeTillNextUpdate = 0; } float GetZoom() const { return MinZoom + ZoomSliderValue * ( MaxZoom - MinZoom ); } float GetScrollbarOffset() const { return ScrollbarOffset; } TSharedPtr GetTimeline() { return Timeline; } void SetCurrentViewedTime(float NewTime, const bool bForce = false); void RequestShowLogEntry(TSharedPtr Item, TSharedPtr LogEntry); void GetVisibleEntries(const TSharedPtr& Log, TArray >& OutEntries); int32 GetCurrentVisibleLogEntryIndex(const TArray >& InVisibleEntries); protected: void ShowLogEntry(TSharedPtr Item, TSharedPtr LogEntry); void SelectionChanged(class AActor* DebuggedActor, bool bIsBeingDebuggedNow); public: /** Pointer to the visualizer object we want to show ui for */ FLogVisualizer* LogVisualizer; /** Current way we are sorting logs */ ELogsSortMode::Type SortBy; float LogsStartTime; float LogsEndTime; float GetCurrentViewedTime() const { return CurrentViewedTime; } protected: float GetMaxScrollOffsetFraction() const { return 1.0f - 1.0f / GetZoom(); } float GetMaxGraphOffset() const { return GetZoom() - 1.0f; } void DrawOnCanvas(UCanvas* Canvas, APlayerController*); void LoadFiles(TArray& OpenFilenames); void SaveSelectedLogs(FString& Filename); private: void UpdateStatusItems(const FVisLogEntry* LogEntry); TSharedRef HandleGenerateLogStatus(TSharedPtr InItem, const TSharedRef& OwnerTable); void OnLogStatusGetChildren(TSharedPtr InItem, TArray< TSharedPtr >& OutItems); /** Construct main menu */ TSharedRef< SWidget > MakeMainMenu(); void FillHelpMenu(FMenuBuilder& MenuBuilder); void OpenSavedSession(FMenuBuilder& MenuBuilder); FString GetLogEntryStatusText() const; void AddLog(int32 Index, const FActorsVisLog* Log); void SelectActor(class AActor* SelectedActor); void CameraActorSelected(class AActor* SelectedActor); void IncrementCurrentLogIndex(int32 IncrementBy); /** Called when a single log is added */ void OnLogAdded(); /** Regenerate logs list based on current filter */ void RebuildFilteredList(); /** Update filtering members from entry widgets */ void UpdateFilterInfo(); // zoom functionality float GetZoomValue() const; void OnSetZoomValue(float NewValue); void OnZoomScrolled(float InScrollOffsetFraction); /** handler for toggling DrawLogEntriesPath option change */ void OnDrawLogEntriesPathChanged(ESlateCheckBoxState::Type NewState); /** retrieves whether DrawLogEntriesPath checkbox should be checked */ ESlateCheckBoxState::Type GetDrawLogEntriesPathState() const; /** handler for toggling IgnoreTrivialLogs option change */ void OnIgnoreTrivialLogs(ESlateCheckBoxState::Type NewState); /** retrieves whether IgnoreTrivialLogs checkbox should be checked */ ESlateCheckBoxState::Type GetIgnoreTrivialLogs() const; /** handler for toggling log visualizer camera in game view */ void OnToggleCamera(ESlateCheckBoxState::Type NewState); /** retrieves whether ToggleCamera toggle button should appear pressed */ ESlateCheckBoxState::Type GetToggleCameraState() const; /** See if a particular log passes the current filter and other display flags */ bool ShouldListLog(const FActorsVisLog& Log); void ShowEntry(const FVisLogEntry* LogEntry); int32 FindIndexInLogsList(const int32 LogIndex) const; void OnLogCategoryFiltersChanged(); UWorld* GetWorld() const; // MEMBERS /** The filter list */ TSharedPtr FilterListPtr; /** Index into LogVisualizer->Logs array for entries you want to show. */ TArray > LogsList; /** filled with current log entry's log lines is a source of LogsLinesWidget */ TArray > LogEntryLines; TArray UsedCategories; FLinearColor GetColorForUsedCategory(int32 Index) const; /** used to filter logs by name */ FString LogNameFilterString; FString LastBrowsePath; /** index of currently viewed log */ int32 LogEntryIndex; /** index of entry withing currently viewed log */ int32 SelectedLogIndex; float TimeTillNextUpdate; /** Zoom slider value */ float ZoomSliderValue; float ScrollbarOffset; float LastBarsOffset; float CurrentViewedTime; float MinZoom; float MaxZoom; FOnZoomChanged ZoomChangedNotify; FDebugDrawDelegate DrawingOnCanvasDelegate; bool bDrawLogEntriesPath; bool bIgnoreTrivialLogs; TWeakObjectPtr CameraController; TArray< TSharedPtr > StatusItems; // WIDGETS /** Main log list widget */ TSharedPtr > > LogsListWidget; TSharedPtr< STreeView< TSharedPtr > > StatusItemsView; TSharedPtr LogNameFilterBox; TSharedPtr StatusTextBlock; TSharedPtr > > LogsLinesWidget; TSharedPtr Timeline; TSharedPtr ScrollBar; TSharedPtr ZoomSlider; };