14
#include "sexpr/sexp.h"
19
#define IS_HEAPED(obj) (obj->magic == MAGIC_HEAPED)
20
#define SET_HEAPED(obj) obj->magic = MAGIC_HEAPED
23
typedef oesui_propnode_t asset_t;
28
assetcache_t assetcache1;
32
int oesui_widget_paint (oesui_t *, oesui_widget_t *);
33
int oesui_widget_update (oesui_t *, oesui_widget_t *);
34
int oesui_widget_signal (oesui_t *, oesui_widget_t *, oesui_signal_t *);
35
int oesui_widget_open (oesui_t *, oesui_widget_t *);
36
int oesui_widget_close (oesui_t *, oesui_widget_t *);
42
hashify (const char *s)
49
/**********************
50
* Asset cache manager *
51
**********************/
54
assetcache_init (assetcache_t *self)
58
self = (assetcache_t*)calloc(1, sizeof(*self));
59
if (!self) return NULL;
64
self->cache = (asset_t*)calloc(self->alloc, sizeof(asset_t));
70
assetcache_delete (assetcache_t *self)
72
if (self->cache) free(self->cache);
82
assetcache_get (assetcache_t *self, const char *key)
86
targhash = hashify(key);
87
for (i = 1; i < self->len; i++)
89
if (self->cache[i].hash != targhash) continue; /* can't possibly match. */
90
if (strcmp(self->cache[i].key, key)) continue; /* not exact match. */
91
return self->cache[i].val.p;
98
assetcache_idx (assetcache_t *self, int idx)
100
if (idx < 0) return NULL;
101
if (idx > self->len) return NULL;
102
return self->cache[idx].val.p;
107
assetcache_register (assetcache_t *self, const char *key, void *obj)
110
self = assetcache_init(NULL);
111
if (assetcache_get(self, key)) /* Already registered. */
113
if (self->len > self->alloc)
116
self->cache = (asset_t*)realloc(self->cache, self->alloc * sizeof(asset_t));
118
self->cache[self->len].key = strdup(key);
119
self->cache[self->len].hash = hashify(key);
120
self->cache[self->len].valtype = OESATOM_PTR; //20
121
self->cache[self->len].val.p = obj;
127
/* special-case asset-manager wrapper */
129
imgasset_register (const char *name)
135
if (!(obj = assetcache_get(&assetcache1, name)))
137
//printf("caching image '%s'\n", name);
138
if ((img = oes_load_img(name)))
140
assetcache1.cache[assetcache1.len].hash = hashify(name);
141
assetcache1.cache[assetcache1.len].key = strdup(name);
142
assetcache1.cache[assetcache1.len].valtype = OESATOM_PTR; //20;
143
assetcache1.cache[assetcache1.len].val.p = img;
149
//printf("Image '%s' already cached\n", name);
150
img = (SDL_Surface*)obj;
159
/**********************
160
* Properties... list? *
161
**********************/
164
oesui_propnode_init (oesui_propnode_t *self, const char *key)
169
self = (oesui_propnode_t*)calloc(1, sizeof(*self));
170
if (!self) return NULL;
173
self->hash = hashify(key);
174
// self->key = strdup(key);
181
self->key = (char*)malloc(n);
182
strcpy(self->key, key);
187
oesui_propnode_delete (oesui_propnode_t *self)
194
switch (self->valtype)
203
self->val.sym = NULL;
221
oesui_props_init (oesui_props_t *self)
225
self = (oesui_props_t*)calloc(1, sizeof(oesui_props_t));
226
if (!self) return NULL;
229
// memset(self, 0, sizeof(*self));
237
oesui_props_delete (oesui_props_t *self)
239
llist_t *iter, *next;
241
for (iter = self->list; iter; iter = iter->next)
244
oesui_propnode_delete((oesui_propnode_t*)(iter->data));
254
oesui_props_get (oesui_props_t *self, const char *key)
256
oesui_propnode_t *temp;
260
if (!self) return NULL;
261
targhash = hashify(key);
262
for (iter = self->list; iter; iter = iter->next)
264
temp = (oesui_propnode_t*)(iter->data);
265
if (targhash != temp->hash)
266
continue; /* can't possibly match */
267
if (strcasecmp(temp->key, key))
268
continue; /* not exact match */
276
oesui_props_append (oesui_props_t *self, oesui_propnode_t *node)
279
self = (oesui_props_t*)calloc(1, sizeof(*self));
282
self->list = (llist_t*)malloc(sizeof(llist_t));
283
self->list->data = node;
284
self->list->next = NULL;
285
self->tail = self->list;
289
self->tail->next = (llist_t*)malloc(sizeof(llist_t));
290
self->tail->next->data = node;
291
self->tail->next->next = NULL;
292
self->tail = self->tail->next;
299
oesui_props_set_int (oesui_props_t *self, const char *key, int val)
301
oesui_propnode_t *node;
303
node = oesui_props_get(self, key);
306
node = oesui_propnode_init(NULL, key);
307
if (!node) return NULL;
308
self = oesui_props_append (self, node);
310
node->valtype = OESATOM_INT;
317
oesui_props_set_float (oesui_props_t *self, const char *key, float val)
319
oesui_propnode_t *node;
321
node = oesui_props_get(self, key);
324
node = oesui_propnode_init(NULL, key);
325
if (!node) return NULL;
326
self = oesui_props_append (self, node);
328
node->valtype = OESATOM_FLOAT;
335
oesui_props_set_symbol (oesui_props_t *self, const char *key, const char *val)
337
oesui_propnode_t *node;
339
node = oesui_props_get(self, key);
342
node = oesui_propnode_init(NULL, key);
343
if (!node) return NULL;
344
self = oesui_props_append (self, node);
346
node->valtype = OESATOM_SYMBOL;
353
oesui_props_set_string (oesui_props_t *self, const char *key, char *val)
355
oesui_propnode_t *node;
357
node = oesui_props_get(self, key);
360
node = oesui_propnode_init(NULL, key);
361
if (!node) return NULL;
362
self = oesui_props_append (self, node);
364
node->valtype = OESATOM_STRING;
371
oesui_props_set_ptr (oesui_props_t *self, const char *key, void *val)
373
oesui_propnode_t *node;
375
node = oesui_props_get(self, key);
378
node = oesui_propnode_init(NULL, key);
379
if (!node) return NULL;
380
self = oesui_props_append (self, node);
382
node->valtype = OESATOM_PTR;
389
oesui_props_get_int (oesui_props_t *self, const char *key)
391
oesui_propnode_t *node;
393
node = oesui_props_get(self, key);
395
switch (node->valtype)
397
case OESATOM_INT: return node->val.i; break;
398
case OESATOM_FLOAT: return (int)(node->val.f); break;
399
case OESATOM_SYMBOL: /* fallthrough */
400
case OESATOM_STRING: return strtol(node->val.s, NULL, 0); break;
401
case OESATOM_PTR: return 0; break;
408
oesui_props_get_float (oesui_props_t *self, const char *key)
410
oesui_propnode_t *node;
412
node = oesui_props_get(self, key);
414
switch (node->valtype)
416
case OESATOM_INT: return (float)(node->val.i); break;
417
case OESATOM_FLOAT: return node->val.f; break;
418
case OESATOM_SYMBOL: /* fallthrough */
419
case OESATOM_STRING: return atof(node->val.s); break;
420
case OESATOM_PTR: return 0; break;
427
oesui_props_get_symbol (oesui_props_t *self, const char *key)
429
oesui_propnode_t *node;
432
node = oesui_props_get(self, key);
434
switch (node->valtype)
437
snprintf(buf, sizeof(buf), "%d", node->val.i); return buf; break;
439
snprintf(buf, sizeof(buf), "%f", node->val.f); return buf; break;
440
case OESATOM_SYMBOL: return node->val.sym; break;
441
case OESATOM_STRING: return node->val.s; break;
442
case OESATOM_PTR: return 0; break;
449
oesui_props_get_string (oesui_props_t *self, const char *key)
451
oesui_propnode_t *node;
452
// static char buf[72];
453
static char buf[1024];
455
node = oesui_props_get(self, key);
457
switch (node->valtype)
460
snprintf(buf, sizeof(buf), "%d", node->val.i); return buf; break;
462
snprintf(buf, sizeof(buf), "%f", node->val.f); return buf; break;
464
snprintf(buf, sizeof(buf), "%s", node->val.sym); return buf; break;
465
case OESATOM_STRING: return node->val.s; break;
466
case OESATOM_PTR: return 0; break;
473
oesui_props_get_ptr (oesui_props_t *self, const char *key)
475
oesui_propnode_t *node;
477
node = oesui_props_get(self, key);
479
switch (node->valtype)
481
case OESATOM_INT: return 0; break;
482
case OESATOM_FLOAT: return 0; break;
483
case OESATOM_SYMBOL: /* fallthrough */
484
case OESATOM_STRING: return (void*)(node->val.s); break;
485
case OESATOM_PTR: return node->val.p; break;
500
oesui_signal_init (oesui_signal_t *self, int len)
508
chunksize = sizeof(*self) + (len * sizeof(oesui_atom_t));
509
self = (oesui_signal_t*)calloc(1, chunksize);
510
if (!self) return NULL;
519
oesui_signal_delete (oesui_signal_t *self)
521
free(UISIG_NAME(self));
536
oesui_signals_init (oesui_widget_t *self)
540
self = (oesui_widget_t*)calloc(1, sizeof(*self));
541
if (!self) return NULL;
544
// memset(self, 0, sizeof(*self));
545
// self->props = oesui_props_set_ptr(self->props, " queue ", 0); /* pending signals */
550
/* Connect widget to signal. */
552
oesui_signals_connect (oesui_widget_t *self, const char *signal, int ofs, oesui_widget_t *widget)
554
llist_t *chain, *temp, *curr;
556
chain = (llist_t*)oesui_props_get_ptr(self->props, signal);
559
if (ofs < 0) ofs = INT_MAX;
560
temp = (llist_t*)calloc(1, sizeof(*temp));
571
while (curr->next && (ofs-- > 1))
573
temp->next = curr->next;
579
chain = (llist_t*)calloc(1, sizeof(*chain));
580
chain->data = widget;
583
self->props = oesui_props_set_ptr(self->props, signal, chain);
590
oesui_signals_raise (oesui_widget_t *self, int len, const char *signal, ...)
592
llist_t *chain, *curr, *temp = NULL;
598
signame = strdup(signal);
599
chain = (llist_t*)oesui_props_get_ptr(self->props, " queue ");
601
if (!(sig = oesui_signal_init(NULL, len)))
603
if (temp) free(temp);
606
UISIG_NAME(sig) = signame;
607
va_start(vp, signal);
608
for (i = 1; i < len; i++)
611
UISIG_ARG(sig, 1).i = n;
617
//printf("appending signal '%s' (%08X)\n", signame, signame);
621
temp = (llist_t*)calloc(1, sizeof(*temp));
623
// temp->data = signame;
625
temp->next = curr->next;
630
//printf("inserting signal '%s' (%08X)\n", signame, signame);
631
chain = (llist_t*)calloc(1, sizeof(*chain));
632
// chain->data = signame;
636
self->props = oesui_props_set_ptr(self->props, " queue ", chain);
641
/* propagate signals. */
643
oesui_signals_cycle (oesui_t *gui, oesui_widget_t *signals)
646
llist_t *queue, *nque, *chain;
647
oesui_widget_t *widget;
651
//printf("signals_cycle...\n");
652
queue = (llist_t*)oesui_props_get_ptr(signals->props, " queue ");
653
//printf("queue => %08X\n", queue);
654
if (!queue) return 0;
656
signals->props = oesui_props_set_ptr(signals->props, " queue ", nque);
657
//printf("next in queue = %08X\n", nque);
658
// signame = (char*)(queue->data);
659
sig = (oesui_signal_t*)(queue->data);
660
signame = UISIG_NAME(sig);
661
//printf("signame => (%08X) %s\n", signame, signame);
662
if (!signame) return 0;
664
//printf("Propagating signal '%s'\n", signame);
665
chain = (llist_t*)oesui_props_get_ptr(signals->props, signame);
667
for(; chain; chain = chain->next)
669
widget = (oesui_widget_t*)(chain->data);
670
if (oesui_props_get_int(widget->props, "enabled"))
671
n = oesui_widget_signal(gui, widget, sig);
672
if (n) break; //return 1;
675
/* unblocked signal. */
678
//printf("unblocked signal '%s'\n", signame);
679
n = gui->sighandler(gui, sig);
683
oesui_signal_delete(sig);
684
free(queue); /* Next-in-queue already saved to property */
692
/***********************************
693
* Translation of data into widgets *
694
***********************************/
698
sexp_to_widgetlist (oesui_t *gui, sexp_t *descrlist)
700
llist_t *wlist, *tail = NULL;
701
oesui_widget_t *widget;
705
//print_sexp(buf, sizeof(buf), descrlist);
706
//printf("descrlist = %s\n", buf);
708
for (; descrlist; descrlist = descrlist->next)
710
descr = descrlist->list;
711
widget = sexp_to_widget(gui, descr);
712
// wlist = llist_add(wlist, widget);
715
wlist = (llist_t*)calloc(1, sizeof(*wlist));
717
wlist->data = widget;
722
tail->next = (llist_t*)calloc(1, sizeof(*wlist));
723
tail->next->data = widget;
724
tail->next->next = NULL;
733
sexp_to_widget (oesui_t *gui, sexp_t *descrlist)
735
sexp_t *alist, *pair;
737
oesui_widget_t *widget;
738
const char *key, *val;
741
//print_sexp(buf, sizeof(buf), descrlist);
742
//printf("widgetlist = %s\n", buf);
743
widget = (oesui_widget_t*)calloc(1, sizeof(*widget));
744
widget->props = oesui_props_set_int(widget->props, "enabled", 0);
747
//print_sexp(buf, sizeof(buf), alist);
748
//printf("alist = %s\n", buf);
749
if ((descrlist->ty == SEXP_LIST) && (descrlist->next == NULL))
750
alist = descrlist->list;
751
for (; alist; alist = alist->next)
753
//print_sexp(buf, sizeof(buf), alist);
754
//printf("attrib pair = %s\n", buf);
755
if (alist->ty != SEXP_LIST) continue;
759
else if (0 == strcasecmp(key, "connect"))
763
for (sigs = pair->next; sigs; sigs = sigs->next)
766
//printf("will connect to signal '%s'\n", val);
767
oesui_signals_connect(gui->signals, val, -1, widget);
769
// widget->props = oesui_props_set_ptr(widget->props, "connect", sigs);
771
else if (0 == strcasecmp(key, "container"))
773
//printf("container...\n");
774
wlist = sexp_to_widgetlist(gui, pair->next);
775
widget->props = oesui_props_set_ptr(widget->props, key, wlist);
779
/* normal key/value pair */
782
val = pair->next->val;
783
//printf("attrib %s = %s || widget->props = %08X\n", key, val, widget->props);
784
widget->props = oesui_props_set_string(widget->props, key, strdup(val));
787
//printf("proplist dump:\n");
789
oesui_propnode_t *prop;
790
for (wlist = widget->props->list; wlist; wlist = wlist->next)
792
prop = (oesui_propnode_t*)(wlist->data);
793
printf(" key = %s => %s\n", prop->key, prop->valtype == OESATOM_STRING ? prop->val.s : "-");
796
//printf("/done => %08X.%08X\n", widget, widget->props);
804
/*************************
805
* um... support/utility? *
806
*************************/
810
oesui_pointed (oesui_t *gui, oesui_widget_t *widget)
812
int x0, x1, y0, y1; /* boundary check */
813
int px, py; /* pointer location */
815
x0 = oesui_props_get_int(widget->props, "x");
816
x1 = x0 + oesui_props_get_int(widget->props, "w");
817
y0 = oesui_props_get_int(widget->props, "y");
818
y1 = y0 + oesui_props_get_int(widget->props, "h");
821
//printf("has_focus: X=%d|%d|%d Y=%d|%d|%d\n", x0, px, x1, y0, py, y1);
822
if ((x0 < px) && (px < x1) && (y0 < py) && (py < y1))
837
oesui_ownerdraw_paint (oesui_t *gui, oesui_widget_t *widget)
840
const char *objtype = 0;
841
int rendertime, loadtime;
843
objtype = oesui_props_get_string(widget->props, "tag");
844
if (!objtype) return 0;
845
rendertime = oesui_props_get_int(widget->props, "rendertime");
846
loadtime = oesui_props_get_int(gui->toplevel->props, "loadtime");
847
if ((loadtime) && (rendertime >= loadtime))
849
//printf("Drawing ownertype '%s' (load @ %d, lastrender @ %d)\n", objtype, loadtime, rendertime);
850
r.x = r.y = r.w = r.h = 0;
851
oesui_signals_raise(gui->signals, 5, objtype, r.x, r.y, r.w, r.h);
852
rendertime = SDL_GetTicks();
853
widget->props = oesui_props_set_int(widget->props, "rendertime", rendertime);
867
oesui_label_paint (oesui_t *gui, oesui_widget_t *widget)
869
oesui_propnode_t *prop;
874
prop = oesui_props_get(widget->props, "text");
877
switch (prop->valtype)
880
snprintf(text, sizeof(text), "%d", prop->val.i);
883
snprintf(text, sizeof(text), "%f", prop->val.f);
886
snprintf(text, sizeof(text), "%s", prop->val.sym);
889
snprintf(text, sizeof(text), "%s", prop->val.s);
895
br.x = oesui_props_get_int(widget->props, "x");
896
br.y = oesui_props_get_int(widget->props, "y");
897
br.w = oesui_props_get_int(widget->props, "w");
898
br.h = oesui_props_get_int(widget->props, "h");
899
col = oesui_props_get_int(widget->props, "color");
901
print(br.x, br.y, col, text);
916
oesui_image_paint (oesui_t *gui, oesui_widget_t *widget)
918
oesui_propnode_t *prop;
919
SDL_Surface *img = 0;
922
prop = oesui_props_get(widget->props, "image");
924
switch (prop->valtype)
927
img = (SDL_Surface*)assetcache_idx(&assetcache1, prop->val.i);
930
img = imgasset_register(prop->val.sym);
933
img = imgasset_register(prop->val.s);
936
img = (SDL_Surface*)(prop->val.p);
940
widget->props = oesui_props_set_ptr(widget->props, "image", img);
942
br.x = oesui_props_get_int(widget->props, "x");
943
br.y = oesui_props_get_int(widget->props, "y");
944
br.w = oesui_props_get_int(widget->props, "w");
945
br.h = oesui_props_get_int(widget->props, "h");
950
widget->props = oesui_props_set_int(widget->props, "w", img->w);
955
widget->props = oesui_props_set_int(widget->props, "h", img->h);
958
SDL_BlitSurface(img, NULL, gui->screen, &br);
965
oesui_image_update (oesui_t *gui, oesui_widget_t *widget)
967
//const char *objname;
969
// objname = oesui_props_get_string(widget->props, "name");
970
// if (!objname) return 0;
985
oesui_button_paint (oesui_t *gui, oesui_widget_t *widget)
987
SDL_Rect br = { 0, };
988
SDL_Surface *img = 0;
990
const char *field = 0;
991
//const char *imgname = 0;
993
oesui_propnode_t *prop;
995
// img = gButton.fullscreen;
996
// img = (SDL_Surface*)imgobj;
997
// imgobj = oesui_props_get_ptr(widget->props, field);
998
// imgname = oesui_props_get_string(widget->props, field);
999
focus = oesui_pointed(gui, widget);
1000
field = focus ? "himage" : "image";
1001
prop = oesui_props_get(widget->props, field);
1002
if (!prop) return 0;
1003
switch (prop->valtype)
1006
img = (SDL_Surface*)assetcache_idx(&assetcache1, prop->val.i);
1008
case OESATOM_SYMBOL:
1009
img = imgasset_register(prop->val.sym);
1011
case OESATOM_STRING:
1012
img = imgasset_register(prop->val.s);
1015
img = (SDL_Surface*)(prop->val.p);
1019
widget->props = oesui_props_set_ptr(widget->props, field, img);
1021
br.x = oesui_props_get_int(widget->props, "x");
1022
br.y = oesui_props_get_int(widget->props, "y");
1023
br.w = oesui_props_get_int(widget->props, "w");
1024
br.h = oesui_props_get_int(widget->props, "h");
1029
widget->props = oesui_props_set_int(widget->props, "w", img->w);
1034
widget->props = oesui_props_set_int(widget->props, "h", img->h);
1037
//printf("button at (%d, %d), %d x %d\n", br.x, br.y, br.w, br.h);
1039
SDL_BlitSurface(img, NULL, gui->screen, &br);
1046
oesui_button_update (oesui_t *gui, oesui_widget_t *widget)
1049
SDL_Surface *img = 0, *himg = 0;
1050
const char *imgname = 0, *himgname = 0;
1052
//printf("Button Update\n");
1053
bname = oesui_props_get_string(widget->props, "name");
1054
if (!bname) return 0;
1056
else if (0 == strcmp(bname, "Fullscreen"))
1058
imgname = gPrefs.fullscreen ? "fullscreen.png" : "window.png";
1059
himgname = gPrefs.fullscreen ? "fullscreenh.png" : "windowh.png";
1061
else if (0 == strcmp(bname, "Audio"))
1063
imgname = gPrefs.audio ? "audioon.png" : "audiooff.png";
1064
himgname = gPrefs.audio ? "audioonh.png" : "audiooffh.png";
1065
//printf("Audio button should currently show: %d\n", gPrefs.audio);
1067
else if (0 == strcmp(bname, "Difficulty"))
1069
switch (gPrefs.difficulty)
1071
case 1: imgname = "easy.png"; himgname = "easyh.png"; break;
1072
case 2: imgname = "medium.png"; himgname = "mediumh.png"; break;
1073
case 3: default: imgname = "hard.png"; himgname = "hardh.png"; break;
1076
else if (0 == strcmp(bname, "Quit"))
1080
if (imgname) img = imgasset_register(imgname);
1081
if (himgname) himg = imgasset_register(himgname);
1082
if (img) widget->props = oesui_props_set_ptr(widget->props, "image", img);
1083
if (himg) widget->props = oesui_props_set_ptr(widget->props, "himage", himg);
1084
// if (0 == oesui_props_get_int(widget->props, "w"))
1085
// widget->props = oesui_props_set_int(widget->props, "w", img->w);
1086
// if (0 == oesui_props_get_int(widget->props, "h"))
1087
// widget->props = oesui_props_set_int(widget->props, "h", img->h);
1094
oesui_button_signal (oesui_t *gui, oesui_widget_t *widget, oesui_signal_t *sig)
1100
else if (0 == strcmp(UISIG_NAME(sig), "click"))
1102
//printf("button signal CLICK\n");
1103
if (!(oesui_pointed(gui, widget)))
1105
spit = oesui_props_get_string(widget->props, "on-click");
1106
if (!spit) return 0;
1107
// oesui_signals_raise(gui->signals, spit);
1108
oesui_signals_raise(gui->signals, 1, spit);
1110
else if (0 == strcmp(UISIG_NAME(sig), "focus"))
1112
focus = oesui_props_get_int(widget->props, "focus");
1113
if (oesui_pointed(gui, widget))
1118
/* just came into focus. */
1126
/* just lost focus. */
1143
oesui_toplevel_paint (oesui_t *gui, oesui_widget_t *widget)
1146
oesui_widget_t *child;
1148
container = (llist_t*)oesui_props_get_ptr(widget->props, "container");
1149
if (!container) return 0;
1150
for (; container; container = container->next)
1152
child = (oesui_widget_t*)(container->data);
1153
oesui_widget_paint(gui, child);
1160
oesui_toplevel_update (oesui_t *gui, oesui_widget_t *widget)
1163
oesui_widget_t *child;
1165
if (!widget) return 0;
1166
container = (llist_t*)oesui_props_get_ptr(widget->props, "container");
1167
for (; container; container = container->next)
1169
child = (oesui_widget_t*)(container->data);
1170
oesui_widget_update(gui, child);
1177
oesui_toplevel_signal (oesui_t *gui, oesui_widget_t *widget, oesui_signal_t *sig)
1182
else if (0 == strcmp(UISIG_NAME(sig), "esc"))
1184
emit = oesui_props_get_string(widget->props, "on-esc");
1185
if (!emit) return 0;
1186
//printf("Toplevel got signal '%s', will emit '%s'\n", sig->data[0].s, emit);
1187
// oesui_signals_raise(gui->signals, emit);
1188
oesui_signals_raise(gui->signals, 1, emit);
1190
else if (0 == strcmp(UISIG_NAME(sig), "cycle-focus"))
1199
oesui_toplevel_open (oesui_t *gui, oesui_widget_t *widget)
1202
oesui_widget_t *child;
1205
loadtime = SDL_GetTicks();
1206
//printf("LOADED MENU '%s' at %d\n", menuname, loadtime);
1207
widget->props = oesui_props_set_int(widget->props, "loadtime", loadtime);
1208
widget->props = oesui_props_set_int(widget->props, "enabled", 1);
1210
container = (llist_t*)oesui_props_get_ptr(widget->props, "container");
1211
if (!container) return 0;
1212
for (; container; container = container->next)
1214
child = (oesui_widget_t*)(container->data);
1215
child->props = oesui_props_set_int(child->props, "enabled", 1);
1217
oesui_widget_update(gui, widget);
1223
oesui_toplevel_close (oesui_t *gui, oesui_widget_t *widget)
1226
oesui_widget_t *child;
1228
oesui_widget_update(gui, widget);
1229
container = (llist_t*)oesui_props_get_ptr(widget->props, "container");
1230
widget->props = oesui_props_set_int(widget->props, "enabled", 0);
1231
if (!container) return 0;
1232
for (; container; container = container->next)
1234
child = (oesui_widget_t*)(container->data);
1235
child->props = oesui_props_set_int(child->props, "enabled", 0);
1244
/*********************************/
1245
/* Generalized widget functions. */
1246
/*********************************/
1250
oesui_widget_paint (oesui_t *gui, oesui_widget_t *widget)
1252
const char *objtype;
1253
int (*paintfunc)(oesui_t *, oesui_widget_t*);
1255
objtype = oesui_props_get_string(widget->props, "type");
1256
if (!objtype) return 0;
1257
//printf("painting objtype '%s'\n", objtype);
1259
if (0 == strcasecmp(objtype, "toplevel"))
1260
paintfunc = oesui_toplevel_paint;
1261
else if (0 == strcasecmp(objtype, "button"))
1262
paintfunc = oesui_button_paint;
1263
else if (0 == strcasecmp(objtype, "image"))
1264
paintfunc = oesui_image_paint;
1265
else if (0 == strcasecmp(objtype, "ownerdraw"))
1266
paintfunc = oesui_ownerdraw_paint;
1267
else if (0 == strcasecmp(objtype, "label"))
1268
paintfunc = oesui_label_paint;
1270
return paintfunc(gui, widget);
1276
oesui_widget_update (oesui_t *gui, oesui_widget_t *widget)
1278
const char *objtype;
1279
int (*updatefunc)(oesui_t *, oesui_widget_t *) = NULL;
1281
if (!widget) return 0;
1282
objtype = oesui_props_get_string(widget->props, "type");
1283
if (!objtype) return 0;
1284
if (0 == strcasecmp(objtype, "toplevel"))
1285
updatefunc = oesui_toplevel_update;
1286
else if (0 == strcasecmp(objtype, "button"))
1287
updatefunc = oesui_button_update;
1289
return updatefunc(gui, widget);
1295
oesui_widget_signal (oesui_t *gui, oesui_widget_t *widget, oesui_signal_t *sig)
1297
const char *objtype;
1298
int (*sigfunc)(oesui_t*, oesui_widget_t*, oesui_signal_t *) = NULL;
1300
objtype = oesui_props_get_string(widget->props, "type");
1301
//printf("widget_signal on %s\n", objtype);
1302
if (!objtype) return 0;
1304
else if (0 == strcasecmp(objtype, "toplevel"))
1305
sigfunc = oesui_toplevel_signal;
1306
else if (0 == strcasecmp(objtype, "button"))
1307
sigfunc = oesui_button_signal;
1309
return sigfunc(gui, widget, sig);
1315
oesui_widget_open (oesui_t *gui, oesui_widget_t *widget)
1317
const char *objtype;
1318
int (*openfunc)(oesui_t *, oesui_widget_t *) = NULL;
1320
objtype = oesui_props_get_string(widget->props, "type");
1321
if (!objtype) return 0;
1323
else if (0 == strcasecmp(objtype, "toplevel"))
1324
openfunc = oesui_toplevel_open;
1326
return openfunc(gui, widget);
1332
oesui_widget_close (oesui_t *gui, oesui_widget_t *widget)
1334
const char *objtype;
1335
int (*closefunc)(oesui_t *, oesui_widget_t *) = NULL;
1337
objtype = oesui_props_get_string(widget->props, "type");
1338
if (!objtype) return 0;
1340
else if (0 == strcasecmp(objtype, "toplevel"))
1341
closefunc = oesui_toplevel_close;
1343
return closefunc(gui, widget);
1356
/* Inject event into UI system. */
1358
oesui_event (oesui_t *self, int evtype, int parm)
1360
const char *objtype;
1362
objtype = oesui_props_get_string(self->toplevel->props, "type");
1363
//printf("toplevel objtype (%08X) = %s\n", self->toplevel, objtype);
1368
oesui_widget_update(self, self->toplevel);
1371
oesui_widget_paint(self, self->toplevel);
1378
if (self->px > self->screen->w)
1379
self->px = self->screen->w;
1382
//printf("Pointer @ (%d, %d)\n", self->px, self->py);
1389
if (self->py > self->screen->h)
1390
self->py = self->screen->h;
1393
//printf("Pointer @ (%d, %d)\n", self->px, self->py);
1396
oesui_widget_open(self, self->toplevel);
1399
oesui_widget_close(self, self->toplevel);
1405
// oesui_signals_raise(self->signals, "esc");
1406
oesui_signals_raise(self->signals, 1, "esc");
1409
// oesui_signals_raise(self->signals, "cycle-focus");
1410
oesui_signals_raise(self->signals, 1, "cycle-focus");
1415
// return oesui_toplevel_click(self, self->toplevel, parm);
1417
// return oesui_signals_raise(self->signals, "click");
1418
return oesui_signals_raise(self->signals, 3, "click", self->px, self->py);
1426
/* Load assets specified in data file */
1428
oesui_cache_assets (oesui_t *self, sexp_t *se)
1431
const char *objtype;
1435
for (; se; se = se->next)
1438
objtype = pair->val;
1440
else if (0 == strcasecmp(objtype, "img"))
1442
objname = pair->next->val;
1443
//printf("caching asset (img) '%s'\n", objname);
1444
// img = oes_load_img(objname);
1445
// assetcache_register(&assetcache1, objname, img);
1446
imgasset_register(objname);
1453
/* Select toplevel to display */
1455
oesui_open (oesui_t *self, const char *tlname)
1458
// loadtime = SDL_GetTicks();
1459
// self->toplevel->props = oesui_props_set_int(self->toplevel->props, "loadtime", loadtime);
1462
oesui_toplevel_close(self, self->toplevel);
1463
self->toplevel = (oesui_widget_t*)assetcache_get(&assetcache1, tlname);
1464
oesui_toplevel_open(self, self->toplevel);
1465
//printf("LOADED MENU '%s' at %d\n", tlname, oesui_props_get_int(self->toplevel->props, "loadtime"));
1470
/* Load UI info from file. */
1472
oesui_load (oesui_t *self, const char *fname)
1477
const char *objtype;
1478
oesui_widget_t *widget;
1479
char * menuname = "menus.cfg";
1482
menupath=(char*)calloc(1,strlen(GAMEDATADIR)+1+strlen(menuname)+1);
1483
sprintf(menupath,"%s/%s",GAMEDATADIR,menuname);
1484
if (!(guifile = fopen(menupath, "r"))) {
1485
fprintf(stderr,"Cannot load menu '%s'\n",menupath);
1491
io = init_iowrap(fileno(guifile));
1492
// self->toplevel = read_one_sexp(io);
1493
while ((se = read_one_sexp(io)))
1495
if (se->ty == SEXP_LIST)
1497
if (hd_sexp(se)->ty == SEXP_VALUE)
1499
objtype = se->list->val;
1501
else if (0 == strcasecmp(objtype, "assets"))
1502
oesui_cache_assets(self, se->list->next);
1506
/* toplevel description. */
1507
widget = sexp_to_widget(self, se);
1508
objtype = oesui_props_get_string(widget->props, "name");
1509
//printf("done widget '%s'\n", objtype);
1510
assetcache_register(&assetcache1, objtype, widget);
1511
oesui_widget_update(self, widget);
1514
// self->toplevel = sexp_to_widget(se);
1515
// oesui_widget_update (self, self->toplevel);
1518
//printf("retrieving 'main'...\n");
1519
// self->toplevel = (oesui_widget_t*)assetcache_get(&assetcache1, "main");
1520
// self->toplevel = (oesui_widget_t*)assetcache_get(&assetcache1, "prefs");
1521
//printf("gui->toplevel = %08X\n", self->toplevel);
1522
// oesui_widget_update(self, self->toplevel);
1530
oesui_init (oesui_t *self)
1534
self = (oesui_t*)calloc(1, sizeof(oesui_t));
1535
if (!self) return NULL;
1538
// memset(self, 0, sizeof(*self));
1540
self->screen = NULL;
1541
self->toplevel = NULL;
1542
self->sighandler = NULL;
1546
// self->w = self->screen->w; /* redundant? */
1547
// self->h = self->screen->h;
1548
self->px = self->w / 2;
1549
self->py = self->h / 2;
1551
self->signals = oesui_signals_init(self->signals);
1553
assetcache_init(&assetcache1);
1558
/* Initialize with screen. */
1560
oesui_init_surface (oesui_t *self, SDL_Surface *sdlscreen)
1562
if ((self = oesui_init(self)))
1564
self->screen = sdlscreen;
1565
self->w = self->screen->w; /* redundant? */
1566
self->h = self->screen->h;
1573
oesui_delete (oesui_t *self)
1575
// destroy_sexp(gui->toplevel);
1576
if (IS_HEAPED(self))
1583
oesui_loop (oesui_t *self)
1586
int px, py; /* pointer (mouse) location. */
1591
while (!self->retcode)
1593
ticks = SDL_GetTicks();
1594
if (ticks > lastdraw + 20)
1596
oesui_event(self, OESUI_REFRESH, 1);
1597
SDL_Flip(self->screen);
1599
while (SDL_PollEvent(&event))
1604
if (event.key.keysym.sym == SDLK_F12) /* failsafe */
1607
oesui_event(self, OESUI_UNKEY, (int)(event.key.keysym.sym));
1609
case SDL_MOUSEMOTION:
1610
SDL_GetMouseState(&px, &py);
1611
oesui_event(self, OESUI_WHORIZ, px);
1612
oesui_event(self, OESUI_WVERT, py);
1614
case SDL_MOUSEBUTTONDOWN:
1615
switch (event.button.button)
1617
case SDL_BUTTON_LEFT:
1618
oesui_event(self, OESUI_CLICK, 1);
1621
case SDL_MOUSEBUTTONUP:
1622
switch (event.button.button)
1624
case SDL_BUTTON_LEFT:
1625
oesui_event(self, OESUI_CLICK, 0);
1632
} //switch event.type
1633
} //while SDL_PollEvents
1634
/* Propagate pending signals. */
1635
oesui_signals_cycle(self, self->signals);
1636
} //while !self->retcode
1637
return self->retcode;
1641
/* Set callback handler for unhandled widget signals. */
1643
oesui_sighandle (oesui_t *gui, int (*sighandle)(oesui_t *, oesui_signal_t*))
1645
gui->sighandler = sighandle;