cOMS/ui/UITheme.h

352 lines
16 KiB
C

#ifndef TOS_UI_THEME_H
#define TOS_UI_THEME_H
#include "../stdlib/Types.h"
#include "../memory/RingMemory.h"
#include "../utils/EndianUtils.h"
#include "../stdlib/HashMap.h"
#include "../font/Font.h"
#include "UIAttribute.h"
#include "UIElementType.h"
#if _WIN32
#include "../platform/win32/UtilsWin32.h"
#else
#include "../platform/linux/UtilsLinux.h"
#endif
#define UI_THEME_VERSION 1
struct UITheme {
byte* data;
int32 version;
char name[32];
bool is_active;
// Every element has all the style attributes
UIAttribute styles_global[UI_ELEMENT_TYPE_SIZE * UI_ATTRIBUTE_TYPE_SIZE];
// A theme may have N named styles
// @todo We should probably create a hashmap
// key = name
// value = pointer to group (in the file we store the offset when we load it into memory convert it to pointer)
HashMap hash_map;
int32 style_group_count;
UIAttributeGroup* style_groups;
Font font;
// @todo add cursor styles
};
// WARNING: theme needs to have memory already reserved and asigned to data
void theme_from_file_txt(
RingMemory* ring,
const char* path,
UITheme* theme
) {
FileBody file;
file_read(path, &file, ring);
char* pos = (char *) file.content;
theme->version = strtol(pos, &pos, 10); ++pos;
bool block_open = false;
char block_name[32];
char attribute_name[32];
bool last_token_newline = false;
while (*pos != '\0') {
while (*pos == ' ' || *pos == '\t') {
++pos;
}
if (*pos == '\n') {
++pos;
// 2 new lines => closing block
if (last_token_newline) {
block_open = false;
last_token_newline = false;
} else {
last_token_newline = true;
}
continue;
}
last_token_newline = false;
if (!block_open) {
int32 i = 0;
while (*pos != '\0' && *pos != ' ' && *pos != '\n' && i < 31) {
block_name[i] = *pos;
++pos;
++i;
}
block_name[i] = '\0';
if (*block_name == '#') {
// Named style
// @todo create new style
}
continue;
}
int32 i = 0;
while (*pos != '\0' && *pos != ' ' && *pos != '\n' && i < 31) {
attribute_name[i] = *pos;
++pos;
++i;
}
attribute_name[i] = '\0';
// Skip any white spaces or other delimeters
while (*pos == ' ' || *pos == ':') {
++pos;
}
ASSERT_SIMPLE((*pos != '\0' && *pos != '\n'));
// Handle different attribute types
UIAttribute attribute;
if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_FONT_COLOR), attribute_name) == 0) {
++pos; // Skip '#'
attribute.attribute_id = UI_ATTRIBUTE_TYPE_FONT_COLOR;
uint32 value = (uint32) strtoul(pos, &pos, 16);
pos += 4;
attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f;
attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f;
attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f;
attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_FONT_SIZE), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_FONT_SIZE;
attribute.value_int = strtoul(pos, &pos, 10); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_FONT_WEIGHT), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_FONT_WEIGHT;
attribute.value_int = strtoul(pos, &pos, 10); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_FONT_LINE_HEIGHT), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_FONT_LINE_HEIGHT;
attribute.value_int = strtoul(pos, &pos, 10); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_ALIGN_H), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_ALIGN_H;
attribute.value_int = strtoul(pos, &pos, 10); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_ALIGN_V), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_ALIGN_V;
attribute.value_int = strtoul(pos, &pos, 10); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_ZINDEX), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_ZINDEX;
attribute.value_float = SWAP_ENDIAN_LITTLE(strtof(pos, &pos)); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BACKGROUND_COLOR), attribute_name) == 0) {
++pos; // Skip '#'
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BACKGROUND_COLOR;
uint32 value = (uint32) strtoul(pos, &pos, 16);
pos += 4;
attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f;
attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f;
attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f;
attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BACKGROUND_IMG), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BACKGROUND_IMG;
i = 0;
while (*pos != '\0' && *pos != '\n') {
attribute.value_str[i] = *pos++;
}
attribute.value_str[i] = '\0';
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_OPACITY), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_OPACITY;
attribute.value_float = SWAP_ENDIAN_LITTLE(strtof(pos, &pos)); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_POSITION_V), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_POSITION_V;
attribute.value_int = strtoul(pos, &pos, 10); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_POSITION_H), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_POSITION_H;
attribute.value_int = strtoul(pos, &pos, 10); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_STYLE), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_STYLE;
attribute.value_int = strtoul(pos, &pos, 10); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BORDER_COLOR), attribute_name) == 0) {
++pos; // Skip '#'
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_COLOR;
uint32 value = (uint32) strtoul(pos, &pos, 16);
pos += 4;
attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f;
attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f;
attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f;
attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BORDER_WIDTH), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_WIDTH;
attribute.value_int = strtoul(pos, &pos, 10); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BORDER_TOP_COLOR), attribute_name) == 0) {
++pos; // Skip '#'
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_TOP_COLOR;
uint32 value = (uint32) strtoul(pos, &pos, 16);
pos += 4;
attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f;
attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f;
attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f;
attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BORDER_TOP_WIDTH), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_TOP_WIDTH;
attribute.value_int = strtoul(pos, &pos, 10); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BORDER_RIGHT_COLOR), attribute_name) == 0) {
++pos; // Skip '#'
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_RIGHT_COLOR;
uint32 value = (uint32) strtoul(pos, &pos, 16);
pos += 4;
attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f;
attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f;
attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f;
attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BORDER_RIGHT_WIDTH), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_RIGHT_WIDTH;
attribute.value_int = strtoul(pos, &pos, 10); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BORDER_BOTTOM_COLOR), attribute_name) == 0) {
++pos; // Skip '#'
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_BOTTOM_COLOR;
uint32 value = (uint32) strtoul(pos, &pos, 16);
pos += 4;
attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f;
attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f;
attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f;
attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BORDER_BOTTOM_WIDTH), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_BOTTOM_WIDTH;
attribute.value_int = strtoul(pos, &pos, 10); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BORDER_LEFT_COLOR), attribute_name) == 0) {
++pos; // Skip '#'
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_LEFT_COLOR;
uint32 value = (uint32) strtoul(pos, &pos, 16);
pos += 4;
attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f;
attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f;
attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f;
attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BORDER_LEFT_WIDTH), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_LEFT_WIDTH;
attribute.value_int = strtoul(pos, &pos, 10); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_PADDING), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_PADDING;
attribute.value_int = strtoul(pos, &pos, 10); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_PADDING_TOP), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_PADDING_TOP;
attribute.value_int = strtoul(pos, &pos, 10); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_PADDING_RIGHT), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_PADDING_RIGHT;
attribute.value_int = strtoul(pos, &pos, 10); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_PADDING_BOTTOM), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_PADDING_BOTTOM;
attribute.value_int = strtoul(pos, &pos, 10); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_PADDING_LEFT), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_PADDING_LEFT;
attribute.value_int = strtoul(pos, &pos, 10); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_SHADOW_INNER_COLOR), attribute_name) == 0) {
++pos; // Skip '#'
attribute.attribute_id = UI_ATTRIBUTE_TYPE_SHADOW_INNER_COLOR;
uint32 value = (uint32) strtoul(pos, &pos, 16);
pos += 4;
attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f;
attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f;
attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f;
attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_SHADOW_INNER_ANGLE), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_SHADOW_INNER_ANGLE;
attribute.value_float = strtof(pos, &pos); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_SHADOW_INNER_DISTANCE), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_SHADOW_INNER_DISTANCE;
attribute.value_int = strtoul(pos, &pos, 10); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_SHADOW_OUTER_COLOR), attribute_name) == 0) {
++pos; // Skip '#'
attribute.attribute_id = UI_ATTRIBUTE_TYPE_SHADOW_OUTER_COLOR;
uint32 value = (uint32) strtoul(pos, &pos, 16);
pos += 4;
attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f;
attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f;
attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f;
attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_SHADOW_OUTER_ANGLE), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_SHADOW_OUTER_ANGLE;
attribute.value_float = strtof(pos, &pos); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_SHADOW_OUTER_DISTANCE), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_SHADOW_OUTER_DISTANCE;
attribute.value_int = strtoul(pos, &pos, 10); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_TRANSITION_ANIMATION), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_TRANSITION_ANIMATION;
attribute.value_int = strtoul(pos, &pos, 10); ++pos;
} else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_TRANSITION_DURATION), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_TRANSITION_DURATION;
attribute.value_float = strtof(pos, &pos); ++pos;
} else {
continue;
}
if (block_name[0] == '#') {
// Named block
} else {
// Global default elements and their attributes
int32 element_type = -1;
for (int j = 0; j < UI_ELEMENT_TYPE_SIZE; ++j) {
if (strcmp(ui_element_type_to_string((UIElementType) j), block_name) == 0) {
element_type = j;
break;
}
}
if (element_type < 0) {
continue;
}
memcpy(
theme->styles_global + element_type * UI_ATTRIBUTE_TYPE_SIZE,
&attribute,
sizeof(attribute)
);
}
}
}
void theme_from_file(
RingMemory* ring,
const char* path,
UITheme* theme
) {
// version
// global definitions
// names count
//
}
void theme_to_file(RingMemory* ring,
const char* path,
const UITheme* theme
) {
}
#endif