Skip to content

Commit

Permalink
Submenu contribution to editor/title and view/title not working #12706 (
Browse files Browse the repository at this point in the history
#12814)

* introduce option in RenderContextMenuOptions to ask renderer to not
render a menu with single submenu. Instead render only the children
* add helper method to menu-model-registry to remove the parent nodes
from a menu node as described above
* adjust renderers and callers accordingly
  • Loading branch information
jfaltermeier authored Aug 21, 2023
1 parent de2e7e1 commit a472e72
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 9 deletions.
5 changes: 5 additions & 0 deletions packages/core/src/browser/context-menu-renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,9 @@ export interface RenderContextMenuOptions {
context?: HTMLElement;
contextKeyService?: ContextMatcher;
onHide?: () => void;
/**
* If true a single submenu in the context menu is not rendered but its children are rendered on the top level.
* Default is `false`.
*/
skipSingleRootNode?: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ export class BrowserContextMenuRenderer extends ContextMenuRenderer {
super();
}

protected doRender({ menuPath, anchor, args, onHide, context, contextKeyService }: RenderContextMenuOptions): ContextMenuAccess {
const contextMenu = this.menuFactory.createContextMenu(menuPath, args, context, contextKeyService);
protected doRender({ menuPath, anchor, args, onHide, context, contextKeyService, skipSingleRootNode }: RenderContextMenuOptions): ContextMenuAccess {
const contextMenu = this.menuFactory.createContextMenu(menuPath, args, context, contextKeyService, skipSingleRootNode);
const { x, y } = coordinateFromAnchor(anchor);
if (onHide) {
contextMenu.aboutToClose.connect(() => onHide!());
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/browser/menu/browser-menu-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ export class BrowserMainMenuFactory implements MenuWidgetFactory {
}
}

createContextMenu(path: MenuPath, args?: unknown[], context?: HTMLElement, contextKeyService?: ContextMatcher): MenuWidget {
const menuModel = this.menuProvider.getMenu(path);
createContextMenu(path: MenuPath, args?: unknown[], context?: HTMLElement, contextKeyService?: ContextMatcher, skipSingleRootNode?: boolean): MenuWidget {
const menuModel = skipSingleRootNode ? this.menuProvider.removeSingleRootNode(this.menuProvider.getMenu(path), path) : this.menuProvider.getMenu(path);
const menuCommandRegistry = this.createMenuCommandRegistry(menuModel, args).snapshot(path);
const contextMenu = this.createMenuWidget(menuModel, { commands: menuCommandRegistry, context, rootMenuPath: path, contextKeyService });
return contextMenu;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,10 @@ export class TabBarToolbar extends ReactWidget {
if (this.commandIsToggled(item.command)) {
classNames.push('toggled');
}
} else {
if (this.isEnabled(item)) {
classNames.push('enabled');
}
}
return classNames;
}
Expand Down Expand Up @@ -281,7 +285,8 @@ export class TabBarToolbar extends ReactWidget {
args: [this.current],
anchor,
context: this.current?.node,
onHide: () => toDisposeOnHide.dispose()
onHide: () => toDisposeOnHide.dispose(),
skipSingleRootNode: true,
});
}

Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/browser/style/tabs.css
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,10 @@
cursor: pointer;
}

.p-TabBar-toolbar .item.enabled .action-label::before {
display: flex;
}

.p-TabBar-toolbar :not(.item.enabled) .action-label {
background: transparent;
cursor: default;
Expand Down
50 changes: 50 additions & 0 deletions packages/core/src/common/menu/menu-model-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,56 @@ export class MenuModelRegistry {
return this.findGroup(menuPath);
}

/**
* Checks the given menu model whether it will show a menu with a single submenu.
*
* @param fullMenuModel the menu model to analyze
* @param menuPath the menu's path
* @returns if the menu will show a single submenu this returns a menu that will show the child elements of the submenu,
* otherwise the given `fullMenuModel` is return
*/
removeSingleRootNode(fullMenuModel: MutableCompoundMenuNode, menuPath: MenuPath): CompoundMenuNode {
// check whether all children are compound menus and that there is only one child that has further children
if (!this.allChildrenCompound(fullMenuModel.children)) {
return fullMenuModel;
}
let nonEmptyNode = undefined;
for (const child of fullMenuModel.children) {
if (!this.isEmpty(child.children || [])) {
if (nonEmptyNode === undefined) {
nonEmptyNode = child;
} else {
return fullMenuModel;
}
}
}

if (CompoundMenuNode.is(nonEmptyNode) && nonEmptyNode.children.length === 1 && CompoundMenuNode.is(nonEmptyNode.children[0])) {
nonEmptyNode = nonEmptyNode.children[0];
}

return CompoundMenuNode.is(nonEmptyNode) ? nonEmptyNode : fullMenuModel;
}

protected allChildrenCompound(children: ReadonlyArray<MenuNode>): boolean {
return children.every(CompoundMenuNode.is);
}

protected isEmpty(children: ReadonlyArray<MenuNode>): boolean {
if (children.length === 0) {
return true;
}
if (!this.allChildrenCompound(children)) {
return false;
}
for (const child of children) {
if (!this.isEmpty(child.children || [])) {
return false;
}
}
return true;
}

/**
* Returns the {@link MenuPath path} at which a given menu node can be accessed from this registry, if it can be determined.
* Returns `undefined` if the `parent` of any node in the chain is unknown.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ export class ElectronContextMenuRenderer extends BrowserContextMenuRenderer {

protected override doRender(options: RenderContextMenuOptions): ContextMenuAccess {
if (this.useNativeStyle) {
const { menuPath, anchor, args, onHide, context, contextKeyService } = options;
const menu = this.electronMenuFactory.createElectronContextMenu(menuPath, args, context, contextKeyService);
const { menuPath, anchor, args, onHide, context, contextKeyService, skipSingleRootNode } = options;
const menu = this.electronMenuFactory.createElectronContextMenu(menuPath, args, context, contextKeyService, skipSingleRootNode);
const { x, y } = coordinateFromAnchor(anchor);

const menuHandle = window.electronTheiaCore.popup(menu, x, y, () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ export class ElectronMainMenuFactory extends BrowserMainMenuFactory {
return undefined;
}

createElectronContextMenu(menuPath: MenuPath, args?: any[], context?: HTMLElement, contextKeyService?: ContextMatcher): MenuDto[] {
const menuModel = this.menuProvider.getMenu(menuPath);
createElectronContextMenu(menuPath: MenuPath, args?: any[], context?: HTMLElement, contextKeyService?: ContextMatcher, skipSingleRootNode?: boolean): MenuDto[] {
const menuModel = skipSingleRootNode ? this.menuProvider.removeSingleRootNode(this.menuProvider.getMenu(menuPath), menuPath) : this.menuProvider.getMenu(menuPath);
return this.fillMenuTemplate([], menuModel, args, { showDisabled: true, context, rootMenuPath: menuPath, contextKeyService });
}

Expand Down

0 comments on commit a472e72

Please sign in to comment.