138 lines
3.2 KiB
C
138 lines
3.2 KiB
C
/**
|
|
* Copyright (c) 2021 Dominic Masters
|
|
*
|
|
* This software is released under the MIT License.
|
|
* https://opensource.org/licenses/MIT
|
|
*/
|
|
|
|
#include "grid.h"
|
|
|
|
void gridInit(grid_t *grid) {
|
|
uint8_t i;
|
|
|
|
grid->columns = 1;
|
|
grid->rows = 1;
|
|
grid->gutterX = 0;
|
|
grid->gutterY = 0;
|
|
grid->borderX = 0;
|
|
grid->borderY = 0;
|
|
grid->width = 1;
|
|
grid->height = 1;
|
|
|
|
for(i = 0; i < GRID_COLUMN_COUNT_MAX; i++) {
|
|
grid->columnDefinitions[i] = GRID_CEL_SIZE_AUTO;
|
|
}
|
|
for(i = 0; i < GRID_ROW_COUNT_MAX; i++) {
|
|
grid->rowDefinitions[i] = GRID_CEL_SIZE_AUTO;
|
|
}
|
|
}
|
|
|
|
void gridRecalculate(grid_t *grid) {
|
|
uint8_t i, countFlexiColumns, countFlexiRows;
|
|
float flexiWidth, flexiHeight, s, p, totalFlexiWidth, totalFlexiHeight;
|
|
|
|
// Pass 1, determine the "flexible width size"
|
|
countFlexiColumns = 0;
|
|
countFlexiRows = 0;
|
|
totalFlexiWidth = (
|
|
grid->width -
|
|
(grid->gutterX * mathMax(grid->columns-1, 0)) -
|
|
(grid->borderX * 2.0f)
|
|
);
|
|
totalFlexiHeight = (
|
|
grid->height -
|
|
(grid->gutterY * mathMax(grid->rows-1, 0)) -
|
|
(grid->borderY * 2.0f)
|
|
);
|
|
|
|
|
|
for(i = 0; i < grid->columns; i++) {
|
|
if(grid->columnDefinitions[i] == GRID_CEL_SIZE_AUTO) {
|
|
countFlexiColumns++;
|
|
} else {
|
|
totalFlexiWidth -= grid->columnDefinitions[i];
|
|
}
|
|
}
|
|
|
|
for(i = 0; i < grid->rows; i++) {
|
|
if(grid->rowDefinitions[i] == GRID_CEL_SIZE_AUTO) {
|
|
countFlexiRows++;
|
|
} else {
|
|
totalFlexiHeight -= grid->rowDefinitions[i];
|
|
}
|
|
}
|
|
|
|
// Determine the "flexi size for each flexi cell"
|
|
flexiWidth = totalFlexiWidth / countFlexiColumns;
|
|
flexiHeight = totalFlexiHeight / countFlexiRows;
|
|
|
|
// Now set up the positions and sizes for each cell.
|
|
p = grid->borderX;
|
|
for(i = 0; i < grid->columns; i++) {
|
|
s = grid->columnDefinitions[i];
|
|
if(s == GRID_CEL_SIZE_AUTO) s = flexiWidth;
|
|
|
|
grid->columnPositions[i] = p;
|
|
grid->columnSizes[i] = s;
|
|
p += s + grid->gutterX;
|
|
}
|
|
|
|
p = grid->borderY;
|
|
for(i = 0; i < grid->rows; i++) {
|
|
s = grid->rowDefinitions[i];
|
|
if(s == GRID_CEL_SIZE_AUTO) s = flexiHeight;
|
|
|
|
grid->rowPositions[i] = p;
|
|
grid->rowSizes[i] = s;
|
|
p += s + grid->gutterY;
|
|
}
|
|
}
|
|
|
|
void gridResize(grid_t *grid, float width, float height) {
|
|
if(grid->width == width && grid->height == height) return;
|
|
grid->width = width;
|
|
grid->height = height;
|
|
gridRecalculate(grid);
|
|
}
|
|
|
|
void gridGetChild(
|
|
grid_t *grid, uint8_t col, uint8_t row, uint8_t columns, uint8_t rows,
|
|
float *x, float *y, float *width, float *height
|
|
) {
|
|
uint8_t i;
|
|
float s;
|
|
|
|
// Set positions
|
|
*x = grid->columnPositions[col];
|
|
*y = grid->rowPositions[row];
|
|
|
|
// Calculate width.
|
|
s = 0;
|
|
for(i = col; i < col+columns; i++) {
|
|
s += grid->columnSizes[i];
|
|
}
|
|
*width = s;
|
|
|
|
// Calculate height
|
|
s = 0;
|
|
for(i = row; i < row+rows; i++) {
|
|
s += grid->rowSizes[i];
|
|
}
|
|
*height = s;
|
|
}
|
|
|
|
align_t gridGetAndAlignChild(
|
|
grid_t *grid, uint8_t col, uint8_t row, uint8_t columns, uint8_t rows,
|
|
uint8_t alignX, uint8_t alignY, float width, float height
|
|
) {
|
|
float gx, gy, gw, gh;
|
|
|
|
// Get the size of the child first
|
|
gridGetChild(grid, col, row, columns, rows, &gx, &gy, &gw, &gh);
|
|
|
|
// Now align
|
|
align_t align = alignmentGet(alignX, alignY, gw, gh, width, height, -1,-1);
|
|
align.x += gx;
|
|
align.y += gy;
|
|
return align;
|
|
} |