#include #include #include "Ui.h" #include "render.h" struct List *newList(struct Ui_Colors *colors) { struct List *list = malloc(sizeof(struct List)); if (list == NULL) return NULL; initList(list); list->colors = colors; return list; } int freeList(struct List *list) { freeListItems(list); free(list); // :) return 0; } int initList(struct List *list) { if (list == NULL) return 1; list->box.x = list->box.y = list->box.w = list->box.h = 0; list->page = list->items_per_page = list->count = list->selected = 0; list->items = NULL; return 0; } int remListIndex(struct List *list, int index) { if (index > list->count || index < 0) { return 1; } struct Button* r_hand[list->count-index+1]; memcpy(&r_hand, list->items+index+1, (list->count-(index+1))*sizeof(struct Button*)); list->items = realloc(list->items, (list->count-1)*(sizeof(struct Button*))); memcpy(list->items+index, r_hand, (list->count-(index+1))*sizeof(struct Button*)); list->count--; return 0; } int addListItem(struct List *list, struct Button *item) { list->count++; list->items = realloc(list->items, sizeof(struct Button*)*list->count); list->items[list->count-1] = item; return 0; } int remListItem(struct List *list, struct Button *item) { int i; for(i = 0; i < list->count; i++) { if (list->items[i] == item) { return remListIndex(list, i); } } return 1; } int freeListItems(struct List *list) { int i; for(i = 0; i < list->count; i++) { freeButton(list->items[i]); } free(list->items); list->items = NULL; list->count = 0; return 0; } int prepList(struct List *list) { int i; int offset_y = 0; for(i = 0; i < list->count; i++) { list->items[i]->box.y = offset_y; offset_y += list->items[i]->box.h; } return 0; } int renderList(struct List *list) { if (list == NULL) return 1; int i; int base_x = list->box.x; int base_y = list->box.y; renderSQuad(base_x, base_y, list->box.w, list->box.h, list->colors->bg); int offset_y = 0; for(i = 0; i < list->count; i++) { int x = base_x + (list->box.w/2) - (list->items[i]->box.w/2); int y = base_y + offset_y + list->items[i]->box.y; if (list->items[i]->flags & UI_ACTIVE) { renderSQuad(base_x, base_y+offset_y, list->box.w, list->items[i]->box.h, list->items[i]->colors->fg); renderGlyphString(list->items[i]->glyphs, list->items[i]->colors->bg, x, y, list->items[i]->text); } else { renderSQuad(base_x, base_y+offset_y, list->box.w, list->items[i]->box.h, list->items[i]->colors->bg); renderGlyphString(list->items[i]->glyphs, list->items[i]->colors->fg, x, y, list->items[i]->text); } /*if (i%2 == 0) { renderSQuad(base_x, base_y+offset_y, list->box.w, list->items[i]->box.h, list->colors->fg); renderGlyphString(list->items[i]->glyphs, list->items[i]->colors->bg, x, y, list->items[i]->text); } else { renderSQuad(base_x, base_y+offset_y, list->box.w, list->items[i]->box.h, list->items[i]->colors->bg); renderGlyphString(list->items[i]->glyphs, list->items[i]->colors->fg, x, y, list->items[i]->text); }*/ //int x = base_x + list->items[i]->box.x; offset_y += list->items[i]->box.h; } return 0; } struct Box getListItemBox(struct List *list, int i) { struct Box box = { 0, 0, 0, 0 }; if (list == NULL) return box; if (i < 0 || i > list->count) return box; box.x = 0; box.y = i * list->items[i]->box.h; // FIXME: list y should be homogenously referenced box.w = list->items[i]->box.w; box.h = list->items[i]->box.h; return box; } struct Box getListItemBoxAbs(struct List *list, int i) { struct Box box = { 0, 0, 0, 0 }; if (list == NULL) return box; if (i < 0 || i > list->count) return box; box.x = list->box.x; box.y = list->box.y + i * list->items[i]->box.h; // FIXME: list y should be homogenously referenced box.w = list->box.w; box.h = list->items[i]->box.h; return box; } struct Button *newButton(struct Glyphs *glyphs, struct Ui_Colors *colors, const char *string) { if (glyphs == NULL) return NULL; if (string == NULL) return NULL; struct Button *button = malloc(sizeof(struct Button)); if (button == NULL) return NULL; button->colors = colors; button->text = NULL; button->flags = 0; button->p_flags = 0; button->glyphs = glyphs; button->box.x = button->box.y = button->box.w = button->box.h = 0; if (setButtonText(button, string) != 0) return NULL; return button; } int freeButton(struct Button *button) { if (button == NULL) return 1; free(button->text); free(button); return 0; } int setButtonText(struct Button *button, const char *string) { if (button == NULL) return 1; if (string == NULL) return 2; if (button->glyphs == NULL) return 3; int size = strlen(string)+1; if ((button->text = realloc(button->text, size)) == NULL) { return 4; } memcpy(button->text, string, size); button->box.w = getGlyphStringW(button->glyphs, button->text)+4; button->box.h = button->glyphs->h+2; // TODO: getGlyphStringH return 0; } int renderButton(struct Button *button) { if (button == NULL) return 1; SDL_Color fg, bg; if (button->flags & UI_ACTIVE) { fg = button->colors->a_fg; bg = button->colors->a_bg; renderSQuad(button->box.x+2, button->box.y+2, button->box.w, button->box.h, bg); int x = (button->box.w/2) - getGlyphStringW(button->glyphs, button->text)/2; renderGlyphString(button->glyphs, button->colors->a_fg, button->box.x+x+2, button->box.y+2, button->text); } else { fg = button->colors->fg; bg = button->colors->bg; // draw shadow renderSQuad(button->box.x+2, button->box.y+2, button->box.w, button->box.h, button->colors->a_bg); renderSQuad(button->box.x, button->box.y, button->box.w, button->box.h, bg); int x = (button->box.w/2) - getGlyphStringW(button->glyphs, button->text)/2; renderGlyphString(button->glyphs, button->colors->fg, button->box.x+x, button->box.y, button->text); } if (button->p_flags & UI_BORDER) { renderLQuad(button->box.x, button->box.y, button->box.w+2, button->box.h+2, fg); } return 0; } struct TextInput *newTextInput(struct Glyphs *glyphs, struct Ui_Colors *colors, int width) { if (glyphs == NULL) return NULL; if (colors == NULL) return NULL; struct TextInput *input = malloc(sizeof(struct TextInput)); if (input == NULL) return NULL; input->colors = colors; input->text = malloc(1); input->text[0] = '\0'; input->cursor = 0; input->p_flags = 0; input->flags = 0; input->glyphs = glyphs; input->box.x = input->box.y = input->box.w = input->box.h = 0; input->box.w = width; input->box.h = input->glyphs->h; // TODO: getGlyphStringH return input; } int freeTextInput(struct TextInput *input) { free(input->text); free(input); return 0; } int insertTextInput(struct TextInput *text_input, const char *string) { int text_size = strlen(text_input->text)+1; int string_size = strlen(string)+1; // calculate insert position int l_hand = text_input->cursor*sizeof(char); int r_hand = (text_size - l_hand)*sizeof(char); // create a copy of our current text char temp[r_hand]; memcpy(&temp, text_input->text+l_hand, r_hand); // reallocate our text to fit added string text_input->text = realloc(text_input->text, text_size+string_size-1); // insert string, minus \0 memcpy(text_input->text+l_hand, string, string_size-1); // copy over right-hand side of the text memcpy(text_input->text+l_hand+string_size-1, &temp, r_hand); text_input->cursor += string_size-1; // hopefully nothing exploded return 0; } int deleteTextInput(struct TextInput *text_input, int start, int length) { if (text_input == NULL) return 1; int text_size = strlen(text_input->text)+1; if (start < 0 || start > text_size) return 2; if (length <= 0 || start+length > text_size) return 2; char temp[text_size - (start+length)]; memcpy(&temp, text_input->text+start+length, text_size - (start+length)); text_input->text = realloc(text_input->text, text_size-length); memcpy(text_input->text+start, temp, text_size-(start+length)); return 0; } int setTextInputText(struct TextInput *text_input, const char *string, ...) { if (text_input == NULL) return 1; if (string == NULL) return 2; if (text_input->glyphs == NULL) return 3; char buf[128]; char *buffer; int overflow; va_list args; buffer = buf; va_start(args, string); overflow = vsnprintf(buffer, 128, string, args); va_end(args); // did we overflow? if (overflow >= 128) { buffer = (char*)malloc(overflow+1); va_start(args, string); overflow = vsnprintf(buffer, overflow+1, string, args); va_end(args); } if ((text_input->text = realloc(text_input->text, overflow+1)) == NULL) { return 4; } memcpy(text_input->text, buffer, overflow+1); if (buffer != buf) { free(buffer); } text_input->cursor = overflow; //text_input->box.w = getGlyphStringW(text_input->glyphs, string); //text_input->box.h = text_input->glyphs->h; // TODO: getGlyphStringH return 0; } int renderTextInput(struct TextInput *input) { if (input == NULL) return 1; SDL_Color fg, bg; if (input->flags & UI_ACTIVE) { fg = input->colors->a_fg; bg = input->colors->a_bg; } else { fg = input->colors->fg; bg = input->colors->bg; } renderSQuad(input->box.x, input->box.y, input->box.w, input->box.h, bg); renderGlyphString(input->glyphs, input->colors->fg, input->box.x+2, input->box.y, input->text); if (input->p_flags & UI_BORDER) { renderLQuad(input->box.x, input->box.y, input->box.w+2, input->box.h+2, fg); } // draw cursor char cursor_offset[input->cursor+1]; memcpy(&cursor_offset, input->text, input->cursor); cursor_offset[input->cursor] = '\0'; renderGlyph(input->glyphs, input->colors->fg, '|', input->box.x+getGlyphStringW(input->glyphs, cursor_offset)-3, input->box.y); return 0; } struct Textt *newTextt(struct Glyphs *glyphs, struct Ui_Colors *colors, const char *string) { if (glyphs == NULL) return NULL; if (string == NULL) return NULL; struct Textt *text = malloc(sizeof(struct Textt)); if (text == NULL) return NULL; text->colors = colors; text->text = NULL; text->flags = 0; text->p_flags = 0; text->glyphs = glyphs; text->box.x = text->box.y = text->box.w = text->box.h = 0; if (setTextt(text, string) != 0) return NULL; return text; } int freeTextt(struct Textt *text) { if (text == NULL) return 1; free(text->text); free(text); return 0; } int setTextt(struct Textt *text, const char *string, ...) { char buf[128]; char *buffer; int overflow; va_list args; buffer = buf; va_start(args, string); overflow = vsnprintf(buffer, 128, string, args); va_end(args); // did we overflow? if (overflow >= 128) { buffer = (char*)malloc(overflow+1); va_start(args, string); overflow = vsnprintf(buffer, overflow+1, string, args); va_end(args); } if ((text->text = realloc(text->text, overflow+1)) == NULL) { return 4; } memcpy(text->text, buffer, overflow+1); if (buffer != buf) { free(buffer); } text->box.w = getGlyphStringW(text->glyphs, text->text); text->box.h = text->glyphs->h; // TODO: getGlyphStringH return 0; } int addTexttChar(struct Textt *text, char ch) { // eww printf("old: %s\n", text->text); int size = strlen(text->text)+1; text->text = realloc(text->text, size+1); text->text[size] = ch; text->text[size+1] = '\0'; printf("added %c, string is now \"%s\"\n", ch, text->text); return 0; } int renderTextt(struct Textt *text) { if (text == NULL) return 1; SDL_Color fg, bg; if (text->flags & UI_ACTIVE) { fg = text->colors->a_fg; bg = text->colors->a_bg; //renderSQuad(text->box.x+2, text->box.y+2, text->box.w, text->box.h, bg); int x = (text->box.w/2) - getGlyphStringW(text->glyphs, text->text)/2; renderGlyphString(text->glyphs, text->colors->a_fg, text->box.x+x+2, text->box.y+2, text->text); } else { fg = text->colors->fg; bg = text->colors->bg; // draw shadow //renderSQuad(text->box.x, text->box.y, text->box.w, text->box.h, bg); int x = (text->box.w/2) - getGlyphStringW(text->glyphs, text->text)/2; renderGlyphString(text->glyphs, text->colors->fg, text->box.x+x, text->box.y, text->text); } if (text->p_flags & UI_BORDER) { renderLQuad(text->box.x, text->box.y, text->box.w+2, text->box.h+2, fg); } return 0; }