From 7638a9e1060067fa18d99bc105794a22311e734e Mon Sep 17 00:00:00 2001 From: Anas Shahid Date: Fri, 7 Aug 2020 15:58:07 -0400 Subject: [PATCH] [badge]: Badge decoration for active debug sessions Fixes: https://github.com/eclipse-theia/theia/issues/8303 Decorates the debug tab-bar with active debug sessions. Co-authored-by: Kaiyue Pan Co-authored-by: Anton Kosyakov Signed-off-by: Anas Shahid --- .../browser/frontend-application-module.ts | 1 + .../src/browser/shell/tab-bar-decorator.ts | 8 +-- .../src/browser/debug-frontend-module.ts | 5 ++ .../src/browser/debug-tab-bar-decorator.ts | 57 +++++++++++++++++++ 4 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 packages/debug/src/browser/debug-tab-bar-decorator.ts diff --git a/packages/core/src/browser/frontend-application-module.ts b/packages/core/src/browser/frontend-application-module.ts index 7c4241334c6f9..9197d38fb786c 100644 --- a/packages/core/src/browser/frontend-application-module.ts +++ b/packages/core/src/browser/frontend-application-module.ts @@ -156,6 +156,7 @@ export const frontendApplicationModule = new ContainerModule((bind, unbind, isBo bindContributionProvider(bind, TabBarDecorator); bind(TabBarDecoratorService).toSelf().inSingletonScope(); + bind(FrontendApplicationContribution).toService(TabBarDecoratorService); bindContributionProvider(bind, OpenHandler); bind(DefaultOpenerService).toSelf().inSingletonScope(); diff --git a/packages/core/src/browser/shell/tab-bar-decorator.ts b/packages/core/src/browser/shell/tab-bar-decorator.ts index d8c64a2eeb1dd..0d5c5c36eb71f 100644 --- a/packages/core/src/browser/shell/tab-bar-decorator.ts +++ b/packages/core/src/browser/shell/tab-bar-decorator.ts @@ -16,9 +16,10 @@ import debounce = require('lodash.debounce'); import { Title, Widget } from '@phosphor/widgets'; -import { inject, injectable, named, postConstruct } from 'inversify'; +import { inject, injectable, named } from 'inversify'; import { Event, Emitter, ContributionProvider } from '../../common'; import { WidgetDecoration } from '../widget-decoration'; +import { FrontendApplicationContribution } from '../frontend-application'; export const TabBarDecorator = Symbol('TabBarDecorator'); @@ -43,7 +44,7 @@ export interface TabBarDecorator { } @injectable() -export class TabBarDecoratorService { +export class TabBarDecoratorService implements FrontendApplicationContribution { protected readonly onDidChangeDecorationsEmitter = new Emitter(); @@ -52,8 +53,7 @@ export class TabBarDecoratorService { @inject(ContributionProvider) @named(TabBarDecorator) protected readonly contributions: ContributionProvider; - @postConstruct() - protected init(): void { + initialize(): void { this.contributions.getContributions().map(decorator => decorator.onDidChangeDecorations(this.fireDidChangeDecorations)); } diff --git a/packages/debug/src/browser/debug-frontend-module.ts b/packages/debug/src/browser/debug-frontend-module.ts index 431eb7ee07705..f1ced0af36ee3 100644 --- a/packages/debug/src/browser/debug-frontend-module.ts +++ b/packages/debug/src/browser/debug-frontend-module.ts @@ -57,6 +57,8 @@ import { MonacoEditorService } from '@theia/monaco/lib/browser/monaco-editor-ser import { DebugBreakpointWidget } from './editor/debug-breakpoint-widget'; import { DebugInlineValueDecorator } from './editor/debug-inline-value-decorator'; import { JsonSchemaContribution } from '@theia/core/lib/browser/json-schema-store'; +import { TabBarDecorator } from '@theia/core/lib/browser/shell/tab-bar-decorator'; +import { DebugTabBarDecorator } from './debug-tab-bar-decorator'; export default new ContainerModule((bind: interfaces.Bind) => { bind(DebugCallStackItemTypeKey).toDynamicValue(({ container }) => @@ -116,4 +118,7 @@ export default new ContainerModule((bind: interfaces.Bind) => { bindLaunchPreferences(bind); bind(DebugWatchManager).toSelf().inSingletonScope(); + + bind(DebugTabBarDecorator).toSelf().inSingletonScope(); + bind(TabBarDecorator).toService(DebugTabBarDecorator); }); diff --git a/packages/debug/src/browser/debug-tab-bar-decorator.ts b/packages/debug/src/browser/debug-tab-bar-decorator.ts new file mode 100644 index 0000000000000..6e11856f45d57 --- /dev/null +++ b/packages/debug/src/browser/debug-tab-bar-decorator.ts @@ -0,0 +1,57 @@ +/******************************************************************************** + * Copyright (C) 2020 Ericsson and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the Eclipse + * Public License v. 2.0 are satisfied: GNU General Public License, version 2 + * with the GNU Classpath Exception which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + ********************************************************************************/ + +import { injectable, inject, postConstruct } from 'inversify'; +import { DebugSessionManager } from './debug-session-manager'; +import { DebugWidget } from './view/debug-widget'; +import { Emitter, Event } from '@theia/core/lib/common/event'; +import { TabBarDecorator } from '@theia/core/lib/browser/shell/tab-bar-decorator'; +import { Title, Widget } from '@theia/core/lib/browser'; +import { WidgetDecoration } from '@theia/core/lib/browser/widget-decoration'; +import { DisposableCollection } from '@theia/core/lib/common'; + +@injectable() +export class DebugTabBarDecorator implements TabBarDecorator { + readonly id = 'theia-debug-tabbar-decorator'; + + protected readonly emitter = new Emitter(); + protected toDispose = new DisposableCollection(); + + @inject(DebugSessionManager) + protected readonly debugSessionManager: DebugSessionManager; + + @postConstruct() + protected init(): void { + this.toDispose.pushAll([ + this.debugSessionManager.onDidStartDebugSession(() => this.fireDidChangeDecorations()), + this.debugSessionManager.onDidDestroyDebugSession(() => this.fireDidChangeDecorations()) + ]); + } + + decorate(title: Title): WidgetDecoration.Data[] { + return (title.owner.id === DebugWidget.ID) + ? [{ badge: this.debugSessionManager.sessions.length }] + : []; + } + + get onDidChangeDecorations(): Event { + return this.emitter.event; + } + + protected fireDidChangeDecorations(): void { + this.emitter.fire(undefined); + } +}