提交 c64f16d3 编写于 作者: A Alex Dima

Inline OverviewRulerImpl (#38418)

上级 a44cbeec
......@@ -6,37 +6,56 @@
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
import { IOverviewRuler } from 'vs/editor/browser/editorBrowser';
import { OverviewRulerImpl } from 'vs/editor/browser/viewParts/overviewRuler/overviewRulerImpl';
import { ViewContext } from 'vs/editor/common/view/viewContext';
import * as viewEvents from 'vs/editor/common/view/viewEvents';
import { OverviewRulerPosition } from 'vs/editor/common/config/editorOptions';
import { OverviewRulerZone } from 'vs/editor/common/view/overviewZoneManager';
import { OverviewRulerZone, OverviewZoneManager, ColorZone } from 'vs/editor/common/view/overviewZoneManager';
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
import { Color } from 'vs/base/common/color';
import { LIGHT } from 'vs/platform/theme/common/themeService';
import { OverviewRulerLane } from 'vs/editor/common/editorCommon';
export class OverviewRuler extends ViewEventHandler implements IOverviewRuler {
private _context: ViewContext;
private _overviewRuler: OverviewRulerImpl;
private _canvasLeftOffset: number;
private _domNode: FastDomNode<HTMLCanvasElement>;
private _lanesCount: number;
private _zoneManager: OverviewZoneManager;
private _background: Color;
constructor(context: ViewContext, cssClassName: string, minimumHeight: number, maximumHeight: number) {
super();
this._context = context;
this._overviewRuler = new OverviewRulerImpl(
0,
cssClassName,
this._context.viewLayout.getScrollHeight(),
this._context.configuration.editor.lineHeight,
this._context.configuration.editor.pixelRatio,
minimumHeight,
maximumHeight,
(lineNumber: number) => this._context.viewLayout.getVerticalOffsetForLineNumber(lineNumber)
);
this._canvasLeftOffset = 0;
this._domNode = createFastDomNode(document.createElement('canvas'));
this._domNode.setClassName(cssClassName);
this._domNode.setPosition('absolute');
this._domNode.setLayerHinting(true);
this._lanesCount = 3;
this._background = null;
this._zoneManager = new OverviewZoneManager((lineNumber: number) => this._context.viewLayout.getVerticalOffsetForLineNumber(lineNumber));
this._zoneManager.setMinimumHeight(minimumHeight);
this._zoneManager.setMaximumHeight(maximumHeight);
this._zoneManager.setThemeType(LIGHT);
this._zoneManager.setDOMWidth(0);
this._zoneManager.setDOMHeight(0);
this._zoneManager.setOuterHeight(this._context.viewLayout.getScrollHeight());
this._zoneManager.setLineHeight(this._context.configuration.editor.lineHeight);
this._zoneManager.setPixelRatio(this._context.configuration.editor.pixelRatio);
this._context.addEventHandler(this);
}
public dispose(): void {
this._context.removeEventHandler(this);
this._overviewRuler.dispose();
this._zoneManager = null;
super.dispose();
}
......@@ -44,11 +63,17 @@ export class OverviewRuler extends ViewEventHandler implements IOverviewRuler {
public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean {
if (e.lineHeight) {
this._overviewRuler.setLineHeight(this._context.configuration.editor.lineHeight, true);
this._zoneManager.setLineHeight(this._context.configuration.editor.lineHeight);
this.render(true);
}
if (e.pixelRatio) {
this._overviewRuler.setPixelRatio(this._context.configuration.editor.pixelRatio, true);
this._zoneManager.setPixelRatio(this._context.configuration.editor.pixelRatio);
this._domNode.setWidth(this._zoneManager.getDOMWidth());
this._domNode.setHeight(this._zoneManager.getDOMHeight());
this._domNode.domNode.width = this._zoneManager.getCanvasWidth();
this._domNode.domNode.height = this._zoneManager.getCanvasHeight();
this.render(true);
}
return true;
......@@ -59,7 +84,8 @@ export class OverviewRuler extends ViewEventHandler implements IOverviewRuler {
}
public onScrollChanged(e: viewEvents.ViewScrollChangedEvent): boolean {
this._overviewRuler.setScrollHeight(e.scrollHeight, true);
this._zoneManager.setOuterHeight(e.scrollHeight);
this.render(true);
return super.onScrollChanged(e) || e.scrollHeightChanged;
}
......@@ -70,14 +96,134 @@ export class OverviewRuler extends ViewEventHandler implements IOverviewRuler {
// ---- end view event handlers
public getDomNode(): HTMLElement {
return this._overviewRuler.getDomNode();
return this._domNode.domNode;
}
public setLayout(position: OverviewRulerPosition): void {
this._overviewRuler.setLayout(position, true);
this._domNode.setTop(position.top);
this._domNode.setRight(position.right);
let hasChanged = false;
hasChanged = this._zoneManager.setDOMWidth(position.width) || hasChanged;
hasChanged = this._zoneManager.setDOMHeight(position.height) || hasChanged;
if (hasChanged) {
this._domNode.setWidth(this._zoneManager.getDOMWidth());
this._domNode.setHeight(this._zoneManager.getDOMHeight());
this._domNode.domNode.width = this._zoneManager.getCanvasWidth();
this._domNode.domNode.height = this._zoneManager.getCanvasHeight();
this.render(true);
}
}
public setZones(zones: OverviewRulerZone[]): void {
this._overviewRuler.setZones(zones, true);
this._zoneManager.setZones(zones);
this.render(false);
}
public render(forceRender: boolean): boolean {
if (this._zoneManager.getOuterHeight() === 0) {
return false;
}
const width = this._zoneManager.getCanvasWidth();
const height = this._zoneManager.getCanvasHeight();
let colorZones = this._zoneManager.resolveColorZones();
let id2Color = this._zoneManager.getId2Color();
let ctx = this._domNode.domNode.getContext('2d');
if (this._background === null) {
ctx.clearRect(0, 0, width, height);
} else {
ctx.fillStyle = Color.Format.CSS.formatHex(this._background);
ctx.fillRect(0, 0, width, height);
}
if (colorZones.length > 0) {
let remainingWidth = width - this._canvasLeftOffset;
if (this._lanesCount >= 3) {
this._renderThreeLanes(ctx, colorZones, id2Color, remainingWidth);
} else if (this._lanesCount === 2) {
this._renderTwoLanes(ctx, colorZones, id2Color, remainingWidth);
} else if (this._lanesCount === 1) {
this._renderOneLane(ctx, colorZones, id2Color, remainingWidth);
}
}
return true;
}
private _renderOneLane(ctx: CanvasRenderingContext2D, colorZones: ColorZone[], id2Color: string[], w: number): void {
this._renderVerticalPatch(ctx, colorZones, id2Color, OverviewRulerLane.Left | OverviewRulerLane.Center | OverviewRulerLane.Right, this._canvasLeftOffset, w);
}
private _renderTwoLanes(ctx: CanvasRenderingContext2D, colorZones: ColorZone[], id2Color: string[], w: number): void {
let leftWidth = Math.floor(w / 2);
let rightWidth = w - leftWidth;
let leftOffset = this._canvasLeftOffset;
let rightOffset = this._canvasLeftOffset + leftWidth;
this._renderVerticalPatch(ctx, colorZones, id2Color, OverviewRulerLane.Left | OverviewRulerLane.Center, leftOffset, leftWidth);
this._renderVerticalPatch(ctx, colorZones, id2Color, OverviewRulerLane.Right, rightOffset, rightWidth);
}
private _renderThreeLanes(ctx: CanvasRenderingContext2D, colorZones: ColorZone[], id2Color: string[], w: number): void {
let leftWidth = Math.floor(w / 3);
let rightWidth = Math.floor(w / 3);
let centerWidth = w - leftWidth - rightWidth;
let leftOffset = this._canvasLeftOffset;
let centerOffset = this._canvasLeftOffset + leftWidth;
let rightOffset = this._canvasLeftOffset + leftWidth + centerWidth;
this._renderVerticalPatch(ctx, colorZones, id2Color, OverviewRulerLane.Left, leftOffset, leftWidth);
this._renderVerticalPatch(ctx, colorZones, id2Color, OverviewRulerLane.Center, centerOffset, centerWidth);
this._renderVerticalPatch(ctx, colorZones, id2Color, OverviewRulerLane.Right, rightOffset, rightWidth);
}
private _renderVerticalPatch(ctx: CanvasRenderingContext2D, colorZones: ColorZone[], id2Color: string[], laneMask: number, xpos: number, width: number): void {
let currentColorId = 0;
let currentFrom = 0;
let currentTo = 0;
for (let i = 0, len = colorZones.length; i < len; i++) {
let zone = colorZones[i];
if (!(zone.position & laneMask)) {
continue;
}
let zoneColorId = zone.colorId;
let zoneFrom = zone.from;
let zoneTo = zone.to;
if (zoneColorId !== currentColorId) {
ctx.fillRect(xpos, currentFrom, width, currentTo - currentFrom);
currentColorId = zoneColorId;
ctx.fillStyle = id2Color[currentColorId];
currentFrom = zoneFrom;
currentTo = zoneTo;
} else {
if (currentTo >= zoneFrom) {
currentTo = Math.max(currentTo, zoneTo);
} else {
ctx.fillRect(xpos, currentFrom, width, currentTo - currentFrom);
currentFrom = zoneFrom;
currentTo = zoneTo;
}
}
}
ctx.fillRect(xpos, currentFrom, width, currentTo - currentFrom);
}
}
\ No newline at end of file
}
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
import { OverviewRulerLane } from 'vs/editor/common/editorCommon';
import { OverviewZoneManager, ColorZone, OverviewRulerZone } from 'vs/editor/common/view/overviewZoneManager';
import { Color } from 'vs/base/common/color';
import { OverviewRulerPosition } from 'vs/editor/common/config/editorOptions';
import { ThemeType, LIGHT } from 'vs/platform/theme/common/themeService';
export class OverviewRulerImpl {
private _canvasLeftOffset: number;
private _domNode: FastDomNode<HTMLCanvasElement>;
private _lanesCount: number;
private _zoneManager: OverviewZoneManager;
private _background: Color;
constructor(
canvasLeftOffset: number, cssClassName: string, scrollHeight: number, lineHeight: number,
pixelRatio: number, minimumHeight: number, maximumHeight: number,
getVerticalOffsetForLine: (lineNumber: number) => number
) {
this._canvasLeftOffset = canvasLeftOffset;
this._domNode = createFastDomNode(document.createElement('canvas'));
this._domNode.setClassName(cssClassName);
this._domNode.setPosition('absolute');
this._domNode.setLayerHinting(true);
this._lanesCount = 3;
this._background = null;
this._zoneManager = new OverviewZoneManager(getVerticalOffsetForLine);
this._zoneManager.setMinimumHeight(minimumHeight);
this._zoneManager.setMaximumHeight(maximumHeight);
this._zoneManager.setThemeType(LIGHT);
this._zoneManager.setDOMWidth(0);
this._zoneManager.setDOMHeight(0);
this._zoneManager.setOuterHeight(scrollHeight);
this._zoneManager.setLineHeight(lineHeight);
this._zoneManager.setPixelRatio(pixelRatio);
}
public dispose(): void {
this._zoneManager = null;
}
public setLayout(position: OverviewRulerPosition, render: boolean): void {
this._domNode.setTop(position.top);
this._domNode.setRight(position.right);
let hasChanged = false;
hasChanged = this._zoneManager.setDOMWidth(position.width) || hasChanged;
hasChanged = this._zoneManager.setDOMHeight(position.height) || hasChanged;
if (hasChanged) {
this._domNode.setWidth(this._zoneManager.getDOMWidth());
this._domNode.setHeight(this._zoneManager.getDOMHeight());
this._domNode.domNode.width = this._zoneManager.getCanvasWidth();
this._domNode.domNode.height = this._zoneManager.getCanvasHeight();
if (render) {
this.render(true);
}
}
}
public getLanesCount(): number {
return this._lanesCount;
}
public setLanesCount(newLanesCount: number, render: boolean): void {
this._lanesCount = newLanesCount;
if (render) {
this.render(true);
}
}
public setThemeType(themeType: ThemeType, render: boolean): void {
this._zoneManager.setThemeType(themeType);
if (render) {
this.render(true);
}
}
public setUseBackground(background: Color, render: boolean): void {
this._background = background;
if (render) {
this.render(true);
}
}
public getDomNode(): HTMLCanvasElement {
return this._domNode.domNode;
}
public getPixelWidth(): number {
return this._zoneManager.getCanvasWidth();
}
public getPixelHeight(): number {
return this._zoneManager.getCanvasHeight();
}
public setScrollHeight(scrollHeight: number, render: boolean): void {
this._zoneManager.setOuterHeight(scrollHeight);
if (render) {
this.render(true);
}
}
public setLineHeight(lineHeight: number, render: boolean): void {
this._zoneManager.setLineHeight(lineHeight);
if (render) {
this.render(true);
}
}
public setPixelRatio(pixelRatio: number, render: boolean): void {
this._zoneManager.setPixelRatio(pixelRatio);
this._domNode.setWidth(this._zoneManager.getDOMWidth());
this._domNode.setHeight(this._zoneManager.getDOMHeight());
this._domNode.domNode.width = this._zoneManager.getCanvasWidth();
this._domNode.domNode.height = this._zoneManager.getCanvasHeight();
if (render) {
this.render(true);
}
}
public setZones(zones: OverviewRulerZone[], render: boolean): void {
this._zoneManager.setZones(zones);
if (render) {
this.render(false);
}
}
public render(forceRender: boolean): boolean {
if (this._zoneManager.getOuterHeight() === 0) {
return false;
}
const width = this._zoneManager.getCanvasWidth();
const height = this._zoneManager.getCanvasHeight();
let colorZones = this._zoneManager.resolveColorZones();
let id2Color = this._zoneManager.getId2Color();
let ctx = this._domNode.domNode.getContext('2d');
if (this._background === null) {
ctx.clearRect(0, 0, width, height);
} else {
ctx.fillStyle = Color.Format.CSS.formatHex(this._background);
ctx.fillRect(0, 0, width, height);
}
if (colorZones.length > 0) {
let remainingWidth = width - this._canvasLeftOffset;
if (this._lanesCount >= 3) {
this._renderThreeLanes(ctx, colorZones, id2Color, remainingWidth);
} else if (this._lanesCount === 2) {
this._renderTwoLanes(ctx, colorZones, id2Color, remainingWidth);
} else if (this._lanesCount === 1) {
this._renderOneLane(ctx, colorZones, id2Color, remainingWidth);
}
}
return true;
}
private _renderOneLane(ctx: CanvasRenderingContext2D, colorZones: ColorZone[], id2Color: string[], w: number): void {
this._renderVerticalPatch(ctx, colorZones, id2Color, OverviewRulerLane.Left | OverviewRulerLane.Center | OverviewRulerLane.Right, this._canvasLeftOffset, w);
}
private _renderTwoLanes(ctx: CanvasRenderingContext2D, colorZones: ColorZone[], id2Color: string[], w: number): void {
let leftWidth = Math.floor(w / 2);
let rightWidth = w - leftWidth;
let leftOffset = this._canvasLeftOffset;
let rightOffset = this._canvasLeftOffset + leftWidth;
this._renderVerticalPatch(ctx, colorZones, id2Color, OverviewRulerLane.Left | OverviewRulerLane.Center, leftOffset, leftWidth);
this._renderVerticalPatch(ctx, colorZones, id2Color, OverviewRulerLane.Right, rightOffset, rightWidth);
}
private _renderThreeLanes(ctx: CanvasRenderingContext2D, colorZones: ColorZone[], id2Color: string[], w: number): void {
let leftWidth = Math.floor(w / 3);
let rightWidth = Math.floor(w / 3);
let centerWidth = w - leftWidth - rightWidth;
let leftOffset = this._canvasLeftOffset;
let centerOffset = this._canvasLeftOffset + leftWidth;
let rightOffset = this._canvasLeftOffset + leftWidth + centerWidth;
this._renderVerticalPatch(ctx, colorZones, id2Color, OverviewRulerLane.Left, leftOffset, leftWidth);
this._renderVerticalPatch(ctx, colorZones, id2Color, OverviewRulerLane.Center, centerOffset, centerWidth);
this._renderVerticalPatch(ctx, colorZones, id2Color, OverviewRulerLane.Right, rightOffset, rightWidth);
}
private _renderVerticalPatch(ctx: CanvasRenderingContext2D, colorZones: ColorZone[], id2Color: string[], laneMask: number, xpos: number, width: number): void {
let currentColorId = 0;
let currentFrom = 0;
let currentTo = 0;
for (let i = 0, len = colorZones.length; i < len; i++) {
let zone = colorZones[i];
if (!(zone.position & laneMask)) {
continue;
}
let zoneColorId = zone.colorId;
let zoneFrom = zone.from;
let zoneTo = zone.to;
if (zoneColorId !== currentColorId) {
ctx.fillRect(xpos, currentFrom, width, currentTo - currentFrom);
currentColorId = zoneColorId;
ctx.fillStyle = id2Color[currentColorId];
currentFrom = zoneFrom;
currentTo = zoneTo;
} else {
if (currentTo >= zoneFrom) {
currentTo = Math.max(currentTo, zoneTo);
} else {
ctx.fillRect(xpos, currentFrom, width, currentTo - currentFrom);
currentFrom = zoneFrom;
currentTo = zoneTo;
}
}
}
ctx.fillRect(xpos, currentFrom, width, currentTo - currentFrom);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册