Path: blob/main/src/vs/workbench/contrib/comments/browser/commentGlyphWidget.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import * as nls from '../../../../nls.js';6import { Color } from '../../../../base/common/color.js';7import { ContentWidgetPositionPreference, ICodeEditor, IContentWidgetPosition } from '../../../../editor/browser/editorBrowser.js';8import { IModelDecorationOptions, OverviewRulerLane } from '../../../../editor/common/model.js';9import { ModelDecorationOptions } from '../../../../editor/common/model/textModel.js';10import { darken, editorBackground, editorForeground, listInactiveSelectionBackground, opaque, registerColor } from '../../../../platform/theme/common/colorRegistry.js';11import { themeColorFromId } from '../../../../platform/theme/common/themeService.js';12import { IEditorDecorationsCollection } from '../../../../editor/common/editorCommon.js';13import { CommentThreadState } from '../../../../editor/common/languages.js';14import { Disposable, toDisposable } from '../../../../base/common/lifecycle.js';15import { Emitter } from '../../../../base/common/event.js';1617export const overviewRulerCommentingRangeForeground = registerColor('editorGutter.commentRangeForeground', { dark: opaque(listInactiveSelectionBackground, editorBackground), light: darken(opaque(listInactiveSelectionBackground, editorBackground), .05), hcDark: Color.white, hcLight: Color.black }, nls.localize('editorGutterCommentRangeForeground', 'Editor gutter decoration color for commenting ranges. This color should be opaque.'));18const overviewRulerCommentForeground = registerColor('editorOverviewRuler.commentForeground', overviewRulerCommentingRangeForeground, nls.localize('editorOverviewRuler.commentForeground', 'Editor overview ruler decoration color for resolved comments. This color should be opaque.'));19const overviewRulerCommentUnresolvedForeground = registerColor('editorOverviewRuler.commentUnresolvedForeground', overviewRulerCommentForeground, nls.localize('editorOverviewRuler.commentUnresolvedForeground', 'Editor overview ruler decoration color for unresolved comments. This color should be opaque.'));2021const editorGutterCommentGlyphForeground = registerColor('editorGutter.commentGlyphForeground', { dark: editorForeground, light: editorForeground, hcDark: Color.black, hcLight: Color.white }, nls.localize('editorGutterCommentGlyphForeground', 'Editor gutter decoration color for commenting glyphs.'));22registerColor('editorGutter.commentUnresolvedGlyphForeground', editorGutterCommentGlyphForeground, nls.localize('editorGutterCommentUnresolvedGlyphForeground', 'Editor gutter decoration color for commenting glyphs for unresolved comment threads.'));2324export class CommentGlyphWidget extends Disposable {25public static description = 'comment-glyph-widget';26private _lineNumber!: number;27private _editor: ICodeEditor;28private _threadState: CommentThreadState | undefined;29private readonly _commentsDecorations: IEditorDecorationsCollection;30private _commentsOptions: ModelDecorationOptions;3132private readonly _onDidChangeLineNumber = this._register(new Emitter<number>());33public readonly onDidChangeLineNumber = this._onDidChangeLineNumber.event;3435constructor(editor: ICodeEditor, lineNumber: number) {36super();37this._commentsOptions = this.createDecorationOptions();38this._editor = editor;39this._commentsDecorations = this._editor.createDecorationsCollection();40this._register(this._commentsDecorations.onDidChange(e => {41const range = (this._commentsDecorations.length > 0 ? this._commentsDecorations.getRange(0) : null);42if (range && range.endLineNumber !== this._lineNumber) {43this._lineNumber = range.endLineNumber;44this._onDidChangeLineNumber.fire(this._lineNumber);45}46}));47this._register(toDisposable(() => this._commentsDecorations.clear()));48this.setLineNumber(lineNumber);49}5051private createDecorationOptions(): ModelDecorationOptions {52const unresolved = this._threadState === CommentThreadState.Unresolved;53const decorationOptions: IModelDecorationOptions = {54description: CommentGlyphWidget.description,55isWholeLine: true,56overviewRuler: {57color: themeColorFromId(unresolved ? overviewRulerCommentUnresolvedForeground : overviewRulerCommentForeground),58position: OverviewRulerLane.Center59},60collapseOnReplaceEdit: true,61linesDecorationsClassName: `comment-range-glyph comment-thread${unresolved ? '-unresolved' : ''}`62};6364return ModelDecorationOptions.createDynamic(decorationOptions);65}6667setThreadState(state: CommentThreadState | undefined): void {68if (this._threadState !== state) {69this._threadState = state;70this._commentsOptions = this.createDecorationOptions();71this._updateDecorations();72}73}7475private _updateDecorations(): void {76const commentsDecorations = [{77range: {78startLineNumber: this._lineNumber, startColumn: 1,79endLineNumber: this._lineNumber, endColumn: 180},81options: this._commentsOptions82}];8384this._commentsDecorations.set(commentsDecorations);85}8687setLineNumber(lineNumber: number): void {88this._lineNumber = lineNumber;89this._updateDecorations();90}9192getPosition(): IContentWidgetPosition {93const range = (this._commentsDecorations.length > 0 ? this._commentsDecorations.getRange(0) : null);9495return {96position: {97lineNumber: range ? range.endLineNumber : this._lineNumber,98column: 199},100preference: [ContentWidgetPositionPreference.EXACT]101};102}103}104105106