~ubuntu-branches/ubuntu/jaunty/orbital-eunuchs-sniper/jaunty

« back to all changes in this revision

Viewing changes to src/ui.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook
  • Date: 2007-05-29 09:32:48 UTC
  • mfrom: (1.1.1 upstream) (2.1.2 gutsy)
  • Revision ID: james.westby@ubuntu.com-20070529093248-laj1bsm2dffohdf9
Tags: 1.30+svn20070601-1
Fix broken "upstream" rule to generate correctly versioned orig.tar.gz
to avoid native package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  ui system
 
3
*/
 
4
 
 
5
#include <SDL/SDL.h>
 
6
#include <stdarg.h>
 
7
#include <stdio.h>
 
8
#include <stdlib.h>
 
9
#include <string.h>
 
10
#include <limits.h>
 
11
 
 
12
#include "config.h"
 
13
#include "snipe2d.h"
 
14
#include "sexpr/sexp.h"
 
15
 
 
16
#include "ui.h"
 
17
 
 
18
 
 
19
#define IS_HEAPED(obj) (obj->magic == MAGIC_HEAPED)
 
20
#define SET_HEAPED(obj) obj->magic = MAGIC_HEAPED
 
21
 
 
22
/* types */
 
23
typedef oesui_propnode_t asset_t;
 
24
 
 
25
 
 
26
/* globals */
 
27
extern PREFS gPrefs;
 
28
assetcache_t assetcache1;
 
29
 
 
30
 
 
31
/* prototypes */
 
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 *);
 
37
 
 
38
 
 
39
/* functions */
 
40
 
 
41
int
 
42
hashify (const char *s)
 
43
{
 
44
  return 0;
 
45
}
 
46
 
 
47
 
 
48
 
 
49
/**********************
 
50
* Asset cache manager *
 
51
**********************/
 
52
 
 
53
assetcache_t *
 
54
assetcache_init (assetcache_t *self)
 
55
{
 
56
  if (!self)
 
57
    {
 
58
      self = (assetcache_t*)calloc(1, sizeof(*self));
 
59
      if (!self) return NULL;
 
60
      SET_HEAPED(self);
 
61
    }
 
62
  self->len = 1;
 
63
  self->alloc = 64;
 
64
  self->cache = (asset_t*)calloc(self->alloc, sizeof(asset_t));
 
65
  return self;
 
66
}
 
67
 
 
68
 
 
69
void
 
70
assetcache_delete (assetcache_t *self)
 
71
{
 
72
  if (self->cache) free(self->cache);
 
73
  self->cache = NULL;
 
74
  self->len = 0;
 
75
  self->alloc = 0;
 
76
  if (IS_HEAPED(self))
 
77
      free(self);
 
78
}
 
79
 
 
80
 
 
81
void *
 
82
assetcache_get (assetcache_t *self, const char *key)
 
83
{
 
84
  int i, targhash;
 
85
 
 
86
  targhash = hashify(key);
 
87
  for (i = 1; i < self->len; i++)
 
88
    {
 
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;
 
92
    }
 
93
  return NULL;
 
94
}
 
95
 
 
96
 
 
97
void *
 
98
assetcache_idx (assetcache_t *self, int idx)
 
99
{
 
100
  if (idx < 0) return NULL;
 
101
  if (idx > self->len) return NULL;
 
102
  return self->cache[idx].val.p;
 
103
}
 
104
 
 
105
 
 
106
assetcache_t *
 
107
assetcache_register (assetcache_t *self, const char *key, void *obj)
 
108
{
 
109
  if (!self)
 
110
      self = assetcache_init(NULL);
 
111
  if (assetcache_get(self, key))  /* Already registered. */
 
112
      return self;
 
113
  if (self->len > self->alloc)
 
114
    {
 
115
      self->alloc += 64;
 
116
      self->cache = (asset_t*)realloc(self->cache, self->alloc * sizeof(asset_t));
 
117
    }
 
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;
 
122
  self->len++;
 
123
  return self;
 
124
}
 
125
 
 
126
 
 
127
/* special-case asset-manager wrapper */
 
128
SDL_Surface *
 
129
imgasset_register (const char *name)
 
130
{
 
131
  void *obj;
 
132
  SDL_Surface *img;
 
133
 
 
134
  obj = NULL;
 
135
  if (!(obj = assetcache_get(&assetcache1, name)))
 
136
    {
 
137
//printf("caching image '%s'\n", name);
 
138
      if ((img = oes_load_img(name)))
 
139
        {
 
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;
 
144
          assetcache1.len++;
 
145
        }
 
146
    }
 
147
  else
 
148
    {
 
149
//printf("Image '%s' already cached\n", name);
 
150
      img = (SDL_Surface*)obj;
 
151
    }
 
152
  return img;
 
153
}
 
154
 
 
155
 
 
156
 
 
157
 
 
158
 
 
159
/**********************
 
160
* Properties... list? *
 
161
**********************/
 
162
 
 
163
oesui_propnode_t *
 
164
oesui_propnode_init (oesui_propnode_t *self, const char *key)
 
165
{
 
166
  int n;
 
167
  if (!self)
 
168
    {
 
169
      self = (oesui_propnode_t*)calloc(1, sizeof(*self));
 
170
      if (!self) return NULL;
 
171
      SET_HEAPED(self);
 
172
    }
 
173
  self->hash = hashify(key);
 
174
//  self->key = strdup(key);
 
175
  n = strlen(key) + 1;
 
176
  if (self->key)
 
177
    {
 
178
      free(self->key);
 
179
      self->key = NULL;
 
180
    }
 
181
  self->key = (char*)malloc(n);
 
182
  strcpy(self->key, key);
 
183
  return self;
 
184
}
 
185
 
 
186
void
 
187
oesui_propnode_delete (oesui_propnode_t *self)
 
188
{
 
189
  if (self->key)
 
190
    {
 
191
      free(self->key);
 
192
      self->key = 0;
 
193
    }
 
194
  switch (self->valtype)
 
195
    {
 
196
      case OESATOM_INT:
 
197
        self->val.i = 0;
 
198
        break;
 
199
      case OESATOM_FLOAT:
 
200
        self->val.f = 0;
 
201
        break;
 
202
      case OESATOM_SYMBOL:
 
203
        self->val.sym = NULL;
 
204
        break;
 
205
      case OESATOM_STRING:
 
206
        free(self->val.s);
 
207
        self->val.s = NULL;
 
208
        break;
 
209
      case OESATOM_PTR:
 
210
        self->val.p = NULL;
 
211
        break;
 
212
    }
 
213
  if (IS_HEAPED(self))
 
214
      free(self);
 
215
}
 
