~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/box2d/glui/glui_list.cpp

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
  
 
3
  GLUI User Interface Toolkit
 
4
  ---------------------------
 
5
 
 
6
     glui_list.cpp - GLUI_List control class
 
7
 
 
8
 
 
9
          --------------------------------------------------
 
10
 
 
11
  Copyright (c) 2004 John Kew
 
12
 
 
13
  This program is freely distributable without licensing fees and is
 
14
  provided without guarantee or warrantee expressed or implied. This
 
15
  program is -not- in the public domain.
 
16
 
 
17
*****************************************************************************/
 
18
 
 
19
#include "glui_internal_control.h"
 
20
#include <cmath>
 
21
#include <sys/timeb.h>
 
22
 
 
23
/****************************** GLUI_List::GLUI_List() **********/
 
24
 
 
25
GLUI_List::GLUI_List( GLUI_Node *parent, bool scroll,
 
26
                      int id, GLUI_CB callback
 
27
                      /*,GLUI_Control *object 
 
28
                      GLUI_InterObject_CB obj_cb*/)
 
29
{
 
30
  common_construct(parent, NULL, scroll, id, callback/*, object, obj_cb*/);
 
31
}
 
32
 
 
33
/****************************** GLUI_List::GLUI_List() **********/
 
34
 
 
35
GLUI_List::GLUI_List( GLUI_Node *parent,
 
36
                      GLUI_String& live_var, bool scroll, 
 
37
                      int id, 
 
38
                      GLUI_CB callback 
 
39
                      /* ,GLUI_Control *object
 
40
                      ,GLUI_InterObject_CB obj_cb*/ )
 
41
{
 
42
  common_construct(parent, &live_var, scroll, id, callback/*, object, obj_cb*/);
 
43
}
 
44
 
 
45
/****************************** GLUI_List::common_construct() **********/
 
46
 
 
47
void GLUI_List::common_construct(
 
48
  GLUI_Node *parent,
 
49
  GLUI_String* data, bool scroll, 
 
50
  int id, 
 
51
  GLUI_CB callback
 
52
  /*,GLUI_Control *object
 
53
  , GLUI_InterObject_CB obj_cb*/)
 
54
{
 
55
  common_init();
 
56
  GLUI_Node *list_panel = parent;
 
57
 
 
58
  if (scroll) {
 
59
    GLUI_Panel *p = new GLUI_Panel(parent,"",GLUI_PANEL_NONE);
 
60
    p->x_off = 1;
 
61
    list_panel = p;
 
62
  }
 
63
  this->ptr_val     = data;
 
64
  if (data) {
 
65
    this->live_type = GLUI_LIVE_STRING;
 
66
  }
 
67
  this->user_id     = id;
 
68
  this->callback    = callback;
 
69
  this->name        = "list";
 
70
  list_panel->add_control( this );
 
71
  if (scroll) 
 
72
  {
 
73
    new GLUI_Column(list_panel, false);
 
74
    scrollbar = 
 
75
      new GLUI_Scrollbar(list_panel,
 
76
                         "scrollbar",
 
77
                         GLUI_SCROLL_VERTICAL,
 
78
                         GLUI_SCROLL_INT);
 
79
    scrollbar->set_object_callback(GLUI_List::scrollbar_callback, this);
 
80
    scrollbar->set_alignment(GLUI_ALIGN_LEFT);
 
81
    // scrollbar->can_activate = false; //kills ability to mouse drag too
 
82
  }
 
83
  init_live();
 
84
}
 
85
 
 
86
/****************************** GLUI_List::mouse_down_handler() **********/
 
87
int    GLUI_List::mouse_down_handler( int local_x, int local_y )
 
