Flu_Combo_Box.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:7k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: Flu_Combo_Box.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 21:05:38  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.2
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*
  10.  * These files were imported into NCBI's CVS directly from FLU version 2.9.1.
  11.  * Modifications to the source are listed below.
  12.  *
  13.  * ==========================================================================
  14.  * $Log: Flu_Combo_Box.cpp,v $
  15.  * Revision 1000.1  2004/06/01 21:05:38  gouriano
  16.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.2
  17.  *
  18.  * Revision 1.2  2004/05/21 22:27:51  gorelenk
  19.  * Added PCH ncbi_pch.hpp
  20.  *
  21.  * Revision 1.1  2004/03/11 13:51:39  dicuccio
  22.  * Imported FLU version 2.9.1.  Altered export specifiers to match NCBI layout.
  23.  * Altered include paths to match NCBI toolkit layout.
  24.  *
  25.  * ==========================================================================
  26.  */
  27. // $Id: Flu_Combo_Box.cpp,v 1000.1 2004/06/01 21:05:38 gouriano Exp $
  28. /***************************************************************
  29.  *                FLU - FLTK Utility Widgets 
  30.  *  Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University
  31.  *
  32.  * This file and its content is protected by a software license.
  33.  * You should have received a copy of this license with this file.
  34.  * If not, please contact the Ohio Supercomputer Center immediately:
  35.  * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212
  36.  * 
  37.  ***************************************************************/
  38. #include <ncbi_pch.hpp>
  39. #include <stdio.h>
  40. #include <FL/Fl.H>
  41. #include <FL/fl_draw.H>
  42. #include <string.h>
  43. #include <stdlib.h>
  44. #include <FL/math.h>
  45. #include <gui/widgets/FLU/Flu_Combo_Box.h>
  46. Flu_Combo_Box :: Flu_Combo_Box( int X, int Y, int W, int H, const char* l )
  47.   : Fl_Group( X, Y, W, H, l ), input( X+2, Y+2, W-20-1-2, H-4 )
  48. {
  49.   box( FL_DOWN_BOX );
  50.   align( FL_ALIGN_LEFT );
  51.   pop_height( 100 );
  52.   _cbox = NULL;
  53.   _valbox = FL_UP_BOX;
  54.   input_callback( NULL );
  55.   input.box( FL_FLAT_BOX );
  56.   input.callback( input_cb, this );
  57.   input.when( FL_WHEN_ENTER_KEY_ALWAYS );
  58.   input.color( FL_WHITE, selection_color());
  59.   input.textfont( FL_HELVETICA );
  60.   input.textsize(  FL_NORMAL_SIZE );
  61.   input.textcolor( FL_FOREGROUND_COLOR );
  62.   editable( true );
  63.   end();
  64. }
  65. Flu_Combo_Box::~Flu_Combo_Box()
  66. {
  67. }
  68. void Flu_Combo_Box :: set_combo_widget( Fl_Widget *w )
  69. {
  70.   _cbox = w;
  71.   this->add( w );
  72. }
  73. void Flu_Combo_Box :: input_cb( Fl_Widget*, void* v )
  74. {
  75.   // taken from Fl_Counter.cxx
  76.   Flu_Combo_Box& t = *(Flu_Combo_Box*)v;
  77.   if( strcmp( t.input.value(), t.value() )!=0 || t.input.when() & FL_WHEN_NOT_CHANGED)
  78.     {
  79.       if( t.when() )
  80. {
  81.   t.clear_changed();
  82.   if( t._inputCB )
  83.     t._inputCB( &t, t._inputCBD );
  84.   else
  85.     t.do_callback();
  86. }
  87.       else
  88. {
  89.   t.set_changed();
  90. }
  91.     }
  92. }
  93. void Flu_Combo_Box :: resize( int X, int Y, int W, int H )
  94. {
  95.   Fl_Group::resize( X, Y, W, H );
  96.   input.resize( X+2, Y+2, W-20-1-2, H-4 );
  97. }
  98. void Flu_Combo_Box :: draw()
  99. {
  100.   int W = 18, H = h()-4;
  101.   int X = x()+w()-W-2, Y = y()+2;
  102.   fl_draw_box( box(), x(), y(), w(), h(), color() );
  103.   // draw the arrow button
  104.   fl_draw_box( (Fl_Boxtype)_valbox, X, Y, W, H, color() );
  105.   fl_color( active_r() ? FL_FOREGROUND_COLOR : fl_inactive(FL_FOREGROUND_COLOR) );
  106.   fl_polygon( X+W/2-4, Y+H/2-2, X+W/2+4, Y+H/2-2, X+W/2, Y+H/2+2 );
  107.   draw_child( input );
  108.   if (Fl::focus() == this) draw_focus();
  109. }
  110. Flu_Combo_Box::Popup :: Popup( Flu_Combo_Box *b, Fl_Widget *c, int H )
  111.   : Fl_Double_Window( Fl::x()+b->window()->x()+b->x()-2,
  112.       Fl::y()+b->window()->y()+b->y()+b->h()-2,
  113.       b->w()+4, H, 0 )
  114. {
  115.   combo = b;
  116.   dragging = false;
  117.   selected = NULL;
  118.   box( FL_BORDER_FRAME );
  119.   border( 0 );
  120.   add( c );
  121.   end();
  122.   //set_non_modal();
  123.   set_modal();
  124.   c->resize( 1, 1, w()-2, h()-2 );
  125. }
  126. Flu_Combo_Box::Popup :: ~Popup()
  127. {
  128.   while( children() )
  129.     remove( child(0) );
  130. }
  131. void Flu_Combo_Box :: value( const char *v )
  132. {
  133.   if( _value( v ) )
  134.     input.value( v );
  135. }
  136. void Flu_Combo_Box :: selected( const char *v )
  137. {
  138.   if( v )
  139.     input.value( v );
  140.   _popped = false;
  141.   do_callback();
  142. }
  143. int Flu_Combo_Box::Popup :: handle( int event )
  144. {
  145.   // FL_MOVE is generated while the window is moving
  146.   // this attempts to keep the popup window moving with the enclosing window
  147.   if( event == FL_MOVE )
  148.     position( combo->window()->x()+combo->x()-2, combo->window()->y()+combo->y()+combo->h()-2 );
  149.   if( event == FL_DRAG )
  150.     dragging = true;
  151.   // if push outside the popup window, popdown
  152.   if( event == FL_PUSH &&
  153.       !Fl::event_inside( child(0) ) )
  154.     {
  155.       combo->_popped = false;
  156.       return 0;
  157.     }
  158.   // if release after dragging outside the popup window, popdown
  159.   if( event == FL_RELEASE && dragging && 
  160.       !Fl::event_inside( child(0) ) )
  161.     {
  162.       combo->_popped = false;
  163.       return 0;
  164.     }
  165.   if( event == FL_KEYDOWN )
  166.     {
  167.       if( Fl::event_key( FL_Escape ) )
  168. {
  169.   combo->_popped = false;
  170.   return 0;
  171. }
  172.       else if( Fl::event_key( FL_Up ) )
  173. {
  174.   selected = combo->_previous();
  175.   return 1;
  176. }
  177.       else if( Fl::event_key( FL_Down ) )
  178. {
  179.   selected = combo->_next();
  180.   return 1;
  181. }
  182.       else if( Fl::event_key( FL_Enter ) || Fl::event_key( ' ' ) )
  183. {
  184.   if( selected )
  185.     {
  186.       combo->value( selected );
  187.       combo->selected( selected );
  188.     }
  189.   combo->_popped = false;
  190.   return 1;   
  191. }
  192.     }
  193.   return Fl_Double_Window::handle( event );
  194. }
  195. int Flu_Combo_Box :: handle( int event )
  196. {
  197.   if( event == FL_KEYDOWN && Fl::event_key( FL_Tab ) )
  198.     return Fl_Group::handle( event );
  199.   // is it time to popup?
  200.   bool open = ( event == FL_PUSH ) && 
  201.     (!Fl::event_inside( &input ) || ( !editable() && Fl::event_inside( &input ) ) );
  202.   open |= ( event == FL_KEYDOWN ) && Fl::event_key( ' ' );
  203.   if( open )
  204.     {
  205.       fl_cursor( FL_CURSOR_DEFAULT );
  206.       _valbox = FL_THIN_DOWN_BOX;
  207.       redraw();
  208.       // remember old current group
  209.       Fl_Group *c = Fl_Group::current();
  210.       // set current group to 0 so this is a top level popup window
  211.       Fl_Group::current( 0 );
  212.       Popup *_popup = new Popup( this, _cbox, popHeight );
  213.       // show it and make FLTK send all events there
  214.       value( value() );
  215.       _popup->show();
  216.       Fl::grab( *_popup );
  217.       Fl::focus( _cbox );
  218.       _popped = true;
  219.       Fl::pushed( _cbox );
  220.       // wait for a selection to be made
  221.       while( _popped )
  222. Fl::wait();
  223.       // restore things and delete the popup
  224.       _popup->hide();
  225.       Fl::grab( 0 );
  226.       delete _popup;
  227.       Fl_Group::current( c );
  228.       Fl::focus( this );
  229.       _valbox = FL_UP_BOX;
  230.       redraw();
  231.       return 1;
  232.     }
  233.   if( input.handle(event) )
  234.     {
  235.       if( !editable() && ( event == FL_ENTER || event == FL_LEAVE ) )
  236. fl_cursor( FL_CURSOR_DEFAULT );
  237.       return 1;
  238.     }
  239.   else
  240.     return 0;
  241. }