TORCS  1.3.9
The Open Racing Car Simulator
guiscrollist.cpp
Go to the documentation of this file.
1 /***************************************************************************
2 
3  file : guiscrollist.cpp
4  created : Mon Aug 23 19:22:49 CEST 1999
5  copyright : (C) 1999 by Eric Espie
6  email : torcs@free.fr
7  version : $Id$
8 
9  ***************************************************************************/
10 
11 /***************************************************************************
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * *
18  ***************************************************************************/
19 
27 #include <stdlib.h>
28 #include <stdio.h>
29 #ifdef WIN32
30 #include <windows.h>
31 #endif
32 #include <tgfclient.h>
33 #include "gui.h"
34 #include "guifont.h"
35 #include <portability.h>
36 
37 void
39 {
40 }
41 
42 static void
44 {
45  tGfuiObject *object;
46  tGfuiScrollList *scrollist;
47 
48  object = (tGfuiObject *) sinfo->userData;
49  //object = gfuiGetObject(GfuiScreen, (long)(sinfo->userData));
50 
51  if(object == NULL) {
52  return;
53  }
54 
55  if(object->widget != GFUI_SCROLLIST) {
56  return;
57  }
58 
59  scrollist = &(object->u.scrollist);
60 
61  scrollist->firstVisible = sinfo->pos;
62 
63  if((scrollist->selectedElt < scrollist->firstVisible) ||
64  (scrollist->selectedElt > scrollist->firstVisible + scrollist->nbVisible)) {
65  scrollist->selectedElt = -1;
66  }
67 }
68 
69 void
71 {
72  tGfuiScrollList *scrollist;
73 
74  scrollist = &(object->u.scrollist);
75 
76  scrollist->selectedElt++;
77 
78  if(scrollist->selectedElt == scrollist->nbElts) {
79  scrollist->selectedElt = scrollist->nbElts - 1;
80  return;
81  }
82 
83  if(scrollist->onSelect) {
84  scrollist->onSelect(scrollist->userDataOnSelect);
85  }
86 
87  if(scrollist->selectedElt == scrollist->firstVisible + scrollist->nbVisible) {
88  /* Scroll down */
89  if(scrollist->firstVisible + scrollist->nbVisible < scrollist->nbElts) {
90  scrollist->firstVisible++;
91 
92  if(scrollist->scrollBar) {
93  GfuiScrollBarPosSet(GfuiScreen, scrollist->scrollBar, 0, MAX(scrollist->nbElts - scrollist->nbVisible, 0),
94  scrollist->nbVisible, scrollist->firstVisible);
95  }
96  }
97  }
98 }
99 
100 void
102 {
103  tGfuiScrollList *scrollist;
104 
105  scrollist = &(object->u.scrollist);
106 
107  scrollist->selectedElt--;
108 
109  if(scrollist->selectedElt < 0) {
110  scrollist->selectedElt = 0;
111  return;
112  }
113 
114  if(scrollist->onSelect) {
115  scrollist->onSelect(scrollist->userDataOnSelect);
116  }
117 
118  if(scrollist->selectedElt < scrollist->firstVisible) {
119  /* Scroll down */
120  if(scrollist->firstVisible > 0) {
121  scrollist->firstVisible--;
122 
123  if(scrollist->scrollBar) {
124  GfuiScrollBarPosSet(GfuiScreen, scrollist->scrollBar, 0, MAX(scrollist->nbElts - scrollist->nbVisible, 0),
125  scrollist->nbVisible, scrollist->firstVisible);
126  }
127  }
128  }
129 }
130 
131 
149 int
150 GfuiScrollListCreate(void *scr, int font, int x, int y, int align, int width, int height,
151  int scrollBarPos, void *userDataOnSelect, tfuiCallback onSelect)
152 {
153  tGfuiScrollList *scrollist;
154  tGfuiObject *object;
155  tGfuiScreen *screen = (tGfuiScreen *)scr;
156 
157  object = (tGfuiObject *)calloc(1, sizeof(tGfuiObject));
158  object->widget = GFUI_SCROLLIST;
159  object->focusMode = GFUI_FOCUS_MOUSE_MOVE;
160  object->id = screen->curId++;
161  object->visible = 1;
162 
163  object->xmin = x;
164  object->xmax = x + width;
165  object->ymin = y;
166  object->ymax = y + height;
167 
168  scrollist = &(object->u.scrollist);
169  scrollist->fgColor[0] = &(GfuiColor[GFUI_FGSCROLLIST][0]);
170  scrollist->bgColor[0] = &(GfuiColor[GFUI_BGSCROLLIST][0]);
171  scrollist->fgSelectColor[0] = &(GfuiColor[GFUI_FGSELSCROLLIST][0]);
172  scrollist->bgSelectColor[0] = &(GfuiColor[GFUI_BGSELSCROLLIST][0]);
173  scrollist->font = gfuiFont[font];
174  scrollist->nbVisible = height / (scrollist->font->getDescender() + scrollist->font->getHeight());
175  scrollist->selectedElt = -1;
176  scrollist->userDataOnSelect = userDataOnSelect;
177  scrollist->onSelect = onSelect;
178 
179  switch(scrollBarPos) {
180  case GFUI_SB_NONE:
181  break;
182  case GFUI_SB_RIGHT:
183  scrollist->scrollBar = GfuiScrollBarCreate(scr, x + width, y, GFUI_ALIGN_HL_VB, height, GFUI_VERT_SCROLLBAR,
184  0, 10, 10, 10, (void *)(object), gfuiScroll);
185  break;
186  case GFUI_SB_LEFT:
187  scrollist->scrollBar = GfuiScrollBarCreate(scr, x, y, GFUI_ALIGN_HR_VB, height, GFUI_VERT_SCROLLBAR,
188  0, 10, 10, 10, (void *)(object), gfuiScroll);
189  break;
190  }
191 
192  gfuiAddObject(screen, object);
193  return object->id;
194 }
195 
196 static void
198 {
199  tGfuiListElement *cur;
200  int i;
201 
202  if(scrollist->elts == NULL) {
203  scrollist->elts = elt;
204  elt->next = elt;
205  elt->prev = elt;
206  } else {
207  cur = scrollist->elts;
208  i = 0;
209 
210  do {
211  if(i == index) {
212  break;
213  }
214 
215  cur = cur->next;
216  i++;
217  } while(cur != scrollist->elts);
218 
219  elt->next = cur->next;
220  cur->next = elt;
221  elt->prev = cur;
222  elt->next->prev = elt;
223 
224  if((cur == scrollist->elts) && (index != 0)) {
225  scrollist->elts = elt;
226  }
227  }
228 }
229 
230 static tGfuiListElement *
231 gfuiScrollListRemElt(tGfuiScrollList *scrollist, int index)
232 {
233  tGfuiListElement *cur;
234  int i;
235 
236  if(scrollist->elts == NULL) {
237  return (tGfuiListElement *)NULL;
238  }
239 
240  cur = scrollist->elts;
241  i = 0;
242 
243  do {
244  cur = cur->next;
245 
246  if(i == index) {
247  break;
248  }
249 
250  i++;
251  } while(cur != scrollist->elts);
252 
253  cur->next->prev = cur->prev;
254  cur->prev->next = cur->next;
255 
256  if(cur == scrollist->elts) {
257  if(cur->next == cur) {
258  scrollist->elts = (tGfuiListElement *)NULL;
259  } else {
260  scrollist->elts = cur->prev;
261  }
262  }
263 
264  return cur;
265 }
266 
275 char *
276 GfuiScrollListGetSelectedElement(void *scr, int Id, void **userData)
277 {
278  tGfuiObject *object;
279  tGfuiScrollList *scrollist;
280  tGfuiListElement *elt;
281  char *name;
282  int i;
283 
284 
285  object = gfuiGetObject(scr, Id);
286 
287  if(object == NULL) {
288  return (char *)NULL;
289  }
290 
291  if(object->widget != GFUI_SCROLLIST) {
292  return (char *)NULL;
293  }
294 
295  scrollist = &(object->u.scrollist);
296 
297  if(scrollist->selectedElt == -1) {
298  return (char *)NULL;
299  }
300 
301  if(scrollist->elts == NULL) {
302  return (char *)NULL;
303  }
304 
305  elt = scrollist->elts;
306  i = 0;
307 
308  do {
309  elt = elt->next;
310 
311  if(i == scrollist->selectedElt) {
312  break;
313  }
314 
315  i++;
316  } while(elt != scrollist->elts);
317 
318  name = elt->name;
319  *userData = elt->userData;
320 
321  return name;
322 }
323 
333 char *
334 GfuiScrollListGetElement(void *scr, int Id, int index, void **userData)
335 {
336  tGfuiObject *object;
337  tGfuiScrollList *scrollist;
338  tGfuiListElement *elt;
339  char *name;
340  int i;
341 
342  object = gfuiGetObject(scr, Id);
343 
344  if(object == NULL) {
345  return (char *)NULL;
346  }
347 
348  if(object->widget != GFUI_SCROLLIST) {
349  return (char *)NULL;
350  }
351 
352  scrollist = &(object->u.scrollist);
353 
354  if((index < 0) || (index > scrollist->nbElts - 1)) {
355  return (char *)NULL;
356  }
357 
358  if(scrollist->elts == NULL) {
359  return (char *)NULL;
360  }
361 
362  elt = scrollist->elts;
363  i = 0;
364 
365  do {
366  elt = elt->next;
367 
368  if(i == index) {
369  break;
370  }
371 
372  i++;
373  } while(elt != scrollist->elts);
374 
375  name = elt->name;
376  *userData = elt->userData;
377 
378  return name;
379 }
380 
389 char *
390 GfuiScrollListExtractSelectedElement(void *scr, int Id, void **userData)
391 {
392  tGfuiObject *object;
393  tGfuiScrollList *scrollist;
394  tGfuiListElement *elt;
395  char *name;
396 
397  object = gfuiGetObject(scr, Id);
398 
399  if(object == NULL) {
400  return (char *)NULL;
401  }
402 
403  if(object->widget != GFUI_SCROLLIST) {
404  return (char *)NULL;
405  }
406 
407  scrollist = &(object->u.scrollist);
408 
409  if(scrollist->selectedElt == -1) {
410  return (char *)NULL;
411  }
412 
413  elt = gfuiScrollListRemElt(scrollist, scrollist->selectedElt);
414 
415  scrollist->nbElts--;
416 
417  if(scrollist->selectedElt > scrollist->nbElts - 1) {
418  scrollist->selectedElt--;
419  }
420 
421  name = elt->name;
422  *userData = elt->userData;
423  free(elt);
424 
425  return name;
426 }
427 
437 char *
438 GfuiScrollListExtractElement(void *scr, int Id, int index, void **userData)
439 {
440  tGfuiObject *object;
441  tGfuiScrollList *scrollist;
442  tGfuiListElement *elt;
443  char *name;
444 
445  object = gfuiGetObject(scr, Id);
446 
447  if(object == NULL) {
448  return (char *)NULL;
449  }
450 
451  if(object->widget != GFUI_SCROLLIST) {
452  return (char *)NULL;
453  }
454 
455  scrollist = &(object->u.scrollist);
456 
457  if((index < 0) || (index > scrollist->nbElts - 1)) {
458  return (char *)NULL;
459  }
460 
461  elt = gfuiScrollListRemElt(scrollist, index);
462 
463  scrollist->nbElts--;
464 
465  if(scrollist->selectedElt > scrollist->nbElts - 1) {
466  scrollist->selectedElt--;
467  }
468 
469  name = elt->name;
470  *userData = elt->userData;
471  free(elt);
472 
473  return name;
474 }
475 
476 
487 int
488 GfuiScrollListInsertElement(void *scr, int Id, char *element, int index, void *userData)
489 {
490  tGfuiObject *object;
491  tGfuiScrollList *scrollist;
492  tGfuiListElement *elt;
493 
494  object = gfuiGetObject(scr, Id);
495 
496  if(object == NULL) {
497  return -1;
498  }
499 
500  if(object->widget != GFUI_SCROLLIST) {
501  return -1;
502  }
503 
504  scrollist = &(object->u.scrollist);
505 
506  elt = (tGfuiListElement *)calloc(1, sizeof(tGfuiListElement));
507  elt->name = element;
508  elt->label = elt->name; /* TODO LENGTH !!!!!*/
509  elt->userData = userData;
510  elt->index = index;
511 
512  gfuiScrollListInsElt(scrollist, elt, index);
513 
514  scrollist->nbElts++;
515 
516  if(scrollist->scrollBar) {
517  GfuiScrollBarPosSet(scr, scrollist->scrollBar, 0, MAX(scrollist->nbElts - scrollist->nbVisible, 0),
518  scrollist->nbVisible, scrollist->firstVisible);
519  }
520 
521  return 0;
522 }
523 
524 
525 void
527 {
528  tGfuiScrollList *scrollist;
529  tGfuiListElement *elt;
530  float *fgColor;
531  float *bgColor;
532  const int BUFSIZE = 256;
533  char buf[BUFSIZE];
534  int w, h, x, y;
535  int index;
536 
537  scrollist = &(obj->u.scrollist);
538 
539  fgColor = scrollist->fgColor[0];
540  bgColor = scrollist->bgColor[0];
541 
542  if(bgColor[3] != 0.0) {
543  glBegin(GL_QUADS);
544  glColor4fv(bgColor);
545  glVertex2i(obj->xmin, obj->ymin);
546  glVertex2i(obj->xmin, obj->ymax);
547  glVertex2i(obj->xmax, obj->ymax);
548  glVertex2i(obj->xmax, obj->ymin);
549  glEnd();
550  }
551 
552  glBegin(GL_LINE_STRIP);
553  glColor4fv(fgColor);
554  glVertex2i(obj->xmin, obj->ymin);
555  glVertex2i(obj->xmin, obj->ymax);
556  glVertex2i(obj->xmax, obj->ymax);
557  glVertex2i(obj->xmax, obj->ymin);
558  glVertex2i(obj->xmin, obj->ymin);
559  glEnd();
560 
561 
562  h = scrollist->font->getDescender() + scrollist->font->getHeight();
563  x = obj->xmin;
564  y = obj->ymax;
565  index = 0;
566  elt = scrollist->elts;
567 
568  if(elt != NULL) {
569  if(scrollist->nbElts < 100) {
570  snprintf(buf, BUFSIZE, " 00 ");
571  } else {
572  snprintf(buf, BUFSIZE, " 000 ");
573  }
574 
575  w = scrollist->font->getWidth((const char *)buf);
576 
577  do {
578  elt = elt->next;
579 
580  if(index < scrollist->firstVisible) {
581  index++;
582  continue;
583  }
584 
585  if(index == scrollist->selectedElt) {
586  glColor4fv(scrollist->fgSelectColor[0]);
587  } else {
588  glColor4fv(scrollist->fgColor[0]);
589  }
590 
591  index++;
592 
593  if(index > (scrollist->firstVisible + scrollist->nbVisible)) {
594  break;
595  }
596 
597  y -= h;
598  snprintf(buf, BUFSIZE, " %d", index);
599  gfuiPrintString(x, y, scrollist->font, buf);
600  gfuiPrintString(x + w, y, scrollist->font, elt->label);
601  } while(elt != scrollist->elts);
602  }
603 
604 
605 }
606 
607 void
609 {
610  tGfuiObject *curObject;
611 
612  curObject = GfuiScreen->objects;
613 
614  if(curObject != NULL) {
615  do {
616  curObject = curObject->next;
617 
618  if(curObject->widget == GFUI_SCROLLIST) {
619  curObject->u.scrollist.selectedElt = -1;
620  }
621  } while(curObject != GfuiScreen->objects);
622  }
623 
624 }
625 
626 
627 void
629 {
630  tGfuiObject *object;
631  tGfuiScrollList *scrollist;
632  int relY;
633 
634  if(mouse == 0) {
635  /* button down */
637  object = GfuiScreen->hasFocus;
638  scrollist = &(object->u.scrollist);
639  relY = object->ymax - GfuiMouse.Y;
640  relY = scrollist->firstVisible + relY / (scrollist->font->getDescender() + scrollist->font->getHeight()) + 1;
641 
642  if(relY > scrollist->nbElts) {
643  scrollist->selectedElt = -1;
644  return;
645  }
646 
647  scrollist->selectedElt = relY - 1;
648 
649  if(scrollist->onSelect) {
650  scrollist->onSelect(scrollist->userDataOnSelect);
651  }
652  }
653 }
654 
663 int
664 GfuiScrollListMoveSelectedElement(void *scr, int Id, int delta)
665 {
666  tGfuiObject *object;
667  tGfuiScrollList *scrollist;
668  int newPos;
669  tGfuiListElement *elt;
670 
671  object = gfuiGetObject(scr, Id);
672 
673  if(object == NULL) {
674  return -1;
675  }
676 
677  if(object->widget != GFUI_SCROLLIST) {
678  return -1;
679  }
680 
681  scrollist = &(object->u.scrollist);
682 
683  if(scrollist->selectedElt == -1) {
684  return -1;
685  }
686 
687  newPos = scrollist->selectedElt + delta;
688 
689  if((newPos < 0) || (newPos > scrollist->nbElts - 1)) {
690  return -1;
691  }
692 
693  elt = gfuiScrollListRemElt(scrollist, scrollist->selectedElt);
694 
695  gfuiScrollListInsElt(scrollist, elt, newPos);
696 
697  scrollist->selectedElt = newPos;
698 
699  if(scrollist->selectedElt == scrollist->firstVisible + scrollist->nbVisible) {
700  /* Scroll down */
701  if(scrollist->firstVisible + scrollist->nbVisible < scrollist->nbElts) {
702  scrollist->firstVisible++;
703 
704  if(scrollist->scrollBar) {
705  GfuiScrollBarPosSet(GfuiScreen, scrollist->scrollBar, 0, MAX(scrollist->nbElts - scrollist->nbVisible, 0),
706  scrollist->nbVisible, scrollist->firstVisible);
707  }
708  }
709  } else if(scrollist->selectedElt < scrollist->firstVisible) {
710  /* Scroll down */
711  if(scrollist->firstVisible > 0) {
712  scrollist->firstVisible--;
713 
714  if(scrollist->scrollBar) {
715  GfuiScrollBarPosSet(GfuiScreen, scrollist->scrollBar, 0, MAX(scrollist->nbElts - scrollist->nbVisible, 0),
716  scrollist->nbVisible, scrollist->firstVisible);
717  }
718  }
719  }
720 
721  return 0;
722 }
723 
724 
725 void
727 {
728  tGfuiScrollList *scrollist;
729  tGfuiListElement *elt;
730 
731  scrollist = &(curObject->u.scrollist);
732 
733  while((elt = gfuiScrollListRemElt(scrollist, 0)) != NULL) {
734  free(elt);
735  }
736 
737  free(curObject);
738 }
739 
void gfuiReleaseScrollist(tGfuiObject *curObject)
char * GfuiScrollListExtractSelectedElement(void *scr, int Id, void **userData)
Extract the selected element from the scroll list (removed).
static void gfuiScroll(tScrollBarInfo *sinfo)
void * userDataOnSelect
Definition: gui.h:162
float * fgColor[3]
Definition: gui.h:151
void gfuiDrawScrollist(tGfuiObject *obj)
int nbVisible
Definition: gui.h:158
tGfuiListElement * elts
Definition: gui.h:155
void GfuiScrollBarPosSet(void *scr, int id, int min, int max, int len, int start)
Set new values for position.
static void onSelect(void *)
int GfuiScrollListInsertElement(void *scr, int Id, char *element, int index, void *userData)
Insert an element in a scroll list.
void gfuiScrollListPrevElt(tGfuiObject *object)
char * GfuiScrollListGetSelectedElement(void *scr, int Id, void **userData)
Get the selected element from the scroll list.
Scroll bar call-back information.
Definition: tgfclient.h:99
void * userData
Associated user data.
Definition: tgfclient.h:102
int GfuiScrollListMoveSelectedElement(void *scr, int Id, int delta)
Move the selected element within the scroll list.
#define GFUI_SB_RIGHT
Definition: tgfclient.h:89
#define GFUI_BGSELSCROLLIST
Definition: gui.h:45
#define GFUI_ALIGN_HR_VB
Definition: tgfclient.h:75
int curId
Definition: gui.h:245
int ymin
Definition: gui.h:205
int scrollBar
Definition: gui.h:160
The Gaming Framework API (client part).
void gfuiScrollListAction(int mouse)
GfuiFontClass * font
Definition: gui.h:154
float * fgSelectColor[3]
Definition: gui.h:153
tfuiCallback onSelect
Definition: gui.h:161
tGfuiScrollList scrollist
Definition: gui.h:212
char * GfuiScrollListExtractElement(void *scr, int Id, int index, void **userData)
Extract the specified element from the scroll list.
#define GFUI_SB_LEFT
Definition: tgfclient.h:90
#define GFUI_SCROLLIST
Definition: tgfclient.h:64
int firstVisible
Definition: gui.h:157
GfuiFontClass * gfuiFont[FONT_NB]
Definition: guifont.cpp:43
#define GFUI_FOCUS_MOUSE_MOVE
Definition: gui.h:133
int xmax
Definition: gui.h:206
#define GFUI_FGSELSCROLLIST
Definition: gui.h:46
struct GfuiListElement * next
Definition: gui.h:143
char * GfuiScrollListGetElement(void *scr, int Id, int index, void **userData)
Get the specified element from the scroll list.
Definition: Endpoint.h:36
#define GFUI_FGSCROLLIST
Definition: gui.h:44
int index
Definition: gui.h:142
tMouseInfo GfuiMouse
Definition: gui.cpp:37
int GfuiScrollBarCreate(void *scr, int x, int y, int align, int width, int orientation, int min, int max, int len, int start, void *userData, tfuiSBCallback onScroll)
Create a new scroll bar.
void gfuiScrollListDeselectAll(void)
union GfuiObject::@17 u
#define GFUI_BGSCROLLIST
Definition: gui.h:43
tGfuiScreen * GfuiScreen
Definition: gui.cpp:35
void(* tfuiCallback)(void *)
Definition: tgfclient.h:105
struct GfuiListElement * prev
Definition: gui.h:144
tGfuiObject * gfuiGetObject(void *scr, int id)
Definition: guiobject.cpp:501
struct GfuiObject * next
Definition: gui.h:217
void gfuiAddObject(tGfuiScreen *screen, tGfuiObject *object)
Definition: guiobject.cpp:485
char * label
Definition: gui.h:139
#define GFUI_ALIGN_HL_VB
Definition: tgfclient.h:69
float GfuiColor[GFUI_COLORNB][4]
Definition: gui.cpp:41
static void gfuiScrollListInsElt(tGfuiScrollList *scrollist, tGfuiListElement *elt, int index)
void gfuiScrListInit(void)
float * bgColor[3]
Definition: gui.h:150
static Vector y[4]
Definition: Convex.cpp:56
int getHeight() const
Definition: guifont.cpp:261
int pos
Current scroll bar position.
Definition: tgfclient.h:101
void gfuiScrollListNextElt(tGfuiObject *object)
int GfuiScrollListCreate(void *scr, int font, int x, int y, int align, int width, int height, int scrollBarPos, void *userDataOnSelect, tfuiCallback onSelect)
Create a new scroll list.
tGfuiObject * hasFocus
Definition: gui.h:244
int ymax
Definition: gui.h:206
tGfuiObject * objects
Definition: gui.h:243
int selectedElt
Definition: gui.h:159
#define GFUI_SB_NONE
Definition: tgfclient.h:88
void * userData
Definition: gui.h:140
static tGfuiListElement * gfuiScrollListRemElt(tGfuiScrollList *scrollist, int index)
void gfuiPrintString(int x, int y, GfuiFontClass *font, const char *string)
Definition: guiobject.cpp:32
int nbElts
Definition: gui.h:156
int widget
Definition: gui.h:199
char * name
Definition: gui.h:138
int xmin
Definition: gui.h:205
float * bgSelectColor[3]
Definition: gui.h:152
#define GFUI_VERT_SCROLLBAR
Definition: tgfclient.h:96
int getWidth(const char *text)
Definition: guifont.cpp:222
int getDescender() const
Definition: guifont.cpp:272