mirror of
https://github.com/Karaka-Management/cOMS.git
synced 2026-01-10 19:08:39 +00:00
293 lines
12 KiB
C++
Executable File
293 lines
12 KiB
C++
Executable File
#ifndef COMS_UI_ATTRIBUTE_H
|
|
#define COMS_UI_ATTRIBUTE_H
|
|
|
|
#include "../../stdlib/Types.h"
|
|
#include "../../utils/StringUtils.h"
|
|
#include "../../math/Evaluator.h"
|
|
#include "../../compiler/CompilerUtils.h"
|
|
#include "UIAttributeType.h"
|
|
#include "UIAttributeDimension.h"
|
|
#include "UIAttributeFont.h"
|
|
|
|
enum UIAttributeDataType : byte {
|
|
UI_ATTRIBUTE_DATA_TYPE_INT,
|
|
UI_ATTRIBUTE_DATA_TYPE_F32,
|
|
UI_ATTRIBUTE_DATA_TYPE_STR,
|
|
UI_ATTRIBUTE_DATA_TYPE_V4_F32,
|
|
};
|
|
|
|
struct UIAttribute {
|
|
// Attributes use ids (=type name) instead of strings
|
|
UIAttributeType attribute_id;
|
|
UIAttributeDataType datatype;
|
|
|
|
union {
|
|
// @performance The string makes this struct really large when it is not needed in 95% of the cases
|
|
char value_str[32];
|
|
int32 value_int;
|
|
uint32 value_uint;
|
|
f32 value_float;
|
|
v4_f32 value_v4_f32;
|
|
};
|
|
};
|
|
|
|
struct UIAttributeGroup {
|
|
// @question Why is this a uint32 instead of uint16, I think it doesn't matter due to the alignment?!
|
|
uint32 attribute_count;
|
|
// We don't use a pointer since this would prevent us from copying around the main data owner
|
|
// The UIAttribute values come directly after UIAttributeGroup (e.g. group + 1 in memory)
|
|
//UIAttribute* attributes;
|
|
};
|
|
|
|
UIAttribute* ui_attribute_from_group(const UIAttributeGroup* group, UIAttributeType type)
|
|
{
|
|
if (!group->attribute_count) {
|
|
return NULL;
|
|
}
|
|
|
|
UIAttribute* attributes = (UIAttribute *) (group + 1);
|
|
|
|
// The following code is an optimized binary search
|
|
// @performance Consider to use EytzingerSearch for even better performance
|
|
int32 length = group->attribute_count;
|
|
while (length > 1) {
|
|
int32 half = length / 2;
|
|
length -= half;
|
|
attributes += (attributes[half - 1].attribute_id < type) * half;
|
|
}
|
|
|
|
return attributes->attribute_id == type ? attributes : NULL;
|
|
}
|
|
|
|
constexpr
|
|
int32 ui_attribute_type_to_id(const char* attribute_name)
|
|
{
|
|
if (str_compare(attribute_name, "x") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_POSITION_X;
|
|
} else if (str_compare(attribute_name, "y") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_POSITION_Y;
|
|
} else if (str_compare(attribute_name, "width") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_DIMENSION_WIDTH;
|
|
} else if (str_compare(attribute_name, "height") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_DIMENSION_HEIGHT;
|
|
} else if (str_compare(attribute_name, "width_min") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_DIMENSION_WIDTH_MIN;
|
|
} else if (str_compare(attribute_name, "height_min") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_DIMENSION_HEIGHT_MIN;
|
|
} else if (str_compare(attribute_name, "width_max") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_DIMENSION_WIDTH_MAX;
|
|
} else if (str_compare(attribute_name, "height_max") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_DIMENSION_HEIGHT_MAX;
|
|
} else if (str_compare(attribute_name, "overflow") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_DIMENSION_OVERFLOW;
|
|
} else if (str_compare(attribute_name, "font_name") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_FONT_NAME;
|
|
} else if (str_compare(attribute_name, "font_color") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_FONT_COLOR;
|
|
} else if (str_compare(attribute_name, "font_size") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_FONT_SIZE;
|
|
} else if (str_compare(attribute_name, "font_weight") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_FONT_WEIGHT;
|
|
} else if (str_compare(attribute_name, "font_line_height") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_FONT_LINE_HEIGHT;
|
|
} else if (str_compare(attribute_name, "align_h") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_ALIGN_H;
|
|
} else if (str_compare(attribute_name, "align_v") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_ALIGN_V;
|
|
} else if (str_compare(attribute_name, "zindex") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_ZINDEX;
|
|
} else if (str_compare(attribute_name, "style1") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_STYLE1;
|
|
} else if (str_compare(attribute_name, "style2") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_STYLE2;
|
|
} else if (str_compare(attribute_name, "style3") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_STYLE3;
|
|
} else if (str_compare(attribute_name, "style4") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_STYLE4;
|
|
} else if (str_compare(attribute_name, "style5") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_STYLE5;
|
|
} else if (str_compare(attribute_name, "style6") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_STYLE6;
|
|
} else if (str_compare(attribute_name, "style7") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_STYLE7;
|
|
} else if (str_compare(attribute_name, "style8") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_STYLE8;
|
|
} else if (str_compare(attribute_name, "foreground_color") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_FOREGROUND_COLOR;
|
|
} else if (str_compare(attribute_name, "foreground_img") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_FOREGROUND_IMG;
|
|
} else if (str_compare(attribute_name, "foreground_img_opacity") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_FOREGROUND_IMG_OPACITY;
|
|
} else if (str_compare(attribute_name, "foreground_img_position_v") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_FOREGROUND_IMG_POSITION_V;
|
|
} else if (str_compare(attribute_name, "foreground_img_position_h") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_FOREGROUND_IMG_POSITION_H;
|
|
} else if (str_compare(attribute_name, "foreground_img_style") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_FOREGROUND_IMG_STYLE;
|
|
} else if (str_compare(attribute_name, "background_color") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_BACKGROUND_COLOR;
|
|
} else if (str_compare(attribute_name, "background_img") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_BACKGROUND_IMG;
|
|
} else if (str_compare(attribute_name, "background_img_opacity") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_OPACITY;
|
|
} else if (str_compare(attribute_name, "background_img_position_v") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_POSITION_V;
|
|
} else if (str_compare(attribute_name, "background_img_position_h") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_POSITION_H;
|
|
} else if (str_compare(attribute_name, "background_img_style") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_STYLE;
|
|
} else if (str_compare(attribute_name, "border_color") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_BORDER_COLOR;
|
|
} else if (str_compare(attribute_name, "border_width") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_BORDER_WIDTH;
|
|
} else if (str_compare(attribute_name, "border_top_color") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_BORDER_TOP_COLOR;
|
|
} else if (str_compare(attribute_name, "border_top_width") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_BORDER_TOP_WIDTH;
|
|
} else if (str_compare(attribute_name, "border_right_color") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_BORDER_RIGHT_COLOR;
|
|
} else if (str_compare(attribute_name, "border_right_width") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_BORDER_RIGHT_WIDTH;
|
|
} else if (str_compare(attribute_name, "border_bottom_color") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_BORDER_BOTTOM_COLOR;
|
|
} else if (str_compare(attribute_name, "border_bottom_width") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_BORDER_BOTTOM_WIDTH;
|
|
} else if (str_compare(attribute_name, "border_left_color") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_BORDER_LEFT_COLOR;
|
|
} else if (str_compare(attribute_name, "border_left_width") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_BORDER_LEFT_WIDTH;
|
|
} else if (str_compare(attribute_name, "padding") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_PADDING;
|
|
} else if (str_compare(attribute_name, "padding_top") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_PADDING_TOP;
|
|
} else if (str_compare(attribute_name, "padding_right") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_PADDING_RIGHT;
|
|
} else if (str_compare(attribute_name, "padding_bottom") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_PADDING_BOTTOM;
|
|
} else if (str_compare(attribute_name, "padding_left") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_PADDING_LEFT;
|
|
} else if (str_compare(attribute_name, "scroll_style") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_SCROLL_STYLE;
|
|
} else if (str_compare(attribute_name, "scroll_x") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_SCROLL_X;
|
|
} else if (str_compare(attribute_name, "scroll_y") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_SCROLL_Y;
|
|
} else if (str_compare(attribute_name, "shadow_inner_color") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_SHADOW_INNER_COLOR;
|
|
} else if (str_compare(attribute_name, "shadow_inner_angle") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_SHADOW_INNER_ANGLE;
|
|
} else if (str_compare(attribute_name, "shadow_inner_distance") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_SHADOW_INNER_DISTANCE;
|
|
} else if (str_compare(attribute_name, "shadow_outer_color") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_SHADOW_OUTER_COLOR;
|
|
} else if (str_compare(attribute_name, "shadow_outer_angle") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_SHADOW_OUTER_ANGLE;
|
|
} else if (str_compare(attribute_name, "shadow_outer_distance") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_SHADOW_OUTER_DISTANCE;
|
|
} else if (str_compare(attribute_name, "transition_animation") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_TRANSITION_ANIMATION;
|
|
} else if (str_compare(attribute_name, "transition_duration") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_TRANSITION_DURATION;
|
|
} else if (str_compare(attribute_name, "text_limit") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_TEXT_LIMIT;
|
|
} else if (str_compare(attribute_name, "cache_size") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_CACHE_SIZE;
|
|
} else if (str_compare(attribute_name, "anim") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_ANIMATION;
|
|
} else if (str_compare(attribute_name, "vertex_count") == 0) {
|
|
return UI_ATTRIBUTE_TYPE_VERTEX_COUNT;
|
|
}
|
|
|
|
ASSERT_SIMPLE(false);
|
|
|
|
return -1;
|
|
}
|
|
|
|
inline
|
|
void ui_attribute_parse_value(UIAttribute* attr, const char* attribute_name, const char* pos)
|
|
{
|
|
attr->attribute_id = (UIAttributeType) ui_attribute_type_to_id(attribute_name);
|
|
char value[64];
|
|
|
|
str_copy_until(value, pos, "\r\n");
|
|
|
|
if (str_is_integer(value)) {
|
|
attr->value_int = (int32) str_to_int(value);
|
|
attr->datatype = UI_ATTRIBUTE_DATA_TYPE_INT;
|
|
} else if (str_is_float(value)) {
|
|
attr->value_float = str_to_float(value, NULL);
|
|
attr->datatype = UI_ATTRIBUTE_DATA_TYPE_F32;
|
|
} else if (str_is_hex_color(value)) {
|
|
++pos; // Skip '#'
|
|
hexstr_to_rgba(&attr->value_v4_f32, pos);
|
|
attr->datatype = UI_ATTRIBUTE_DATA_TYPE_V4_F32;
|
|
} else {
|
|
str_copy_until(attr->value_str, value, "\r\n");
|
|
attr->datatype = UI_ATTRIBUTE_DATA_TYPE_STR;
|
|
}
|
|
}
|
|
|
|
inline
|
|
void ui_theme_assign_f32(f32* a, const UIAttribute* attr)
|
|
{
|
|
if (attr->datatype == UI_ATTRIBUTE_DATA_TYPE_INT) {
|
|
*a = (f32) attr->value_int;
|
|
} else if (attr->datatype == UI_ATTRIBUTE_DATA_TYPE_F32) {
|
|
*a = (f32) attr->value_float;
|
|
} else if (attr->datatype == UI_ATTRIBUTE_DATA_TYPE_STR) {
|
|
ASSERT_SIMPLE(str_length(attr->value_str) > 0);
|
|
|
|
char value[32];
|
|
memcpy(value, attr->value_str, ARRAY_COUNT(attr->value_str));
|
|
*a = (f32) evaluator_evaluate(value);
|
|
}
|
|
}
|
|
|
|
inline
|
|
void ui_theme_assign_dimension(UIAttributeDimension* dimension, const UIAttribute* attr)
|
|
{
|
|
switch (attr->attribute_id) {
|
|
case UI_ATTRIBUTE_TYPE_POSITION_X: {
|
|
ui_theme_assign_f32(&dimension->dimension.x, attr);
|
|
} break;
|
|
case UI_ATTRIBUTE_TYPE_DIMENSION_WIDTH: {
|
|
ui_theme_assign_f32(&dimension->dimension.width, attr);
|
|
} break;
|
|
case UI_ATTRIBUTE_TYPE_POSITION_Y: {
|
|
ui_theme_assign_f32(&dimension->dimension.y, attr);
|
|
} break;
|
|
case UI_ATTRIBUTE_TYPE_DIMENSION_HEIGHT: {
|
|
ui_theme_assign_f32(&dimension->dimension.height, attr);
|
|
} break;
|
|
default: {
|
|
UNREACHABLE();
|
|
}
|
|
}
|
|
}
|
|
|
|
inline
|
|
void ui_theme_assign_font(UIAttributeFont* font, const UIAttribute* attr)
|
|
{
|
|
switch (attr->attribute_id) {
|
|
case UI_ATTRIBUTE_TYPE_FONT_NAME: {
|
|
UNREACHABLE();
|
|
} break;
|
|
case UI_ATTRIBUTE_TYPE_FONT_COLOR: {
|
|
font->color = attr->value_uint;
|
|
} break;
|
|
case UI_ATTRIBUTE_TYPE_FONT_SIZE: {
|
|
font->size = attr->value_float;
|
|
} break;
|
|
case UI_ATTRIBUTE_TYPE_FONT_WEIGHT: {
|
|
font->weight = attr->value_float;
|
|
} break;
|
|
case UI_ATTRIBUTE_TYPE_FONT_LINE_HEIGHT: {
|
|
font->line_height = attr->value_float;
|
|
} break;
|
|
default: {
|
|
UNREACHABLE();
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif |