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

游戏引擎

开发平台:

Visual C++

  1. /****************************************************************************
  2.   
  3.   GLUI User Interface Toolkit
  4.   ---------------------------
  5.      glui_listbox - GLUI_ListBox control class
  6.           --------------------------------------------------
  7.   Copyright (c) 1998 Paul Rademacher
  8.   WWW:    http://sourceforge.net/projects/glui/
  9.   Forums: http://sourceforge.net/forum/?group_id=92496
  10.   This library is free software; you can redistribute it and/or
  11.   modify it under the terms of the GNU Lesser General Public
  12.   License as published by the Free Software Foundation; either
  13.   version 2.1 of the License, or (at your option) any later version.
  14.   This library is distributed in the hope that it will be useful,
  15.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17.   Lesser General Public License for more details.
  18.   You should have received a copy of the GNU Lesser General Public
  19.   License along with this library; if not, write to the Free Software
  20.   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21. *****************************************************************************/
  22. #include "glui_internal_control.h"
  23. /****************************** GLUI_Listbox::GLUI_Listbox() **********/
  24. GLUI_Listbox::GLUI_Listbox( GLUI_Node *parent,
  25.                             const char *name, int *value_ptr,
  26.                             int id, 
  27.                             GLUI_CB cb)
  28. {
  29.   common_init();
  30.   set_ptr_val( value_ptr );
  31.   user_id    = id;
  32.   set_name( name );
  33.   callback    = cb;
  34.   parent->add_control( this );
  35.   init_live();
  36. }
  37. /****************************** GLUI_Listbox::mouse_down_handler() **********/
  38. int    GLUI_Listbox::mouse_down_handler( int local_x, int local_y )
  39. {
  40.   return false;
  41. }
  42. /****************************** GLUI_Listbox::mouse_up_handler() **********/
  43. int    GLUI_Listbox::mouse_up_handler( int local_x, int local_y, bool inside )
  44. {
  45.   return false;
  46. }
  47. /****************************** GLUI_Listbox::mouse_held_down_handler() ******/
  48. int    GLUI_Listbox::mouse_held_down_handler( int local_x, int local_y,
  49.       bool inside)
  50. {
  51.   
  52.   return false;
  53. }
  54. /****************************** GLUI_Listbox::key_handler() **********/
  55. int    GLUI_Listbox::key_handler( unsigned char key,int modifiers )
  56. {
  57.   return false;
  58. }
  59. /****************************** GLUI_Listbox::draw() **********/
  60. void    GLUI_Listbox::draw( int x, int y )
  61. {
  62.   GLUI_DRAWINGSENTINAL_IDIOM
  63.   int name_x;
  64.   /*  draw_active_area();              */
  65.   name_x = MAX(text_x_offset - string_width(this->name) - 3,0);
  66.   draw_name( name_x , 13);
  67.   draw_box_inwards_outline( text_x_offset, w,
  68.     0, h );
  69.   if ( NOT active ) {
  70.     draw_box( text_x_offset+3, w-2, 2, h-2, 1.0, 1.0, 1.0 );
  71.     if ( NOT enabled )
  72.       glColor3b( 32, 32, 32 );
  73.     else
  74.       glColor3f( 0.0, 0.0, 0.0 );
  75.     glRasterPos2i( text_x_offset+5, 13 );
  76.     draw_string( curr_text );
  77.   }
  78.   else {
  79.     draw_box( text_x_offset+3, w-2, 2, h-2, .0, .0, .6 );
  80.     glColor3f( 1.0, 1.0, 1.0 );
  81.     glRasterPos2i( text_x_offset+5, 13 );
  82.     draw_string( curr_text );
  83.   }
  84.   if ( enabled ) {
  85.     glui->std_bitmaps.
  86.       draw(GLUI_STDBITMAP_LISTBOX_UP,
  87.    w-glui->std_bitmaps.width(GLUI_STDBITMAP_LISTBOX_UP)-1,
  88.    2 );
  89.   }
  90.   else {
  91.     glui->std_bitmaps.
  92.       draw(GLUI_STDBITMAP_LISTBOX_UP_DIS,
  93.    w-glui->std_bitmaps.width(GLUI_STDBITMAP_LISTBOX_UP)-1,
  94.    2 );
  95.   }
  96. }
  97. /************************************ GLUI_Listbox::update_si() **********/
  98. void   GLUI_Listbox::update_size( void )
  99. {
  100.   recalculate_item_width();
  101. }
  102. /********************************* GLUI_Listbox::set_int_val() **************/
  103. void    GLUI_Listbox::set_int_val( int new_val )
  104. {
  105.   /*  int_val = new_val;              */
  106.   do_selection( new_val );
  107.   /*** Update the variable we're (possibly) pointing to, and update the main gfx ***/
  108.   output_live(true);
  109. }
  110. /**************************************** GLUI_Listbox::add_item() **********/
  111. int  GLUI_Listbox::add_item( int id, const char *new_text )
  112. {
  113.   GLUI_Listbox_Item *new_node = new GLUI_Listbox_Item;
  114.   GLUI_Listbox_Item *head;
  115.   new_node->text = new_text;
  116.   new_node->id = id;
  117.   head = (GLUI_Listbox_Item*) items_list.first_child();
  118.   new_node->link_this_to_parent_last( &items_list );
  119.   if ( head == NULL ) {
  120.     /***   This is first item added   ***/
  121.     int_val       = id+1;  /** Different than id **/
  122.     do_selection( id );
  123.     last_live_int = id;
  124.     if( glui )
  125.       glui->post_update_main_gfx();
  126.   }
  127.   if (recalculate_item_width()) glui->refresh();
  128.   return true;
  129. }
  130. /************************************** GLUI_Listbox::delete_item() **********/
  131. int  GLUI_Listbox::delete_item( const char *text )
  132. {
  133.   GLUI_Listbox_Item *node = get_item_ptr(text);
  134.   if (node) 
  135.   {
  136.     node->unlink();
  137.     delete node;
  138.     return true;
  139.   }
  140.   if (recalculate_item_width()) glui->refresh();
  141.   return false;
  142. }
  143. /************************************** GLUI_Listbox::delete_item() **********/
  144. int  GLUI_Listbox::delete_item(int id)
  145. {
  146.   GLUI_Listbox_Item *node = get_item_ptr(id);
  147.   if (node) 
  148.   {
  149.     node->unlink();
  150.     delete node;
  151.     return true;
  152.   }
  153.   if (recalculate_item_width()) glui->refresh();
  154.   
  155.   return false;
  156. }
  157. /************************************** GLUI_Listbox::sort_items() **********/
  158. int  GLUI_Listbox::sort_items( void )
  159. {
  160.   return false;
  161. }
  162. /********************************************* GLUI_Listbox::dump() **********/
  163. void     GLUI_Listbox::dump( FILE *output )
  164. {
  165.   GLUI_Listbox_Item *item;
  166.   /*  printf( "%pn", (char*) name );              */
  167.   fprintf( output, "Listbox: %sn", name.c_str() );
  168.   item = (GLUI_Listbox_Item *) items_list.first_child();
  169.   while( item ) {
  170.     fprintf( output, "         %3d : %sn", item->id, item->text.c_str() );
  171.     
  172.     item = (GLUI_Listbox_Item *) item->next();
  173.   }
  174. }
  175. /************************************ GLUI_Listbox::get_item_ptr() **********/
  176. GLUI_Listbox_Item *GLUI_Listbox::get_item_ptr( const char *text )
  177. {
  178.   GLUI_Listbox_Item *item;
  179.   item = (GLUI_Listbox_Item *) items_list.first_child();
  180.   while( item ) {
  181.     if ( item->text == text )
  182.       return item;
  183.     
  184.     item = (GLUI_Listbox_Item *) item->next();
  185.   }
  186.   return NULL;
  187. }
  188. /************************************ GLUI_Listbox::get_item_ptr() **********/
  189. GLUI_Listbox_Item *GLUI_Listbox::get_item_ptr( int id )
  190. {
  191.   GLUI_Listbox_Item *item;
  192.   item = (GLUI_Listbox_Item *) items_list.first_child();
  193.   while( item ) {
  194.     if ( item->id == id )
  195.       return item;
  196.     
  197.     item = (GLUI_Listbox_Item *) item->next();
  198.   }
  199.   return NULL;
  200. }
  201. /************************************ GLUI_Listbox::mouse_over() **********/
  202. static void listbox_callback( int i )
  203. {
  204.   int old_val;
  205.   if ( NOT GLUI_Master.curr_left_button_glut_menu OR 
  206.        !dynamic_cast<GLUI_Listbox*>(GLUI_Master.curr_left_button_glut_menu) ) 
  207.     return;
  208.   old_val = ((GLUI_Listbox*)GLUI_Master.curr_left_button_glut_menu)->int_val;
  209.   ((GLUI_Listbox*)GLUI_Master.curr_left_button_glut_menu)->set_int_val(i);
  210.   /****   If value changed, execute callback   ****/
  211.   if ( old_val != 
  212.        ((GLUI_Listbox*)GLUI_Master.curr_left_button_glut_menu)->int_val ) {
  213.     ((GLUI_Listbox*)GLUI_Master.curr_left_button_glut_menu)->execute_callback();
  214.   }
  215. }
  216. /*************************************** GLUI_Listbox::mouse_over() **********/
  217. int     GLUI_Listbox::mouse_over( int state, int x, int y )
  218. {
  219.   GLUI_Listbox_Item *item;
  220.   /*  printf( "x/y:   %d/%dn", x, y );              */
  221.   if ( state AND enabled AND x > x_abs + text_x_offset) {
  222.     /****  Build a GLUT menu for this listbox   ***/
  223.     
  224.     /* printf( "%d %dn", x, y );              */
  225.     glut_menu_id = glutCreateMenu(listbox_callback);
  226.     item = (GLUI_Listbox_Item *) items_list.first_child();
  227.     while( item ) {
  228.       glutAddMenuEntry( item->text.c_str(), item->id );
  229.       item = (GLUI_Listbox_Item *) item->next();
  230.     }
  231.     glutAttachMenu( GLUT_LEFT_BUTTON);
  232.     
  233.     GLUI_Master.set_left_button_glut_menu_control( this );
  234.   }
  235.   else if ( glut_menu_id != -1 ) {
  236.     /*    printf( "OUTn" );              */
  237.     glutDetachMenu( GLUT_LEFT_BUTTON );
  238.     glutDestroyMenu( glut_menu_id );
  239.     glut_menu_id = -1;
  240.   }
  241.   return true;
  242. }
  243. /************************************ GLUI_Listbox::do_selection() **********/
  244. int    GLUI_Listbox::do_selection( int item_num )
  245. {
  246.   GLUI_Listbox_Item *item, *sel_item;
  247.   /***  Is this item already selected?  ***/
  248.   if ( item_num == int_val )
  249.     return false;
  250.   sel_item = NULL;
  251.   item     = (GLUI_Listbox_Item *) items_list.first_child();
  252.   while( item ) {
  253.     if ( item->id == item_num ) {
  254.       sel_item = item;
  255.       break;
  256.     }
  257.     
  258.     item = (GLUI_Listbox_Item *) item->next();
  259.   }
  260.   if ( NOT sel_item )
  261.     return false;
  262.   /*  printf( "-> %sn", (char*) sel_item->text );              */
  263.   int_val = item_num;
  264.   curr_text = sel_item->text;
  265.   redraw();
  266.   return true;
  267. }
  268. /*********************************** GLUI_Listbox::~GLUI_Listbox() **********/
  269. GLUI_Listbox::~GLUI_Listbox()
  270. {
  271.   GLUI_Listbox_Item *item = (GLUI_Listbox_Item *) items_list.first_child();
  272.   while (item) 
  273.   {
  274.     GLUI_Listbox_Item *tmp = item;
  275.     item = (GLUI_Listbox_Item *) item->next();
  276.     delete tmp;
  277.   }
  278. }
  279. /****************************** GLUI_Listbox::special_handler() **********/
  280. int    GLUI_Listbox::special_handler( int key,int modifiers )
  281. {
  282.   GLUI_Listbox_Item *node, *new_node;
  283.   node     = get_item_ptr( int_val );
  284.   new_node = NULL;
  285.   if ( key == GLUT_KEY_DOWN ) {
  286.     new_node = (GLUI_Listbox_Item*) node->next();
  287.   }
  288.   else if ( key == GLUT_KEY_UP ) {
  289.     new_node = (GLUI_Listbox_Item*) node->prev();
  290.   }
  291.   else if ( key == GLUT_KEY_HOME ) {
  292.     new_node = (GLUI_Listbox_Item*) items_list.first_child();
  293.   }
  294.   else if ( key == GLUT_KEY_END ) {
  295.     new_node = (GLUI_Listbox_Item*) items_list.last_child();
  296.   }
  297.   if ( new_node != NULL AND new_node != node ) {
  298.     node = new_node;
  299.     set_int_val( node->id );
  300.     execute_callback();
  301.     return true;
  302.   }
  303.   else {
  304.     return false;
  305.   }
  306. }
  307. /************************* GLUI_Listbox::recalculate_item_width( void ) ***********/
  308. /** Change w and return true if we need to be widened to fit the current items. */
  309. bool    GLUI_Listbox::recalculate_item_width( void )
  310. {
  311.   int item_text_size;
  312.   if ( NOT glui )
  313.     return false;
  314.   /* Find the title size */
  315.   text_x_offset = string_width( name );
  316.   /* Find the longest item string ***/
  317.   item_text_size = 0;   
  318.  
  319.   GLUI_Listbox_Item *item = (GLUI_Listbox_Item *) items_list.first_child();
  320.   while( item ) {
  321.     item_text_size = MAX(item_text_size,string_width(item->text));
  322.     item = (GLUI_Listbox_Item *) item->next();
  323.   }
  324.   
  325.   /* Sum up our layout: name, item, and drop-down marker */
  326.   int new_wid=text_x_offset+MAX(GLUI_EDITTEXT_MIN_TEXT_WIDTH,item_text_size)+20;
  327.   if ( w != new_wid) {
  328.     w = new_wid;
  329.     return true; /* we gotta be shortened or widened */
  330.   }
  331.   else {
  332.     return false; /* our current width is OK */
  333.   }
  334. }