kettek2/wiki/games/newsboy/Newsboy_0x00/engine/Ui.c

374 lines
12 KiB
C

#include <stdlib.h>
#include <stdio.h>
#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;
}