Files
Dawn/src/dawn/ui/grid.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;
}