Skip to content

Commit

Permalink
Right clicking the Favorites and History lists' icons will now show a…
Browse files Browse the repository at this point in the history
… context menu to quickly select objects from these lists
  • Loading branch information
yasirkula committed Nov 24, 2019
1 parent 7257870 commit 29ba802
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 36 deletions.
22 changes: 12 additions & 10 deletions Plugins/InspectPlus/Editor/CustomProjectWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ public void Show( string directory )
rootDirectory = directory;
}

public CustomProjectWindowDrawer GetTreeView()
{
return treeView;
}

public void Refresh()
{
if( treeView != null )
Expand All @@ -64,11 +69,6 @@ public void OnGUI()

rect = GUILayoutUtility.GetRect( 0, 100000, 0, 100000 );
treeView.OnGUI( rect );

// This happens only when the mouse click is not captured by TreeView
Event e = Event.current;
if( e.type == EventType.MouseDown && e.button == 0 )
treeView.SetSelection( new int[0] );
}
}

Expand Down Expand Up @@ -121,6 +121,8 @@ public void Refresh( string path )

private bool isSearching;

public bool SyncSelection;

public CustomProjectWindowDrawer( TreeViewState state, string rootDirectory ) : base( state )
{
this.rootDirectory = rootDirectory;
Expand Down Expand Up @@ -309,14 +311,13 @@ protected override bool CanBeParent( TreeViewItem item )

protected override void SelectionChanged( IList<int> selectedIds )
{
if( selectedIds == null )
if( !SyncSelection || selectedIds == null )
return;

int[] result = new int[selectedIds.Count];
for( int i = 0; i < selectedIds.Count; i++ )
result[i] = selectedIds[i];
int[] selectionArray = new int[selectedIds.Count];
selectedIds.CopyTo( selectionArray, 0 );

Selection.instanceIDs = result;
Selection.instanceIDs = selectionArray;
}

protected override bool CanRename( TreeViewItem item )
Expand Down Expand Up @@ -344,6 +345,7 @@ protected override void ContextClicked()

protected override void ContextClickedItem( int id )
{
ChangeUnitySelection();
EditorUtility.DisplayPopupMenu( new Rect( Event.current.mousePosition, new Vector2( 0f, 0f ) ), "Assets/", null );
Event.current.Use();
}
Expand Down
4 changes: 3 additions & 1 deletion Plugins/InspectPlus/Editor/InspectPlusSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,11 @@ public static InspectPlusSettings Instance
public bool ShowHistoryByDefault = true;
[Tooltip( "New windows should show object preview area in the Inspector by default (only shown when an object support preview)" )]
public bool ShowPreviewByDefault = false;
[Tooltip( "While inspecting a folder, selecting files/folders inside the folder will update Unity's selection, as well" )]
public bool SyncProjectWindowSelection = true;
[Tooltip( "Selecting an object in Favorites or History will highlight the object in Hierarchy/Project" )]
public bool AutomaticallyPingSelectedObject = true;
[Tooltip( "Clearing the History via context menu will delete the inspected object's History entry, as well" )]
[Tooltip( "Clearing the History via context menu will delete the currently inspected object's History entry, as well" )]
public bool ClearingHistoryRemovesActiveObject = false;

private void OnEnable()
Expand Down
105 changes: 80 additions & 25 deletions Plugins/InspectPlus/Editor/InspectPlusWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,20 @@ private enum ButtonState { Normal = -1, LeftClicked = 0, RightClicked = 1, Middl
private static Rect lastWindowPosition;

// These are not readonly to support serialization of the data
// SerializeField makes history data persist between editor sessions
// SerializeField makes history data persist between editor sessions (unfortunately, only assets persist, not scene objects)
[SerializeField]
private List<Object> history = new List<Object>( 8 );
[SerializeField]
private Object mainObject;

private List<Editor> inspectorDrawers = new List<Editor>( 16 );
private int inspectorDrawerCount;
private Object mainObject;

// Serializing CustomProjectWindow makes the TreeView's state (collapsed entries etc.) persist during domain reload
// Serializing CustomProjectWindow makes the TreeView's state (collapsed entries etc.) persist between editor sessions
[SerializeField]
private CustomProjectWindow projectWindow = new CustomProjectWindow();
private bool showProjectWindow;
private bool syncProjectWindowSelection;

private bool shouldRepositionSelf;
private bool shouldRepaint;
Expand Down Expand Up @@ -132,6 +135,7 @@ private void Awake()
showFavorites = InspectPlusSettings.Instance.ShowFavoritesByDefault;
showHistory = InspectPlusSettings.Instance.ShowHistoryByDefault;
showPreview = InspectPlusSettings.Instance.ShowPreviewByDefault;
syncProjectWindowSelection = InspectPlusSettings.Instance.SyncProjectWindowSelection;

// Window is restored after Unity is closed and then reopened
if( history.Count > 0 )
Expand All @@ -154,27 +158,18 @@ private void OnEnable()
Undo.undoRedoPerformed -= OnUndoRedo;
Undo.undoRedoPerformed += OnUndoRedo;

// Make sure that debug mode drawers are recreated
if( inspectorDrawerCount > 0 )
if( mainObject )
{
try
{
if( inspectorDrawers[0].target )
InspectInternal( inspectorDrawers[0].target, false );
else
{
for( int i = 0; i < inspectorDrawers.Count; i++ )
DestroyImmediate( inspectorDrawers[i] );
// This also makes sure that debug mode drawers are recreated
InspectInternal( mainObject, false );
}
else
{
for( int i = 0; i < inspectorDrawers.Count; i++ )
DestroyImmediate( inspectorDrawers[i] );

inspectorDrawers.Clear();
inspectorDrawerCount = 0;
}
}
catch( NullReferenceException )
{
// Some Editors (like folder editors) might throw NullReferenceException when accessing 'target' in OnEnable
InspectInternal( mainObject, false );
}
inspectorDrawers.Clear();
inspectorDrawerCount = 0;
}

historyHolder.Add( history );
Expand Down Expand Up @@ -203,8 +198,6 @@ private void OnDestroy()

inspectorDrawers.Clear();
inspectorDrawerCount = 0;

mainObject = null;
}

private void OnFocus()
Expand Down Expand Up @@ -379,6 +372,20 @@ void IHasCustomMenu.AddItemsToMenu( GenericMenu menu )
menu.AddItem( new GUIContent( "Debug Mode" ), debugMode, () => debugMode = !debugMode );
menu.AddSeparator( "" );

if( showProjectWindow )
{
menu.AddItem( new GUIContent( "Synchronize Selection" ), syncProjectWindowSelection, () =>
{
syncProjectWindowSelection = !syncProjectWindowSelection;

CustomProjectWindowDrawer treeView = projectWindow.GetTreeView();
if( treeView != null )
treeView.SyncSelection = syncProjectWindowSelection;
} );

menu.AddSeparator( "" );
}

menu.AddItem( new GUIContent( "Clear Favorites" ), false, () =>
{
InspectPlusSettings.Instance.FavoriteAssets.Clear();
Expand Down Expand Up @@ -436,6 +443,34 @@ void IHasCustomMenu.AddItemsToMenu( GenericMenu menu )
} );
}