216
 
 
217
 
 
218
 
 
219
 
 
220
oesui_props_t *
 
221
oesui_props_init (oesui_props_t *self)
 
222
{
 
223
  if (!self)
 
224
    {
 
225
      self = (oesui_props_t*)calloc(1, sizeof(oesui_props_t));
 
226
      if (!self) return NULL;
 
227
      SET_HEAPED(self);
 
228
    }
 
229
//  memset(self, 0, sizeof(*self));
 
230
  self->list = NULL;
 
231
  self->tail = NULL;
 
232
  return self;
 
233
}
 
234
 
 
235
 
 
236
void
 
237
oesui_props_delete (oesui_props_t *self)
 
238
{
 
239
  llist_t *iter, *next;
 
240
 
 
241
  for (iter = self->list; iter; iter = iter->next)
 
242
    {
 
243
      next = iter->next;
 
244
      oesui_propnode_delete((oesui_propnode_t*)(iter->data));
 
245
      iter->data = NULL;
 
246
      free(iter);
 
247
    }
 
248
  if (IS_HEAPED(self))
 
249
      free(self);
 
250
}
 
251
 
 
252
 
 
253
oesui_propnode_t *
 
254
oesui_props_get (oesui_props_t *self, const char *key)
 
255
{
 
256
  oesui_propnode_t *temp;
 
257
  llist_t *iter;
 
258
  int targhash;
 
259
 
 
260
  if (!self) return NULL;
 
261
  targhash = hashify(key);
 
262
  for (iter = self->list; iter; iter = iter->next)
 
263
    {
 
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 */
 
269
      return temp;
 
270
    }
 
271
  return NULL;
 
272
}
 
273
 
 
274
 
 
275
oesui_props_t *
 
276
oesui_props_append (oesui_props_t *self, oesui_propnode_t *node)
 
277
{
 
278
  if (!self)
 
279
      self = (oesui_props_t*)calloc(1, sizeof(*self));
 
280
  if (!self->list)
 
281
    {
 
282
      self->list = (llist_t*)malloc(sizeof(llist_t));
 
283
      self->list->data = node;
 
284
      self->list->next = NULL;
 
285
      self->tail = self->list;
 
286
    }
 
287
  else
 
288
    {
 
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;
 
293
    }
 
294
  return self;
 
295
}
 
296
 
 
297
 
 
298
oesui_props_t *
 
299
oesui_props_set_int (oesui_props_t *self, const char *key, int val)
 
300
{
 
301
  oesui_propnode_t *node;
 
302
 
 
303
  node = oesui_props_get(self, key);
 
304
  if (!node)
 
305
    {
 
306
      node = oesui_propnode_init(NULL, key);
 
307
      if (!node) return NULL;
 
308
      self = oesui_props_append (self, node);
 
309
    }
 
310
  node->valtype = OESATOM_INT;
 
311
  node->val.i = val;
 
312
  return self;
 
313
}
 
314
 
 
315
 
 
316
oesui_props_t *
 
317
oesui_props_set_float (oesui_props_t *self, const char *key, float val)
 
318
{
 
319
  oesui_propnode_t *node;
 
320
 
 
321
  node = oesui_props_get(self, key);
 
322
  if (!node)
 
323
    {
 
324
      node = oesui_propnode_init(NULL, key);
 
325
      if (!node) return NULL;
 
326
      self = oesui_props_append (self, node);
 
327
    }
 
328
  node->valtype = OESATOM_FLOAT;
 
329
  node->val.f = val;
 
330
  return self;
 
331
}
 
332
 
 
333
 
 
334
oesui_props_t *
 
335
oesui_props_set_symbol (oesui_props_t *self, const char *key, const char *val)
 
336
{
 
337
  oesui_propnode_t *node;
 
338
 
 
339
  node = oesui_props_get(self, key);
 
340
  if (!node)
 
341
    {
 
342
      node = oesui_propnode_init(NULL, key);
 
343
      if (!node) return NULL;
 
344
      self = oesui_props_append (self, node);
 
345
    }
 
346
  node->valtype = OESATOM_SYMBOL;
 
347
  node->val.sym = val;
 
348
  return self;
 
349
}
 
350
 
 
351
 
 
352
oesui_props_t *
 
353
oesui_props_set_string (oesui_props_t *self, const char *key, char *val)
 
354
{
 
355
  oesui_propnode_t *node;
 
356
 
 
357
  node = oesui_props_get(self, key);
 
358
  if (!node)
 
359
    {
 
360
      node = oesui_propnode_init(NULL, key);
 
361
      if (!node) return NULL;
 
362
      self = oesui_props_append (self, node);
 
363
    }
 
364
  node->valtype = OESATOM_STRING;
 
365
  node->val.s = val;
 
366
  return self;
 
367
}
 
368
 
 
369
 
 
370
oesui_props_t *
 
371
oesui_props_set_ptr (oesui_props_t *self, const char *key, void *val)
 
372
{
 
373
  oesui_propnode_t *node;
 
374
 
 
375
  node = oesui_props_get(self, key);
 
376
  if (!node)
 
377
    {
 
378
      node = oesui_propnode_init(NULL, key);
 
379
      if (!node) return NULL;
 
380
      self = oesui_props_append (self, node);
 
381
    }
 
382
  node->valtype = OESATOM_PTR;
 
383
  node->val.p = val;
 
384
  return self;
 
385
}
 
386
 
 
387
 
 
388
int
 
389
oesui_props_get_int (oesui_props_t *self, const char *key)
 
390
{
 
391
  oesui_propnode_t *node;
 
392
 
 
393
  node = oesui_props_get(self, key);
 
394
  if (!node) return 0;
 
395
  switch (node->valtype)
 
396
    {
 
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;
 
402
    }
 
403
  return 0;
 
404
}
 
405
 
 
406
 
 
407
float
 
408
oesui_props_get_float (oesui_props_t *self, const char *key)
 
409
{
 
410
  oesui_propnode_t *node;
 
411
 
 
412
  node = oesui_props_get(self, key);
 
413
  if (!node) return 0;
 
414
  switch (node->valtype)
 
415
    {
 
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;
 
421
    }
 
422
  return 0;
 
423
}
 
424
 
 
425
 
 
426
const char *
 
427
oesui_props_get_symbol (oesui_props_t *self, const char *key)
 
428
{
 
429
  oesui_propnode_t *node;
 
430
  static char buf[72];
 
431
 
 
432
  node = oesui_props_get(self, key);
 
433
  if (!node) return 0;
 
434
  switch (node->valtype)
 
435
    {
 
436
      case OESATOM_INT:
 
437
         snprintf(buf, sizeof(buf), "%d", node->val.i); return buf; break;
 
438
      case OESATOM_FLOAT:
 
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;
 
443
    }
 
444
  return 0;
 
445
}
 
446
 
 
447
 
 
448
char *
 
449
oesui_props_get_string (oesui_props_t *self, const char *key)
 
450
{
 
451
  oesui_propnode_t *node;
 
452
//  static char buf[72];
 
453
  static char buf[1024];
 
454
 
 
455
  node = oesui_props_get(self, key);
 
456
  if (!node) return 0;
 
457
  switch (node->valtype)
 
458
    {
 
459
      case OESATOM_INT:
 
460
         snprintf(buf, sizeof(buf), "%d", node->val.i); return buf; break;
 
461
      case OESATOM_FLOAT:
 
462
         snprintf(buf, sizeof(buf), "%f", node->val.f); return buf; break;
 
463
      case OESATOM_SYMBOL:
 
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;
 
467
    }
 
468
  return 0;
 
469
}
 
470
 
 
471
 
 
472
void *
 
473
oesui_props_get_ptr (oesui_props_t *self, const char *key)
 
474
{
 
475
  oesui_propnode_t *node;
 
476
 
 
477
  node = oesui_props_get(self, key);
 
478
  if (!node) return 0;
 
479
  switch (node->valtype)
 
480
    {
 
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;
 
486
    }
 
487
  return 0;
 
488
}
 
489
 
 
490
 
 
491
 
 
492
 
 
493
 
 
494
/*****************
 
495
* Signal message *
 
496
*****************/
 
497
 
 
498
 
 
499
oesui_signal_t *
 
500
oesui_signal_init (oesui_signal_t *self, int len)
 
501
{
 
502
  int chunksize;
 
503
 
 
504
  if (!len)
 
505
      return NULL;
 
506
  if (!self)
 
507
    {
 
508
      chunksize = sizeof(*self) + (len * sizeof(oesui_atom_t));
 
509
      self = (oesui_signal_t*)calloc(1, chunksize);
 
510
      if (!self) return NULL;
 
511
      SET_HEAPED(self);
 
512
    }
 
513
  self->len = len;
 
514
  return self;
 
515
}
 
516
 
 
517
 
 
518
void
 
519
oesui_signal_delete (oesui_signal_t *self)
 
520
{
 
521
  free(UISIG_NAME(self));
 
522
  if (IS_HEAPED(self))
 
523
      free(self);
 
524
}
 
525
 
 
526
 
 
527
 
 
528
 
 
529
 
 
530
/*****************
 
531
* Widget Signals *
 
532
*****************/
 
533
 
 
534
 
 
535
oesui_widget_t *
 
536
oesui_signals_init (oesui_widget_t *self)
 
537
{
 
538
  if (!self)
 
539
    {
 
540
      self = (oesui_widget_t*)calloc(1, sizeof(*self));
 
541
      if (!self) return NULL;
 
542
      SET_HEAPED(self);
 
543
    }
 
544
//  memset(self, 0, sizeof(*self));
 
545
//  self->props = oesui_props_set_ptr(self->props, " queue ", 0);  /* pending signals */
 
546
  self->props = NULL;
 
547
  return self;
 
548
}
 
549
 
 
550
/* Connect widget to signal. */
 
551
int
 
552
oesui_signals_connect (oesui_widget_t *self, const char *signal, int ofs, oesui_widget_t *widget)
 
553
{
 
554
  llist_t *chain, *temp, *curr;
 
555
 
 
556
  chain = (llist_t*)oesui_props_get_ptr(self->props, signal);
 
557
  if (chain)
 
558
    {
 
559
      if (ofs < 0) ofs = INT_MAX;
 
560
      temp = (llist_t*)calloc(1, sizeof(*temp));
 
561
      temp->data = widget;
 
562
      temp->next = NULL;
 
563
      if (ofs == 0)
 
564
        {
 
565
          temp->next = chain;
 
566
          chain = temp;
 
567
        }
 
568
      else
 
569
        {
 
570
          curr = chain;
 
571
          while (curr->next && (ofs-- > 1))
 
572
              curr = curr->next;
 
573
          temp->next = curr->next;
 
574
          curr->next = temp;
 
575
        }
 
576
    }
 
577
  else
 
578
    { /* empty chain */
 
579
      chain = (llist_t*)calloc(1, sizeof(*chain));
 
580
      chain->data = widget;
 
581
      chain->next = NULL;
 
582
    }
 
583
  self->props = oesui_props_set_ptr(self->props, signal, chain);
 
584
  return 1;
 
585
}
 
586
 
 
587
 
 
588
/* raise signal. */
 
589
int
 
590
oesui_signals_raise (oesui_widget_t *self, int len, const char *signal, ...)
 
591
{
 
592
  llist_t *chain, *curr, *temp = NULL;
 
593
  char *signame;
 
594
  oesui_signal_t *sig;
 
595
  va_list vp;
 
596
  int i, n;
 
597
 
 
598
  signame = strdup(signal);
 
599
  chain = (llist_t*)oesui_props_get_ptr(self->props, " queue ");
 
600
 
 
601
  if (!(sig = oesui_signal_init(NULL, len)))
 
602
    {
 
603
      if (temp) free(temp);
 
604
      return 0;
 
605
    }
 
606
  UISIG_NAME(sig) = signame;
 
607
  va_start(vp, signal);
 
608
  for (i = 1; i < len; i++)
 
609
    {
 
610
      n = va_arg(vp, int);
 
611
      UISIG_ARG(sig, 1).i = n;
 
612
    }
 
613
  va_end(vp);
 
614
 
 
615
  if (chain)
 
616
    {
 
617
//printf("appending signal '%s' (%08X)\n", signame, signame);
 
618
      curr = chain;
 
619
      while (curr->next)
 
620
          curr = curr->next;
 
621
      temp = (llist_t*)calloc(1, sizeof(*temp));
 
622
      if (!temp) return 0;
 
623
//      temp->data = signame;
 
624
      temp->data = sig;
 
625
      temp->next = curr->next;
 
626
      curr->next = temp;
 
627
    }
 
628
  else
 
629
    { /* empty chain */
 
630
//printf("inserting signal '%s' (%08X)\n", signame, signame);
 
631
      chain = (llist_t*)calloc(1, sizeof(*chain));
 
632
//      chain->data = signame;
 
633
      chain->data = sig;
 
634
      chain->next = NULL;
 
635
    }
 
636
  self->props = oesui_props_set_ptr(self->props, " queue ", chain);
 
637
  return 1;
 
638
}
 
639
 
 
640
 
 
641
/* propagate signals. */
 
642
int
 
643
oesui_signals_cycle (oesui_t *gui, oesui_widget_t *signals)
 
644
{
 
645
  char *signame;
 
646
  llist_t *queue, *nque, *chain;
 
647
  oesui_widget_t *widget;
 
648
  oesui_signal_t *sig;
 
649
  int n;
 
650
 
 
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;
 
655
  nque = queue->next;
 
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;
 
663
 
 
664
//printf("Propagating signal '%s'\n", signame);
 
665
  chain = (llist_t*)oesui_props_get_ptr(signals->props, signame);
 
666
  n = 0;
 
667
  for(; chain; chain = chain->next)
 
668
    {
 
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;
 
673
    }
 
674
 
 
675
/* unblocked signal. */
 
676
  if (n == 0)
 
677
    {
 
678
//printf("unblocked signal '%s'\n", signame);
 
679
      n = gui->sighandler(gui, sig);
 
680
    }
 
681
 
 
682
//  free(signame);
 
683
  oesui_signal_delete(sig);
 
684
  free(queue);  /* Next-in-queue already saved to property */
 
685
  return n;
 
686
}
 
687
 
 
688
 
 
689
 
 
690
 
 
691
 
 
692
/***********************************
 
693
* Translation of data into widgets *
 
694
***********************************/
 
695
 
 
696
 
 
697
llist_t *
 
698
sexp_to_widgetlist (oesui_t *gui, sexp_t *descrlist)
 
699
{
 
700
  llist_t *wlist, *tail = NULL;
 
701
  oesui_widget_t *widget;
 
702
  sexp_t *descr;
 
703
  //char buf[1024];
 
704
 
 
705
//print_sexp(buf, sizeof(buf), descrlist);
 
706
//printf("descrlist = %s\n", buf);
 
707
  wlist = NULL;
 
708
  for (; descrlist; descrlist = descrlist->next)
 
709
    {
 
710
      descr = descrlist->list;
 
711
      widget = sexp_to_widget(gui, descr);
 
712
//      wlist =  llist_add(wlist, widget);
 
713
      if (!wlist)
 
714
        {
 
715
          wlist = (llist_t*)calloc(1, sizeof(*wlist));
 
716
          tail = wlist;
 
717
          wlist->data = widget;
 
718
          wlist->next = NULL;
 
719
        }
 
720
      else
 
721
        {
 
722
          tail->next = (llist_t*)calloc(1, sizeof(*wlist));
 
723
          tail->next->data = widget;
 
724
          tail->next->next = NULL;
 
725
          tail = tail->next;
 
726
        }
 
727
    }
 
728
  return wlist;
 
729
}
 
730
 
 
731
 
 
732
oesui_widget_t *
 
733
sexp_to_widget (oesui_t *gui, sexp_t *descrlist)
 
734
{
 
735
  sexp_t *alist, *pair;
 
736
  llist_t *wlist;
 
737
  oesui_widget_t *widget;
 
738
  const char *key, *val;
 
739
  //char buf[1024];
 
740
 
 
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);
 
745
  /* alist */
 
746
  alist = descrlist;
 
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)
 
752
    {
 
753
//print_sexp(buf, sizeof(buf), alist);
 
754
//printf("attrib pair = %s\n", buf);
 
755
      if (alist->ty != SEXP_LIST) continue;
 
756
      pair = alist->list;
 
757
      key = pair->val;
 
758
      if (0);
 
759
      else if (0 == strcasecmp(key, "connect"))
 
760
        {
 
761
          sexp_t *sigs;
 
762
          sigs = pair->next;
 
763
          for (sigs = pair->next; sigs; sigs = sigs->next)
 
764
            {
 
765
              val = sigs->val;
 
766
//printf("will connect to signal '%s'\n", val);
 
767
              oesui_signals_connect(gui->signals, val, -1, widget);
 
768
            }
 
769
//          widget->props = oesui_props_set_ptr(widget->props, "connect", sigs);
 
770
        }
 
771
      else if (0 == strcasecmp(key, "container"))
 
772
        {
 
773
//printf("container...\n");
 
774
          wlist = sexp_to_widgetlist(gui, pair->next);
 
775
          widget->props = oesui_props_set_ptr(widget->props, key, wlist);
 
776
        }
 
777
      else
 
778
        {
 
779
          /* normal key/value pair */
 
780
          val = "";
 
781
          if (pair->next)
 
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));
 
785
        }
 
786
    }
 
787
//printf("proplist dump:\n");
 
788
#if 0
 
789
oesui_propnode_t *prop;
 
790
for (wlist = widget->props->list; wlist; wlist = wlist->next)
 
791
{
 
792
  prop = (oesui_propnode_t*)(wlist->data);
 
793
  printf(" key = %s  =>  %s\n", prop->key, prop->valtype == OESATOM_STRING ? prop->val.s : "-");
 
794
}
 
795
#endif /* 0 */
 
796
//printf("/done => %08X.%08X\n", widget, widget->props);
 
797
  return widget;
 
798
}
 
799
 
 
800
 
 
801
 
 
802
 
 
803
 
 
804
/*************************
 
805
* um... support/utility? *
 
806
*************************/
 
807
 
 
808
 
 
809
int
 
810
oesui_pointed (oesui_t *gui, oesui_widget_t *widget)
 
811
{
 
812
  int x0, x1, y0, y1;  /* boundary check */
 
813
  int px, py;  /* pointer location */
 
814
 
 
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");
 
819
  px = gui->px;
 
820
  py = gui->py;
 
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))
 
823
      return 1;
 
824
  return 0;
 
825
}
 
826
 
 
827
 
 
828
 
 
829
 
 
830
 
 
831
/*******************
 
832
* Ownerdraw widget *
 
833
*******************/
 
834
 
 
835
 
 
836
int
 
837
oesui_ownerdraw_paint (oesui_t *gui, oesui_widget_t *widget)
 
838
{
 
839
  SDL_Rect r;
 
840
  const char *objtype = 0;
 
841
  int rendertime, loadtime;
 
842
 
 
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))
 
848
      return 0;
 
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);
 
854
  return 1;
 
855
}
 
856
 
 
857
 
 
858
 
 
859
 
 
860
 
 
861
/***************
 
862
* Label widget *
 
863
***************/
 
864
 
 
865
 
 
866
int
 
867
oesui_label_paint (oesui_t *gui, oesui_widget_t *widget)
 
868
{
 
869
  oesui_propnode_t *prop;
 
870
  int col; /* color */
 
871
  char text[256];
 
872
  SDL_Rect br;
 
873
 
 
874
  prop = oesui_props_get(widget->props, "text");
 
875
  if (!prop) return 0;
 
876
  *text = 0;
 
877
  switch (prop->valtype)
 
878
    {
 
879
      case OESATOM_INT:
 
880
        snprintf(text, sizeof(text), "%d", prop->val.i);
 
881
        break;
 
882
      case OESATOM_FLOAT:
 
883
        snprintf(text, sizeof(text), "%f", prop->val.f);
 
884
        break;
 
885
      case OESATOM_SYMBOL:
 
886
        snprintf(text, sizeof(text), "%s", prop->val.sym);
 
887
        break;
 
888
      case OESATOM_STRING:
 
889
        snprintf(text, sizeof(text), "%s", prop->val.s);
 
890
        break;
 
891
    }
 
892
  if (!*text)
 
893
      return 0;
 
894
 
 
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");
 
900
 
 
901
  print(br.x, br.y, col, text);
 
902
 
 
903
  return 1;
 
904
}
 
905
 
 
906
 
 
907
 
 
908
 
 
909
 
 
910
/***************
 
911
* Image widget *
 
912
***************/
 
913
 
 
914
 
 
915
int
 
916
oesui_image_paint (oesui_t *gui, oesui_widget_t *widget)
 
917
{
 
918
  oesui_propnode_t *prop;
 
919
  SDL_Surface *img = 0;
 
920
  SDL_Rect br;
 
921
 
 
922
  prop = oesui_props_get(widget->props, "image");
 
923
  if (!prop) return 0;
 
924
  switch (prop->valtype)
 
925
    {
 
926
      case OESATOM_INT:
 
927
        img = (SDL_Surface*)assetcache_idx(&assetcache1, prop->val.i);
 
928
        break;
 
929
      case OESATOM_SYMBOL:
 
930
        img = imgasset_register(prop->val.sym);
 
931
        break;
 
932
      case OESATOM_STRING:
 
933
        img = imgasset_register(prop->val.s);
 
934
        break;
 
935
      case OESATOM_PTR:
 
936
        img = (SDL_Surface*)(prop->val.p);
 
937
        break;
 
938
    }
 
939
  if (!img) return 0;
 
940
  widget->props = oesui_props_set_ptr(widget->props, "image", img);
 
941
 
 
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");
 
946
 
 
947
  if (!br.w)
 
948
    {
 
949
      br.w = img->w;
 
950
      widget->props = oesui_props_set_int(widget->props, "w", img->w);
 
951
    }
 
952
  if (!br.h)
 
953
    {
 
954
      br.h = img->h;
 
955
      widget->props = oesui_props_set_int(widget->props, "h", img->h);
 
956
    }
 
957
 
 
958
  SDL_BlitSurface(img, NULL, gui->screen, &br);
 
959
 
 
960
  return 0;
 
961
}
 
962
 
 
963
 
 
964
int
 
965
oesui_image_update (oesui_t *gui, oesui_widget_t *widget)
 
966
{
 
967
  //const char *objname;
 
968
 
 
969
//  objname = oesui_props_get_string(widget->props, "name");
 
970
//  if (!objname) return 0;
 
971
//  if (0);
 
972
  return 0;
 
973
}
 
974
 
 
975
 
 
976
 
 
977
 
 
978
 
 
979
/****************
 
980
* Button widget *
 
981
****************/
 
982
 
 
983
 
 
984
int
 
985
oesui_button_paint (oesui_t *gui, oesui_widget_t *widget)
 
986
{
 
987
  SDL_Rect br = { 0, };
 
988
  SDL_Surface *img = 0;
 
989
  int focus = 0;
 
990
  const char *field = 0;
 
991
  //const char *imgname = 0;
 
992
  //void *imgobj;
 
993
  oesui_propnode_t *prop;
 
994
 
 
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)
 
1004
    {
 
1005
      case OESATOM_INT:
 
1006
        img = (SDL_Surface*)assetcache_idx(&assetcache1, prop->val.i);
 
1007
        break;
 
1008
      case OESATOM_SYMBOL:
 
1009
        img = imgasset_register(prop->val.sym);
 
1010
        break;
 
1011
      case OESATOM_STRING:
 
1012
        img = imgasset_register(prop->val.s);
 
1013
        break;
 
1014
      case OESATOM_PTR:
 
1015
        img = (SDL_Surface*)(prop->val.p);
 
1016
        break;
 
1017
    }
 
1018
  if (!img) return 0;
 
1019
  widget->props = oesui_props_set_ptr(widget->props, field, img);
 
1020
 
 
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");
 
1025
 
 
1026
  if (!br.w)
 
1027
    {
 
1028
      br.w = img->w;
 
1029
      widget->props = oesui_props_set_int(widget->props, "w", img->w);
 
1030
    }
 
1031
  if (!br.h)
 
1032
    {
 
1033
      br.h = img->h;
 
1034
      widget->props = oesui_props_set_int(widget->props, "h", img->h);
 
1035
    }
 
1036
 
 
1037
//printf("button at (%d, %d), %d x %d\n", br.x, br.y, br.w, br.h);
 
1038
 
 
1039
  SDL_BlitSurface(img, NULL, gui->screen, &br);
 
1040
 
 
1041
  return 1;
 
1042
}
 
1043
 
 
1044
 
 
1045
int
 
1046
oesui_button_update (oesui_t *gui, oesui_widget_t *widget)
 
