1
/****************************************************************************
3
GLUI User Interface Toolkit
4
---------------------------
6
glui_listbox - GLUI_ListBox control class
9
--------------------------------------------------
11
Copyright (c) 1998 Paul Rademacher
13
WWW: http://sourceforge.net/projects/glui/
14
Forums: http://sourceforge.net/forum/?group_id=92496
16
This library is free software; you can redistribute it and/or
17
modify it under the terms of the GNU Lesser General Public
18
License as published by the Free Software Foundation; either
19
version 2.1 of the License, or (at your option) any later version.
21
This library is distributed in the hope that it will be useful,
22
but WITHOUT ANY WARRANTY; without even the implied warranty of
23
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24
Lesser General Public License for more details.
26
You should have received a copy of the GNU Lesser General Public
27
License along with this library; if not, write to the Free Software
28
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30
*****************************************************************************/
32
#include "glui_internal_control.h"
34
/****************************** GLUI_Listbox::GLUI_Listbox() **********/
35
GLUI_Listbox::GLUI_Listbox( GLUI_Node *parent,
36
const char *name, int *value_ptr,
41
set_ptr_val( value_ptr );
46
parent->add_control( this );
52
/****************************** GLUI_Listbox::mouse_down_handler() **********/
54
int GLUI_Listbox::mouse_down_handler( int local_x, int local_y )
60
/****************************** GLUI_Listbox::mouse_up_handler() **********/
62
int GLUI_Listbox::mouse_up_handler( int local_x, int local_y, bool inside )
69
/****************************** GLUI_Listbox::mouse_held_down_handler() ******/
71
int GLUI_Listbox::mouse_held_down_handler( int local_x, int local_y,
79
/****************************** GLUI_Listbox::key_handler() **********/
81
int GLUI_Listbox::key_handler( unsigned char key,int modifiers )
87
/****************************** GLUI_Listbox::draw() **********/
89
void GLUI_Listbox::draw( int x, int y )
91
GLUI_DRAWINGSENTINAL_IDIOM
94
/* draw_active_area(); */
96
name_x = MAX(text_x_offset - string_width(this->name) - 3,0);
97
draw_name( name_x , 13);
98
draw_box_inwards_outline( text_x_offset, w,
102
draw_box( text_x_offset+3, w-2, 2, h-2, 1.0, 1.0, 1.0 );
104
glColor3b( 32, 32, 32 );
106
glColor3f( 0.0, 0.0, 0.0 );
107
glRasterPos2i( text_x_offset+5, 13 );
108
draw_string( curr_text );
111
draw_box( text_x_offset+3, w-2, 2, h-2, .0, .0, .6 );
112
glColor3f( 1.0, 1.0, 1.0 );
113
glRasterPos2i( text_x_offset+5, 13 );
114
draw_string( curr_text );
120
draw(GLUI_STDBITMAP_LISTBOX_UP,
121
w-glui->std_bitmaps.width(GLUI_STDBITMAP_LISTBOX_UP)-1,
126
draw(GLUI_STDBITMAP_LISTBOX_UP_DIS,
127
w-glui->std_bitmaps.width(GLUI_STDBITMAP_LISTBOX_UP)-1,
133
/************************************ GLUI_Listbox::update_si() **********/
134
void GLUI_Listbox::update_size( void )
136
recalculate_item_width();
139
/********************************* GLUI_Listbox::set_int_val() **************/
141
void GLUI_Listbox::set_int_val( int new_val )
143
/* int_val = new_val; */
145
do_selection( new_val );
147
/*** Update the variable we're (possibly) pointing to, and update the main gfx ***/
151
/**************************************** GLUI_Listbox::add_item() **********/
153
int GLUI_Listbox::add_item( int id, const char *new_text )
155
GLUI_Listbox_Item *new_node = new GLUI_Listbox_Item;
156
GLUI_Listbox_Item *head;
158
new_node->text = new_text;
161
head = (GLUI_Listbox_Item*) items_list.first_child();
162
new_node->link_this_to_parent_last( &items_list );
164
if ( head == NULL ) {
165
/*** This is first item added ***/
167
int_val = id+1; /** Different than id **/
172
glui->post_update_main_gfx();
174
if (recalculate_item_width()) glui->refresh();
180
/************************************** GLUI_Listbox::delete_item() **********/
182
int GLUI_Listbox::delete_item( const char *text )
184
GLUI_Listbox_Item *node = get_item_ptr(text);
192
if (recalculate_item_width()) glui->refresh();
198
/************************************** GLUI_Listbox::delete_item() **********/
200
int GLUI_Listbox::delete_item(int id)
202
GLUI_Listbox_Item *node = get_item_ptr(id);
210
if (recalculate_item_width()) glui->refresh();
216
/************************************** GLUI_Listbox::sort_items() **********/
218
int GLUI_Listbox::sort_items( void )
224
/********************************************* GLUI_Listbox::dump() **********/
226
void GLUI_Listbox::dump( FILE *output )
228
GLUI_Listbox_Item *item;
230
/* printf( "%p\n", (char*) name ); */
232
fprintf( output, "Listbox: %s\n", name.c_str() );
234
item = (GLUI_Listbox_Item *) items_list.first_child();
236
fprintf( output, " %3d : %s\n", item->id, item->text.c_str() );
238
item = (GLUI_Listbox_Item *) item->next();
243
/************************************ GLUI_Listbox::get_item_ptr() **********/
245
GLUI_Listbox_Item *GLUI_Listbox::get_item_ptr( const char *text )
247
GLUI_Listbox_Item *item;
249
item = (GLUI_Listbox_Item *) items_list.first_child();
251
if ( item->text == text )
254
item = (GLUI_Listbox_Item *) item->next();
261
/************************************ GLUI_Listbox::get_item_ptr() **********/
263
GLUI_Listbox_Item *GLUI_Listbox::get_item_ptr( int id )
265
GLUI_Listbox_Item *item;
267
item = (GLUI_Listbox_Item *) items_list.first_child();
269
if ( item->id == id )
272
item = (GLUI_Listbox_Item *) item->next();
279
/************************************ GLUI_Listbox::mouse_over() **********/
281
static void listbox_callback( int i )
285
if ( NOT GLUI_Master.curr_left_button_glut_menu OR
286
!GLUI_Master.curr_left_button_glut_menu->dynamicCastGLUI_Listbox() )
289
old_val = ((GLUI_Listbox*)GLUI_Master.curr_left_button_glut_menu)->int_val;
290
((GLUI_Listbox*)GLUI_Master.curr_left_button_glut_menu)->set_int_val(i);
292
/**** If value changed, execute callback ****/
294
((GLUI_Listbox*)GLUI_Master.curr_left_button_glut_menu)->int_val ) {
295
((GLUI_Listbox*)GLUI_Master.curr_left_button_glut_menu)->execute_callback();
300
/*************************************** GLUI_Listbox::mouse_over() **********/
302
int GLUI_Listbox::mouse_over( int state, int x, int y )
304
GLUI_Listbox_Item *item;
306
/* printf( "x/y: %d/%d\n", x, y ); */
308
if ( state AND enabled AND x > x_abs + text_x_offset) {
309
/**** Build a GLUT menu for this listbox ***/
311
/* printf( "%d %d\n", x, y ); */
313
glut_menu_id = glutCreateMenu(listbox_callback);
315
item = (GLUI_Listbox_Item *) items_list.first_child();
317
glutAddMenuEntry( item->text.c_str(), item->id );
318
item = (GLUI_Listbox_Item *) item->next();
321
glutAttachMenu( GLUT_LEFT_BUTTON);
323
GLUI_Master.set_left_button_glut_menu_control( this );
325
else if ( glut_menu_id != -1 ) {
326
/* printf( "OUT\n" ); */
327
glutDetachMenu( GLUT_LEFT_BUTTON );
328
glutDestroyMenu( glut_menu_id );
336
/************************************ GLUI_Listbox::do_selection() **********/
338
int GLUI_Listbox::do_selection( int item_num )
340
GLUI_Listbox_Item *item, *sel_item;
342
/*** Is this item already selected? ***/
343
if ( item_num == int_val )
347
item = (GLUI_Listbox_Item *) items_list.first_child();
349
if ( item->id == item_num ) {
354
item = (GLUI_Listbox_Item *) item->next();
360
/* printf( "-> %s\n", (char*) sel_item->text ); */
363
curr_text = sel_item->text;
370
/*********************************** GLUI_Listbox::~GLUI_Listbox() **********/
372
GLUI_Listbox::~GLUI_Listbox()
374
GLUI_Listbox_Item *item = (GLUI_Listbox_Item *) items_list.first_child();
378
GLUI_Listbox_Item *tmp = item;
379
item = (GLUI_Listbox_Item *) item->next();
384
/****************************** GLUI_Listbox::special_handler() **********/
386
int GLUI_Listbox::special_handler( int key,int modifiers )
388
GLUI_Listbox_Item *node, *new_node;
390
node = get_item_ptr( int_val );
393
if ( key == GLUT_KEY_DOWN ) {
394
new_node = (GLUI_Listbox_Item*) node->next();
396
else if ( key == GLUT_KEY_UP ) {
397
new_node = (GLUI_Listbox_Item*) node->prev();
399
else if ( key == GLUT_KEY_HOME ) {
400
new_node = (GLUI_Listbox_Item*) items_list.first_child();
402
else if ( key == GLUT_KEY_END ) {
403
new_node = (GLUI_Listbox_Item*) items_list.last_child();
406
if ( new_node != NULL AND new_node != node ) {
408
set_int_val( node->id );
418
/************************* GLUI_Listbox::recalculate_item_width( void ) ***********/
419
/** Change w and return true if we need to be widened to fit the current items. */
420
bool GLUI_Listbox::recalculate_item_width( void )
427
/* Find the title size */
428
text_x_offset = string_width( name );
430
/* Find the longest item string ***/
433
GLUI_Listbox_Item *item = (GLUI_Listbox_Item *) items_list.first_child();
435
item_text_size = MAX(item_text_size,string_width(item->text));
436
item = (GLUI_Listbox_Item *) item->next();
439
/* Sum up our layout: name, item, and drop-down marker */
440
int new_wid=text_x_offset+MAX(GLUI_EDITTEXT_MIN_TEXT_WIDTH,item_text_size)+20;
443
return true; /* we gotta be shortened or widened */
446
return false; /* our current width is OK */