mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-08-02 08:50:18 -04:00
* Add Qt-Advanced-Docking-System 5.0 * Bind new CDockManager, dock areas * Use Valve's CSS & images for ADS as a baseline, load stuff from disk instead of embedded in c++ * dockmanager.css in tool styles, auto loads and hotloads * Rewrite DockManager * delete toolwindowmanager * Delete the 50 different ways to create/add/register a dock, you just add a dock, that's all u need * More dockmanager rejigging * restore all editor dock layouts and asset browser on the new docking system * remove last toolwindowmanager remnants, add ADS to third party legal notice * build classic default layout in code for main editor reset/first-run, add relative area AddDock overload * relativeTo placement API, restore correct default layouts for all tool windows, register [Dock] types closed instead of eagerly docking * styling pass * disable ADS built-in stylesheet load, styling comes from editor stylesheet * lock picker browser tabs against closing/dragging, make ActionGraph reset layout actually reposition docks * add DockManager.OpenDock, dedupe layout code in EditorMainWindow/ActionGraph * CloseDockWidget internal * add "Close Tabs to the Left/Right" to dock tab context menu * expose dock MinimumSizeFromContent * only offer close left/right tab options when open tabs exist on that side * move "Close Tabs to the Left/Right" out of the ADS lib into a components factory * guard dock tab context menu against pinned docks with no dock area * fix crash when pinned tab is destroyed before delayed auto hide timer fires * recreate scene widget swapchains when Qt recreates their native window on dock reparent * wrap all sbox changes to the dock lib in #ifdef SBOX * save a plain window rect as fallback for when Qt rejects saved geometry on mixed-DPI monitors * expose DockWidget Float/IsFloating * always restore window geometry from a plain saved rect instead of Qt's DPI fragile geometry blob * route all window centering through one screen aware helper that handles mixed DPI monitors * restore window geometry onto the screen it was saved on * don't close live docks when a dock type unregisters, hotload substitutes them in place --------- Co-authored-by: Layla <1667289+aylaylay@users.noreply.github.com>
194 lines
3.7 KiB
C#
194 lines
3.7 KiB
C#
using System;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace Editor
|
|
{
|
|
public class QObject : IValid
|
|
{
|
|
internal static Dictionary<Native.QObject, QObject> AllObjects = new();
|
|
|
|
internal Native.QObject _object;
|
|
internal Dictionary<GCHandle, CallbackMethod> _handles = new();
|
|
|
|
bool IsDestroyed;
|
|
bool IValid.IsValid => IsValid;
|
|
|
|
[Hide]
|
|
public bool IsValid => _object.IsValid && !IsDestroyed;
|
|
|
|
internal virtual void NativeInit( IntPtr ptr )
|
|
{
|
|
if ( ptr == default )
|
|
throw new System.Exception( "QObject was null!" );
|
|
|
|
_object = ptr;
|
|
|
|
AllObjects[_object] = this;
|
|
|
|
// Get notified when object is destroyed - so we can invalidate our pointers
|
|
WidgetUtil.OnObject_Destroyed( ptr, Callback( NativeShutdown ) );
|
|
EditorEvent.Register( this );
|
|
}
|
|
|
|
public virtual void OnDestroyed()
|
|
{
|
|
|
|
}
|
|
|
|
internal virtual void NativeShutdown()
|
|
{
|
|
EditorEvent.Unregister( this );
|
|
Sandbox.InteropSystem.Free( this );
|
|
|
|
AllObjects.Remove( _object );
|
|
|
|
_object = default;
|
|
|
|
// Can free all the allocated handles now
|
|
// because they won't get called
|
|
foreach ( var handle in _handles )
|
|
{
|
|
handle.Key.Free();
|
|
}
|
|
|
|
_handles.Clear();
|
|
_handles = null;
|
|
|
|
OnDestroyed();
|
|
}
|
|
|
|
internal delegate void CallbackMethod( IntPtr qobj );
|
|
internal IntPtr Callback( Action cb )
|
|
{
|
|
CallbackMethod wrapped = ( IntPtr qobj ) =>
|
|
{
|
|
try
|
|
{
|
|
cb();
|
|
}
|
|
catch ( System.Exception ex )
|
|
{
|
|
try { Log.Error( ex ); }
|
|
catch { }
|
|
}
|
|
};
|
|
|
|
_handles.Add( GCHandle.Alloc( wrapped ), wrapped );
|
|
return Marshal.GetFunctionPointerForDelegate( wrapped );
|
|
}
|
|
|
|
public void Destroy()
|
|
{
|
|
if ( IsDestroyed )
|
|
return;
|
|
|
|
IsDestroyed = true;
|
|
|
|
EditorEvent.Unregister( this );
|
|
|
|
if ( _object.IsValid )
|
|
{
|
|
OnDestroyingLater();
|
|
_object.deleteMuchLater();
|
|
}
|
|
}
|
|
|
|
internal virtual void OnDestroyingLater()
|
|
{
|
|
|
|
}
|
|
|
|
internal unsafe Native.QObject[] GetChildren()
|
|
{
|
|
if ( !_object.IsValid )
|
|
{
|
|
return Array.Empty<Native.QObject>();
|
|
}
|
|
|
|
var c = WidgetUtil.GetChildrenCount( _object );
|
|
|
|
if ( c <= 0 )
|
|
return Array.Empty<Native.QObject>();
|
|
|
|
var list = new Native.QObject[c];
|
|
|
|
fixed ( Native.QObject* ptr = list )
|
|
{
|
|
WidgetUtil.GetChildren( _object, ptr, list.Length );
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
static internal QObject FindOrCreate( Native.QObject obj )
|
|
{
|
|
if ( AllObjects.TryGetValue( obj, out var handle ) )
|
|
return handle;
|
|
|
|
// leafiest first!
|
|
|
|
{
|
|
Native.QPushButton ptr = (Native.QPushButton)obj;
|
|
if ( ptr.IsValid ) return new Button( ptr );
|
|
}
|
|
|
|
{
|
|
Native.QTabBar ptr = (Native.QTabBar)obj;
|
|
if ( ptr.IsValid ) return new TabBar( ptr );
|
|
}
|
|
|
|
{
|
|
Native.QMenuBar ptr = (Native.QMenuBar)obj;
|
|
if ( ptr.IsValid ) return new MenuBar( ptr );
|
|
}
|
|
|
|
{
|
|
Native.CDockWidget ptr = (Native.CDockWidget)obj;
|
|
if ( ptr.IsValid ) return new DockWidget( ptr );
|
|
}
|
|
|
|
{
|
|
Native.QWidget ptr = (Native.QWidget)obj;
|
|
if ( ptr.IsValid ) return new Widget( ptr );
|
|
}
|
|
|
|
{
|
|
QMimeData ptr = (QMimeData)obj;
|
|
if ( ptr.IsValid ) return new DragData( ptr );
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public void SetProperty( string name, bool value )
|
|
{
|
|
_object.setProperty( name, value );
|
|
}
|
|
|
|
public void SetProperty( string name, float value )
|
|
{
|
|
_object.setProperty( name, value );
|
|
}
|
|
|
|
public void SetProperty( string name, string value )
|
|
{
|
|
_object.setProperty( name, value );
|
|
}
|
|
|
|
public Sandbox.Bind.Builder Bind( string targetName, Action onChanged = null )
|
|
{
|
|
var bb = new Sandbox.Bind.Builder
|
|
{
|
|
system = Sandbox.Internal.GlobalToolsNamespace.BindSystem
|
|
};
|
|
|
|
return bb.Set( this, targetName, onChanged );
|
|
}
|
|
|
|
internal void SetParent( QObject obj )
|
|
{
|
|
_object.setParent( obj._object );
|
|
}
|
|
}
|
|
}
|