1047
{
 
1048
  const char *bname;
 
1049
  SDL_Surface *img = 0, *himg = 0;
 
1050
  const char *imgname = 0, *himgname = 0;
 
1051
 
 
1052
//printf("Button Update\n");
 
1053
  bname = oesui_props_get_string(widget->props, "name");
 
1054
  if (!bname) return 0;
 
1055
  if (0);
 
1056
  else if (0 == strcmp(bname, "Fullscreen"))
 
1057
    {
 
1058
      imgname = gPrefs.fullscreen ? "fullscreen.png" : "window.png";
 
1059
      himgname = gPrefs.fullscreen ? "fullscreenh.png" : "windowh.png";
 
1060
    }
 
1061
  else if (0 == strcmp(bname, "Audio"))
 
1062
    {
 
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);
 
1066
    }
 
1067
  else if (0 == strcmp(bname, "Difficulty"))
 
1068
    {
 
1069
      switch (gPrefs.difficulty)
 
1070
        {
 
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;
 
1074
        }
 
1075
    }
 
1076
  else if (0 == strcmp(bname, "Quit"))
 
1077
    {
 
1078
      /* do nothing */
 
1079
    }
 
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);
 
1088
  
 
1089
  return 0;
 
1090
}
 
1091
 
 
1092
 
 
1093
int
 
1094
oesui_button_signal (oesui_t *gui, oesui_widget_t *widget, oesui_signal_t *sig)
 
1095
{
 
1096
  const char *spit;
 
1097
  int focus;
 
1098
 
 
1099
  if (0);
 
1100
  else if (0 == strcmp(UISIG_NAME(sig), "click"))
 
1101
    {
 
1102
//printf("button signal CLICK\n");
 
1103
      if (!(oesui_pointed(gui, widget)))
 
1104
          return 0;
 
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);
 
1109
    }
 
1110
  else if (0 == strcmp(UISIG_NAME(sig), "focus"))
 
1111
    { 
 
1112
      focus = oesui_props_get_int(widget->props, "focus");
 
1113
      if (oesui_pointed(gui, widget))
 
1114
        {
 
1115
          /* in focus */
 
1116
          if (focus == 0)
 
1117
            {
 
1118
              /* just came into focus. */
 
1119
            }
 
1120
        }
 
1121
      else
 
1122
        {
 
1123
          /* not in focus. */
 
1124
          if (focus)
 
1125
            {
 
1126
              /* just lost focus. */
 
1127
            }
 
1128
        }
 
1129
    }
 
1130
  return 0;
 
1131
}
 
1132
 
 
1133
 
 
1134
 
 
1135
 
 
1136
 
 
1137
/******************
 
1138
* Toplevel widget *
 
1139
******************/
 
1140
 
 
1141
 
 
1142
int
 
1143
oesui_toplevel_paint (oesui_t *gui, oesui_widget_t *widget)
 
1144
{
 
1145
  llist_t *container;
 
1146
  oesui_widget_t *child;
 
1147
 
 
1148
  container = (llist_t*)oesui_props_get_ptr(widget->props, "container");
 
1149
  if (!container) return 0;
 
1150
  for (; container; container = container->next)
 
1151
    {
 
1152
      child = (oesui_widget_t*)(container->data);
 
1153
      oesui_widget_paint(gui, child);
 
1154
    }
 
1155
  return 0;
 
1156
}
 
1157
 
 
1158
 
 
1159
int
 
1160
oesui_toplevel_update (oesui_t *gui, oesui_widget_t *widget)
 
1161
{
 
1162
  llist_t *container;
 
1163
  oesui_widget_t *child;
 
1164
 
 
1165
  if (!widget) return 0;
 
1166
  container = (llist_t*)oesui_props_get_ptr(widget->props, "container");
 
1167
  for (; container; container = container->next)
 
1168
    {
 
1169
      child = (oesui_widget_t*)(container->data);
 
1170
      oesui_widget_update(gui, child);
 
1171
    }
 
1172
  return 1;
 
1173
}
 
1174
 
 
1175
 
 
1176
int
 
1177
oesui_toplevel_signal (oesui_t *gui, oesui_widget_t *widget, oesui_signal_t *sig)
 
1178
{
 
1179
  const char *emit;
 
1180
 
 
1181
  if (0);
 
1182
  else if (0 == strcmp(UISIG_NAME(sig), "esc"))
 
1183
    {
 
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);
 
1189
    }
 
1190
  else if (0 == strcmp(UISIG_NAME(sig), "cycle-focus"))
 
1191
    {
 
1192
      /* do nothing */
 
1193
    }
 
1194
  return 0;
 
1195
}
 
1196
 
 
1197
 
 
1198
int
 
1199
oesui_toplevel_open (oesui_t *gui, oesui_widget_t *widget)
 
1200
{
 
1201
  llist_t *container;
 
1202
  oesui_widget_t *child;
 
1203
  int loadtime;
 
1204
 
 
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);
 
1209
 
 
1210
  container = (llist_t*)oesui_props_get_ptr(widget->props, "container");
 
1211
  if (!container) return 0;
 
1212
  for (; container; container = container->next)
 
1213
    {
 
1214
      child = (oesui_widget_t*)(container->data);
 
1215
      child->props = oesui_props_set_int(child->props, "enabled", 1);
 
1216
    }
 
1217
  oesui_widget_update(gui, widget);
 
1218
  return 0;
 
1219
}
 
1220
 
 
1221
 
 
1222
int
 
1223
oesui_toplevel_close (oesui_t *gui, oesui_widget_t *widget)
 
1224
{
 
1225
  llist_t *container;
 
1226
  oesui_widget_t *child;
 
1227
 
 
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)
 
1233
    {
 
1234
      child = (oesui_widget_t*)(container->data);
 
1235
      child->props = oesui_props_set_int(child->props, "enabled", 0);
 
1236
    }
 
1237
  return 0;
 
1238
}
 
1239
 
 
1240
 
 
1241
 
 
1242
 
 
1243
 
 
1244
/*********************************/
 
1245
/* Generalized widget functions. */
 
1246
/*********************************/
 
1247
 
 
1248
 
 
1249
int
 
1250
oesui_widget_paint (oesui_t *gui, oesui_widget_t *widget)
 
1251
{
 
1252
  const char *objtype;
 
1253
  int (*paintfunc)(oesui_t *, oesui_widget_t*);
 
1254
 
 
1255
  objtype = oesui_props_get_string(widget->props, "type");
 
1256
  if (!objtype) return 0;
 
1257
//printf("painting objtype '%s'\n", objtype);
 
1258
  paintfunc = 0;
 
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;
 
1269
  if (paintfunc)
 
1270
      return paintfunc(gui, widget);
 
1271
  return 0;
 
1272
}
 
