//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
//**************** Copyright (c) 2016 Marko Pintera (marko.pintera@gmail.com). All rights reserved. **********************//
using System.Collections.Generic;
using bs;
namespace bs.Editor
{
/** @addtogroup Inspector
* @{
*/
///
/// Default implementation of the inspector used when no specified inspector is provided for the type. Inspector
/// displays GUI for all the inspectable fields in the object.
///
internal sealed class GenericInspector : Inspector
{
private bool isEmpty = true;
private GenericInspectorDrawer drawer;
///
internal override void FocusOnField(string path)
{
drawer.FocusOnField(path);
}
///
protected internal override void Initialize()
{
if (InspectedObject == null)
LoadResource();
Component inspectedComponent = InspectedObject as Component;
drawer = new GenericInspectorDrawer(InspectedObject, new InspectableContext(Persistent, inspectedComponent),
Layout);
isEmpty = drawer.Fields.Count == 0;
base.SetVisible(!isEmpty);
}
///
protected internal override InspectableState Refresh()
{
return drawer.Refresh();
}
///
internal override void SetVisible(bool visible)
{
base.SetVisible(!isEmpty && visible);
}
}
///
/// Helper class that draws the default inspector elements for an object, with an optional callback to render custom
/// inspectors for certain types.
///
internal sealed class GenericInspectorDrawer
{
///
/// List of fields created and updated by the drawer.
///
public List Fields { get; } = new List();
///
/// Creates new generic inspector field drawer for the specified object.
///
/// Object whose fields to create the GUI for.
/// Context shared by all inspectable fields created by the same parent.
/// Parent layout that all the field GUI elements will be added to.
///
/// Optional callback that allows you to override the look of individual fields in the object. If non-null the
/// callback will be called with information about every field in the provided object. If the callback returns
/// non-null that inspectable field will be used for drawing the GUI, otherwise the default inspector field type
/// will be used.
///
public GenericInspectorDrawer(object obj, InspectableContext context, GUILayoutY layout,
InspectableField.FieldOverrideCallback overrideCallback = null)
{
if (obj == null)
return;
SerializableObject serializableObject = new SerializableObject(obj.GetType(), obj);
Fields = InspectableField.CreateFields(serializableObject, context, "", 0, layout, overrideCallback);
}
///
/// Checks if contents of the inspector fields have been modified, and updates them if needed.
///
/// State representing was anything modified between two last calls to .
public InspectableState Refresh()
{
InspectableState state = InspectableState.NotModified;
int currentIndex = 0;
foreach (var field in Fields)
{
state |= field.Refresh(currentIndex);
currentIndex += field.GetNumLayoutElements();
}
return state;
}
///
/// Changes keyboard focus to the provided field.
///
/// Path to the field on the object being inspected.
public void FocusOnField(string path)
{
InspectableField field = InspectableField.FindPath(path, 0, Fields);
field?.SetHasFocus();
}
}
/** @} */
}