| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 2f4dfd4 commit c85375c
10 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,162 @@ | |||
| 1 | + // Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. | ||
| 2 | + | ||
| 3 | + #include "PythonConsolePrivatePCH.h" | ||
| 4 | + #include "SPythonConsole.h" | ||
| 5 | + #include "SPythonLog.h" | ||
| 6 | + #include "Editor/WorkspaceMenuStructure/Public/WorkspaceMenuStructureModule.h" | ||
| 7 | + #include "SDockTab.h" | ||
| 8 | + | ||
| 9 | + IMPLEMENT_MODULE( FPythonConsoleModule, PythonLog ); | ||
| 10 | + | ||
| 11 | + namespace PythonConsoleModule | ||
| 12 | + { | ||
| 13 | + static const FName PythonLogTabName = FName(TEXT("PythonLog")); | ||
| 14 | + } | ||
| 15 | + | ||
| 16 | + /** This class is to capture all log output even if the log window is closed */ | ||
| 17 | + class FPythonLogHistory : public FOutputDevice | ||
| 18 | + { | ||
| 19 | + public: | ||
| 20 | + | ||
| 21 | + FPythonLogHistory() | ||
| 22 | + { | ||
| 23 | + GLog->AddOutputDevice(this); | ||
| 24 | + GLog->SerializeBacklog(this); | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + ~FPythonLogHistory() | ||
| 28 | + { | ||
| 29 | + // At shutdown, GLog may already be null | ||
| 30 | + if( GLog != NULL ) | ||
| 31 | + { | ||
| 32 | + GLog->RemoveOutputDevice(this); | ||
| 33 | + } | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + /** Gets all captured messages */ | ||
| 37 | + const TArray< TSharedPtr<FLogMessage> >& GetMessages() const | ||
| 38 | + { | ||
| 39 | + return Messages; | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + protected: | ||
| 43 | + | ||
| 44 | + virtual void Serialize( const TCHAR* V, ELogVerbosity::Type Verbosity, const class FName& Category ) override | ||
| 45 | + { | ||
| 46 | + // Capture all incoming messages and store them in history | ||
| 47 | + SPythonLog::CreateLogMessages(V, Verbosity, Category, Messages); | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + private: | ||
| 51 | + | ||
| 52 | + /** All log messsges since this module has been started */ | ||
| 53 | + TArray< TSharedPtr<FLogMessage> > Messages; | ||
| 54 | + }; | ||
| 55 | + | ||
| 56 | + /** Our global output log app spawner */ | ||
| 57 | + static TSharedPtr<FPythonLogHistory> PythonLogHistory; | ||
| 58 | + | ||
| 59 | + TSharedRef<SDockTab> SpawnPythonLog( const FSpawnTabArgs& Args ) | ||
| 60 | + { | ||
| 61 | + return SNew(SDockTab) | ||
| 62 | + .Icon(FEditorStyle::GetBrush("Log.TabIcon")) | ||
| 63 | + .TabRole( ETabRole::NomadTab ) | ||
| 64 | + .Label( NSLOCTEXT("PythonConsole", "TabTitle", "Python Console") ) | ||
| 65 | + [ | ||
| 66 | + SNew(SPythonLog).Messages( PythonLogHistory->GetMessages() ) | ||
| 67 | + ]; | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + void FPythonConsoleModule::StartupModule() | ||
| 71 | + { | ||
| 72 | + FGlobalTabmanager::Get()->RegisterNomadTabSpawner(PythonConsoleModule::PythonLogTabName, FOnSpawnTab::CreateStatic( &SpawnPythonLog ) ) | ||
| 73 | + .SetDisplayName(NSLOCTEXT("UnrealEditor", "PythonLogTab", "Python Console")) | ||
| 74 | + .SetTooltipText(NSLOCTEXT("UnrealEditor", "PythonLogTooltipText", "Open the Python Console tab.")) | ||
| 75 | + .SetGroup( WorkspaceMenu::GetMenuStructure().GetDeveloperToolsLogCategory() ) | ||
| 76 | + .SetIcon( FSlateIcon(FEditorStyle::GetStyleSetName(), "Log.TabIcon") ); | ||
| 77 | + | ||
| 78 | + | ||
| 79 | + PythonLogHistory = MakeShareable(new FPythonLogHistory); | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + void FPythonConsoleModule::ShutdownModule() | ||
| 83 | + { | ||
| 84 | + if (FSlateApplication::IsInitialized()) | ||
| 85 | + { | ||
| 86 | + FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(PythonConsoleModule::PythonLogTabName); | ||
| 87 | + } | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + TSharedRef< SWidget > FPythonConsoleModule::MakeConsoleInputBox( TSharedPtr< SEditableTextBox >& OutExposedEditableTextBox ) const | ||
| 91 | + { | ||
| 92 | + TSharedRef< SPythonConsoleInputBox > NewConsoleInputBox = SNew( SPythonConsoleInputBox ); | ||
| 93 | + OutExposedEditableTextBox = NewConsoleInputBox->GetEditableTextBox(); | ||
| 94 | + return NewConsoleInputBox; | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + | ||
| 98 | + void FPythonConsoleModule::TogglePythonConsoleForWindow( const TSharedRef< SWindow >& Window, const EPythonConsoleStyle::Type InStyle, const FPythonConsoleDelegates& PythonConsoleDelegates ) | ||
| 99 | + { | ||
| 100 | + bool bShouldOpen = true; | ||
| 101 | + // Close an existing console box, if there is one | ||
| 102 | + TSharedPtr< SWidget > PinnedPythonConsole( PythonConsole.Pin() ); | ||
| 103 | + if( PinnedPythonConsole.IsValid() ) | ||
| 104 | + { | ||
| 105 | + // If the console is already open close it unless it is in a different window. In that case reopen it on that window | ||
| 106 | + bShouldOpen = false; | ||
| 107 | + TSharedPtr< SWindow > WindowForExistingConsole = FSlateApplication::Get().FindWidgetWindow(PinnedPythonConsole.ToSharedRef()); | ||
| 108 | + if (WindowForExistingConsole.IsValid()) | ||
| 109 | + { | ||
| 110 | + WindowForExistingConsole->RemoveOverlaySlot(PinnedPythonConsole.ToSharedRef()); | ||
| 111 | + PythonConsole.Reset(); | ||
| 112 | + } | ||
| 113 | + | ||
| 114 | + if( WindowForExistingConsole != Window ) | ||
| 115 | + { | ||
| 116 | + // Console is being opened on another window | ||
| 117 | + bShouldOpen = true; | ||
| 118 | + } | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + TSharedPtr<SDockTab> ActiveTab = FGlobalTabmanager::Get()->GetActiveTab(); | ||
| 122 | + if (ActiveTab.IsValid() && ActiveTab->GetLayoutIdentifier() == FTabId(PythonConsoleModule::PythonLogTabName)) | ||
| 123 | + { | ||
| 124 | + FGlobalTabmanager::Get()->DrawAttention(ActiveTab.ToSharedRef()); | ||
| 125 | + bShouldOpen = false; | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | + if( bShouldOpen ) | ||
| 129 | + { | ||
| 130 | + const EPythonConsoleStyle::Type PythonConsoleStyle = InStyle; | ||
| 131 | + TSharedRef< SPythonConsole > PythonConsoleRef = SNew( SPythonConsole, PythonConsoleStyle, this, &PythonConsoleDelegates ); | ||
| 132 | + PythonConsole = PythonConsoleRef; | ||
| 133 | + | ||
| 134 | + const int32 MaximumZOrder = MAX_int32; | ||
| 135 | + Window->AddOverlaySlot( MaximumZOrder ) | ||
| 136 | + .VAlign(VAlign_Bottom) | ||
| 137 | + .HAlign(HAlign_Center) | ||
| 138 | + .Padding( 10.0f ) | ||
| 139 | + [ | ||
| 140 | + PythonConsoleRef | ||
| 141 | + ]; | ||
| 142 | + | ||
| 143 | + // Force keyboard focus | ||
| 144 | + PythonConsoleRef->SetFocusToEditableText(); | ||
| 145 | + } | ||
| 146 | + } | ||
| 147 | + | ||
| 148 | + | ||
| 149 | + void FPythonConsoleModule::ClosePythonConsole() | ||
| 150 | + { | ||
| 151 | + TSharedPtr< SWidget > PinnedPythonConsole( PythonConsole.Pin() ); | ||
| 152 | + | ||
| 153 | + if( PinnedPythonConsole.IsValid() ) | ||
| 154 | + { | ||
| 155 | + TSharedPtr< SWindow > WindowForExistingConsole = FSlateApplication::Get().FindWidgetWindow(PinnedPythonConsole.ToSharedRef()); | ||
| 156 | + if (WindowForExistingConsole.IsValid()) | ||
| 157 | + { | ||
| 158 | + WindowForExistingConsole->RemoveOverlaySlot( PinnedPythonConsole.ToSharedRef() ); | ||
| 159 | + PythonConsole.Reset(); | ||
| 160 | + } | ||
| 161 | + } | ||
| 162 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,13 @@ | |||
| 1 | + // Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. | ||
| 2 | + | ||
| 3 | + #pragma once | ||
| 4 | + | ||
| 5 | + #include "UnrealEd.h" | ||
| 6 | + #include "PythonConsoleModule.h" | ||
| 7 | + #include "SlateBasics.h" | ||
| 8 | + | ||
| 9 | + #if UNREAL_ENGINE_PYTHON_ON_MAC | ||
| 10 | + #include <python3.5m/Python.h> | ||
| 11 | + #else | ||
| 12 | + #include <include/Python.h> | ||
| 13 | + #endif | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,136 @@ | |||
| 1 | + // Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. | ||
| 2 | + | ||
| 3 | + #include "PythonConsolePrivatePCH.h" | ||
| 4 | + #include "PythonConsoleModule.h" | ||
| 5 | + #include "SPythonConsole.h" | ||
| 6 | + #include "SPythonLog.h" | ||
| 7 | + | ||
| 8 | + namespace PythonConsoleDefs | ||
| 9 | + { | ||
| 10 | + // How many seconds to animate when console is summoned | ||
| 11 | + static const float IntroAnimationDuration = 0.25f; | ||
| 12 | + } | ||
| 13 | + | ||
| 14 | + BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION | ||
| 15 | + | ||
| 16 | + void SPythonConsole::Construct( const FArguments& InArgs, const EPythonConsoleStyle::Type InStyle, FPythonConsoleModule* PythonConsoleModule, const FPythonConsoleDelegates* PythonConsoleDelegates ) | ||
| 17 | + { | ||
| 18 | + CurrentStyle = InStyle; | ||
| 19 | + | ||
| 20 | + TSharedPtr<SPythonConsoleInputBox> ConsoleInputBox; | ||
| 21 | + | ||
| 22 | + check( PythonConsoleModule != NULL ); | ||
| 23 | + ChildSlot | ||
| 24 | + [ | ||
| 25 | + SNew( SVerticalBox ) | ||
| 26 | + +SVerticalBox::Slot() | ||
| 27 | + .AutoHeight() | ||
| 28 | + [ | ||
| 29 | + SNew( SVerticalBox ) | ||
| 30 | + .Visibility( this, &SPythonConsole::MakeVisibleIfLogIsShown ) | ||
| 31 | + | ||
| 32 | + +SVerticalBox::Slot() | ||
| 33 | + .AutoHeight() | ||
| 34 | + .Padding( 10.0f ) | ||
| 35 | + [ | ||
| 36 | + SNew(SBox) | ||
| 37 | + .HeightOverride( 200.0f ) | ||
| 38 | + [ | ||
| 39 | + SNew( SBorder ) | ||
| 40 | + .BorderImage( FEditorStyle::GetBrush( "ToolPanel.GroupBorder" ) ) | ||
| 41 | + .ColorAndOpacity( this, &SPythonConsole::GetAnimatedColorAndOpacity ) | ||
| 42 | + .BorderBackgroundColor( this, &SPythonConsole::GetAnimatedSlateColor ) | ||
| 43 | + [ | ||
| 44 | + SNew( SSpacer ) | ||
| 45 | + ] | ||
| 46 | + ] | ||
| 47 | + ] | ||
| 48 | + ] | ||
| 49 | + | ||
| 50 | + +SVerticalBox::Slot() | ||
| 51 | + .AutoHeight() | ||
| 52 | + .Padding( 10.0f ) | ||
| 53 | + [ | ||
| 54 | + SNew(SBox) | ||
| 55 | + .HeightOverride( 26.0f ) | ||
| 56 | + .HAlign( HAlign_Left ) | ||
| 57 | + [ | ||
| 58 | + SNew( SBorder ) | ||
| 59 | + .Padding( FMargin(2) ) | ||
| 60 | + .BorderImage( FEditorStyle::GetBrush( "PythonConsole.Background" ) ) | ||
| 61 | + .ColorAndOpacity( this, &SPythonConsole::GetAnimatedColorAndOpacity ) | ||
| 62 | + .BorderBackgroundColor( this, &SPythonConsole::GetAnimatedSlateColor ) | ||
| 63 | + [ | ||
| 64 | + SNew(SHorizontalBox) | ||
| 65 | + + SHorizontalBox::Slot() | ||
| 66 | + .AutoWidth() | ||
| 67 | + .Padding(3.0f) | ||
| 68 | + .VAlign(VAlign_Center) | ||
| 69 | + [ | ||
| 70 | + SNew(STextBlock) | ||
| 71 | + .Text(NSLOCTEXT("Console", "ConsoleLabel", "Console")) | ||
| 72 | + | ||
| 73 | + ] | ||
| 74 | + + SHorizontalBox::Slot() | ||
| 75 | + .Padding(5.0f, 2.0f) | ||
| 76 | + .VAlign(VAlign_Center) | ||
| 77 | + .MaxWidth(400.0f) | ||
| 78 | + [ | ||
| 79 | + SAssignNew(ConsoleInputBox, SPythonConsoleInputBox) | ||
| 80 | + .OnConsoleCommandExecuted(PythonConsoleDelegates->OnConsoleCommandExecuted) | ||
| 81 | + ] | ||
| 82 | + ] | ||
| 83 | + ] | ||
| 84 | + ] | ||
| 85 | + ]; | ||
| 86 | + | ||
| 87 | + EditableTextBox = ConsoleInputBox->GetEditableTextBox(); | ||
| 88 | + | ||
| 89 | + // Kick off intro animation | ||
| 90 | + AnimCurveSequence = FCurveSequence(); | ||
| 91 | + AnimCurve = AnimCurveSequence.AddCurve( 0.0f, PythonConsoleDefs::IntroAnimationDuration, ECurveEaseFunction::QuadOut ); | ||
| 92 | + FlashCurve = AnimCurveSequence.AddCurve( PythonConsoleDefs::IntroAnimationDuration, .15f, ECurveEaseFunction::QuadInOut ); | ||
| 93 | + | ||
| 94 | + AnimCurveSequence.Play(this->AsShared()); | ||
| 95 | + } | ||
| 96 | + END_SLATE_FUNCTION_BUILD_OPTIMIZATION | ||
| 97 | + | ||
| 98 | + SPythonConsole::SPythonConsole() | ||
| 99 | + : CurrentStyle( EPythonConsoleStyle::Compact ) | ||
| 100 | + { | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + | ||
| 104 | + void SPythonConsole::SetFocusToEditableText() | ||
| 105 | + { | ||
| 106 | + FSlateApplication::Get().SetKeyboardFocus( EditableTextBox.ToSharedRef(), EFocusCause::SetDirectly ); | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + EVisibility SPythonConsole::MakeVisibleIfLogIsShown() const | ||
| 110 | + { | ||
| 111 | + return CurrentStyle == EPythonConsoleStyle::WithLog ? EVisibility::Visible : EVisibility::Collapsed; | ||
| 112 | + } | ||
| 113 | + | ||
| 114 | + | ||
| 115 | + FLinearColor SPythonConsole::GetAnimatedColorAndOpacity() const | ||
| 116 | + { | ||
| 117 | + return FLinearColor( 1.0f, 1.0f, 1.0f, AnimCurve.GetLerp() ); | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | + | ||
| 121 | + FSlateColor SPythonConsole::GetAnimatedSlateColor() const | ||
| 122 | + { | ||
| 123 | + return FSlateColor( GetAnimatedColorAndOpacity() ); | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + FSlateColor SPythonConsole::GetFlashColor() const | ||
| 127 | + { | ||
| 128 | + float FlashAlpha = 1.0f - FlashCurve.GetLerp(); | ||
| 129 | + | ||
| 130 | + if (FlashAlpha == 1.0f) | ||
| 131 | + { | ||
| 132 | + FlashAlpha = 0.0f; | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | + return FLinearColor(1,1,1,FlashAlpha); | ||
| 136 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,53 @@ | |||
| 1 | + // Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. | ||
| 2 | + | ||
| 3 | + #pragma once | ||
| 4 | + | ||
| 5 | + | ||
| 6 | + /** | ||
| 7 | + * Debug console widget, designed to be summoned on top of a viewport or window | ||
| 8 | + */ | ||
| 9 | + class SPythonConsole : public SCompoundWidget | ||
| 10 | + { | ||
| 11 | + public: | ||
| 12 | + | ||
| 13 | + SLATE_BEGIN_ARGS( SPythonConsole ) | ||
| 14 | + { | ||
| 15 | + } | ||
| 16 | + | ||
| 17 | + SLATE_END_ARGS() | ||
| 18 | + | ||
| 19 | + /** Constructs this widget */ | ||
| 20 | + void Construct( const FArguments& InArgs, const EPythonConsoleStyle::Type InStyle, FPythonConsoleModule* PythonConsoleModule, const FPythonConsoleDelegates* PythonConsoleDelegates ); | ||
| 21 | + | ||
| 22 | + /** Call to set focus to this debug console's editable text box */ | ||
| 23 | + void SetFocusToEditableText(); | ||
| 24 | + | ||
| 25 | + /** Default constructor */ | ||
| 26 | + SPythonConsole(); | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + protected: | ||
| 30 | + /** Returns EVisibility::Visible if style has log being shown, otherwise VIS_COLLAPSED */ | ||
| 31 | + EVisibility MakeVisibleIfLogIsShown() const; | ||
| 32 | + | ||
| 33 | + /** Returns a color and opacity value to use based on any current animation */ | ||
| 34 | + FLinearColor GetAnimatedColorAndOpacity() const; | ||
| 35 | + | ||
| 36 | + /** Returns a Slate color based on any current animation (same color as GetAnimatedColorAndOpacity) */ | ||
| 37 | + FSlateColor GetAnimatedSlateColor() const; | ||
| 38 | + | ||
| 39 | + FSlateColor GetFlashColor() const; | ||
| 40 | + private: | ||
| 41 | + | ||
| 42 | + /** Editable text box for this debug console's input line */ | ||
| 43 | + TSharedPtr< SEditableTextBox > EditableTextBox; | ||
| 44 | + | ||
| 45 | + /** Current style of the debug console. Can be changed on the fly. */ | ||
| 46 | + EPythonConsoleStyle::Type CurrentStyle; | ||
| 47 | + | ||
| 48 | + /** Intro/outro animation curve */ | ||
| 49 | + FCurveSequence AnimCurveSequence; | ||
| 50 | + FCurveHandle AnimCurve; | ||
| 51 | + FCurveHandle FlashCurve; | ||
| 52 | + }; | ||
| 53 | + | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments