TORCS  1.3.9
The Open Racing Car Simulator
guiedit.cpp
Go to the documentation of this file.
1 /***************************************************************************
2 
3  file : guiedit.cpp
4  created : Mon Apr 24 10:23:28 CEST 2000
5  copyright : (C) 2000-2014 by Eric Espie, Bernhard Wymann
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 #ifdef WIN32
29 #include <windows.h>
30 #endif
31 #include <tgfclient.h>
32 #include "gui.h"
33 #include "guifont.h"
34 
35 void
37 {
38 }
39 
56 int
57 GfuiEditboxCreate(void *scr, const char *text, int font, int x, int y, int width, int maxlen,
58  void *userDataOnFocus, tfuiCallback onFocus, tfuiCallback onFocusLost, int margin)
59 {
60  tGfuiEditbox *editbox;
61  tGfuiLabel *label;
62  tGfuiObject *object;
63  tGfuiScreen *screen = (tGfuiScreen*)scr;
64 
65 
66  object = (tGfuiObject*)calloc(1, sizeof(tGfuiObject));
67  object->widget = GFUI_EDITBOX;
68  object->focusMode = GFUI_FOCUS_MOUSE_CLICK;
69  object->id = screen->curId++;
70  object->visible = 1;
71 
72  editbox = &(object->u.editbox);
73  editbox->state = GFUI_BTN_RELEASED;
74  editbox->userDataOnFocus = userDataOnFocus;
75  editbox->onFocus = onFocus;
76  editbox->onFocusLost = onFocusLost;
77 
78  editbox->bgColor[0] = &(GfuiColor[GFUI_BGBTNDISABLED][0]);
79  editbox->bgColor[1] = &(GfuiColor[GFUI_BGBTNENABLED][0]);
80  editbox->bgColor[2] = &(GfuiColor[GFUI_BGBTNCLICK][0]);
81  editbox->bgFocusColor[0] = &(GfuiColor[GFUI_BGBTNDISABLED][0]);
82  editbox->bgFocusColor[1] = &(GfuiColor[GFUI_BGBTNFOCUS][0]);
83  editbox->bgFocusColor[2] = &(GfuiColor[GFUI_BGBTNCLICK][0]);
84  editbox->fgColor[0] = &(GfuiColor[GFUI_BTNDISABLED][0]);
85  editbox->fgColor[1] = &(GfuiColor[GFUI_BTNENABLED][0]);
86  editbox->fgColor[2] = &(GfuiColor[GFUI_BTNCLICK][0]);
87  editbox->fgFocusColor[0] = &(GfuiColor[GFUI_BTNDISABLED][0]);
88  editbox->fgFocusColor[1] = &(GfuiColor[GFUI_BTNFOCUS][0]);
89  editbox->fgFocusColor[2] = &(GfuiColor[GFUI_BTNCLICK][0]);
90  editbox->cursorColor[0] = &(GfuiColor[GFUI_EDITCURSORCLR][0]);
91  editbox->cursorColor[1] = &(GfuiColor[GFUI_EDITCURSORCLR][1]);
92  editbox->cursorColor[2] = &(GfuiColor[GFUI_EDITCURSORCLR][2]);
93 
94 
95  label = &(editbox->label);
96  if (maxlen == 0) maxlen = strlen(text);
97  label->text = (char*)calloc(1, maxlen+1);
98  strncpy(label->text, text, maxlen);
99  label->text[maxlen] = '\0';
100  label->font = gfuiFont[font];
101  label->maxlen = maxlen;
102 
103  if (width == 0) {
104  char *buf;
105  int i;
106  buf = (char*)malloc(maxlen+1);
107  if (buf == NULL) return -1; // Memory leak does not matter, this must not happen
108  for (i = 0; i < maxlen; i++) buf[i] = 'W';
109  buf[i] = '\0';
110  width = gfuiFont[font]->getWidth((const char *)buf);
111  free(buf);
112  }
113 
114  label->align = GFUI_ALIGN_HL_VC;
115  label->x = object->xmin = x;
116  label->y = y - 2 * gfuiFont[font]->getDescender();
117  object->ymin = y;
118  object->xmax = x + width;
119  object->ymax = y + gfuiFont[font]->getHeight() - gfuiFont[font]->getDescender();
120  editbox->cursory1 = object->ymin + 2;
121  editbox->cursory2 = object->ymax - 2;
122  editbox->cursorx = label->x;
123 
124  object->xmin -= margin;
125  object->xmax += margin;
126 
127  gfuiAddObject(screen, object);
128  return object->id;
129 }
130 
131 
137 int
139 {
140  tGfuiObject *curObject;
141 
142  if (GfuiScreen != NULL) {
143  curObject = GfuiScreen->objects;
144  if (curObject != NULL) {
145  do {
146  curObject = curObject->next;
147  if (curObject->focus) {
148  if (curObject->widget == GFUI_EDITBOX) {
149  return curObject->id;
150  }
151  return -1;
152  }
153  } while (curObject != GfuiScreen->objects);
154  }
155  }
156  return -1;
157 }
158 
159 
160 void
162 {
163  tGfuiLabel *label;
164  tGfuiEditbox *editbox;
165  float *fgColor;
166  float *bgColor;
167 
168  editbox = &(obj->u.editbox);
169  if (obj->state == GFUI_DISABLE) {
170  editbox->state = GFUI_BTN_DISABLE;
171  } else {
172  editbox->state = GFUI_BTN_RELEASED;
173  }
174  if (obj->focus) {
175  fgColor = editbox->fgFocusColor[editbox->state];
176  bgColor = editbox->bgFocusColor[editbox->state];
177  } else {
178  fgColor = editbox->fgColor[editbox->state];
179  bgColor = editbox->bgColor[editbox->state];
180  }
181 
182  glColor4fv(bgColor);
183  glBegin(GL_QUADS);
184  glVertex2i(obj->xmin, obj->ymin);
185  glVertex2i(obj->xmin, obj->ymax);
186  glVertex2i(obj->xmax, obj->ymax);
187  glVertex2i(obj->xmax, obj->ymin);
188  glEnd();
189 
190  glColor4fv(fgColor);
191  glBegin(GL_LINE_STRIP);
192  glVertex2i(obj->xmin, obj->ymin);
193  glVertex2i(obj->xmin, obj->ymax);
194  glVertex2i(obj->xmax, obj->ymax);
195  glVertex2i(obj->xmax, obj->ymin);
196  glVertex2i(obj->xmin, obj->ymin);
197  glEnd();
198 
199  label = &(editbox->label);
200  glColor4fv(fgColor);
201  gfuiPrintString(label->x, label->y, label->font, label->text);
202 
203  if ((obj->state != GFUI_DISABLE) && (obj->focus)) {
204  /* draw cursor */
205  glColor3fv(editbox->cursorColor[editbox->state]);
206  glBegin(GL_LINES);
207  glVertex2i(editbox->cursorx, editbox->cursory1);
208  glVertex2i(editbox->cursorx, editbox->cursory2);
209  glEnd();
210  }
211 }
212 
213 
214 void
216 {
217  tGfuiObject *object;
218  tGfuiLabel *label;
219  tGfuiEditbox *editbox;
220  int relX;
221  char buf[256];
222  uint i;
223 
224  object = GfuiScreen->hasFocus;
225  if (object->state == GFUI_DISABLE) {
226  return;
227  }
228 
229  if (mouse == 2) { /* enter key */
231  } else if (mouse == 0) { /* mouse down */
232  editbox = &(object->u.editbox);
233  label = &(editbox->label);
234  /* Set the cursor position */
235  relX = GfuiMouse.X - label->x;
236  for (i = 0; i < strlen(label->text); i++){
237  buf[i] = label->text[i];
238  buf[i+1] = '\0';
239  if (relX < label->font->getWidth((const char *)buf)) {
240  break;
241  }
242  }
243  editbox->cursorIdx = i;
244  if (i == 0) {
245  editbox->cursorx = label->x;
246  } else {
247  buf[i] = '\0';
248  editbox->cursorx = label->x + label->font->getWidth((const char *)buf);
249  }
250  }
251 }
252 
253 /* recalc cursorx with cursorIdx */
254 static void
256 {
257  char buf[256];
258  tGfuiEditbox *editbox;
259  tGfuiLabel *label;
260 
261  editbox = &(obj->u.editbox);
262  label = &(editbox->label);
263  strncpy(buf, label->text, editbox->cursorIdx);
264  buf[editbox->cursorIdx] = '\0';
265  editbox->cursorx = label->x + label->font->getWidth((const char *)buf);
266 }
267 
268 
269 void
270 gfuiEditboxKey(tGfuiObject *obj, int key, int modifier)
271 {
272  tGfuiEditbox *editbox;
273  tGfuiLabel *label;
274  char *p1, *p2;
275  int i1, i2;
276 
277  if (obj->state == GFUI_DISABLE) {
278  return;
279  }
280 
281  editbox = &(obj->u.editbox);
282  label = &(editbox->label);
283 
284  switch (modifier) {
285  case 0:
286  case GLUT_ACTIVE_SHIFT:
287  switch (key) {
288  case 256 + GLUT_KEY_RIGHT:
289  editbox->cursorIdx++;
290  if (editbox->cursorIdx > (int)strlen(label->text)) {
291  editbox->cursorIdx--;
292  }
293  break;
294  case 256 + GLUT_KEY_LEFT:
295  editbox->cursorIdx--;
296  if (editbox->cursorIdx < 0) {
297  editbox->cursorIdx = 0;
298  }
299  break;
300  case 256 + GLUT_KEY_HOME:
301  editbox->cursorIdx = 0;
302  break;
303  case 256 + GLUT_KEY_END:
304  editbox->cursorIdx = (int)strlen(label->text);
305  break;
306  case 0x7F : /* DEL */
307  if (editbox->cursorIdx < (int)strlen(label->text)) {
308  p1 = &(label->text[editbox->cursorIdx]);
309  p2 = &(label->text[editbox->cursorIdx+1]);
310  while ( *p1 != '\0' ) {
311  *p1++ = *p2++;
312  }
313  }
314  break;
315  case '\b' : /* Backspace */
316  if (editbox->cursorIdx > 0) {
317  p1 = &(label->text[editbox->cursorIdx-1]);
318  p2 = &(label->text[editbox->cursorIdx]);
319  while ( *p1 != '\0' ) {
320  *p1++ = *p2++;
321  }
322  editbox->cursorIdx--;
323  }
324  break;
325  }
326  if (key >= ' ' && key < 127) {
327  if ((int)strlen(label->text) < label->maxlen) {
328  i2 = (int)strlen(label->text) + 1;
329  i1 = i2 - 1;
330  while (i2 > editbox->cursorIdx) {
331  label->text[i2] = label->text[i1];
332  i1--;
333  i2--;
334  }
335  label->text[editbox->cursorIdx] = key;
336  editbox->cursorIdx++;
337  }
338  }
339  break;
340 
341  case GLUT_ACTIVE_CTRL:
342  break;
343 
344  case GLUT_ACTIVE_ALT:
345  break;
346  }
347 
349 }
350 
357 char *
358 GfuiEditboxGetString(void *scr, int id)
359 {
360  tGfuiObject *curObject;
361  tGfuiEditbox *editbox;
362  tGfuiLabel *label;
363 
364  curObject = gfuiGetObject(scr, id);
365 
366  if ((curObject == NULL) || (curObject->widget != GFUI_EDITBOX)) {
367  return (char*)NULL;
368  }
369 
370  editbox = &(curObject->u.editbox);
371  label = &(editbox->label);
372 
373  return label->text;
374 }
375 
383 void GfuiEditboxSetString(void *scr, int id, const char *text)
384 {
385  tGfuiObject *curObject;
386  tGfuiEditbox *editbox;
387  tGfuiLabel *label;
388 
389  curObject = gfuiGetObject(scr, id);
390 
391  if ((curObject == NULL) || (curObject->widget != GFUI_EDITBOX)) {
392  return;
393  }
394 
395  editbox = &(curObject->u.editbox);
396  label = &(editbox->label);
397 
398  strncpy(label->text, text, label->maxlen);
399  label->text[label->maxlen] = '\0';
400 }
401 
402 
403 void
405 {
406  tGfuiEditbox *editbox;
407  tGfuiLabel *label;
408 
409  editbox = &(curObject->u.editbox);
410  label = &(editbox->label);
411  free(label->text);
412  free(curObject);
413 }
414 
#define GFUI_BGBTNENABLED
Definition: gui.h:31
int focus
Definition: gui.h:203
void gfuiEditboxInit(void)
Definition: guiedit.cpp:36
char * GfuiEditboxGetString(void *scr, int id)
Get the string.
Definition: guiedit.cpp:358
int GfuiEditboxGetFocused(void)
Get the Id of the editbox focused in the current screen.
Definition: guiedit.cpp:138
int align
Definition: gui.h:85
tGfuiEditbox editbox
Definition: gui.h:214
tfuiCallback onFocus
Definition: gui.h:188
void gfuiDrawEditbox(tGfuiObject *obj)
Definition: guiedit.cpp:161
int id
Definition: gui.h:200
void gfuiReleaseEditbox(tGfuiObject *curObject)
Definition: guiedit.cpp:404
int y
Definition: gui.h:84
float * fgFocusColor[3]
Definition: gui.h:181
int GfuiEditboxCreate(void *scr, const char *text, int font, int x, int y, int width, int maxlen, void *userDataOnFocus, tfuiCallback onFocus, tfuiCallback onFocusLost, int margin)
Add a editbox to a screen.
Definition: guiedit.cpp:57
#define GFUI_BGBTNFOCUS
Definition: gui.h:29
GfuiFontClass * font
Definition: gui.h:83
int curId
Definition: gui.h:245
int ymin
Definition: gui.h:205
The Gaming Framework API (client part).
float * fgColor[3]
Definition: gui.h:179
int state
Definition: gui.h:182
#define GFUI_EDITBOX
Definition: tgfclient.h:66
GfuiFontClass * gfuiFont[FONT_NB]
Definition: guifont.cpp:43
void GfuiEditboxSetString(void *scr, int id, const char *text)
Set a new string.
Definition: guiedit.cpp:383
int xmax
Definition: gui.h:206
float * cursorColor[3]
Definition: gui.h:177
static void onFocusLost(void *)
#define GFUI_BTN_RELEASED
Definition: gui.h:91
#define GFUI_ALIGN_HL_VC
Definition: tgfclient.h:70
tMouseInfo GfuiMouse
Definition: gui.cpp:37
#define GFUI_EDITCURSORCLR
Definition: gui.h:47
int x
Definition: gui.h:84
union GfuiObject::@17 u
char * text
Definition: gui.h:80
int cursorx
Definition: gui.h:183
tGfuiScreen * GfuiScreen
Definition: gui.cpp:35
void(* tfuiCallback)(void *)
Definition: tgfclient.h:105
#define GFUI_FOCUS_MOUSE_CLICK
Definition: gui.h:134
tGfuiObject * gfuiGetObject(void *scr, int id)
Definition: guiobject.cpp:501
struct GfuiObject * next
Definition: gui.h:217
void gfuiEditboxAction(int mouse)
Definition: guiedit.cpp:215
float * bgFocusColor[3]
Definition: gui.h:180
#define GFUI_BTNDISABLED
Definition: gui.h:36
static void gfuiEditboxRecalcCursor(tGfuiObject *obj)
Definition: guiedit.cpp:255
void gfuiAddObject(tGfuiScreen *screen, tGfuiObject *object)
Definition: guiobject.cpp:485
#define GFUI_DISABLE
Definition: tgfclient.h:161
#define GFUI_BTNCLICK
Definition: gui.h:34
#define GFUI_BGBTNDISABLED
Definition: gui.h:32
float GfuiColor[GFUI_COLORNB][4]
Definition: gui.cpp:41
float * bgColor[3]
Definition: gui.h:178
void * userDataOnFocus
Definition: gui.h:187
static Vector y[4]
Definition: Convex.cpp:56
int getHeight() const
Definition: guifont.cpp:261
Definition: gui.h:78
int maxlen
Definition: gui.h:86
int cursory1
Definition: gui.h:184
tGfuiObject * hasFocus
Definition: gui.h:244
int ymax
Definition: gui.h:206
#define GFUI_BTNFOCUS
Definition: gui.h:33
tGfuiObject * objects
Definition: gui.h:243
int cursory2
Definition: gui.h:185
#define GFUI_BTN_DISABLE
Definition: gui.h:90
int state
Definition: gui.h:204
tfuiCallback onFocusLost
Definition: gui.h:189
void gfuiPrintString(int x, int y, GfuiFontClass *font, const char *string)
Definition: guiobject.cpp:32
void gfuiEditboxKey(tGfuiObject *obj, int key, int modifier)
Definition: guiedit.cpp:270
#define GFUI_BGBTNCLICK
Definition: gui.h:30
tGfuiLabel label
Definition: gui.h:176
#define GFUI_BTNENABLED
Definition: gui.h:35
int widget
Definition: gui.h:199
int xmin
Definition: gui.h:205
int getWidth(const char *text)
Definition: guifont.cpp:222
int cursorIdx
Definition: gui.h:186
int getDescender() const
Definition: guifont.cpp:272
void gfuiSelectNext(void *)
Definition: guiobject.cpp:311