mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-18 22:29:56 +01:00
Fixes #20947: Add option to render blocks instead of characters
This commit is contained in:
@@ -28,7 +28,30 @@ import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
const enum RenderMinimap {
|
||||
None = 0,
|
||||
Small = 1,
|
||||
Large = 2
|
||||
Large = 2,
|
||||
Blocks = 3,
|
||||
}
|
||||
|
||||
function getMinimapLineHeight(renderMinimap: RenderMinimap): number {
|
||||
if (renderMinimap === RenderMinimap.Large) {
|
||||
return Constants.x2_CHAR_HEIGHT;
|
||||
}
|
||||
if (renderMinimap === RenderMinimap.Small) {
|
||||
return Constants.x1_CHAR_HEIGHT;
|
||||
}
|
||||
// RenderMinimap.Blocks
|
||||
return 3;
|
||||
}
|
||||
|
||||
function getMinimapCharWidth(renderMinimap: RenderMinimap): number {
|
||||
if (renderMinimap === RenderMinimap.Large) {
|
||||
return Constants.x2_CHAR_WIDTH;
|
||||
}
|
||||
if (renderMinimap === RenderMinimap.Small) {
|
||||
return Constants.x1_CHAR_WIDTH;
|
||||
}
|
||||
// RenderMinimap.Blocks
|
||||
return 1;
|
||||
}
|
||||
|
||||
class MinimapOptions {
|
||||
@@ -127,7 +150,7 @@ class MinimapLayout {
|
||||
scrollbarSliderCenter: number
|
||||
) {
|
||||
const pixelRatio = options.pixelRatio;
|
||||
const minimapLineHeight = (options.renderMinimap === RenderMinimap.Large ? Constants.x2_CHAR_HEIGHT : Constants.x1_CHAR_HEIGHT);
|
||||
const minimapLineHeight = getMinimapLineHeight(options.renderMinimap);
|
||||
const minimapLinesFitting = Math.floor(options.canvasInnerHeight / minimapLineHeight);
|
||||
const lineHeight = options.lineHeight;
|
||||
|
||||
@@ -419,7 +442,7 @@ export class Minimap extends ViewPart {
|
||||
if (!this._lastRenderData) {
|
||||
return;
|
||||
}
|
||||
const minimapLineHeight = (renderMinimap === RenderMinimap.Large ? Constants.x2_CHAR_HEIGHT : Constants.x1_CHAR_HEIGHT);
|
||||
const minimapLineHeight = getMinimapLineHeight(renderMinimap);
|
||||
const internalOffsetY = this._options.pixelRatio * e.browserEvent.offsetY;
|
||||
const lineIndex = Math.floor(internalOffsetY / minimapLineHeight);
|
||||
|
||||
@@ -550,7 +573,7 @@ export class Minimap extends ViewPart {
|
||||
|
||||
const startLineNumber = layout.startLineNumber;
|
||||
const endLineNumber = layout.endLineNumber;
|
||||
const minimapLineHeight = (renderMinimap === RenderMinimap.Large ? Constants.x2_CHAR_HEIGHT : Constants.x1_CHAR_HEIGHT);
|
||||
const minimapLineHeight = getMinimapLineHeight(renderMinimap);
|
||||
|
||||
const imageData = this._getBuffer();
|
||||
|
||||
@@ -693,7 +716,7 @@ export class Minimap extends ViewPart {
|
||||
): void {
|
||||
const content = lineData.content;
|
||||
const tokens = lineData.tokens;
|
||||
const charWidth = (renderMinimap === RenderMinimap.Large ? Constants.x2_CHAR_WIDTH : Constants.x1_CHAR_WIDTH);
|
||||
const charWidth = getMinimapCharWidth(renderMinimap);
|
||||
const maxDx = target.width - charWidth;
|
||||
|
||||
let dx = 0;
|
||||
@@ -724,8 +747,10 @@ export class Minimap extends ViewPart {
|
||||
} else {
|
||||
if (renderMinimap === RenderMinimap.Large) {
|
||||
minimapCharRenderer.x2RenderChar(target, dx, dy, charCode, tokenColor, backgroundColor, useLighterFont);
|
||||
} else {
|
||||
} else if (renderMinimap === RenderMinimap.Small) {
|
||||
minimapCharRenderer.x1RenderChar(target, dx, dy, charCode, tokenColor, backgroundColor, useLighterFont);
|
||||
} else {
|
||||
minimapCharRenderer.blockRenderChar(target, dx, dy, tokenColor, backgroundColor, useLighterFont);
|
||||
}
|
||||
dx += charWidth;
|
||||
}
|
||||
|
||||
@@ -185,6 +185,7 @@ class InternalEditorOptionsHelper {
|
||||
scrollbarArrowSize: scrollbar.arrowSize,
|
||||
verticalScrollbarHasArrows: scrollbar.verticalHasArrows,
|
||||
minimap: minimap.enabled,
|
||||
minimapRenderText: minimap.renderText,
|
||||
pixelRatio: pixelRatio
|
||||
});
|
||||
|
||||
@@ -371,7 +372,8 @@ class InternalEditorOptionsHelper {
|
||||
|
||||
private static _sanitizeMinimapOpts(raw: editorCommon.IEditorMinimapOptions): editorCommon.InternalEditorMinimapOptions {
|
||||
return new editorCommon.InternalEditorMinimapOptions({
|
||||
enabled: toBooleanWithDefault(raw.enabled, false)
|
||||
enabled: toBooleanWithDefault(raw.enabled, false),
|
||||
renderText: toBooleanWithDefault(raw.renderText, true),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -670,6 +672,11 @@ const editorConfiguration: IConfigurationNode = {
|
||||
'default': DefaultConfig.editor.minimap.enabled,
|
||||
'description': nls.localize('minimap.enabled', "Controls if the minimap is shown")
|
||||
},
|
||||
'editor.minimap.renderText': {
|
||||
'type': 'boolean',
|
||||
'default': DefaultConfig.editor.minimap.renderText,
|
||||
'description': nls.localize('minimap.renderText', "Render the actual text on a line (as opposed to color blocks)")
|
||||
},
|
||||
'editor.wordWrap': {
|
||||
'type': 'string',
|
||||
'enum': ['off', 'on', 'fixed', 'clamped'],
|
||||
|
||||
@@ -57,7 +57,8 @@ class ConfigClass implements IConfiguration {
|
||||
horizontalHasArrows: false
|
||||
},
|
||||
minimap: {
|
||||
enabled: false
|
||||
enabled: false,
|
||||
renderText: true
|
||||
},
|
||||
fixedOverflowWidgets: false,
|
||||
overviewRulerLanes: 2,
|
||||
|
||||
@@ -163,6 +163,11 @@ export interface IEditorMinimapOptions {
|
||||
* Defaults to false.
|
||||
*/
|
||||
enabled?: boolean;
|
||||
/**
|
||||
* Render the actual text on a line (as opposed to color blocks).
|
||||
* Defaults to true.
|
||||
*/
|
||||
renderText?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -642,14 +647,17 @@ export class InternalEditorMinimapOptions {
|
||||
readonly _internalEditorMinimapOptionsBrand: void;
|
||||
|
||||
readonly enabled: boolean;
|
||||
readonly renderText: boolean;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
constructor(source: {
|
||||
enabled: boolean;
|
||||
renderText: boolean;
|
||||
}) {
|
||||
this.enabled = Boolean(source.enabled);
|
||||
this.renderText = Boolean(source.renderText);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -658,6 +666,7 @@ export class InternalEditorMinimapOptions {
|
||||
public equals(other: InternalEditorMinimapOptions): boolean {
|
||||
return (
|
||||
this.enabled === other.enabled
|
||||
&& this.renderText === other.renderText
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2815,7 +2824,8 @@ export class OverviewRulerPosition {
|
||||
export enum RenderMinimap {
|
||||
None = 0,
|
||||
Small = 1,
|
||||
Large = 2
|
||||
Large = 2,
|
||||
Blocks = 3,
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,6 +34,11 @@ export class MinimapTokensColorTracker {
|
||||
|
||||
private _updateColorMap(): void {
|
||||
const colorMap = TokenizationRegistry.getColorMap();
|
||||
if (!colorMap) {
|
||||
this._colors = [null];
|
||||
this._backgroundIsLight = true;
|
||||
return;
|
||||
}
|
||||
this._colors = [null];
|
||||
for (let colorId = 1; colorId < colorMap.length; colorId++) {
|
||||
this._colors[colorId] = colorMap[colorId].toRGBA();
|
||||
@@ -229,4 +234,43 @@ export class MinimapCharRenderer {
|
||||
dest[destOffset + 2] = backgroundB + deltaB * c;
|
||||
}
|
||||
}
|
||||
|
||||
public blockRenderChar(target: ImageData, dx: number, dy: number, color: RGBA, backgroundColor: RGBA, useLighterFont: boolean): void {
|
||||
if (dx + Constants.x1_CHAR_WIDTH > target.width || dy + Constants.x1_CHAR_HEIGHT > target.height) {
|
||||
console.warn('bad render request outside image data');
|
||||
return;
|
||||
}
|
||||
|
||||
const outWidth = target.width * Constants.RGBA_CHANNELS_CNT;
|
||||
|
||||
const c = 0.5;
|
||||
|
||||
const backgroundR = backgroundColor.r;
|
||||
const backgroundG = backgroundColor.g;
|
||||
const backgroundB = backgroundColor.b;
|
||||
|
||||
const deltaR = color.r - backgroundR;
|
||||
const deltaG = color.g - backgroundG;
|
||||
const deltaB = color.b - backgroundB;
|
||||
|
||||
const colorR = backgroundR + deltaR * c;;
|
||||
const colorG = backgroundG + deltaG * c;
|
||||
const colorB = backgroundB + deltaB * c;
|
||||
|
||||
const dest = target.data;
|
||||
|
||||
let destOffset = dy * outWidth + dx * Constants.RGBA_CHANNELS_CNT;
|
||||
{
|
||||
dest[destOffset + 0] = colorR;
|
||||
dest[destOffset + 1] = colorG;
|
||||
dest[destOffset + 2] = colorB;
|
||||
}
|
||||
|
||||
destOffset += outWidth;
|
||||
{
|
||||
dest[destOffset + 0] = colorR;
|
||||
dest[destOffset + 1] = colorG;
|
||||
dest[destOffset + 2] = colorB;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ export interface IEditorLayoutProviderOpts {
|
||||
horizontalScrollbarHeight: number;
|
||||
|
||||
minimap: boolean;
|
||||
minimapRenderText: boolean;
|
||||
pixelRatio: number;
|
||||
}
|
||||
|
||||
@@ -48,6 +49,7 @@ export class EditorLayoutProvider {
|
||||
const scrollbarArrowSize = _opts.scrollbarArrowSize | 0;
|
||||
const horizontalScrollbarHeight = _opts.horizontalScrollbarHeight | 0;
|
||||
const minimap = Boolean(_opts.minimap);
|
||||
const minimapRenderText = Boolean(_opts.minimapRenderText);
|
||||
const pixelRatio = Number(_opts.pixelRatio);
|
||||
|
||||
let lineNumbersWidth = 0;
|
||||
@@ -77,11 +79,16 @@ export class EditorLayoutProvider {
|
||||
contentWidth = remainingWidth;
|
||||
} else {
|
||||
let minimapCharWidth: number;
|
||||
if (pixelRatio >= 2) {
|
||||
renderMinimap = RenderMinimap.Large;
|
||||
minimapCharWidth = 2 / pixelRatio;
|
||||
if (minimapRenderText) {
|
||||
if (pixelRatio >= 2) {
|
||||
renderMinimap = RenderMinimap.Large;
|
||||
minimapCharWidth = 2 / pixelRatio;
|
||||
} else {
|
||||
renderMinimap = RenderMinimap.Small;
|
||||
minimapCharWidth = 1 / pixelRatio;
|
||||
}
|
||||
} else {
|
||||
renderMinimap = RenderMinimap.Small;
|
||||
renderMinimap = RenderMinimap.Blocks;
|
||||
minimapCharWidth = 1 / pixelRatio;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ suite('Editor ViewLayout - EditorLayoutProvider', () => {
|
||||
scrollbarArrowSize: 0,
|
||||
verticalScrollbarHasArrows: false,
|
||||
minimap: false,
|
||||
minimapRenderText: true,
|
||||
pixelRatio: 1,
|
||||
}, new EditorLayoutInfo({
|
||||
width: 1000,
|
||||
@@ -86,6 +87,7 @@ suite('Editor ViewLayout - EditorLayoutProvider', () => {
|
||||
scrollbarArrowSize: 13,
|
||||
verticalScrollbarHasArrows: true,
|
||||
minimap: false,
|
||||
minimapRenderText: true,
|
||||
pixelRatio: 1,
|
||||
}, new EditorLayoutInfo({
|
||||
width: 1000,
|
||||
@@ -140,6 +142,7 @@ suite('Editor ViewLayout - EditorLayoutProvider', () => {
|
||||
scrollbarArrowSize: 0,
|
||||
verticalScrollbarHasArrows: false,
|
||||
minimap: false,
|
||||
minimapRenderText: true,
|
||||
pixelRatio: 1,
|
||||
}, new EditorLayoutInfo({
|
||||
width: 900,
|
||||
@@ -194,6 +197,7 @@ suite('Editor ViewLayout - EditorLayoutProvider', () => {
|
||||
scrollbarArrowSize: 0,
|
||||
verticalScrollbarHasArrows: false,
|
||||
minimap: false,
|
||||
minimapRenderText: true,
|
||||
pixelRatio: 1,
|
||||
}, new EditorLayoutInfo({
|
||||
width: 900,
|
||||
@@ -248,6 +252,7 @@ suite('Editor ViewLayout - EditorLayoutProvider', () => {
|
||||
scrollbarArrowSize: 0,
|
||||
verticalScrollbarHasArrows: false,
|
||||
minimap: false,
|
||||
minimapRenderText: true,
|
||||
pixelRatio: 1,
|
||||
}, new EditorLayoutInfo({
|
||||
width: 900,
|
||||
@@ -302,6 +307,7 @@ suite('Editor ViewLayout - EditorLayoutProvider', () => {
|
||||
scrollbarArrowSize: 0,
|
||||
verticalScrollbarHasArrows: false,
|
||||
minimap: false,
|
||||
minimapRenderText: true,
|
||||
pixelRatio: 1,
|
||||
}, new EditorLayoutInfo({
|
||||
width: 900,
|
||||
@@ -356,6 +362,7 @@ suite('Editor ViewLayout - EditorLayoutProvider', () => {
|
||||
scrollbarArrowSize: 0,
|
||||
verticalScrollbarHasArrows: false,
|
||||
minimap: false,
|
||||
minimapRenderText: true,
|
||||
pixelRatio: 1,
|
||||
}, new EditorLayoutInfo({
|
||||
width: 900,
|
||||
@@ -410,6 +417,7 @@ suite('Editor ViewLayout - EditorLayoutProvider', () => {
|
||||
scrollbarArrowSize: 0,
|
||||
verticalScrollbarHasArrows: false,
|
||||
minimap: false,
|
||||
minimapRenderText: true,
|
||||
pixelRatio: 1,
|
||||
}, new EditorLayoutInfo({
|
||||
width: 900,
|
||||
@@ -464,6 +472,7 @@ suite('Editor ViewLayout - EditorLayoutProvider', () => {
|
||||
scrollbarArrowSize: 0,
|
||||
verticalScrollbarHasArrows: false,
|
||||
minimap: false,
|
||||
minimapRenderText: true,
|
||||
pixelRatio: 1,
|
||||
}, new EditorLayoutInfo({
|
||||
width: 900,
|
||||
@@ -518,6 +527,7 @@ suite('Editor ViewLayout - EditorLayoutProvider', () => {
|
||||
scrollbarArrowSize: 0,
|
||||
verticalScrollbarHasArrows: false,
|
||||
minimap: false,
|
||||
minimapRenderText: true,
|
||||
pixelRatio: 1,
|
||||
}, new EditorLayoutInfo({
|
||||
width: 900,
|
||||
@@ -572,6 +582,7 @@ suite('Editor ViewLayout - EditorLayoutProvider', () => {
|
||||
scrollbarArrowSize: 0,
|
||||
verticalScrollbarHasArrows: false,
|
||||
minimap: true,
|
||||
minimapRenderText: true,
|
||||
pixelRatio: 1,
|
||||
}, new EditorLayoutInfo({
|
||||
width: 1000,
|
||||
@@ -626,6 +637,7 @@ suite('Editor ViewLayout - EditorLayoutProvider', () => {
|
||||
scrollbarArrowSize: 0,
|
||||
verticalScrollbarHasArrows: false,
|
||||
minimap: true,
|
||||
minimapRenderText: true,
|
||||
pixelRatio: 2,
|
||||
}, new EditorLayoutInfo({
|
||||
width: 1000,
|
||||
@@ -680,6 +692,7 @@ suite('Editor ViewLayout - EditorLayoutProvider', () => {
|
||||
scrollbarArrowSize: 0,
|
||||
verticalScrollbarHasArrows: false,
|
||||
minimap: true,
|
||||
minimapRenderText: true,
|
||||
pixelRatio: 4,
|
||||
}, new EditorLayoutInfo({
|
||||
width: 1000,
|
||||
|
||||
Vendored
+7
@@ -1085,6 +1085,11 @@ declare module monaco.editor {
|
||||
* Defaults to false.
|
||||
*/
|
||||
enabled?: boolean;
|
||||
/**
|
||||
* Render the actual text on a line (as opposed to color blocks).
|
||||
* Defaults to true.
|
||||
*/
|
||||
renderText?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1498,6 +1503,7 @@ declare module monaco.editor {
|
||||
export class InternalEditorMinimapOptions {
|
||||
readonly _internalEditorMinimapOptionsBrand: void;
|
||||
readonly enabled: boolean;
|
||||
readonly renderText: boolean;
|
||||
}
|
||||
|
||||
export class EditorWrappingInfo {
|
||||
@@ -2590,6 +2596,7 @@ declare module monaco.editor {
|
||||
None = 0,
|
||||
Small = 1,
|
||||
Large = 2,
|
||||
Blocks = 3,
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user