improved column resize logic
This commit is contained in:
@@ -130,7 +130,9 @@ export class TrackList extends LitElement implements SelectionHost {
|
|||||||
private resizingColumn: number | null = null;
|
private resizingColumn: number | null = null;
|
||||||
private resizeStartX = 0;
|
private resizeStartX = 0;
|
||||||
private resizeStartWidths: number[] = [];
|
private resizeStartWidths: number[] = [];
|
||||||
private resizeObserver: ResizeObserver | null = null;
|
private resizeObserver: ResizeObserver | null =
|
||||||
|
null;
|
||||||
|
|
||||||
private flowLayout = flow();
|
private flowLayout = flow();
|
||||||
private hasRestoredScroll = false;
|
private hasRestoredScroll = false;
|
||||||
|
|
||||||
@@ -192,7 +194,11 @@ export class TrackList extends LitElement implements SelectionHost {
|
|||||||
const positions: number[] = [];
|
const positions: number[] = [];
|
||||||
let cumulative = padding;
|
let cumulative = padding;
|
||||||
|
|
||||||
for (let i = 0; i < this.columnWidths.length - 1; i++) {
|
for (
|
||||||
|
let i = 0;
|
||||||
|
i < this.columnWidths.length - 1;
|
||||||
|
i++
|
||||||
|
) {
|
||||||
cumulative += this.columnWidths[i] ?? 0;
|
cumulative += this.columnWidths[i] ?? 0;
|
||||||
positions.push(cumulative);
|
positions.push(cumulative);
|
||||||
}
|
}
|
||||||
@@ -429,30 +435,122 @@ export class TrackList extends LitElement implements SelectionHost {
|
|||||||
private onColResizeMove = (e: MouseEvent) => {
|
private onColResizeMove = (e: MouseEvent) => {
|
||||||
if (this.resizingColumn === null) return;
|
if (this.resizingColumn === null) return;
|
||||||
|
|
||||||
|
const container = this.clientWidth;
|
||||||
|
|
||||||
|
if (container <= 0) return;
|
||||||
|
|
||||||
const delta = e.clientX - this.resizeStartX;
|
const delta = e.clientX - this.resizeStartX;
|
||||||
const col = this.resizingColumn;
|
const col = this.resizingColumn;
|
||||||
const nextCol = col + 1;
|
const starts = this.resizeStartWidths;
|
||||||
const startLeft = this.resizeStartWidths[col] ?? 0;
|
|
||||||
const startRight = this.resizeStartWidths[nextCol] ?? 0;
|
|
||||||
const total = startLeft + startRight;
|
|
||||||
|
|
||||||
let newLeft = startLeft + delta;
|
// Sum of columns to the left (unchanged).
|
||||||
let newRight = startRight - delta;
|
let leftSum = 0;
|
||||||
|
|
||||||
if (newLeft < MIN_COLUMN_WIDTH) {
|
for (let i = 0; i < col; i++) {
|
||||||
newLeft = MIN_COLUMN_WIDTH;
|
leftSum += starts[i] ?? 0;
|
||||||
newRight = total - MIN_COLUMN_WIDTH;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newRight < MIN_COLUMN_WIDTH) {
|
// Count and sum of columns to the right.
|
||||||
newRight = MIN_COLUMN_WIDTH;
|
const rightCount =
|
||||||
newLeft = total - MIN_COLUMN_WIDTH;
|
starts.length - col - 1;
|
||||||
|
|
||||||
|
let rightSum = 0;
|
||||||
|
|
||||||
|
for (
|
||||||
|
let i = col + 1;
|
||||||
|
i < starts.length;
|
||||||
|
i++
|
||||||
|
) {
|
||||||
|
rightSum += starts[i] ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const updated = [...this.resizeStartWidths];
|
// Clamp dragged column: leave at least
|
||||||
|
// MIN_COLUMN_WIDTH for each right column.
|
||||||
|
const maxWidth =
|
||||||
|
container -
|
||||||
|
leftSum -
|
||||||
|
rightCount * MIN_COLUMN_WIDTH;
|
||||||
|
|
||||||
|
let newWidth = Math.max(
|
||||||
|
MIN_COLUMN_WIDTH,
|
||||||
|
Math.min(
|
||||||
|
maxWidth,
|
||||||
|
(starts[col] ?? 0) + delta,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
const updated: number[] = new Array(
|
||||||
|
starts.length,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Left columns keep starting widths.
|
||||||
|
for (let i = 0; i < col; i++) {
|
||||||
|
updated[i] = starts[i] ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
updated[col] = newWidth;
|
||||||
|
|
||||||
|
// Right columns always fill remaining space
|
||||||
|
// proportionally (handles both grow & shrink).
|
||||||
|
const availableForRight =
|
||||||
|
container - leftSum - newWidth;
|
||||||
|
|
||||||
|
if (rightCount === 0 || rightSum <= 0) {
|
||||||
|
// Nothing to distribute.
|
||||||
|
} else {
|
||||||
|
const scale =
|
||||||
|
availableForRight / rightSum;
|
||||||
|
|
||||||
|
let roundedSum = 0;
|
||||||
|
let maxIdx = -1;
|
||||||
|
let maxVal = 0;
|
||||||
|
|
||||||
|
for (
|
||||||
|
let i = col + 1;
|
||||||
|
i < starts.length;
|
||||||
|
i++
|
||||||
|
) {
|
||||||
|
const scaled = Math.max(
|
||||||
|
MIN_COLUMN_WIDTH,
|
||||||
|
Math.round(
|
||||||
|
(starts[i] ?? 0) * scale,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
updated[i] = scaled;
|
||||||
|
roundedSum += scaled;
|
||||||
|
|
||||||
|
if (scaled > maxVal) {
|
||||||
|
maxVal = scaled;
|
||||||
|
maxIdx = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fix rounding remainder on the widest
|
||||||
|
// right column.
|
||||||
|
const diff =
|
||||||
|
availableForRight - roundedSum;
|
||||||
|
|
||||||
|
if (diff !== 0 && maxIdx >= 0) {
|
||||||
|
updated[maxIdx] =
|
||||||
|
(updated[maxIdx] ?? 0) + diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-derive dragged width so total is
|
||||||
|
// exactly container.
|
||||||
|
newWidth =
|
||||||
|
container -
|
||||||
|
leftSum -
|
||||||
|
roundedSum -
|
||||||
|
diff;
|
||||||
|
|
||||||
|
if (newWidth < MIN_COLUMN_WIDTH) {
|
||||||
|
newWidth = MIN_COLUMN_WIDTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
updated[col] = newWidth;
|
||||||
|
}
|
||||||
|
|
||||||
updated[col] = newLeft;
|
|
||||||
updated[nextCol] = newRight;
|
|
||||||
this.columnWidths = updated;
|
this.columnWidths = updated;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -660,9 +758,11 @@ export class TrackList extends LitElement implements SelectionHost {
|
|||||||
document.addEventListener('mousemove', this.onColResizeMove);
|
document.addEventListener('mousemove', this.onColResizeMove);
|
||||||
document.addEventListener('mouseup', this.onColResizeEnd);
|
document.addEventListener('mouseup', this.onColResizeEnd);
|
||||||
|
|
||||||
this.resizeObserver = new ResizeObserver(() => {
|
this.resizeObserver = new ResizeObserver(
|
||||||
this.onHostResize();
|
() => {
|
||||||
});
|
this.onHostResize();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
this.resizeObserver.observe(this);
|
this.resizeObserver.observe(this);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user