Files
sbox-public/game/addons/tools/Code/NodeGraph/ResizableItem.cs
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

214 lines
4.5 KiB
C#

using System;
using System.Reflection;
namespace Editor.NodeEditor;
/// <summary>
/// Example of a resizable item for when I need it
/// </summary>
public class ResizableItem : GraphicsItem
{
[Flags]
private enum SizeDirection
{
None = 0,
Top = 1 << 0,
Bottom = 1 << 1,
Left = 1 << 2,
Right = 1 << 3
}
private bool _resizing;
private Vector2 _offset;
private Vector2 _minSize => new( 32, 32 );
private Vector2 _maxSize => new( 10000, 10000 );
private Vector2 _dragSize => new( 16, 16 );
private SizeDirection _direction;
public ResizableItem()
{
Movable = true;
Selectable = true;
HoverEvents = true;
ZIndex = -1;
Size = new Vector2( 256, 256 );
}
protected override void OnPaint()
{
Paint.ClearPen();
Paint.SetBrush( Theme.Blue.WithAlpha( 0.9f ) );
Paint.DrawRect( LocalRect.Shrink( 4 ), 4 );
}
private void UpdateDirection( Vector2 position )
{
_direction = SizeDirection.None;
Cursor = CursorShape.None;
if ( position.x <= _dragSize.x )
{
_direction |= SizeDirection.Left;
_offset.x = position.x;
}
else if ( position.x >= Size.x - _dragSize.x )
{
_direction |= SizeDirection.Right;
_offset.x = position.x - Size.x;
}
if ( position.y <= _dragSize.y )
{
_direction |= SizeDirection.Top;
_offset.y = position.y;
Cursor = _direction.HasFlag( SizeDirection.Left ) ? CursorShape.SizeFDiag :
_direction.HasFlag( SizeDirection.Right ) ? CursorShape.SizeBDiag : CursorShape.SizeV;
}
else if ( position.y >= Size.y - _dragSize.y )
{
_direction |= SizeDirection.Bottom;
_offset.y = position.y - Size.y;
Cursor = _direction.HasFlag( SizeDirection.Left ) ? CursorShape.SizeBDiag :
_direction.HasFlag( SizeDirection.Right ) ? CursorShape.SizeFDiag : CursorShape.SizeV;
}
else if ( _direction.HasFlag( SizeDirection.Left ) || _direction.HasFlag( SizeDirection.Right ) )
{
Cursor = CursorShape.SizeH;
}
else
{
Cursor = CursorShape.None;
}
}
protected override void OnMousePressed( GraphicsMouseEvent e )
{
if ( e.LeftMouseButton && !_resizing )
{
UpdateDirection( e.LocalPosition );
if ( _direction != SizeDirection.None )
{
_resizing = true;
e.Accepted = true;
}
}
if ( _resizing )
{
e.Accepted = true;
}
base.OnMousePressed( e );
}
protected override void OnMouseReleased( GraphicsMouseEvent e )
{
if ( _resizing )
{
e.Accepted = true;
if ( !e.LeftMouseButton )
{
_resizing = false;
}
}
base.OnMouseReleased( e );
}
protected override void OnHoverMove( GraphicsHoverEvent e )
{
base.OnHoverMove( e );
UpdateDirection( e.LocalPosition );
}
protected override void OnHoverEnter( GraphicsHoverEvent e )
{
base.OnHoverEnter( e );
UpdateDirection( e.LocalPosition );
}
protected override void OnHoverLeave( GraphicsHoverEvent e )
{
base.OnHoverLeave( e );
_direction = SizeDirection.None;
Cursor = CursorShape.None;
}
protected override void OnMouseMove( GraphicsMouseEvent e )
{
base.OnMouseMove( e );
if ( !_resizing )
return;
e.Accepted = true;
var gridSize = GraphicsView is IGridSizeView view ? view.GridSize : 16f;
var position = (e.ScenePosition - _offset).SnapToGrid( gridSize );
var rect = SceneRect;
if ( _direction.HasFlag( SizeDirection.Left ) )
rect = ResizeLeft( rect, position.x );
else if ( _direction.HasFlag( SizeDirection.Right ) )
rect = ResizeRight( rect, position.x );
if ( _direction.HasFlag( SizeDirection.Top ) )
rect = ResizeTop( rect, position.y );
else if ( _direction.HasFlag( SizeDirection.Bottom ) )
rect = ResizeBottom( rect, position.y );
SceneRect = rect;
PrepareGeometryChange();
Update();
}
protected override void OnPositionChanged()
{
Position = Position.SnapToGrid( 16.0f );
}
private Rect ResizeTop( Rect rect, float position )
{
rect.Top = position;
var size = rect.Bottom - rect.Top;
size -= size.Clamp( _minSize.y, _maxSize.y );
rect.Top += size;
return rect;
}
private Rect ResizeLeft( Rect rect, float position )
{
rect.Left = position;
var size = rect.Right - rect.Left;
size -= size.Clamp( _minSize.x, _maxSize.x );
rect.Left += size;
return rect;
}
private Rect ResizeBottom( Rect rect, float position )
{
rect.Bottom = position;
var size = rect.Bottom - rect.Top;
size -= size.Clamp( _minSize.y, _maxSize.y );
rect.Bottom -= size;
return rect;
}
private Rect ResizeRight( Rect rect, float position )
{
rect.Right = position;
var size = rect.Right - rect.Left;
size -= size.Clamp( _minSize.x, _maxSize.x );
rect.Right -= size;
return rect;
}
}