RenderableInspector.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using BansheeEngine;
  4. namespace BansheeEditor
  5. {
  6. /// <summary>
  7. /// Renders an inspector for the <see cref="Renderable"/> component.
  8. /// </summary>
  9. [CustomInspector(typeof (Renderable))]
  10. internal class RenderableInspector : Inspector
  11. {
  12. private GUIResourceField meshField;
  13. private GUIListBoxField layersField;
  14. private GUIArrayField<Material, MaterialArrayRow> materialsField;
  15. private List<MaterialParamGUI[]> materialParams = new List<MaterialParamGUI[]>();
  16. private ulong layersValue = 0;
  17. private InspectableState modifyState;
  18. private Material[] materials;
  19. private GUILayout materialsLayout;
  20. /// <inheritdoc/>
  21. protected internal override void Initialize()
  22. {
  23. BuildGUI();
  24. }
  25. /// <inheritdoc/>
  26. protected internal override InspectableState Refresh()
  27. {
  28. Renderable renderable = InspectedObject as Renderable;
  29. if (renderable == null)
  30. return InspectableState.NotModified;
  31. bool rebuildMaterialsGUI = false;
  32. Material[] newMaterials = renderable.Materials;
  33. if (newMaterials == null)
  34. rebuildMaterialsGUI = materials != null;
  35. else
  36. {
  37. if (materials == null)
  38. rebuildMaterialsGUI = true;
  39. else
  40. {
  41. if (materials.Length != newMaterials.Length)
  42. rebuildMaterialsGUI = true;
  43. else
  44. {
  45. for (int i = 0; i < materials.Length; i++)
  46. {
  47. if (materials[i] != newMaterials[i])
  48. {
  49. rebuildMaterialsGUI = true;
  50. break;
  51. }
  52. }
  53. }
  54. }
  55. }
  56. if (rebuildMaterialsGUI)
  57. BuildMaterialsGUI();
  58. meshField.Value = renderable.Mesh;
  59. if (layersValue != renderable.Layers)
  60. {
  61. bool[] states = new bool[64];
  62. for (int i = 0; i < states.Length; i++)
  63. states[i] = (renderable.Layers & Layers.Values[i]) == Layers.Values[i];
  64. layersField.States = states;
  65. layersValue = renderable.Layers;
  66. }
  67. InspectableState materialsModified = materialsField.Refresh();
  68. if (materialsModified == InspectableState.Modified)
  69. renderable.Materials = materials;
  70. modifyState |= materialsModified;
  71. if (materials != null)
  72. {
  73. for (int i = 0; i < materialParams.Count; i++)
  74. {
  75. if (materialParams[i] != null)
  76. {
  77. foreach (var param in materialParams[i])
  78. param.Refresh(materials[i]);
  79. }
  80. }
  81. }
  82. InspectableState oldState = modifyState;
  83. if (modifyState.HasFlag(InspectableState.Modified))
  84. modifyState = InspectableState.NotModified;
  85. return oldState;
  86. }
  87. /// <summary>
  88. /// Recreates all the GUI elements used by this inspector.
  89. /// </summary>
  90. private void BuildGUI()
  91. {
  92. Layout.Clear();
  93. Renderable renderable = InspectedObject as Renderable;
  94. if (renderable == null)
  95. return;
  96. meshField = new GUIResourceField(typeof(Mesh), new LocEdString("Mesh"));
  97. layersField = new GUIListBoxField(Layers.Names, true, new LocEdString("Layers"));
  98. Layout.AddElement(meshField);
  99. Layout.AddElement(layersField);
  100. layersValue = 0;
  101. materials = renderable.Materials;
  102. materialsField = GUIArrayField<Material, MaterialArrayRow>.Create(new LocEdString("Materials"), materials, Layout);
  103. meshField.OnChanged += x =>
  104. {
  105. renderable.Mesh = x as Mesh;
  106. MarkAsModified();
  107. ConfirmModify();
  108. };
  109. layersField.OnSelectionChanged += x =>
  110. {
  111. ulong layers = 0;
  112. bool[] states = layersField.States;
  113. for (int i = 0; i < states.Length; i++)
  114. layers |= states[i] ? Layers.Values[i] : 0;
  115. layersValue = layers;
  116. renderable.Layers = layers;
  117. MarkAsModified();
  118. ConfirmModify();
  119. };
  120. materialsLayout = Layout.AddLayoutY();
  121. BuildMaterialsGUI();
  122. }
  123. /// <summary>
  124. /// Builds the portion of the GUI that displays details about individual materials.
  125. /// </summary>
  126. private void BuildMaterialsGUI()
  127. {
  128. materialsLayout.Clear();
  129. materialParams.Clear();
  130. if (materials != null)
  131. {
  132. for (int i = 0; i < materials.Length; i++)
  133. {
  134. if (materials[i] == null)
  135. {
  136. materialParams.Add(new MaterialParamGUI[0]);
  137. continue;
  138. }
  139. materialsLayout.AddSpace(10);
  140. MaterialParamGUI[] matParams = MaterialInspector.CreateMaterialGUI(materials[i], materialsLayout);
  141. materialParams.Add(matParams);
  142. }
  143. }
  144. }
  145. /// <summary>
  146. /// Marks the contents of the inspector as modified.
  147. /// </summary>
  148. protected void MarkAsModified()
  149. {
  150. modifyState |= InspectableState.ModifyInProgress;
  151. }
  152. /// <summary>
  153. /// Confirms any queued modifications.
  154. /// </summary>
  155. protected void ConfirmModify()
  156. {
  157. if (modifyState.HasFlag(InspectableState.ModifyInProgress))
  158. modifyState |= InspectableState.Modified;
  159. }
  160. /// <summary>
  161. /// Row element used for displaying GUI for material array elements.
  162. /// </summary>
  163. public class MaterialArrayRow : GUIListFieldRow
  164. {
  165. private GUIResourceField materialField;
  166. /// <inheritdoc/>
  167. protected override GUILayoutX CreateGUI(GUILayoutY layout)
  168. {
  169. GUILayoutX titleLayout = layout.AddLayoutX();
  170. materialField = new GUIResourceField(typeof(Material), new LocEdString(SeqIndex + ". "), 20);
  171. titleLayout.AddElement(materialField);
  172. materialField.OnChanged += x =>
  173. {
  174. SetValue(x);
  175. MarkAsModified();
  176. ConfirmModify();
  177. };
  178. return titleLayout;
  179. }
  180. /// <inheritdoc/>
  181. internal protected override InspectableState Refresh()
  182. {
  183. materialField.Value = GetValue<Material>();
  184. return base.Refresh();
  185. }
  186. }
  187. }
  188. }