Files
sbox-public/game/addons/tools/Code/Scene/SceneView/ViewportTools.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

194 lines
4.1 KiB
C#

namespace Editor;
public partial class ViewportTools : Widget
{
private Widget toolbarWidget;
private SceneViewWidget sceneViewWidget;
private float Margin => 6;
private float Spacing => 6;
public ViewportTools( SceneViewWidget sceneViewWidget )
{
Layout = Layout.Column();
this.sceneViewWidget = sceneViewWidget;
Rebuild();
}
void AddSeparator( Layout layout )
{
layout.AddSpacingCell( Spacing );
layout.Add( new Separator() );
layout.AddSpacingCell( Spacing );
}
public void Rebuild()
{
Layout.Clear( true );
//
// Toolbar
//
toolbarWidget = Layout.Add( new Widget() );
toolbarWidget.Name = "ViewportToolbar";
toolbarWidget.FixedHeight = Theme.ControlHeight + Margin * 2;
toolbarWidget.OnPaintOverride = () =>
{
Paint.ClearPen();
Paint.SetBrush( Theme.SurfaceBackground );
Paint.DrawRect( toolbarWidget.LocalRect );
return true;
};
var toolbar = toolbarWidget.Layout = Layout.Row();
toolbar.Margin = new Sandbox.UI.Margin( 2, Margin, Margin, Margin );
toolbar.Spacing = Spacing;
var left = toolbar.AddRow( 1 );
left.Spacing = Spacing;
left.Alignment = TextFlag.LeftCenter;
var center = toolbar.AddRow( 1 );
center.Spacing = Spacing;
center.Alignment = TextFlag.Center;
var right = toolbar.AddRow( 1 );
right.Spacing = Spacing;
right.Alignment = TextFlag.RightCenter;
// These only get built for game view mode, clear them.
FrameTimeLabel = null;
FrameRateLabel = null;
ResolutionComboBox = null;
if ( sceneViewWidget.CurrentView == SceneViewWidget.ViewMode.Game )
{
BuildToolbarGame( left );
}
else
{
BuildToolbarLeft( left );
AddSeparator( left );
BuildToolbarScene( left );
}
toolbar.AddStretchCell();
var centerGroup = center.Add( AddGroup() );
BuildPlayToolbar( centerGroup.Layout );
BuildToolbarRight( right );
Layout.AddStretchCell();
}
[Shortcut( "editor.toggle-fullscreen", "F3", ShortcutType.Window )]
internal static void ToggleFullscreen()
{
EditorWindow.SetFullscreen( SceneViewWidget.Current );
}
[EditorEvent.Frame]
public void OnViewportToolsFrame()
{
UpdateDimensions();
UpdateChildren();
}
int lastGeometryHash = -1;
private void UpdateDimensions()
{
if ( !Parent.IsValid() )
return;
// this wasn't always being triggered properly when relying on widget events from the parent (causing HUGE jank)
int geometryHash = HashCode.Combine( Parent.ScreenPosition, Parent.Size );
if ( lastGeometryHash != geometryHash )
{
Position = Vector2.Zero;
Size = Parent.Size;
}
lastGeometryHash = geometryHash;
}
private void UpdateChildren()
{
foreach ( var child in toolbarWidget.Children )
{
if ( child is EditorToolButton button )
{
button.UpdateState();
}
}
}
private EditorToolButton AddToggleButton( Layout layout, string tooltip, Func<string> getIcon, Func<bool> getVal, Action<bool> setVal )
{
var __getVal = () => { try { return getVal(); } catch ( System.Exception ) { return false; } };
var __setVal = ( bool b ) => { try { setVal( b ); } catch ( System.Exception ) { } };
var b = new EditorToolButton();
b.GetIcon = getIcon;
b.ToolTip = tooltip;
b.Action = () => __setVal( !__getVal() );
b.IsActive = () => __getVal();
layout.Add( b );
return b;
}
private EditorToolButton AddButton( Layout layout, string tooltip, string getIcon, Action onClick )
{
var b = new EditorToolButton();
b.GetIcon = () => getIcon;
b.ToolTip = tooltip;
b.Action = onClick;
layout.Add( b );
return b;
}
private Widget AddGroup()
{
var w = new Widget();
w.OnPaintOverride = () =>
{
Paint.ClearPen();
Paint.SetBrush( Theme.ControlBackground );
Paint.DrawRect( w.LocalRect, Theme.ControlRadius );
return true;
};
w.FixedHeight = Theme.RowHeight;
w.Layout = Layout.Row();
w.Layout.Spacing = Spacing;
w.Layout.Margin = new( 2, 0 );
return w;
}
}
file class Separator : Widget
{
public Separator() : base( null )
{
FixedHeight = Theme.ControlHeight;
FixedWidth = 1;
}
protected override void OnPaint()
{
Paint.Antialiasing = true;
Paint.ClearPen();
Paint.SetBrush( Color.White.WithAlpha( 0.25f ) );
Paint.DrawRect( LocalRect );
}
}