Skip to content

Commit df74b40

Browse files
committed
Introduce a MinimapModel
1 parent a937a14 commit df74b40

1 file changed

Lines changed: 166 additions & 47 deletions

File tree

src/vs/editor/browser/viewParts/minimap/minimap.ts

Lines changed: 166 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import * as dom from 'vs/base/browser/dom';
88
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
99
import { GlobalMouseMoveMonitor, IStandardMouseMoveEventData, standardMouseMoveMerger } from 'vs/base/browser/globalMouseMoveMonitor';
1010
import { CharCode } from 'vs/base/common/charCode';
11-
import { IDisposable } from 'vs/base/common/lifecycle';
11+
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
1212
import * as platform from 'vs/base/common/platform';
1313
import * as strings from 'vs/base/common/strings';
1414
import { ILine, RenderedLinesCollection } from 'vs/editor/browser/view/viewLayer';
@@ -24,15 +24,15 @@ import { MinimapTokensColorTracker } from 'vs/editor/common/viewModel/minimapTok
2424
import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
2525
import { ViewContext, EditorTheme } from 'vs/editor/common/view/viewContext';
2626
import * as viewEvents from 'vs/editor/common/view/viewEvents';
27-
import { ViewLineData } from 'vs/editor/common/viewModel/viewModel';
27+
import { ViewLineData, ViewModelDecoration, MinimapLinesRenderingData } from 'vs/editor/common/viewModel/viewModel';
2828
import { minimapSelection, scrollbarShadow, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground, minimapBackground } from 'vs/platform/theme/common/colorRegistry';
2929
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
3030
import { ModelDecorationMinimapOptions } from 'vs/editor/common/model/textModel';
3131
import { Selection } from 'vs/editor/common/core/selection';
3232
import { Color } from 'vs/base/common/color';
3333
import { GestureEvent, EventType, Gesture } from 'vs/base/browser/touch';
3434
import { MinimapCharRendererFactory } from 'vs/editor/browser/viewParts/minimap/minimapCharRendererFactory';
35-
import { MinimapPosition } from 'vs/editor/common/model';
35+
import { MinimapPosition, TextModelResolvedOptions } from 'vs/editor/common/model';
3636
import { once } from 'vs/base/common/functional';
3737

