bug: gap sizing fixes

This commit is contained in:
mathuo 2024-08-10 14:10:18 +01:00
parent 35b3ee2b0f
commit 49b1c5a174
No known key found for this signature in database
GPG Key ID: C6EEDEFD6CA07281
3 changed files with 155 additions and 24 deletions

View File

@ -782,8 +782,9 @@ describe('splitview', () => {
splitview.layout(924, 500);
const view1 = new Testview(0, 1000);
const view2 = new Testview(0, 1000, LayoutPriority.High);
const view2 = new Testview(0, 1000);
const view3 = new Testview(0, 1000);
const view4 = new Testview(0, 1000);
splitview.addView(view1);
expect([view1.size]).toEqual([924]);
@ -793,5 +794,108 @@ describe('splitview', () => {
splitview.addView(view3);
expect([view1.size, view2.size, view3.size]).toEqual([292, 292, 292]); // 292 + 24 + 292 + 24 + 292 = 924
splitview.addView(view4);
expect([view1.size, view2.size, view3.size, view4.size]).toEqual([
213, 213, 213, 213,
]); // 213 + 24 + 213 + 24 + 213 + 24 + 213 = 924
let viewQuery = Array.from(
container
.querySelectorAll(
'.split-view-container > .view-container > .view'
)
.entries()
)
.map(([i, e]) => e as HTMLElement)
.map((e) => ({
left: e.style.left,
top: e.style.top,
height: e.style.height,
width: e.style.width,
}));
let sashQuery = Array.from(
container
.querySelectorAll(
'.split-view-container > .sash-container > .sash'
)
.entries()
)
.map(([i, e]) => e as HTMLElement)
.map((e) => ({
left: e.style.left,
top: e.style.top,
}));
// check HTMLElement positions since these are the ones that really matter
expect(viewQuery).toEqual([
{ left: '0px', top: '', width: '213px', height: '' },
// 213 + 24 = 237
{ left: '237px', top: '', width: '213px', height: '' },
// 237 + 213 + 24 = 474
{ left: '474px', top: '', width: '213px', height: '' },
// 474 + 213 + 24 = 474
{ left: '711px', top: '', width: '213px', height: '' },
// 711 + 213 = 924
]);
// 924 / 4 = 231 view size
// 231 - (24*3/4) = 213 margin adjusted view size
// 213 - 4/2 + 24/2 = 223
expect(sashQuery).toEqual([
// 213 - 4/2 + 24/2 = 223
{ left: '223px', top: '0px' },
// 213 + 24 + 213 = 450
// 450 - 4/2 + 24/2 = 460
{ left: '460px', top: '0px' },
// 213 + 24 + 213 + 24 + 213 = 687
// 687 - 4/2 + 24/2 = 697
{ left: '697px', top: '0px' },
]);
splitview.setViewVisible(0, false);
viewQuery = Array.from(
container
.querySelectorAll(
'.split-view-container > .view-container > .view'
)
.entries()
)
.map(([i, e]) => e as HTMLElement)
.map((e) => ({
left: e.style.left,
top: e.style.top,
height: e.style.height,
width: e.style.width,
}));
sashQuery = Array.from(
container
.querySelectorAll(
'.split-view-container > .sash-container > .sash'
)
.entries()
)
.map(([i, e]) => e as HTMLElement)
.map((e) => ({
left: e.style.left,
top: e.style.top,
}));
expect(viewQuery).toEqual([
{ left: '0px', top: '', width: '0px', height: '' },
{ left: '0px', top: '', width: '215px', height: '' },
{ left: '239px', top: '', width: '215px', height: '' },
{ left: '478px', top: '', width: '446px', height: '' },
]);
expect(sashQuery).toEqual([
{ left: '0px', top: '0px' },
{ left: '225px', top: '0px' },
{ left: '464px', top: '0px' },
]);
});
});

View File

@ -811,47 +811,69 @@ export class Splitview {
return;
}
const visibleViewItemCount = this.viewItems.filter((i) => i.visible).length
const visibleViewItems = this.viewItems.filter((i) => i.visible);
const sashCount = visibleViewItemCount - 1
const marginReducedSize = (this.margin * sashCount) / visibleViewItemCount
const sashCount = Math.max(0, visibleViewItems.length - 1);
const marginReducedSize =
(this.margin * sashCount) / Math.max(1, visibleViewItems.length);
let totalLeftOffset = 0;
const viewLeftOffsets: number[] = [];
// Calc sashes style
for (let i = 0; i < this.viewItems.length - 1; i++) {
const sashWidth = 4; // hardcoded in css
const runningVisiblePanelCount = this.viewItems.reduce(
(arr, viewItem, i) => {
const flag = viewItem.visible ? 1 : 0;
if (i === 0) {
arr.push(flag);
} else {
arr.push(arr[i - 1] + flag);
}
return arr;
},
[] as number[]
);
// calculate both view and cash positions
this.viewItems.forEach((view, i) => {
totalLeftOffset += this.viewItems[i].size;
viewLeftOffsets.push(totalLeftOffset);
const offset = Math.min(
Math.max(0, totalLeftOffset - (1 + this.margin) / 2),
this.size - this.margin
);
const size = view.visible ? view.size - marginReducedSize : 0;
if (this._orientation === Orientation.HORIZONTAL) {
this.sashes[i].container.style.left = `${offset}px`;
this.sashes[i].container.style.top = `0px`;
}
if (this._orientation === Orientation.VERTICAL) {
this.sashes[i].container.style.left = `0px`;
this.sashes[i].container.style.top = `${offset}px`;
}
}
const visiblePanelsBeforeThisView = Math.max(0, runningVisiblePanelCount[i] - 1);
// Calc views style
this.viewItems.forEach((view, i) => {
const size = view.size - marginReducedSize;
const offset =
i === 0 || sashCount === 0
i === 0 || visiblePanelsBeforeThisView === 0
? 0
: viewLeftOffsets[i - 1] +
(i / sashCount) * marginReducedSize;
(visiblePanelsBeforeThisView / sashCount) * marginReducedSize;
if (i < this.viewItems.length - 1) {
// calculate sash position
const newSize = view.visible
? offset + size - sashWidth / 2 + this.margin / 2
: offset;
if (this._orientation === Orientation.HORIZONTAL) {
this.sashes[i].container.style.left = `${newSize}px`;
this.sashes[i].container.style.top = `0px`;
}
if (this._orientation === Orientation.VERTICAL) {
this.sashes[i].container.style.left = `0px`;
this.sashes[i].container.style.top = `${newSize}px`;
}
}
// calculate view position
if (this._orientation === Orientation.HORIZONTAL) {
view.container.style.width = `${size}px`;
view.container.style.left = `${offset}px`;
view.container.style.top = '';
view.container.style.height = '';
}
if (this._orientation === Orientation.VERTICAL) {

View File

@ -268,6 +268,8 @@
}
.vertical > .sash-container > .sash {
&:not(.disabled) {
&::after {
content: '';
height: 4px;
@ -287,9 +289,11 @@
);
}
}
}
}
.horizontal > .sash-container > .sash {
&:not(.disabled) {
&::after {
content: '';
height: 40px;
@ -309,6 +313,7 @@
);
}
}
}
}
}