1273
 
 
1274
 
 
1275
int
 
1276
oesui_widget_update (oesui_t *gui, oesui_widget_t *widget)
 
1277
{
 
1278
  const char *objtype;
 
1279
  int (*updatefunc)(oesui_t *, oesui_widget_t *) = NULL;
 
1280
 
 
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;
 
1288
  if (updatefunc)
 
1289
      return updatefunc(gui, widget);
 
1290
  return 0;
 
1291
}
 
1292
 
 
1293
 
 
1294
int
 
1295
oesui_widget_signal (oesui_t *gui, oesui_widget_t *widget, oesui_signal_t *sig)
 
1296
{
 
1297
  const char *objtype;
 
1298
  int (*sigfunc)(oesui_t*, oesui_widget_t*, oesui_signal_t *) = NULL;
 
1299
 
 
1300
  objtype = oesui_props_get_string(widget->props, "type");
 
1301
//printf("widget_signal on %s\n", objtype);
 
1302
  if (!objtype) return 0;
 
1303
  if (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;
 
1308
  if (sigfunc)
 
1309
      return sigfunc(gui, widget, sig);
 
1310
  return 0;
 
1311
}
 
1312
 
 
1313
 
 
1314
int
 
1315
oesui_widget_open (oesui_t *gui, oesui_widget_t *widget)
 
1316
{
 
1317
  const char *objtype;
 
1318
  int (*openfunc)(oesui_t *, oesui_widget_t *) = NULL;
 
1319
 
 
1320
  objtype = oesui_props_get_string(widget->props, "type");
 
1321
  if (!objtype) return 0;
 
1322
  if (0);
 
1323
  else if (0 == strcasecmp(objtype, "toplevel"))
 
1324
      openfunc = oesui_toplevel_open;
 
1325
  if (openfunc)
 
1326
      return openfunc(gui, widget);
 
1327
  return 0;
 
1328
}
 
1329
 
 
1330
 
 
1331
int
 
1332
oesui_widget_close (oesui_t *gui, oesui_widget_t *widget)
 
1333
{
 
1334
  const char *objtype;
 
1335
  int (*closefunc)(oesui_t *, oesui_widget_t *) = NULL;
 
1336
 
 
1337
  objtype = oesui_props_get_string(widget->props, "type");
 
1338
  if (!objtype) return 0;
 
1339
  if (0);
 
1340
  else if (0 == strcasecmp(objtype, "toplevel"))
 
1341
      closefunc = oesui_toplevel_close;
 
1342
  if (closefunc)
 
1343
      return closefunc(gui, widget);
 
1344
  return 0;
 
1345
}
 
1346
 
 
1347
 
 
1348
 
 
1349
 
 
1350
 
 
1351
/************
 
1352
* UI System *
 
1353
************/
 
1354
 
 
1355
 
 
1356
/* Inject event into UI system. */
 
1357
int
 
1358
oesui_event (oesui_t *self, int evtype, int parm)
 
1359
{
 
1360
  const char *objtype;
 
1361
 
 
1362
objtype = oesui_props_get_string(self->toplevel->props, "type");
 
1363
//printf("toplevel objtype (%08X) = %s\n", self->toplevel, objtype);
 
1364
 
 
1365
  switch (evtype)
 
1366
    {
 
1367
      case OESUI_UPDATE:
 
1368
        oesui_widget_update(self, self->toplevel);
 
1369
        break;
 
1370
      case OESUI_REFRESH:
 
1371
        oesui_widget_paint(self, self->toplevel);
 
1372
        break;
 
1373
      case OESUI_WHORIZ:
 
1374
        self->px = 0;
 
1375
        /* fallthrough */
 
1376
      case OESUI_MHORIZ:
 
1377
        self->px += parm;
 
1378
        if (self->px > self->screen->w)
 
1379
            self->px = self->screen->w;
 
1380
        if (self->px < 0)
 
1381
            self->px = 0;
 
1382
//printf("Pointer @ (%d, %d)\n", self->px, self->py);
 
1383
        break;
 
1384
      case OESUI_WVERT:
 
1385
        self->py = 0;
 
1386
        /* fallthrough */
 
1387
      case OESUI_MVERT:
 
1388
        self->py += parm;
 
1389
        if (self->py > self->screen->h)
 
1390
            self->py = self->screen->h;
 
1391
        if (self->py < 0)
 
1392
            self->py = 0;
 
1393
//printf("Pointer @ (%d, %d)\n", self->px, self->py);
 
1394
        break;
 
1395
      case OESUI_OPEN:
 
1396
        oesui_widget_open(self, self->toplevel);
 
1397
        break;
 
1398
      case OESUI_CLOSE:
 
1399
        oesui_widget_close(self, self->toplevel);
 
1400
        break;
 
1401
      case OESUI_UNKEY:
 
1402
        switch (parm)
 
1403
          {
 
1404
            case SDLK_ESCAPE:
 
1405
//              oesui_signals_raise(self->signals, "esc");
 
1406
              oesui_signals_raise(self->signals, 1, "esc");
 
1407
              break;
 
1408
            case SDLK_TAB:
 
1409
//              oesui_signals_raise(self->signals, "cycle-focus");
 
1410
              oesui_signals_raise(self->signals, 1, "cycle-focus");
 
1411
              break;
 
1412
          }
 
1413
        break;
 
1414
      case OESUI_CLICK:
 
1415
//        return oesui_toplevel_click(self, self->toplevel, parm);
 
1416
        if (parm)
 
1417
//            return oesui_signals_raise(self->signals, "click");
 
1418
            return oesui_signals_raise(self->signals, 3, "click", self->px, self->py);
 
1419
        break;
 
1420
    }
 
1421
 
 
1422
  return 0;
 
1423
}
 
1424
 
 
1425
 
 
1426
/* Load assets specified in data file */
 
1427
int
 
1428
oesui_cache_assets (oesui_t *self, sexp_t *se)
 
1429
{
 
1430
  sexp_t *pair;
 
1431
  const char *objtype;
 
1432
  char *objname;
 
1433
  //SDL_Surface *img;
 
1434
 
 
1435
  for (; se; se = se->next)
 
1436
    {
 
1437
      pair = se->list;
 
1438
      objtype = pair->val;
 
1439
      if (0);
 
1440
      else if (0 == strcasecmp(objtype, "img"))
 
1441
        {
 
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);
 
1447
        }
 
1448
    }
 
1449
  return 0;
 
1450
}
 