88
{
 
89
  int tmp_line;
 
90
  unsigned long int ms;
 
91
  timeb time;
 
92
  ftime(&time);
 
93
  ms = time.millitm + (time.time)*1000;
 
94
 
 
95
  tmp_line = find_line( local_x-x_abs, local_y-y_abs-5 );  
 
96
  if ( tmp_line == -1 ) {
 
97
    if ( glui )
 
98
      glui->deactivate_current_control(  );
 
99
    return false;
 
100
  }
 
101
 
 
102
  if (tmp_line < num_lines) {
 
103
    curr_line = tmp_line;
 
104
    if (scrollbar)
 
105
      scrollbar->set_int_val(curr_line);
 
106
    this->execute_callback();
 
107
    if (associated_object != NULL)
 
108
      if (cb_click_type == GLUI_SINGLE_CLICK) {
 
109
        if (obj_cb) {
 
110
          // obj_cb(associated_object, user_id);
 
111
          obj_cb(this);
 
112
        }
 
113
      } else {
 
114
        if (last_line == curr_line && (ms - last_click_time) < 300) {
 
115
          //obj_cb(associated_object, user_id);
 
116
          obj_cb(this);
 
117
        } else {
 
118
          last_click_time = ms;
 
119
          last_line = curr_line;
 
120
        }
 
121
      }
 
122
    if ( can_draw())
 
123
      update_and_draw_text();
 
124
  }
 
125
 
 
126
  return true;
 
127
}
 
128
 
 
129
 
 
130
 
 
131
 
 
132
/******************************** GLUI_List::mouse_up_handler() **********/
 
133
 
 
134
int    GLUI_List::mouse_up_handler( int local_x, int local_y, bool inside )
 
135
{
 
136
  return false;
 
137
}
 
138
 
 
139
 
 
140
/***************************** GLUI_List::mouse_held_down_handler() ******/
 
141
 
 
142
int    GLUI_List::mouse_held_down_handler( int local_x, int local_y,
 
143
                           bool new_inside)
 
144
{
 
145
  return false;
 
146
}
 
147
 
 
148
 
 
149
/****************************** GLUI_List::key_handler() **********/
 
150
 
 
151
int    GLUI_List::key_handler( unsigned char key,int modifiers )
 
152
{
 
153
 
 
154
 
 
155
  draw_text_only = false;  /** Well, hack is not yet working **/
 
156
  update_and_draw_text();
 
157
  draw_text_only = false;
 
158
 
 
159
  return true;
 
160
}
 
161
 
 
162
 
 
163
/****************************** GLUI_List::activate() **********/
 
164
 
 
165
void    GLUI_List::activate( int how )
 
166
{
 
167
//   if ( debug )
 
168
//     dump( stdout, "-> ACTIVATE" );
 
169
  active = true;
 
170
 
 
171
  if ( how == GLUI_ACTIVATE_MOUSE )
 
172
    return;  /* Don't select everything if activated with mouse */
 
173
 
 
174
}
 
175
 
 
176
 
 
177
/****************************** GLUI_List::deactivate() **********/
 
178
 
 
179
void    GLUI_List::deactivate( void )
 
180
{
 
181
  active = false;
 
182
  redraw();
 
183
}
 
184
 
 
185
/****************************** GLUI_List::draw() **********/
 
186
 
 
187
void    GLUI_List::draw( int x, int y )
 
