Cleaned up the grid code.
This commit is contained in:
@ -70,6 +70,8 @@
|
||||
|
||||
|
||||
// User Interface Objects
|
||||
#include "ui/grid.h"
|
||||
|
||||
#include "ui/frame.h"
|
||||
#include "ui/image.h"
|
||||
#include "ui/label.h"
|
||||
|
72
include/dawn/ui/grid.h
Normal file
72
include/dawn/ui/grid.h
Normal file
@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../libs.h"
|
||||
|
||||
/** Maximum number of breakpoints a grid can support */
|
||||
#define GRID_BREAKPOINT_COUNT 4
|
||||
|
||||
/** Max number of children that a grid can support */
|
||||
#define GRID_CHILD_COUNT 32
|
||||
|
||||
/** Definition of a breakpoint */
|
||||
typedef struct {
|
||||
float width;
|
||||
} breakpointsize_t;
|
||||
|
||||
/** Definition of a grid breakpoint */
|
||||
typedef struct {
|
||||
uint8_t rows;
|
||||
uint8_t columns;
|
||||
float gutterX;
|
||||
float gutterY;
|
||||
} gridbreakpoint_t;
|
||||
|
||||
/** Callback to receive when a grid child is to be resized */
|
||||
typedef void gridchildresizecallback_t(
|
||||
void *user, int32_t i,
|
||||
float screenWidth, float screenHeight,
|
||||
float x, float y,
|
||||
float width, float height
|
||||
);
|
||||
|
||||
/** Definition of a grid child's breakpoint */
|
||||
typedef struct {
|
||||
uint8_t columns;
|
||||
uint8_t rows;
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
} gridchildbreakpoint_t;
|
||||
|
||||
/** Definition of a grid child */
|
||||
typedef struct {
|
||||
gridchildbreakpoint_t breakpoints[GRID_BREAKPOINT_COUNT];
|
||||
uint8_t breakpointCount;
|
||||
gridchildresizecallback_t *onResize;
|
||||
} gridchild_t;
|
||||
|
||||
/** Definitio of a grid */
|
||||
typedef struct {
|
||||
/** Breakpoints */
|
||||
gridbreakpoint_t breakpoints[GRID_BREAKPOINT_COUNT];
|
||||
breakpointsize_t breakpointSizes[GRID_BREAKPOINT_COUNT];
|
||||
uint8_t breakpointCount;
|
||||
|
||||
/** Child items of the grid */
|
||||
gridchild_t children[GRID_CHILD_COUNT];
|
||||
uint8_t childCount;
|
||||
|
||||
/** Internal size reference, used for caching resize events */
|
||||
float width;
|
||||
float height;
|
||||
float x;
|
||||
float y;
|
||||
|
||||
/** Pointer to any custom user data */
|
||||
void *user;
|
||||
} grid_t;
|
@ -21,37 +21,47 @@ uint8_t gridAddBreakpoint(
|
||||
uint8_t rows, uint8_t columns,
|
||||
float gutterX, float gutterY
|
||||
) {
|
||||
uint8_t i;
|
||||
i = grid->breakpointCount;
|
||||
grid->grids[i].rows = rows;
|
||||
grid->grids[i].columns = columns;
|
||||
grid->grids[i].gutterX = gutterX;
|
||||
grid->grids[i].gutterY = gutterY;
|
||||
grid->breakpoints[i].width = width;
|
||||
grid->breakpointCount++;
|
||||
uint8_t i = grid->breakpointCount++;
|
||||
|
||||
grid->breakpoints[i].rows = rows;
|
||||
grid->breakpoints[i].columns = columns;
|
||||
grid->breakpoints[i].gutterX = gutterX;
|
||||
grid->breakpoints[i].gutterY = gutterY;
|
||||
grid->breakpointSizes[i].width = width;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
gridchild_t * gridAddChild(grid_t *grid) {
|
||||
gridchild_t *child = grid->children + grid->childCount;
|
||||
child->defCount = 1;
|
||||
child->defs[0].columns = 1;
|
||||
child->defs[0].rows = 1;
|
||||
child->defs[0].x = 0;
|
||||
child->defs[0].y = 0;
|
||||
grid->childCount++;
|
||||
gridchild_t *child = grid->children + grid->childCount++;
|
||||
child->breakpointCount = 0;
|
||||
return child;
|
||||
}
|
||||
|
||||
|
||||
uint8_t gridChildAddBreakpoint(gridchild_t *child,
|
||||
uint8_t x, uint8_t y, uint8_t columns, uint8_t rows
|
||||
) {
|
||||
uint8_t i;
|
||||
gridchildbreakpoint_t *bp;
|
||||
i = child->breakpointCount++;
|
||||
bp = child->breakpoints + i;
|
||||
bp->x = x;
|
||||
bp->y = y;
|
||||
bp->rows = rows;
|
||||
bp->columns = columns;
|
||||
return i;
|
||||
}
|
||||
|
||||
void gridSetSize(grid_t *grid,
|
||||
float screenWidth, float screenHeight,
|
||||
float width, float height,
|
||||
float x, float y
|
||||
) {
|
||||
uint8_t i, breakpoint;
|
||||
gridchild_t *item;
|
||||
gridchilddef_t *itemdef;
|
||||
griddef_t griddef;
|
||||
gridchild_t *child;
|
||||
gridchildbreakpoint_t *childbp;
|
||||
gridbreakpoint_t *gridbp;
|
||||
float sizeCol, sizeRow, gx, gy, gw, gh;
|
||||
|
||||
// Need to resize?
|
||||
@ -71,47 +81,45 @@ void gridSetSize(grid_t *grid,
|
||||
// Determine breakpoint
|
||||
breakpoint = 0xFF;
|
||||
for(i = 0; i < grid->breakpointCount; i++) {
|
||||
if(grid->breakpoints[i].width < screenWidth) continue;
|
||||
if(grid->breakpointSizes[i].width < screenWidth) continue;
|
||||
breakpoint = i;
|
||||
}
|
||||
if(breakpoint == 0xFF) breakpoint = grid->breakpointCount - 1;
|
||||
griddef = grid->grids[breakpoint];
|
||||
gridbp = grid->breakpoints + breakpoint;
|
||||
|
||||
// Determine the size of a single column
|
||||
sizeCol = (width - (
|
||||
griddef.gutterX * (griddef.columns - 1)
|
||||
)) / griddef.columns;
|
||||
|
||||
sizeRow = (height - (
|
||||
griddef.gutterY * (griddef.rows - 1)
|
||||
)) / griddef.rows;
|
||||
// Determine the size of a single column/row
|
||||
sizeCol = (width - (gridbp->gutterX * (gridbp->columns-1))) / gridbp->columns;
|
||||
sizeRow = (height - (gridbp->gutterY * (gridbp->rows - 1))) / gridbp->rows;
|
||||
|
||||
// Resize children
|
||||
for(i = 0; i < grid->childCount; i++) {
|
||||
// Get the item and the definition.
|
||||
item = grid->children + i;
|
||||
itemdef = item->defs + (
|
||||
breakpoint >= item->defCount ? item->defCount-1 : breakpoint
|
||||
child = grid->children + i;
|
||||
childbp = child->breakpoints + (
|
||||
breakpoint >= child->breakpointCount ?
|
||||
child->breakpointCount - 1 :
|
||||
breakpoint
|
||||
);
|
||||
|
||||
// Get the local X/Y
|
||||
gx = (sizeCol * itemdef->x) + (griddef.gutterX * itemdef->x);
|
||||
gy = (sizeRow * itemdef->y) + (griddef.gutterY * itemdef->y);
|
||||
gx = (sizeCol * childbp->x) + (gridbp->gutterX * childbp->x);
|
||||
gy = (sizeRow * childbp->y) + (gridbp->gutterY * childbp->y);
|
||||
|
||||
// Get the width/height
|
||||
gw = (
|
||||
(itemdef->columns * sizeCol) +
|
||||
(mathMax(itemdef->columns - 1, 0) * griddef.gutterX)
|
||||
(childbp->columns * sizeCol) +
|
||||
(mathMax(childbp->columns - 1, 0) * gridbp->gutterX)
|
||||
);
|
||||
gh = (
|
||||
(itemdef->rows * sizeRow) +
|
||||
(mathMax(itemdef->rows - 1, 0) * griddef.gutterY)
|
||||
(childbp->rows * sizeRow) +
|
||||
(mathMax(childbp->rows - 1, 0) * gridbp->gutterY)
|
||||
);
|
||||
|
||||
item->onResize(
|
||||
// Fire the resize event.
|
||||
child->onResize(
|
||||
grid->user, i,
|
||||
screenWidth, screenHeight,
|
||||
x + gx,y + gy,
|
||||
x + gx, y + gy,
|
||||
gw, gh
|
||||
);
|
||||
}
|
||||
|
@ -8,68 +8,65 @@
|
||||
#pragma once
|
||||
#include <dawn/dawn.h>
|
||||
|
||||
#define BREAKPOINT_COUNT 4
|
||||
|
||||
#define GRID_CHILD_COUNT 32
|
||||
|
||||
typedef struct {
|
||||
float width;
|
||||
} breakpoint_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t rows;
|
||||
uint8_t columns;
|
||||
float gutterX;
|
||||
float gutterY;
|
||||
} griddef_t;
|
||||
|
||||
typedef void gridchildresizecallback_t(
|
||||
void *user, int32_t i,
|
||||
float screenWidth, float screenHeight,
|
||||
float x, float y,
|
||||
float width, float height
|
||||
);
|
||||
|
||||
typedef struct {
|
||||
uint8_t columns;
|
||||
uint8_t rows;
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
} gridchilddef_t;
|
||||
|
||||
typedef struct {
|
||||
gridchilddef_t defs[BREAKPOINT_COUNT];
|
||||
uint8_t defCount;
|
||||
gridchildresizecallback_t *onResize;
|
||||
} gridchild_t;
|
||||
|
||||
typedef struct {
|
||||
griddef_t grids[BREAKPOINT_COUNT];
|
||||
breakpoint_t breakpoints[BREAKPOINT_COUNT];
|
||||
gridchild_t children[GRID_CHILD_COUNT];
|
||||
uint8_t childCount;
|
||||
|
||||
float width;
|
||||
float height;
|
||||
float x;
|
||||
float y;
|
||||
|
||||
uint8_t breakpointCount;
|
||||
void *user;
|
||||
} grid_t;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize a grid system.
|
||||
*
|
||||
* @param grid Grid system to initialize.
|
||||
*/
|
||||
void gridInit(grid_t *grid);
|
||||
|
||||
/**
|
||||
* Adds a breakpoint to a grid system.
|
||||
*
|
||||
* @param grid Grid to add to.
|
||||
* @param width Screen dimension width of the breakpoint.
|
||||
* @param rows How many rows at this breakpoint.
|
||||
* @param columns How many columns at this breakpoint.
|
||||
* @param gutterX Gutter X at this breakpoint.
|
||||
* @param gutterY Gutter Y at this breakpoint.
|
||||
* @return Index of the breakpoint within the grid.
|
||||
*/
|
||||
uint8_t gridAddBreakpoint(
|
||||
grid_t *grid, float width,
|
||||
uint8_t rows, uint8_t columns,
|
||||
float gutterX, float gutterY
|
||||
);
|
||||
|
||||
/**
|
||||
* Add a child to the grid.
|
||||
*
|
||||
* @param grid Grid to add the child to.
|
||||
* @return The grid child item that was added.
|
||||
*/
|
||||
gridchild_t * gridAddChild(grid_t *grid);
|
||||
|
||||
|
||||
/**
|
||||
* Add a breakpoint to a grid child.
|
||||
*
|
||||
* @param child Child to add the breakpoint to.
|
||||
* @param x Column X position.
|
||||
* @param y Row Y position.
|
||||
* @param columns Count of columns this child will span.
|
||||
* @param rows Count of rows this child will span.
|
||||
* @return The index to the breakpoint in question.
|
||||
*/
|
||||
uint8_t gridChildAddBreakpoint(gridchild_t *child,
|
||||
uint8_t x, uint8_t y, uint8_t columns, uint8_t rows
|
||||
);
|
||||
|
||||
/**
|
||||
* Set the size of a grid system. This will only update if it's found to be
|
||||
* necessary.
|
||||
*
|
||||
* @param grid Grid system to resize.
|
||||
* @param screenWidth Current screen width.
|
||||
* @param screenHeight Current screen height.
|
||||
* @param width Width of the grid itself, useful for nested grids.
|
||||
* @param height Height of the grid itself, useful for nested grids.
|
||||
* @param x X position of this grid (to offset children by).
|
||||
* @param y Y position of this grid (to offset children by).
|
||||
*/
|
||||
void gridSetSize(grid_t *grid,
|
||||
float screenWidth, float screenHeight,
|
||||
float width, float height,
|
||||
|
Reference in New Issue
Block a user