/// <summary> /// Builds and returns a <see cref="GenericMenu"/> for the given <see cref="EditorMenu"/>. /// </summary> /// <param name="menu">Input menu data structure.</param> /// <returns> /// A new <see cref="GenericMenu"/> instance. /// </returns> public virtual GenericMenu BuildMenu(EditorMenu menu) { var genericMenu = new GenericMenu(); var populatedPaths = new HashSet <string>(); int entryIndex = -1; foreach (var entry in menu.Entries) { ++entryIndex; if (entry.EvaluateIsVisible() == false) { continue; } var separatorEntry = entry as EditorMenuSeparatorEntry; if (separatorEntry != null) { bool isFirstAtPath = !populatedPaths.Contains(entry.Path); if (this.CanAddSeparatorEntryToMenu(menu, entryIndex, entry.Path, isFirstAtPath)) { this.AddSeparatorEntryToMenu(genericMenu, separatorEntry); } continue; } populatedPaths.Add(entry.Path); this.AddEntryToMenu(genericMenu, entry); } return(genericMenu); }
/// <inheritdoc/> public void ShowAsDropdown(Rect position, EditorMenu menu) { var genericMenu = this.BuildMenu(menu); if (genericMenu.GetItemCount() > 0) { genericMenu.DropDown(position); } }
/// <inheritdoc/> public void ShowAsContext(EditorMenu menu) { var genericMenu = this.BuildMenu(menu); if (genericMenu.GetItemCount() > 0) { genericMenu.ShowAsContext(); } }
/// <summary> /// Finds the next visible menu entry at the given path. /// </summary> /// <param name="menu">Input menu data structure.</param> /// <param name="path">Path of the entry.</param> /// <param name="fromEntryIndex">Zero-based index of the starting entry (excluded).</param> /// <returns> /// The next visible <see cref="IEditorMenuEntry"/> instance when found; /// otherwise, a value of <c>null</c>. /// </returns> protected static IEditorMenuEntry FindNextVisibleMenuEntryAtPath(EditorMenu menu, string path, int fromEntryIndex) { for (int entryIndex = fromEntryIndex + 1; entryIndex < menu.Entries.Count; ++entryIndex) { var entry = menu.Entries[entryIndex]; if (entry.Path == path && entry.EvaluateIsVisible()) { return(entry); } } return(null); }
/// <summary> /// Determines whether a separator can be added to the <see cref="GenericMenu"/>. /// </summary> /// <param name="menu">Input menu data structure.</param> /// <param name="entryIndex">Zero-based index of the separator entry.</param> /// <param name="path">Path of the separator entry.</param> /// <param name="isFirstAtPath">Indicates if the separator would be the first /// output entry at that path.</param> /// <returns> /// A value of <c>true</c> if the separator entry can be added to the output /// <see cref="GenericMenu"/>; else, a value of <c>false</c>. /// </returns> protected virtual bool CanAddSeparatorEntryToMenu(EditorMenu menu, int entryIndex, string path, bool isFirstAtPath) { // Don't output separator at the start of a path... it just doesn't look good! if (isFirstAtPath) { return(false); } var nextEntryAtPath = FindNextVisibleMenuEntryAtPath(menu, path, entryIndex); // Don't output separator if no entry follows in same menu path. if (nextEntryAtPath == null) { return(false); } // Don't output separator if next entry is also separator... it doesn't look good! if (nextEntryAtPath is EditorMenuSeparatorEntry) { return(false); } return(true); }