188
{
 
189
  int line = 0;
 
190
  int box_width;
 
191
  GLUI_List_Item *item;
 
192
 
 
193
  GLUI_DRAWINGSENTINAL_IDIOM
 
194
 
 
195
  /* Bevelled Border */
 
196
  glBegin( GL_LINES );
 
197
  glColor3f( .5, .5, .5 );
 
198
  glVertex2i( 0, 0 );     glVertex2i( w, 0 );
 
199
  glVertex2i( 0, 0 );     glVertex2i( 0, h );     
 
200
 
 
201
  glColor3f( 1., 1., 1. );
 
202
  glVertex2i( 0, h );     glVertex2i( w, h );
 
203
  glVertex2i( w, h );     glVertex2i( w, 0 );
 
204
 
 
205
  if ( enabled )
 
206
    glColor3f( 0., 0., 0. );
 
207
  else
 
208
    glColor3f( .25, .25, .25 );
 
209
  glVertex2i( 1, 1 );     glVertex2i( w-1, 1 );
 
210
  glVertex2i( 1, 1 );     glVertex2i( 1, h-1 );
 
211
 
 
212
  glColor3f( .75, .75, .75 );
 
213
  glVertex2i( 1, h-1 );     glVertex2i( w-1, h-1 );
 
214
  glVertex2i( w-1, h-1 );   glVertex2i( w-1, 1 );
 
215
  glEnd();
 
216
 
 
217
  /* Draw Background if enabled*/
 
218
  if (enabled) {
 
219
    glColor3f( 1., 1., 1. );
 
220
    glDisable( GL_CULL_FACE );
 
221
    glBegin( GL_QUADS );
 
222
    glVertex2i( 2, 2 );     glVertex2i( w-2, 2 );
 
223
    glVertex2i( w-2, h-2 );               glVertex2i(2, h-2 );
 
224
    glEnd();
 
225
  } else {
 
226
    glColor3f( .8, .8, .8 );
 
227
    glDisable( GL_CULL_FACE );
 
228
    glBegin( GL_QUADS );
 
229
    glVertex2i( 2, 2 );     glVertex2i( w-2, 2 );
 
230
    glVertex2i( w-2, h-2 );               glVertex2i(2, h-2 );
 
231
    glEnd();
 
232
  }
 
233
 
 
234
  /* Figure out how wide the box is */
 
235
  box_width = get_box_width();
 
236
 
 
237
  /* Figure out which lines are visible*/
 
238
 
 
239
  visible_lines = (int)(h-20)/15;
 
240
 
 
241
  item = (GLUI_List_Item *) items_list.first_child();
 
242
 
 
243
  line = 0;
 
244
  while (item) {
 
245
    if (line < start_line) {
 
246
      line++;
 
247
      item = (GLUI_List_Item *) item->next();
 
248
      continue;
 
249
    }
 
250
    if (line >= start_line && line <= (start_line+visible_lines)) {
 
251
      if (curr_line == line)
 
252
        draw_text(item->text.c_str(),1,0,(line - start_line)*15);
 
253
      else
 
254
        draw_text(item->text.c_str(),0,0,(line - start_line)*15);
 
255
    }
 
256
    line++;
 
257
    item = (GLUI_List_Item *) item->next();
 
258
  }
 
259
 
 
260
  if (scrollbar) {
 
261
    scrollbar->set_int_limits(MAX(0,num_lines-visible_lines), 0);
 
262
    glPushMatrix();
 
263
    glTranslatef(scrollbar->x_abs-x_abs, scrollbar->y_abs-y_abs,0.0);
 
264
    scrollbar->draw_scroll();
 
265
    glPopMatrix();
 
266
  }
 
267
}
 
268
 
 
269
/********************************* GLUI_List::draw_text() ****************/
 
270
 
 
271
void    GLUI_List::draw_text(const char *t, int selected, int x, int y )
 
272
{
 
273
  int text_x, i, x_pos;
 
274
  int box_width;
 
275
 
 
276
  GLUI_DRAWINGSENTINAL_IDIOM
 
277
 
 
278
  /** Find where to draw the text **/
 
279
 
 
280
  text_x = 2 + GLUI_LIST_BOXINNERMARGINX;
 
281
 
 
282
  /** Draw selection area dark **/
 
283
  if ( enabled && selected ) {
 
284
    glColor3f( 0.0f, 0.0f, .6f );
 
285
    glBegin( GL_QUADS );
 
286
    glVertex2i(text_x, y+5 );    glVertex2i( w-text_x, y+5 );
 
287
    glVertex2i(w-text_x, y+19 );    glVertex2i(text_x, y+19 );
 
288
    glEnd();
 
289
  }
 
290
  box_width = get_box_width();   
 
291
 
 
292
  if ( !selected || !enabled ) {   /* No current selection */
 
293
    x_pos = text_x;                /*  or control disabled */
 
294
    if ( enabled )
 
295
      glColor3b( 0, 0, 0 );
 
296
    else
 
297
      glColor3b( 32, 32, 32 );
 
298
    
 
299
    glRasterPos2i( text_x, y+15);
 
300
    i = 0;
 
301
    while( t[i] != '\0' && substring_width(t,0,i) < box_width) {
 
302
      glutBitmapCharacter( get_font(), t[i] );
 
303
      x_pos += char_width( t[i] );
 
304
      i++;
 
305
    }
 
306
  }
 
307
  else { /* There is a selection */
 
308
    i = 0;
 
309
    x_pos = text_x;
 
310
    glColor3f( 1., 1., 1. );
 
311
    glRasterPos2i( text_x, y+15);
 
312
    while( t[i] != '\0' && substring_width(t,0,i) < box_width) {
 
313
      glutBitmapCharacter( get_font(), t[i] );
 
314
      x_pos += char_width( t[i] );
 
315
      i++;
 
316
    }
 
317
  }
 
318
}
 