private void OnScrollViewIconRightClicked( GenericMenu menu, List<List<Object>> lists )
{
List<Object> allObjects = new List<Object>( 8 );
for( int i = 0; i < lists.Count; i++ )
{
List<Object> list = lists[i];
for( int j = 0; j < list.Count; j++ )
{
if( !list[j] )
continue;

// Insert object into sorted list
// Credit: https://stackoverflow.com/a/12172412/2373034
int index = allObjects.BinarySearch( list[j], Utilities.unityObjectComparer );
if( index < 0 )
index = ~index;

allObjects.Insert( index, list[j] );
}
}

for( int i = 0; i < allObjects.Count; i++ )
{
Object obj = allObjects[i];
menu.AddItem( new GUIContent( string.Concat( obj.name, " (", obj.GetType().Name, ")" ) ), false, () => pendingInspectTarget = obj );
}
}

private void OnScrollViewButtonRightClicked( GenericMenu menu, List<Object> list, int index )
{
menu.AddItem( new GUIContent( "Remove" ), false, () => RemoveObjectFromList( list, index ) );
Expand Down Expand Up @@ -582,6 +617,8 @@ private void InspectInternal( Object obj, bool addHistoryEntry )
if( !string.IsNullOrEmpty( assetPath ) && AssetDatabase.IsValidFolder( assetPath ) )
{
projectWindow.Show( assetPath );
projectWindow.GetTreeView().SyncSelection = syncProjectWindowSelection;

showProjectWindow = true;
}
else
Expand Down Expand Up @@ -762,6 +799,14 @@ private void OnGUI()
{
GUILayout.Space( -4 ); // Get rid of the free space above the project window's header
projectWindow.OnGUI();

// This happens only when the mouse click is not captured by project window's TreeView
// In this case, clear project window's selection
if( ev.type == EventType.MouseDown && ev.button == 0 )
{
projectWindow.GetTreeView().SetSelection( new int[0] );
shouldRepaint = true;
}
}

if( showPreview )
Expand Down Expand Up @@ -799,6 +844,14 @@ private Vector2 DrawScrollableList( bool drawingFavorites )

GUILayout.BeginHorizontal();
GUILayout.Label( icon, scrollableListIconGuiStyle, scrollableListIconSize, height );
if( ev.type == EventType.ContextClick && GUILayoutUtility.GetLastRect().Contains( ev.mousePosition ) )
{
GenericMenu menu = new GenericMenu();
OnScrollViewIconRightClicked( menu, lists );
if( menu.GetItemCount() > 0 )
menu.ShowAsContext();
}

scrollPosition = GUILayout.BeginScrollView( scrollPosition, height );
GUILayout.BeginHorizontal();

Expand Down Expand Up @@ -948,8 +1001,10 @@ private ButtonState DraggableButton( GUIContent content, GUIStyle style, Object
if( GUIUtility.hotControl == controlID )
{
GUIUtility.hotControl = 0;
result = (ButtonState) ev.button;
shouldRepaint = true;

if( rect.Contains( ev.mousePosition ) )
result = (ButtonState) ev.button;
}
break;
case EventType.Repaint:
Expand Down
10 changes: 10 additions & 0 deletions Plugins/InspectPlus/Editor/Utilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,20 @@
using System.Reflection;
using System.Text;
using UnityEngine;
using Object = UnityEngine.Object;

namespace InspectPlusNamespace.Extras
{
public static class Utilities
{
public class UnityObjectComparer : IComparer<Object>
{
public int Compare( Object x, Object y )
{
return x.name.CompareTo( y.name );
}
}

private const BindingFlags VARIABLE_BINDING_FLAGS = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly;

private static readonly HashSet<Type> primitiveUnityTypes = new HashSet<Type>()
Expand All @@ -29,6 +38,7 @@ public static class Utilities
private static readonly Dictionary<Type, VariableGetterHolder[]> typeToVariables = new Dictionary<Type, VariableGetterHolder[]>( 1024 );
private static readonly string reflectionNameSpace = typeof( Assembly ).Namespace;
public static readonly StringBuilder stringBuilder = new StringBuilder( 256 );
public static readonly UnityObjectComparer unityObjectComparer = new UnityObjectComparer();

// Get filtered variables for a type
public static VariableGetterHolder[] GetFilteredVariablesForType( Type type )
Expand Down
1 change: 1 addition & 0 deletions Plugins/InspectPlus/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ This plugin helps you view an object's Inspector in a separate tab/window, copy&
3) right clicking a component in the Inspector
- You can right click an object in the History list to add it to the Favorites list
- You can drag&drop objects to the History and Favorites lists to quickly fill these lists
- You can right click the icons of the History and Favorites lists to quickly select an object from these lists
- You can right click variables in the Inspector to copy&paste their values (variables that are not drawn with SerializedProperty don't support this feature)
- You can right click the Inspect+ tab to enable Debug mode: you can inspect all variables of an object in this mode, including static, readonly and non-serializable variables
- You can show the Inspect+ window from your editor scripts by calling the InspectPlusNamespace.InspectPlusWindow.Inspect functions
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ After importing [InspectPlus.unitypackage](https://github.com/yasirkula/UnityIns
- right clicking a component in the Inspector
- You can right click an object in the **History** list to add it to the **Favorites** list
- You can drag&drop objects to the History and Favorites lists to quickly fill these lists
- You can right click the icons of the History and Favorites lists to quickly select an object from these lists
- You can right click variables in the Inspector to copy&paste their values (variables that are not drawn with *SerializedProperty* don't support this feature)
- You can right click the Inspect+ tab to enable **Debug mode**: you can inspect all variables of an object in this mode, including static, readonly and non-serializable variables
- You can show the Inspect+ window from your editor scripts by calling the `InspectPlusNamespace.InspectPlusWindow.Inspect` functions

0 comments on commit 29ba802

Please sign in to comment.