GenericInspector.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. using System.Collections.Generic;
  4. using bs;
  5. namespace bs.Editor
  6. {
  7. /** @addtogroup Inspector
  8. * @{
  9. */
  10. /// <summary>
  11. /// Default implementation of the inspector used when no specified inspector is provided for the type. Inspector
  12. /// displays GUI for all the inspectable fields in the object.
  13. /// </summary>
  14. internal sealed class GenericInspector : Inspector
  15. {
  16. private bool isEmpty = true;
  17. private GenericInspectorDrawer drawer;
  18. /// <inheritdoc/>
  19. internal override void FocusOnField(string path)
  20. {
  21. drawer.FocusOnField(path);
  22. }
  23. /// <inheritdoc/>
  24. protected internal override void Initialize()
  25. {
  26. if (InspectedObject == null)
  27. LoadResource();
  28. Component inspectedComponent = InspectedObject as Component;
  29. drawer = new GenericInspectorDrawer(InspectedObject, new InspectableContext(Persistent, inspectedComponent),
  30. Layout);
  31. isEmpty = drawer.Fields.Count == 0;
  32. base.SetVisible(!isEmpty);
  33. }
  34. /// <inheritdoc/>
  35. protected internal override InspectableState Refresh()
  36. {
  37. return drawer.Refresh();
  38. }
  39. /// <inheritdoc/>
  40. internal override void SetVisible(bool visible)
  41. {
  42. base.SetVisible(!isEmpty && visible);
  43. }
  44. }
  45. /// <summary>
  46. /// Helper class that draws the default inspector elements for an object, with an optional callback to render custom
  47. /// inspectors for certain types.
  48. /// </summary>
  49. internal sealed class GenericInspectorDrawer
  50. {
  51. /// <summary>
  52. /// List of fields created and updated by the drawer.
  53. /// </summary>
  54. public List<InspectableField> Fields { get; } = new List<InspectableField>();
  55. /// <summary>
  56. /// Creates new generic inspector field drawer for the specified object.
  57. /// </summary>
  58. /// <param name="obj">Object whose fields to create the GUI for.</param>
  59. /// <param name="context">Context shared by all inspectable fields created by the same parent.</param>
  60. /// <param name="layout">Parent layout that all the field GUI elements will be added to.</param>
  61. /// <param name="overrideCallback">
  62. /// Optional callback that allows you to override the look of individual fields in the object. If non-null the
  63. /// callback will be called with information about every field in the provided object. If the callback returns
  64. /// non-null that inspectable field will be used for drawing the GUI, otherwise the default inspector field type
  65. /// will be used.
  66. /// </param>
  67. public GenericInspectorDrawer(object obj, InspectableContext context, GUILayoutY layout,
  68. InspectableField.FieldOverrideCallback overrideCallback = null)
  69. {
  70. if (obj == null)
  71. return;
  72. SerializableObject serializableObject = new SerializableObject(obj.GetType(), obj);
  73. Fields = InspectableField.CreateFields(serializableObject, context, "", 0, layout, overrideCallback);
  74. }
  75. /// <summary>
  76. /// Checks if contents of the inspector fields have been modified, and updates them if needed.
  77. /// </summary>
  78. /// <returns>State representing was anything modified between two last calls to <see cref="Refresh"/>.</returns>
  79. public InspectableState Refresh()
  80. {
  81. InspectableState state = InspectableState.NotModified;
  82. int currentIndex = 0;
  83. foreach (var field in Fields)
  84. {
  85. state |= field.Refresh(currentIndex);
  86. currentIndex += field.GetNumLayoutElements();
  87. }
  88. return state;
  89. }
  90. /// <summary>
  91. /// Changes keyboard focus to the provided field.
  92. /// </summary>
  93. /// <param name="path">Path to the field on the object being inspected.</param>
  94. public void FocusOnField(string path)
  95. {
  96. InspectableField field = InspectableField.FindPath(path, 0, Fields);
  97. field?.SetHasFocus();
  98. }
  99. }
  100. /** @} */
  101. }