mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-01-11 07:48:36 -05:00
This commit imports the C# engine code and game files, excluding C++ source code. [Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
130 lines
3.2 KiB
C#
130 lines
3.2 KiB
C#
namespace Sandbox.UI
|
|
{
|
|
/// <summary>
|
|
/// A generic box that displays a given texture within itself.
|
|
/// </summary>
|
|
[Library( "image" ), Alias( "img" ), Expose]
|
|
public partial class Image : Panel
|
|
{
|
|
/// <summary>
|
|
/// The texture being displayed by this panel.
|
|
/// </summary>
|
|
public Texture Texture { get; set; }
|
|
|
|
public override bool HasContent => Texture != null;
|
|
|
|
public Image()
|
|
{
|
|
YogaNode.SetMeasureFunction( MeasureTexture );
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set <see cref="Texture"/> from a file path. URLs supported.
|
|
/// </summary>
|
|
public async void SetTexture( string name )
|
|
{
|
|
if ( string.IsNullOrWhiteSpace( name ) ) return;
|
|
if ( !IsValid ) return;
|
|
|
|
Texture = await Texture.LoadAsync( name );
|
|
|
|
if ( !IsValid ) return;
|
|
YogaNode.MarkDirty(); // Update MeasureTexture
|
|
}
|
|
|
|
float oldScaleToScreen = 1.0f;
|
|
internal override void PreLayout( LayoutCascade cascade )
|
|
{
|
|
base.PreLayout( cascade );
|
|
|
|
if ( ScaleToScreen != oldScaleToScreen )
|
|
{
|
|
YogaNode.MarkDirty();
|
|
}
|
|
}
|
|
|
|
internal override void DrawContent( PanelRenderer renderer, ref RenderState state )
|
|
{
|
|
if ( Texture == null )
|
|
return;
|
|
|
|
if ( renderer is PanelRenderer pr )
|
|
{
|
|
var length = ComputedStyle.ObjectFit switch
|
|
{
|
|
ObjectFit.Contain => Length.Contain,
|
|
ObjectFit.Cover => Length.Cover,
|
|
ObjectFit.Fill => Length.Percent( 100 ).Value,
|
|
_ => Length.Auto,
|
|
};
|
|
|
|
pr.DrawBackgroundTexture( this, Texture, state, length );
|
|
}
|
|
}
|
|
|
|
public override void SetProperty( string name, string value )
|
|
{
|
|
base.SetProperty( name, value );
|
|
|
|
if ( name == "src" ) SetTexture( value );
|
|
}
|
|
|
|
internal Vector2 MeasureTexture( YGNodeRef node, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode )
|
|
{
|
|
if ( !Texture.IsValid() ) return default;
|
|
|
|
try
|
|
{
|
|
var (w, h) = (Texture.Width, Texture.Height);
|
|
var exact = YGMeasureMode.YGMeasureModeExactly;
|
|
var atMost = YGMeasureMode.YGMeasureModeAtMost;
|
|
|
|
oldScaleToScreen = ScaleToScreen;
|
|
var ideal = new Vector2( w * ScaleToScreen, h * ScaleToScreen );
|
|
|
|
if ( widthMode == exact ) return new Vector2( width, h * width / w );
|
|
if ( heightMode == exact ) return new Vector2( w * height / h, height );
|
|
|
|
if ( widthMode == atMost && heightMode == atMost && (width < ideal.x || height < ideal.y) )
|
|
{
|
|
float scale = Math.Min( width / w, height / h );
|
|
return new Vector2( w * scale, h * scale );
|
|
}
|
|
|
|
if ( widthMode == atMost && width < ideal.x ) return new Vector2( width, h * width / w );
|
|
if ( heightMode == atMost && height < ideal.y ) return new Vector2( w * height / h, height );
|
|
|
|
return ideal;
|
|
}
|
|
catch ( System.Exception e )
|
|
{
|
|
Log.Warning( e );
|
|
return default;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
namespace Construct
|
|
{
|
|
public static class ImageConstructor
|
|
{
|
|
/// <summary>
|
|
/// Create an image with given texture and CSS classname.
|
|
/// </summary>
|
|
public static Image Image( this PanelCreator self, string image = null, string classname = null )
|
|
{
|
|
var control = self.panel.AddChild<Image>();
|
|
|
|
if ( image != null )
|
|
control.SetTexture( image );
|
|
|
|
if ( classname != null )
|
|
control.AddClass( classname );
|
|
|
|
return control;
|
|
}
|
|
}
|
|
}
|
|
}
|