Skip to content

Commit

Permalink
Inline edits UI enhancements (#237611)
Browse files Browse the repository at this point in the history
inline edits UI changes
  • Loading branch information
benibenj authored Jan 9, 2025
1 parent f74e6be commit ddf3841
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,11 @@ export class InlineEditsSideBySideDiff extends Disposable {
return;
}

this.previewEditor.layout({ height: layoutInfo.editHeight, width: layoutInfo.previewEditorWidth });

const topEdit = layoutInfo.edit1;
const bottomEdit = layoutInfo.edit2;

this.previewEditor.layout({ height: bottomEdit.y - topEdit.y, width: layoutInfo.previewEditorWidth });
this.previewEditor.updateOptions({ padding: { top: layoutInfo.padding, bottom: layoutInfo.padding } });
this._editorContainer.element.style.top = `${topEdit.y}px`;
this._editorContainer.element.style.left = `${topEdit.x}px`;
}));
Expand Down Expand Up @@ -261,6 +263,7 @@ export class InlineEditsSideBySideDiff extends Disposable {
overviewRulerLanes: 0,
lineDecorationsWidth: 0,
lineNumbersMinChars: 0,
revealHorizontalRightPadding: 0,
bracketPairColorization: { enabled: true, independentColorPoolPerBracketType: false },
scrollBeyondLastLine: false,
scrollbar: {
Expand Down Expand Up @@ -440,8 +443,10 @@ export class InlineEditsSideBySideDiff extends Disposable {

const previewEditorWidth = Math.min(previewContentWidth, remainingWidthRightOfEditor + editorLayout.width - editorLayout.contentLeft - codeEditDist);

const PADDING = 4;

const edit1 = new Point(left + codeEditDist, selectionTop);
const edit2 = new Point(left + codeEditDist, selectionTop + editHeight);
const edit2 = new Point(left + codeEditDist, selectionTop + editHeight + PADDING * 2);

return {
code1,
Expand All @@ -456,7 +461,9 @@ export class InlineEditsSideBySideDiff extends Disposable {
maxContentWidth,
shouldShowShadow: clipped,
desiredPreviewEditorScrollLeft,
previewEditorWidth
previewEditorWidth,
padding: PADDING,
borderRadius: PADDING
};
});

Expand Down Expand Up @@ -484,13 +491,28 @@ export class InlineEditsSideBySideDiff extends Disposable {
private readonly _extendedModifiedPath = derived(reader => {
const layoutInfo = this._previewEditorLayoutInfo.read(reader);
if (!layoutInfo) { return undefined; }
const width = layoutInfo.previewEditorWidth;
const width = layoutInfo.previewEditorWidth + layoutInfo.padding;


const topLeft = layoutInfo.edit1;
const topRight = layoutInfo.edit1.deltaX(width);
const topRightBefore = topRight.deltaX(-layoutInfo.borderRadius);
const topRightAfter = topRight.deltaY(layoutInfo.borderRadius);

const bottomLeft = layoutInfo.edit2;
const bottomRight = bottomLeft.deltaX(width);
const bottomRightBefore = bottomRight.deltaY(-layoutInfo.borderRadius);
const bottomRightAfter = bottomRight.deltaX(-layoutInfo.borderRadius);

const extendedModifiedPathBuilder = new PathBuilder()
.moveTo(layoutInfo.code1)
.lineTo(layoutInfo.edit1)
.lineTo(layoutInfo.edit1.deltaX(width))
.lineTo(layoutInfo.edit2.deltaX(width))
.lineTo(layoutInfo.edit2);
.lineTo(topLeft)
.lineTo(topRightBefore)
.curveTo(topRight, topRightAfter)
.lineTo(bottomRightBefore)
.curveTo(bottomRight, bottomRightAfter)
.lineTo(bottomLeft);

if (layoutInfo.edit2.y !== layoutInfo.code2.y) {
extendedModifiedPathBuilder.curveTo2(layoutInfo.edit2.deltaX(-20), layoutInfo.code2.deltaX(20), layoutInfo.code2.deltaX(0));
}
Expand Down Expand Up @@ -545,14 +567,26 @@ export class InlineEditsSideBySideDiff extends Disposable {
}),
]).keepUpdated(this._store);

private readonly _middleBorderWithShadow = n.div({
class: ['middleBorderWithShadow'],
style: {
position: 'absolute',
display: this._previewEditorLayoutInfo.map(i => i?.shouldShowShadow ? 'block' : 'none'),
width: '6px',
boxShadow: 'var(--vscode-scrollbar-shadow) -6px 0 6px -6px inset',
left: this._previewEditorLayoutInfo.map(i => i ? i.code1.x - 6 : 0),
top: this._previewEditorLayoutInfo.map(i => i ? i.code1.y : 0),
height: this._previewEditorLayoutInfo.map(i => i ? i.code2.y - i.code1.y : 0),
},
}, []).keepUpdated(this._store);

private readonly _foregroundSvg = n.svg({
transform: 'translate(-0.5 -0.5)',
style: { overflow: 'visible', pointerEvents: 'none', position: 'absolute' },
}, derived(reader => {
const layoutInfoObs = mapOutFalsy(this._previewEditorLayoutInfo).read(reader);
if (!layoutInfoObs) { return undefined; }

const shadowWidth = 6;
return [
n.svgElem('path', {
class: 'originalOverlay',
Expand All @@ -579,46 +613,19 @@ export class InlineEditsSideBySideDiff extends Disposable {
strokeWidth: '1px',
}
}),

...(!layoutInfoObs.map(i => i.shouldShowShadow).read(reader)
? [
n.svgElem('path', {
class: 'middleBorder',
d: layoutInfoObs.map(layoutInfo => new PathBuilder()
.moveTo(layoutInfo.code1)
.lineTo(layoutInfo.code2)
.build()
),
style: {
stroke: 'var(--vscode-inlineEdit-modifiedBorder)',
strokeWidth: '1px'
}
})
]
: [
n.svgElem('defs', {}, [
n.svgElem('linearGradient', { id: 'gradient', x1: '0%', x2: '100%', }, [
n.svgElem('stop', {
offset: '0%',
style: { stopColor: 'var(--vscode-inlineEdit-modifiedBorder)', stopOpacity: '0', }
}),
n.svgElem('stop', {
offset: '100%',
style: { stopColor: 'var(--vscode-inlineEdit-modifiedBorder)', stopOpacity: '1', }
})
])
]),
n.svgElem('rect', {
class: 'middleBorderWithShadow',
x: layoutInfoObs.map(layoutInfo => layoutInfo.code1.x - shadowWidth),
y: layoutInfoObs.map(layoutInfo => layoutInfo.code1.y),
width: shadowWidth,
height: layoutInfoObs.map(layoutInfo => layoutInfo.code2.y - layoutInfo.code1.y),
fill: 'url(#gradient)',
style: { strokeWidth: '0', stroke: 'transparent', }
})
]
)
n.svgElem('path', {
class: 'middleBorder',
d: layoutInfoObs.map(layoutInfo => new PathBuilder()
.moveTo(layoutInfo.code1)
.lineTo(layoutInfo.code2)
.build()
),
style: {
display: layoutInfoObs.map(i => i.shouldShowShadow ? 'none' : 'block'),
stroke: 'var(--vscode-inlineEdit-modifiedBorder)',
strokeWidth: '1px'
}
})
];
})).keepUpdated(this._store);

Expand All @@ -634,7 +641,7 @@ export class InlineEditsSideBySideDiff extends Disposable {
},
}, [
this._backgroundSvg,
derived(this, reader => this._shouldOverflow.read(reader) ? [] : [this._foregroundBackgroundSvg, this._editorContainer, this._foregroundSvg]),
derived(this, reader => this._shouldOverflow.read(reader) ? [] : [this._foregroundBackgroundSvg, this._editorContainer, this._foregroundSvg, this._middleBorderWithShadow]),
]).keepUpdated(this._store);

