Skip to content

Commit

Permalink
Add selection highlight decorations to minimap, closes #21404
Browse files Browse the repository at this point in the history
  • Loading branch information
Rachel Macfarlane authored Sep 11, 2019
1 parent 1b9a873 commit 67dc534
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 15 deletions.
47 changes: 32 additions & 15 deletions src/vs/editor/browser/viewParts/minimap/minimap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ import { getOrCreateMinimapCharRenderer } from 'vs/editor/common/view/runtimeMin
import { ViewContext } from 'vs/editor/common/view/viewContext';
import * as viewEvents from 'vs/editor/common/view/viewEvents';
import { ViewLineData, ViewModelDecoration } from 'vs/editor/common/viewModel/viewModel';
import { scrollbarShadow, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground } from 'vs/platform/theme/common/colorRegistry';
import { scrollbarShadow, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground, minimapSelection } from 'vs/platform/theme/common/colorRegistry';
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { ModelDecorationMinimapOptions } from 'vs/editor/common/model/textModel';
import { Selection } from 'vs/editor/common/core/selection';
import { Color } from 'vs/base/common/color';

function getMinimapLineHeight(renderMinimap: RenderMinimap): number {
if (renderMinimap === RenderMinimap.Large) {
Expand Down Expand Up @@ -453,6 +455,8 @@ export class Minimap extends ViewPart {
private _options: MinimapOptions;
private _lastRenderData: RenderData | null;
private _lastDecorations: ViewModelDecoration[] | undefined;
private _selections: Selection[] = [];
private _selectionColor: Color | undefined;
private _renderDecorations: boolean = false;
private _buffers: MinimapBuffers | null;

Expand All @@ -462,6 +466,7 @@ export class Minimap extends ViewPart {
this._options = new MinimapOptions(this._context.configuration);
this._lastRenderData = null;
this._buffers = null;
this._selectionColor = this._context.theme.getColor(minimapSelection);

this._domNode = createFastDomNode(document.createElement('div'));
PartFingerprints.write(this._domNode, PartFingerprint.Minimap);
Expand Down Expand Up @@ -631,6 +636,11 @@ export class Minimap extends ViewPart {
public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean {
return this._onOptionsMaybeChanged();
}
public onCursorStateChanged(e: viewEvents.ViewCursorStateChangedEvent): boolean {
this._selections = e.selections;
this._renderDecorations = true;
return true;
}
public onFlushed(e: viewEvents.ViewFlushedEvent): boolean {
this._lastRenderData = null;
return true;
Expand Down Expand Up @@ -680,9 +690,9 @@ export class Minimap extends ViewPart {

public onThemeChanged(e: viewEvents.ViewThemeChangedEvent): boolean {
this._context.model.invalidateMinimapColorCache();
// Only bother calling render if decorations are currently shown
this._renderDecorations = !!this._lastDecorations;
return !!this._lastDecorations;
this._selectionColor = this._context.theme.getColor(minimapSelection);
this._renderDecorations = true;
return true;
}

// --- end event handlers
Expand Down Expand Up @@ -744,8 +754,16 @@ export class Minimap extends ViewPart {

canvasContext.clearRect(0, 0, canvasInnerWidth, canvasInnerHeight);

// Loop over decorations, ignoring those that don't have the minimap property set and rendering rectangles for each line the decoration spans
const lineOffsetMap = new Map<number, number[]>();
for (let i = 0; i < this._selections.length; i++) {
const selection = this._selections[i];

for (let line = selection.startLineNumber; line <= selection.endLineNumber; line++) {
this.renderDecorationOnLine(canvasContext, lineOffsetMap, selection, this._selectionColor, layout, line, lineHeight, lineHeight, tabSize, characterWidth);
}
}

// Loop over decorations, ignoring those that don't have the minimap property set and rendering rectangles for each line the decoration spans
for (let i = 0; i < decorations.length; i++) {
const decoration = decorations[i];

Expand All @@ -754,7 +772,8 @@ export class Minimap extends ViewPart {
}

for (let line = decoration.range.startLineNumber; line <= decoration.range.endLineNumber; line++) {
this.renderDecorationOnLine(canvasContext, lineOffsetMap, decoration, layout, line, lineHeight, lineHeight, tabSize, characterWidth);
const decorationColor = (<ModelDecorationMinimapOptions>decoration.options.minimap).getColor(this._context.theme);
this.renderDecorationOnLine(canvasContext, lineOffsetMap, decoration.range, decorationColor, layout, line, lineHeight, lineHeight, tabSize, characterWidth);
}
}

Expand All @@ -764,7 +783,8 @@ export class Minimap extends ViewPart {

private renderDecorationOnLine(canvasContext: CanvasRenderingContext2D,
lineOffsetMap: Map<number, number[]>,
decoration: ViewModelDecoration,
decorationRange: Range,
decorationColor: Color | undefined,
layout: MinimapLayout,
lineNumber: number,
height: number,
Expand Down Expand Up @@ -793,7 +813,7 @@ export class Minimap extends ViewPart {
lineOffsetMap.set(lineNumber, lineIndexToXOffset);
}

const { startColumn, endColumn, startLineNumber, endLineNumber } = decoration.range;
const { startColumn, endColumn, startLineNumber, endLineNumber } = decorationRange;
const x = startLineNumber === lineNumber ? lineIndexToXOffset[startColumn - 1] : 0;

const endColumnForLine = endLineNumber > lineNumber ? lineIndexToXOffset.length - 1 : endColumn - 1;
Expand All @@ -802,24 +822,21 @@ export class Minimap extends ViewPart {
// If the decoration starts at the last character of the column and spans over it, ensure it has a width
const width = lineIndexToXOffset[endColumnForLine] - x || 2;

this.renderDecoration(canvasContext, <ModelDecorationMinimapOptions>decoration.options.minimap, x, y, width, height);
this.renderDecoration(canvasContext, decorationColor, x, y, width, height);
}

if (isFirstDecorationForLine) {
this.renderLineHighlight(canvasContext, <ModelDecorationMinimapOptions>decoration.options.minimap, y, height);
this.renderLineHighlight(canvasContext, decorationColor, y, height);
}

}

private renderLineHighlight(canvasContext: CanvasRenderingContext2D, minimapOptions: ModelDecorationMinimapOptions, y: number, height: number): void {
const decorationColor = minimapOptions.getColor(this._context.theme);
private renderLineHighlight(canvasContext: CanvasRenderingContext2D, decorationColor: Color | undefined, y: number, height: number): void {
canvasContext.fillStyle = decorationColor && decorationColor.transparent(0.5).toString() || '';
canvasContext.fillRect(0, y, canvasContext.canvas.width, height);
}

private renderDecoration(canvasContext: CanvasRenderingContext2D, minimapOptions: ModelDecorationMinimapOptions, x: number, y: number, width: number, height: number) {
const decorationColor = minimapOptions.getColor(this._context.theme);

private renderDecoration(canvasContext: CanvasRenderingContext2D, decorationColor: Color | undefined, x: number, y: number, width: number, height: number) {
canvasContext.fillStyle = decorationColor && decorationColor.toString() || '';
canvasContext.fillRect(x, y, width, height);
}
Expand Down
1 change: 1 addition & 0 deletions src/vs/platform/theme/common/colorRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ export const overviewRulerFindMatchForeground = registerColor('editorOverviewRul
export const overviewRulerSelectionHighlightForeground = registerColor('editorOverviewRuler.selectionHighlightForeground', { dark: '#A0A0A0CC', light: '#A0A0A0CC', hc: '#A0A0A0CC' }, nls.localize('overviewRulerSelectionHighlightForeground', 'Overview ruler marker color for selection highlights. The color must not be opaque so as not to hide underlying decorations.'), true);

export const minimapFindMatch = registerColor('minimap.findMatchHighlight', { light: '#d18616', dark: '#d18616', hc: '#AB5A00' }, nls.localize('minimapFindMatchHighlight', 'Minimap marker color for find matches.'), true);
export const minimapSelection = registerColor('minimap.selectionHighlight', { light: '#ADD6FF', dark: '#264F78', hc: '#f3f518' }, nls.localize('minimapSelectionHighlight', 'Minimap marker color for the current editor selection.'), true);


// ----- color functions
Expand Down

0 comments on commit 67dc534

Please sign in to comment.