提交 30499c23 编写于 作者: J Joao Moreno

grid: getNeighborViews

上级 1815c1dc
......@@ -42,7 +42,7 @@ function getNode<T extends IView>(node: GridNode<T>, location: number[]): GridNo
return getNode(node.children[index], rest);
}
function getViews<T extends IView>(node: GridNode<T>): T[] {
function getAllViews<T extends IView>(node: GridNode<T>): T[] {
const result: T[] = [];
function collectViews(node: GridNode<T>): void {
......@@ -246,61 +246,57 @@ export class Grid<T extends IView> implements IDisposable {
getNeighborViews(view: T, direction: Direction, wrap: boolean = false): T[] {
const location = this.getViewLocation(view);
const locationOrientation = getLocationOrientation(this.orientation, location);
const directionOrientation = getDirectionOrientation(direction);
const diff = direction === Direction.Up || direction === Direction.Left ? -1 : 1;
const root = this.getViews();
const [parentLocation, index] = tail2(location);
if (locationOrientation === directionOrientation) {
const parent = getNode(root, parentLocation);
if (!isGridBranchNode(parent)) {
throw new Error('Invalid location');
}
const result = this._getNeighborViews(location, direction);
let neighborIndex = index + diff;
if (!wrap && (neighborIndex === -1 || neighborIndex >= parent.children.length)) {
return [];
}
if (result.length > 0 || !wrap) {
return result;
}
neighborIndex = neighborIndex % parent.children.length;
const neighbor = parent.children[neighborIndex];
const directionOrientation = getDirectionOrientation(direction);
const ancestorLocation = location.slice(0, directionOrientation === this.orientation ? 0 : 1);
const root = this.getViews();
const ancestorParent = getNode(root, ancestorLocation);
return getViews(neighbor);
if (!isGridBranchNode(ancestorParent)) {
return [ancestorParent.view];
}
if (direction === Direction.Up || direction === Direction.Left) {
return getAllViews(ancestorParent.children[ancestorParent.children.length - 1]);
} else {
if (parentLocation.length === 0) {
return [];
}
const [grandParentLocation, parentIndex] = tail2(parentLocation);
const grandParent = getNode(root, grandParentLocation);
return getAllViews(ancestorParent.children[0]);
}
}
if (!isGridBranchNode(grandParent)) {
throw new Error('Invalid location');
}
_getNeighborViews(location: number[], direction: Direction): T[] {
if (location.length === 0) {
return [];
}
let uncleIndex = parentIndex + diff;
const locationOrientation = getLocationOrientation(this.orientation, location);
const directionOrientation = getDirectionOrientation(direction);
const [parentLocation, index] = tail2(location);
if (!wrap && (uncleIndex === -1 || uncleIndex >= grandParent.children.length)) {
return [];
}
if (locationOrientation !== directionOrientation) {
return this._getNeighborViews(parentLocation, direction);
}
uncleIndex = uncleIndex % grandParent.children.length;
const root = this.getViews();
const parent = getNode(root, parentLocation);
const uncle = grandParent.children[uncleIndex];
if (!isGridBranchNode(parent)) {
throw new Error('Invalid location');
}
if (!isGridBranchNode(uncle)) {
return [uncle.view];
}
const diff = direction === Direction.Up || direction === Direction.Left ? -1 : 1;
let neighborIndex = index + diff;
const uncleLocation = [...grandParentLocation, uncleIndex];
const range = this.gridview.getViewRange(location);
const cousinIndexes = this.gridview.getChildrenInRange(uncleLocation, range);
return cousinIndexes.reduce((r, i) => [...r, ...getViews(uncle.children[i])], [] as T[]);
if (neighborIndex === -1 || neighborIndex >= parent.children.length) {
return this._getNeighborViews(parentLocation, direction);
}
const neighbor = parent.children[neighborIndex];
return getAllViews(neighbor);
}
private getViewLocation(view: T): number[] {
......
......@@ -288,6 +288,103 @@ suite('Grid', function () {
assert.deepEqual(view2.size, [800, 200]);
assert.deepEqual(view4.size, [800, 200]);
});
test('getNeighborViews should work on single view layout', function () {
const view1 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
const grid = new Grid(container, view1);
grid.layout(800, 600);
assert.deepEqual(grid.getNeighborViews(view1, Direction.Up), []);
assert.deepEqual(grid.getNeighborViews(view1, Direction.Right), []);
assert.deepEqual(grid.getNeighborViews(view1, Direction.Down), []);
assert.deepEqual(grid.getNeighborViews(view1, Direction.Left), []);
assert.deepEqual(grid.getNeighborViews(view1, Direction.Up, true), [view1]);
assert.deepEqual(grid.getNeighborViews(view1, Direction.Right, true), [view1]);
assert.deepEqual(grid.getNeighborViews(view1, Direction.Down, true), [view1]);
assert.deepEqual(grid.getNeighborViews(view1, Direction.Left, true), [view1]);
});
test('getNeighborViews should work on simple layout', function () {
const view1 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
const grid = new Grid(container, view1);
grid.layout(800, 600);
const view2 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
grid.addView(view2, Sizing.Distribute, view1, Direction.Down);
const view3 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
grid.addView(view3, Sizing.Distribute, view2, Direction.Down);
assert.deepEqual(grid.getNeighborViews(view1, Direction.Up), []);
assert.deepEqual(grid.getNeighborViews(view1, Direction.Right), []);
assert.deepEqual(grid.getNeighborViews(view1, Direction.Down), [view2]);
assert.deepEqual(grid.getNeighborViews(view1, Direction.Left), []);
assert.deepEqual(grid.getNeighborViews(view1, Direction.Up, true), [view3]);
assert.deepEqual(grid.getNeighborViews(view1, Direction.Right, true), [view1]);
assert.deepEqual(grid.getNeighborViews(view1, Direction.Down, true), [view2]);
assert.deepEqual(grid.getNeighborViews(view1, Direction.Left, true), [view1]);
assert.deepEqual(grid.getNeighborViews(view2, Direction.Up), [view1]);
assert.deepEqual(grid.getNeighborViews(view2, Direction.Right), []);
assert.deepEqual(grid.getNeighborViews(view2, Direction.Down), [view3]);
assert.deepEqual(grid.getNeighborViews(view2, Direction.Left), []);
assert.deepEqual(grid.getNeighborViews(view2, Direction.Up, true), [view1]);
assert.deepEqual(grid.getNeighborViews(view2, Direction.Right, true), [view2]);
assert.deepEqual(grid.getNeighborViews(view2, Direction.Down, true), [view3]);
assert.deepEqual(grid.getNeighborViews(view2, Direction.Left, true), [view2]);
assert.deepEqual(grid.getNeighborViews(view3, Direction.Up), [view2]);
assert.deepEqual(grid.getNeighborViews(view3, Direction.Right), []);
assert.deepEqual(grid.getNeighborViews(view3, Direction.Down), []);
assert.deepEqual(grid.getNeighborViews(view3, Direction.Left), []);
assert.deepEqual(grid.getNeighborViews(view3, Direction.Up, true), [view2]);
assert.deepEqual(grid.getNeighborViews(view3, Direction.Right, true), [view3]);
assert.deepEqual(grid.getNeighborViews(view3, Direction.Down, true), [view1]);
assert.deepEqual(grid.getNeighborViews(view3, Direction.Left, true), [view3]);
});
test('getNeighborViews should work on a complex layout', function () {
const view1 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
const grid = new Grid(container, view1);
grid.layout(800, 600);
const view2 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
grid.addView(view2, Sizing.Distribute, view1, Direction.Down);
const view3 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
grid.addView(view3, Sizing.Distribute, view2, Direction.Down);
const view4 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
grid.addView(view4, Sizing.Distribute, view2, Direction.Right);
const view5 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
grid.addView(view5, Sizing.Distribute, view4, Direction.Down);
assert.deepEqual(grid.getNeighborViews(view1, Direction.Up), []);
assert.deepEqual(grid.getNeighborViews(view1, Direction.Right), []);
assert.deepEqual(grid.getNeighborViews(view1, Direction.Down), [view2, view4, view5]);
assert.deepEqual(grid.getNeighborViews(view1, Direction.Left), []);
assert.deepEqual(grid.getNeighborViews(view2, Direction.Up), [view1]);
assert.deepEqual(grid.getNeighborViews(view2, Direction.Right), [view4, view5]);
assert.deepEqual(grid.getNeighborViews(view2, Direction.Down), [view3]);
assert.deepEqual(grid.getNeighborViews(view2, Direction.Left), []);
assert.deepEqual(grid.getNeighborViews(view4, Direction.Up), [view1]);
assert.deepEqual(grid.getNeighborViews(view4, Direction.Right), []);
assert.deepEqual(grid.getNeighborViews(view4, Direction.Down), [view5]);
assert.deepEqual(grid.getNeighborViews(view4, Direction.Left), [view2]);
assert.deepEqual(grid.getNeighborViews(view5, Direction.Up), [view4]);
assert.deepEqual(grid.getNeighborViews(view5, Direction.Right), []);
assert.deepEqual(grid.getNeighborViews(view5, Direction.Down), [view3]);
assert.deepEqual(grid.getNeighborViews(view5, Direction.Left), [view2]);
assert.deepEqual(grid.getNeighborViews(view3, Direction.Up), [view2, view4, view5]);
assert.deepEqual(grid.getNeighborViews(view3, Direction.Right), []);
assert.deepEqual(grid.getNeighborViews(view3, Direction.Down), []);
assert.deepEqual(grid.getNeighborViews(view3, Direction.Left), []);
});
});
class TestSerializableView extends TestView implements ISerializableView {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册