Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: menu name may use string field #1008

Merged
merged 5 commits into from
Dec 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 70 additions & 5 deletions Editor/Inspector/Menu/MenuItemGUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ internal static ImmutableList<ProvidedParameter> GetParametersForObject(GameObje

internal class MenuItemCoreGUI
{
private const string ImpliesRichText = "<";

private static readonly ObjectIDGenerator IdGenerator = new ObjectIDGenerator();
private readonly GameObject _parameterReference;
private readonly Action _redraw;
Expand Down Expand Up @@ -92,11 +94,14 @@ internal class MenuItemCoreGUI
private readonly SerializedProperty _prop_isDefault;
private readonly SerializedProperty _prop_automaticValue;

private readonly SerializedProperty _prop_label;

public bool AlwaysExpandContents = false;
public bool ExpandContents = false;

private readonly Dictionary<string, ProvidedParameter> _knownParameters = new();
private bool _parameterSourceNotDetermined;
private bool _useLabel;

public MenuItemCoreGUI(SerializedObject obj, Action redraw)
{
Expand Down Expand Up @@ -144,6 +149,8 @@ public MenuItemCoreGUI(SerializedObject obj, Action redraw)
_prop_isDefault = obj.FindProperty(nameof(ModularAvatarMenuItem.isDefault));
_prop_automaticValue = obj.FindProperty(nameof(ModularAvatarMenuItem.automaticValue));

_prop_label = obj.FindProperty(nameof(ModularAvatarMenuItem.label));

_previewGUI = new MenuPreviewGUI(redraw);
}

Expand Down Expand Up @@ -260,11 +267,69 @@ public void DoGUI()
EditorGUILayout.BeginHorizontal();

EditorGUILayout.BeginVertical();
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(_name, G("menuitem.prop.name"));
if (EditorGUI.EndChangeCheck())

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One note: Please make sure this doesn't break in some terrible way when multiple items are selected...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm stuck on this, I can't figure out how to properly handle multi-editing. Best I can do right now is to maintain the current behaviour where it just edits the GameObject name

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's maybe better to multi-edit the label field in that case. Seems like less surprising behavior than editing the name of all the GameObjects at once?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be current behaviour as of the latest commit

EditorGUILayout.BeginHorizontal();

if (_parameterReference == null)
{
_name.serializedObject.ApplyModifiedProperties();
EditorGUI.BeginChangeCheck();
if (_obj != null && _obj.isEditingMultipleObjects)
{
EditorGUILayout.PropertyField(_prop_label, G("menuitem.prop.name"));
}
else
{
EditorGUILayout.PropertyField(_name, G("menuitem.prop.name"));
}
if (EditorGUI.EndChangeCheck())
{
_name.serializedObject.ApplyModifiedProperties();
}
}
else
{
_useLabel |= !string.IsNullOrEmpty(_prop_label.stringValue);

if (!_useLabel)
{
EditorGUI.BeginChangeCheck();
var previousName = _name.stringValue;
EditorGUILayout.PropertyField(_name, G("menuitem.prop.name"));
if (EditorGUI.EndChangeCheck())
{
if (!previousName.Contains(ImpliesRichText) && _name.stringValue.Contains(ImpliesRichText))
{
_prop_label.stringValue = _name.stringValue;
}
else
{
_name.serializedObject.ApplyModifiedProperties();
}
}
}
else
{
EditorGUILayout.PropertyField(_prop_label, G("menuitem.prop.name"));
}

var linkIcon = EditorGUIUtility.IconContent(_useLabel ? "UnLinked" : "Linked").image;
var guiIcon = new GUIContent(linkIcon, S(_useLabel ? "menuitem.label.gameobject_name.tooltip" : "menuitem.label.long_name.tooltip"));
if (GUILayout.Button(guiIcon, GUILayout.Height(EditorGUIUtility.singleLineHeight), GUILayout.Width(25)))
{
_prop_label.stringValue = !_useLabel ? _name.stringValue : "";
_useLabel = !_useLabel;
}
Comment on lines +317 to +321
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's some confusing behavior that occurs when you do the following:

  • Unlink a menu item
  • Update its name
  • Relink it by clicking the link button

Expected behavior: The displayed name in the inspector should match the game object name.

Actual behavior: The displayed name in the inspector is the old label value, until you change focus away from the name field (at which point it'll reset to the gameobject name).

}

EditorGUILayout.EndHorizontal();

if (_useLabel && _prop_label.stringValue.Contains(ImpliesRichText))
{
var style = new GUIStyle(EditorStyles.textField);
style.richText = true;
style.alignment = TextAnchor.MiddleCenter;

EditorGUILayout.LabelField(" ", _prop_label.stringValue, style, GUILayout.Height(EditorGUIUtility.singleLineHeight * 3));
}

EditorGUILayout.PropertyField(_texture, G("menuitem.prop.icon"));
Expand All @@ -274,7 +339,7 @@ public void DoGUI()
_parameterGUI.DoGUI(true);

ShowInnateParameterGUI();

EditorGUILayout.EndVertical();

if (_texture != null)
Expand Down
5 changes: 5 additions & 0 deletions Editor/Localization/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,10 @@
"ro_sim.effect_group.rule_inverted": "This rule is inverted",
"ro_sim.effect_group.rule_inverted.tooltip": "This rule will be applied when one of its conditions is NOT met",
"ro_sim.effect_group.conditions": "Conditions",

"menuitem.label.long_name.tooltip": "Use a long name which may contain rich text and line breaks.",
"menuitem.label.gameobject_name.tooltip": "Use the GameObject name.",

"remove-vertex-color.mode": "Mode",
"remove-vertex-color.mode.Remove": "Remove Vertex Colors",
"remove-vertex-color.mode.DontRemove": "Keep Vertex Colors",
Expand All @@ -296,4 +300,5 @@
"sync-param-sequence.parameters.tooltip": "The asset to store common parameters in. Do not use the same Expression Parameters that you have set in your avatar descriptor.",
"sync-param-sequence.create-asset": "New",
"sync-param-sequence.create-asset.tooltip": "Creates a new expression parameters asset"

}
10 changes: 9 additions & 1 deletion Runtime/ModularAvatarMenuItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ public class ModularAvatarMenuItem : AvatarTagComponent, MenuSource
/// </summary>
public bool automaticValue;

/// <summary>
/// Although unspecified, the label of a menu may contain rich text and line breaks.
/// If label is not an empty string, this MenuItem will use that as its name.
/// Otherwise, it will use the name of the containing game object as the label.
/// </summary>
[Multiline]
public string label = "";

private void Reset()
{
// Init settings only when added or reset manually from the Inspector.
Expand Down Expand Up @@ -98,7 +106,7 @@ public void Visit(NodeContext context)

var cloned = new VirtualControl(Control);
cloned.subMenu = null;
cloned.name = gameObject.name;
cloned.name = string.IsNullOrEmpty(label) ? gameObject.name : label;

FilterSubParameters(cloned);

Expand Down
Loading