mirror of
https://github.com/esjeon/krohnkite.git
synced 2024-10-03 23:07:13 +03:00
implement ColumnLayout adjustment
This commit is contained in:
parent
f119d47a4e
commit
ab9b0f5a82
@ -53,8 +53,77 @@ class ColumnLayout implements ILayout {
|
||||
this.tileWeights = new LayoutWeightMap();
|
||||
}
|
||||
|
||||
// public adjust(area: Rect, tiles: Window[], basis: Window): void {
|
||||
// }
|
||||
public adjust(area: Rect, tiles: Window[], basis: Window): void {
|
||||
/* TODO: make this function simpler by spliting layout-building logic into a new method */
|
||||
|
||||
const entry = this.tileCache[basis.id];
|
||||
if (!entry) return;
|
||||
|
||||
const numColumns = this.columnMasters.length;
|
||||
const [basisColumn, basisIndex] = entry;
|
||||
const delta = WindowResizeDelta.fromWindow(basis);
|
||||
|
||||
/* horizontal adjustment */
|
||||
if (basisColumn === null) {
|
||||
/* the stack is resized. */
|
||||
/* adjust colums-stack ratio. */
|
||||
this.stackRatio = 1 - LayoutUtils.adjustAreaHalfWeights(area, 1 - this.stackRatio, 20,
|
||||
1, delta, true);
|
||||
} else if (basisColumn === numColumns - 1) {
|
||||
/* the last column is resized */
|
||||
/* adjust columns-stack ratio */
|
||||
if (delta.east !== 0) {
|
||||
const columnsDelta = new WindowResizeDelta(delta.east, 0, 0, 0);
|
||||
this.stackRatio = 1 - LayoutUtils.adjustAreaHalfWeights(area, 1 - this.stackRatio, 20,
|
||||
0, columnsDelta, true);
|
||||
}
|
||||
|
||||
/* adjust colums ratio */
|
||||
if (delta.west !== 0) {
|
||||
const columnDelta = new WindowResizeDelta(0, delta.west, 0, 0);
|
||||
const newWeights = LayoutUtils.adjustAreaWeights(area, this.columnWeights, 20,
|
||||
basisColumn, columnDelta, true);
|
||||
this.columnWeights = newWeights;
|
||||
}
|
||||
} else {
|
||||
/* any other columns */
|
||||
/* adjust colums weights */
|
||||
const newWeights = LayoutUtils.adjustAreaWeights(area, this.columnWeights, 20,
|
||||
basisColumn, delta, true);
|
||||
this.columnWeights = newWeights;
|
||||
}
|
||||
|
||||
const numColumnTiles = this.columnMasters.reduce((sum, numMaster) => sum + numMaster, 0);
|
||||
const [columnsTiles, stackTiles] = partitionArray(tiles, (tile, idx) => idx < numColumnTiles);
|
||||
|
||||
/* vertical adjustment */
|
||||
if (basisColumn === null) {
|
||||
/* stack */
|
||||
if (stackTiles.length > 0) {
|
||||
const stackTileWeights = stackTiles.map((tile) => this.tileWeights.get(tile));
|
||||
const newWeights = LayoutUtils.adjustAreaWeights(area, stackTileWeights, CONFIG.tileLayoutGap,
|
||||
basisIndex, delta);
|
||||
newWeights.forEach((weight, index) => {
|
||||
const tile = stackTiles[index];
|
||||
this.tileWeights.set(tile, weight * stackTiles.length);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
/* column */
|
||||
if (columnsTiles.length > 0) {
|
||||
const columnTilesList = partitionArrayBySizes(columnsTiles, this.columnMasters)
|
||||
.filter((arr) => arr.length > 0);
|
||||
const columnTiles = columnTilesList[basisColumn];
|
||||
const weights = columnTiles.map((tile) => this.tileWeights.get(tile));
|
||||
const newWeights = LayoutUtils.adjustAreaWeights(area, weights, CONFIG.tileLayoutGap,
|
||||
basisIndex, delta);
|
||||
newWeights.forEach((weight, index) => {
|
||||
const tile = columnTiles[index];
|
||||
this.tileWeights.set(tile, weight * columnTiles.length);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public apply(ctx: EngineContext, tiles: Window[], area: Rect): void {
|
||||
this.tileCache = {};
|
||||
|
@ -71,9 +71,103 @@ class LayoutUtils {
|
||||
return LayoutUtils.splitAreaWeighted(area, [weight, 1 - weight], gap, horizontal);
|
||||
}
|
||||
|
||||
public static calculateWeights(parts: number[]): number[] {
|
||||
const length = parts.reduce((acc, partLength) => acc + partLength, 0);
|
||||
return parts.map((partLength) => partLength / length);
|
||||
/**
|
||||
* adjustWeights recalculates the weights of subareas of the line, based on size change.
|
||||
* @param line The line being aplitted
|
||||
* @param weights The weight of each part
|
||||
* @param gap The gap size b/w parts
|
||||
* @param target The index of the part being changed.
|
||||
* @param deltaFw The amount of growth towards the origin.
|
||||
* @param deltaBw The amount of growth towards the infinity.
|
||||
*/
|
||||
public static adjustWeights(
|
||||
[begin, length]: [number, number],
|
||||
weights: number[],
|
||||
gap: number,
|
||||
target: number,
|
||||
deltaFw: number,
|
||||
deltaBw: number,
|
||||
): number[] {
|
||||
// TODO: configurable min length?
|
||||
const minLength = 1;
|
||||
|
||||
const parts = this.splitWeighted([begin, length], weights, gap);
|
||||
const [targetBase, targetLength] = parts[target];
|
||||
|
||||
/* apply backward delta */
|
||||
if (target > 0 && deltaBw !== 0) {
|
||||
const neighbor = target - 1;
|
||||
const [neighborBase, neighborLength] = parts[neighbor];
|
||||
|
||||
/* limit delta to prevent squeezing windows */
|
||||
const delta = clip(deltaBw,
|
||||
minLength - targetLength,
|
||||
neighborLength - minLength,
|
||||
);
|
||||
|
||||
parts[target] = [(targetBase - delta), (targetLength + delta)];
|
||||
parts[neighbor] = [neighborBase, (neighborLength - delta)];
|
||||
}
|
||||
|
||||
/* apply forward delta */
|
||||
if (target < parts.length - 1 && deltaFw !== 0) {
|
||||
const neighbor = target + 1;
|
||||
const [neighborBase, neighborLength] = parts[neighbor];
|
||||
|
||||
/* limit delta to prevent squeezing windows */
|
||||
const delta = clip(deltaFw,
|
||||
minLength - targetLength,
|
||||
neighborLength - minLength,
|
||||
);
|
||||
|
||||
parts[target] = [targetBase, targetLength + delta];
|
||||
parts[neighbor] = [neighborBase + delta, neighborLength - delta];
|
||||
}
|
||||
|
||||
return LayoutUtils.calculateWeights(parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* adjustAreaWeights recalculates weights of subareas splitting the given area, based on size change.
|
||||
* @param area The area being splitted
|
||||
* @param weights The weight of each part
|
||||
* @param gap The gap size b/w parts
|
||||
* @param target The index of the part being changed.
|
||||
* @param delta The changes in dimension of the target
|
||||
* @param horizontal If true, calculate horizontal weights, instead of vertical.
|
||||
*/
|
||||
public static adjustAreaWeights(
|
||||
area: Rect,
|
||||
weights: number[],
|
||||
gap: number,
|
||||
target: number,
|
||||
delta: WindowResizeDelta,
|
||||
horizontal?: boolean,
|
||||
): number[] {
|
||||
const line: [number, number] = (horizontal) ? [area.x, area.width] : [area.y, area.height];
|
||||
const [deltaFw, deltaBw] = (horizontal)
|
||||
? [delta.east, delta.west]
|
||||
: [delta.south, delta.north]
|
||||
;
|
||||
return LayoutUtils.adjustWeights(line, weights, gap, target, deltaFw, deltaBw);
|
||||
}
|
||||
|
||||
public static adjustAreaHalfWeights(
|
||||
area: Rect,
|
||||
weight: number,
|
||||
gap: number,
|
||||
target: number,
|
||||
delta: WindowResizeDelta,
|
||||
horizontal?: boolean,
|
||||
): number {
|
||||
const weights = [weight, 1 - weight];
|
||||
const newWeights = LayoutUtils.adjustAreaWeights(area, weights, gap, target, delta, horizontal);
|
||||
return newWeights[0];
|
||||
}
|
||||
|
||||
public static calculateWeights(parts: Array<[number, number]>): number[] {
|
||||
const totalLength = parts.reduce((acc, [base, length]) => acc + length, 0);
|
||||
return parts.map(([base, length]) => length / totalLength);
|
||||
}
|
||||
|
||||
public static calculateAreaWeights(area: Rect, geometries: Rect[], gap?: number, horizontal?: boolean): number[] {
|
||||
@ -81,9 +175,9 @@ class LayoutUtils {
|
||||
horizontal = (horizontal !== undefined) ? horizontal : false;
|
||||
|
||||
const line = (horizontal) ? area.width : area.height;
|
||||
const parts = (horizontal)
|
||||
? geometries.map((geometry) => geometry.width)
|
||||
: geometries.map((geometry) => geometry.height)
|
||||
const parts: Array<[number, number]> = (horizontal)
|
||||
? geometries.map((geometry) => [geometry.x, geometry.width])
|
||||
: geometries.map((geometry) => [geometry.y, geometry.height])
|
||||
;
|
||||
return LayoutUtils.calculateWeights(parts);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user