提交 39a2da8f 编写于 作者: R Ramya Rao 提交者: GitHub

Use getDomNodePagePosition to position suggest docs (#26676)

* Use getDomNodePagePosition to position suggest docs

* Use css instead of setting width explicityl

* Simplifying adjustdocs
上级 e68316c5
......@@ -9,6 +9,17 @@
width: 660px;
}
.monaco-editor .suggest-widget > .tree,
.monaco-editor .suggest-widget > .details {
width: 330px;
}
.monaco-editor .suggest-widget.small,
.monaco-editor .suggest-widget.small > .tree,
.monaco-editor .suggest-widget.small > .details {
width: 400px;
}
.monaco-editor .suggest-widget.visible {
-webkit-transition: left .05s ease-in-out;
-moz-transition: left .05s ease-in-out;
......@@ -18,7 +29,6 @@
.monaco-editor .suggest-widget > .message {
padding-left: 22px;
opacity: 0.7;
}
.monaco-editor .suggest-widget > .tree {
......
......@@ -13,7 +13,7 @@ import Event, { Emitter, chain } from 'vs/base/common/event';
import { TPromise } from 'vs/base/common/winjs.base';
import { isPromiseCanceledError, onUnexpectedError } from 'vs/base/common/errors';
import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
import { addClass, append, $, hide, removeClass, show, toggleClass } from 'vs/base/browser/dom';
import { addClass, append, $, hide, removeClass, show, toggleClass, getDomNodePagePosition } from 'vs/base/browser/dom';
import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
import { IDelegate, IListEvent, IRenderer } from 'vs/base/browser/ui/list/list';
import { List } from 'vs/base/browser/ui/list/listWidget';
......@@ -30,8 +30,6 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { attachListStyler } from 'vs/platform/theme/common/styler';
import { IThemeService, ITheme, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { registerColor, editorWidgetBackground, listFocusBackground, activeContrastBorder, listHighlightForeground, editorForeground, editorWidgetBorder } from 'vs/platform/theme/common/colorRegistry';
import { Position } from 'vs/editor/common/core/position';
import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService';
const sticky = false; // for development purposes
......@@ -308,10 +306,8 @@ export class SuggestWidget implements IContentWidget, IDelegate<ICompletionItem>
readonly onDidHide: Event<this> = this.onDidHideEmitter.event;
readonly onDidShow: Event<this> = this.onDidShowEmitter.event;
private preferredPosition: Position;
private readonly maxWidgetWidth = 660;
private readonly listWidth = 330;
private readonly docsWidth = 330;
private readonly minWidgetWidth = 400;
constructor(
......@@ -319,8 +315,7 @@ export class SuggestWidget implements IContentWidget, IDelegate<ICompletionItem>
@ITelemetryService private telemetryService: ITelemetryService,
@IContextKeyService contextKeyService: IContextKeyService,
@IInstantiationService instantiationService: IInstantiationService,
@IThemeService themeService: IThemeService,
@IEditorGroupService private editorGroupService: IEditorGroupService
@IThemeService themeService: IThemeService
) {
this.isAuto = false;
this.focusedItem = null;
......@@ -508,9 +503,9 @@ export class SuggestWidget implements IContentWidget, IDelegate<ICompletionItem>
this.ignoreFocusEvents = false;
this.list.setFocus([index]);
this.updateWidgetHeight();
this.list.reveal(index);
this.showDetails();
this.adjustDocsPosition();
this._ariaAlert(this._getSuggestionAriaAlertLabel(item));
})
.then(null, err => !isPromiseCanceledError(err) && onUnexpectedError(err))
......@@ -782,7 +777,7 @@ export class SuggestWidget implements IContentWidget, IDelegate<ICompletionItem>
}
return {
position: this.preferredPosition ? this.preferredPosition : this.editor.getPosition(),
position: this.editor.getPosition(),
preference: [ContentWidgetPositionPreference.BELOW, ContentWidgetPositionPreference.ABOVE]
};
}
......@@ -821,74 +816,52 @@ export class SuggestWidget implements IContentWidget, IDelegate<ICompletionItem>
}
private adjustWidgetWidth() {
// Reset
removeClass(this.element, 'list-right');
removeClass(this.element, 'docs-below');
this.preferredPosition = this.editor.getPosition();
// Message element is shown, list and docs are not
if (this.messageElement.style.display !== 'none'
&& this.details.element.style.display === 'none'
&& this.listElement.style.display === 'none') {
this.element.style.width = `${this.minWidgetWidth}px`;
addClass(this.element, 'small');
return;
}
const perColumnWidth = this.editor.getLayoutInfo().contentWidth / this.editor.getLayoutInfo().viewportColumn;
const spaceOntheLeft = Math.floor(this.editor.getPosition().column * perColumnWidth) - this.editor.getScrollLeft();
const spaceOntheRight = this.editor.getLayoutInfo().contentWidth - spaceOntheLeft;
let matches = this.element.style.maxWidth.match(/(\d+)px/);
if (!matches || Number(matches[1]) >= this.maxWidgetWidth) {
// Reset width
removeClass(this.element, 'small');
}
// Reset width
this.details.element.style.width = `${this.docsWidth}px`;
this.element.style.width = `${this.maxWidgetWidth}px`;
this.listElement.style.width = `${this.listWidth}px`;
// Reset list margin
this.listElement.style.marginTop = '0px';
}
let editorStacksModel = this.editorGroupService.getStacksModel();
let totalEditors = editorStacksModel.groups.length;
let currentEditorPosition = editorStacksModel.positionOfGroup(editorStacksModel.activeGroup);
private adjustDocsPosition() {
const cursorCoords = this.editor.getScrolledVisiblePosition(this.editor.getPosition());
const editorCoords = getDomNodePagePosition(this.editor.getDomNode());
const cursorX = editorCoords.left + cursorCoords.left;
const cursorY = editorCoords.top + cursorCoords.top + cursorCoords.height;
const widgetX = this.element.offsetLeft;
const widgetY = this.element.offsetTop;
if (spaceOntheRight > this.maxWidgetWidth ||
(this.editorGroupService.getGroupOrientation() === 'vertical' && currentEditorPosition < totalEditors - 1)) {
// There is enough space on the right, so nothing to do here.
return;
}
removeClass(this.element, 'list-right');
if (this.editorGroupService.getGroupOrientation() === 'horizontal' || totalEditors === 1) {
if (this.editor.getLayoutInfo().contentWidth > this.maxWidgetWidth) {
if (spaceOntheRight < this.docsWidth) {
this.swapDocs();
}
return;
}
this.showDocsBelow();
if (this.element.clientWidth < this.maxWidgetWidth && this.listElement.clientWidth !== this.minWidgetWidth) {
// Not enough space to show side by side, so show docs below the list
addClass(this.element, 'small');
return;
}
// Its vertical, multiple editors, active editor is the last one and not enough space on the right for widget
// TODO: Check if window width < this.maxDocsWidth, in which case we may have to drop the docs below.
if (spaceOntheRight < this.docsWidth) {
this.swapDocs();
if (widgetX < cursorX - this.listWidth) {
// Widget is too far to the left of cursor, swap list and docs
addClass(this.element, 'list-right');
}
if (cursorY > widgetY && this.details.element.clientHeight > this.listElement.clientHeight) {
// Docs is bigger than list and widget is above cursor, apply margin-top so that list appears right above cursor
this.listElement.style.marginTop = `${this.details.element.clientHeight - this.listElement.clientHeight}px`;
}
}
private swapDocs() {
const perColumnWidth = this.editor.getLayoutInfo().contentWidth / this.editor.getLayoutInfo().viewportColumn;
const columnsOccupiedByDocs = Math.floor(this.docsWidth / perColumnWidth);
addClass(this.element, 'list-right');
this.preferredPosition = new Position(this.editor.getPosition().lineNumber, this.editor.getPosition().column - columnsOccupiedByDocs);
}
private showDocsBelow() {
// Not enough space to show side by side
// So show docs below the list
addClass(this.element, 'docs-below');
this.listElement.style.width = `${this.minWidgetWidth}px`;
this.element.style.width = `${this.minWidgetWidth}px`;
this.details.element.style.width = `${this.minWidgetWidth}px`;
}
private renderDetails(): void {
if (this.state === State.Details || this.state === State.Open) {
this.details.render(this.list.getFocusedElements()[0]);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册