Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/editor/browser/viewParts/overviewRuler/overviewRuler.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { FastDomNode, createFastDomNode } from '../../../../base/browser/fastDomNode.js';
7
import { IOverviewRuler } from '../../editorBrowser.js';
8
import { OverviewRulerPosition, EditorOption } from '../../../common/config/editorOptions.js';
9
import { ColorZone, OverviewRulerZone, OverviewZoneManager } from '../../../common/viewModel/overviewZoneManager.js';
10
import { ViewContext } from '../../../common/viewModel/viewContext.js';
11
import * as viewEvents from '../../../common/viewEvents.js';
12
import { ViewEventHandler } from '../../../common/viewEventHandler.js';
13
14
/**
15
* The overview ruler appears underneath the editor scroll bar and shows things
16
* like the cursor, various decorations, etc.
17
*/
18
export class OverviewRuler extends ViewEventHandler implements IOverviewRuler {
19
20
private readonly _context: ViewContext;
21
private readonly _domNode: FastDomNode<HTMLCanvasElement>;
22
private readonly _zoneManager: OverviewZoneManager;
23
24
constructor(context: ViewContext, cssClassName: string) {
25
super();
26
this._context = context;
27
const options = this._context.configuration.options;
28
29
this._domNode = createFastDomNode(document.createElement('canvas'));
30
this._domNode.setClassName(cssClassName);
31
this._domNode.setPosition('absolute');
32
this._domNode.setLayerHinting(true);
33
this._domNode.setContain('strict');
34
35
this._zoneManager = new OverviewZoneManager((lineNumber: number) => this._context.viewLayout.getVerticalOffsetForLineNumber(lineNumber));
36
this._zoneManager.setDOMWidth(0);
37
this._zoneManager.setDOMHeight(0);
38
this._zoneManager.setOuterHeight(this._context.viewLayout.getScrollHeight());
39
this._zoneManager.setLineHeight(options.get(EditorOption.lineHeight));
40
41
this._zoneManager.setPixelRatio(options.get(EditorOption.pixelRatio));
42
43
this._context.addEventHandler(this);
44
}
45
46
public override dispose(): void {
47
this._context.removeEventHandler(this);
48
super.dispose();
49
}
50
51
// ---- begin view event handlers
52
53
public override onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean {
54
const options = this._context.configuration.options;
55
56
if (e.hasChanged(EditorOption.lineHeight)) {
57
this._zoneManager.setLineHeight(options.get(EditorOption.lineHeight));
58
this._render();
59
}
60
61
if (e.hasChanged(EditorOption.pixelRatio)) {
62
this._zoneManager.setPixelRatio(options.get(EditorOption.pixelRatio));
63
this._domNode.setWidth(this._zoneManager.getDOMWidth());
64
this._domNode.setHeight(this._zoneManager.getDOMHeight());
65
this._domNode.domNode.width = this._zoneManager.getCanvasWidth();
66
this._domNode.domNode.height = this._zoneManager.getCanvasHeight();
67
this._render();
68
}
69
70
return true;
71
}
72
public override onFlushed(e: viewEvents.ViewFlushedEvent): boolean {
73
this._render();
74
return true;
75
}
76
public override onScrollChanged(e: viewEvents.ViewScrollChangedEvent): boolean {
77
if (e.scrollHeightChanged) {
78
this._zoneManager.setOuterHeight(e.scrollHeight);
79
this._render();
80
}
81
return true;
82
}
83
public override onZonesChanged(e: viewEvents.ViewZonesChangedEvent): boolean {
84
this._render();
85
return true;
86
}
87
88
// ---- end view event handlers
89
90
public getDomNode(): HTMLElement {
91
return this._domNode.domNode;
92
}
93
94
public setLayout(position: OverviewRulerPosition): void {
95
this._domNode.setTop(position.top);
96
this._domNode.setRight(position.right);
97
98
let hasChanged = false;
99
hasChanged = this._zoneManager.setDOMWidth(position.width) || hasChanged;
100
hasChanged = this._zoneManager.setDOMHeight(position.height) || hasChanged;
101
102
if (hasChanged) {
103
this._domNode.setWidth(this._zoneManager.getDOMWidth());
104
this._domNode.setHeight(this._zoneManager.getDOMHeight());
105
this._domNode.domNode.width = this._zoneManager.getCanvasWidth();
106
this._domNode.domNode.height = this._zoneManager.getCanvasHeight();
107
108
this._render();
109
}
110
}
111
112
public setZones(zones: OverviewRulerZone[]): void {
113
this._zoneManager.setZones(zones);
114
this._render();
115
}
116
117
private _render(): boolean {
118
if (this._zoneManager.getOuterHeight() === 0) {
119
return false;
120
}
121
122
const width = this._zoneManager.getCanvasWidth();
123
const height = this._zoneManager.getCanvasHeight();
124
125
const colorZones = this._zoneManager.resolveColorZones();
126
const id2Color = this._zoneManager.getId2Color();
127
128
const ctx = this._domNode.domNode.getContext('2d')!;
129
ctx.clearRect(0, 0, width, height);
130
if (colorZones.length > 0) {
131
this._renderOneLane(ctx, colorZones, id2Color, width);
132
}
133
134
return true;
135
}
136
137
private _renderOneLane(ctx: CanvasRenderingContext2D, colorZones: ColorZone[], id2Color: string[], width: number): void {
138
139
let currentColorId = 0;
140
let currentFrom = 0;
141
let currentTo = 0;
142
143
for (const zone of colorZones) {
144
145
const zoneColorId = zone.colorId;
146
const zoneFrom = zone.from;
147
const zoneTo = zone.to;
148
149
if (zoneColorId !== currentColorId) {
150
ctx.fillRect(0, currentFrom, width, currentTo - currentFrom);
151
152
currentColorId = zoneColorId;
153
ctx.fillStyle = id2Color[currentColorId];
154
currentFrom = zoneFrom;
155
currentTo = zoneTo;
156
} else {
157
if (currentTo >= zoneFrom) {
158
currentTo = Math.max(currentTo, zoneTo);
159
} else {
160
ctx.fillRect(0, currentFrom, width, currentTo - currentFrom);
161
currentFrom = zoneFrom;
162
currentTo = zoneTo;
163
}
164
}
165
}
166
167
ctx.fillRect(0, currentFrom, width, currentTo - currentFrom);
168
169
}
170
}
171
172