Repository: FlaxEngine/FlaxEngine
File: Source/Editor/Windows/ContentWindow.ContextMenu.cs (C#)

Code before:

                b = cm.AddButton("Paste", _view.Paste);
                b.Enabled = _view.CanPaste();

                cm.AddButton("Refresh", () => Editor.ContentDatabase.RefreshFolder(CurrentViewFolder, true));

                cm.AddButton("Refresh all thumbnails", RefreshViewItemsThumbnails);
            }

            cm.AddSeparator();

            if (!isRootFolder)
            {
                cm.AddButton("New folder", NewFolder);
            }

            c = cm.AddChildMenu("New");
            c.ContextMenu.Tag = item;
            c.ContextMenu.AutoSort = true;
            int newItems = 0;
            for (int i = 0; i < Editor.ContentDatabase.Proxy.Count; i++)
            {
                var p = Editor.ContentDatabase.Proxy[i];
                if (p.CanCreate(folder))
                {
                    if (_animationGroupNames.Contains(p.Name))
                        AddContentProxyToMenu(c.ContextMenu, p, "Animation");
                    else if (_particleGroupNames.Contains(p.Name))
                        AddContentProxyToMenu(c.ContextMenu, p, "Particles");
                    else if (_materialGroupNames.Contains(p.Name))
                        AddContentProxyToMenu(c.ContextMenu, p, "Materials");
                    else if (_physicsGroupNames.Contains(p.Name))
                        AddContentProxyToMenu(c.ContextMenu, p, "Physics");
                    else
                        c.ContextMenu.AddButton(p.Name, () => NewItem(p));
                    
                    newItems++;
                }
            }
            c.Enabled = newItems > 0;

            if (folder.CanHaveAssets)
            {
                cm.AddButton("Import file", () =>
                {
                    _view.ClearSelection();
                    Editor.ContentImporting.ShowImportFileDialog(CurrentViewFolder);
                });
            }

            // Show it

Review comment (suggestion):
I think it would be better to let `AssetProxy` return the name of the category and use it here to build nested menu - easier to extend and maintain in the future.

Code after:

                ContentProxy p;
                if (type.Type.IsSubclassOf(typeof(ContentProxy)))
                {
                    p = Editor.ContentDatabase.Proxy.Find(T => T.GetType() == type.Type);
                }
                else
                {
                    // user can use attribute to put their own assets into the content context menu
                    var generic = typeof(SpawnableJsonAssetProxy<>).MakeGenericType(type.Type);
                    var instance = Activator.CreateInstance(generic);
                    p = instance as AssetProxy;
                }
                
                if (p == null)
                    continue;
                
                // create menus
                if (p.CanCreate(folder))
                {
                    var splitPath = attribute.Path.Split('/');
                    ContextMenuChildMenu childCM = null;
                    bool mainCM = true;
                    for (int i = 0; i < splitPath?.Length; i++)
                    {
                        if (i == splitPath.Length - 1)
                        {
                            if (mainCM)
                            {
                                cm.AddButton(splitPath[i].Trim(), () => NewItem(p));
                                mainCM = false;
                            }
                            else
                            {
                                childCM?.ContextMenu.AddButton(splitPath[i].Trim(), () => NewItem(p));
                                childCM.ContextMenu.AutoSort = true;
                            }
                        }
                        else
                        {
                            if (mainCM)
                            {
                                childCM = cm.GetOrAddChildMenu(splitPath[i].Trim());
                                mainCM = false;
                            }
                            else
                            {
                                childCM = childCM?.ContextMenu.GetOrAddChildMenu(splitPath[i].Trim());
                            }
                            childCM.ContextMenu.AutoSort = true;
                        }