@ -4,10 +4,8 @@ using System.Linq;
using System.Numerics ;
using System.Numerics ;
using gaemstone.Client.Utility ;
using gaemstone.Client.Utility ;
using gaemstone.ECS ;
using gaemstone.ECS ;
using gaemstone.Flecs ;
using ImGuiNET ;
using ImGuiNET ;
using static gaemstone . Client . Systems . ImGuiManager ;
using static gaemstone . Client . Systems . ImGuiManager ;
using Icon = gaemstone . Client . Utility . ForkAwesome ;
using ImGuiInternal = ImGuiNET . Internal . ImGui ;
using ImGuiInternal = ImGuiNET . Internal . ImGui ;
namespace gaemstone.Client.Systems ;
namespace gaemstone.Client.Systems ;
@ -15,13 +13,13 @@ namespace gaemstone.Client.Systems;
[Module]
[Module]
[DependsOn<gaemstone.Client.Systems.ImGuiManager>]
[DependsOn<gaemstone.Client.Systems.ImGuiManager>]
public partial class EntityInspector
public partial class EntityInspector
: IModuleInitializer
: IModuleLifetime
{
{
[Tag]
[Tag]
public struct InspectorWindow { }
public struct InspectorWindow { }
[Relation, Exclusive]
[Relation, Exclusive]
[Add<Core.OnDeleteTarget, C ore.Delete>]
[Add<flecs.core.OnDeleteTarget, flecs.c ore.Delete>]
public struct Selected { }
public struct Selected { }
[Tag]
[Tag]
@ -54,43 +52,68 @@ public partial class EntityInspector
}
}
[Component]
[Component]
public struct DocPriority { public float Value ; }
public record struct Priority ( float Value ) ;
[Component]
[Component]
public struct DocIcon { public char Value ; }
public record struct Icon ( char Value ) ;
[Path("/flecs/core/Module")]
[Add<Doc.DisplayType>, Set<Priority>(0), Set<Icon>(ForkAwesome.Archive)]
public struct Module { }
[Path("/flecs/system/System")]
[Add<Doc.DisplayType>, Set<Priority>(1), Set<Icon>(ForkAwesome.Cog)]
public struct System { }
[Path("/flecs/core/Observer")]
[Add<Doc.DisplayType>, Set<Priority>(2), Set<Icon>(ForkAwesome.Eye)]
public struct Observer { }
[Path("/gaemstone/Doc/Relation")]
[Add<Doc.DisplayType>, Set<Priority>(3), Set<Icon>(ForkAwesome.ShareAlt)]
public struct Relation { }
[Path("/flecs/core/Component")]
[Add<Doc.DisplayType>, Set<Priority>(4), Set<Icon>(ForkAwesome.PencilSquare)]
public struct Component { }
[Path("/gaemstone/Doc/Tag")]
[Add<Doc.DisplayType>, Set<Priority>(5), Set<Icon>(ForkAwesome.Tag)]
public struct Tag { }
[Path("/flecs/core/Prefab")]
[Add<Doc.DisplayType>, Set<Priority>(6), Set<Icon>(ForkAwesome.Cube)]
public struct Prefab { }
private const string DefaultWindowTitle = "Inspector Gadget" ;
private const string DefaultWindowTitle = "Inspector Gadget" ;
public static void Initialize < T > ( Entity < T > module )
{
void SetDocInfo ( string path , float priority , string icon , float r , float g , float b )
= > module . World . LookupPathOrThrow ( path )
. Add < Doc . DisplayType > ( )
. Set ( new DocPriority { Value = priority } )
. Set ( new DocIcon { Value = icon [ 0 ] } )
. SetDocColor ( Color . FromRGB ( r , g , b ) . ToHexString ( ) ) ;
SetDocInfo ( "/flecs/core/Module" , 0 , Icon . Archive , 1.0f , 0.9f , 0.7f ) ;
public static void OnEnable < T > ( Entity < T > module )
SetDocInfo ( "/flecs/system/System" , 1 , Icon . Cog , 1.0f , 0.7f , 0.7f ) ;
{
SetDocInfo ( "/flecs/core/Observer" , 2 , Icon . Eye , 1.0f , 0.8f , 0.8f ) ;
var world = module . World ;
SetDocInfo ( "/gaemstone/Doc/Relation" , 3 , Icon . ShareAlt , 0.7f , 1.0f , 0.8f ) ;
world . LookupPathOrNull ( "/flecs/core/Module" ) ? . SetDocColor ( "#FFE4B2" ) ;
SetDocInfo ( "/flecs/core/Component" , 4 , Icon . PencilSquare , 0.6f , 0.6f , 1.0f ) ;
world . LookupPathOrNull ( "/flecs/system/System" ) ? . SetDocColor ( "#FFB2B2" ) ;
// TODO: Handle tags like Flecs does.
world . LookupPathOrNull ( "/flecs/core/Observer" ) ? . SetDocColor ( "#FFCCCC" ) ;
SetDocInfo ( "/flecs/core/Tag" , 5 , Icon . Tag , 0.7f , 0.8f , 1.0f ) ;
world . LookupPathOrNull ( "/gaemstone/Doc/Relation" ) ? . SetDocColor ( "#B2FFCC" ) ;
SetDocInfo ( "/flecs/core/Prefab" , 6 , Icon . Cube , 0.9f , 0.8f , 1.0f ) ;
world . LookupPathOrNull ( "/flecs/core/Component" ) ? . SetDocColor ( "#9999FF" ) ;
world . LookupPathOrNull ( "/gaemstone/Doc/Tag" ) ? . SetDocColor ( "#B2CCFF" ) ;
world . LookupPathOrNull ( "/flecs/core/Prefab" ) ? . SetDocColor ( "#E4CCFF" ) ;
}
}
public static void OnDisable < T > ( Entity < T > module ) { }
[System]
[System]
public static void ShowUIButton < T > ( World < T > world , ImGuiData _ )
public static void ShowUIButton < T > ( World < T > world , ImGuiData _ )
{
{
var hasAnyInspector = false ;
var hasAnyInspector = false ;
var inspectorWindow = world . Entity < InspectorWindow > ( ) ;
var inspectorWindow = world . Entity < InspectorWindow > ( ) ;
foreach ( var entity in Iterator < T > . FromTerm ( world , new ( inspectorWindow ) ) )
foreach ( var entity in world . Term ( new ( inspectorWindow ) ) )
{ hasAnyInspector = true ; break ; }
{ hasAnyInspector = true ; break ; }
if ( ImGuiUtility . UIButton ( 0 , Icon . Search , DefaultWindowTitle , hasAnyInspector ) )
if ( ImGuiUtility . UIButton ( 0 , ForkAwesome . Search , DefaultWindowTitle , hasAnyInspector ) )
NewEntityInspectorWindow ( world ) ;
NewEntityInspectorWindow ( world ) ;
}
}
@ -104,7 +127,7 @@ public partial class EntityInspector
ImGui . SetNextWindowSize ( new ( fontSize * 4 0 , fontSize * 2 5 ) , ImGuiCond . Appearing ) ;
ImGui . SetNextWindowSize ( new ( fontSize * 4 0 , fontSize * 2 5 ) , ImGuiCond . Appearing ) ;
ImGui . PushFont ( ImGui . GetIO ( ) . Fonts . Fonts [ 1 ] ) ;
ImGui . PushFont ( ImGui . GetIO ( ) . Fonts . Fonts [ 1 ] ) ;
var title = window . GetDocName ( ) ? ? DefaultWindowTitle ;
var title = window . GetDocName ( ) ? ? DefaultWindowTitle ;
if ( ImGui . Begin ( $"{Icon .Search} {title}###{window.NumericId}" ,
if ( ImGui . Begin ( $"{ForkAwesome .Search} {title}###{window.NumericId}" ,
ref isOpen , ImGuiWindowFlags . NoScrollbar ) ) {
ref isOpen , ImGuiWindowFlags . NoScrollbar ) ) {
ImGui . PushFont ( ImGui . GetIO ( ) . Fonts . Fonts [ 0 ] ) ;
ImGui . PushFont ( ImGui . GetIO ( ) . Fonts . Fonts [ 0 ] ) ;
@ -132,9 +155,9 @@ public partial class EntityInspector
ImGui . TableNextColumn ( ) ;
ImGui . TableNextColumn ( ) ;
ImGui . BeginChild ( "EntityView" , new ( - float . Epsilon , - float . Epsilon ) ) ;
ImGui . BeginChild ( "EntityView" , new ( - float . Epsilon , - float . Epsilon ) ) ;
if ( ! ImGui . BeginTabBar ( "Tabs" ) ) return ;
if ( ! ImGui . BeginTabBar ( "Tabs" ) ) return ;
Tab ( $"{Icon .PencilSquare} Components" , ComponentsTab ) ;
Tab ( $"{ForkAwesome .PencilSquare} Components" , ComponentsTab ) ;
Tab ( $"{Icon .ShareAlt} References" , ReferencesTab ) ;
Tab ( $"{ForkAwesome .ShareAlt} References" , ReferencesTab ) ;
Tab ( $"{Icon .InfoCircle} Documentation" , DocumentationTab ) ;
Tab ( $"{ForkAwesome .InfoCircle} Documentation" , DocumentationTab ) ;
ImGui . EndTabBar ( ) ;
ImGui . EndTabBar ( ) ;
ImGui . EndChild ( ) ;
ImGui . EndChild ( ) ;
@ -149,7 +172,7 @@ public partial class EntityInspector
if ( ! isOpen ) window . Delete ( ) ;
if ( ! isOpen ) window . Delete ( ) ;
}
}
[Observer<C ore.OnRemove>]
[Observer<flecs.c ore.OnRemove>]
public static void ClearStorageOnRemove < T > ( Entity < T > _ 1 , InspectorWindow _ 2 )
public static void ClearStorageOnRemove < T > ( Entity < T > _ 1 , InspectorWindow _ 2 )
{
{
// TODO: Clear out settings store for the window.
// TODO: Clear out settings store for the window.
@ -157,9 +180,9 @@ public partial class EntityInspector
private static void ActionBarAndPath < T > ( Entity < T > window , History ? history , Entity < T > ? selected )
private static void ActionBarAndPath < T > ( Entity < T > window , History ? history , Entity < T > ? selected )
{
{
static bool IconButtonWithToolTip ( string icon , string tooltip , bool enabled = true ) {
static bool IconButtonWithToolTip ( char icon , string tooltip , bool enabled = true ) {
if ( ! enabled ) ImGui . BeginDisabled ( ) ;
if ( ! enabled ) ImGui . BeginDisabled ( ) ;
var clicked = ImGui . Button ( icon ) ;
var clicked = ImGui . Button ( icon . ToString ( ) ) ;
if ( ! enabled ) ImGui . EndDisabled ( ) ;
if ( ! enabled ) ImGui . EndDisabled ( ) ;
if ( ImGui . IsItemHovered ( ImGuiHoveredFlags . AllowWhenDisabled ) )
if ( ImGui . IsItemHovered ( ImGuiHoveredFlags . AllowWhenDisabled ) )
ImGui . SetTooltip ( tooltip ) ;
ImGui . SetTooltip ( tooltip ) ;
@ -173,23 +196,23 @@ public partial class EntityInspector
ImGui . TableSetupColumn ( "Entity" , ImGuiTableColumnFlags . WidthFixed ) ;
ImGui . TableSetupColumn ( "Entity" , ImGuiTableColumnFlags . WidthFixed ) ;
ImGui . TableNextColumn ( ) ;
ImGui . TableNextColumn ( ) ;
var hasExpanded = window . Has < Expanded , C ore. Wildcard > ( ) ;
var hasExpanded = window . Has < Expanded , flecs . c ore. Wildcard > ( ) ;
if ( IconButtonWithToolTip ( Icon . Outdent , "Collapse all items in the Explorer View" , hasExpanded ) )
if ( IconButtonWithToolTip ( ForkAwesome . Outdent , "Collapse all items in the Explorer View" , hasExpanded ) )
window . Remove < Expanded , C ore. Wildcard > ( ) ;
window . Remove < Expanded , flecs . c ore. Wildcard > ( ) ;
if ( history ! = null ) {
if ( history ! = null ) {
var hasPrev = ( ( selected ! = null ) ? history . Current ? . Prev : history . Current ) ! = null ;
var hasPrev = ( ( selected ! = null ) ? history . Current ? . Prev : history . Current ) ! = null ;
var hasNext = history . Current ? . Next ! = null ;
var hasNext = history . Current ? . Next ! = null ;
ImGui . SameLine ( ) ;
ImGui . SameLine ( ) ;
if ( IconButtonWithToolTip ( Icon . ArrowLeft , "Go to the previously viewed entity" , hasPrev ) )
if ( IconButtonWithToolTip ( ForkAwesome . ArrowLeft , "Go to the previously viewed entity" , hasPrev ) )
GoToPrevious ( window , history , selected ) ;
GoToPrevious ( window , history , selected ) ;
ImGui . SameLine ( ) ;
ImGui . SameLine ( ) ;
if ( IconButtonWithToolTip ( Icon . ArrowRight , "Go to the next viewed entity" , hasNext ) )
if ( IconButtonWithToolTip ( ForkAwesome . ArrowRight , "Go to the next viewed entity" , hasNext ) )
GoToNext ( window , history ) ;
GoToNext ( window , history ) ;
}
}
ImGui . SameLine ( ) ;
ImGui . SameLine ( ) ;
if ( IconButtonWithToolTip ( Icon . Crosshairs , "Scroll to the current entity in the Explorer View" , ( selected ! = null ) ) )
if ( IconButtonWithToolTip ( ForkAwesome . Crosshairs , "Scroll to the current entity in the Explorer View" , ( selected ! = null ) ) )
window . Add < ScrollToSelected > ( ) ;
window . Add < ScrollToSelected > ( ) ;
ImGui . TableNextColumn ( ) ;
ImGui . TableNextColumn ( ) ;
@ -197,22 +220,22 @@ public partial class EntityInspector
PathInput ( window , history , selected , availableWidth ) ;
PathInput ( window , history , selected , availableWidth ) ;
ImGui . TableNextColumn ( ) ;
ImGui . TableNextColumn ( ) ;
if ( IconButtonWithToolTip ( Icon . PlusCircle , "Create a new child entity" , ( selected ! = null ) ) )
if ( IconButtonWithToolTip ( ForkAwesome . PlusCircle , "Create a new child entity" , ( selected ! = null ) ) )
SetSelected ( window , history , selected ? . NewChild ( ) . Build ( ) ) ;
SetSelected ( window , history , selected ? . NewChild ( ) . Build ( ) ) ;
ImGui . SameLine ( ) ;
ImGui . SameLine ( ) ;
if ( IconButtonWithToolTip ( Icon . Pencil , "Rename the current entity" , false & & ( selected ! = null ) ) )
if ( IconButtonWithToolTip ( ForkAwesome . Pencil , "Rename the current entity" , false & & ( selected ! = null ) ) )
{ } // TODO: Implement this!
{ } // TODO: Implement this!
ImGui . SameLine ( ) ;
ImGui . SameLine ( ) ;
var isDisabled = ( selected ? . IsDisabled = = true ) ;
var isDisabled = ( selected ? . IsDisabled = = true ) ;
var icon = ! isDisabled ? Icon . BellSlash : Icon . Bell ;
var icon = ! isDisabled ? ForkAwesome . BellSlash : ForkAwesome . Bell ;
var tooltip = $"{(!isDisabled ? " Disable " : " Enable ")} the current entity" ;
var tooltip = $"{(!isDisabled ? " Disable " : " Enable ")} the current entity" ;
if ( IconButtonWithToolTip ( icon , tooltip , ( selected ! = null ) ) )
if ( IconButtonWithToolTip ( icon , tooltip , ( selected ! = null ) ) )
{ if ( isDisabled ) selected ? . Enable ( ) ; else selected ? . Disable ( ) ; }
{ if ( isDisabled ) selected ? . Enable ( ) ; else selected ? . Disable ( ) ; }
ImGui . SameLine ( ) ;
ImGui . SameLine ( ) ;
if ( IconButtonWithToolTip ( Icon . Trash , "Delete the current entity" , ( selected ! = null ) ) ) {
if ( IconButtonWithToolTip ( ForkAwesome . Trash , "Delete the current entity" , ( selected ! = null ) ) ) {
// TODO: Delete history for deleted entity?
// TODO: Delete history for deleted entity?
SetSelected ( window , history , selected ? . Parent ) ;
SetSelected ( window , history , selected ? . Parent ) ;
selected ? . Delete ( ) ; // TODO: Confirmation dialog?
selected ? . Delete ( ) ; // TODO: Confirmation dialog?
@ -350,10 +373,10 @@ public partial class EntityInspector
// nullable, so let's be explicit about the type here.
// nullable, so let's be explicit about the type here.
var world = window . World ;
var world = window . World ;
var Wildcard = world . Entity < C ore. Wildcard > ( ) . Value ;
var Wildcard = world . Entity < flecs . c ore. Wildcard > ( ) . Value ;
var Any = world . Entity < C ore. Any > ( ) . Value ;
var Any = world . Entity < flecs . c ore. Any > ( ) . Value ;
var This = world . Entity < C ore. This > ( ) . Value ;
var This = world . Entity < flecs . c ore. This > ( ) . Value ;
var Variable = world . Entity < C ore. Variable > ( ) . Value ;
var Variable = world . Entity < flecs . c ore. Variable > ( ) . Value ;
bool IsSpecialEntity ( Entity entity )
bool IsSpecialEntity ( Entity entity )
= > ( entity = = Wildcard ) | | ( entity = = Any )
= > ( entity = = Wildcard ) | | ( entity = = Any )
| | ( entity = = This ) | | ( entity = = Variable ) ;
| | ( entity = = This ) | | ( entity = = Variable ) ;
@ -361,9 +384,9 @@ public partial class EntityInspector
var expId = world . Entity < Expanded > ( ) . NumericId ;
var expId = world . Entity < Expanded > ( ) . NumericId ;
List < IExplorerEntry > GetEntries ( Entity ? parent ) {
List < IExplorerEntry > GetEntries ( Entity ? parent ) {
var result = new List < IExplorerEntry > ( ) ;
var result = new List < IExplorerEntry > ( ) ;
using var rule = new Rule < T > ( world , new (
using var rule = world . Rule ( new (
$"(ChildOf, {parent?.NumericId ?? 0})" // Must be child of parent, or root entity.
$"(ChildOf, {parent?.NumericId ?? 0})" // Must be child of parent, or root entity.
+ $",?{expId}({window.NumericId}, $T his)" // Whether entity is expanded in explorer view.
+ $",?{expId}({window.NumericId}, $t his)" // Whether entity is expanded in explorer view.
+ $",?Disabled" // Don't filter out disabled entities.
+ $",?Disabled" // Don't filter out disabled entities.
) ) ;
) ) ;
foreach ( var iter in rule . Iter ( ) ) {
foreach ( var iter in rule . Iter ( ) ) {
@ -372,7 +395,7 @@ public partial class EntityInspector
for ( var i = 0 ; i < iter . Count ; i + + ) {
for ( var i = 0 ; i < iter . Count ; i + + ) {
var entity = iter . Entity ( i ) ;
var entity = iter . Entity ( i ) ;
var count = IsSpecialEntity ( entity ) ? 0
var count = IsSpecialEntity ( entity ) ? 0
: world . Pair < C ore. ChildOf > ( entity ) . Count ;
: world . Pair < flecs . c ore. ChildOf > ( entity ) . Count ;
result . Add ( new ExplorerEntry < T > ( entity , count , isExpanded , isDisabled ) ) ;
result . Add ( new ExplorerEntry < T > ( entity , count , isExpanded , isDisabled ) ) ;
}
}
}
}
@ -456,7 +479,7 @@ public partial class EntityInspector
private static void ComponentsTab < T > ( Entity < T > window , History ? history , Entity < T > ? sel )
private static void ComponentsTab < T > ( Entity < T > window , History ? history , Entity < T > ? sel )
{
{
if ( sel is not Entity < T > selected ) return ;
if ( sel is not Entity < T > selected ) return ;
var ChildOf = window . World . Entity < C ore. ChildOf > ( ) ;
var ChildOf = window . World . Entity < flecs . c ore. ChildOf > ( ) ;
foreach ( var id in selected . Type ) {
foreach ( var id in selected . Type ) {
// Hide ChildOf relations, as they are visible in the explorer.
// Hide ChildOf relations, as they are visible in the explorer.
if ( id . IsPair & & ( id . Value . RelationUnsafe = = ChildOf ) ) continue ;
if ( id . IsPair & & ( id . Value . RelationUnsafe = = ChildOf ) ) continue ;
@ -468,16 +491,16 @@ public partial class EntityInspector
{
{
if ( sel is not Entity < T > selected ) return ;
if ( sel is not Entity < T > selected ) return ;
var world = window . World ;
var world = window . World ;
var ChildOf = world . Entity < C ore. ChildOf > ( ) ;
var ChildOf = world . Entity < flecs . c ore. ChildOf > ( ) ;
var Wildcard = world . Entity < C ore. Wildcard > ( ) ;
var Wildcard = world . Entity < flecs . c ore. Wildcard > ( ) ;
if ( ImGui . CollapsingHeader ( $"As {Icon .Tag} Component" , ImGuiTreeNodeFlags . DefaultOpen ) )
if ( ImGui . CollapsingHeader ( $"As {ForkAwesome .Tag} Component" , ImGuiTreeNodeFlags . DefaultOpen ) )
foreach ( var iter in Iterator < T > . FromTerm ( world , new ( selected ) ) )
foreach ( var iter in world . Term ( new ( selected ) ) )
for ( var i = 0 ; i < iter . Count ; i + + )
for ( var i = 0 ; i < iter . Count ; i + + )
RenderEntity ( window , history , iter . Entity ( i ) ) ;
RenderEntity ( window , history , iter . Entity ( i ) ) ;
if ( ImGui . CollapsingHeader ( $"As {Icon .ShareAlt} Relation" , ImGuiTreeNodeFlags . DefaultOpen ) )
if ( ImGui . CollapsingHeader ( $"As {ForkAwesome .ShareAlt} Relation" , ImGuiTreeNodeFlags . DefaultOpen ) )
foreach ( var iter in Iterator < T > . FromTerm ( world , new ( selected , Wildcard ) ) ) {
foreach ( var iter in world . Term ( new ( selected , Wildcard ) ) ) {
var id = iter . FieldId ( 1 ) ;
var id = iter . FieldId ( 1 ) ;
if ( id . AsPair ( ) is not ( Entity < T > relation , Entity < T > target ) ) throw new InvalidOperationException ( ) ;
if ( id . AsPair ( ) is not ( Entity < T > relation , Entity < T > target ) ) throw new InvalidOperationException ( ) ;
if ( relation = = ChildOf ) continue ; // Hide ChildOf relations.
if ( relation = = ChildOf ) continue ; // Hide ChildOf relations.
@ -489,8 +512,8 @@ public partial class EntityInspector
}
}
}
}
if ( ImGui . CollapsingHeader ( $"As {Icon .Bullseye} Target" , ImGuiTreeNodeFlags . DefaultOpen ) )
if ( ImGui . CollapsingHeader ( $"As {ForkAwesome .Bullseye} Target" , ImGuiTreeNodeFlags . DefaultOpen ) )
foreach ( var iter in Iterator < T > . FromTerm ( world , new ( Wildcard , selected ) ) ) {
foreach ( var iter in world . Term ( new ( Wildcard , selected ) ) ) {
var id = iter . FieldId ( 1 ) ;
var id = iter . FieldId ( 1 ) ;
if ( id . AsPair ( ) is not ( Entity < T > relation , Entity < T > target ) ) throw new InvalidOperationException ( ) ;
if ( id . AsPair ( ) is not ( Entity < T > relation , Entity < T > target ) ) throw new InvalidOperationException ( ) ;
if ( relation = = ChildOf ) continue ; // Hide ChildOf relations.
if ( relation = = ChildOf ) continue ; // Hide ChildOf relations.
@ -521,7 +544,7 @@ public partial class EntityInspector
if ( fill ) ImGui . SetNextItemWidth ( - float . Epsilon ) ;
if ( fill ) ImGui . SetNextItemWidth ( - float . Epsilon ) ;
}
}
Column ( $"{Icon .Tag} Display Name" , "" "
Column ( $"{ForkAwesome .Tag} Display Name" , "" "
A display name for this entity .
A display name for this entity .
Names in the entity hierarchy must be unique within the parent entity ,
Names in the entity hierarchy must be unique within the parent entity ,
This doesn ' t apply to display names - they are mostly informational .
This doesn ' t apply to display names - they are mostly informational .
@ -532,7 +555,7 @@ public partial class EntityInspector
selected ? . SetDocName ( ( name . Length > 0 ) ? name : null ) ;
selected ? . SetDocName ( ( name . Length > 0 ) ? name : null ) ;
if ( ! hasSelected ) ImGui . EndDisabled ( ) ;
if ( ! hasSelected ) ImGui . EndDisabled ( ) ;
Column ( $"{Icon .Comment} Description" ,
Column ( $"{ForkAwesome .Comment} Description" ,
"A brief description of this entity." ) ;
"A brief description of this entity." ) ;
if ( ! hasSelected ) ImGui . BeginDisabled ( ) ;
if ( ! hasSelected ) ImGui . BeginDisabled ( ) ;
var brief = selected ? . GetDocBrief ( ) ? ? "" ;
var brief = selected ? . GetDocBrief ( ) ? ? "" ;
@ -540,7 +563,7 @@ public partial class EntityInspector
selected ? . SetDocBrief ( ( brief . Length > 0 ) ? brief : null ) ;
selected ? . SetDocBrief ( ( brief . Length > 0 ) ? brief : null ) ;
if ( ! hasSelected ) ImGui . EndDisabled ( ) ;
if ( ! hasSelected ) ImGui . EndDisabled ( ) ;
Column ( $"{Icon .FileText} Documentation" , "" "
Column ( $"{ForkAwesome .FileText} Documentation" , "" "
A detailed description , or full documentation , of this entity ' s purpose and behaviors .
A detailed description , or full documentation , of this entity ' s purpose and behaviors .
It ' s encouraged to use multiple paragraphs and markdown formatting if necessary .
It ' s encouraged to use multiple paragraphs and markdown formatting if necessary .
"" ");
"" ");
@ -556,7 +579,7 @@ public partial class EntityInspector
selected ? . SetDocDetail ( ( detail . Length > 0 ) ? detail : null ) ;
selected ? . SetDocDetail ( ( detail . Length > 0 ) ? detail : null ) ;
if ( ! hasSelected ) ImGui . EndDisabled ( ) ;
if ( ! hasSelected ) ImGui . EndDisabled ( ) ;
Column ( $"{Icon .Link} Link" , "" "
Column ( $"{ForkAwesome .Link} Link" , "" "
A link to a website relating to this entity , such as
A link to a website relating to this entity , such as
a module ' s repository , or further documentation .
a module ' s repository , or further documentation .
"" ");
"" ");
@ -566,7 +589,7 @@ public partial class EntityInspector
selected ? . SetDocLink ( ( link . Length > 0 ) ? link : null ) ;
selected ? . SetDocLink ( ( link . Length > 0 ) ? link : null ) ;
if ( ! hasSelected ) ImGui . EndDisabled ( ) ;
if ( ! hasSelected ) ImGui . EndDisabled ( ) ;
Column ( $"{Icon .PaintBrush} Color" , "" "
Column ( $"{ForkAwesome .PaintBrush} Color" , "" "
A custom color to represent this entity .
A custom color to represent this entity .
Used in the entity inspector ' s explorer view .
Used in the entity inspector ' s explorer view .
"" ", false);
"" ", false);
@ -607,7 +630,7 @@ public partial class EntityInspector
bool scrollTo = true ) // Should entity be scrolled to in the explorer view?
bool scrollTo = true ) // Should entity be scrolled to in the explorer view?
{
{
if ( entity is Entity < T > e1 ) window . Add < Selected > ( e1 ) ;
if ( entity is Entity < T > e1 ) window . Add < Selected > ( e1 ) ;
else window . Remove < Selected , C ore. Wildcard > ( ) ;
else window . Remove < Selected , flecs . c ore. Wildcard > ( ) ;
for ( var p = entity ? . Parent ; p is Entity < T > parent ; p = parent . Parent )
for ( var p = entity ? . Parent ; p is Entity < T > parent ; p = parent . Parent )
window . Add < Expanded > ( parent ) ;
window . Add < Expanded > ( parent ) ;
@ -647,9 +670,9 @@ public partial class EntityInspector
private static ( Entity < T > ? DisplayType , float Priority ) FindDisplayType < T > ( Entity < T > entity )
private static ( Entity < T > ? DisplayType , float Priority ) FindDisplayType < T > ( Entity < T > entity )
{
{
var world = entity . World ;
var world = entity . World ;
var component = world . Entity < C ore. Component > ( ) ;
var component = world . Entity < flecs . c ore. Component > ( ) ;
var rule = ( Rule < T > ) ( _f indDisplayTypeRule ? ? = new Rule < T > ( world , new (
var rule = ( Rule < T > ) ( _f indDisplayTypeRule ? ? = world . Rule ( new (
$"$Type, gaemstone.Doc.DisplayType($Type)" ) ) ) ;
$"$Type, gaemstone.Doc.DisplayType($Type)" ) ) ) ;
var typeVar = rule . Variables [ "Type" ] ! ;
var typeVar = rule . Variables [ "Type" ] ! ;
@ -658,9 +681,9 @@ public partial class EntityInspector
foreach ( var iter in rule . Iter ( ) . SetVar ( rule . ThisVar ! , entity ) )
foreach ( var iter in rule . Iter ( ) . SetVar ( rule . ThisVar ! , entity ) )
for ( var i = 0 ; i < iter . Count ; i + + ) {
for ( var i = 0 ; i < iter . Count ; i + + ) {
var type = iter . GetVar ( typeVar ) ;
var type = iter . GetVar ( typeVar ) ;
if ( ( type = = component ) & & ( entity . GetOrNull < C ore. Component > ( component ) ? . Size = = 0 ) )
if ( ( type = = component ) & & ( entity . GetOrNull < flecs . c ore. Component > ( component ) ? . Size = = 0 ) )
type = world . Entity < C ore. Tag > ( ) ;
type = world . Entity < flecs . c ore. Tag > ( ) ;
var priority = type ? . GetOrNull < Doc Priority> ( ) ? . Value ? ? float . MaxValue ;
var priority = type ? . GetOrNull < Priority > ( ) ? . Value ? ? float . MaxValue ;
if ( priority < = curPriority ) { curType = type ; curPriority = priority ; }
if ( priority < = curPriority ) { curType = type ; curPriority = priority ; }
}
}
@ -706,7 +729,7 @@ public partial class EntityInspector
var ( displayType , _ ) = FindDisplayType ( entity ) ;
var ( displayType , _ ) = FindDisplayType ( entity ) ;
var docColor = Color . TryParseHex ( entity . GetDocColor ( ) ) ? ? Color . TryParseHex ( displayType ? . GetDocColor ( ) ) ;
var docColor = Color . TryParseHex ( entity . GetDocColor ( ) ) ? ? Color . TryParseHex ( displayType ? . GetDocColor ( ) ) ;
var docIcon = entity . GetOrNull < Doc Icon> ( ) ? . Value . ToString ( ) ? ? displayType ? . GetOrNull < Doc Icon> ( ) ? . Value . ToString ( ) ;
var docIcon = entity . GetOrNull < Icon > ( ) ? . Value . ToString ( ) ? ? displayType ? . GetOrNull < Icon > ( ) ? . Value . ToString ( ) ;
var docName = entity . GetDocName ( false ) ;
var docName = entity . GetDocName ( false ) ;
var isDisabled = entity . IsDisabled ;
var isDisabled = entity . IsDisabled ;
@ -749,7 +772,7 @@ public partial class EntityInspector
if ( isHeaderLike ) pos . X + = ImGui . GetStyle ( ) . FramePadding . X ;
if ( isHeaderLike ) pos . X + = ImGui . GetStyle ( ) . FramePadding . X ;
drawList . AddText ( ImGui . GetFont ( ) , ImGui . GetFontSize ( ) , pos , color . RGBA , displayName ) ;
drawList . AddText ( ImGui . GetFont ( ) , ImGui . GetFontSize ( ) , pos , color . RGBA , displayName ) ;
if ( ! isHeaderLike & & canClick & & hovered ) {
if ( ! isHeaderLike & & canClick & & hovered ) {
// Draw a hyperlink-link underscore.
// Draw a hyperlink-link undersflecs. core.
var p1 = pos + new Vector2 ( 0 , size . Y - 1.75f ) ;
var p1 = pos + new Vector2 ( 0 , size . Y - 1.75f ) ;
var p2 = pos + new Vector2 ( size . X , size . Y - 1.75f ) ;
var p2 = pos + new Vector2 ( size . X , size . Y - 1.75f ) ;
if ( docIcon ! = null ) p1 . X + = ImGui . CalcTextSize ( $"{docIcon} " ) . X ;
if ( docIcon ! = null ) p1 . X + = ImGui . CalcTextSize ( $"{docIcon} " ) . X ;