mirror of
https://github.com/voideditor/void
synced 2026-05-24 09:58:23 +00:00
better helperwidget positioning
This commit is contained in:
parent
77c031abc5
commit
51c84df5a5
1 changed files with 65 additions and 16 deletions
|
|
@ -14,10 +14,12 @@ import * as dom from '../../../../base/browser/dom.js';
|
|||
import { mountVoidSelectionHelper } from './react/out/void-editor-widgets-tsx/index.js';
|
||||
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
|
||||
import { IVoidSettingsService } from '../common/voidSettingsService.js';
|
||||
import { EditorOption } from '../../../../editor/common/config/editorOptions.js';
|
||||
import { getLengthOfTextPx } from './editCodeService.js';
|
||||
|
||||
|
||||
const minDistanceFromRightPx = 400;
|
||||
const minDistanceFromLeftPx = 60;
|
||||
const minLeftPx = 60;
|
||||
|
||||
|
||||
export type VoidSelectionHelperProps = {
|
||||
|
|
@ -156,34 +158,81 @@ export class SelectionHelperContribution extends Disposable implements IEditorCo
|
|||
|
||||
const model = this._editor.getModel()!;
|
||||
|
||||
// get the longest length of the nearest neighbors of the target
|
||||
const { tabSize: numSpacesInTab } = model.getFormattingOptions();
|
||||
const spaceWidth = this._editor.getOption(EditorOption.fontInfo).spaceWidth;
|
||||
const tabWidth = numSpacesInTab * spaceWidth;
|
||||
const numLinesModel = model.getLineCount()
|
||||
|
||||
// Calculate right edge of visible editor area
|
||||
const editorWidthPx = this._editor.getLayoutInfo().width;
|
||||
const maxLeftPx = editorWidthPx - minDistanceFromRightPx
|
||||
|
||||
// returns the position where the box should go on the targetLine
|
||||
const getBoxPosition = (targetLine: number): { top: number, left: number } => {
|
||||
|
||||
const targetPosition = this._editor.getScrolledVisiblePosition({ lineNumber: targetLine, column: 1 }) ?? { left: 0, top: 0 };
|
||||
|
||||
const { top: targetTop, left: targetLeft } = targetPosition
|
||||
|
||||
let targetWidth = 0;
|
||||
for (let i = targetLine; i <= targetLine + 1; i++) {
|
||||
|
||||
// if not in range, continue
|
||||
if (!(i >= 1) || !(i <= numLinesModel)) continue;
|
||||
|
||||
const content = model.getLineContent(i);
|
||||
const currWidth = getLengthOfTextPx({
|
||||
tabWidth,
|
||||
spaceWidth,
|
||||
content
|
||||
})
|
||||
|
||||
targetWidth = Math.max(targetWidth, currWidth);
|
||||
}
|
||||
|
||||
return {
|
||||
top: targetTop,
|
||||
left: targetLeft + targetWidth,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Calculate the middle line of the selection
|
||||
const startLine = selection.startLineNumber;
|
||||
const endLine = selection.endLineNumber;
|
||||
const middleLineNumber = Math.floor(startLine + (endLine - startLine) / 2);
|
||||
// const middleLine = Math.floor(startLine + (endLine - startLine) / 2);
|
||||
const targetLine = endLine - startLine + 1 <= 2 ? startLine : startLine + 2;
|
||||
|
||||
// Get the content of the middle line
|
||||
const lineContent = model.getLineContent(middleLineNumber);
|
||||
let boxPos = getBoxPosition(targetLine);
|
||||
|
||||
// Find the position at the end of the middle line
|
||||
const endOfLinePos = this._editor.getScrolledVisiblePosition({
|
||||
lineNumber: middleLineNumber,
|
||||
column: lineContent.length + 1 // +1 because columns are 1-based
|
||||
});
|
||||
// if the position of the box is too far to the right, keep searching for a good position
|
||||
let attempt = 0;
|
||||
const maxAttempts = 3;
|
||||
outerLoop: while (boxPos.left > maxLeftPx && attempt < maxAttempts) {
|
||||
attempt++
|
||||
|
||||
if (!endOfLinePos) {
|
||||
this._hideHelper();
|
||||
return;
|
||||
const linesToTry = [targetLine - attempt, targetLine + attempt]
|
||||
for (const line of linesToTry) {
|
||||
boxPos = getBoxPosition(line);
|
||||
if (boxPos.left <= maxLeftPx) {
|
||||
break outerLoop;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (boxPos.left > maxLeftPx) { // if still not found, make it the line before
|
||||
boxPos = getBoxPosition(targetLine - 1)
|
||||
}
|
||||
|
||||
// Calculate right edge of visible editor area
|
||||
const editorWidth = this._editor.getLayoutInfo().width;
|
||||
|
||||
// Position the helper element at the end of the middle line but ensure it's visible
|
||||
const xPosition = Math.max(Math.min(endOfLinePos.left, editorWidth - minDistanceFromRightPx), minDistanceFromLeftPx);
|
||||
const xPosition = Math.max(Math.min(boxPos.left, maxLeftPx), minLeftPx);
|
||||
const yPosition = boxPos.top;
|
||||
|
||||
// Update the React component position
|
||||
this._rootHTML.style.left = `${xPosition}px`;
|
||||
this._rootHTML.style.top = `${endOfLinePos.top}px`;
|
||||
this._rootHTML.style.top = `${yPosition}px`;
|
||||
this._rootHTML.style.display = 'flex'; // Show the container
|
||||
|
||||
this._isVisible = true;
|
||||
|
|
|
|||
Loading…
Reference in a new issue