3838
function getMinimapLineHeight(renderMinimap: RenderMinimap, scale: number): number {
@@ -460,6 +460,132 @@ class MinimapBuffers {
460460

461461
export class Minimap extends ViewPart {
462462

463+
private _model: MinimapModel;
464+
private _actual: InnerMinimap;
465+
466+
constructor(context: ViewContext) {
467+
super(context);
468+
469+
this._model = new MinimapModel(context);
470+
this._actual = new InnerMinimap(context.configuration, context.theme, this._model);
471+
}
472+
473+
public dispose(): void {
474+
this._actual.dispose();
475+
super.dispose();
476+
}
477+
478+
public getDomNode(): FastDomNode<HTMLElement> {
479+
return this._actual.getDomNode();
480+
}
481+
482+
// ---- begin view event handlers
483+
484+
public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean {
485+
return this._actual.onConfigurationChanged(e);
486+
}
487+
public onCursorStateChanged(e: viewEvents.ViewCursorStateChangedEvent): boolean {
488+
return this._actual.onCursorStateChanged(e);
489+
}
490+
public onDecorationsChanged(e: viewEvents.ViewDecorationsChangedEvent): boolean {
491+
return this._actual.onDecorationsChanged(e);
492+
}
493+
public onFlushed(e: viewEvents.ViewFlushedEvent): boolean {
494+
return this._actual.onFlushed(e);
495+
}
496+
public onLinesChanged(e: viewEvents.ViewLinesChangedEvent): boolean {
497+
return this._actual.onLinesChanged(e);
498+
}
499+
public onLinesDeleted(e: viewEvents.ViewLinesDeletedEvent): boolean {
500+
return this._actual.onLinesDeleted(e);
501+
}
502+
public onLinesInserted(e: viewEvents.ViewLinesInsertedEvent): boolean {
503+
return this._actual.onLinesInserted(e);
504+
}
505+
public onScrollChanged(e: viewEvents.ViewScrollChangedEvent): boolean {
506+
return this._actual.onScrollChanged(e);
507+
}
508+
public onThemeChanged(e: viewEvents.ViewThemeChangedEvent): boolean {
509+
this._context.model.invalidateMinimapColorCache();
510+
this._actual.onThemeChanged(e);
511+
return true;
512+
}
513+
public onTokensChanged(e: viewEvents.ViewTokensChangedEvent): boolean {
514+
return this._actual.onTokensChanged(e);
515+
}
516+
public onTokensColorsChanged(e: viewEvents.ViewTokensColorsChangedEvent): boolean {
517+
return this._actual.onTokensColorsChanged(e);
518+
}
519+
public onZonesChanged(e: viewEvents.ViewZonesChangedEvent): boolean {
520+
return this._actual.onZonesChanged(e);
521+
}
522+
523+
// --- end event handlers
524+
525+
public prepareRender(ctx: RenderingContext): void {
526+
this._actual.prepareRender(ctx);
527+
}
528+
529+
public render(ctx: RestrictedRenderingContext): void {
530+
this._actual.render(ctx);
531+
}
532+
}
533+
534+
class MinimapModel {
535+
536+
private readonly _context: ViewContext;
537+
538+
constructor(context: ViewContext) {
539+
this._context = context;
540+
}
541+
542+
public getLineCount(): number {
543+
return this._context.model.getLineCount();
544+
}
545+
546+
public getLineContent(lineNumber: number): string {
547+
return this._context.model.getLineContent(lineNumber);
548+
}
549+
550+
public getLineMaxColumn(lineNumber: number): number {
551+
return this._context.model.getLineMaxColumn(lineNumber);
552+
}
553+
554+
public getMinimapLinesRenderingData(startLineNumber: number, endLineNumber: number, needed: boolean[]): MinimapLinesRenderingData {
555+
return this._context.model.getMinimapLinesRenderingData(startLineNumber, endLineNumber, needed);
556+
}
557+
558+
public getDecorationsInViewport(visibleRange: Range): ViewModelDecoration[] {
559+
return this._context.model.getDecorationsInViewport(visibleRange);
560+
}
561+
562+
public getOptions(): TextModelResolvedOptions {
563+
return this._context.model.getOptions();
564+
}
565+
566+
public revealLineNumber(lineNumber: number): void {
567+
this._context.privateViewEventBus.emit(new viewEvents.ViewRevealRangeRequestEvent(
568+
'mouse',
569+
new Range(lineNumber, 1, lineNumber, 1),
570+
viewEvents.VerticalRevealType.Center,
571+
false,
572+
ScrollType.Smooth
573+
));
574+
}
575+
576+
public setScrollTop(scrollTop: number): void {
577+
this._context.viewLayout.setScrollPositionNow({
578+
scrollTop: scrollTop
579+
});
580+
}
581+
}
582+
583+
class InnerMinimap extends Disposable {
584+
585+
private readonly _configuration: IConfiguration;
586+
private readonly _theme: EditorTheme;
587+
private readonly _model: MinimapModel;
588+
463589
private readonly _tokensColorTracker: MinimapTokensColorTracker;
464590
private readonly _domNode: FastDomNode<HTMLElement>;
465591
private readonly _shadow: FastDomNode<HTMLElement>;
@@ -483,14 +609,22 @@ export class Minimap extends ViewPart {
483609
private _gestureInProgress: boolean = false;
484610
private _buffers: MinimapBuffers | null;
485611

486-
constructor(context: ViewContext) {
487-
super(context);
612+
constructor(
613+
configuration: IConfiguration,
614+
theme: EditorTheme,
615+
model: MinimapModel
616+
) {
617+
super();
618+
619+
this._configuration = configuration;
620+
this._theme = theme;
621+
this._model = model;
488622

489623
this._tokensColorTracker = MinimapTokensColorTracker.getInstance();
490-
this._options = new MinimapOptions(this._context.configuration, this._context.theme, this._tokensColorTracker);
624+
this._options = new MinimapOptions(this._configuration, this._theme, this._tokensColorTracker);
491625
this._lastRenderData = null;
492626
this._buffers = null;
493-
this._selectionColor = this._context.theme.getColor(minimapSelection);
627+
this._selectionColor = this._theme.getColor(minimapSelection);
494628

495629
this._domNode = createFastDomNode(document.createElement('div'));
496630
PartFingerprints.write(this._domNode, PartFingerprint.Minimap);
@@ -543,15 +677,9 @@ export class Minimap extends ViewPart {
543677
const lineIndex = Math.floor(internalOffsetY / minimapLineHeight);
544678

545679
let lineNumber = lineIndex + this._lastRenderData.renderedLayout.startLineNumber;
546-
lineNumber = Math.min(lineNumber, this._context.model.getLineCount());
547-
548-
this._context.privateViewEventBus.emit(new viewEvents.ViewRevealRangeRequestEvent(
549-
'mouse',
550-
new Range(lineNumber, 1, lineNumber, 1),
551-
viewEvents.VerticalRevealType.Center,
552-
false,
553-
ScrollType.Smooth
554-
));
680+
lineNumber = Math.min(lineNumber, this._model.getLineCount());
681+
682+
this._model.revealLineNumber(lineNumber);
555683
});
556684

557685
this._sliderMouseMoveMonitor = new GlobalMouseMoveMonitor<IStandardMouseMoveEventData>();
@@ -575,16 +703,12 @@ export class Minimap extends ViewPart {
575703

576704
if (platform.isWindows && mouseOrthogonalDelta > MOUSE_DRAG_RESET_DISTANCE) {
577705
// The mouse has wondered away from the scrollbar => reset dragging
578-
this._context.viewLayout.setScrollPositionNow({
579-
scrollTop: initialSliderState.scrollTop
580-
});
706+
this._model.setScrollTop(initialSliderState.scrollTop);
581707
return;
582708
}
583709

584710
const mouseDelta = mouseMoveData.posy - initialMousePosition;
585-
this._context.viewLayout.setScrollPositionNow({
586-
scrollTop: initialSliderState.getDesiredScrollTopFromDelta(mouseDelta)
587-
});
711+
this._model.setScrollTop(initialSliderState.getDesiredScrollTopFromDelta(mouseDelta));
588712
},
589713
() => {
590714
this._slider.toggleClassName('active', false);
@@ -623,9 +747,7 @@ export class Minimap extends ViewPart {
623747
private scrollDueToTouchEvent(touch: GestureEvent) {
624748
const startY = this._domNode.domNode.getBoundingClientRect().top;
625749
const scrollTop = this._lastRenderData!.renderedLayout.getDesiredScrollTopFromTouchLocation(touch.pageY - startY);
626-
this._context.viewLayout.setScrollPositionNow({
627-
scrollTop: scrollTop
628-
});
750+
this._model.setScrollTop(scrollTop);
629751
}
630752

631753
public dispose(): void {
@@ -684,7 +806,7 @@ export class Minimap extends ViewPart {
684806
}
685807

686808
private _onOptionsMaybeChanged(): boolean {
687-
const opts = new MinimapOptions(this._context.configuration, this._context.theme, this._tokensColorTracker);
809+
const opts = new MinimapOptions(this._configuration, this._theme, this._tokensColorTracker);
688810
if (this._options.equals(opts)) {
689811
return false;
690812
}
@@ -706,6 +828,10 @@ export class Minimap extends ViewPart {
706828
this._renderDecorations = true;
707829
return true;
708830
}
831+
public onDecorationsChanged(e: viewEvents.ViewDecorationsChangedEvent): boolean {
832+
this._renderDecorations = true;
833+
return true;
834+
}
709835
public onFlushed(e: viewEvents.ViewFlushedEvent): boolean {
710836
this._lastRenderData = null;
711837
return true;
@@ -732,6 +858,12 @@ export class Minimap extends ViewPart {
732858
this._renderDecorations = true;
733859
return true;
734860
}
861+
public onThemeChanged(e: viewEvents.ViewThemeChangedEvent): boolean {
862+
this._selectionColor = this._theme.getColor(minimapSelection);
863+
this._renderDecorations = true;
864+
this._onOptionsMaybeChanged();
865+
return true;
866+
}
735867
public onTokensChanged(e: viewEvents.ViewTokensChangedEvent): boolean {
736868
if (this._lastRenderData) {
737869
return this._lastRenderData.onTokensChanged(e);
@@ -748,19 +880,6 @@ export class Minimap extends ViewPart {
748880
return true;
749881
}
750882

751-
public onDecorationsChanged(e: viewEvents.ViewDecorationsChangedEvent): boolean {
752-
this._renderDecorations = true;
753-
return true;
754-
}
755-
756-
public onThemeChanged(e: viewEvents.ViewThemeChangedEvent): boolean {
757-
this._context.model.invalidateMinimapColorCache();
758-
this._selectionColor = this._context.theme.getColor(minimapSelection);
759-
this._renderDecorations = true;
760-
this._onOptionsMaybeChanged();
761-
return true;
762-
}
763-
764883
// --- end event handlers
765884

766885
public prepareRender(ctx: RenderingContext): void {
@@ -787,7 +906,7 @@ export class Minimap extends ViewPart {
787906
renderingCtx.visibleRange.endLineNumber,
788907
renderingCtx.viewportHeight,
789908
(renderingCtx.viewportData.whitespaceViewportData.length > 0),
790-
this._context.model.getLineCount(),
909+
this._model.getLineCount(),
791910
renderingCtx.scrollTop,
792911
renderingCtx.scrollHeight,
793912
this._lastRenderData ? this._lastRenderData.renderedLayout : null
@@ -810,12 +929,12 @@ export class Minimap extends ViewPart {
810929
private renderDecorations(layout: MinimapLayout) {
811930
if (this._renderDecorations) {
812931
this._renderDecorations = false;
813-
const decorations = this._context.model.getDecorationsInViewport(new Range(layout.startLineNumber, 1, layout.endLineNumber, this._context.model.getLineMaxColumn(layout.endLineNumber)));
932+
const decorations = this._model.getDecorationsInViewport(new Range(layout.startLineNumber, 1, layout.endLineNumber, this._model.getLineMaxColumn(layout.endLineNumber)));
814933

815934
const { renderMinimap, canvasInnerWidth, canvasInnerHeight } = this._options;
816935
const lineHeight = getMinimapLineHeight(renderMinimap, this._options.fontScale);
817936
const characterWidth = getMinimapCharWidth(renderMinimap, this._options.fontScale);
818-
const tabSize = this._context.model.getOptions().tabSize;
937+
const tabSize = this._model.getOptions().tabSize;
819938
const canvasContext = this._decorationsCanvas.domNode.getContext('2d')!;
820939

821940
canvasContext.clearRect(0, 0, canvasInnerWidth, canvasInnerHeight);
@@ -837,7 +956,7 @@ export class Minimap extends ViewPart {
837956
continue;
838957
}
839958

840-
const decorationColor = (<ModelDecorationMinimapOptions>decoration.options.minimap).getColor(this._context.theme);
959+
const decorationColor = (<ModelDecorationMinimapOptions>decoration.options.minimap).getColor(this._theme);
841960
for (let line = decoration.range.startLineNumber; line <= decoration.range.endLineNumber; line++) {
842961
switch (decoration.options.minimap.position) {
843962

@@ -877,7 +996,7 @@ export class Minimap extends ViewPart {
877996
let lineIndexToXOffset = lineOffsetMap.get(lineNumber);
878997
const isFirstDecorationForLine = !lineIndexToXOffset;
879998
if (!lineIndexToXOffset) {
880-
const lineData = this._context.model.getLineContent(lineNumber);
999+
const lineData = this._model.getLineContent(lineNumber);
8811000
lineIndexToXOffset = [MINIMAP_GUTTER_WIDTH];
8821001
for (let i = 1; i < lineData.length + 1; i++) {
8831002
const charCode = lineData.charCodeAt(i - 1);
@@ -944,7 +1063,7 @@ export class Minimap extends ViewPart {
9441063
}
9451064

9461065
// Render untouched lines by using last rendered data.
947-
let [_dirtyY1, _dirtyY2, needed] = Minimap._renderUntouchedLines(
1066+
let [_dirtyY1, _dirtyY2, needed] = InnerMinimap._renderUntouchedLines(
9481067
imageData,
9491068
startLineNumber,
9501069
endLineNumber,
@@ -953,7 +1072,7 @@ export class Minimap extends ViewPart {
9531072
);
9541073

9551074
// Fetch rendering info from view model for rest of lines that need rendering.
956-
const lineInfo = this._context.model.getMinimapLinesRenderingData(startLineNumber, endLineNumber, needed);
1075+
const lineInfo = this._model.getMinimapLinesRenderingData(startLineNumber, endLineNumber, needed);
9571076
const tabSize = lineInfo.tabSize;
9581077
const background = this._options.backgroundColor;
9591078
const useLighterFont = this._tokensColorTracker.backgroundIsLight();
@@ -963,7 +1082,7 @@ export class Minimap extends ViewPart {
9631082
const renderedLines: MinimapLine[] = [];
9641083
for (let lineIndex = 0, lineCount = endLineNumber - startLineNumber + 1; lineIndex < lineCount; lineIndex++) {
9651084
if (needed[lineIndex]) {
966-
Minimap._renderLine(
1085+
InnerMinimap._renderLine(
9671086
imageData,
9681087
background,
9691088
useLighterFont,

0 commit comments

Comments
 (0)