mirror of
https://github.com/Karaka-Management/cOMS.git
synced 2026-01-11 11:18:40 +00:00
147 lines
4.8 KiB
C
147 lines
4.8 KiB
C
#ifndef TOS_UI_LAYOUT_H
|
|
#define TOS_UI_LAYOUT_H
|
|
|
|
#include "../stdlib/Types.h"
|
|
#include "../stdlib/HashMap.h"
|
|
#include "UIElement.h"
|
|
#include "../asset/Asset.h"
|
|
|
|
// Modified for every scene
|
|
struct UILayout {
|
|
// This array has the size of the game window and represents in color codes where interactible ui elements are
|
|
// Size is based on screen size (we don't need full screen size since we assume an interactible element is at least 4 pixels width and height)
|
|
// width = 25% of screen size
|
|
// height = 25% of screen size
|
|
uint16 width;
|
|
uint16 height;
|
|
|
|
// Contains all UI elements also dynamic ones (e.g. movable windows)
|
|
uint32* ui_chroma_codes;
|
|
|
|
// Contains constant UI elements that usually don't change (e.g. HUD)
|
|
uint32* ui_chroma_codes_static;
|
|
|
|
// Used to directly find element by name
|
|
// The values are the UIElements
|
|
HashMap hash_map;
|
|
|
|
int32 vertex_size;
|
|
Asset* ui_asset;
|
|
|
|
// @question Should we maybe also hold the font atlas asset here AND the color palette?
|
|
|
|
// Defines the length of the static vertex array
|
|
int32 vertex_size_static;
|
|
};
|
|
|
|
inline
|
|
uint32 layout_element_from_location(UILayout* layout, uint16 x, uint16 y)
|
|
{
|
|
return layout->ui_chroma_codes[layout->width * y / 4 + x / 4];
|
|
}
|
|
|
|
// This function should only get called if the location of a UI Element changes
|
|
// @performance How to handle moving elements (= dragging a window). We don't want to update this while dragging!
|
|
void layout_chroma_codes_update(UILayout* layout)
|
|
{
|
|
// Reset all
|
|
memcpy(layout->ui_chroma_codes, layout->ui_chroma_codes_static, layout->width * layout->height * sizeof(uint32));
|
|
|
|
// @question Are the dimension values below even absolute? They may be in relation to the parent?!
|
|
for (int32 i = 0; i < layout->hash_map.buf.count; ++i) {
|
|
if (!layout->hash_map.table[i]) {
|
|
continue;
|
|
}
|
|
|
|
HashEntry* entry = (HashEntry *) layout->hash_map.table[i];
|
|
UIElement* element = (UIElement *) entry->value;
|
|
|
|
if (element->is_dynamic) {
|
|
continue;
|
|
}
|
|
|
|
int32 y_start = element->dimension.y1 / 4;
|
|
int32 y_end = element->dimension.y2 / 4;
|
|
int32 x_start = element->dimension.x1 / 4;
|
|
int32 x_end = element->dimension.x2 / 4;
|
|
|
|
for (int32 y = y_start; y < y_end; ++y) {
|
|
int32 y_offset = layout->width * y;
|
|
for (int32 x = x_start; x < x_end; ++x) {
|
|
layout->ui_chroma_codes[y_offset + x] = (uint32) element->id;
|
|
}
|
|
}
|
|
|
|
// Now handle all next elements
|
|
while (entry->next) {
|
|
entry = entry->next;
|
|
|
|
element = (UIElement *) entry->value;
|
|
|
|
y_start = element->dimension.y1 / 4;
|
|
y_end = element->dimension.y2 / 4;
|
|
x_start = element->dimension.x1 / 4;
|
|
x_end = element->dimension.x2 / 4;
|
|
|
|
for (int32 y = y_start; y < y_end; ++y) {
|
|
int32 y_offset = layout->width * y;
|
|
for (int32 x = x_start; x < x_end; ++x) {
|
|
layout->ui_chroma_codes[y_offset + x] = (uint32) element->id;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void layout_chroma_codes_update_static(UILayout* layout)
|
|
{
|
|
// Reset all
|
|
memset(layout->ui_chroma_codes_static, 0, layout->width * layout->height * sizeof(uint32));
|
|
|
|
// @question Are the dimension values below even absolute? They may be in relation to the parent?!
|
|
for (int32 i = 0; i < layout->hash_map.buf.count; ++i) {
|
|
if (!layout->hash_map.table[i]) {
|
|
continue;
|
|
}
|
|
|
|
HashEntry* entry = (HashEntry *) layout->hash_map.table[i];
|
|
UIElement* element = (UIElement *) entry->value;
|
|
|
|
if (!element->is_dynamic) {
|
|
continue;
|
|
}
|
|
|
|
int32 y_start = element->dimension.y1 / 4;
|
|
int32 y_end = element->dimension.y2 / 4;
|
|
int32 x_start = element->dimension.x1 / 4;
|
|
int32 x_end = element->dimension.x2 / 4;
|
|
|
|
for (int32 y = y_start; y < y_end; ++y) {
|
|
int32 y_offset = layout->width * y;
|
|
for (int32 x = x_start; x < x_end; ++x) {
|
|
layout->ui_chroma_codes_static[y_offset + x] = (uint32) element->id;
|
|
}
|
|
}
|
|
|
|
// Now handle all next elements
|
|
while (entry->next) {
|
|
entry = entry->next;
|
|
|
|
element = (UIElement *) entry->value;
|
|
|
|
y_start = element->dimension.y1 / 4;
|
|
y_end = element->dimension.y2 / 4;
|
|
x_start = element->dimension.x1 / 4;
|
|
x_end = element->dimension.x2 / 4;
|
|
|
|
for (int32 y = y_start; y < y_end; ++y) {
|
|
int32 y_offset = layout->width * y;
|
|
for (int32 x = x_start; x < x_end; ++x) {
|
|
layout->ui_chroma_codes_static[y_offset + x] = (uint32) element->id;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif |