glui_list.cpp
上传用户:gb3593
上传日期:2022-01-07
资源大小:3028k
文件大小:13k
- /****************************************************************************
-
- GLUI User Interface Toolkit
- ---------------------------
- glui_list.cpp - GLUI_List control class
- --------------------------------------------------
- Copyright (c) 2004 John Kew
- This program is freely distributable without licensing fees and is
- provided without guarantee or warrantee expressed or implied. This
- program is -not- in the public domain.
- *****************************************************************************/
- #include "glui_internal_control.h"
- #include <cmath>
- #include <sys/timeb.h>
- /****************************** GLUI_List::GLUI_List() **********/
- GLUI_List::GLUI_List( GLUI_Node *parent, bool scroll,
- int id, GLUI_CB callback
- /*,GLUI_Control *object
- GLUI_InterObject_CB obj_cb*/)
- {
- common_construct(parent, NULL, scroll, id, callback/*, object, obj_cb*/);
- }
- /****************************** GLUI_List::GLUI_List() **********/
- GLUI_List::GLUI_List( GLUI_Node *parent,
- GLUI_String& live_var, bool scroll,
- int id,
- GLUI_CB callback
- /* ,GLUI_Control *object
- ,GLUI_InterObject_CB obj_cb*/ )
- {
- common_construct(parent, &live_var, scroll, id, callback/*, object, obj_cb*/);
- }
- /****************************** GLUI_List::common_construct() **********/
- void GLUI_List::common_construct(
- GLUI_Node *parent,
- GLUI_String* data, bool scroll,
- int id,
- GLUI_CB callback
- /*,GLUI_Control *object
- , GLUI_InterObject_CB obj_cb*/)
- {
- common_init();
- GLUI_Node *list_panel = parent;
- if (scroll) {
- GLUI_Panel *p = new GLUI_Panel(parent,"",GLUI_PANEL_NONE);
- p->x_off = 1;
- list_panel = p;
- }
- this->ptr_val = data;
- if (data) {
- this->live_type = GLUI_LIVE_STRING;
- }
- this->user_id = id;
- this->callback = callback;
- this->name = "list";
- list_panel->add_control( this );
- if (scroll)
- {
- new GLUI_Column(list_panel, false);
- scrollbar =
- new GLUI_Scrollbar(list_panel,
- "scrollbar",
- GLUI_SCROLL_VERTICAL,
- GLUI_SCROLL_INT);
- scrollbar->set_object_callback(GLUI_List::scrollbar_callback, this);
- scrollbar->set_alignment(GLUI_ALIGN_LEFT);
- // scrollbar->can_activate = false; //kills ability to mouse drag too
- }
- init_live();
- }
- /****************************** GLUI_List::mouse_down_handler() **********/
- int GLUI_List::mouse_down_handler( int local_x, int local_y )
- {
- int tmp_line;
- unsigned long int ms;
- timeb time;
- ftime(&time);
- ms = time.millitm + (time.time)*1000;
- tmp_line = find_line( local_x-x_abs, local_y-y_abs-5 );
- if ( tmp_line == -1 ) {
- if ( glui )
- glui->deactivate_current_control( );
- return false;
- }
- if (tmp_line < num_lines) {
- curr_line = tmp_line;
- if (scrollbar)
- scrollbar->set_int_val(curr_line);
- this->execute_callback();
- if (associated_object != NULL)
- if (cb_click_type == GLUI_SINGLE_CLICK) {
- if (obj_cb) {
- // obj_cb(associated_object, user_id);
- obj_cb(this);
- }
- } else {
- if (last_line == curr_line && (ms - last_click_time) < 300) {
- //obj_cb(associated_object, user_id);
- obj_cb(this);
- } else {
- last_click_time = ms;
- last_line = curr_line;
- }
- }
- if ( can_draw())
- update_and_draw_text();
- }
- return true;
- }
- /******************************** GLUI_List::mouse_up_handler() **********/
- int GLUI_List::mouse_up_handler( int local_x, int local_y, bool inside )
- {
- return false;
- }
- /***************************** GLUI_List::mouse_held_down_handler() ******/
- int GLUI_List::mouse_held_down_handler( int local_x, int local_y,
- bool new_inside)
- {
- return false;
- }
- /****************************** GLUI_List::key_handler() **********/
- int GLUI_List::key_handler( unsigned char key,int modifiers )
- {
- draw_text_only = false; /** Well, hack is not yet working **/
- update_and_draw_text();
- draw_text_only = false;
- return true;
- }
- /****************************** GLUI_List::activate() **********/
- void GLUI_List::activate( int how )
- {
- // if ( debug )
- // dump( stdout, "-> ACTIVATE" );
- active = true;
- if ( how == GLUI_ACTIVATE_MOUSE )
- return; /* Don't select everything if activated with mouse */
- }
- /****************************** GLUI_List::deactivate() **********/
- void GLUI_List::deactivate( void )
- {
- active = false;
- redraw();
- }
- /****************************** GLUI_List::draw() **********/
- void GLUI_List::draw( int x, int y )
- {
- int line = 0;
- int box_width;
- GLUI_List_Item *item;
-
- GLUI_DRAWINGSENTINAL_IDIOM
- /* Bevelled Border */
- glBegin( GL_LINES );
- glColor3f( .5, .5, .5 );
- glVertex2i( 0, 0 ); glVertex2i( w, 0 );
- glVertex2i( 0, 0 ); glVertex2i( 0, h );
- glColor3f( 1., 1., 1. );
- glVertex2i( 0, h ); glVertex2i( w, h );
- glVertex2i( w, h ); glVertex2i( w, 0 );
- if ( enabled )
- glColor3f( 0., 0., 0. );
- else
- glColor3f( .25, .25, .25 );
- glVertex2i( 1, 1 ); glVertex2i( w-1, 1 );
- glVertex2i( 1, 1 ); glVertex2i( 1, h-1 );
- glColor3f( .75, .75, .75 );
- glVertex2i( 1, h-1 ); glVertex2i( w-1, h-1 );
- glVertex2i( w-1, h-1 ); glVertex2i( w-1, 1 );
- glEnd();
- /* Draw Background if enabled*/
- if (enabled) {
- glColor3f( 1., 1., 1. );
- glDisable( GL_CULL_FACE );
- glBegin( GL_QUADS );
- glVertex2i( 2, 2 ); glVertex2i( w-2, 2 );
- glVertex2i( w-2, h-2 ); glVertex2i(2, h-2 );
- glEnd();
- } else {
- glColor3f( .8, .8, .8 );
- glDisable( GL_CULL_FACE );
- glBegin( GL_QUADS );
- glVertex2i( 2, 2 ); glVertex2i( w-2, 2 );
- glVertex2i( w-2, h-2 ); glVertex2i(2, h-2 );
- glEnd();
- }
- /* Figure out how wide the box is */
- box_width = get_box_width();
- /* Figure out which lines are visible*/
- visible_lines = (int)(h-20)/15;
- item = (GLUI_List_Item *) items_list.first_child();
- line = 0;
- while (item) {
- if (line < start_line) {
- line++;
- item = (GLUI_List_Item *) item->next();
- continue;
- }
- if (line >= start_line && line <= (start_line+visible_lines)) {
- if (curr_line == line)
- draw_text(item->text.c_str(),1,0,(line - start_line)*15);
- else
- draw_text(item->text.c_str(),0,0,(line - start_line)*15);
- }
- line++;
- item = (GLUI_List_Item *) item->next();
- }
- if (scrollbar) {
- scrollbar->set_int_limits(MAX(0,num_lines-visible_lines), 0);
- glPushMatrix();
- glTranslatef(scrollbar->x_abs-x_abs, scrollbar->y_abs-y_abs,0.0);
- scrollbar->draw_scroll();
- glPopMatrix();
- }
- }
- /********************************* GLUI_List::draw_text() ****************/
- void GLUI_List::draw_text(const char *t, int selected, int x, int y )
- {
- int text_x, i, x_pos;
- int box_width;
- GLUI_DRAWINGSENTINAL_IDIOM
- /** Find where to draw the text **/
- text_x = 2 + GLUI_LIST_BOXINNERMARGINX;
- /** Draw selection area dark **/
- if ( enabled && selected ) {
- glColor3f( 0.0f, 0.0f, .6f );
- glBegin( GL_QUADS );
- glVertex2i(text_x, y+5 ); glVertex2i( w-text_x, y+5 );
- glVertex2i(w-text_x, y+19 ); glVertex2i(text_x, y+19 );
- glEnd();
- }
- box_width = get_box_width();
- if ( !selected || !enabled ) { /* No current selection */
- x_pos = text_x; /* or control disabled */
- if ( enabled )
- glColor3b( 0, 0, 0 );
- else
- glColor3b( 32, 32, 32 );
-
- glRasterPos2i( text_x, y+15);
- i = 0;
- while( t[i] != ' ' && substring_width(t,0,i) < box_width) {
- glutBitmapCharacter( get_font(), t[i] );
- x_pos += char_width( t[i] );
- i++;
- }
- }
- else { /* There is a selection */
- i = 0;
- x_pos = text_x;
- glColor3f( 1., 1., 1. );
- glRasterPos2i( text_x, y+15);
- while( t[i] != ' ' && substring_width(t,0,i) < box_width) {
- glutBitmapCharacter( get_font(), t[i] );
- x_pos += char_width( t[i] );
- i++;
- }
- }
- }
- int GLUI_List::find_line(int x, int y) {
- return start_line + ((int)(y/15));
- }
- int GLUI_List::get_box_width() {
- return MAX( this->w
- - 6 /* 2 * the two-line box border */
- - 2 * GLUI_LIST_BOXINNERMARGINX, 0 );
- }
- /******************************** GLUI_List::substring_width() *********/
- int GLUI_List::substring_width( const char *t, int start, int end )
- {
- int i, width;
- width = 0;
- for( i=start; i<=end; i++ )
- width += char_width( t[i] );
- return width;
- }
-
- /***************************** GLUI_List::update_and_draw_text() ********/
- void GLUI_List::update_and_draw_text( void )
- {
- if ( NOT can_draw() )
- return;
- //update_substring_bounds();
- /* printf( "ss: %d/%dn", substring_start, substring_end ); */
- redraw();
- }
- /********************************* GLUI_List::special_handler() **********/
- int GLUI_List::special_handler( int key,int modifiers )
- {
- if ( NOT glui )
- return false;
- if ( key == GLUT_KEY_DOWN ) {
- if (curr_line < num_lines) {
- curr_line++;
- if (curr_line > start_line+visible_lines)
- start_line++;
- }
- } else if ( key == GLUT_KEY_UP ) {
- if (curr_line > 0) {
- curr_line--;
- if (curr_line < start_line)
- start_line--;
- }
- }
- if (scrollbar)
- scrollbar->set_int_val(curr_line);
- redraw();
- return true;
- }
- /************************************ GLUI_List::update_size() **********/
- void GLUI_List::update_size( void )
- {
- if ( NOT glui )
- return;
- if ( w < GLUI_LIST_MIN_TEXT_WIDTH )
- w = GLUI_LIST_MIN_TEXT_WIDTH;
- }
- /**************************************** GLUI_Listbox::add_item() **********/
- int GLUI_List::add_item( int id, const char *new_text )
- {
- GLUI_List_Item *new_node = new GLUI_List_Item;
- GLUI_List_Item *head;
- new_node->text = new_text;
- new_node->id = id;
- head = (GLUI_List_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();
- }
- num_lines++;
- if (scrollbar)
- scrollbar->set_int_limits(MAX(num_lines-visible_lines,0), 0);
- return true;
- }
- /************************************** GLUI_Listbox::delete_() **********/
- int GLUI_List::delete_all()
- {
- GLUI_List_Item *item;
- item = (GLUI_List_Item *) items_list.first_child();
- while( item ) {
- item->unlink();
- delete item;
- item = (GLUI_List_Item *) items_list.first_child();
- }
- num_lines = 0;
- curr_line = 0;
- return true;
- }
- /************************************** GLUI_Listbox::delete_item() **********/
- int GLUI_List::delete_item( const char *text )
- {
- GLUI_List_Item *node = get_item_ptr( text );
- if ( node ) {
- node->unlink();
- delete node;
- num_lines--;
- return true;
- }
- else {
- return false;
- }
- }
- /************************************** GLUI_Listbox::delete_item() **********/
- int GLUI_List::delete_item( int id )
- {
- GLUI_List_Item *node = get_item_ptr( id );
- if ( node ) {
- node->unlink();
- delete node;
- num_lines--;
- return true;
- }
- else {
- return false;
- }
- }
- /************************************ GLUI_Listbox::get_item_ptr() **********/
- GLUI_List_Item *GLUI_List::get_item_ptr( const char *text )
- {
- GLUI_List_Item *item;
- item = (GLUI_List_Item *) items_list.first_child();
- while( item ) {
- if ( item->text == text )
- return item;
-
- item = (GLUI_List_Item *) item->next();
- }
- return NULL;
- }
- /************************************ GLUI_Listbox::get_item_ptr() **********/
- GLUI_List_Item *GLUI_List::get_item_ptr( int id )
- {
- GLUI_List_Item *item;
- item = (GLUI_List_Item *) items_list.first_child();
- while( item ) {
- if ( item->id == id )
- return item;
-
- item = (GLUI_List_Item *) item->next();
- }
- return NULL;
- }
- /**************************************** GLUI_List::mouse_over() ********/
- int GLUI_List::mouse_over( int state, int x, int y )
- {
- glutSetCursor( GLUT_CURSOR_LEFT_ARROW );
- return true;
- }
- void GLUI_List::scrollbar_callback(GLUI_Control *my_scrollbar) {
- GLUI_Scrollbar *sb = dynamic_cast<GLUI_Scrollbar*>(my_scrollbar);
- if (!sb) return;
- GLUI_List* me = (GLUI_List*) sb->associated_object;
- if (me->scrollbar == NULL)
- return;
- int new_start_line = sb->get_int_val(); // TODO!!
- me->start_line = new_start_line;
- if ( me->can_draw() )
- me->update_and_draw_text();
- }