namespace Mapbox.Editor { using System.Collections.Generic; using UnityEngine; using UnityEditor.IMGUI.Controls; using UnityEditor; using Mapbox.Unity.Map; internal class FeatureSubLayerTreeView : TreeViewWithTreeModel { public SerializedProperty Layers; private float kToggleWidth = 18f; public int uniqueId; public static int uniqueIdPoI = 1000; public static int uniqueIdFeature = 3000; public int maxElementsAdded = 0; public bool hasChanged = false; const float kRowHeights = 15f; const float nameOffset = 15f; MultiColumnHeaderState m_MultiColumnHeaderState; private GUIStyle columnStyle = new GUIStyle() { alignment = TextAnchor.MiddleCenter, normal = new GUIStyleState() { textColor = Color.white } }; public FeatureSubLayerTreeView(TreeViewState state, MultiColumnHeader multicolumnHeader, TreeModel model, int uniqueIdentifier = 3000) : base(state, multicolumnHeader, model) { showAlternatingRowBackgrounds = true; showBorder = true; customFoldoutYOffset = (kRowHeights - EditorGUIUtility.singleLineHeight) * 0.5f; // center foldout in the row since we also center content. See RowGUI extraSpaceBeforeIconAndLabel = kToggleWidth; uniqueId = uniqueIdentifier; Reload(); } protected override bool CanRename(TreeViewItem item) { // Only allow rename if we can show the rename overlay with a certain width (label might be clipped by other columns) Rect renameRect = GetRenameRect(treeViewRect, 0, item); return renameRect.width > 30; } protected override void RenameEnded(RenameEndedArgs args) { if (Layers == null || Layers.arraySize == 0) { return; } if (args.acceptedRename) { var element = treeModel.Find(args.itemID); element.name = string.IsNullOrEmpty(args.newName.Trim()) ? args.originalName : args.newName; element.Name = string.IsNullOrEmpty(args.newName.Trim()) ? args.originalName : args.newName; var layer = Layers.GetArrayElementAtIndex(args.itemID - uniqueId); layer.FindPropertyRelative("coreOptions.sublayerName").stringValue = element.name; Reload(); } } protected override Rect GetRenameRect(Rect rowRect, int row, TreeViewItem item) { Rect cellRect = GetCellRectForTreeFoldouts(rowRect); cellRect.xMin = nameOffset; CenterRectUsingSingleLineHeight(ref cellRect); return base.GetRenameRect(cellRect, row, item); } public void RemoveItemFromTree(int id) { treeModel.RemoveElements(new List() { id }); } public void AddElementToTree(SerializedProperty subLayer) { var name = subLayer.FindPropertyRelative("coreOptions.sublayerName").stringValue; var id = Layers.arraySize - 1 + uniqueId; if (treeModel.Find(id) != null) { Debug.Log(" found one. exiting"); return; } var type = ((PresetFeatureType)subLayer.FindPropertyRelative("presetFeatureType").enumValueIndex).ToString(); FeatureTreeElement element = new FeatureTreeElement(name, 0, id); element.Name = name; element.Type = type; treeModel.AddElement(element, treeModel.root, treeModel.numberOfDataElements - 1); } protected override void RowGUI(RowGUIArgs args) { var rowItem = (TreeViewItem)args.item; for (int i = 0; i < args.GetNumVisibleColumns(); ++i) { CellGUI(args.GetCellRect(i), rowItem, (FeatureSubLayerColumns)args.GetColumn(i), ref args); } } void CellGUI(Rect cellRect, TreeViewItem item, FeatureSubLayerColumns column, ref RowGUIArgs args) { // Center cell rect vertically (makes it easier to place controls, icons etc in the cells) if (Layers == null || Layers.arraySize == 0) { return; } if (Layers.arraySize <= args.item.id - uniqueId) { return; } var layer = Layers.GetArrayElementAtIndex(args.item.id - uniqueId); CenterRectUsingSingleLineHeight(ref cellRect); if (column == FeatureSubLayerColumns.Name) { Rect toggleRect = cellRect; toggleRect.x += GetContentIndent(item); toggleRect.width = kToggleWidth; EditorGUI.BeginChangeCheck(); item.data.isActive = layer.FindPropertyRelative("coreOptions.isActive").boolValue; if (toggleRect.xMax < cellRect.xMax) { item.data.isActive = EditorGUI.Toggle(toggleRect, item.data.isActive); // hide when outside cell rect } layer.FindPropertyRelative("coreOptions.isActive").boolValue = item.data.isActive; if (EditorGUI.EndChangeCheck()) { VectorSubLayerProperties vectorSubLayerProperties = (VectorSubLayerProperties)EditorHelper.GetTargetObjectOfProperty(layer); EditorHelper.CheckForModifiedProperty(layer, vectorSubLayerProperties.coreOptions); } cellRect.xMin += nameOffset; // Adding some gap between the checkbox and the name args.rowRect = cellRect; layer.FindPropertyRelative("coreOptions.sublayerName").stringValue = item.data.Name; //This draws the name property base.RowGUI(args); } if (column == FeatureSubLayerColumns.Type) { cellRect.xMin += 15f; // Adding some gap between the checkbox and the name var typeString = ((PresetFeatureType)layer.FindPropertyRelative("presetFeatureType").intValue).ToString(); item.data.Type = typeString; EditorGUI.LabelField(cellRect, item.data.Type, columnStyle); } } // All columns enum FeatureSubLayerColumns { Name, Type } public static MultiColumnHeaderState CreateDefaultMultiColumnHeaderState() { var columns = new[] { //Name column new MultiColumnHeaderState.Column { headerContent = new GUIContent("Name"), contextMenuText = "Name", headerTextAlignment = TextAlignment.Center, autoResize = true, canSort = false, allowToggleVisibility = false, }, //Type column new MultiColumnHeaderState.Column { headerContent = new GUIContent("Type"), contextMenuText = "Type", headerTextAlignment = TextAlignment.Center, autoResize = true, canSort = false, allowToggleVisibility = false } }; var state = new MultiColumnHeaderState(columns); return state; } } }