glui_list.cpp
上传用户:gb3593
上传日期:2022-01-07
资源大小:3028k
文件大小:13k
源码类别:

游戏引擎

开发平台:

Visual C++

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