1451
 
 
1452
 
 
1453
/* Select toplevel to display */
 
1454
int
 
1455
oesui_open (oesui_t *self, const char *tlname)
 
1456
{
 
1457
///  int loadtime;
 
1458
//  loadtime = SDL_GetTicks();
 
1459
//  self->toplevel->props = oesui_props_set_int(self->toplevel->props, "loadtime", loadtime);
 
1460
 
 
1461
  if (self->toplevel)
 
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"));
 
1466
  return 0;
 
1467
}
 
1468
 
 
1469
 
 
1470
/* Load UI info from file. */
 
1471
int
 
1472
oesui_load (oesui_t *self, const char *fname)
 
1473
{
 
1474
  FILE *guifile;
 
1475
  sexp_iowrap_t *io;
 
1476
  sexp_t *se;
 
1477
  const char *objtype;
 
1478
  oesui_widget_t *widget;
 
1479
  char * menuname = "menus.cfg";
 
1480
  char * menupath;
 
1481
 
 
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);
 
1486
    exit(1);
 
1487
  }
 
1488
  free(menupath);
 
1489
  menupath=NULL;
 
1490
 
 
1491
  io = init_iowrap(fileno(guifile));
 
1492
//  self->toplevel = read_one_sexp(io);
 
1493
  while ((se = read_one_sexp(io)))
 
1494
    {
 
1495
      if (se->ty == SEXP_LIST)
 
1496
        {
 
1497
          if (hd_sexp(se)->ty == SEXP_VALUE)
 
1498
            {
 
1499
              objtype = se->list->val;
 
1500
              if (0);
 
1501
              else if (0 == strcasecmp(objtype, "assets"))
 
1502
                  oesui_cache_assets(self, se->list->next);
 
1503
            }
 
1504
          else
 
1505
            {
 
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);
 
1512
            }
 
1513
        }
 
1514
//      self->toplevel = sexp_to_widget(se);
 
1515
//      oesui_widget_update (self, self->toplevel);
 
1516
        destroy_sexp(se);
 
1517
    }
 
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);
 
1523
  destroy_iowrap(io);
 
1524
  fclose(guifile);
 
1525
  return 1;
 
1526
}
 
1527
 
 
1528
 
 
1529
oesui_t *
 
1530
oesui_init (oesui_t *self)
 
1531
{
 
1532
  if (!self)
 
1533
    {
 
1534
      self = (oesui_t*)calloc(1, sizeof(oesui_t));
 
1535
      if (!self) return NULL;
 
1536
      SET_HEAPED(self);
 
1537
    }
 
1538
//  memset(self, 0, sizeof(*self));
 
1539
 
 
1540
  self->screen = NULL;
 
1541
  self->toplevel = NULL;
 
1542
  self->sighandler = NULL;
 
1543
 
 
1544
  self->x = 0;
 
1545
  self->y = 0;
 
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;
 
1550
  self->pz = 0;
 
1551
  self->signals = oesui_signals_init(self->signals);
 
1552
  self->retcode = 0;
 
1553
  assetcache_init(&assetcache1);
 
1554
  return self;
 
1555
}
 
1556
 
 
1557
 
 
1558
/* Initialize with screen. */
 
1559
oesui_t *
 
1560
oesui_init_surface (oesui_t *self, SDL_Surface *sdlscreen)
 
1561
{
 
1562
  if ((self = oesui_init(self)))
 
1563
    {
 
1564
      self->screen = sdlscreen;
 
1565
      self->w = self->screen->w;  /* redundant? */
 
1566
      self->h = self->screen->h;
 
1567
    }
 
1568
  return self;
 
1569
}
 
1570
 
 
1571
 
 
1572
void
 
1573
oesui_delete (oesui_t *self)
 
1574
{
 
1575
//  destroy_sexp(gui->toplevel);
 
1576
  if (IS_HEAPED(self))
 
1577
      free(self);
 
1578
}
 
1579
 
 
1580
 
 
1581
/* UI loop. */
 
1582
int
 
1583
oesui_loop (oesui_t *self)
 
1584
{
 
1585
  int lastdraw = 0;
 
1586
  int px, py;  /* pointer (mouse) location. */
 
1587
  int ticks;
 
1588
  SDL_Event event;
 
1589
 
 
1590
  SDL_ShowCursor(1);
 
1591
  while (!self->retcode)
 
1592
    {
 
1593
      ticks = SDL_GetTicks();
 
1594
      if (ticks > lastdraw + 20)
 
1595
        {
 
1596
          oesui_event(self, OESUI_REFRESH, 1);
 
1597
          SDL_Flip(self->screen);
 
1598
        }
 
1599
      while (SDL_PollEvent(&event))
 
1600
        {
 
1601
          switch (event.type)
 
1602
            {
 
1603
              case SDL_KEYUP:
 
1604
                if (event.key.keysym.sym == SDLK_F12)  /* failsafe */
 
1605
                    exit(0);
 
1606
                else
 
1607
                    oesui_event(self, OESUI_UNKEY, (int)(event.key.keysym.sym));
 
1608
                break;
 
1609
              case SDL_MOUSEMOTION:
 
1610
                SDL_GetMouseState(&px, &py);
 
1611
                oesui_event(self, OESUI_WHORIZ, px);
 
1612
                oesui_event(self, OESUI_WVERT, py);
 
1613
                break;
 
1614
              case SDL_MOUSEBUTTONDOWN:
 
1615
                switch (event.button.button)
 
1616
                  {
 
1617
                    case SDL_BUTTON_LEFT:
 
1618
                      oesui_event(self, OESUI_CLICK, 1);
 
1619
                      break;
 
1620
                  }
 
1621
              case SDL_MOUSEBUTTONUP:
 
1622
                switch (event.button.button)
 
1623
                  {
 
1624
                    case SDL_BUTTON_LEFT:
 
1625
                      oesui_event(self, OESUI_CLICK, 0);
 
1626
                      break;
 
1627
                  }
 
1628
                break;
 
1629
              case SDL_QUIT:
 
1630
                exit(0);
 
1631
                break;
 
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;
 
1638
}
 
1639
 
 
1640
 
 
1641
/* Set callback handler for unhandled widget signals. */
 
1642
int
 
1643
oesui_sighandle (oesui_t *gui, int (*sighandle)(oesui_t *, oesui_signal_t*))
 
1644
{
 
1645
  gui->sighandler = sighandle;
 
1646
  return 0;
 
1647
}