Path: blob/main/src/vs/editor/common/viewModel/overviewZoneManager.ts
3294 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*--------------------------------------------------------------------------------------------*/45const enum Constants {6MINIMUM_HEIGHT = 47}89export class ColorZone {10_colorZoneBrand: void = undefined;1112public readonly from: number;13public readonly to: number;14public readonly colorId: number;1516constructor(from: number, to: number, colorId: number) {17this.from = from | 0;18this.to = to | 0;19this.colorId = colorId | 0;20}2122public static compare(a: ColorZone, b: ColorZone): number {23if (a.colorId === b.colorId) {24if (a.from === b.from) {25return a.to - b.to;26}27return a.from - b.from;28}29return a.colorId - b.colorId;30}31}3233/**34* A zone in the overview ruler35*/36export class OverviewRulerZone {37_overviewRulerZoneBrand: void = undefined;3839public readonly startLineNumber: number;40public readonly endLineNumber: number;41/**42* If set to 0, the height in lines will be determined based on `endLineNumber`.43*/44public readonly heightInLines: number;45public readonly color: string;4647private _colorZone: ColorZone | null;4849constructor(50startLineNumber: number,51endLineNumber: number,52heightInLines: number,53color: string54) {55this.startLineNumber = startLineNumber;56this.endLineNumber = endLineNumber;57this.heightInLines = heightInLines;58this.color = color;59this._colorZone = null;60}6162public static compare(a: OverviewRulerZone, b: OverviewRulerZone): number {63if (a.color === b.color) {64if (a.startLineNumber === b.startLineNumber) {65if (a.heightInLines === b.heightInLines) {66return a.endLineNumber - b.endLineNumber;67}68return a.heightInLines - b.heightInLines;69}70return a.startLineNumber - b.startLineNumber;71}72return a.color < b.color ? -1 : 1;73}7475public setColorZone(colorZone: ColorZone): void {76this._colorZone = colorZone;77}7879public getColorZones(): ColorZone | null {80return this._colorZone;81}82}8384export class OverviewZoneManager {8586private readonly _getVerticalOffsetForLine: (lineNumber: number) => number;87private _zones: OverviewRulerZone[];88private _colorZonesInvalid: boolean;89private _lineHeight: number;90private _domWidth: number;91private _domHeight: number;92private _outerHeight: number;93private _pixelRatio: number;9495private _lastAssignedId: number;96private readonly _color2Id: { [color: string]: number };97private readonly _id2Color: string[];9899constructor(getVerticalOffsetForLine: (lineNumber: number) => number) {100this._getVerticalOffsetForLine = getVerticalOffsetForLine;101this._zones = [];102this._colorZonesInvalid = false;103this._lineHeight = 0;104this._domWidth = 0;105this._domHeight = 0;106this._outerHeight = 0;107this._pixelRatio = 1;108109this._lastAssignedId = 0;110this._color2Id = Object.create(null);111this._id2Color = [];112}113114public getId2Color(): string[] {115return this._id2Color;116}117118public setZones(newZones: OverviewRulerZone[]): void {119this._zones = newZones;120this._zones.sort(OverviewRulerZone.compare);121}122123public setLineHeight(lineHeight: number): boolean {124if (this._lineHeight === lineHeight) {125return false;126}127this._lineHeight = lineHeight;128this._colorZonesInvalid = true;129return true;130}131132public setPixelRatio(pixelRatio: number): void {133this._pixelRatio = pixelRatio;134this._colorZonesInvalid = true;135}136137public getDOMWidth(): number {138return this._domWidth;139}140141public getCanvasWidth(): number {142return this._domWidth * this._pixelRatio;143}144145public setDOMWidth(width: number): boolean {146if (this._domWidth === width) {147return false;148}149this._domWidth = width;150this._colorZonesInvalid = true;151return true;152}153154public getDOMHeight(): number {155return this._domHeight;156}157158public getCanvasHeight(): number {159return this._domHeight * this._pixelRatio;160}161162public setDOMHeight(height: number): boolean {163if (this._domHeight === height) {164return false;165}166this._domHeight = height;167this._colorZonesInvalid = true;168return true;169}170171public getOuterHeight(): number {172return this._outerHeight;173}174175public setOuterHeight(outerHeight: number): boolean {176if (this._outerHeight === outerHeight) {177return false;178}179this._outerHeight = outerHeight;180this._colorZonesInvalid = true;181return true;182}183184public resolveColorZones(): ColorZone[] {185const colorZonesInvalid = this._colorZonesInvalid;186const lineHeight = Math.floor(this._lineHeight);187const totalHeight = Math.floor(this.getCanvasHeight());188const outerHeight = Math.floor(this._outerHeight);189const heightRatio = totalHeight / outerHeight;190const halfMinimumHeight = Math.floor(Constants.MINIMUM_HEIGHT * this._pixelRatio / 2);191192const allColorZones: ColorZone[] = [];193for (let i = 0, len = this._zones.length; i < len; i++) {194const zone = this._zones[i];195196if (!colorZonesInvalid) {197const colorZone = zone.getColorZones();198if (colorZone) {199allColorZones.push(colorZone);200continue;201}202}203204const offset1 = this._getVerticalOffsetForLine(zone.startLineNumber);205const offset2 = (206zone.heightInLines === 0207? this._getVerticalOffsetForLine(zone.endLineNumber) + lineHeight208: offset1 + zone.heightInLines * lineHeight209);210211const y1 = Math.floor(heightRatio * offset1);212const y2 = Math.floor(heightRatio * offset2);213214let ycenter = Math.floor((y1 + y2) / 2);215let halfHeight = (y2 - ycenter);216217if (halfHeight < halfMinimumHeight) {218halfHeight = halfMinimumHeight;219}220221if (ycenter - halfHeight < 0) {222ycenter = halfHeight;223}224if (ycenter + halfHeight > totalHeight) {225ycenter = totalHeight - halfHeight;226}227228const color = zone.color;229let colorId = this._color2Id[color];230if (!colorId) {231colorId = (++this._lastAssignedId);232this._color2Id[color] = colorId;233this._id2Color[colorId] = color;234}235const colorZone = new ColorZone(ycenter - halfHeight, ycenter + halfHeight, colorId);236237zone.setColorZone(colorZone);238allColorZones.push(colorZone);239}240241this._colorZonesInvalid = false;242243allColorZones.sort(ColorZone.compare);244return allColorZones;245}246}247248249