319
 
 
320
 
 
321
int GLUI_List::find_line(int x, int y) {
 
322
  return start_line + ((int)(y/15));
 
323
}
 
324
 
 
325
int      GLUI_List::get_box_width() {
 
326
   return MAX( this->w 
 
327
                   - 6     /*  2 * the two-line box border */ 
 
328
                   - 2 * GLUI_LIST_BOXINNERMARGINX, 0 );
 
329
 
 
330
}
 
331
 
 
332
/******************************** GLUI_List::substring_width() *********/
 
333
int  GLUI_List::substring_width( const char *t, int start, int end )
 
334
{
 
335
  int i, width;
 
336
 
 
337
  width = 0;
 
338
 
 
339
  for( i=start; i<=end; i++ )
 
340
    width += char_width( t[i] ); 
 
341
 
 
342
  return width;
 
343
}
 
344
 
 
345
 
 
346
/***************************** GLUI_List::update_and_draw_text() ********/
 
347
 
 
348
void   GLUI_List::update_and_draw_text( void )
 
349
{
 
350
  if ( NOT can_draw() )
 
351
    return;
 
352
 
 
353
  //update_substring_bounds();
 
354
  /*  printf( "ss: %d/%d\n", substring_start, substring_end );                  */
 
355
 
 
356
  redraw();
 
357
}
 
358
 
 
359
 
 
360
/********************************* GLUI_List::special_handler() **********/
 
361
 
 
362
int    GLUI_List::special_handler( int key,int modifiers )
 
363
{
 
364
  if ( NOT glui )
 
365
    return false;
 
366
 
 
367
  if ( key == GLUT_KEY_DOWN ) {
 
368
     if (curr_line < num_lines) {
 
369
       curr_line++;
 
370
       if (curr_line > start_line+visible_lines)
 
371
         start_line++;
 
372
     }
 
373
  } else if ( key == GLUT_KEY_UP ) {
 
374
     if (curr_line > 0) {
 
375
       curr_line--;
 
376
       if (curr_line < start_line)
 
377
         start_line--;
 
378
     }
 
379
  }
 
380
 
 
381
  if (scrollbar)
 
382
    scrollbar->set_int_val(curr_line);
 
383
  redraw();
 
384
  return true;
 
385
}
 
386
 
 
387
 
 
388
/************************************ GLUI_List::update_size() **********/
 
389
 
 
390
void   GLUI_List::update_size( void )
 
391
{
 
392
  if ( NOT glui )
 
393
    return;
 
394
 
 
395
  if ( w < GLUI_LIST_MIN_TEXT_WIDTH )
 
396
      w = GLUI_LIST_MIN_TEXT_WIDTH;
 
397
}
 
398
 
 
399
/**************************************** GLUI_Listbox::add_item() **********/
 
400
 
 
401
int  GLUI_List::add_item( int id, const char *new_text )
 
402
{
 
403
  GLUI_List_Item *new_node = new GLUI_List_Item;
 
404
  GLUI_List_Item *head;
 
405
 
 
406
  new_node->text = new_text;
 
407
  new_node->id = id;
 
408
 
 
409
  head = (GLUI_List_Item*) items_list.first_child();
 
410
  new_node->link_this_to_parent_last( &items_list );
 
411
 
 
412
  if ( head == NULL ) {
 
413
    /***   This is first item added   ***/
 
414
 
 
415
    int_val       = id+1;  /** Different than id **/
 
416
    //    do_selection( id );
 
417
    last_live_int = id;
 
418
 
 
419
    if( glui )
 
420
      glui->post_update_main_gfx();
 
421
  }
 
422
  num_lines++;
 
423
  if (scrollbar)
 
424
    scrollbar->set_int_limits(MAX(num_lines-visible_lines,0), 0);
 
425
 
 
426
  return true;
 
427
}
 
