aboutsummaryrefslogtreecommitdiff
path: root/tests/bullet/Extras/glui/glui_control.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/bullet/Extras/glui/glui_control.cpp')
-rw-r--r--tests/bullet/Extras/glui/glui_control.cpp1203
1 files changed, 1203 insertions, 0 deletions
diff --git a/tests/bullet/Extras/glui/glui_control.cpp b/tests/bullet/Extras/glui/glui_control.cpp
new file mode 100644
index 00000000..576a2a9d
--- /dev/null
+++ b/tests/bullet/Extras/glui/glui_control.cpp
@@ -0,0 +1,1203 @@
+/****************************************************************************
+
+ GLUI User Interface Toolkit
+ ---------------------------
+
+ glui_control.cpp - top-level GLUI_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"
+
+int _glui_draw_border_only = 0;
+
+/*************************** Drawing Utility routines *********************/
+
+/* Redraw this control. */
+void GLUI_Control::redraw(void) {
+ if (glui==NULL || hidden) return;
+ if (glui->should_redraw_now(this))
+ translate_and_draw_front();
+}
+
+/** Redraw everybody in our window. */
+void GLUI_Control::redraw_window(void) {
+ if (glui==NULL || hidden) return;
+ if ( glui->get_glut_window_id() == -1 ) return;
+ int orig = set_to_glut_window();
+ glutPostRedisplay();
+ restore_window(orig);
+}
+
+
+
+/* GLUI_Control::translate_and_draw_front() ********/
+
+void GLUI_Control::translate_and_draw_front()
+{
+ GLUI_DRAWINGSENTINAL_IDIOM
+
+ glMatrixMode( GL_MODELVIEW );
+ glPushMatrix();
+ translate_to_origin();
+ draw(0,0);
+ glPopMatrix();
+}
+
+
+/********** GLUI_Control::set_to_bkgd_color() ********/
+
+void GLUI_Control::set_to_bkgd_color( void )
+{
+ if ( NOT glui )
+ return;
+
+ glColor3ub( glui->bkgd_color.r, glui->bkgd_color.g, glui->bkgd_color.b );
+}
+
+/******** GLUI_Control::draw_box_inwards_outline() ********/
+
+void GLUI_Control::draw_box_inwards_outline( int x_min, int x_max, int y_min, int y_max )
+{
+ glBegin( GL_LINES );
+ glColor3f( .5, .5, .5 );
+ glVertex2i( x_min, y_min ); glVertex2i( x_max, y_min );
+ glVertex2i( x_min, y_min ); glVertex2i( x_min, y_max );
+
+ glColor3f( 1., 1., 1. );
+ glVertex2i( x_min, y_max ); glVertex2i( x_max, y_max );
+ glVertex2i( x_max, y_max ); glVertex2i( x_max, y_min );
+
+ if ( enabled )
+ glColor3f( 0., 0., 0. );
+ else
+ glColor3f( .25, .25, .25 );
+
+ glVertex2i( x_min+1, y_min+1 ); glVertex2i( x_max-1, y_min+1 );
+ glVertex2i( x_min+1, y_min+1 ); glVertex2i( x_min+1, y_max-1 );
+
+ glColor3f( .75, .75, .75 );
+ glVertex2i( x_min+1, y_max-1 ); glVertex2i( x_max-1, y_max-1 );
+ glVertex2i( x_max-1, y_max-1 ); glVertex2i( x_max-1, y_min+1 );
+ glEnd();
+}
+
+
+/******* GLUI_Control::draw_box() **********/
+
+void GLUI_Control::draw_box( int x_min, int x_max, int y_min, int y_max, float r, float g, float b)
+{
+ if ( r == 1.0 AND g == 1.0 AND b == 1.0 AND NOT enabled AND glui ) {
+ draw_bkgd_box( x_min, x_max, y_min, y_max );
+ return;
+ }
+
+ glColor3f( r, g, b );
+ glBegin( GL_QUADS );
+ glVertex2i( x_min, y_min ); glVertex2i( x_max, y_min );
+ glVertex2i( x_max, y_max ); glVertex2i( x_min, y_max );
+ glEnd();
+}
+
+
+/******* GLUI_Control::draw_bkgd_box() **********/
+
+void GLUI_Control::draw_bkgd_box( int x_min, int x_max, int y_min, int y_max )
+{
+ set_to_bkgd_color();
+
+ glBegin( GL_QUADS );
+ glVertex2i( x_min, y_min ); glVertex2i( x_max, y_min );
+ glVertex2i( x_max, y_max ); glVertex2i( x_min, y_max );
+ glEnd();
+}
+
+
+/**** GLUI_Control::draw_active_area() ********/
+
+void GLUI_Control::draw_active_box( int x_min, int x_max, int y_min, int y_max )
+{
+ GLUI_DRAWINGSENTINAL_IDIOM
+
+ if ( active ) {
+ glEnable( GL_LINE_STIPPLE );
+ glLineStipple( 1, 0x5555 );
+ glColor3f( 0., 0., 0. );
+ } else {
+ set_to_bkgd_color();
+ }
+
+ glBegin( GL_LINE_LOOP );
+ glVertex2i(x_min, y_min); glVertex2i( x_max, y_min );
+ glVertex2i(x_max, y_max); glVertex2i( x_min, y_max );
+ glEnd();
+
+ glDisable( GL_LINE_STIPPLE );
+}
+
+
+/**** GLUI_Control::draw_emboss_box() ********/
+
+void GLUI_Control::draw_emboss_box(int x_min,int x_max,int y_min,int y_max)
+{
+ glLineWidth( 1.0 );
+ glColor3f( 1.0, 1.0, 1.0 );
+
+ glBegin( GL_LINE_LOOP );
+ glVertex2i( x_min, y_min ); glVertex2i( x_max, y_min );
+ glVertex2i( x_max, y_max ); glVertex2i( x_min, y_max );
+ glEnd();
+
+ glBegin( GL_LINE_LOOP );
+ glVertex2i( x_min+1, y_min+1 ); glVertex2i( x_max-1, y_min+1 );
+ glVertex2i( x_max-1, y_max-1 ); glVertex2i( x_min+1, y_max-1 );
+ glEnd();
+
+ glColor3f( .5, .5, .5 );
+ glBegin( GL_LINE_LOOP );
+ glVertex2i( x_min, y_min );
+ glVertex2i( x_max-1, y_min );
+ glVertex2i( x_max-1, y_max-1 );
+ glVertex2i( x_min, y_max-1 );
+ glEnd();
+}
+
+
+
+/******* GLUT_Control::draw_recursive() **********/
+
+void GLUI_Control::draw_recursive( int x, int y )
+{
+ GLUI_Control *node;
+
+ /* printf( "%s %d\n", this->name.c_str(), this->hidden );*/
+ if ( NOT can_draw() )
+ return;
+
+ /*if ( 1 ) { -- Debugging to check control width
+ glColor3f( 1.0, 0.0, 0.0 );
+ glBegin( GL_LINES );
+ glVertex2i( x_abs, y_abs );00
+ glVertex2i( x_abs+w, y_abs );
+
+ glEnd();
+ }*/
+
+ glMatrixMode( GL_MODELVIEW );
+ glPushMatrix();
+
+ glTranslatef( (float) this->x_abs + .5,
+ (float) this->y_abs + .5,
+ 0.0 );
+
+ if ( NOT _glui_draw_border_only ) {
+ if ( NOT strcmp( name.c_str(), "Rollout" ) ) {
+ }
+
+ this->draw( this->x_off, this->y_off_top );
+ }
+ else
+ {
+ if ( this->dynamicCastGLUI_Column() ) {
+ /* printf( "%s w/h: %d/%d\n", (char*) name, w, h ); */
+ /*w = 2; */
+ }
+
+ /* The following draws the area of each control */
+ glColor3f( 1.0, 0.0, 0.0 );
+ glBegin( GL_LINE_LOOP );
+ glVertex2i( 0, 0 ); glVertex2i( w, 0 );
+ glVertex2i( w, h ); glVertex2i( 0, h );
+ glEnd();
+ }
+ glPopMatrix();
+
+ node = (GLUI_Control*) first_child();
+ while( node ) {
+ node->draw_recursive( node->x_abs, node->y_abs );
+ node = (GLUI_Control*) node->next();
+ }
+}
+
+
+/****** GLUI_Control::set_to_glut_window() *********/
+/* Sets the current window to the glut window associated with this control */
+
+int GLUI_Control::set_to_glut_window()
+{
+ int orig_window;
+
+ if ( NOT glui)
+ return 1;
+
+ orig_window = glutGetWindow();
+
+ glutSetWindow( glui->get_glut_window_id());
+
+ return orig_window;
+}
+
+
+/********** GLUI_Control::restore_window() *********/
+
+void GLUI_Control::restore_window(int orig)
+{
+ if ( orig > 0 )
+ glutSetWindow( orig );
+}
+
+
+
+/****************************** Text ***************************/
+
+/*************** GLUI_Control::set_font() **********/
+
+void GLUI_Control::set_font(void *new_font)
+{
+ font = new_font;
+ redraw();
+}
+
+
+/********** GLUI_Control::draw_string() ************/
+
+void GLUI_Control::draw_string( const char *text )
+{
+ _glutBitmapString( get_font(), text );
+}
+
+
+/**************** GLUI_Control::draw_char() ********/
+
+void GLUI_Control::draw_char(char c)
+{
+ glutBitmapCharacter( get_font(), c );
+}
+
+
+/*********** GLUI_Control::string_width() **********/
+
+int GLUI_Control::string_width(const char *text)
+{
+ return _glutBitmapWidthString( get_font(), text );
+}
+
+
+/************* GLUI_Control::char_width() **********/
+
+int GLUI_Control::char_width(char c)
+{ /* Hash table for faster character width lookups - JVK
+ Speeds up the textbox a little bit.
+ */
+ int hash_index = c % CHAR_WIDTH_HASH_SIZE;
+ if (char_widths[hash_index][0] != c) {
+ char_widths[hash_index][0] = c;
+ char_widths[hash_index][1] = glutBitmapWidth( get_font(), c );
+ }
+ return char_widths[hash_index][1];
+}
+
+
+/*************** GLUI_Control::get_font() **********/
+
+void *GLUI_Control::get_font( void )
+{
+ /*** Does this control have its own font? ***/
+ if ( this->font != NULL )
+ return this->font;
+
+ /*** Does the parent glui have a font? ***/
+ if ( glui )
+ return glui->font;
+
+ /*** Return the default font ***/
+ return GLUT_BITMAP_HELVETICA_12;
+}
+
+
+/************* GLUI_Control::draw_name() ***********/
+/* This draws the name of the control as either black (if enabled), or */
+/* embossed if disabled. */
+
+void GLUI_Control::draw_name(int x, int y)
+{
+ if ( NOT can_draw() )
+ return;
+
+ if ( enabled )
+ {
+ set_to_bkgd_color();
+ glRasterPos2i(x+1, y+1);
+ draw_string(name);
+ glColor3b( 0, 0, 0 );
+ glRasterPos2i(x, y);
+ draw_string(name);
+ }
+ else
+ { /* Control is disabled - emboss the string */
+ glColor3f( 1.0f, 1.0f, 1.0f );
+ glRasterPos2i(x+1, y+1);
+ draw_string(name);
+ glColor3f( .4f, .4f, .4f );
+ glRasterPos2i(x, y);
+ draw_string(name);
+ }
+}
+
+
+/**************************** Layout and Packing *********************/
+
+/****** GLUI_Control::align() **************/
+
+void GLUI_Control::align()
+{
+ int col_x, col_y, col_w, col_h, col_x_off, col_y_off;
+ int orig_x_abs;
+
+ orig_x_abs = x_abs;
+
+ /* Fix alignment bug relating to columns */
+ /*return; */
+
+ if ( NOT parent() )
+ return; /* Clearly this shouldn't happen, though */
+
+ get_this_column_dims(&col_x, &col_y, &col_w, &col_h,
+ &col_x_off, &col_y_off);
+
+ if ( this->dynamicCastGLUI_Column() ) {
+ /* if ( this->prev() != NULL ) {
+ ((GLUI_Control*)prev())->get_this_column_dims(&col_x, &col_y, &col_w, &col_h,
+ &col_x_off, &col_y_off);
+
+ x_abs = col_x + col_w;
+ }
+ else {
+ x_abs = ((GLUI_Control*)parent())->x_abs;
+ }
+ */
+ return;
+ }
+
+ if ( alignment == GLUI_ALIGN_LEFT ) {
+ x_abs = col_x + col_x_off;
+ }
+ else if ( alignment == GLUI_ALIGN_RIGHT ) {
+ x_abs = col_x + col_w - col_x_off - this->w;
+ }
+ else if ( alignment == GLUI_ALIGN_CENTER ) {
+ x_abs = col_x + (col_w - this->w) / 2;
+ }
+
+ if ( this->is_container ) {
+ /*** Shift all child columns ***/
+ int delta = x_abs - orig_x_abs;
+
+ GLUI_Control *node;
+
+ node = (GLUI_Control*) this->first_child();
+ while( node != NULL ) {
+ if ( node->dynamicCastGLUI_Column() ) {
+ node->x_abs += delta;
+ }
+
+ node = (GLUI_Control*) node->next();
+ }
+ }
+
+}
+
+
+/************** GLUI_Control::pack() ************/
+/* Recalculate positions and offsets */
+
+void GLUI_Control::pack_old(int x, int y)
+{
+ GLUI_Control *node;
+ int max_w, curr_y, curr_x, max_y;
+ int x_in = x, y_in =y;
+ int x_margin, y_margin_top, y_margin_bot;
+ int y_top_column;
+ int column_x;
+ GLUI_Column *curr_column = NULL;
+ this->update_size();
+ x_margin = this->x_off;
+ y_margin_top = this->y_off_top;
+ y_margin_bot = this->y_off_bot;
+ this->x_abs = x_in;
+ this->y_abs = y_in;
+ max_w = -1;
+ max_y = -1;
+ curr_x = this->x_abs + x_margin;
+ curr_y = this->y_abs + y_margin_top;
+ /*** Record start of this set of columns ***/
+ y_top_column = curr_y;
+ column_x = 0;
+ if ( this == glui->main_panel ) {
+ x=x;
+ }
+ /*** Iterate over children, packing them first ***/
+ node = (GLUI_Control*) this->first_child();
+ while( node != NULL ) {
+ if ( node->dynamicCastGLUI_Panel() && !node->collapsible) {
+ /* Pad some space above fixed size panels */
+ curr_y += GLUI_ITEMSPACING;
+ }
+ else if ( node->dynamicCastGLUI_Column()) {
+ curr_column = (GLUI_Column*) node;
+ if ( 1 ) {
+ column_x += max_w + 2 * x_margin;
+ curr_x += max_w + 2 * x_margin;
+ }
+ else {
+ column_x += max_w + 0 * x_margin;
+ curr_x += max_w + 0 * x_margin;
+ }
+ /*node->pack( curr_x, curr_y ); */
+ node->x_abs = curr_x;
+ node->y_abs = y_top_column;
+ node->w = 2;
+ node->h = curr_y - y_top_column;
+ curr_x += x_margin * 3 + 40;
+ curr_y = y_top_column;
+ max_w = 0;
+ node = (GLUI_Control*) node->next();
+ continue;
+ }
+ node->pack( curr_x, curr_y );
+ if ( node->dynamicCastGLUI_Panel() && !node->collapsible)
+ /* Pad some space below fixed size panels */
+ curr_y += GLUI_ITEMSPACING;
+ curr_y += node->h;
+ if ( node->w > max_w ) {
+ max_w = node->w;
+ if ( curr_column != NULL )
+ curr_column->w = max_w;
+ }
+ node = (GLUI_Control*) node->next();
+ if ( node ) {
+ curr_y += GLUI_ITEMSPACING;
+ }
+ if ( curr_y > max_y )
+ max_y = curr_y;
+ }
+ if ( this->is_container ) {
+ max_y += y_margin_bot; /*** Add bottom border inside box */
+ if ( this->first_child() ) {
+ if ( this->dynamicCastGLUI_Rollout() ) {
+ /** We don't want the rollout to shrink in width when it's
+ closed **/
+ this->w = MAX(this->w, column_x + max_w + 2 * x_margin );
+ }
+ else {
+ this->w = column_x + max_w + 2 * x_margin;
+ }
+ this->h = (max_y - y_in);
+ }
+ else { /* An empty container, so just assign default w & h */
+ this->w = GLUI_DEFAULT_CONTROL_WIDTH;
+ this->h = GLUI_DEFAULT_CONTROL_HEIGHT;
+ }
+ /** Expand panel if necessary (e.g., to include all the text in
+ a panel label) **/
+ this->update_size();
+ }
+}
+
+/*** GLUI_Control::get_this_column_dims() **********/
+/* Gets the x,y,w,h,and x/y offsets of the column to which a control belongs */
+
+void GLUI_Control::get_this_column_dims( int *col_x, int *col_y,
+ int *col_w, int *col_h,
+ int *col_x_off, int *col_y_off )
+{
+ GLUI_Control *node, *parent_ptr;
+ int parent_h, parent_y_abs;
+
+ parent_ptr = (GLUI_Control*) parent();
+
+ if ( parent_ptr==NULL )
+ return;
+
+ parent_h = parent_ptr->h;
+ parent_y_abs = parent_ptr->y_abs;
+
+ if ( parent_ptr->dynamicCastGLUI_Panel() AND
+ parent_ptr->int_val == GLUI_PANEL_EMBOSSED AND
+ parent_ptr->name != "" ) {
+ parent_h -= GLUI_PANEL_EMBOSS_TOP;
+ parent_y_abs += GLUI_PANEL_EMBOSS_TOP;
+ }
+
+ if ( 0 ) {
+ GLUI_Node *first, *last, *curr;
+
+ /** Look for first control in this column **/
+ first = this;
+ while (first->prev() AND !(first->prev())->dynamicCastGLUI_Column() )
+ first = first->prev();
+
+ /** Look for last control in this column **/
+ last = this;
+ while ( last->next() AND !(first->next())->dynamicCastGLUI_Column() )
+ last = last->next();
+
+ curr = first;
+ int max_w = -1;
+ do {
+ if ( ((GLUI_Control*)curr)->w > max_w )
+ max_w = ((GLUI_Control*)curr)->w;
+
+ if ( curr == last )
+ break;
+
+ curr = curr->next();
+ } while( curr != NULL );
+
+ *col_x = ((GLUI_Control*)first)->x_abs;
+ *col_y = ((GLUI_Control*)first)->y_abs;
+ *col_w = max_w;
+ if ( parent() ) {
+ *col_h = ((GLUI_Control*)parent())->h;
+ *col_x_off = ((GLUI_Control*)parent())->x_off;
+ }
+ else {
+ *col_h = 10;
+ *col_x_off = 0;
+ }
+ *col_y_off = 0;
+
+ return;
+ }
+
+ if ( 1 ) { /* IS THIS WRONG? */
+ /*** Look for preceding column ***/
+ node = (GLUI_Control*) this->prev();
+ while( node ) {
+ if ( node->dynamicCastGLUI_Column() ) {
+ *col_x = node->x_abs;
+ *col_y = parent_y_abs;
+ *col_w = node->w;
+ *col_h = parent_h;
+ *col_x_off = node->x_off;
+ *col_y_off = 0;
+
+ return;
+ }
+
+ node = (GLUI_Control*) node->prev();
+ }
+
+ /*** Nope, Look for next column ***/
+ node = (GLUI_Control*) this->next();
+ while( node ) {
+ if ( node->dynamicCastGLUI_Column() ) {
+ *col_x = parent_ptr->x_abs;
+ *col_y = parent_y_abs;
+ *col_w = node->x_abs - parent_ptr->x_abs;
+ *col_h = parent_h;
+ *col_x_off = node->x_off;
+ *col_y_off = 0;
+
+ return;
+ }
+
+ node = (GLUI_Control*) node->next();
+ }
+
+ /*** This is single-column panel, so return panel dims ***/
+ *col_x = parent_ptr->x_abs;
+ *col_y = parent_y_abs;
+ *col_w = parent_ptr->w;
+ *col_h = parent_h;
+ *col_x_off = parent_ptr->x_off;
+ *col_y_off = 0;
+ }
+}
+
+
+void GLUI_Control::pack( int x, int y )
+{
+ GLUI_Control *node;
+ int max_w, curr_y, curr_x, max_y;
+ int x_in = x, y_in =y;
+ int x_margin, y_margin_top, y_margin_bot;
+ int y_top_column;
+ int column_x;
+ GLUI_Column *curr_column = NULL;
+
+ this->update_size();
+
+ x_margin = this->x_off;
+ y_margin_top = this->y_off_top;
+ y_margin_bot = this->y_off_bot;
+
+ this->x_abs = x_in;
+ this->y_abs = y_in;
+
+ max_w = 0;
+ max_y = 0;
+ curr_x = this->x_abs + x_margin;
+ curr_y = this->y_abs + y_margin_top;
+
+ /*** Record start of this set of columns ***/
+
+ y_top_column = curr_y;
+ column_x = curr_x;
+
+ /*** Iterate over children, packing them first ***/
+
+ node = (GLUI_Control*) this->first_child();
+ while( node != NULL ) {
+ if ( node->dynamicCastGLUI_Panel() && !node->collapsible) {
+ /* Pad some space above fixed-size panels */
+ curr_y += GLUI_ITEMSPACING;
+ }
+ else if ( node->dynamicCastGLUI_Column() ) {
+ curr_column = (GLUI_Column*) node;
+ curr_x += max_w + 1 * x_margin;
+ column_x = curr_x;
+
+ node->x_abs = curr_x;
+ node->y_abs = y_top_column;
+ node->w = 2;
+ node->h = curr_y - y_top_column;
+
+ curr_x += x_margin * 1;
+ curr_y = y_top_column;
+ max_w = 0;
+
+ node = (GLUI_Control*) node->next();
+ continue;
+ }
+
+ node->pack( curr_x, curr_y );
+
+ if ( node->dynamicCastGLUI_Panel() && !node->collapsible)
+ /* Pad some space below fixed-size panels */
+ curr_y += GLUI_ITEMSPACING;
+
+ curr_y += node->h;
+
+ if ( node->w > max_w ) {
+ max_w = node->w;
+ if ( curr_column != NULL )
+ curr_column->w = max_w + x_margin;
+ }
+
+ if ( curr_y > max_y ) {
+ max_y = curr_y;
+ if ( curr_column != NULL )
+ curr_column->h = max_y - y_top_column;
+ }
+
+ node = (GLUI_Control*) node->next();
+
+ if ( node ) {
+ curr_y += GLUI_ITEMSPACING;
+ }
+
+ }
+
+ if ( this->is_container ) {
+ max_y += y_margin_bot; /*** Add bottom border inside box */
+
+ if ( this->first_child() ) {
+ this->w = column_x + max_w + 2 * x_margin - x_in;
+ this->h = (max_y - y_in);
+ }
+ else { /* An empty container, so just assign default w & h */
+ if ( !this->dynamicCastGLUI_Rollout() &&
+ !this->dynamicCastGLUI_Tree() ) {
+ this->w = GLUI_DEFAULT_CONTROL_WIDTH;
+ this->h = GLUI_DEFAULT_CONTROL_HEIGHT;
+ }
+ }
+
+ /** Expand panel if necessary (e.g., to include all the text in
+ a panel label) **/
+ this->update_size();
+
+
+ /*** Now we step through the GLUI_Columns, setting the 'h' ***/
+ node = (GLUI_Control*) this->first_child();
+ while( node != NULL ) {
+ if ( node->dynamicCastGLUI_Column() ) {
+ node->h = this->h - y_margin_bot - y_margin_top;
+ }
+
+ node = (GLUI_Control*) node->next();
+ }
+ }
+}
+
+
+
+/******************************** Live Variables **************************/
+/*********** GLUI_Control::sync_live() ************/
+/* Reads live variable and sets control to its current value */
+/* This function is recursive, and operates on control's children */
+
+void GLUI_Control::sync_live(int recurse, int draw_it)
+{
+ GLUI_Node *node;
+ int sync_it=true;
+ int i;
+ float *fp;
+ bool changed = false;
+
+ /*** If this is currently active control, and mouse button is down,
+ don't sync ***/
+ if ( glui )
+ {
+ if ( this == glui->active_control AND glui->mouse_button_down )
+ sync_it = false;
+
+ /*** Actually, just disable syncing if button is down ***/
+ /*** Nope, go ahead and sync if mouse is down - this allows syncing in
+ callbacks ***/
+ if ( 0 ) { /* THIS CODE BELOW SHOULD NOT BE EXECUTED */
+ if ( glui->mouse_button_down ) {
+ /* printf( "Can't sync\n" ); */
+ return;
+ }
+ }
+ }
+
+ /*** If this control has a live variable, we check its current value
+ against the stored value in the control ***/
+
+ if ( ptr_val != NULL ) {
+ if ( live_type == GLUI_LIVE_NONE OR NOT sync_it ) {
+ }
+ else if ( live_type == GLUI_LIVE_INT ) {
+ if ( *((int*)ptr_val) != last_live_int ) {
+ set_int_val( *((int*)ptr_val) );
+ last_live_int = *((int*)ptr_val);
+ changed = true;
+ }
+ }
+ else if ( live_type == GLUI_LIVE_FLOAT ) {
+ if ( *((float*)ptr_val) != last_live_float ) {
+ set_float_val( *((float*)ptr_val) );
+ last_live_float = *((float*)ptr_val);
+ changed = true;
+ }
+ }
+ else if ( live_type == GLUI_LIVE_TEXT ) {
+ if ( last_live_text.compare((const char*)ptr_val) != 0 ) {
+ set_text( (char*) ptr_val );
+ last_live_text = (const char*)ptr_val;
+ changed = true;
+ }
+ }
+ else if ( live_type == GLUI_LIVE_STRING ) {
+ if ( last_live_text.compare(((std::string*) ptr_val)->c_str()) != 0 ) {
+ set_text( ((std::string*) ptr_val)->c_str());
+ last_live_text = *((std::string*) ptr_val);
+ changed = true;
+ }
+ }
+ else if ( live_type == GLUI_LIVE_FLOAT_ARRAY ) {
+ /*** Step through the arrays, and see if they're the same ***/
+
+ fp = (float*) ptr_val;
+ for ( i=0; i<float_array_size; i++ ) {
+ if ( *fp != last_live_float_array[i] ) {
+ changed = true;
+ break;
+ }
+
+ fp++;
+ }
+
+ if ( changed == true) {
+ fp = (float*) ptr_val;
+ set_float_array_val( fp );
+ for ( i=0; i<float_array_size; i++ ) {
+ last_live_float_array[i] = *fp;
+ fp++;
+ }
+ }
+ }
+ else if ( live_type == GLUI_LIVE_DOUBLE ) {
+ }
+ }
+
+ /*** If this control is changed and we're supposed to be drawing, then
+ draw it now ***/
+ if ( changed == true AND draw_it ) {
+ redraw();
+ }
+
+ if ( recurse ) {
+ /*** Now recursively output live vars for all children ***/
+ node = this->first_child();
+ while( node ) {
+ ((GLUI_Control*) node)->sync_live(true, true);
+ node = node->next();
+ }
+
+ if ( collapsible == true AND is_open == false ) {
+ /** Here we have a collapsed control (e.g., a rollout that is closed **/
+ /** We need to go in and sync all the collapsed controls inside **/
+
+ node = this->collapsed_node.first_child();
+ while( node ) {
+ ((GLUI_Control*) node)->sync_live(true, false);
+ node = node->next();
+ }
+ }
+ }
+}
+
+
+/********** GLUI_Control::output_live() ************/
+/* Writes current value of control to live variable. */
+
+void GLUI_Control::output_live(int update_main_gfx)
+{
+ int i;
+ float *fp;
+
+ if ( ptr_val == NULL )
+ return;
+
+ if ( NOT live_inited )
+ return;
+
+ if ( live_type == GLUI_LIVE_NONE ) {
+ }
+ else if ( live_type == GLUI_LIVE_INT ) {
+ *((int*)ptr_val) = int_val;
+ last_live_int = int_val;
+ }
+ else if ( live_type == GLUI_LIVE_FLOAT ) {
+ *((float*)ptr_val) = float_val;
+ last_live_float = float_val;
+ }
+ else if ( live_type == GLUI_LIVE_TEXT ) {
+ strncpy( (char*) ptr_val, text.c_str(), text.length()+1);
+ last_live_text = text;
+ }
+ else if ( live_type == GLUI_LIVE_STRING ) {
+ (*(std::string*)ptr_val)= text.c_str();
+ last_live_text = text;
+ }
+ else if ( live_type == GLUI_LIVE_FLOAT_ARRAY ) {
+ fp = (float*) ptr_val;
+
+ for( i=0; i<float_array_size; i++ ) {
+ *fp = float_array_val[i];
+ last_live_float_array[i] = float_array_val[i];
+ fp++;
+ }
+ }
+ else if ( live_type == GLUI_LIVE_DOUBLE ) {
+ }
+
+ /** Update the main gfx window? **/
+ if ( update_main_gfx AND this->glui != NULL ) {
+ this->glui->post_update_main_gfx();
+ }
+}
+
+
+/****** GLUI_Control::execute_callback() **********/
+
+void GLUI_Control::execute_callback()
+{
+ int old_window;
+
+ old_window = glutGetWindow();
+
+ if ( glui AND glui->main_gfx_window_id != -1 )
+ glutSetWindow( glui->main_gfx_window_id );
+
+ this->callback( this );
+// if ( this->callback )
+// this->callback( this->user_id );
+
+ glutSetWindow( old_window );
+}
+
+
+/************** GLUI_Control::init_live() **********/
+/* Reads in value of a live variable. Called once, when ctrl is created */
+
+void GLUI_Control::init_live()
+{
+ int i;
+ float *fp;
+
+ if ( ptr_val == NULL )
+ return;
+
+ if ( live_type == GLUI_LIVE_NONE ) {
+ }
+ else if ( live_type == GLUI_LIVE_INT ) {
+ set_int_val( *((int*)ptr_val) );
+ last_live_int = *((int*)ptr_val);
+ }
+ else if ( live_type == GLUI_LIVE_FLOAT ) {
+ set_float_val( *((float*)ptr_val) );
+ last_live_float = *((float*)ptr_val);
+ }
+ else if ( live_type == GLUI_LIVE_TEXT ) {
+ set_text( (const char*) ptr_val );
+ last_live_text = (const char*) ptr_val;
+ }
+ else if ( live_type == GLUI_LIVE_STRING ) {
+ set_text( ((std::string*) ptr_val)->c_str() );
+ last_live_text = ((std::string*) ptr_val)->c_str();
+ }
+ else if ( live_type == GLUI_LIVE_FLOAT_ARRAY ) {
+ set_float_array_val( (float*) ptr_val );
+
+ fp = (float*) ptr_val;
+
+ for( i=0; i<float_array_size; i++ ) {
+ last_live_float_array[i] = *fp;
+ fp++;
+ }
+
+ }
+ else if ( live_type == GLUI_LIVE_DOUBLE ) {
+ }
+
+ live_inited = true;
+}
+
+/***** GLUI_Control::set_float_array_val() ********/
+
+void GLUI_Control::set_float_array_val( float *array_ptr )
+{
+ int i;
+
+ if ( array_ptr == NULL )
+ return;
+
+ for( i=0; i<float_array_size; i++ ) {
+ float_array_val[i] = array_ptr[i];
+ }
+
+ /*** Output the live var, without updating the main gfx window ***/
+ output_live(false);
+}
+
+
+/***** GLUI_Control::get_float_array_val() ********/
+
+void GLUI_Control::get_float_array_val( float *array_ptr )
+{
+ int i;
+
+ if ( array_ptr == NULL )
+ return;
+
+ for( i=0; i<float_array_size; i++ ) {
+ array_ptr[i] = float_array_val[i];
+ }
+}
+
+
+
+/**************************** Little Utility Routines ********************/
+
+/**** GLUI_Control::set_name() ********************/
+
+void GLUI_Control::set_name( const char *str )
+{
+ name = str;
+ redraw();
+}
+
+/**** GLUI_Control::enable() ****************/
+
+void GLUI_Control::enable()
+{
+ GLUI_Control *node;
+
+ enabled = true;
+
+ if ( NOT glui )
+ return;
+
+ redraw();
+
+ /*** Now recursively enable all buttons below it ***/
+ node = (GLUI_Control*) first_child();
+ while(node)
+ {
+ node->enable();
+ node = (GLUI_Control*) node->next();
+ }
+}
+
+
+/***** GLUI_Control::disable() ****************/
+
+void GLUI_Control::disable()
+{
+ GLUI_Control *node;
+
+ enabled = false;
+
+ if ( NOT glui )
+ return;
+
+ if ( glui->active_control == this )
+ glui->deactivate_current_control();
+ redraw();
+
+ /*** Now recursively disable all buttons below it ***/
+ node = (GLUI_Control*) first_child();
+ while(node) {
+ node->disable();
+ node = (GLUI_Control*) node->next();
+ }
+}
+
+/******* GLUI_Control::set_w() **************/
+
+void GLUI_Control::set_w(int new_w)
+{
+ w = new_w;
+ update_size(); /* Make sure control is big enough to fit text */
+ if (glui) glui->refresh();
+}
+
+
+/**** GLUI_Control::set_h() **************/
+
+void GLUI_Control::set_h(int new_h)
+{
+ h = new_h;
+ update_size(); /* Make sure control is big enough to fit text */
+ if (glui) glui->refresh();
+}
+
+
+/***** GLUI_Control::set_alignment() ******/
+
+void GLUI_Control::set_alignment(int new_align)
+{
+ alignment = new_align;
+
+ if ( glui )
+ {
+ glui->align_controls(this);
+ redraw_window();
+ }
+}
+
+
+/***** GLUI_Control::needs_idle() *********/
+/* This method gets overloaded by specific classes, e.g. Spinner. */
+/* It returns whether or not a control needs to receive an idle event or not */
+/* For example, a spinner only needs idle events when the user is holding */
+/* the mouse down in one of the arrows. Otherwise, don't waste cycles */
+/* and OpenGL context switching by calling its idle. */
+
+bool GLUI_Control::needs_idle() const
+{
+ return false;
+}
+
+
+/********* GLUI_Control::~GLUI_Control() **********/
+
+GLUI_Control::~GLUI_Control()
+{
+ GLUI_Control *item = (GLUI_Control*) this->first_child();
+
+ while (item)
+ {
+ GLUI_Control *tmp = item;
+ item = (GLUI_Control*) item->next();
+ delete tmp;
+ }
+}
+
+/********* GLUI_Control::hide_internal() ********/
+/** Sets hidden==true for this control and all its siblings. */
+/** If recurse is true, we go to children as well */
+
+void GLUI_Control::hide_internal( int recurse )
+{
+ GLUI_Node *node;
+
+ node = (GLUI_Node *) this;
+ while( node != NULL ) {
+ ((GLUI_Control*)node)->hidden = true;
+
+ if ( recurse AND node->first_child() != NULL )
+ ((GLUI_Control*) node->first_child())->hide_internal(true);
+
+ node = node->next();
+ }
+
+ node = this->collapsed_node.first_child();
+ while( node != NULL ) {
+ ((GLUI_Control*)node)->hidden = true;
+
+ if ( recurse AND node->first_child() != NULL )
+ ((GLUI_Control*) node->first_child())->hide_internal(true);
+
+ node = node->next();
+ }
+}
+
+
+/********* GLUI_Control::unhide_internal() ********/
+/** Sets hidden==false for this control and all its siblings. */
+/** If recurse is true, we go to children as well */
+
+void GLUI_Control::unhide_internal( int recurse )
+{
+ GLUI_Node *node;
+
+ node = (GLUI_Node *) this;
+ while( node != NULL ) {
+ /* printf( "unhide: %s [%d]\n", ((GLUI_Control*)node)->name.c_str(),
+ ((GLUI_Control*)node)->hidden );*/
+ ((GLUI_Control*)node)->hidden = false;
+
+ if ( recurse AND node->first_child() != NULL )
+ ((GLUI_Control*) node->first_child())->unhide_internal(true);
+
+ node = node->next();
+ }
+
+ node = this->collapsed_node.first_child();
+ while( node != NULL ) {
+ ((GLUI_Control*)node)->hidden = false;
+
+ if ( recurse AND node->first_child() != NULL )
+ ((GLUI_Control*) node->first_child())->unhide_internal(true);
+
+ node = node->next();
+ }
+}