//********************************** 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 BansheeEngine; namespace BansheeEditor { /** @addtogroup Inspectors * @{ */ /// /// Renders an inspector for the component. /// [CustomInspector(typeof (Renderable))] internal class RenderableInspector : Inspector { private GUIResourceField meshField; private GUIListBoxField layersField; private GUIArrayField, MaterialArrayRow> materialsField; private List materialParams = new List(); private ulong layersValue = 0; private InspectableState modifyState; private RRef[] materials; private GUILayout materialsLayout; /// protected internal override void Initialize() { BuildGUI(); } /// protected internal override InspectableState Refresh() { 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(); meshField.ValueRef = renderable.Mesh; if (layersValue != renderable.Layers) { bool[] states = new bool[64]; for (int i = 0; i < states.Length; i++) states[i] = (renderable.Layers & Layers.Values[i]) == Layers.Values[i]; layersField.States = states; layersValue = renderable.Layers; } InspectableState materialsModified = materialsField.Refresh(); if (materialsModified == InspectableState.Modified) renderable.Materials = materials; modifyState |= materialsModified; 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); } } } InspectableState oldState = modifyState; if (modifyState.HasFlag(InspectableState.Modified)) modifyState = InspectableState.NotModified; return oldState; } /// /// Recreates all the GUI elements used by this inspector. /// private void BuildGUI() { Layout.Clear(); Renderable renderable = InspectedObject as Renderable; if (renderable == null) return; meshField = new GUIResourceField(typeof(Mesh), new LocEdString("Mesh")); layersField = new GUIListBoxField(Layers.Names, false, new LocEdString("Layer")); Layout.AddElement(meshField); Layout.AddElement(layersField); layersValue = 0; materials = renderable.Materials; materialsField = GUIArrayField, MaterialArrayRow>.Create(new LocEdString("Materials"), materials, Layout); materialsField.OnChanged += x => { materials = x; }; materialsField.IsExpanded = Persistent.GetBool("materialsField_Expanded"); materialsField.OnExpand += x => Persistent.SetBool("materialsField_Expanded", x); meshField.OnChanged += x => { Mesh mesh = Resources.Load(x.UUID); renderable.Mesh = mesh; MarkAsModified(); ConfirmModify(); }; layersField.OnSelectionChanged += x => { ulong layers = 0; bool[] states = layersField.States; for (int i = 0; i < states.Length; i++) layers |= states[i] ? Layers.Values[i] : 0; layersValue = layers; renderable.Layers = layers; MarkAsModified(); ConfirmModify(); }; materialsLayout = Layout.AddLayoutY(); BuildMaterialsGUI(); } /// /// Builds the portion of the GUI that displays details about individual materials. /// private void BuildMaterialsGUI() { materialsLayout.Clear(); materialParams.Clear(); if (materials != null) { for (int i = 0; i < materials.Length; i++) { Material material = materials[i].Value; if (material == null) { materialParams.Add(new MaterialParamGUI[0]); continue; } materialsLayout.AddSpace(10); MaterialParamGUI[] matParams = MaterialInspector.CreateMaterialGUI(material, materialsLayout); materialParams.Add(matParams); } } } /// /// Marks the contents of the inspector as modified. /// protected void MarkAsModified() { modifyState |= InspectableState.ModifyInProgress; } /// /// Confirms any queued modifications. /// protected void ConfirmModify() { if (modifyState.HasFlag(InspectableState.ModifyInProgress)) modifyState |= InspectableState.Modified; } /// /// Row element used for displaying GUI for material array elements. /// private class MaterialArrayRow : GUIListFieldRow { private GUIResourceField materialField; /// protected override GUILayoutX CreateGUI(GUILayoutY layout) { GUILayoutX titleLayout = layout.AddLayoutX(); materialField = new GUIResourceField(typeof(Material), new LocEdString(SeqIndex + ". "), 20); titleLayout.AddElement(materialField); materialField.OnChanged += x => { SetValue(x.As()); MarkAsModified(); ConfirmModify(); }; return titleLayout; } /// internal protected override InspectableState Refresh() { materialField.ValueRef = GetValue>(); return base.Refresh(); } } } /** @} */ }