Moved a tonne of code around
This commit is contained in:
78
src/dawn/ui/align.c
Normal file
78
src/dawn/ui/align.c
Normal file
@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "align.h"
|
||||
|
||||
void alignmentGetAxis(
|
||||
uint8_t align,
|
||||
float containerSize, float childSize, float childPos,
|
||||
float *outSize, float *outPos
|
||||
) {
|
||||
if(align & ALIGN_SIZE_FILL) {
|
||||
*outSize = containerSize;
|
||||
} else if(align & ALIGN_SIZE_ORIGINAL) {
|
||||
*outSize = childSize;
|
||||
}
|
||||
|
||||
if(align & ALIGN_POS_START) {
|
||||
*outPos = 0;
|
||||
} else if(align & ALIGN_POS_CENTER) {
|
||||
*outPos = (containerSize/2.0f) - ((*outSize) / 2.0f);
|
||||
} else if(align & ALIGN_POS_END) {
|
||||
*outPos = containerSize - (*outSize);
|
||||
}
|
||||
}
|
||||
|
||||
align_t alignmentGet(
|
||||
uint8_t alignX, uint8_t alignY,
|
||||
float containerWidth, float containerHeight,
|
||||
float childWidth, float childHeight,
|
||||
float childX, float childY
|
||||
) {
|
||||
align_t out = {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = 0,
|
||||
.height = 0
|
||||
};
|
||||
|
||||
if(alignX & ALIGN_SIZE_RATIO) {
|
||||
// Work out Y size and alignment first, then we base off that.
|
||||
alignmentGetAxis(
|
||||
alignY, containerHeight, childHeight, childY, &out.height, &out.y
|
||||
);
|
||||
|
||||
// Now work out ratio
|
||||
out.width = out.height * (childWidth / childHeight);
|
||||
|
||||
// Now do X
|
||||
alignmentGetAxis(
|
||||
alignX, containerWidth, childWidth, childX, &out.width, &out.x
|
||||
);
|
||||
} else {
|
||||
alignmentGetAxis(
|
||||
alignX, containerWidth, childWidth, childX, &out.width, &out.x
|
||||
);
|
||||
}
|
||||
|
||||
// Same as above but inverted for Y axis.
|
||||
if(alignY & ALIGN_SIZE_RATIO) {
|
||||
alignmentGetAxis(
|
||||
alignX, containerWidth, childWidth, childX, &out.width, &out.x
|
||||
);
|
||||
out.height = out.width * (childHeight / childWidth);
|
||||
alignmentGetAxis(
|
||||
alignY, containerHeight, childHeight, childY, &out.height, &out.y
|
||||
);
|
||||
} else {
|
||||
alignmentGetAxis(
|
||||
alignY, containerHeight, childHeight, childY, &out.height, &out.y
|
||||
);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
60
src/dawn/ui/align.h
Normal file
60
src/dawn/ui/align.h
Normal file
@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../libs.h"
|
||||
#include "../util/flags.h"
|
||||
|
||||
#define ALIGN_POS_CENTER flagDefine(0)
|
||||
#define ALIGN_POS_START flagDefine(1)
|
||||
#define ALIGN_POS_END flagDefine(2)
|
||||
|
||||
#define ALIGN_SIZE_FILL flagDefine(3)
|
||||
#define ALIGN_SIZE_ORIGINAL flagDefine(4)
|
||||
#define ALIGN_SIZE_RATIO flagDefine(5)
|
||||
|
||||
typedef struct {
|
||||
float x, y;
|
||||
float width, height;
|
||||
} align_t;
|
||||
|
||||
/**
|
||||
* Return the alignment for a specific access, really this doesn't need to be
|
||||
* used. Does not support the ALIGN_SIZE_RATIO alignment method.
|
||||
*
|
||||
* @param align Alignment flags to get.
|
||||
* @param containerSize Size of the container.
|
||||
* @param childSize Size of the child.
|
||||
* @param childPos Currently unused.
|
||||
* @param outSize Pointer to a float for the size output.
|
||||
* @param outPos Poitner to a float for the position output.
|
||||
*/
|
||||
void alignmentGetAxis(
|
||||
uint8_t align,
|
||||
float containerSize, float childSize, float childPos,
|
||||
float *outSize, float *outPos
|
||||
);
|
||||
|
||||
/**
|
||||
* Get the alignment set for a given set of options.
|
||||
*
|
||||
* @param alignX Alignment options for the X axis.
|
||||
* @param alignY Alignment options for the Y axis.
|
||||
* @param containerWidth Width of the container.
|
||||
* @param containerHeight Height of the container.
|
||||
* @param childWidth Width of the child
|
||||
* @param childHeight Height of the child.
|
||||
* @param childX Currently unused.
|
||||
* @param childY Currently unused.
|
||||
* @return The alignment calculation.
|
||||
*/
|
||||
align_t alignmentGet(
|
||||
uint8_t alignX, uint8_t alignY,
|
||||
float containerWidth, float containerHeight,
|
||||
float childWidth, float childHeight,
|
||||
float childX, float childY
|
||||
);
|
44
src/dawn/ui/breakpoint.c
Normal file
44
src/dawn/ui/breakpoint.c
Normal file
@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "breakpoint.h"
|
||||
|
||||
void breakpointListInit(breakpointlist_t *list) {
|
||||
list->breakpointCount = 0;
|
||||
list->user = NULL;
|
||||
list->onBreakpoint = NULL;
|
||||
list->breakpointCurrent = 0x00;
|
||||
}
|
||||
|
||||
uint8_t breakpointGet(breakpointlist_t *list, float width) {
|
||||
uint8_t bp, i;
|
||||
bp = 0xFF;
|
||||
for(i = 0; i < list->breakpointCount; i++) {
|
||||
if(list->breakpoints[i] > width) break;
|
||||
bp = i;
|
||||
}
|
||||
if(bp == 0xFF) bp = 0;
|
||||
return bp;
|
||||
}
|
||||
|
||||
void breakpointAdd(breakpointlist_t *list, float width) {
|
||||
list->breakpoints[list->breakpointCount++] = width;
|
||||
}
|
||||
|
||||
void breakpointResize(breakpointlist_t *list, float width) {
|
||||
uint8_t bp;
|
||||
|
||||
// Determine breakpoint
|
||||
bp = breakpointGet(list, width);
|
||||
if(list->breakpointCurrent == bp) return;
|
||||
list->breakpointCurrent = bp;
|
||||
|
||||
// Fire event.
|
||||
if(list->onBreakpoint != NULL) {
|
||||
list->onBreakpoint(list->user, bp, list->breakpoints[bp]);
|
||||
}
|
||||
}
|
60
src/dawn/ui/breakpoint.h
Normal file
60
src/dawn/ui/breakpoint.h
Normal file
@ -0,0 +1,60 @@
|
||||
// Copyright (c) 2021 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "../libs.h"
|
||||
|
||||
/** Maximum breakpoints that the list can support. */
|
||||
#define BREAKPOINT_COUNT_MAX 0x04
|
||||
|
||||
/** Callback for when a new breakpint is reached. */
|
||||
typedef void breakpointcallback_t(void *user, uint8_t i, float breakpoint);
|
||||
|
||||
typedef struct {
|
||||
/** List of breakpoints */
|
||||
float breakpoints[BREAKPOINT_COUNT_MAX];
|
||||
uint8_t breakpointCount;
|
||||
|
||||
/** Which breakpoint is current */
|
||||
uint8_t breakpointCurrent;
|
||||
|
||||
/** Pointer to any custom user data. */
|
||||
void *user;
|
||||
|
||||
/** Callback for when a breakpoint is reached */
|
||||
breakpointcallback_t *onBreakpoint;
|
||||
} breakpointlist_t;
|
||||
|
||||
/**
|
||||
* Initialize a breakpoint.
|
||||
*
|
||||
* @param list List to initialize.
|
||||
*/
|
||||
void breakpointInit(breakpointlist_t *list);
|
||||
|
||||
/**
|
||||
* Get the breakpoint for a given width set.
|
||||
*
|
||||
* @param list List to get from.
|
||||
* @param width Width to use.
|
||||
* @return The breakpoint (index) for this screen size.
|
||||
*/
|
||||
uint8_t breakpointGet(breakpointlist_t *list, float width);
|
||||
|
||||
/**
|
||||
* Add a breakpoint definition to a breakpoint list.
|
||||
*
|
||||
* @param list List to add to.
|
||||
* @param width Width of the breakpoint.
|
||||
*/
|
||||
void breakpointAdd(breakpointlist_t *list, float width);
|
||||
|
||||
/**
|
||||
* Resize a breakpoint list, which (in turn) will fire the necessary events.
|
||||
*
|
||||
* @param list List to resize.
|
||||
* @param width Width to use.
|
||||
*/
|
||||
void breakpointResize(breakpointlist_t *list, float width);
|
116
src/dawn/ui/frame.c
Normal file
116
src/dawn/ui/frame.c
Normal file
@ -0,0 +1,116 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "frame.h"
|
||||
|
||||
void frameInit(frame_t *frame) {
|
||||
frame->texture = NULL;
|
||||
primitiveInit(
|
||||
&frame->primitive,
|
||||
QUAD_VERTICE_COUNT * FRAME_PRIMITIVE_COUNT,
|
||||
QUAD_INDICE_COUNT * FRAME_PRIMITIVE_COUNT
|
||||
);
|
||||
|
||||
frameSetInnerSize(frame, FRAME_BORDER_SIZE, FRAME_BORDER_SIZE);
|
||||
}
|
||||
|
||||
void frameSetSize(frame_t *frame, float width, float height) {
|
||||
frameSetInnerSize(frame,
|
||||
width - FRAME_BORDER_SIZE_FULL, height - FRAME_BORDER_SIZE_FULL
|
||||
);
|
||||
}
|
||||
|
||||
void frameSetInnerSize(frame_t *frame, float width, float height) {
|
||||
float rightStart = FRAME_BORDER_SIZE + width;
|
||||
float rightEnd = rightStart + FRAME_BORDER_SIZE;
|
||||
|
||||
float bottomStart = FRAME_BORDER_SIZE + height;
|
||||
float bottomEnd = bottomStart + FRAME_BORDER_SIZE;
|
||||
|
||||
float tw = 1.0f / 3.0f;
|
||||
float th = tw;
|
||||
|
||||
// Buffer the top left edge
|
||||
quadBuffer(&frame->primitive, 0,
|
||||
0, 0, 0, 0,
|
||||
FRAME_BORDER_SIZE, FRAME_BORDER_SIZE, tw, th,
|
||||
0, 0
|
||||
);
|
||||
|
||||
// Buffer the top edge.
|
||||
quadBuffer(&frame->primitive, 0,
|
||||
FRAME_BORDER_SIZE, 0, tw, 0,
|
||||
rightStart, FRAME_BORDER_SIZE, tw*2, th,
|
||||
QUAD_VERTICE_COUNT, QUAD_INDICE_COUNT
|
||||
);
|
||||
|
||||
// Buffer the top right edge.
|
||||
quadBuffer(&frame->primitive, 0,
|
||||
rightStart, 0, tw*2, 0,
|
||||
rightEnd, FRAME_BORDER_SIZE, tw*3, th,
|
||||
QUAD_VERTICE_COUNT*2, QUAD_INDICE_COUNT*2
|
||||
);
|
||||
|
||||
|
||||
// Buffer the left edge
|
||||
quadBuffer(&frame->primitive, 0,
|
||||
0, FRAME_BORDER_SIZE, 0, th,
|
||||
FRAME_BORDER_SIZE, bottomStart, tw, th*2,
|
||||
QUAD_VERTICE_COUNT*3, QUAD_INDICE_COUNT*3
|
||||
);
|
||||
|
||||
// Buffer the center
|
||||
quadBuffer(&frame->primitive, 0,
|
||||
FRAME_BORDER_SIZE, FRAME_BORDER_SIZE, tw, th,
|
||||
rightStart, bottomStart, tw*2, th*2,
|
||||
QUAD_VERTICE_COUNT*4, QUAD_INDICE_COUNT*4
|
||||
);
|
||||
|
||||
// Buffer the right edge.
|
||||
quadBuffer(&frame->primitive, 0,
|
||||
rightStart, FRAME_BORDER_SIZE, tw*2, th,
|
||||
rightEnd, bottomStart, tw*3, th*2,
|
||||
QUAD_VERTICE_COUNT*5, QUAD_INDICE_COUNT*5
|
||||
);
|
||||
|
||||
|
||||
// Buffer the bottom left edge.
|
||||
quadBuffer(&frame->primitive, 0,
|
||||
0, bottomStart, 0, th*2,
|
||||
FRAME_BORDER_SIZE, bottomEnd, tw, th*3,
|
||||
QUAD_VERTICE_COUNT*6, QUAD_INDICE_COUNT*6
|
||||
);
|
||||
|
||||
// Buffer the bottom edge.
|
||||
quadBuffer(&frame->primitive, 0,
|
||||
FRAME_BORDER_SIZE, bottomStart, tw, th*2,
|
||||
rightStart, bottomEnd, tw*2, th*3,
|
||||
QUAD_VERTICE_COUNT*7, QUAD_INDICE_COUNT*7
|
||||
);
|
||||
|
||||
// Buffer the bottom right edge.
|
||||
quadBuffer(&frame->primitive, 0,
|
||||
rightStart, bottomStart, tw*2, th*2,
|
||||
rightEnd, bottomEnd, tw*3, th*3,
|
||||
QUAD_VERTICE_COUNT*8, QUAD_INDICE_COUNT*8
|
||||
);
|
||||
}
|
||||
|
||||
void frameRender(
|
||||
frame_t *frame, shader_t *shader,
|
||||
shaderuniform_t uniformModel, shaderuniform_t uniformTexture,
|
||||
float x, float y
|
||||
) {
|
||||
if(frame->texture == NULL) return;
|
||||
shaderUsePosition(shader, uniformModel, x, y, 0, 0, 0, 0);
|
||||
shaderUseTexture(shader, uniformTexture, frame->texture);
|
||||
primitiveDraw(&frame->primitive, 0, -1);
|
||||
}
|
||||
|
||||
void frameDispose(frame_t *frame) {
|
||||
primitiveDispose(&frame->primitive);
|
||||
}
|
73
src/dawn/ui/frame.h
Normal file
73
src/dawn/ui/frame.h
Normal file
@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../libs.h"
|
||||
#include "../display/shader.h"
|
||||
#include "../display/primitive/primitive.h"
|
||||
#include "../display/primitive/quad.h"
|
||||
#include "../display/font.h"
|
||||
|
||||
/** Size of the border (in pixels) on each edge */
|
||||
#define FRAME_BORDER_SIZE 16
|
||||
/** Total border size for a given frame on each axis */
|
||||
#define FRAME_BORDER_SIZE_FULL FRAME_BORDER_SIZE * 2
|
||||
/** How many quads are within the frame */
|
||||
#define FRAME_PRIMITIVE_COUNT 9
|
||||
|
||||
typedef struct {
|
||||
texture_t *texture;
|
||||
primitive_t primitive;
|
||||
} frame_t;
|
||||
|
||||
/**
|
||||
* Initialize a GUI Frame.
|
||||
*
|
||||
* @param frame Frame to initialize.
|
||||
*/
|
||||
void frameInit(frame_t *frame);
|
||||
|
||||
/**
|
||||
* Set the size of the frame (including the size of the border).
|
||||
*
|
||||
* @param frame Frame to set the size of.
|
||||
* @param width Width of the frame.
|
||||
* @param height Height of the frame
|
||||
*/
|
||||
void frameSetSize(frame_t *frame, float width, float height);
|
||||
|
||||
/**
|
||||
* Set the size of the frame's innards (size excluding the borders).
|
||||
*
|
||||
* @param frame Frame to set the size of
|
||||
* @param width Width of the inner frame.
|
||||
* @param height Height of the inner frame.
|
||||
*/
|
||||
void frameSetInnerSize(frame_t *frame, float width, float height);
|
||||
|
||||
/**
|
||||
* Render a game frame.
|
||||
*
|
||||
* @param frame Frame to render.
|
||||
* @param shader Shader to use while rendering.
|
||||
* @param uniformModel Shader uniform for the model position.
|
||||
* @param uniformTexture Shader uniform for the texture.
|
||||
* @param x X position.
|
||||
* @param y Y position.
|
||||
*/
|
||||
void frameRender(
|
||||
frame_t *frame, shader_t *shader,
|
||||
shaderuniform_t uniformModel, shaderuniform_t uniformTexture,
|
||||
float x, float y
|
||||
);
|
||||
|
||||
/**
|
||||
* Cleanup a previously initialized frame.
|
||||
*
|
||||
* @param frame Frame to dispose.
|
||||
*/
|
||||
void frameDispose(frame_t *frame);
|
44
src/dawn/ui/framedtextmenu.c
Normal file
44
src/dawn/ui/framedtextmenu.c
Normal file
@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "framedtextmenu.h"
|
||||
|
||||
void framedTextMenuInit(framedtextmenu_t *menu, font_t *font, texture_t *text) {
|
||||
frameInit(&menu->frame);
|
||||
textMenuInit(&menu->menu, font);
|
||||
menu->frame.texture = text;
|
||||
menu->menu.grid.borderX = FRAME_BORDER_SIZE;
|
||||
menu->menu.grid.borderY = FRAME_BORDER_SIZE;
|
||||
menu->menu.grid.gutterX = FRAMED_TEXT_MENU_GUTTER_DEFAULT;
|
||||
menu->menu.grid.gutterY = FRAMED_TEXT_MENU_GUTTER_DEFAULT;
|
||||
}
|
||||
|
||||
void framedTextMenuResize(framedtextmenu_t *menu, float width, float height) {
|
||||
if(menu->menu.grid.width == width && menu->menu.grid.height == height) {
|
||||
return;
|
||||
}
|
||||
gridResize(&menu->menu.grid, width, height);
|
||||
frameSetSize(&menu->frame, width, height);
|
||||
}
|
||||
|
||||
void framedTextMenuUpdate(framedtextmenu_t *menu, engine_t *engine) {
|
||||
menuUpdate(&menu->menu.menu, engine);
|
||||
}
|
||||
|
||||
void framedTextMenuRender(
|
||||
framedtextmenu_t *menu, shader_t *shader,
|
||||
shaderuniform_t uniformModel, shaderuniform_t uniformTexture,
|
||||
float x, float y
|
||||
) {
|
||||
frameRender(&menu->frame, shader, uniformModel, uniformTexture, x, y);
|
||||
textMenuRender(&menu->menu, shader, uniformModel, uniformTexture, x, y);
|
||||
}
|
||||
|
||||
void framedTextMenuDispose(framedtextmenu_t *menu) {
|
||||
textMenuDispse(&menu->menu);
|
||||
frameDispose(&menu->frame);
|
||||
}
|
71
src/dawn/ui/framedtextmenu.h
Normal file
71
src/dawn/ui/framedtextmenu.h
Normal file
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../engine/engine.h"
|
||||
#include "../libs.h"
|
||||
#include "frame.h"
|
||||
#include "textmenu.h"
|
||||
#include "grid.h"
|
||||
#include "menu.h"
|
||||
|
||||
/** The default gutter for the grid of a framed text menu */
|
||||
#define FRAMED_TEXT_MENU_GUTTER_DEFAULT 8.0f
|
||||
|
||||
typedef struct {
|
||||
frame_t frame;
|
||||
textmenu_t menu;
|
||||
} framedtextmenu_t;
|
||||
|
||||
/**
|
||||
* Initialize a framed text ui element.
|
||||
*
|
||||
* @param menu Menu to initialize.
|
||||
* @param font Font to use for the text.
|
||||
* @param text Texture for the frame.
|
||||
*/
|
||||
void framedTextMenuInit(framedtextmenu_t *menu, font_t *font, texture_t *text);
|
||||
|
||||
/**
|
||||
* Resize a framed text menu.
|
||||
*
|
||||
* @param menu Menu to resize.
|
||||
* @param width Width of the menu.
|
||||
* @param height Height of the menu.
|
||||
*/
|
||||
void framedTextMenuResize(framedtextmenu_t *menu, float width, float height);
|
||||
|
||||
/**
|
||||
* Update a framed text menu.
|
||||
*
|
||||
* @param menu Menu to update.
|
||||
* @param engine Engine to use when updating.
|
||||
*/
|
||||
void framedTextMenuUpdate(framedtextmenu_t *menu, engine_t *engine);
|
||||
|
||||
/**
|
||||
* Render a framed text menu.
|
||||
*
|
||||
* @param menu Menu to render.
|
||||
* @param shader Shader to use.
|
||||
* @param uniformModel Shader uniform for the model position.
|
||||
* @param uniformTexture Shader uniform for the texture.
|
||||
* @param x X Position.
|
||||
* @param y Y Position.
|
||||
*/
|
||||
void framedTextMenuRender(
|
||||
framedtextmenu_t *menu, shader_t *shader,
|
||||
shaderuniform_t uniformModel, shaderuniform_t uniformTexture,
|
||||
float x, float y
|
||||
);
|
||||
|
||||
/**
|
||||
* Dispose a previously created framed text menu.
|
||||
*
|
||||
* @param menu Menu to dispose.
|
||||
*/
|
||||
void framedTextMenuDispose(framedtextmenu_t *menu);
|
138
src/dawn/ui/grid.c
Normal file
138
src/dawn/ui/grid.c
Normal file
@ -0,0 +1,138 @@
|
||||
/**
|
||||
* 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;
|
||||
}
|
102
src/dawn/ui/grid.h
Normal file
102
src/dawn/ui/grid.h
Normal file
@ -0,0 +1,102 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../libs.h"
|
||||
#include "../util/math.h"
|
||||
#include "align.h"
|
||||
|
||||
/** Maximum number of columns a grid can have */
|
||||
#define GRID_COLUMN_COUNT_MAX 16
|
||||
/** Maximum number of rows a grid can have */
|
||||
#define GRID_ROW_COUNT_MAX GRID_COLUMN_COUNT_MAX
|
||||
|
||||
/** Cell size for "auto", basically to fill the remaining space evenly */
|
||||
#define GRID_CEL_SIZE_AUTO -1
|
||||
|
||||
/** Definitio of a grid */
|
||||
typedef struct {
|
||||
/** Count of columns/rows in the grid */
|
||||
uint8_t columns, rows;
|
||||
|
||||
/** Cell Definitions, used to control how the cells will size themselves */
|
||||
float columnDefinitions[GRID_COLUMN_COUNT_MAX];
|
||||
float rowDefinitions[GRID_COLUMN_COUNT_MAX];
|
||||
|
||||
/** Settings to control gutters (space between cells) and border (of grid) */
|
||||
float gutterX, gutterY;
|
||||
float borderX, borderY;
|
||||
|
||||
/** Calculated sizes and positions for each cell */
|
||||
float columnSizes[GRID_COLUMN_COUNT_MAX];
|
||||
float columnPositions[GRID_COLUMN_COUNT_MAX];
|
||||
float rowSizes[GRID_ROW_COUNT_MAX];
|
||||
float rowPositions[GRID_COLUMN_COUNT_MAX];
|
||||
|
||||
/** Cached size of the grid */
|
||||
float width, height;
|
||||
} grid_t;
|
||||
|
||||
/**
|
||||
* Initialize a grid system.
|
||||
*
|
||||
* @param grid Grid system to initialize.
|
||||
*/
|
||||
void gridInit(grid_t *grid);
|
||||
|
||||
/**
|
||||
* Recalculate the cell size and positions.
|
||||
*
|
||||
* @param grid Grid to recalculate for.
|
||||
*/
|
||||
void gridRecalculate(grid_t *grid);
|
||||
|
||||
/**
|
||||
* Resize (and recalculate) a grid.
|
||||
*
|
||||
* @param grid Grid to resize.
|
||||
* @param width Width to use.
|
||||
* @param height Height to use.
|
||||
*/
|
||||
void gridResize(grid_t *grid, float width, float height);
|
||||
|
||||
/**
|
||||
* Get the dimensions of a particular cell and span.
|
||||
*
|
||||
* @param grid Grid to get from.
|
||||
* @param col Starting column.
|
||||
* @param row Starting row.
|
||||
* @param columns Count of columns the cell spans.
|
||||
* @param rows Count of rows the cell spans.
|
||||
* @param x Pointer to output X float.
|
||||
* @param y Pointer to output Y float
|
||||
* @param width Pointer to output width float.
|
||||
* @param height Pointer to output height float.
|
||||
*/
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
* Align a child within its set cell.
|
||||
*
|
||||
* @param grid Grid to use when aligning.
|
||||
* @param col Starting column.
|
||||
* @param row Starting row.
|
||||
* @param columns Count of columns the cell spans.
|
||||
* @param rows Count of rows the cell spans.
|
||||
* @param alignX Alignment flags for the X axis.
|
||||
* @param alignY Alignment flags for the Y axis.
|
||||
* @param width Current width of the child.
|
||||
* @param height Current height of the child.
|
||||
* @return The alignment information to align the child within the cell.
|
||||
*/
|
||||
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
|
||||
);
|
66
src/dawn/ui/image.c
Normal file
66
src/dawn/ui/image.c
Normal file
@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "image.h"
|
||||
|
||||
void imageInit(image_t *image) {
|
||||
image->quad.verticeCount = -1;
|
||||
image->width = 1;
|
||||
image->height = 1;
|
||||
imageSetTexture(image, NULL);
|
||||
}
|
||||
|
||||
void imageSetTexture(image_t *image, texture_t *texture) {
|
||||
imageSetTextureAndCrop(image, texture,
|
||||
0, 0,
|
||||
texture == NULL ? 0 : (float)texture->width,
|
||||
texture == NULL ? 0 : (float)texture->height
|
||||
);
|
||||
}
|
||||
|
||||
void imageSetTextureAndCrop(image_t *image, texture_t *texture,
|
||||
float x, float y, float width, float height
|
||||
) {
|
||||
float u0, u1, v0, v1;
|
||||
if(image->quad.verticeCount != -1) {
|
||||
primitiveDispose(&image->quad);
|
||||
image->quad.verticeCount = -1;
|
||||
}
|
||||
if(texture == NULL) return;
|
||||
|
||||
u0 = x / texture->width;
|
||||
u1 = u0 + (width / texture->width);
|
||||
v0 = y / texture->height;
|
||||
v1 = v0 + (height / texture->height);
|
||||
|
||||
image->texture = texture;
|
||||
image->width = width;
|
||||
image->height = height;
|
||||
quadInit(&image->quad, 0,
|
||||
0,0,u0,v0,
|
||||
1,1,u1,v1
|
||||
);
|
||||
}
|
||||
|
||||
void imageRender(
|
||||
image_t *image, shader_t *shader,
|
||||
shaderuniform_t uniformModel, shaderuniform_t uniformTexture,
|
||||
float x, float y
|
||||
) {
|
||||
if(image->texture == NULL) return;
|
||||
shaderUsePositionAndScale(shader, uniformModel,
|
||||
x,y,0,
|
||||
0,0,0,
|
||||
image->width, image->height, 1
|
||||
);
|
||||
shaderUseTexture(shader, uniformTexture, image->texture);
|
||||
primitiveDraw(&image->quad, 0, -1);
|
||||
}
|
||||
|
||||
void imageDispose(image_t *image) {
|
||||
if(image->quad.verticeCount != -1) primitiveDispose(&image->quad);
|
||||
}
|
72
src/dawn/ui/image.h
Normal file
72
src/dawn/ui/image.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"
|
||||
#include "../display/primitive/primitive.h"
|
||||
#include "../display/primitive/quad.h"
|
||||
#include "../display/texture.h"
|
||||
#include "../display/shader.h"
|
||||
|
||||
typedef struct {
|
||||
texture_t *texture;
|
||||
primitive_t quad;
|
||||
float width, height;
|
||||
} image_t;
|
||||
|
||||
/**
|
||||
* Initialize an image.
|
||||
*
|
||||
* @param image Image to initialize.
|
||||
*/
|
||||
void imageInit(image_t *image);
|
||||
|
||||
/**
|
||||
* Set the texture for an image. This will also initialize the underlying quad.
|
||||
*
|
||||
* @param image Image to set the texture for.
|
||||
* @param texture Texture to use.
|
||||
*/
|
||||
void imageSetTexture(image_t *image, texture_t *texture);
|
||||
|
||||
/**
|
||||
* Set the texture for an image. This will also initialize the underlying quad.
|
||||
* Also allows cropping of the texture image.
|
||||
*
|
||||
* @param image Image to set the texture for.
|
||||
* @param texture Texture to use.
|
||||
* @param x X position of the crop.
|
||||
* @param y Y position of the crop.
|
||||
* @param width Width of the crop.
|
||||
* @param height Height of the crop.
|
||||
*/
|
||||
void imageSetTextureAndCrop(image_t *image, texture_t *texture,
|
||||
float x, float y, float width, float height
|
||||
);
|
||||
|
||||
/**
|
||||
* Render an image
|
||||
*
|
||||
* @param image Image to render.
|
||||
* @param shader Shader to use while rendering.
|
||||
* @param uniformModel Shader uniform for the model position.
|
||||
* @param uniformTexture Shader uniform for the texture.
|
||||
* @param x X position.
|
||||
* @param y Y position.
|
||||
*/
|
||||
void imageRender(
|
||||
image_t *image, shader_t *shader,
|
||||
shaderuniform_t uniformModel, shaderuniform_t uniformTexture,
|
||||
float x, float y
|
||||
);
|
||||
|
||||
/**
|
||||
* Cleanup a previously initialized image.
|
||||
*
|
||||
* @param image Image to dispose.
|
||||
*/
|
||||
void imageDispose(image_t *image);
|
43
src/dawn/ui/label.c
Normal file
43
src/dawn/ui/label.c
Normal file
@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "label.h"
|
||||
|
||||
void labelInit(label_t *label) {
|
||||
label->fontSize = FONT_SIZE_DEFAULT;
|
||||
label->font = NULL;
|
||||
label->maxWidth = -1;
|
||||
label->primitive.verticeCount = 0;
|
||||
}
|
||||
|
||||
void labelSetText(label_t *label, font_t *font, char *text) {
|
||||
if(label->primitive.verticeCount != 0) {
|
||||
primitiveDispose(&label->primitive);
|
||||
label->primitive.verticeCount = 0;
|
||||
}
|
||||
|
||||
label->font = font;
|
||||
fontTextBuffer(
|
||||
font, &label->primitive, &label->info, text,
|
||||
label->maxWidth, label->fontSize
|
||||
);
|
||||
}
|
||||
|
||||
void labelRender(
|
||||
label_t *label, shader_t *shader,
|
||||
shaderuniform_t uniformModel, shaderuniform_t uniformTexture,
|
||||
float x, float y
|
||||
) {
|
||||
if(label->primitive.verticeCount == 0) return;
|
||||
shaderUsePosition(shader, uniformModel, x,y,0, 0,0,0);
|
||||
shaderUseTexture(shader, uniformTexture, &label->font->texture);
|
||||
primitiveDraw(&label->primitive, 0, -1);
|
||||
}
|
||||
|
||||
void labelDispose(label_t *label) {
|
||||
primitiveDispose(&label->primitive);
|
||||
}
|
57
src/dawn/ui/label.h
Normal file
57
src/dawn/ui/label.h
Normal file
@ -0,0 +1,57 @@
|
||||
// Copyright (c) 2021 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "../libs.h"
|
||||
#include "../display/shader.h"
|
||||
#include "../display/primitive/primitive.h"
|
||||
#include "../display/font.h"
|
||||
|
||||
/** Representation of a Label UI Element */
|
||||
typedef struct {
|
||||
font_t *font;
|
||||
float fontSize;
|
||||
float maxWidth;
|
||||
fonttextinfo_t info;
|
||||
primitive_t primitive;
|
||||
} label_t;
|
||||
|
||||
/**
|
||||
* Initialize a Label UI Element.
|
||||
* @param label Label to initialize.
|
||||
*/
|
||||
void labelInit(label_t *label);
|
||||
|
||||
/**
|
||||
* Sets the text for a given label.
|
||||
*
|
||||
* @param label Label to update.
|
||||
* @param font Font to use.
|
||||
* @param text Text to set.
|
||||
*/
|
||||
void labelSetText(label_t *label, font_t *font, char *text);
|
||||
|
||||
/**
|
||||
* Render a label UI element.
|
||||
*
|
||||
* @param label Label to render.
|
||||
* @param shader Shader to use while rendering.
|
||||
* @param uniformModel Shader uniform for the model position.
|
||||
* @param uniformTexture Shader uniform for the texture.
|
||||
* @param x X position.
|
||||
* @param y Y position.
|
||||
*/
|
||||
void labelRender(
|
||||
label_t *label, shader_t *shader,
|
||||
shaderuniform_t uniformModel, shaderuniform_t uniformTexture,
|
||||
float x, float y
|
||||
);
|
||||
|
||||
/**
|
||||
* Dispose a previously created label.
|
||||
*
|
||||
* @param label Label to dispose.
|
||||
*/
|
||||
void labelDispose(label_t *label);
|
97
src/dawn/ui/menu.c
Normal file
97
src/dawn/ui/menu.c
Normal file
@ -0,0 +1,97 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "menu.h"
|
||||
|
||||
void menuInit(menu_t *menu) {
|
||||
menu->itemCount = 0;
|
||||
menu->selected = 0;
|
||||
menu->cursorX = 0;
|
||||
menu->cursorY = 0;
|
||||
menu->user = NULL;
|
||||
menu->onSelect = NULL;
|
||||
}
|
||||
|
||||
void menuUpdate(menu_t *menu, engine_t *engine) {
|
||||
menuitem_t *current;
|
||||
menuitem_t *item;
|
||||
uint8_t x, y, i, j;
|
||||
|
||||
current = menu->items + menu->selected;
|
||||
|
||||
if(inputIsPressed(&engine->input, INPUT_ACCEPT)) {
|
||||
if(menu->onSelect != NULL) {
|
||||
menu->onSelect(menu->user, menu->selected);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle press binds.
|
||||
if(inputIsPressed(&engine->input, INPUT_DOWN)) {
|
||||
x = 0;
|
||||
y = 1;
|
||||
} else if(inputIsPressed(&engine->input, INPUT_UP)) {
|
||||
x = 0;
|
||||
y = -1;
|
||||
} else if(inputIsPressed(&engine->input, INPUT_LEFT)) {
|
||||
x = -1;
|
||||
y = 0;
|
||||
} else if(inputIsPressed(&engine->input, INPUT_RIGHT)) {
|
||||
x = 1;
|
||||
y = 0;
|
||||
} else {
|
||||
x = 0;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
// Update cursor positions
|
||||
if(x != 0 || y != 0) {
|
||||
if(x > 0) {
|
||||
menu->cursorX = (current->x + current->width - 1) + x;
|
||||
} else if(x < 0) {
|
||||
menu->cursorX = current->x + x;
|
||||
}
|
||||
|
||||
if(y > 0) {
|
||||
menu->cursorY = (current->y + current->height - 1) + y;
|
||||
} else if(y < 0) {
|
||||
menu->cursorY = current->y + y;
|
||||
}
|
||||
|
||||
// Get the item selected
|
||||
j = MENU_ITEMS_MAX;
|
||||
for(i = 0; i < menu->itemCount; i++) {
|
||||
if(i == menu->selected) continue;
|
||||
item = menu->items + i;
|
||||
|
||||
if(
|
||||
item->x > menu->cursorX || (item->x+item->width-1) < menu->cursorX ||
|
||||
item->y > menu->cursorY || (item->y+item->height-1) < menu->cursorY
|
||||
) continue;
|
||||
|
||||
j = i;
|
||||
break;
|
||||
}
|
||||
|
||||
// Was a target found?
|
||||
if(j == MENU_ITEMS_MAX) return;
|
||||
menu->selected = j;
|
||||
}
|
||||
}
|
||||
|
||||
menuitem_t * menuAdd(menu_t *menu) {
|
||||
menuitem_t *item;
|
||||
|
||||
if(menu->itemCount >= MENU_ITEMS_MAX) return NULL;
|
||||
item = menu->items + menu->itemCount++;
|
||||
item->x = 0;
|
||||
item->y = 0;
|
||||
item->width = 1;
|
||||
item->height = 1;
|
||||
|
||||
return item;
|
||||
}
|
62
src/dawn/ui/menu.h
Normal file
62
src/dawn/ui/menu.h
Normal file
@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../libs.h"
|
||||
#include "../input/input.h"
|
||||
#include "../epoch/epoch.h"
|
||||
#include "../util/array.h"
|
||||
#include "../engine/engine.h"
|
||||
|
||||
/** The maximum number of items a menu can hold */
|
||||
#define MENU_ITEMS_MAX 32
|
||||
|
||||
/** Callback for when menu events are fired. */
|
||||
typedef void menucallback_t(void *user, uint8_t i);
|
||||
|
||||
typedef struct {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
uint8_t width;
|
||||
uint8_t height;
|
||||
} menuitem_t;
|
||||
|
||||
typedef struct {
|
||||
menuitem_t items[MENU_ITEMS_MAX];
|
||||
uint8_t itemCount;
|
||||
uint8_t selected;
|
||||
uint8_t cursorX;
|
||||
uint8_t cursorY;
|
||||
|
||||
void *user;
|
||||
menucallback_t *onSelect;
|
||||
} menu_t;
|
||||
|
||||
/**
|
||||
* Initialize a menu.
|
||||
*
|
||||
* @param menu Menu to initialize.
|
||||
* @param columns Count of rows.
|
||||
* @param rows Count of columns.
|
||||
*/
|
||||
void menuInit(menu_t *menu);
|
||||
|
||||
/**
|
||||
* Updates the menu to handle inputs.
|
||||
*
|
||||
* @param menu Menu to update.
|
||||
* @param engine Engine to update from.
|
||||
*/
|
||||
void menuUpdate(menu_t *menu, engine_t *engine);
|
||||
|
||||
/**
|
||||
* Add an item to the menu
|
||||
*
|
||||
* @param menu Menu to add to.
|
||||
* @return Item to add to.
|
||||
*/
|
||||
menuitem_t * menuAdd(menu_t *menu);
|
40
src/dawn/ui/rectangle.c
Normal file
40
src/dawn/ui/rectangle.c
Normal file
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "rectangle.h"
|
||||
|
||||
void rectangleInit(rectangle_t *rectangle) {
|
||||
rectangle->width = 32;
|
||||
rectangle->height = 32;
|
||||
textureInit(&rectangle->texture, 1, 1, NULL);
|
||||
quadInit(&rectangle->quad, 0, 0,0,0,0, 1,1,1,1);
|
||||
}
|
||||
|
||||
void rectangleSetColor(rectangle_t *rectangle, pixel_t color) {
|
||||
textureBufferPixels(&rectangle->texture,
|
||||
0, 0, 1, 1, &color
|
||||
);
|
||||
}
|
||||
|
||||
void rectangleRender(
|
||||
rectangle_t *rect, shader_t *shader,
|
||||
shaderuniform_t uniformModel, shaderuniform_t uniformTexture,
|
||||
float x, float y
|
||||
) {
|
||||
shaderUsePositionAndScale(shader, uniformModel,
|
||||
x, y, 0,
|
||||
0, 0, 0,
|
||||
rect->width, rect->height, 1
|
||||
);
|
||||
shaderUseTexture(shader, uniformTexture, &rect->texture);
|
||||
primitiveDraw(&rect->quad, 0, -1);
|
||||
}
|
||||
|
||||
void rectangleDispose(rectangle_t *rectangle) {
|
||||
primitiveDispose(&rectangle->quad);
|
||||
textureDispose(&rectangle->texture);
|
||||
}
|
31
src/dawn/ui/rectangle.h
Normal file
31
src/dawn/ui/rectangle.h
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../libs.h"
|
||||
#include "../display/texture.h"
|
||||
#include "../display/shader.h"
|
||||
#include "../display/primitive/primitive.h"
|
||||
#include "../display/primitive/quad.h"
|
||||
|
||||
typedef struct {
|
||||
float width, height;
|
||||
texture_t texture;
|
||||
primitive_t quad;
|
||||
} rectangle_t;
|
||||
|
||||
void rectangleInit(rectangle_t *rectangle);
|
||||
|
||||
void rectangleSetColor(rectangle_t *rectangle, pixel_t color);
|
||||
|
||||
void rectangleRender(
|
||||
rectangle_t *rect, shader_t *shader,
|
||||
shaderuniform_t uniformModel, shaderuniform_t uniformTexture,
|
||||
float x, float y
|
||||
);
|
||||
|
||||
void rectangleDispose(rectangle_t *rectangle);
|
81
src/dawn/ui/textmenu.c
Normal file
81
src/dawn/ui/textmenu.c
Normal file
@ -0,0 +1,81 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "textmenu.h"
|
||||
|
||||
void _textMenuOnSelect(void *user, uint8_t i) {
|
||||
textmenu_t *textMenu = (textmenu_t *)user;
|
||||
|
||||
if(textMenu->onSelect != NULL) {
|
||||
textMenu->onSelect(textMenu->user, i, textMenu->texts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void textMenuInit(textmenu_t *menu, font_t *font) {
|
||||
menuInit(&menu->menu);
|
||||
gridInit(&menu->grid);
|
||||
rectangleInit(&menu->rectangle);
|
||||
rectangleSetColor(&menu->rectangle, TEXTMENU_SELECTION_COLOR);
|
||||
|
||||
menu->menu.user = menu;
|
||||
menu->menu.onSelect = &_textMenuOnSelect;
|
||||
menu->font = font;
|
||||
menu->onSelect = NULL;
|
||||
}
|
||||
|
||||
menuitem_t * textMenuAdd(textmenu_t *menu, char *item) {
|
||||
menu->texts[menu->menu.itemCount] = item;
|
||||
labelInit(menu->labels + menu->menu.itemCount);
|
||||
labelSetText(menu->labels + menu->menu.itemCount, menu->font, item);
|
||||
(menu->labels + menu->menu.itemCount)->font = menu->font;
|
||||
return menuAdd(&menu->menu);
|
||||
}
|
||||
|
||||
void textMenuRender(
|
||||
textmenu_t *menu, shader_t *shader,
|
||||
shaderuniform_t uniformModel, shaderuniform_t uniformTexture,
|
||||
float x, float y
|
||||
) {
|
||||
uint8_t i;
|
||||
label_t *label;
|
||||
menuitem_t *item;
|
||||
align_t align;
|
||||
float gx, gy;
|
||||
|
||||
// Render selection box.
|
||||
item = menu->menu.items + menu->menu.selected;
|
||||
gridGetChild(
|
||||
&menu->grid, item->x, item->y, item->width, item->height,
|
||||
&gx, &gy, &menu->rectangle.width, &menu->rectangle.height
|
||||
);
|
||||
rectangleRender(
|
||||
&menu->rectangle, shader, uniformModel, uniformTexture, x + gx, y + gy
|
||||
);
|
||||
|
||||
// Render labels
|
||||
for(i = 0; i < menu->menu.itemCount; i++) {
|
||||
item = menu->menu.items + i;
|
||||
label = menu->labels + i;
|
||||
align = gridGetAndAlignChild(
|
||||
&menu->grid, item->x, item->y, item->width, item->height,
|
||||
ALIGN_POS_START | ALIGN_SIZE_ORIGINAL,
|
||||
ALIGN_POS_START | ALIGN_SIZE_ORIGINAL,
|
||||
label->info.width, label->info.height
|
||||
);
|
||||
labelRender(
|
||||
label, shader, uniformModel, uniformTexture, align.x + x, align.y + y
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void textMenuDispse(textmenu_t *menu) {
|
||||
uint8_t i;
|
||||
rectangleDispose(&menu->rectangle);
|
||||
for(i = 0; i < menu->menu.itemCount; i++) {
|
||||
labelDispose(menu->labels + i);
|
||||
}
|
||||
}
|
75
src/dawn/ui/textmenu.h
Normal file
75
src/dawn/ui/textmenu.h
Normal file
@ -0,0 +1,75 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../libs.h"
|
||||
#include "menu.h"
|
||||
#include "grid.h"
|
||||
#include "label.h"
|
||||
#include "rectangle.h"
|
||||
|
||||
/** Colour of the selection box for the text menu */
|
||||
#define TEXTMENU_SELECTION_COLOR ((pixel_t){.r=0xFF,.g=0xFF,.b=0xFF,.a=0x64})
|
||||
|
||||
/** Callback type for when an item is selected */
|
||||
typedef void textmenucallback_t(void *user, uint8_t i, char *text);
|
||||
|
||||
typedef struct {
|
||||
menu_t menu;
|
||||
grid_t grid;
|
||||
font_t *font;
|
||||
rectangle_t rectangle;
|
||||
|
||||
char *texts[MENU_ITEMS_MAX];
|
||||
label_t labels[MENU_ITEMS_MAX];
|
||||
|
||||
textmenucallback_t *onSelect;
|
||||
void *user;
|
||||
} textmenu_t;
|
||||
|
||||
/** Callback to be notified from the menu when the menu items are selected. */
|
||||
void _textMenuOnSelect(void *user, uint8_t i);
|
||||
|
||||
/**
|
||||
* Initialize a text menu item.
|
||||
*
|
||||
* @param menu Menu to initialize.
|
||||
* @param font Font to use during initialization.
|
||||
*/
|
||||
void textMenuInit(textmenu_t *menu, font_t *font);
|
||||
|
||||
/**
|
||||
* Add text to a menu list.
|
||||
*
|
||||
* @param menu Menu to add to.
|
||||
* @param item Text to add (must be a constant value).
|
||||
* @return The grid subsystem item.
|
||||
*/
|
||||
menuitem_t * textMenuAdd(textmenu_t *menu, char *item);
|
||||
|
||||
/**
|
||||
* Render a text menu list.
|
||||
*
|
||||
* @param menu Menu to render.
|
||||
* @param shader Shader to use.
|
||||
* @param uniformModel Shader uniform for the model position.
|
||||
* @param uniformTexture Shader uniform for the texture.
|
||||
* @param x X position of the menu.
|
||||
* @param y Y position of the menu.
|
||||
*/
|
||||
void textMenuRender(
|
||||
textmenu_t *menu, shader_t *shader,
|
||||
shaderuniform_t uniformModel, shaderuniform_t uniformTexture,
|
||||
float x, float y
|
||||
);
|
||||
|
||||
/**
|
||||
* Dispose/Cleanup a text menu.
|
||||
*
|
||||
* @param menu Text menu to dispose.
|
||||
*/
|
||||
void textMenuDispse(textmenu_t *menu);
|
Reference in New Issue
Block a user