import { HEIGHT, WIDTH, COLUMN, ROW } from '../enums/constants';
/**
* Gets measurement for an instance of visual matrix
*
* @param {Array} matrix instance of visual matrix
* @param {string} type height/width
* @return {Object} Logical height/width of the matrix
*/
export function getMatrixMeasurement (matrix, type) {
if (matrix) {
return matrix.getLogicalSpace()[type];
}
return 0;
}
/**
* Sets available space for an instance of visual matrix
*
* @param {Array} matrix instance of visual matrix
* @param {string} type height/width
* @param {number} value Value of measurement
*/
export function setMatrixMeasurement (matrix, type, value) {
if (matrix) {
const spaces = matrix.getLogicalSpace();
if (value && spaces[type] !== value) {
type === HEIGHT ? matrix.setAvailableSpace(spaces.width, value) :
matrix.setAvailableSpace(value, spaces.height);
}
}
}
const setAvailableSpace = (matrix, widths, heights) => {
matrix.forEach((row, rIdx) => {
row.forEach((placeholder, cIdx) => {
placeholder.setAvailableSpace(widths[cIdx], heights[rIdx]);
});
});
};
const setViewSpaces = (layout, pointerType, viewSpaces) => {
let pointer = layout.config()[`${pointerType}Pointer`];
if (viewSpaces.length - 1 < pointer) {
pointer = 0;
layout.config({ [`${pointerType}Pointer`]: pointer });
}
return pointer;
};
/**
* Computes the measurements of space for all matrices in the
* layout
*
* @param {Object} layout Instance of grid layout
* @return {Object} set of measurements for the layout
*/
export const computeLayoutMeasurements = (layout) => {
const rowMatrix = layout.rowMatrix();
const columnMatrix = layout.columnMatrix();
const centerMatrix = layout.centerMatrix();
const {
width,
height
} = layout.measurement();
const {
border
} = layout.config();
const matrices = layout.matrices();
const {
top,
bottom
} = matrices;
// Get width of row matrix
const rowMatrixWidth = getMatrixMeasurement(rowMatrix, WIDTH);
// Set width for column matrix
// Border adjustment for each cell in the central matrix
const borderWidth = border.width;
const columnMatrixWidth = width - rowMatrixWidth - borderWidth;
setMatrixMeasurement(columnMatrix, WIDTH, columnMatrixWidth);
const columnViewPages = columnMatrix.getViewableSpaces();
setViewSpaces(layout, COLUMN, columnViewPages);
// Figuring out total space needed by current view space
const columnViewSpace = columnViewPages[layout.config().columnPointer];
// Getting height of column matrix
const columnMatrixHeight = columnViewSpace.height.primary + columnViewSpace.height.secondary;
// Set height for row matrix
const rowMatrixHeight = height - columnMatrixHeight;
setMatrixMeasurement(rowMatrix, HEIGHT, rowMatrixHeight);
// Get heights of each cell of row matrix
const rowViewableSpaces = rowMatrix.getViewableSpaces();
setViewSpaces(layout, ROW, rowViewableSpaces);
const rowHeights = [].concat(...rowViewableSpaces.map(e => e.rowHeights.primary));
const rowWidthsPrimary = [].concat(...rowViewableSpaces.map(e => e.columnWidths.primary));
const rowWidthsSecondary = [].concat(...rowViewableSpaces.map(e => e.columnWidths.secondary));
const columnViewableSpaces = columnMatrix.getViewableSpaces();
// Get widths of each cell of column matrix
const columnWidths = [].concat(...columnViewableSpaces.map(e => e.columnWidths.primary));
const columnHeightsPrimary = columnViewableSpaces[0].rowHeights.primary;
const columnHeightsSecondary = [].concat(...columnViewableSpaces.map(e => e.rowHeights.secondary));
// Setting the available space for each cell in the centre matrix
centerMatrix.forEach((matrix, rIdx) => {
matrix.forEach((placeholder, cIdx) => {
placeholder.setAvailableSpace(columnWidths[cIdx] - borderWidth, rowHeights[rIdx] - borderWidth);
});
});
setAvailableSpace(top[0], rowWidthsPrimary, columnHeightsPrimary);
setAvailableSpace(top[2], rowWidthsSecondary, columnHeightsPrimary);
setAvailableSpace(bottom[0], rowWidthsPrimary, columnHeightsSecondary);
setAvailableSpace(bottom[2], rowWidthsSecondary, columnHeightsSecondary);
return {
rowMatrixHeight,
rowMatrixWidth,
columnMatrixHeight,
columnMatrixWidth
};
};
/**
* Gets view matrices based on current pointers for row and column
*
* @param {Object} layout instance of layout
* @param {number} rowPointer current row pointer
* @param {number} columnPointer current column pointer
* @return {Object} returns the view matrix and its relevant information
*/
export const getViewMatrices = (layout, rowPointer, columnPointer) => {
const rowMatrix = layout.rowMatrix();
const columnMatrix = layout.columnMatrix();
const centerMatrix = layout.centerMatrix();
const matrices = layout.matrices();
const rowMatrices = rowMatrix.getViewableData();
const columnMatrices = columnMatrix.getViewableData();
const centralMatrixPointer = {
row: 0,
column: 0
};
for (let i = rowPointer - 1; i >= 0; i--) {
const length = Math.max(rowMatrices[i].primaryMatrix.length,
rowMatrices[i].secondaryMatrix.length);
centralMatrixPointer.row += length;
}
/* istanbul ignore next */
for (let i = columnPointer - 1; i >= 0; i--) {
const matrix = columnMatrices[i];
const { primaryMatrix, secondaryMatrix } = matrix;
const length = Math.max(primaryMatrix[0] ? primaryMatrix[0].length : 0,
secondaryMatrix[0] ? secondaryMatrix[0].length : 0);
centralMatrixPointer.column += length;
}
matrices.top[1] = columnMatrices[columnPointer].primaryMatrix;
matrices.bottom[1] = columnMatrices[columnPointer].secondaryMatrix;
matrices.center[0] = rowMatrices[rowPointer].primaryMatrix;
matrices.center[2] = rowMatrices[rowPointer].secondaryMatrix;
const rowMatrixLen = Math.max(matrices.center[0].length, matrices.center[2].length);
/* istanbul ignore next */
const columnMatrixLen = Math.max(matrices.top[1][0] ? matrices.top[1][0].length : 0, matrices.bottom[1][0] ?
matrices.bottom[1][0].length : 0);
matrices.center[1] = centerMatrix.slice(centralMatrixPointer.row, centralMatrixPointer.row + rowMatrixLen)
.map(matrix => matrix.slice(centralMatrixPointer.column, centralMatrixPointer.column + columnMatrixLen));
return {
matrices,
rowPages: rowMatrices.length,
columnPages: columnMatrices.length
};
};
/**
* Returns measurements of the cells of the current matrix
*
* @param {Object} layout instance of layout
* @return {Object} returns the measurements for current view matrix
*/
export const getViewMeasurements = (layout) => {
const rowMatrix = layout.rowMatrix();
const columnMatrix = layout.columnMatrix();
const {
width,
height
} = layout.measurement();
const {
columnPointer,
rowPointer
} = layout.config();
const rowMatrixWidth = rowMatrix.getViewableSpaces()[rowPointer].width;
const { primary: leftWidth, secondary: rightWidth } = rowMatrixWidth;
const columnMatrixHeight = columnMatrix.getViewableSpaces()[columnPointer].height;
const { primary: topHeight, secondary: bottomHeight } = columnMatrixHeight;
const centerHeight = height - (topHeight + bottomHeight);
const centerWidth = width - (leftWidth + rightWidth);
return {
viewWidth: [leftWidth, centerWidth, rightWidth],
viewHeight: [topHeight, centerHeight, bottomHeight]
};
};