Editor/SpriteRenderingWidget.cs
using Editor;
using Sandbox;
using System;
namespace SpriteTools;
public class SpriteRenderingWidget : SceneRenderingWidget
{
public Action OnDragSelected;
public ModelRenderer TextureRect;
ModelRenderer BackgroundRect;
public Material PreviewMaterial;
public Vector2 TextureSize { get; private set; }
public float AspectRatio { get; private set; }
protected float targetZoom = 115f;
Vector2 cameraGrabPos = Vector2.Zero;
bool cameraGrabbing = false;
protected virtual bool CanZoom => true;
public SpriteRenderingWidget ( Widget parent ) : base( parent )
{
MouseTracking = true;
FocusMode = FocusMode.Click;
Scene = Scene.CreateEditorScene();
using ( Scene.Push() )
{
var cameraObj = new GameObject( "Camera" );
Camera = cameraObj.Components.Create<CameraComponent>();
Camera.ZFar = 4000f;
Camera.ZNear = 1f;
Camera.EnablePostProcessing = false;
Camera.Orthographic = true; ;
Camera.OrthographicHeight = 512f;
Camera.WorldRotation = new Angles( 90, 180, 0 );
Camera.BackgroundColor = Theme.ControlBackground;
Camera.WorldPosition = new Vector3( 0, 0, targetZoom );
var ambientLight = cameraObj.Components.Create<AmbientLight>();
ambientLight.Color = Color.White * 1f;
var backgroundMat = Material.Load( "materials/sprite_editor_transparent.vmat" );
var backgroundObj = new GameObject( "Background" );
BackgroundRect = backgroundObj.AddComponent<ModelRenderer>();
BackgroundRect.Model = Model.Load( "models/preview_quad.vmdl" );
BackgroundRect.MaterialOverride = backgroundMat;
BackgroundRect.WorldPosition = new Vector3( 0, 0, -1 );
PreviewMaterial = Material.Load( "materials/sprite_2d.vmat" ).CreateCopy();
PreviewMaterial.Set( "Texture", Color.Transparent );
PreviewMaterial.Set( "g_flFlashAmount", 0f );
var textureObj = new GameObject( "Texture" );
TextureRect = textureObj.AddComponent<ModelRenderer>();
TextureRect.Model = Model.Load( "models/preview_quad.vmdl" );
TextureRect.MaterialOverride = PreviewMaterial;
TextureRect.WorldTransform = Transform.Zero;
TextureRect.RenderType = ModelRenderer.ShadowRenderType.Off;
}
}
protected override void OnWheel ( WheelEvent e )
{
base.OnWheel( e );
if ( CanZoom )
Zoom( e.Delta );
}
protected override void OnMousePress ( MouseEvent e )
{
base.OnMousePress( e );
if ( e.MiddleMouseButton )
{
cameraGrabbing = true;
cameraGrabPos = e.LocalPosition;
}
}
protected override void OnMouseMove ( MouseEvent e )
{
base.OnMouseMove( e );
if ( cameraGrabbing )
{
var delta = ( cameraGrabPos - e.LocalPosition ) * ( Camera.OrthographicHeight / 512f );
Camera.WorldPosition = new Vector3( Camera.WorldPosition.x + delta.y, Camera.WorldPosition.y + delta.x, Camera.WorldPosition.z );
cameraGrabPos = e.LocalPosition;
}
}
protected override void OnMouseReleased ( MouseEvent e )
{
base.OnMouseReleased( e );
if ( e.MiddleMouseButton )
{
cameraGrabbing = false;
}
}
protected override void PreFrame ()
{
Camera.OrthographicHeight = Camera.OrthographicHeight.LerpTo( targetZoom, 0.1f );
}
public void Zoom ( float delta )
{
targetZoom *= 1f - ( delta / 500f );
targetZoom = targetZoom.Clamp( 1, 1000 );
}
public void Fit ()
{
targetZoom = 115f;
Camera.WorldPosition = new Vector3( 0, 0, targetZoom );
}
public void SetTexture ( Texture texture, Rect rect = default )
{
if ( rect == default )
{
rect = new Rect( 0, 0, texture.Width, texture.Height );
}
PreviewMaterial.Set( "Texture", texture );
TextureSize = new Vector2( texture.Width, texture.Height );
TextureRect.MaterialOverride = PreviewMaterial;
var tiling = rect.Size / TextureSize;
var offset = rect.Position / TextureSize;
PreviewMaterial.Set( "g_vTiling", tiling );
PreviewMaterial.Set( "g_vOffset", offset );
TextureSize = rect.Size;
ResizeQuads();
}
void ResizeQuads ()
{
if ( !BackgroundRect.IsValid() || !TextureRect.IsValid() )
return;
// Scale the quad to be the same aspect ratio as the texture
AspectRatio = TextureSize.x / TextureSize.y;
var size = new Vector3( 1f / AspectRatio, 1f, 1f );
if ( AspectRatio < 1f )
size = new Vector3( 1f, AspectRatio, 1f );
BackgroundRect.WorldTransform = Transform.Zero.WithScale( size ).WithPosition( new Vector3( 0, 0, -1 ) );
TextureRect.WorldTransform = Transform.Zero.WithScale( size );
}
protected void UpdateInputs ()
{
Camera.CustomSize = Size;
GizmoInstance.Input.IsHovered = IsUnderMouse;
GizmoInstance.Input.Modifiers = Editor.Application.KeyboardModifiers;
GizmoInstance.Input.CursorPosition = Editor.Application.CursorPosition;
GizmoInstance.Input.LeftMouse = Editor.Application.MouseButtons.HasFlag( MouseButtons.Left );
GizmoInstance.Input.RightMouse = Editor.Application.MouseButtons.HasFlag( MouseButtons.Right );
GizmoInstance.Input.CursorPosition -= ScreenPosition;
GizmoInstance.Input.CursorRay = Camera.ScreenPixelToRay( GizmoInstance.Input.CursorPosition );
if ( !GizmoInstance.Input.IsHovered )
{
GizmoInstance.Input.LeftMouse = false;
GizmoInstance.Input.RightMouse = false;
}
}
}