Files
sbox-public/game/addons/tools/Code/Editor/VerticalTabWidget.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

215 lines
4.1 KiB
C#

namespace Editor;
public class VerticalTabWidget : Widget
{
Dictionary<string, Widget> pages = new();
Dictionary<string, VerticalTab> tabs = new();
Widget _currentPage;
Widget tabContainer;
Widget contentContainer;
public Widget CurrentPage
{
get => _currentPage;
set
{
if ( _currentPage == value )
return;
SetPage( value );
if ( _currentPage.IsValid() )
_currentPage.Visible = false;
_currentPage = value;
if ( _currentPage.IsValid() )
_currentPage.Visible = true;
Update();
}
}
public string Selected { get; private set; }
public Action<string> OnSelectedChanged { get; set; }
public VerticalTabWidget( Widget parent ) : base( parent )
{
Layout = Layout.Row();
tabContainer = Layout.Add( new Widget( this ) );
tabContainer.FixedWidth = Theme.RowHeight * 2;
tabContainer.Layout = Layout.Column();
tabContainer.Layout.Alignment = TextFlag.Top;
contentContainer = Layout.Add( new Widget( this ) );
contentContainer.Layout = Layout.Column();
}
public void SetPage( Widget page )
{
var entry = pages.FirstOrDefault( x => x.Value == page );
if ( !entry.Value.IsValid() ) return;
if ( _currentPage == entry.Value ) return;
foreach ( var p in pages )
{
p.Value.Visible = false;
}
entry.Value.Visible = true;
_currentPage = entry.Value;
Selected = entry.Key;
foreach ( var tab in tabs )
{
tab.Value.IsActive = tab.Key == Selected;
tab.Value.Update();
}
Update();
OnSelectedChanged?.Invoke( Selected );
Save();
}
public void AddPage( string name, string icon = null, Widget page = null, string tooltip = null )
{
page ??= new Widget( null );
page.Visible = false;
pages[name] = page;
var tab = tabContainer.Layout.Add( new VerticalTab( icon )
{
ToolTip = tooltip ?? name,
IsActive = false,
Name = name
} );
tabs[name] = tab;
tab.MouseClick = () =>
{
SetPage( page );
};
contentContainer.Layout.Add( page );
if ( pages.Count == 1 )
{
CurrentPage = page;
}
}
public void SetPageEnabled( string name, bool enabled )
{
if ( !tabs.TryGetValue( name, out var tab ) )
return;
tab.Enabled = enabled;
}
string _cookie;
public string StateCookie
{
get => _cookie;
set
{
if ( _cookie == value ) return;
_cookie = value;
Restore();
}
}
private void Save()
{
if ( string.IsNullOrEmpty( StateCookie ) ) return;
var pageName = "";
var page = pages.FirstOrDefault( x => x.Value == CurrentPage );
pageName = page.Key ?? "";
EditorCookie.Set( $"verticaltabwidget.{StateCookie}", pageName );
}
private void Restore()
{
if ( string.IsNullOrEmpty( StateCookie ) ) return;
var pageName = EditorCookie.Get<string>( $"verticaltabwidget.{StateCookie}", null );
if ( string.IsNullOrWhiteSpace( pageName ) ) return;
var page = pages.FirstOrDefault( x => x.Key == pageName );
if ( page.Key == null ) return;
SetPage( page.Value );
}
protected override void OnPaint()
{
Paint.ClearPen();
Paint.ClearBrush();
var tabRect = tabContainer.LocalRect;
Paint.SetBrush( Theme.ControlBackground );
Paint.DrawRect( tabRect );
Paint.SetBrushAndPen( Theme.Border );
var borderRect = tabRect;
borderRect.Left = borderRect.Right - 1;
Paint.DrawRect( borderRect );
Paint.SetBrushAndPen( Theme.BorderLight );
borderRect.Position += new Vector2( 1, 0 );
Paint.DrawRect( borderRect );
}
}
public class VerticalTab : Button
{
public bool IsActive { get; set; }
public VerticalTab( string icon ) : base( null )
{
Icon = icon;
FixedHeight = Theme.RowHeight * 1.5f;
}
protected override void OnPaint()
{
Paint.ClearPen();
Paint.ClearBrush();
Paint.SetBrushAndPen( Theme.Border );
var r = LocalRect;
r.Top = r.Bottom - 1;
Paint.DrawRect( r );
Paint.SetBrushAndPen( Theme.BorderLight );
r.Position += new Vector2( 0, 1 );
Paint.DrawRect( r );
if ( !Enabled )
{
Paint.ClearBrush();
Paint.SetPen( Theme.TextDisabled );
Paint.DrawIcon( LocalRect, Icon, 16.0f );
return;
}
if ( IsActive )
{
Paint.SetBrush( Theme.Primary );
Paint.DrawRect( LocalRect );
}
Paint.ClearBrush();
Paint.SetPen( Theme.TextControl );
Paint.DrawIcon( LocalRect, Icon, 16.0f );
}
}