Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/editor/contrib/hover/browser/resizableContentWidget.ts
4779 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 { ResizableHTMLElement } from '../../../../base/browser/ui/resizable/resizable.js';
7
import { Disposable } from '../../../../base/common/lifecycle.js';
8
import { ContentWidgetPositionPreference, ICodeEditor, IContentWidget, IContentWidgetPosition } from '../../../browser/editorBrowser.js';
9
import { EditorOption } from '../../../common/config/editorOptions.js';
10
import { IPosition, Position } from '../../../common/core/position.js';
11
import * as dom from '../../../../base/browser/dom.js';
12
13
const TOP_HEIGHT = 30;
14
const BOTTOM_HEIGHT = 24;
15
16
export abstract class ResizableContentWidget extends Disposable implements IContentWidget {
17
18
readonly allowEditorOverflow: boolean = true;
19
readonly suppressMouseDown: boolean = false;
20
21
protected readonly _resizableNode = this._register(new ResizableHTMLElement());
22
protected _contentPosition: IContentWidgetPosition | null = null;
23
24
private _isResizing: boolean = false;
25
26
constructor(
27
protected readonly _editor: ICodeEditor,
28
minimumSize: dom.IDimension = new dom.Dimension(10, 10)
29
) {
30
super();
31
this._resizableNode.domNode.style.position = 'absolute';
32
this._resizableNode.minSize = dom.Dimension.lift(minimumSize);
33
this._resizableNode.layout(minimumSize.height, minimumSize.width);
34
this._resizableNode.enableSashes(true, true, true, true);
35
this._register(this._resizableNode.onDidResize(e => {
36
this._resize(new dom.Dimension(e.dimension.width, e.dimension.height));
37
if (e.done) {
38
this._isResizing = false;
39
}
40
}));
41
this._register(this._resizableNode.onDidWillResize(() => {
42
this._isResizing = true;
43
}));
44
}
45
46
get isResizing() {
47
return this._isResizing;
48
}
49
50
abstract getId(): string;
51
52
getDomNode(): HTMLElement {
53
return this._resizableNode.domNode;
54
}
55
56
getPosition(): IContentWidgetPosition | null {
57
return this._contentPosition;
58
}
59
60
get position(): Position | undefined {
61
return this._contentPosition?.position ? Position.lift(this._contentPosition.position) : undefined;
62
}
63
64
protected _availableVerticalSpaceAbove(position: IPosition): number | undefined {
65
const editorDomNode = this._editor.getDomNode();
66
const mouseBox = this._editor.getScrolledVisiblePosition(position);
67
if (!editorDomNode || !mouseBox) {
68
return;
69
}
70
const editorBox = dom.getDomNodePagePosition(editorDomNode);
71
return editorBox.top + mouseBox.top - TOP_HEIGHT;
72
}
73
74
protected _availableVerticalSpaceBelow(position: IPosition): number | undefined {
75
const editorDomNode = this._editor.getDomNode();
76
const mouseBox = this._editor.getScrolledVisiblePosition(position);
77
if (!editorDomNode || !mouseBox) {
78
return;
79
}
80
const editorBox = dom.getDomNodePagePosition(editorDomNode);
81
const bodyBox = dom.getClientArea(editorDomNode.ownerDocument.body);
82
const mouseBottom = editorBox.top + mouseBox.top + mouseBox.height;
83
return bodyBox.height - mouseBottom - BOTTOM_HEIGHT;
84
}
85
86
protected _findPositionPreference(widgetHeight: number, showAtPosition: IPosition): ContentWidgetPositionPreference | undefined {
87
const maxHeightBelow = Math.min(this._availableVerticalSpaceBelow(showAtPosition) ?? Infinity, widgetHeight);
88
const maxHeightAbove = Math.min(this._availableVerticalSpaceAbove(showAtPosition) ?? Infinity, widgetHeight);
89
const maxHeight = Math.min(Math.max(maxHeightAbove, maxHeightBelow), widgetHeight);
90
const height = Math.min(widgetHeight, maxHeight);
91
let renderingAbove: ContentWidgetPositionPreference;
92
if (this._editor.getOption(EditorOption.hover).above) {
93
renderingAbove = height <= maxHeightAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW;
94
} else {
95
renderingAbove = height <= maxHeightBelow ? ContentWidgetPositionPreference.BELOW : ContentWidgetPositionPreference.ABOVE;
96
}
97
if (renderingAbove === ContentWidgetPositionPreference.ABOVE) {
98
this._resizableNode.enableSashes(true, true, false, false);
99
} else {
100
this._resizableNode.enableSashes(false, true, true, false);
101
}
102
return renderingAbove;
103
}
104
105
protected _resize(dimension: dom.Dimension): void {
106
this._resizableNode.layout(dimension.height, dimension.width);
107
}
108
}
109
110