private readonly _overflowView = n.div({
Expand All @@ -645,6 +652,6 @@ export class InlineEditsSideBySideDiff extends Disposable {
display: this._display,
},
}, [
derived(this, reader => this._shouldOverflow.read(reader) ? [this._foregroundBackgroundSvg, this._editorContainer, this._foregroundSvg] : []),
derived(this, reader => this._shouldOverflow.read(reader) ? [this._foregroundBackgroundSvg, this._editorContainer, this._foregroundSvg, this._middleBorderWithShadow] : []),
]).keepUpdated(this._store);
}
Original file line number Diff line number Diff line change
Expand Up @@ -392,11 +392,13 @@ function setClassName(domNode: Element, className: string) {
function resolve<T>(value: ValueOrList<T>, reader: IReader | undefined, cb: (val: T) => void): void {
if (isObservable(value)) {
cb(value.read(reader));
return;
}
if (Array.isArray(value)) {
for (const v of value) {
resolve(v, reader, cb);
}
return;
}
cb(value as any);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const transparentHoverBackground = registerColor(
'inlineEdit.wordReplacementView.background',
{
light: transparent(editorHoverStatusBarBackground, 0.1),
dark: transparent(editorHoverStatusBarBackground, 0.5),
dark: transparent(editorHoverStatusBarBackground, 0.1),
hcLight: transparent(editorHoverStatusBarBackground, 0.1),
hcDark: transparent(editorHoverStatusBarBackground, 0.1),
},
Expand Down

0 comments on commit ddf3841

Please sign in to comment.