mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-08 17:19:48 +01:00
Move getAllOverviewRulerDecorations to IViewModelLinesCollection
This commit is contained in:
@@ -14,9 +14,8 @@ import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { editorOverviewRulerBorder, editorCursorForeground } from 'vs/editor/common/view/editorColorRegistry';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { ITheme, ThemeColor } from 'vs/platform/theme/common/themeService';
|
||||
import { ITheme } from 'vs/platform/theme/common/themeService';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { ModelDecorationOverviewRulerOptions } from 'vs/editor/common/model/textModelWithDecorations';
|
||||
|
||||
class Settings {
|
||||
|
||||
@@ -275,12 +274,7 @@ export class DecorationsOverviewRuler2 extends ViewPart {
|
||||
}
|
||||
public onThemeChanged(e: viewEvents.ViewThemeChangedEvent): boolean {
|
||||
// invalidate color cache
|
||||
const decorations = this._context.model.getAllOverviewRulerDecorations();
|
||||
for (let i = 0, len = decorations.length; i < len; i++) {
|
||||
const decoration = decorations[i];
|
||||
const opts = <ModelDecorationOverviewRulerOptions>decoration.source.options.overviewRuler;
|
||||
opts._resolvedColor = null;
|
||||
}
|
||||
this._context.model.invalidateOverviewRulerColorCache();
|
||||
return this._updateSettings(false);
|
||||
}
|
||||
|
||||
@@ -303,10 +297,9 @@ export class DecorationsOverviewRuler2 extends ViewPart {
|
||||
const canvasHeight = this._settings.canvasHeight;
|
||||
const lineHeight = this._settings.lineHeight;
|
||||
const viewLayout = this._context.viewLayout;
|
||||
const theme = this._context.theme;
|
||||
const outerHeight = this._context.viewLayout.getScrollHeight();
|
||||
const heightRatio = canvasHeight / outerHeight;
|
||||
const decorations = this._context.model.getAllOverviewRulerDecorations();
|
||||
const decorations = this._context.model.getAllOverviewRulerDecorations(this._context.theme);
|
||||
|
||||
const minDecorationHeight = (Constants.MIN_DECORATION_HEIGHT * this._settings.pixelRatio) | 0;
|
||||
const halfMinDecorationHeight = (minDecorationHeight / 2) | 0;
|
||||
@@ -322,17 +315,12 @@ export class DecorationsOverviewRuler2 extends ViewPart {
|
||||
const paintQueue = new PaintQueue(canvasCtx, this._settings.x, this._settings.w);
|
||||
for (let i = 0, len = decorations.length; i < len; i++) {
|
||||
const decoration = decorations[i];
|
||||
const opts = <ModelDecorationOverviewRulerOptions>decoration.source.options.overviewRuler;
|
||||
const lane = opts.position;
|
||||
if (lane === 0) {
|
||||
if (decoration.lane === 0) {
|
||||
continue;
|
||||
}
|
||||
const startLineNumber = decoration.range.startLineNumber;
|
||||
const endLineNumber = decoration.range.endLineNumber;
|
||||
const color = resolveColor(opts, theme);
|
||||
|
||||
let y1 = (viewLayout.getVerticalOffsetForLineNumber(startLineNumber) * heightRatio) | 0;
|
||||
let y2 = ((viewLayout.getVerticalOffsetForLineNumber(endLineNumber) + lineHeight) * heightRatio) | 0;
|
||||
let y1 = (viewLayout.getVerticalOffsetForLineNumber(decoration.startLineNumber) * heightRatio) | 0;
|
||||
let y2 = ((viewLayout.getVerticalOffsetForLineNumber(decoration.endLineNumber) + lineHeight) * heightRatio) | 0;
|
||||
let height = y2 - y1;
|
||||
if (height < minDecorationHeight) {
|
||||
let yCenter = ((y1 + y2) / 2) | 0;
|
||||
@@ -345,7 +333,7 @@ export class DecorationsOverviewRuler2 extends ViewPart {
|
||||
y2 = yCenter + halfMinDecorationHeight;
|
||||
}
|
||||
|
||||
paintQueueAccept(paintQueue, color, y1, y2, lane);
|
||||
paintQueueAccept(paintQueue, decoration.color, y1, y2, decoration.lane);
|
||||
}
|
||||
for (let i = 0, len = paintQueue.req.length; i < len; i++) {
|
||||
paintQueueFlush(paintQueue, paintQueue.req[i]);
|
||||
@@ -448,7 +436,9 @@ function paintQueueAccept(Q: PaintQueue, color: string, y1: number, y2: number,
|
||||
if (result !== null) {
|
||||
// there is already an ongoing request for this color & lane
|
||||
// => simply merge into it
|
||||
result.y2 = y2;
|
||||
if (y2 > result.y2) {
|
||||
result.y2 = y2;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -466,23 +456,3 @@ function paintQueueFlush(Q: PaintQueue, req: PaintRequest): void {
|
||||
Q.ctx.fillStyle = req.color;
|
||||
Q.ctx.fillRect(Q.x[req.lane], req.y1, Q.w[req.lane], req.y2 - req.y1);
|
||||
}
|
||||
|
||||
function resolveColor(opts: ModelDecorationOverviewRulerOptions, theme: ITheme): string {
|
||||
if (!opts._resolvedColor) {
|
||||
const themeType = theme.type;
|
||||
const color = (themeType === 'dark' ? opts.darkColor : themeType === 'light' ? opts.color : opts.hcColor);
|
||||
opts._resolvedColor = resolveRulerColor(color, theme);
|
||||
}
|
||||
return opts._resolvedColor;
|
||||
}
|
||||
|
||||
function resolveRulerColor(color: string | ThemeColor, theme: ITheme): string {
|
||||
if (typeof color === 'string') {
|
||||
return color;
|
||||
}
|
||||
let c = color ? theme.getColor(color.id) : null;
|
||||
if (!c) {
|
||||
c = Color.transparent;
|
||||
}
|
||||
return c.toString();
|
||||
}
|
||||
|
||||
@@ -10,10 +10,12 @@ import { Range } from 'vs/editor/common/core/range';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { LineTokens } from 'vs/editor/common/core/lineTokens';
|
||||
import { PrefixSumComputerWithCache } from 'vs/editor/common/viewModel/prefixSumComputer';
|
||||
import { ViewLineData, ICoordinatesConverter } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { ViewLineData, ICoordinatesConverter, OverviewRulerDecoration } from 'vs/editor/common/viewModel/viewModel';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { WrappingIndent } from 'vs/editor/common/config/editorOptions';
|
||||
import { ModelDecorationOptions } from 'vs/editor/common/model/textModelWithDecorations';
|
||||
import { ModelDecorationOptions, ModelDecorationOverviewRulerOptions } from 'vs/editor/common/model/textModelWithDecorations';
|
||||
import { ThemeColor, ITheme } from 'vs/platform/theme/common/themeService';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
|
||||
export class OutputPosition {
|
||||
_outputPositionBrand: void;
|
||||
@@ -57,6 +59,7 @@ export interface ISplitLine {
|
||||
|
||||
getModelColumnOfViewPosition(outputLineIndex: number, outputColumn: number): number;
|
||||
getViewPositionOfModelPosition(deltaLineNumber: number, inputColumn: number): Position;
|
||||
getViewLineNumberOfModelPosition(deltaLineNumber: number, inputColumn: number): number;
|
||||
}
|
||||
|
||||
export interface IViewModelLinesCollection {
|
||||
@@ -82,6 +85,8 @@ export interface IViewModelLinesCollection {
|
||||
getViewLineMaxColumn(viewLineNumber: number): number;
|
||||
getViewLineData(viewLineNumber: number): ViewLineData;
|
||||
getViewLinesData(viewStartLineNumber: number, viewEndLineNumber: number, needed: boolean[]): ViewLineData[];
|
||||
|
||||
getAllOverviewRulerDecorations(ownerId: number, filterOutValidation: boolean, theme: ITheme): OverviewRulerDecoration[];
|
||||
}
|
||||
|
||||
export class CoordinatesConverter implements ICoordinatesConverter {
|
||||
@@ -650,6 +655,42 @@ export class SplitLinesCollection implements IViewModelLinesCollection {
|
||||
// console.log('in -> out ' + inputLineNumber + ',' + inputColumn + ' ===> ' + r.lineNumber + ',' + r);
|
||||
return r;
|
||||
}
|
||||
|
||||
private _getViewLineNumberForModelPosition(inputLineNumber: number, inputColumn: number): number {
|
||||
let lineIndex = inputLineNumber - 1;
|
||||
if (this.lines[lineIndex].isVisible()) {
|
||||
// this model line is visible
|
||||
const deltaLineNumber = 1 + (lineIndex === 0 ? 0 : this.prefixSumComputer.getAccumulatedValue(lineIndex - 1));
|
||||
return this.lines[lineIndex].getViewLineNumberOfModelPosition(deltaLineNumber, inputColumn);
|
||||
}
|
||||
|
||||
// this model line is not visible
|
||||
while (lineIndex > 0 && !this.lines[lineIndex].isVisible()) {
|
||||
lineIndex--;
|
||||
}
|
||||
if (lineIndex === 0 && !this.lines[lineIndex].isVisible()) {
|
||||
// Could not reach a real line
|
||||
return 1;
|
||||
}
|
||||
const deltaLineNumber = 1 + (lineIndex === 0 ? 0 : this.prefixSumComputer.getAccumulatedValue(lineIndex - 1));
|
||||
return this.lines[lineIndex].getViewLineNumberOfModelPosition(deltaLineNumber, this.model.getLineMaxColumn(lineIndex + 1));
|
||||
}
|
||||
|
||||
public getAllOverviewRulerDecorations(ownerId: number, filterOutValidation: boolean, theme: ITheme): OverviewRulerDecoration[] {
|
||||
const decorations = this.model.getOverviewRulerDecorations(ownerId, filterOutValidation);
|
||||
const result = new OverviewRulerDecorations();
|
||||
for (let i = 0, len = decorations.length; i < len; i++) {
|
||||
const decoration = decorations[i];
|
||||
const opts = <ModelDecorationOverviewRulerOptions>decoration.options.overviewRuler;
|
||||
const lane = opts.position;
|
||||
const color = resolveColor(opts, theme);
|
||||
const viewStartLineNumber = this._getViewLineNumberForModelPosition(decoration.range.startLineNumber, decoration.range.startColumn);
|
||||
const viewEndLineNumber = this._getViewLineNumberForModelPosition(decoration.range.endLineNumber, decoration.range.endColumn);
|
||||
|
||||
result.accept(color, viewStartLineNumber, viewEndLineNumber, lane);
|
||||
}
|
||||
return result.result;
|
||||
}
|
||||
}
|
||||
|
||||
class VisibleIdentitySplitLine implements ISplitLine {
|
||||
@@ -711,6 +752,10 @@ class VisibleIdentitySplitLine implements ISplitLine {
|
||||
public getViewPositionOfModelPosition(deltaLineNumber: number, inputColumn: number): Position {
|
||||
return new Position(deltaLineNumber, inputColumn);
|
||||
}
|
||||
|
||||
public getViewLineNumberOfModelPosition(deltaLineNumber: number, inputColumn: number): number {
|
||||
return deltaLineNumber;
|
||||
}
|
||||
}
|
||||
|
||||
class InvisibleIdentitySplitLine implements ISplitLine {
|
||||
@@ -761,6 +806,10 @@ class InvisibleIdentitySplitLine implements ISplitLine {
|
||||
public getViewPositionOfModelPosition(deltaLineNumber: number, inputColumn: number): Position {
|
||||
throw new Error('Not supported');
|
||||
}
|
||||
|
||||
public getViewLineNumberOfModelPosition(deltaLineNumber: number, inputColumn: number): number {
|
||||
throw new Error('Not supported');
|
||||
}
|
||||
}
|
||||
|
||||
export class SplitLine implements ISplitLine {
|
||||
@@ -914,6 +963,14 @@ export class SplitLine implements ISplitLine {
|
||||
// console.log('in -> out ' + deltaLineNumber + ',' + inputColumn + ' ===> ' + (deltaLineNumber+outputLineIndex) + ',' + outputColumn);
|
||||
return new Position(deltaLineNumber + outputLineIndex, outputColumn);
|
||||
}
|
||||
|
||||
public getViewLineNumberOfModelPosition(deltaLineNumber: number, inputColumn: number): number {
|
||||
if (!this._isVisible) {
|
||||
throw new Error('Not supported');
|
||||
}
|
||||
const r = this.positionMapper.getOutputPositionOfInputOffset(inputColumn - 1);
|
||||
return (deltaLineNumber + r.outputLineIndex);
|
||||
}
|
||||
}
|
||||
|
||||
function createSplitLine(linePositionMapperFactory: ILineMapperFactory, text: string, tabSize: number, wrappingColumn: number, columnsForFullWidthChar: number, wrappingIndent: WrappingIndent, isVisible: boolean): ISplitLine {
|
||||
@@ -1093,4 +1150,99 @@ export class IdentityLinesCollection implements IViewModelLinesCollection {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public getAllOverviewRulerDecorations(ownerId: number, filterOutValidation: boolean, theme: ITheme): OverviewRulerDecoration[] {
|
||||
const decorations = this.model.getOverviewRulerDecorations(ownerId, filterOutValidation);
|
||||
const result = new OverviewRulerDecorations();
|
||||
for (let i = 0, len = decorations.length; i < len; i++) {
|
||||
const decoration = decorations[i];
|
||||
const opts = <ModelDecorationOverviewRulerOptions>decoration.options.overviewRuler;
|
||||
const lane = opts.position;
|
||||
const color = resolveColor(opts, theme);
|
||||
const viewStartLineNumber = decoration.range.startLineNumber;
|
||||
const viewEndLineNumber = decoration.range.endLineNumber;
|
||||
|
||||
result.accept(color, viewStartLineNumber, viewEndLineNumber, lane);
|
||||
}
|
||||
result.flushAll();
|
||||
return result.result;
|
||||
}
|
||||
}
|
||||
|
||||
class OverviewRulerDecorations {
|
||||
|
||||
readonly req: OverviewRulerDecoration[] = [];
|
||||
readonly result: OverviewRulerDecoration[] = [];
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
public accept(color: string, startLineNumber: number, endLineNumber: number, lane: number): void {
|
||||
let result: OverviewRulerDecoration = null;
|
||||
for (let i = 0, len = this.req.length; i < len; i++) {
|
||||
const req = this.req[i];
|
||||
if (req.endLineNumber < startLineNumber) {
|
||||
this._flush(req);
|
||||
|
||||
if (i + 1 === len) {
|
||||
// last element
|
||||
this.req.pop();
|
||||
break;
|
||||
} else {
|
||||
this.req[i] = this.req.pop();
|
||||
len--;
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (req.lane === lane && req.color === color) {
|
||||
result = req;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result !== null) {
|
||||
// there is already an ongoing request for this color & lane
|
||||
// => simply merge into it
|
||||
if (endLineNumber > result.endLineNumber) {
|
||||
result.endLineNumber = endLineNumber;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
result = new OverviewRulerDecoration(startLineNumber, endLineNumber, lane, color);
|
||||
this.req.push(result);
|
||||
}
|
||||
|
||||
public flushAll(): void {
|
||||
for (let i = 0, len = this.req.length; i < len; i++) {
|
||||
this._flush(this.req[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private _flush(element: OverviewRulerDecoration): void {
|
||||
this.result.push(element);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function resolveColor(opts: ModelDecorationOverviewRulerOptions, theme: ITheme): string {
|
||||
if (!opts._resolvedColor) {
|
||||
const themeType = theme.type;
|
||||
const color = (themeType === 'dark' ? opts.darkColor : themeType === 'light' ? opts.color : opts.hcColor);
|
||||
opts._resolvedColor = resolveRulerColor(color, theme);
|
||||
}
|
||||
return opts._resolvedColor;
|
||||
}
|
||||
|
||||
function resolveRulerColor(color: string | ThemeColor, theme: ITheme): string {
|
||||
if (typeof color === 'string') {
|
||||
return color;
|
||||
}
|
||||
let c = color ? theme.getColor(color.id) : null;
|
||||
if (!c) {
|
||||
c = Color.transparent;
|
||||
}
|
||||
return c.toString();
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { INewScrollPosition, IModelDecoration, EndOfLinePreference, IViewState } from 'vs/editor/common/editorCommon';
|
||||
import { INewScrollPosition, IModelDecoration, EndOfLinePreference, IViewState, OverviewRulerLane } from 'vs/editor/common/editorCommon';
|
||||
import { ViewLineToken } from 'vs/editor/common/core/viewLineToken';
|
||||
import { Position, IPosition } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
@@ -14,6 +14,7 @@ import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Scrollable, IScrollPosition } from 'vs/base/common/scrollable';
|
||||
import { IPartialViewLinesViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData';
|
||||
import { IEditorWhitespace } from 'vs/editor/common/viewLayout/whitespaceComputer';
|
||||
import { ITheme } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
export interface IViewWhitespaceViewportData {
|
||||
readonly id: number;
|
||||
@@ -138,7 +139,8 @@ export interface IViewModel {
|
||||
getLineMaxColumn(lineNumber: number): number;
|
||||
getLineFirstNonWhitespaceColumn(lineNumber: number): number;
|
||||
getLineLastNonWhitespaceColumn(lineNumber: number): number;
|
||||
getAllOverviewRulerDecorations(): ViewModelDecoration[];
|
||||
getAllOverviewRulerDecorations(theme: ITheme): OverviewRulerDecoration[];
|
||||
invalidateOverviewRulerColorCache(): void;
|
||||
getValueInRange(range: Range, eol: EndOfLinePreference): string;
|
||||
|
||||
getModelLineMaxColumn(modelLineNumber: number): number;
|
||||
@@ -276,6 +278,17 @@ export class ViewModelDecoration {
|
||||
}
|
||||
}
|
||||
|
||||
export class OverviewRulerDecoration {
|
||||
_overviewRulerDecorationBrand: void;
|
||||
|
||||
constructor(
|
||||
public readonly startLineNumber: number,
|
||||
public endLineNumber: number,
|
||||
public readonly lane: OverviewRulerLane,
|
||||
public readonly color: string
|
||||
) { }
|
||||
}
|
||||
|
||||
export class ViewEventsCollector {
|
||||
|
||||
private _events: ViewEvent[];
|
||||
|
||||
@@ -88,17 +88,6 @@ export class ViewModelDecorations implements IDisposable {
|
||||
return r;
|
||||
}
|
||||
|
||||
public getAllOverviewRulerDecorations(): ViewModelDecoration[] {
|
||||
let modelDecorations = this.model.getOverviewRulerDecorations(this.editorId, this.configuration.editor.readOnly);
|
||||
let result: ViewModelDecoration[] = [], resultLen = 0;
|
||||
for (let i = 0, len = modelDecorations.length; i < len; i++) {
|
||||
let modelDecoration = modelDecorations[i];
|
||||
let viewModelDecoration = this._getOrCreateViewModelDecoration(modelDecoration);
|
||||
result[resultLen++] = viewModelDecoration;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public getDecorationsViewportData(viewRange: Range): IDecorationsViewportData {
|
||||
var cacheIsValid = true;
|
||||
cacheIsValid = cacheIsValid && (this._cachedModelDecorationsResolver !== null);
|
||||
|
||||
@@ -12,7 +12,7 @@ import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { TokenizationRegistry, ColorId, LanguageId } from 'vs/editor/common/modes';
|
||||
import { tokenizeLineToHTML } from 'vs/editor/common/modes/textToHtmlTokenizer';
|
||||
import { ViewModelDecorations } from 'vs/editor/common/viewModel/viewModelDecorations';
|
||||
import { MinimapLinesRenderingData, ViewLineRenderingData, ViewModelDecoration, IViewModel, ICoordinatesConverter, ViewEventsCollector } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { MinimapLinesRenderingData, ViewLineRenderingData, ViewModelDecoration, IViewModel, ICoordinatesConverter, ViewEventsCollector, OverviewRulerDecoration } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { SplitLinesCollection, IViewModelLinesCollection, IdentityLinesCollection } from 'vs/editor/common/viewModel/splitLinesCollection';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { MinimapTokensColorTracker } from 'vs/editor/common/view/minimapCharRenderer';
|
||||
@@ -22,6 +22,8 @@ import { CharacterHardWrappingLineMapperFactory } from 'vs/editor/common/viewMod
|
||||
import { ViewLayout } from 'vs/editor/common/viewLayout/viewLayout';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { ITheme } from 'vs/platform/theme/common/themeService';
|
||||
import { ModelDecorationOverviewRulerOptions } from 'vs/editor/common/model/textModelWithDecorations';
|
||||
|
||||
const USE_IDENTITY_LINES_COLLECTION = true;
|
||||
|
||||
@@ -428,8 +430,17 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
|
||||
);
|
||||
}
|
||||
|
||||
public getAllOverviewRulerDecorations(): ViewModelDecoration[] {
|
||||
return this.decorations.getAllOverviewRulerDecorations();
|
||||
public getAllOverviewRulerDecorations(theme: ITheme): OverviewRulerDecoration[] {
|
||||
return this.lines.getAllOverviewRulerDecorations(this.editorId, this.configuration.editor.readOnly, theme);
|
||||
}
|
||||
|
||||
public invalidateOverviewRulerColorCache(): void {
|
||||
const decorations = this.model.getOverviewRulerDecorations();
|
||||
for (let i = 0, len = decorations.length; i < len; i++) {
|
||||
const decoration = decorations[i];
|
||||
const opts = <ModelDecorationOverviewRulerOptions>decoration.options.overviewRuler;
|
||||
opts._resolvedColor = null;
|
||||
}
|
||||
}
|
||||
|
||||
public getValueInRange(range: Range, eol: editorCommon.EndOfLinePreference): string {
|
||||
|
||||
Reference in New Issue
Block a user