Skip to content

Commit

Permalink
[lumino] code changes
Browse files Browse the repository at this point in the history
- use 'iconClass' instead of 'class' in commands
- only access shell handlers once they are initialized
- use Lumino's host option for secondary window support
- adapt tab bar handling
- adapt to Iterable changes
- adapt to Drag interface changes
- adapt to Widget id changes

Contributed on behalf of STMicroelectronics
  • Loading branch information
sdirix committed Oct 15, 2024
1 parent 765afa3 commit d8b6b24
Show file tree
Hide file tree
Showing 15 changed files with 86 additions and 101 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class SampleMenuCommandRegistry extends MenuCommandRegistry {
return this.addCommand(id, {
execute: () => { /* NOOP */ },
label: menu.label,
icon: menu.icon,
iconClass: menu.icon,
isEnabled: () => false,
isVisible: () => true
});
Expand Down
46 changes: 24 additions & 22 deletions packages/core/src/browser/common-frontend-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -479,28 +479,30 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
this.preferences.ready.then(() => this.setSashProperties());
this.preferences.onPreferenceChanged(e => this.handlePreferenceChange(e, app));

app.shell.leftPanelHandler.addBottomMenu({
id: 'settings-menu',
iconClass: codicon('settings-gear'),
title: nls.localizeByDefault(CommonCommands.MANAGE_CATEGORY),
menuPath: MANAGE_MENU,
order: 0,
});
const accountsMenu: SidebarMenu = {
id: 'accounts-menu',
iconClass: codicon('account'),
title: nls.localizeByDefault('Accounts'),
menuPath: ACCOUNTS_MENU,
order: 1,
onDidBadgeChange: this.authenticationService.onDidUpdateSignInCount
};
this.authenticationService.onDidRegisterAuthenticationProvider(() => {
app.shell.leftPanelHandler.addBottomMenu(accountsMenu);
});
this.authenticationService.onDidUnregisterAuthenticationProvider(() => {
if (this.authenticationService.getProviderIds().length === 0) {
app.shell.leftPanelHandler.removeBottomMenu(accountsMenu.id);
}
app.shell.initialized.then(() => {
app.shell.leftPanelHandler.addBottomMenu({
id: 'settings-menu',
iconClass: codicon('settings-gear'),
title: nls.localizeByDefault(CommonCommands.MANAGE_CATEGORY),
menuPath: MANAGE_MENU,
order: 0,
});
const accountsMenu: SidebarMenu = {
id: 'accounts-menu',
iconClass: codicon('account'),
title: nls.localizeByDefault('Accounts'),
menuPath: ACCOUNTS_MENU,
order: 1,
onDidBadgeChange: this.authenticationService.onDidUpdateSignInCount
};
this.authenticationService.onDidRegisterAuthenticationProvider(() => {
app.shell.leftPanelHandler.addBottomMenu(accountsMenu);
});
this.authenticationService.onDidUnregisterAuthenticationProvider(() => {
if (this.authenticationService.getProviderIds().length === 0) {
app.shell.leftPanelHandler.removeBottomMenu(accountsMenu.id);
}
});
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ export class BrowserContextMenuRenderer extends ContextMenuRenderer {
if (onHide) {
contextMenu.aboutToClose.connect(() => onHide!());
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
contextMenu.open(x, y, undefined, context);
contextMenu.open(x, y, { host: context });
return new BrowserContextMenuAccess(contextMenu);
}

Expand Down
12 changes: 6 additions & 6 deletions packages/core/src/browser/menu/browser-menu-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import { injectable, inject } from 'inversify';
import { MenuBar, Menu as MenuWidget, Widget } from '@lumino/widgets';
import { CommandRegistry as PhosphorCommandRegistry } from '@lumino/commands';
import { CommandRegistry as LuminoCommandRegistry } from '@lumino/commands';
import {
CommandRegistry, environment, DisposableCollection, Disposable,
MenuModelRegistry, MAIN_MENU_BAR, MenuPath, MenuNode, MenuCommandExecutor, CompoundMenuNode, CompoundMenuNodeRole, CommandMenuNode
Expand Down Expand Up @@ -272,14 +272,14 @@ export class DynamicMenuWidget extends MenuWidget {
});
}

public override open(x: number, y: number, options?: MenuWidget.IOpenOptions, anchor?: HTMLElement): void {
public override open(x: number, y: number, options?: MenuWidget.IOpenOptions): void {
const cb = () => {
this.restoreFocusedElement();
this.aboutToClose.disconnect(cb);
};
this.aboutToClose.connect(cb);
this.preserveFocusedElement();
super.open(x, y, options, anchor);
super.open(x, y, options);
}

protected updateSubMenus(parent: MenuWidget, menu: CompoundMenuNode, commands: MenuCommandRegistry): void {
Expand Down Expand Up @@ -415,9 +415,9 @@ export class BrowserMenuBarContribution implements FrontendApplicationContributi
}

/**
* Stores Theia-specific action menu nodes instead of PhosphorJS commands with their handlers.
* Stores Theia-specific action menu nodes instead of Lumino commands with their handlers.
*/
export class MenuCommandRegistry extends PhosphorCommandRegistry {
export class MenuCommandRegistry extends LuminoCommandRegistry {

protected actions = new Map<string, [MenuNode & CommandMenuNode, unknown[]]>();
protected toDispose = new DisposableCollection();
Expand Down Expand Up @@ -466,7 +466,7 @@ export class MenuCommandRegistry extends PhosphorCommandRegistry {
const unregisterCommand = this.addCommand(id, {
execute: () => commandExecutor.executeCommand(menuPath, id, ...args),
label: menu.label,
icon: menu.icon,
iconClass: menu.icon,
isEnabled: () => enabled,
isVisible: () => visible,
isToggled: () => toggled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { PreferenceSchemaProvider } from './preference-contribution';
import URI from '../../common/uri';
import { PreferenceScope } from './preference-scope';
import { PreferenceConfigurations } from './preference-configurations';
import { JSONExt, JSONValue } from '@lumino/coreutils/lib/json';
import { JSONExt, JSONValue } from '@lumino/coreutils';
import { OverridePreferenceName, PreferenceLanguageOverrideService } from './preference-language-override-service';

export { PreferenceScope };
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/browser/shell/application-shell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,9 @@ export class ApplicationShell extends Widget {
return this._mainPanelRenderer;
}

private setInitialized: () => void;
initialized: Promise<void> = new Promise(resolve => { this.setInitialized = resolve; });

/**
* Construct a new application shell.
*/
Expand Down Expand Up @@ -319,6 +322,7 @@ export class ApplicationShell extends Widget {
});
}
});
this.setInitialized();
}

protected initializeShell(): void {
Expand Down
25 changes: 3 additions & 22 deletions packages/core/src/browser/shell/tab-bars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ export class ScrollableTabBar extends TabBar<Widget> {

constructor(options?: TabBar.IOptions<Widget> & PerfectScrollbar.Options, dynamicTabOptions?: ScrollableTabBar.Options) {
super(options);
this.scrollBarFactory = () => new PerfectScrollbar(this.scrollbarHost, options);
this.scrollBarFactory = () => new PerfectScrollbar(this.node, options);
this._dynamicTabOptions = dynamicTabOptions;
this.rewireDOM();
}
Expand Down Expand Up @@ -740,7 +740,7 @@ export class ScrollableTabBar extends TabBar<Widget> {
protected rewireDOM(): void {
const contentNode = this.node.getElementsByClassName(ScrollableTabBar.Styles.TAB_BAR_CONTENT)[0];
if (!contentNode) {
throw new Error("'this.node' does not have the content as a direct child with class name 'p-TabBar-content'.");
throw new Error(`'this.node' does not have the content as a direct child with class name '${ScrollableTabBar.Styles.TAB_BAR_CONTENT}'.`);
}
this.node.removeChild(contentNode);
this.contentContainer = document.createElement('div');
Expand Down Expand Up @@ -867,7 +867,7 @@ export class ScrollableTabBar extends TabBar<Widget> {
window.requestAnimationFrame(() => {
const tab = this.contentNode.children[index] as HTMLElement;
if (tab && this.isVisible) {
const parent = this.scrollbarHost;
const parent = this.node;
if (this.orientation === 'horizontal') {
const scroll = parent.scrollLeft;
const left = tab.offsetLeft;
Expand Down Expand Up @@ -901,25 +901,6 @@ export class ScrollableTabBar extends TabBar<Widget> {
this.pendingReveal = result;
return result;
}

/**
* Overrides the `contentNode` property getter in PhosphorJS' TabBar.
*/
// @ts-expect-error TS2611 `TabBar<T>.contentNode` is declared as `readonly contentNode` but is implemented as a getter.
get contentNode(): HTMLUListElement {
return this.tabBarContainer.getElementsByClassName(ToolbarAwareTabBar.Styles.TAB_BAR_CONTENT)[0] as HTMLUListElement;
}

/**
* Overrides the scrollable host from the parent class.
*/
protected get scrollbarHost(): HTMLElement {
return this.tabBarContainer;
}

protected get tabBarContainer(): HTMLElement {
return this.node.getElementsByClassName(ToolbarAwareTabBar.Styles.TAB_BAR_CONTENT_CONTAINER)[0] as HTMLElement;
}
}

export namespace ScrollableTabBar {
Expand Down
48 changes: 24 additions & 24 deletions packages/core/src/browser/view-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// *****************************************************************************

import { interfaces, injectable, inject, postConstruct } from 'inversify';
import { IIterator, toArray, find, some, every, map, ArrayExt } from '@lumino/algorithm';
import { find, some, every, map, ArrayExt } from '@lumino/algorithm';
import {
Widget, EXPANSION_TOGGLE_CLASS, COLLAPSED_CLASS, CODICON_TREE_ITEM_CLASSES, MessageLoop, Message, SplitPanel,
BaseWidget, addEventListener, SplitLayout, LayoutItem, PanelLayout, addKeyListener, waitForRevealed, UnsafeWidgetUtilities, DockPanel, PINNED_CLASS
Expand All @@ -34,7 +34,7 @@ import { isEmpty, isObject, nls } from '../common';
import { WidgetManager } from './widget-manager';
import { Key } from './keys';
import { ProgressBarFactory } from './progress-bar-factory';
import { Drag, IDragEvent } from '@lumino/dragdrop';
import { Drag } from '@lumino/dragdrop';
import { MimeData } from '@lumino/coreutils';
import { ElementExt } from '@lumino/domutils';
import { TabBarDecoratorService } from './shell/tab-bar-decorator';
Expand Down Expand Up @@ -713,46 +713,46 @@ export class ViewContainer extends BaseWidget implements StatefulWidget, Applica

protected override onBeforeAttach(msg: Message): void {
super.onBeforeAttach(msg);
this.node.addEventListener('p-dragenter', this, true);
this.node.addEventListener('p-dragover', this, true);
this.node.addEventListener('p-dragleave', this, true);
this.node.addEventListener('p-drop', this, true);
this.node.addEventListener('lm-dragenter', this, true);
this.node.addEventListener('lm-dragover', this, true);
this.node.addEventListener('lm-dragleave', this, true);
this.node.addEventListener('lm-drop', this, true);
}

protected override onAfterDetach(msg: Message): void {
super.onAfterDetach(msg);
this.node.removeEventListener('p-dragenter', this, true);
this.node.removeEventListener('p-dragover', this, true);
this.node.removeEventListener('p-dragleave', this, true);
this.node.removeEventListener('p-drop', this, true);
this.node.removeEventListener('lm-dragenter', this, true);
this.node.removeEventListener('lm-dragover', this, true);
this.node.removeEventListener('lm-dragleave', this, true);
this.node.removeEventListener('lm-drop', this, true);
}

handleEvent(event: Event): void {
switch (event.type) {
case 'p-dragenter':
this.handleDragEnter(event as IDragEvent);
case 'lm-dragenter':
this.handleDragEnter(event as Drag.Event);
break;
case 'p-dragover':
this.handleDragOver(event as IDragEvent);
case 'lm-dragover':
this.handleDragOver(event as Drag.Event);
break;
case 'p-dragleave':
this.handleDragLeave(event as IDragEvent);
case 'lm-dragleave':
this.handleDragLeave(event as Drag.Event);
break;
case 'p-drop':
this.handleDrop(event as IDragEvent);
case 'lm-drop':
this.handleDrop(event as Drag.Event);
break;
}
}

handleDragEnter(event: IDragEvent): void {
handleDragEnter(event: Drag.Event): void {
if (event.mimeData.hasData('application/vnd.phosphor.view-container-factory')) {
event.preventDefault();
event.stopPropagation();
}
}

toDisposeOnDragEnd = new DisposableCollection();
handleDragOver(event: IDragEvent): void {
handleDragOver(event: Drag.Event): void {
const factory = event.mimeData.getData('application/vnd.phosphor.view-container-factory');
const widget = factory && factory();
if (!(widget instanceof ViewContainerPart)) {
Expand Down Expand Up @@ -797,15 +797,15 @@ export class ViewContainer extends BaseWidget implements StatefulWidget, Applica
event.dropAction = event.proposedAction;
};

handleDragLeave(event: IDragEvent): void {
handleDragLeave(event: Drag.Event): void {
this.toDisposeOnDragEnd.dispose();
if (event.mimeData.hasData('application/vnd.phosphor.view-container-factory')) {
event.preventDefault();
event.stopPropagation();
}
};

handleDrop(event: IDragEvent): void {
handleDrop(event: Drag.Event): void {
this.toDisposeOnDragEnd.dispose();
const factory = event.mimeData.getData('application/vnd.phosphor.view-container-factory');
const draggedPart = factory && factory();
Expand Down Expand Up @@ -1364,13 +1364,13 @@ export class ViewContainerLayout extends SplitLayout {
return (this as any)._items as Array<LayoutItem & ViewContainerLayout.Item>;
}

override iter(): IIterator<ViewContainerPart> {
iter(): IterableIterator<ViewContainerPart> {
return map(this.items, item => item.widget);
}

// @ts-expect-error TS2611 `SplitLayout.widgets` is declared as `readonly widgets` but is implemented as a getter.
get widgets(): ViewContainerPart[] {
return toArray(this.iter());
return Array.from(this.iter());
}

override attachWidget(index: number, widget: ViewContainerPart): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,16 +186,16 @@ export class ElectronMenuContribution extends BrowserMenuBarContribution impleme
/**
* Hides the `theia-top-panel` depending on the selected `titleBarStyle`.
* The `theia-top-panel` is used as the container of the main, application menu-bar for the
* browser. Native Electron has it's own.
* browser. Native Electron has its own.
* By default, this method is called on application `onStart`.
*/
protected hideTopPanel(app: FrontendApplication): void {
const itr = app.shell.children();
let child = itr.next();
while (child) {
while (!child.done) {
// Top panel for the menu contribution is not required for native Electron title bar.
if (child.id === 'theia-top-panel') {
child.setHidden(this.titleBarStyle !== 'custom');
if (child.value.id === 'theia-top-panel') {
child.value.setHidden(this.titleBarStyle !== 'custom');
break;
} else {
child = itr.next();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ export class MemoryLayoutWidget extends Panel implements Disposable, Application
protected dockPanelHoldsWidgets(): boolean {
const iter = this.dockPanel.tabBars();
let tabBar = iter.next();
while (tabBar) {
if (tabBar.titles.length) {
while (!tabBar.done) {
if (tabBar.value.titles.length) {
return true;
}
tabBar = iter.next();
Expand Down Expand Up @@ -135,14 +135,8 @@ export class MemoryLayoutWidget extends Panel implements Disposable, Application
}

getTrackableWidgets(): Widget[] {
const children: Widget[] = [];
const childIterator = this.dockPanel.children();
let currentChild = childIterator.next();
while (currentChild) {
children.push(currentChild);
currentChild = childIterator.next();
}
return children;
return Array.from(childIterator);
}

activateWidget(id: string): Widget | undefined {
Expand Down
8 changes: 4 additions & 4 deletions packages/plugin-dev/src/browser/hosted-plugin-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ export class HostedPluginController implements FrontendApplicationContribution {
protected addCommandsForRunningPlugin(commands: CommandRegistry, menu: Menu): void {
commands.addCommand(HostedPluginCommands.STOP.id, {
label: nls.localize('theia/plugin-dev/stopInstance', 'Stop Instance'),
icon: codicon('debug-stop'),
iconClass: codicon('debug-stop'),
execute: () => setTimeout(() => this.hostedPluginManagerClient.stop(), 100)
});

Expand All @@ -316,7 +316,7 @@ export class HostedPluginController implements FrontendApplicationContribution {

commands.addCommand(HostedPluginCommands.RESTART.id, {
label: nls.localize('theia/plugin-dev/restartInstance', 'Restart Instance'),
icon: codicon('debug-restart'),
iconClass: codicon('debug-restart'),
execute: () => setTimeout(() => this.hostedPluginManagerClient.restart(), 100)
});

Expand All @@ -332,7 +332,7 @@ export class HostedPluginController implements FrontendApplicationContribution {
protected addCommandsForStoppedPlugin(commands: CommandRegistry, menu: Menu): void {
commands.addCommand(HostedPluginCommands.START.id, {
label: nls.localize('theia/plugin-dev/startInstance', 'Start Instance'),
icon: codicon('play'),
iconClass: codicon('play'),
execute: () => setTimeout(() => this.hostedPluginManagerClient.start(), 100)
});

Expand All @@ -343,7 +343,7 @@ export class HostedPluginController implements FrontendApplicationContribution {

commands.addCommand(HostedPluginCommands.DEBUG.id, {
label: nls.localize('theia/plugin-dev/debugInstance', 'Debug Instance'),
icon: codicon('debug'),
iconClass: codicon('debug'),
execute: () => setTimeout(() => this.hostedPluginManagerClient.debug(), 100)
});

Expand Down
Loading

0 comments on commit d8b6b24

Please sign in to comment.