//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
//**************** Copyright (c) 2016 Marko Pintera (marko.pintera@gmail.com). All rights reserved. **********************//
using System.Collections;
using System.Collections.Generic;
using bs;
namespace bs.Editor
{
/** @addtogroup Inspectors
* @{
*/
///
/// Renders an inspector for the component.
///
[CustomInspector(typeof (Renderable))]
internal class RenderableInspector : Inspector
{
private List materialParams = new List();
private List materialVariations = new List();
private RRef[] materials;
private GUILayout materialsLayout;
///
protected internal override void Initialize()
{
Renderable renderable = (Renderable)InspectedObject;
drawer.AddDefault(renderable);
materials = renderable.Materials;
materialsLayout = Layout.AddLayoutY();
BuildMaterialsGUI();
}
///
protected internal override InspectableState Refresh(bool force = false)
{
Renderable renderable = InspectedObject as Renderable;
if (renderable == null)
return InspectableState.NotModified;
bool rebuildMaterialsGUI = false;
RRef[] newMaterials = renderable.Materials;
if (newMaterials == null)
rebuildMaterialsGUI = materials != null;
else
{
if (materials == null)
rebuildMaterialsGUI = true;
else
{
if (materials.Length != newMaterials.Length)
rebuildMaterialsGUI = true;
else
{
for (int i = 0; i < materials.Length; i++)
{
if (materials[i] != newMaterials[i])
{
rebuildMaterialsGUI = true;
break;
}
}
}
}
}
if (rebuildMaterialsGUI)
BuildMaterialsGUI();
if (materials != null)
{
for (int i = 0; i < materialParams.Count; i++)
{
Material material = materials[i].Value;
if (material != null && materialParams[i] != null)
{
foreach (var param in materialParams[i])
param.Refresh(material);
}
}
}
return base.Refresh(force);
}
///
internal override void FocusOnField(string path)
{
if (path.StartsWith("materialParams"))
{
string subPath = InspectableField.GetSubPath(path, 2);
string[] subPathParts = subPath.Split('/');
if (subPathParts.Length < 2)
return;
int lastLeftIdx = subPathParts[0].LastIndexOf('[');
int lastRightIdx = subPathParts[0].LastIndexOf(']', lastLeftIdx);
if (lastLeftIdx == -1 || lastRightIdx == -1)
return;
int count = lastRightIdx - 1 - lastLeftIdx;
if (count <= 0)
return;
string arrayIdxStr = subPath.Substring(lastLeftIdx, count);
if (!int.TryParse(arrayIdxStr, out int idx))
return;
if (idx >= materialParams.Count)
return;
MaterialParamGUI[] entries = materialParams[idx];
foreach (var entry in entries)
{
string fieldSubPath = subPathParts.Length > 2 ? subPathParts[2] : null;
if (entry.Param.name == subPathParts[1])
{
entry.SetHasFocus(fieldSubPath);
break;
}
}
}
base.FocusOnField(path);
}
///
/// Builds the portion of the GUI that displays details about individual materials.
///
private void BuildMaterialsGUI()
{
materialsLayout.Clear();
materialParams.Clear();
materialVariations.Clear();
if (materials != null && materials.Length > 0)
{
for (int i = 0; i < materials.Length; i++)
{
string suffix = "";
if (materials.Length > 1)
suffix = " (" + i + ")";
materialsLayout.AddSpace(10);
GUIToggle foldout = new GUIToggle(new LocEdString("Material parameters" + suffix), EditorStyles.Foldout);
materialsLayout.AddElement(foldout);
GUILayoutY materialLayout = materialsLayout.AddLayoutY();
string tag = "Material" + i + "_Expanded";
foldout.OnToggled += x =>
{
materialLayout.Active = x;
Persistent.SetBool(tag, x);
};
materialLayout.Active = Persistent.GetBool(tag);
Material material = materials[i].Value;
if (material == null)
{
materialParams.Add(new MaterialParamGUI[0]);
continue;
}
MaterialVariationGUI variationGUI = new MaterialVariationGUI(material, materialLayout);
materialVariations.Add(variationGUI);
MaterialParamGUI[] matParams = MaterialInspector.CreateMaterialGUI(material,
"materialParams[" + i + "]", null, materialLayout);
materialParams.Add(matParams);
}
}
}
}
/** @} */
}