text: /****************************************************************************
    
    GLUI User Interface Toolkit
    ---------------------------
  
       glui_panel.cpp - GLUI_Panel 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"
  
  enum {rollout_height_pixels=GLUI_DEFAULT_CONTROL_HEIGHT + 7};
  
  /****************************** GLUI_Rollout::GLUI_Rollout() **********/
  
  GLUI_Rollout::GLUI_Rollout( GLUI_Node *parent, const char *name, 
                              int open, int type )
  {
    common_init();
    set_name( name );
    user_id    = -1;
    int_val    = type;
  		
    if ( NOT open ) {
      is_open = false;
      h = rollout_height_pixels;
    }
  
    parent->add_control( this );
  }
  
  /****************************** GLUI_Rollout::open() **********/
  
  void    GLUI_Rollout::open( void )
  {
    if ( NOT glui )
      return;
  
    if ( is_open )
      return;
    is_open = true;
  
    GLUI_DRAWINGSENTINAL_IDIOM
  
    /* Copy hidden children into our private list "collapsed_node" */
    child_head = collapsed_node.child_head;
    child_tail = collapsed_node.child_tail;
    collapsed_node.child_head = NULL;
    collapsed_node.child_tail = NULL;
  
    if ( child_head != NULL ) {
      ((GLUI_Control*) child_head)->unhide_internal( true );
    }
  
    glui->refresh();
  }
  
  
  /****************************** GLUI_Rollout::close() **********/
  
  void    GLUI_Rollout::close( void )
  {
    if ( NOT glui )
      return;
  
    if ( NOT is_open )
      return;
    is_open = false;
    
    GLUI_DRAWINGSENTINAL_IDIOM
  
    if ( child_head != NULL ) {
      ((GLUI_Control*) child_head)->hide_internal( true );
    }
  
    /* Move all children into a private list of hidden children */
    collapsed_node.child_head = first_child();
    collapsed_node.child_tail = last_child();
    child_head = NULL;
    child_tail = NULL;
  
    this->h = rollout_height_pixels;
  
    glui->refresh();
  }
  
  
  /**************************** GLUI_Rollout::mouse_down_handler() **********/
  
  
  int   GLUI_Rollout::mouse_down_handler( int local_x, int local_y )
  {
    if ( local_y - y_abs > rollout_height_pixels ) {
      initially_inside = currently_inside = false;
      return false;
    }
  
    currently_inside = true;
    initially_inside = true;
    redraw();
  
    return false;
  }
  
  
  /**************************** GLUI_Rollout::mouse_held_down_handler() ****/
  
  int  GLUI_Rollout::mouse_held_down_handler( 
  					   int local_x, int local_y, 
  					   bool new_inside )
  {
    if ( NOT initially_inside )
      return false;
  
    if ( local_y - y_abs> rollout_height_pixels )
      new_inside = false;
    
    if (new_inside != currently_inside) {
       currently_inside = new_inside;
       redraw();
    }
    
    return false;
  }
  
  
  /**************************** GLUI_Rollout::mouse_down_handler() **********/
  
  int   GLUI_Rollout::mouse_up_handler( int local_x, int local_y, bool inside )
  {
    if ( currently_inside ) {    
      if ( is_open )
        close();
      else
        open();
    }
  
    currently_inside = false;
    initially_inside = false;
    redraw();
  
    return false;
  }
  
  
  /********************************* GLUI_Rollout::draw() ***********/
  
  void   GLUI_Rollout::draw( int x, int y )
  {
    GLUI_DRAWINGSENTINAL_IDIOM
    
    int left, right, top, bottom;
  
    left   = 5;
    right  = w-left;
    top    = 3;
    bottom = 3+16;
  
    if ( is_open ) 
      draw_emboss_box( 0, w, top+3, h );
    else
      draw_emboss_box( 0, w, top+3, h-7 );
  
    glui->draw_raised_box( left, top, w-left*2, 16 );
  
    if ( glui )
      glColor3ub(glui->bkgd_color.r,glui->bkgd_color.g,glui->bkgd_color.b);
    glDisable( GL_CULL_FACE );
    glBegin( GL_QUADS );
    glVertex2i( left+1, top+1 );      glVertex2i( right-1, top+1 );
    glVertex2i( right-1, bottom-1 );  glVertex2i( left+1, bottom-1 );
    glEnd();
  
    draw_name( left+8, top+11 );
  
    if ( active ) 
      /*draw_active_box( left+4, left+string_width( name.c_str() )+12,       */
      draw_active_box( left+4, right-17, 
  		     top+2, bottom-2 );
  
  
    /**   Draw '+' or '-'  **/
  
    glBegin( GL_LINES );
    if ( is_open ) {
      if ( enabled )		glColor3f( 0.0, 0.0, 0.0 );
      else			glColor3f( 0.5, 0.5, 0.5 );
      glVertex2i(right-14,(top+bottom)/2);  glVertex2i(right-5,(top+bottom)/2);
  
      glColor3f( 1.0, 1.0, 1.0 );
      glVertex2i(right-14,1+(top+bottom)/2);glVertex2i(right-5,1+(top+bottom)/2);
    }
    else
    {
      glColor3f( 1.0, 1.0, 1.0 );
      glVertex2i(right-9,top+3);							glVertex2i(right-9,bottom-4);
      glVertex2i(right-14,(top+bottom)/2);		glVertex2i(right-5,(top+bottom)/2);
  
      if ( enabled )		glColor3f( 0.0, 0.0, 0.0 );
      else			glColor3f( 0.5, 0.5, 0.5 );
      glVertex2i(right-14,-1+(top+bottom)/2);
      glVertex2i(right-5,-1+(top+bottom)/2);
      glVertex2i(right-10,top+3);
      glVertex2i(right-10,bottom-4);
    }
    glEnd();
  
    glLineWidth( 1.0 );
    
    if (currently_inside) {draw_pressed(); /* heavy black outline when pressed */ }
  }
  
  
  /***************************** GLUI_Rollout::update_size() **********/
  
  void   GLUI_Rollout::update_size( void )
  {
    int text_size;
  
    if ( NOT glui )
      return;
  
    text_size = string_width(name);
  
    if ( w < text_size + 36 )
      w = text_size + 36;
  }
  
  
  /**************************** GLUI_Rollout::draw_pressed() ***********/
  
  void   GLUI_Rollout::draw_pressed( void )
  {
    int left, right, top, bottom;
  
    left   = 5;
    right  = w-left;
    top    = 3;
    bottom = 3+16;
  
    
    glColor3f( 0.0, 0.0, 0.0 );
  
    glBegin( GL_LINE_LOOP );
    glVertex2i( left, top );         glVertex2i( right, top );
    glVertex2i( right, bottom );     glVertex2i( left,bottom );
    glEnd();
  
    glBegin( GL_LINE_LOOP );
    glVertex2i( left+1, top+1 );         glVertex2i( right-1, top+1 );
    glVertex2i( right-1, bottom-1 );     glVertex2i( left+1,bottom-1 );
    glEnd();
  }
  