glui_listbox.cpp
上传用户:gb3593
上传日期:2022-01-07
资源大小:3028k
文件大小:11k
- /****************************************************************************
-
- GLUI User Interface Toolkit
- ---------------------------
- glui_listbox - GLUI_ListBox control class
- --------------------------------------------------
- Copyright (c) 1998 Paul Rademacher
- WWW: http://sourceforge.net/projects/glui/
- Forums: http://sourceforge.net/forum/?group_id=92496
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *****************************************************************************/
- #include "glui_internal_control.h"
- /****************************** GLUI_Listbox::GLUI_Listbox() **********/
- GLUI_Listbox::GLUI_Listbox( GLUI_Node *parent,
- const char *name, int *value_ptr,
- int id,
- GLUI_CB cb)
- {
- common_init();
- set_ptr_val( value_ptr );
- user_id = id;
- set_name( name );
- callback = cb;
- parent->add_control( this );
- init_live();
- }
- /****************************** GLUI_Listbox::mouse_down_handler() **********/
- int GLUI_Listbox::mouse_down_handler( int local_x, int local_y )
- {
- return false;
- }
- /****************************** GLUI_Listbox::mouse_up_handler() **********/
- int GLUI_Listbox::mouse_up_handler( int local_x, int local_y, bool inside )
- {
- return false;
- }
- /****************************** GLUI_Listbox::mouse_held_down_handler() ******/
- int GLUI_Listbox::mouse_held_down_handler( int local_x, int local_y,
- bool inside)
- {
-
- return false;
- }
- /****************************** GLUI_Listbox::key_handler() **********/
- int GLUI_Listbox::key_handler( unsigned char key,int modifiers )
- {
- return false;
- }
- /****************************** GLUI_Listbox::draw() **********/
- void GLUI_Listbox::draw( int x, int y )
- {
- GLUI_DRAWINGSENTINAL_IDIOM
- int name_x;
- /* draw_active_area(); */
- name_x = MAX(text_x_offset - string_width(this->name) - 3,0);
- draw_name( name_x , 13);
- draw_box_inwards_outline( text_x_offset, w,
- 0, h );
- if ( NOT active ) {
- draw_box( text_x_offset+3, w-2, 2, h-2, 1.0, 1.0, 1.0 );
- if ( NOT enabled )
- glColor3b( 32, 32, 32 );
- else
- glColor3f( 0.0, 0.0, 0.0 );
- glRasterPos2i( text_x_offset+5, 13 );
- draw_string( curr_text );
- }
- else {
- draw_box( text_x_offset+3, w-2, 2, h-2, .0, .0, .6 );
- glColor3f( 1.0, 1.0, 1.0 );
- glRasterPos2i( text_x_offset+5, 13 );
- draw_string( curr_text );
- }
- if ( enabled ) {
- glui->std_bitmaps.
- draw(GLUI_STDBITMAP_LISTBOX_UP,
- w-glui->std_bitmaps.width(GLUI_STDBITMAP_LISTBOX_UP)-1,
- 2 );
- }
- else {
- glui->std_bitmaps.
- draw(GLUI_STDBITMAP_LISTBOX_UP_DIS,
- w-glui->std_bitmaps.width(GLUI_STDBITMAP_LISTBOX_UP)-1,
- 2 );
- }
- }
- /************************************ GLUI_Listbox::update_si() **********/
- void GLUI_Listbox::update_size( void )
- {
- recalculate_item_width();
- }
- /********************************* GLUI_Listbox::set_int_val() **************/
- void GLUI_Listbox::set_int_val( int new_val )
- {
- /* int_val = new_val; */
- do_selection( new_val );
- /*** Update the variable we're (possibly) pointing to, and update the main gfx ***/
- output_live(true);
- }
- /**************************************** GLUI_Listbox::add_item() **********/
- int GLUI_Listbox::add_item( int id, const char *new_text )
- {
- GLUI_Listbox_Item *new_node = new GLUI_Listbox_Item;
- GLUI_Listbox_Item *head;
- new_node->text = new_text;
- new_node->id = id;
- head = (GLUI_Listbox_Item*) items_list.first_child();
- new_node->link_this_to_parent_last( &items_list );
- if ( head == NULL ) {
- /*** This is first item added ***/
- int_val = id+1; /** Different than id **/
- do_selection( id );
- last_live_int = id;
- if( glui )
- glui->post_update_main_gfx();
- }
- if (recalculate_item_width()) glui->refresh();
- return true;
- }
- /************************************** GLUI_Listbox::delete_item() **********/
- int GLUI_Listbox::delete_item( const char *text )
- {
- GLUI_Listbox_Item *node = get_item_ptr(text);
- if (node)
- {
- node->unlink();
- delete node;
- return true;
- }
- if (recalculate_item_width()) glui->refresh();
- return false;
- }
- /************************************** GLUI_Listbox::delete_item() **********/
- int GLUI_Listbox::delete_item(int id)
- {
- GLUI_Listbox_Item *node = get_item_ptr(id);
- if (node)
- {
- node->unlink();
- delete node;
- return true;
- }
- if (recalculate_item_width()) glui->refresh();
-
- return false;
- }
- /************************************** GLUI_Listbox::sort_items() **********/
- int GLUI_Listbox::sort_items( void )
- {
- return false;
- }
- /********************************************* GLUI_Listbox::dump() **********/
- void GLUI_Listbox::dump( FILE *output )
- {
- GLUI_Listbox_Item *item;
- /* printf( "%pn", (char*) name ); */
- fprintf( output, "Listbox: %sn", name.c_str() );
- item = (GLUI_Listbox_Item *) items_list.first_child();
- while( item ) {
- fprintf( output, " %3d : %sn", item->id, item->text.c_str() );
-
- item = (GLUI_Listbox_Item *) item->next();
- }
- }
- /************************************ GLUI_Listbox::get_item_ptr() **********/
- GLUI_Listbox_Item *GLUI_Listbox::get_item_ptr( const char *text )
- {
- GLUI_Listbox_Item *item;
- item = (GLUI_Listbox_Item *) items_list.first_child();
- while( item ) {
- if ( item->text == text )
- return item;
-
- item = (GLUI_Listbox_Item *) item->next();
- }
- return NULL;
- }
- /************************************ GLUI_Listbox::get_item_ptr() **********/
- GLUI_Listbox_Item *GLUI_Listbox::get_item_ptr( int id )
- {
- GLUI_Listbox_Item *item;
- item = (GLUI_Listbox_Item *) items_list.first_child();
- while( item ) {
- if ( item->id == id )
- return item;
-
- item = (GLUI_Listbox_Item *) item->next();
- }
- return NULL;
- }
- /************************************ GLUI_Listbox::mouse_over() **********/
- static void listbox_callback( int i )
- {
- int old_val;
- if ( NOT GLUI_Master.curr_left_button_glut_menu OR
- !dynamic_cast<GLUI_Listbox*>(GLUI_Master.curr_left_button_glut_menu) )
- return;
- old_val = ((GLUI_Listbox*)GLUI_Master.curr_left_button_glut_menu)->int_val;
- ((GLUI_Listbox*)GLUI_Master.curr_left_button_glut_menu)->set_int_val(i);
- /**** If value changed, execute callback ****/
- if ( old_val !=
- ((GLUI_Listbox*)GLUI_Master.curr_left_button_glut_menu)->int_val ) {
- ((GLUI_Listbox*)GLUI_Master.curr_left_button_glut_menu)->execute_callback();
- }
- }
- /*************************************** GLUI_Listbox::mouse_over() **********/
- int GLUI_Listbox::mouse_over( int state, int x, int y )
- {
- GLUI_Listbox_Item *item;
- /* printf( "x/y: %d/%dn", x, y ); */
- if ( state AND enabled AND x > x_abs + text_x_offset) {
- /**** Build a GLUT menu for this listbox ***/
-
- /* printf( "%d %dn", x, y ); */
- glut_menu_id = glutCreateMenu(listbox_callback);
- item = (GLUI_Listbox_Item *) items_list.first_child();
- while( item ) {
- glutAddMenuEntry( item->text.c_str(), item->id );
- item = (GLUI_Listbox_Item *) item->next();
- }
- glutAttachMenu( GLUT_LEFT_BUTTON);
-
- GLUI_Master.set_left_button_glut_menu_control( this );
- }
- else if ( glut_menu_id != -1 ) {
- /* printf( "OUTn" ); */
- glutDetachMenu( GLUT_LEFT_BUTTON );
- glutDestroyMenu( glut_menu_id );
- glut_menu_id = -1;
- }
- return true;
- }
- /************************************ GLUI_Listbox::do_selection() **********/
- int GLUI_Listbox::do_selection( int item_num )
- {
- GLUI_Listbox_Item *item, *sel_item;
- /*** Is this item already selected? ***/
- if ( item_num == int_val )
- return false;
- sel_item = NULL;
- item = (GLUI_Listbox_Item *) items_list.first_child();
- while( item ) {
- if ( item->id == item_num ) {
- sel_item = item;
- break;
- }
-
- item = (GLUI_Listbox_Item *) item->next();
- }
- if ( NOT sel_item )
- return false;
- /* printf( "-> %sn", (char*) sel_item->text ); */
- int_val = item_num;
- curr_text = sel_item->text;
- redraw();
- return true;
- }
- /*********************************** GLUI_Listbox::~GLUI_Listbox() **********/
- GLUI_Listbox::~GLUI_Listbox()
- {
- GLUI_Listbox_Item *item = (GLUI_Listbox_Item *) items_list.first_child();
- while (item)
- {
- GLUI_Listbox_Item *tmp = item;
- item = (GLUI_Listbox_Item *) item->next();
- delete tmp;
- }
- }
- /****************************** GLUI_Listbox::special_handler() **********/
- int GLUI_Listbox::special_handler( int key,int modifiers )
- {
- GLUI_Listbox_Item *node, *new_node;
- node = get_item_ptr( int_val );
- new_node = NULL;
- if ( key == GLUT_KEY_DOWN ) {
- new_node = (GLUI_Listbox_Item*) node->next();
- }
- else if ( key == GLUT_KEY_UP ) {
- new_node = (GLUI_Listbox_Item*) node->prev();
- }
- else if ( key == GLUT_KEY_HOME ) {
- new_node = (GLUI_Listbox_Item*) items_list.first_child();
- }
- else if ( key == GLUT_KEY_END ) {
- new_node = (GLUI_Listbox_Item*) items_list.last_child();
- }
- if ( new_node != NULL AND new_node != node ) {
- node = new_node;
- set_int_val( node->id );
- execute_callback();
- return true;
- }
- else {
- return false;
- }
- }
- /************************* GLUI_Listbox::recalculate_item_width( void ) ***********/
- /** Change w and return true if we need to be widened to fit the current items. */
- bool GLUI_Listbox::recalculate_item_width( void )
- {
- int item_text_size;
- if ( NOT glui )
- return false;
- /* Find the title size */
- text_x_offset = string_width( name );
- /* Find the longest item string ***/
- item_text_size = 0;
-
- GLUI_Listbox_Item *item = (GLUI_Listbox_Item *) items_list.first_child();
- while( item ) {
- item_text_size = MAX(item_text_size,string_width(item->text));
- item = (GLUI_Listbox_Item *) item->next();
- }
-
- /* Sum up our layout: name, item, and drop-down marker */
- int new_wid=text_x_offset+MAX(GLUI_EDITTEXT_MIN_TEXT_WIDTH,item_text_size)+20;
- if ( w != new_wid) {
- w = new_wid;
- return true; /* we gotta be shortened or widened */
- }
- else {
- return false; /* our current width is OK */
- }
- }