Code:
//area
Area *initArea(){
Area *a;
a = malloc(sizeof(Area));
a->next = 0;
a->prev = 0;
a->top = a->bottom = a->left = a->right = 0;
a->handle = 0;
return a;
}
Area *addArea(Screen *s, AreaEdge *e1, AreaEdge *e2){
Area *a;
AreaEdge *top, *left, *bottom, *right;
if (!s) return 0;
if (!e1 || !e2) return 0;
if (e1->direction != e2->direction) return 0;
a = initArea();
LIST_append(s->area, a);
a->handle = (int)a;
if (e1->direction == GUI_HORIZONTAL){
if(e1->point1->y > e2->point1->y){
bottom = e1;
top = e2;
}
else{
bottom = e2;
top = e1;
}
if ( !(left = getAreaEdge(s, top->point1, bottom->point1)) )
left = addAreaEdge(s, top->point1, bottom->point1);
if ( !(right = getAreaEdge(s, top->point2, bottom->point2)) )
right = addAreaEdge(s, top->point2, bottom->point2);
}
else{
if(e1->point1->x > e2->point1->x){
right = e1;
left = e2;
}
else{
right = e2;
left = e1;
}
if ( !(top = getAreaEdge(s, left->point1, right->point1)) )
top = addAreaEdge(s, left->point1, right->point1);
if ( !(bottom = getAreaEdge(s, left->point2, right->point2)) )
bottom = addAreaEdge(s, left->point2, right->point2);
}
a->top = top;
top->area2 = a;
a->left = left;
left->area2 = a;
a->bottom = bottom;
bottom->area1 = a;
a->right = right;
right->area1 = a;
return a;
}
void removeArea(Screen *s, Area *a){
int index;
index = LIST_getElemIndex(s->area, a);
LIST_removeAt(s->area, index);
if (a == a->top->area2) a->top->area2 = 0;
if (a == a->bottom->area1) a->bottom->area1 = 0;
if (a == a->left->area2) a->left->area2 = 0;
if (a == a->right->area1) a->right->area1 = 0;
a->handle = 0;
freeArea(a);
}
void freeAreaList(List *l){
Area *a;
while(l->first){
a = LIST_removeLast(l);
freeArea(a);
}
}
void freeArea(Area *a){
free(a);
}
//areaEdge
AreaEdge *initAreaEdge(){
AreaEdge *ae;
ae = malloc(sizeof(AreaEdge));
ae->next = 0;
ae->prev = 0;
ae->point1 = 0;
ae->point2 = 0;
ae->area1 = 0;
ae->area2 = 0;
ae->direction = -1;
return ae;
}
AreaEdge *addAreaEdge(Screen *s, AreaPoint *p1, AreaPoint *p2){
AreaEdge *a;
int dir=0;
if (!s) return 0;
if (!p1 || !p2) return 0;
if ( (p2->x - p1->x) > 0.0001f ) dir |= 1;
if ( (p2->y - p1->y) > 0.0001f ) dir |= 2;
if (dir == 0 || dir == 3) return 0;
dir--;
a = initAreaEdge();
LIST_append(s->areaEdge, a);
a->point1 = p1;
a->point2 = p2;
a->direction = dir;
return a;
}
void removeAreaEdge(Screen *s, AreaEdge *ae){
int index;
if (ae->area1 || ae->area2) return;
index = LIST_getElemIndex(s->areaEdge, ae);
LIST_removeAt(s->areaEdge, index);
ae->point1 = 0;
ae->point2 = 0;
ae->direction = -1;
freeAreaEdge(ae);
}
void freeAreaEdgeList(List *l){
AreaEdge *ae;
while(l->first){
ae = LIST_removeLast(l);
freeAreaEdge(ae);
}
}
void freeAreaEdge(AreaEdge *ae){
free(ae);
}
AreaEdge *getAreaEdge(Screen *s, AreaPoint *p1, AreaPoint *p2){
AreaEdge *t;
t = s->areaEdge->first;
while(t){
if (t->point1 == p1 && t->point2 == p2){
return t;
}
else if (t->point1 == p2 && t->point2 == p1){
return t;
}
t = t->next;
}
return 0;
}
//areaPoint
AreaPoint *initAreaPoint(){
AreaPoint *ap;
ap = malloc(sizeof(AreaPoint));
ap->next = 0;
ap->prev = 0;
ap->x = 0;
ap->y = 0;
return ap;
}
AreaPoint *addAreaPoint(Screen *s, float x, float y){
AreaPoint *p;
if (!s) return 0;
p = initAreaPoint();
LIST_append(s->areaPoint, p);
p->x = x;
p->y = y;
return p;
}
void removeAreaPoint(Screen *s, AreaPoint *ap){
AreaEdge *t;
int index;
t = s->areaEdge->first;
while(t){
if (t->point1 == ap || t->point2 == ap) return;
t = t->next;
}
index = LIST_getElemIndex(s->areaPoint, ap);
LIST_removeAt(s->areaPoint, index);
ap->x = 0;
ap->y = 0;
freeAreaPoint(ap);
}
void freeAreaPointList(List *l){
AreaPoint *ae;
while(l->first){
ae = LIST_removeLast(l);
freeAreaPoint(ae);
}
}
void freeAreaPoint(AreaPoint *ap){
free(ap);
}
void addDefaultArea(Screen *s){
AreaPoint *p1, *p2, *p3, *p4;
AreaEdge *e1, *e2, *e3, *e4;
Area *a;
float x, y;
x = 0; y = 0;
p1 = addAreaPoint(s, x, y);
x = 1; y = 0;
p2 = addAreaPoint(s, x, y);
x = 1; y = 1;
p3 = addAreaPoint(s, x, y);
x = 0; y = 1;
p4 = addAreaPoint(s, x, y);
e1 = addAreaEdge(s, p1, p2);
e2 = addAreaEdge(s, p2, p3);
e3 = addAreaEdge(s, p4, p3);
e4 = addAreaEdge(s, p1, p4);
a = addArea(s, e1, e3);
}
void splitAreaWhere(AreaEdge *ae, int x, int y){
AreaPoint *lb, *rb, *ro, *lo, *newp1, *newp2;
AreaEdge *b, *o, *l, *r, *newe1, *newe2, *newe3, *newe4, *newe5;
Area *split = 0, *newa1, *newa2;
guiEvent *event = 0;
float fx, fy, where;
int dir, loop_done = 0;
//1 : omzetten naar relatieve coordinaten
fx = (float)x / (float)G->win->x;
fy = (float)y / (float)G->win->y;
dir = ae->direction;
//2 : berekenen welke area
if (dir == GUI_HORIZONTAL){
where = fx;
if (fy >= ae->point1->y) split = ae->area2;
else split = ae->area1;
}
else{
where = fy;
if (fx >= ae->point1->x) split = ae->area2;
else split = ae->area1;
}
printf("split : %d\n", split);
printf("ae : %d\n", ae);
lb = split->top->point1;
rb = split->top->point2;
ro = split->bottom->point2;
lo = split->bottom->point1;
b = split->top;
o = split->bottom;
l = split->left;
r = split->right;
//3 : de eigenlijke splitsing
if (dir == GUI_HORIZONTAL){
removeArea(G->curScreen, split);
removeAreaEdge(G->curScreen, b);
removeAreaEdge(G->curScreen, o);
newp1 = addAreaPoint(G->curScreen, where, l->point1->y);
newp2 = addAreaPoint(G->curScreen, where, l->point2->y);
newe1 = addAreaEdge(G->curScreen, lb, newp1);
newe2 = addAreaEdge(G->curScreen, newp1, rb);
newe3 = addAreaEdge(G->curScreen, lo, newp2);
newe4 = addAreaEdge(G->curScreen, newp2, ro);
newe5 = addAreaEdge(G->curScreen, newp1, newp2);
newa1 = addArea(G->curScreen, newe1, newe3);
newa2 = addArea(G->curScreen, newe2, newe4);
}
else{
removeArea(G->curScreen, split);
removeAreaEdge(G->curScreen, l);
removeAreaEdge(G->curScreen, r);
newp1 = addAreaPoint(G->curScreen, b->point1->x, where);
newp2 = addAreaPoint(G->curScreen, b->point2->x, where);
newe1 = addAreaEdge(G->curScreen, lb, newp1);
newe2 = addAreaEdge(G->curScreen, newp1, lo);
newe3 = addAreaEdge(G->curScreen, rb, newp2);
newe4 = addAreaEdge(G->curScreen, newp2, ro);
newe5 = addAreaEdge(G->curScreen, newp1, newp2);
newa1 = addArea(G->curScreen, newe1, newe3);
newa2 = addArea(G->curScreen, newe2, newe4);
}
/*//4 : in loop gaan tot key-up
while (!loop_done){
loop_done = 1;
}
//5 : aanpassen van vensterdata
//6 : update()*/
/*printf("areas :\n");
LIST_printList(G->curScreen->area);
printf("areaEdges :\n");
LIST_printList(G->curScreen->areaEdge);
printf("areaPoints :\n");
LIST_printList(G->curScreen->areaPoint);
printf("\n");*/
}
void joinAreas(AreaEdge *ae){
}
AreaEdge *onAreaEdge(int x, int y){
AreaEdge *a;
float fx, fy;
float t, b, l, r;
float offs = 0.01f;
fx = (float)x / (float)G->win->x;
fy = (float)y / (float)G->win->y;
a = G->curScreen->areaEdge->first;
while (a){
t = a->point1->y - offs;
b = a->point2->y + offs;
l = a->point1->x - offs;
r = a->point2->x + offs;
if (t<=fy && b>=fy && l<=fx && r>=fx) return a;
a = a->next;
}
return 0;
}
Now the error occurs when I have a similar situation as described here :