Writing a custom inspector for a filetype

Hello,

I’ve been digging around for hours and I’m still not 100% convinced either way what I’d like to do is possible, but I’m hoping to get some guidance.

Goal: I’d like to write a custom Inspector for .ini files.

I’m perfectly comfortable with doing all the parsing, showing the key/values in the inspector, etc. but the key issue I have that I can’t find any information on is if there’s any way to hook my custom inspector to show based on the selected FILE, rather than associating my inspector with a type, so I can kick off my script to create the inspector based on the referenced file.

The closest I’ve gotten so far is to basically duplicate the file by creating a custom Asset object when I go to write the file, then using that Asset as the type argument to the Custom Inspector. This is, while not ideal, an acceptable solution, but I can’t seem to get the custom asset object to successfully get created. The error message thrown doesn’t provide any useful information as to what caused the failure, it just says ‘failed to create asset’. Ever so helpful. :expressionless:

Am I on a wild goose chase, here? Or is there a way I can do this (ideally without a .asset file)?

Most obvious way would be to do it the same way they handle C# files or Shaders but those inspectors derives from “AssetImporterInspector”, which is internal; and I do not even know how the AssetImporer class is suppose to be used for custom assets/ files … so that is a dead-end.

Anyway… I used a “wrapper” to show a custom inspector in the inspector panel for nodes selected in my DiaQ editor and that same idea could be applied here. Only problem is that the ini file will not stay “selected” in the project panel since you are forcing a select of the wrapper object.

All of these are editor scripts …

// IniFileGlobal.cs
[InitializeOnLoad]
public class IniFileGlobal
{
	private static IniFileWrapper wrapper = null;
	private static bool selectionChanged = false;

	static IniFileGlobal()
	{
		Selection.selectionChanged += SelectionChanged;
		EditorApplication.update += Update;
	}

	private static void SelectionChanged()
	{
		selectionChanged = true;
		// can't do the wrapper stuff here. it does not work 
		// when you Selection.activeObject = wrapper
		// so do it in Update
	}

	private static void Update()
	{
		if (selectionChanged == false) return;

		selectionChanged = false;
		if (Selection.activeObject != wrapper)
		{
			string fn = AssetDatabase.GetAssetPath(Selection.activeInstanceID);
			if (fn.ToLower().EndsWith(".ini"))
			{
				if (wrapper == null)
				{
					wrapper = ScriptableObject.CreateInstance<IniFileWrapper>();
					wrapper.hideFlags = HideFlags.DontSave;
				}

				wrapper.fileName = fn;
				Selection.activeObject = wrapper;

				Editor[] ed = Resources.FindObjectsOfTypeAll<IniFileWrapperInspector>();
				if (ed.Length > 0) ed[0].Repaint();
			}
		}
	}
}

// IniFileWrapper.cs 
public class IniFileWrapper: ScriptableObject
{
	[System.NonSerialized] public string fileName; // path is relative to Assets/
}

// IniFileWrapperInspector.cs
[CustomEditor(typeof(IniFileWrapper))]
public class IniFileWrapperInspector: Editor
{
	public override void OnInspectorGUI()
	{
		IniFileWrapper Target = (IniFileWrapper)target;

		GUILayout.Label("Editing: " + Target.fileName);
		GUILayout.Label(".... stuff");
	}
}