From 9fa1f52ac2f33ddf62ec37b093a81a39a00a3162 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 5 Oct 2017 16:48:12 +0200 Subject: [PATCH] start with scm file decorations --- .../scm/electron-browser/scm.contribution.ts | 4 + .../electron-browser/scmFileDecorations.ts | 94 +++++++++++++++++++ .../browser/fileDecorationsService.ts | 6 +- 3 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 src/vs/workbench/parts/scm/electron-browser/scmFileDecorations.ts diff --git a/src/vs/workbench/parts/scm/electron-browser/scm.contribution.ts b/src/vs/workbench/parts/scm/electron-browser/scm.contribution.ts index b5ee2acfc51..93da15cee69 100644 --- a/src/vs/workbench/parts/scm/electron-browser/scm.contribution.ts +++ b/src/vs/workbench/parts/scm/electron-browser/scm.contribution.ts @@ -17,6 +17,7 @@ import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; import { StatusUpdater, StatusBarController } from './scmActivity'; +import { FileDecorations } from './scmFileDecorations'; import { SCMViewlet } from 'vs/workbench/parts/scm/electron-browser/scmViewlet'; class OpenSCMViewletAction extends ToggleViewletAction { @@ -49,6 +50,9 @@ Registry.as(WorkbenchExtensions.Workbench) Registry.as(WorkbenchExtensions.Workbench) .registerWorkbenchContribution(StatusBarController); +Registry.as(WorkbenchExtensions.Workbench) + .registerWorkbenchContribution(FileDecorations); + // Register Action to Open Viewlet Registry.as(WorkbenchActionExtensions.WorkbenchActions).registerWorkbenchAction( new SyncActionDescriptor(OpenSCMViewletAction, VIEWLET_ID, localize('toggleSCMViewlet', "Show SCM"), { diff --git a/src/vs/workbench/parts/scm/electron-browser/scmFileDecorations.ts b/src/vs/workbench/parts/scm/electron-browser/scmFileDecorations.ts new file mode 100644 index 00000000000..ff401a62713 --- /dev/null +++ b/src/vs/workbench/parts/scm/electron-browser/scmFileDecorations.ts @@ -0,0 +1,94 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; +import { IFileDecorationsService } from 'vs/workbench/services/fileDecorations/browser/fileDecorations'; +import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { ISCMService, ISCMRepository } from 'vs/workbench/services/scm/common/scm'; +import URI from 'vs/base/common/uri'; +import Severity from 'vs/base/common/severity'; +import { Color } from 'vs/base/common/color'; + +export class FileDecorations implements IWorkbenchContribution { + + private readonly _disposables: IDisposable[]; + // private readonly _type: DecorationType; + private readonly _repositoryListeners = new Map(); + + constructor( + @IFileDecorationsService private _decorationsService: IFileDecorationsService, + @ISCMService private _scmService: ISCMService, + ) { + this._scmService.repositories.forEach(this._onDidAddRepository, this); + this._disposables = [ + this._scmService.onDidAddRepository(this._onDidAddRepository, this), + this._scmService.onDidRemoveRepository(this._onDidRemoveRepository, this), + ]; + } + + dispose(): void { + dispose(this._disposables); + } + + private _onDidAddRepository(repo: ISCMRepository): void { + const type = this._decorationsService.registerDecorationType(repo.provider.label); + const { provider } = repo; + + let oldDecorations = new Map(); + const listener = provider.onDidChangeResources(() => { + + let newDecorations = new Map(); + let baseColor = Color.fromHex('#007acc'); + let factor = 0.0; + for (const group of provider.resources) { + + factor += 0.1; + let color = Color.getDarkerColor(baseColor, Color.black, factor); + + for (const resource of group.resourceCollection.resources) { + + this._decorationsService.setFileDecorations(type, resource.sourceUri, [{ + severity: Severity.Info, + message: resource.decorations.tooltip, + color + }]); + + newDecorations.set(resource.sourceUri.toString(), resource.sourceUri); + } + } + + oldDecorations.forEach((value, key) => { + if (!newDecorations.has(key)) { + this._decorationsService.unsetFileDecorations(type, value); + } + }); + + oldDecorations = newDecorations; + }); + + this._repositoryListeners.set(repo, { + dispose() { + listener.dispose(); + type.dispose(); + } + }); + } + + private _onDidRemoveRepository(repo: ISCMRepository): void { + let listener = this._repositoryListeners.get(repo); + if (listener) { + this._repositoryListeners.delete(repo); + listener.dispose(); + } + } + + + getId(): string { + throw new Error('smc.SCMFileDecorations'); + } + +} diff --git a/src/vs/workbench/services/fileDecorations/browser/fileDecorationsService.ts b/src/vs/workbench/services/fileDecorations/browser/fileDecorationsService.ts index 392f6ece311..a7c225ba106 100644 --- a/src/vs/workbench/services/fileDecorations/browser/fileDecorationsService.ts +++ b/src/vs/workbench/services/fileDecorations/browser/fileDecorationsService.ts @@ -37,7 +37,11 @@ export class FileDecorationsService implements IFileDecorationsService { super(label); } dispose() { - outer._types.delete(type); + let tree = outer._types.get(type); + if (tree) { + tree.forEach(([key]) => outer._onDidChangeFileDecoration.fire(URI.parse(key))); + outer._types.delete(type); + } } }; this._types.set(type, TernarySearchTree.forPaths());