I am using the scm extension (scm-frontend-module, scm-contribution) as a reference in creating a new widget. I chose this extension to reference because it has a nice TabBarToolbar and tree view that I wanted to replicate.
The problem I have is that the TabBarToolbarItems are being added to every widget, rather than only the intended widget. This picture shows the SCM widget with extra unintended “toggle tree view” and “list view” items:
My feeling is that it has something to do with the container that the widget is binding to, but I haven’t been able to locate the issue. My structure is as follows:
my-frontend-module:
bind(MyWidget).toSelf()
bind(WidgetFactory).toDynamicValue(ctx => ({
id: MyWidgetFactoryId,
createWidget: (options: MyWidgetOpts) => {
const child = new Container({ defaultScope: 'Singleton' });
child.parent = ctx.container;
child.bind(MyWidgetOpts).toConstantValue(options)
return child.get(MyWidget)
}
})).inSingletonScope();
bindViewContribution(bind, MyWidgetContribution)
for (const identifier of [CommandContribution, MenuContribution, TabBarToolbarContribution]) {
bind(identifier).toService(MyWidgetContribution);
}
bind(WidgetFactory).toDynamicValue(({ container }) => ({
id: MyContainerId,
createWidget: async () => {
const viewContainer = container.get<ViewContainer.Factory>(ViewContainer.Factory)({
id: MyContainerId,
progressLocationId: 'my-widget'
});
viewContainer.setTitleOptions(MyContainerTitleOpts);
const widget = await container.get(WidgetManager).getOrCreateWidget(MyWidgetFactoryId);
viewContainer.addWidget(widget, {
canHide: false,
initiallyCollapsed: false
});
return viewContainer;
}
})).inSingletonScope();
my-widget-contribution:
@injectable()
export class MyWidgetContribution extends AbstractViewContribution<MyWidget>
implements FrontendApplicationContribution, TabBarToolbarContribution {
@inject(ApplicationShell) protected readonly shell: ApplicationShell;
@inject(WidgetManager) protected readonly widgetManager: WidgetManager;
@inject(CommandRegistry) protected readonly commandRegistry: CommandRegistry;
@inject(ContextKeyService) protected readonly contextKeys: ContextKeyService;
readonly currentEditor: MyWidget | undefined;
protected myFocus: ContextKey<boolean>;
constructor() {
super({
defaultWidgetOptions: { area: "left", rank: 300 },
toggleCommandId: "my:toggle",
toggleKeybinding: "ctrlcmd+shift+m",
viewContainerId: MyContainerId,
widgetName: "My Widget",
widgetId: MyWidgetFactoryId,
});
}
@postConstruct()
protected init(): void {
this. myFocus = this.contextKeys.createKey('myFocus', false);
}
async initializeLayout(): Promise<void> {
await this.openView();
}
onStart(): void {
this.updateContextKeys()
this.shell.onDidChangeCurrentWidget(() => this.updateContextKeys())
}
protected updateContextKeys(): void {
this.myFocus.set(this.shell.currentWidget instanceof MyWidget);
}
registerToolbarItems(registry: TabBarToolbarRegistry): void {
const viewModeEmitter = new Emitter<void>();
const extractEditorWidget = (widget: any) => {
if (widget instanceof ViewContainer) {
const layout = widget.containerLayout;
const myWidgetPart = find(layout.iter(), part => part.wrapped instanceof MyWidget);
if (myWidgetPart && myWidgetPart.wrapped instanceof MyWidget) {
return myWidgetPart.wrapped;
}
}
}
const registerToggleViewItem = (command: Command, mode: 'tree' | 'list') => {
const id = command.id;
const item: TabBarToolbarItem = {
id,
command: id,
tooltip: command.label,
onDidChange: viewModeEmitter.event
};
this.commandRegistry.registerCommand({ id, iconClass: command && command.iconClass }, {
execute: widget => {
},
isVisible: widget => {
return true;
},
});
registry.registerItem(item);
};
registerToggleViewItem(MyCommands.TREE_VIEW_MODE, 'tree');
registerToggleViewItem(MyCommands.LIST_VIEW_MODE, 'list');
this.commandRegistry.registerCommand(MyCommands.COLLAPSE_ALL, {
execute: widget => {
},
isVisible: widget => {
return true;
}
});
registry.registerItem({
...MyCommands.COLLAPSE_ALL,
command: MyCommands.COLLAPSE_ALL.id
});
}
}
The menu item in the “View” drop-down menu also lists my widget twice. Any ideas as to what I may be missing? I am using theia v1.6.0