Files
UnrealEngineUWP/Engine/Source/Editor/WorldBrowser/Private/StreamingLevels/StreamingLevelEdMode.cpp
Andrew Rodham ba3528c9d4 Made it possible for asset editors to maintain their own FEditorModeTools lists
Breaking changes include:
    * Rename of GEditorModeTools -> GLevelEditorModeTools to signify that it applies only to the level editor modes
    * Addition of FEditorModeRegistry, responsible for managing and creating new editor modes. Modes are no longer registered with an instance of the mode, instead with a mode factory that is able to create a new mode of that type.
    * Editor modes now operate on FEditorViewportClients rather than FLevelEditorViewportClients
    * Added ability to specify an FEditorModeTools when creating an FEditorViewport

Moved component vizualiser manager handling outside of individual editor modes, and into FLevelEditorViewportClient. This should make it easier to transplant in future.

This work addresses TTP#334640 - EDITOR: Investigate making editor modes a per-'editor' concept

Reviewed by Michael Noland, Matt Kuhlenschmidt

[CL 2109245 by Andrew Rodham in Main branch]
2014-06-18 10:16:16 -04:00

222 lines
6.0 KiB
C++

// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
#include "WorldBrowserPrivatePCH.h"
#include "StreamingLevelEdMode.h"
#define LOCTEXT_NAMESPACE "WorldBrowser"
/** Constructor */
FStreamingLevelEdMode::FStreamingLevelEdMode()
: FEdMode()
{
UMaterial* GizmoMaterial = (UMaterial*)StaticLoadObject( UMaterial::StaticClass(),NULL,TEXT("/Engine/EditorMaterials/LevelTransformMaterial.LevelTransformMaterial") );
BoxMaterial = UMaterialInstanceDynamic::Create( GizmoMaterial, NULL );
bIsTracking = false;
}
/** Destructor */
FStreamingLevelEdMode::~FStreamingLevelEdMode()
{
}
void FStreamingLevelEdMode::AddReferencedObjects( FReferenceCollector& Collector )
{
// Call parent implementation
FEdMode::AddReferencedObjects( Collector );
Collector.AddReferencedObject(BoxMaterial);
}
EAxisList::Type FStreamingLevelEdMode::GetWidgetAxisToDraw( FWidget::EWidgetMode InWidgetMode ) const
{
switch(InWidgetMode)
{
case FWidget::WM_Translate:
return EAxisList::XYZ;
case FWidget::WM_Rotate:
return EAxisList::Z;
case FWidget::WM_Scale:
return EAxisList::None;
default:
return EAxisList::None;
}
}
bool FStreamingLevelEdMode::ShouldDrawWidget() const
{
return SelectedLevel.IsValid();
}
bool FStreamingLevelEdMode::UsesTransformWidget( FWidget::EWidgetMode CheckMode ) const
{
if( CheckMode == FWidget::EWidgetMode::WM_Scale )
{
return false;
}
return true;
}
FVector FStreamingLevelEdMode::GetWidgetLocation() const
{
if (SelectedLevel.IsValid())
{
return LevelTransform.GetTranslation();
}
return FEdMode::GetWidgetLocation();
}
void FStreamingLevelEdMode::SetLevel( ULevelStreaming* LevelStream )
{
if( SelectedLevel.IsValid() && SelectedLevel.Get() != LevelStream )
{
// Changed level need to apply PostEditMove to the actors we moved in the last level
ApplyPostEditMove();
}
SelectedLevel = LevelStream;
bIsDirty = false;
if ( SelectedLevel.IsValid() )
{
LevelTransform = SelectedLevel->LevelTransform;
ULevel* Level = SelectedLevel->GetLoadedLevel();
// Calculate the Level bounds box
LevelBounds = FBox(0);
if( Level )
{
for( int32 ActorIndex=0; ActorIndex< Level->Actors.Num(); ActorIndex++ )
{
AActor* Actor = Level->Actors[ActorIndex];
// Don't include the builder brush or the world settings as they can artificially make the level bounds bigger
if( Actor && FActorEditorUtils::IsABuilderBrush(Actor) == false && Level->GetWorldSettings() != Actor )
{
LevelBounds += Actor->GetComponentsBoundingBox();
}
}
}
}
GEditor->RedrawAllViewports();
}
bool FStreamingLevelEdMode::InputDelta( FEditorViewportClient* InViewportClient, FViewport* InViewport, FVector& InDrag, FRotator& InRot, FVector& InScale )
{
// Only Update the LevelTransform if the user has clicked on the Widget
if (InViewportClient->GetCurrentWidgetAxis() != EAxisList::None)
{
FVector Translation = LevelTransform.GetTranslation();
Translation += InDrag;
LevelTransform.SetTranslation( Translation );
FRotator Rot = LevelTransform.GetRotation().Rotator();
Rot += InRot;
LevelTransform.SetRotation( Rot.Quaternion() );
return true;
}
return false;
}
void FStreamingLevelEdMode::Render( const FSceneView* View, FViewport* Viewport, FPrimitiveDrawInterface* PDI )
{
FEdMode::Render( View, Viewport, PDI );
if( SelectedLevel.IsValid() )
{
if( !bIsTracking && !LevelTransform.Equals( SelectedLevel->LevelTransform ) )
{
// Level has changed outside of this tool, probably and undo, need to match up the widget again
LevelBounds.Min -= ( LevelTransform.GetLocation() - SelectedLevel->LevelTransform.GetLocation() );
LevelBounds.Max -= ( LevelTransform.GetLocation() - SelectedLevel->LevelTransform.GetLocation() );
LevelTransform = SelectedLevel->LevelTransform;
}
FTransform BoxTransform = LevelTransform;
FVector BoxLocation = ( LevelBounds.GetCenter() ) + ( LevelTransform.GetLocation() - SelectedLevel->LevelTransform.GetLocation() );
BoxTransform.SetLocation( BoxLocation );
DrawBox( PDI, BoxTransform.ToMatrixWithScale(), LevelBounds.GetExtent(), BoxMaterial->GetRenderProxy( false ), SDPG_World );
}
}
bool FStreamingLevelEdMode::StartTracking( FEditorViewportClient* InViewportClient, FViewport* InViewport )
{
bIsTracking = true;
return true;
}
bool FStreamingLevelEdMode::EndTracking( FEditorViewportClient* InViewportClient, FViewport* InViewport )
{
bIsTracking = false;
if( SelectedLevel.IsValid() && !LevelTransform.Equals( SelectedLevel->LevelTransform ) )
{
bIsDirty = true;
// Update Level bounds as its now in a new location
LevelBounds.Min += ( LevelTransform.GetLocation() - SelectedLevel->LevelTransform.GetLocation() );
LevelBounds.Max += ( LevelTransform.GetLocation() - SelectedLevel->LevelTransform.GetLocation() );
// Only update the level transform when the user releases the mouse button
FLevelUtils::SetEditorTransform( SelectedLevel.Get(), LevelTransform, false );
}
return true;
}
void FStreamingLevelEdMode::Enter()
{
FEdMode::Enter();
FWorldDelegates::LevelRemovedFromWorld.AddSP(this, &FStreamingLevelEdMode::OnLevelRemovedFromWorld);
}
void FStreamingLevelEdMode::Exit()
{
FWorldDelegates::LevelRemovedFromWorld.RemoveAll(this);
ApplyPostEditMove();
SelectedLevel = NULL;
FEdMode::Exit();
}
void FStreamingLevelEdMode::ApplyPostEditMove()
{
if( SelectedLevel.IsValid() && bIsDirty )
{
ULevel* LoadedLevel = SelectedLevel->GetLoadedLevel();
if( LoadedLevel != NULL )
{
FLevelUtils::ApplyPostEditMove(LoadedLevel);
bIsDirty = false;
}
}
}
bool FStreamingLevelEdMode::IsEditing( ULevelStreaming* Level )
{
return Level == SelectedLevel.Get();
}
bool FStreamingLevelEdMode::IsSnapRotationEnabled()
{
return true;
}
bool FStreamingLevelEdMode::SnapRotatorToGridOverride( FRotator& Rotation )
{
//Rotation = Rotation.GridSnap( FRotator( 90, 90, 90 ) );
return true;
}
void FStreamingLevelEdMode::OnLevelRemovedFromWorld(ULevel* InLevel, UWorld* InWorld)
{
if (SelectedLevel.IsValid())
{
if (SelectedLevel->GetLoadedLevel() == InLevel)
{
SelectedLevel = NULL;
Exit();
}
}
}
#undef LOCTEXT_NAMESPACE