428
 
 
429
/************************************** GLUI_Listbox::delete_() **********/
 
430
 
 
431
int  GLUI_List::delete_all()
 
432
{
 
433
  GLUI_List_Item *item;
 
434
 
 
435
  item = (GLUI_List_Item *) items_list.first_child();
 
436
  while( item ) {
 
437
    item->unlink();
 
438
    delete item;
 
439
    item = (GLUI_List_Item *) items_list.first_child();
 
440
  }
 
441
 
 
442
  num_lines = 0;
 
443
  curr_line = 0;
 
444
 
 
445
  return true;
 
446
}
 
447
 
 
448
 
 
449
/************************************** GLUI_Listbox::delete_item() **********/
 
450
 
 
451
int  GLUI_List::delete_item( const char *text )
 
452
{
 
453
  GLUI_List_Item *node = get_item_ptr( text );
 
454
 
 
455
  if ( node ) {
 
456
    node->unlink();
 
457
    delete node;
 
458
    num_lines--;
 
459
    return true;
 
460
  }
 
461
  else {
 
462
    return false;
 
463
  }
 
464
}
 
465
 
 
466
 
 
467
/************************************** GLUI_Listbox::delete_item() **********/
 
468
 
 
469
int  GLUI_List::delete_item( int id )
 
470
{
 
471
  GLUI_List_Item *node = get_item_ptr( id );
 
472
 
 
473
  if ( node ) {
 
474
    node->unlink();
 
475
    delete node;
 
476
    num_lines--;
 
477
    return true;
 
478
  }
 
479
  else {
 
480
    return false;
 
481
  }
 
482
}
 
483
 
 
484
 
 
485
/************************************ GLUI_Listbox::get_item_ptr() **********/
 
486
 
 
487
GLUI_List_Item *GLUI_List::get_item_ptr( const char *text )
 
488
{
 
489
  GLUI_List_Item *item;
 
490
 
 
491
  item = (GLUI_List_Item *) items_list.first_child();
 
492
  while( item ) {
 
493
    if ( item->text == text )
 
494
      return item;
 
495
    
 
496
    item = (GLUI_List_Item *) item->next();
 
497
  }
 
498
 
 
499
  return NULL;
 
500
}
 
501
 
 
502
 
 
503
/************************************ GLUI_Listbox::get_item_ptr() **********/
 
504
 
 
505
GLUI_List_Item *GLUI_List::get_item_ptr( int id )
 
506
{
 
507
  GLUI_List_Item *item;
 
508
 
 
509
  item = (GLUI_List_Item *) items_list.first_child();
 
510
  while( item ) {
 
511
    if ( item->id == id )
 
512
      return item;
 
513
    
 
514
    item = (GLUI_List_Item *) item->next();
 
515
  }
 
516
 
 
517
  return NULL;
 
518
}
 
519
 
 
520
/**************************************** GLUI_List::mouse_over() ********/
 
521
 
 
522
int    GLUI_List::mouse_over( int state, int x, int y )
 
523
{
 
524
  glutSetCursor( GLUT_CURSOR_LEFT_ARROW );
 
525
 
 
526
  return true;
 
527
}
 
528
 
 
529
void GLUI_List::scrollbar_callback(GLUI_Control *my_scrollbar) {
 
530
  GLUI_Scrollbar *sb = dynamic_cast<GLUI_Scrollbar*>(my_scrollbar);
 
531
  if (!sb) return;
 
532
  GLUI_List* me = (GLUI_List*) sb->associated_object;
 
533
  if (me->scrollbar == NULL)
 
534
    return;
 
535
  int new_start_line = sb->get_int_val(); // TODO!!
 
536
  me->start_line = new_start_line;
 
537
 
 
538
  if ( me->can_draw() )
 
539
    me->update_and_draw_text();
 
540
}