230 lines
6.8 KiB
C
230 lines
6.8 KiB
C
#include "elements.h"
|
|
#include <stddef.h> // NULL
|
|
#include <string.h> // memcpy
|
|
#include <stdlib.h> // malloc
|
|
|
|
/* ElementList alloc'ing and freeing */
|
|
struct ElementList *newElementList() {
|
|
struct ElementList *list = malloc(sizeof(struct ElementList));
|
|
list->first = NULL;
|
|
list->last = NULL;
|
|
list->user = NULL;
|
|
return list;
|
|
}
|
|
void freeElementList(struct ElementList *list) {
|
|
struct Element *current = list->first;
|
|
while (current != NULL) {
|
|
struct Element *next = current->next;
|
|
freeElement(current);
|
|
current = next;
|
|
}
|
|
free(list);
|
|
}
|
|
|
|
void addElementToList(struct ElementList *list, struct Element *element) {
|
|
if (list->first == NULL)
|
|
list->first = element;
|
|
if (list->last != NULL)
|
|
list->last->next = element;
|
|
element->prev = list->last;
|
|
list->last = element;
|
|
}
|
|
|
|
void freeElementsFromList(struct ElementList *list) {
|
|
struct Element *current = list->first;
|
|
while(current != NULL) {
|
|
struct Element *next = current->next;
|
|
removeElementFromList(list, current);
|
|
freeElement(current);
|
|
current = next;
|
|
}
|
|
}
|
|
|
|
void freeElementFromList(struct ElementList *list, struct Element *element) {
|
|
removeElementFromList(list, element);
|
|
freeElement(element);
|
|
}
|
|
|
|
void removeElementFromList(struct ElementList *list, struct Element *element) {
|
|
if (element == NULL) return;
|
|
if (list->first == element)
|
|
list->first = element->next;
|
|
if (list->last == element)
|
|
list->last = element->prev;
|
|
if (element->prev != NULL)
|
|
element->prev->next = element->next;
|
|
if (element->next != NULL)
|
|
element->next->prev = element->prev;
|
|
}
|
|
|
|
/* Element alloc and freeing */
|
|
struct Element *newElement(int type, int id, void (*function), const struct Dimension dimen) {
|
|
struct Element *element = malloc(sizeof(struct Element));
|
|
element->type = type;
|
|
element->id = id;
|
|
element->key = '\0';
|
|
element->key_pos = 0;
|
|
element->state = E_STATE_NORMAL;
|
|
memcpy(&element->dimen, &dimen, sizeof(struct Dimension));
|
|
|
|
switch (type) {
|
|
case E_TYPE_TEXT:
|
|
element->data = malloc(sizeof(struct TextElement));
|
|
((struct TextElement*)element->data)->length = 0;
|
|
((struct TextElement*)element->data)->string = malloc(1);
|
|
((struct TextElement*)element->data)->string[0] = '\0';
|
|
break;
|
|
case E_TYPE_BUTTON:
|
|
element->data = malloc(sizeof(struct ButtonElement));
|
|
((struct ButtonElement*)element->data)->length = 0;
|
|
((struct ButtonElement*)element->data)->string = malloc(1);
|
|
((struct ButtonElement*)element->data)->string[0] = '\0';
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
element->flags = E_FLAG_UPDATE;
|
|
|
|
element->next = NULL;
|
|
element->prev = NULL;
|
|
element->user = NULL;
|
|
element->self = NULL;
|
|
element->target = NULL;
|
|
element->font = NULL;
|
|
element->sx = 0.0f;
|
|
element->sy = 0.0f;
|
|
int i;
|
|
for(i=0;i < E_MAX_EVENTS;i++) {
|
|
element->onEvent[i] = NULL;
|
|
}
|
|
// call passed function if existing
|
|
if (function != NULL) {
|
|
element->onEvent[E_EVENT_NEW] = function;
|
|
element->onEvent[E_EVENT_NEW](element);
|
|
}
|
|
|
|
return element;
|
|
}
|
|
|
|
void freeElement(struct Element *element) {
|
|
if (element == NULL) return;
|
|
switch(element->type) {
|
|
case E_TYPE_BUTTON:
|
|
free(((struct TextElement*)element->data)->string);
|
|
break;
|
|
case E_TYPE_TEXT:
|
|
free(((struct TextElement*)element->data)->string);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
free(element->data);
|
|
free(element);
|
|
element = NULL;
|
|
}
|
|
|
|
/****
|
|
if the passed Element's type is E_TYPE_BUTTON or E_TYPE_TEXT, set either the TextElement or ButtonElemnt's string to the passed string, realloc'ing as needed. If passed string is NULL, the Text or Button's string is realloc'd to fit one char, which is set to '\0'.
|
|
****/
|
|
int setElementText(struct Element *element, const char *string) {
|
|
element->flags = E_FLAG_UPDATE;
|
|
if (string != NULL) {
|
|
int length = strlen(string);
|
|
switch(element->type) {
|
|
case E_TYPE_BUTTON:
|
|
((struct ButtonElement*)element->data)->string = realloc(((struct ButtonElement*)element->data)->string, length+1);
|
|
if (((struct ButtonElement*)element->data)->string == NULL)
|
|
return -2;
|
|
memcpy(((struct ButtonElement*)element->data)->string, string, length+1);
|
|
((struct ButtonElement*)element->data)->length = length;
|
|
break;
|
|
case E_TYPE_TEXT:
|
|
((struct TextElement*)element->data)->string = realloc(((struct TextElement*)element->data)->string, length+1);
|
|
if (((struct TextElement*)element->data)->string == NULL)
|
|
return -3;
|
|
memcpy(((struct TextElement*)element->data)->string, string, length+1);
|
|
((struct TextElement*)element->data)->length = length;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (element->onEvent[E_EVENT_CHANGE] != NULL)
|
|
element->onEvent[E_EVENT_CHANGE](element);
|
|
return 0;
|
|
} else {
|
|
switch(element->type) {
|
|
case E_TYPE_BUTTON:
|
|
((struct ButtonElement*)element->data)->string = realloc(((struct ButtonElement*)element->data)->string, 1);
|
|
if (((struct ButtonElement*)element->data)->string == NULL)
|
|
return -12;
|
|
((struct ButtonElement*)element->data)->string[0] = '\0';
|
|
((struct ButtonElement*)element->data)->length = 0;
|
|
break;
|
|
case E_TYPE_TEXT:
|
|
((struct TextElement*)element->data)->string = realloc(((struct TextElement*)element->data)->string, 1);
|
|
if (((struct TextElement*)element->data)->string == NULL)
|
|
return -13;
|
|
((struct TextElement*)element->data)->string[0] = '\0';
|
|
((struct TextElement*)element->data)->length = 0;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (element->onEvent[E_EVENT_CHANGE] != NULL)
|
|
element->onEvent[E_EVENT_CHANGE](element);
|
|
return 1;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int setElementValue(struct Element *element, int value) {
|
|
char value_string[128];
|
|
switch(element->type) {
|
|
case E_TYPE_TEXT:
|
|
itoa(value, value_string, 10);
|
|
setElementText(element, value_string);
|
|
return 0;
|
|
break;
|
|
default:
|
|
return -2;
|
|
break;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int setElementFont(struct Element *element, void *font) {
|
|
element->font = font;
|
|
if (element->onEvent[E_EVENT_CHANGE] != NULL)
|
|
element->onEvent[E_EVENT_CHANGE](element);
|
|
return 0;
|
|
}
|
|
|
|
int setElementEvent(struct Element *element, int event_id, void *event_function) {
|
|
if (event_id < 0 || event_id > E_MAX_EVENTS)
|
|
return 1;
|
|
element->onEvent[event_id] = event_function;
|
|
return 0;
|
|
}
|
|
|
|
int setElementKey(struct Element *element, int key, int key_pos) {
|
|
element->key = key;
|
|
element->key_pos = key_pos;
|
|
return 0;
|
|
}
|
|
|
|
char *getElementText(struct Element *element) {
|
|
switch(element->type) {
|
|
case E_TYPE_BUTTON:
|
|
return ((struct ButtonElement*)element->data)->string;
|
|
break;
|
|
case E_TYPE_TEXT:
|
|
return ((struct TextElement*)element->data)->string;
|
|
break;
|
|
default:
|
|
return NULL;
|
|
break;
|
|
}
|
|
return NULL;
|
|
}
|