/// <summary> /// Displays a single-option popup where the option list is only built when the dropdown is shown. /// Useful when building the options list is very demanding (e.g. reflection). /// </summary> public static T PopupSingle ( Rect position, GetOptionsCallback getOptions, T selectedValue, DropdownOption <T> noneOption, GUIContent label = null, GUIStyle style = null ) { var selectedOption = new DropdownOption <T>(selectedValue); return(PopupSingle ( position, getOptions, selectedOption, noneOption, label, style )); }
/// <summary> /// Displays a multiple-options popup where the option list is only built when the dropdown is shown. /// Useful when building the options list is very demanding (e.g. reflection). /// Note that not specifying a label will force the options list to be built at every repaint. /// </summary> public static HashSet <T> PopupMultiple ( Rect position, GetOptionsCallback getOptions, HashSet <T> selectedOptions, bool showNothingEverything = true, GUIContent label = null, GUIStyle style = null ) { var hasMultipleDifferentValues = EditorGUI.showMixedValue; IEnumerable <DropdownOption <T> > options = null; // Determine the label text if no override is specified if (label == null) { options = getOptions(); string text; if (hasMultipleDifferentValues) { text = "\u2014"; // Em Dash } else { var selectedOptionsCount = selectedOptions.Count(); var optionsCount = options.Count(); if (selectedOptionsCount == 0) { text = "Nothing"; } else if (selectedOptionsCount == 1) { text = options.First(o => Equal(o.value, selectedOptions.First())).label; } else if (selectedOptionsCount == optionsCount) { text = "Everything"; } else { text = "(Mixed)"; } } label = new GUIContent(text); } // Apply the popup style if no override is specified if (style == null) { style = EditorStyles.popup; } // Render a button and get its control ID var popupClicked = GUI.Button(position, label, style); var popupControlID = GetLastControlID(); if (popupClicked) { // Cancel button click GUI.changed = false; // Assign the currently active control ID activePopupControlID = popupControlID; // Display the dropdown DropdownMultiple ( new Vector2(position.xMin, position.yMax), (values) => { activeMultipleDropdownValues = values; activeDropdownChanged = true; }, options != null ? options : getOptions(), selectedOptions, showNothingEverything ); } if (popupControlID == activePopupControlID && activeDropdownChanged) { GUI.changed = true; activePopupControlID = -1; activeDropdownChanged = false; return(activeMultipleDropdownValues); } else { return(selectedOptions.ToHashSet()); } }
/// <summary> /// Displays a single-option popup where the option list is only built when the dropdown is shown. /// Useful when building the options list is very demanding (e.g. reflection). /// </summary> public static T PopupSingle ( Rect position, GetOptionsCallback getOptions, DropdownOption <T> selectedOption, DropdownOption <T> noneOption, GUIContent label = null, GUIStyle style = null ) { var hasMultipleDifferentValues = EditorGUI.showMixedValue; // Determine the label text if no override is specified if (label == null) { string text; if (hasMultipleDifferentValues) { text = "\u2014"; // Em Dash } else if (selectedOption == null) { if (noneOption != null) { text = noneOption.label; } else { text = string.Empty; } } else { text = selectedOption.label; } label = new GUIContent(text); } // Apply the popup style is no override is specified if (style == null) { style = EditorStyles.popup; } // Render a button and get its control ID var popupClicked = GUI.Button(position, label, style); var popupControlID = GetLastControlID(); if (popupClicked) { // Cancel button click GUI.changed = false; // Assign the active control ID activePopupControlID = popupControlID; // Display the dropdown DropdownSingle ( new Vector2(position.xMin, position.yMax), (value) => { activeSingleDropdownValue = value; activeDropdownChanged = true; }, getOptions(), selectedOption, noneOption ); } if (popupControlID == activePopupControlID && activeDropdownChanged) { // Selected option changed // TODO: Use EditorWindow.SendEvent like EditorGUI.PopupCallbackInfo does. // Otherwise, there seems to be a 1-frame delay in update. GUI.changed = true; activePopupControlID = -1; activeDropdownChanged = false; return(activeSingleDropdownValue); } else if (selectedOption == null) { // Selected option is null if (noneOption != null) { return(noneOption.value); } else { return(default(T)); } } else { return(selectedOption.value); } }