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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: Flu_Wrap_Group.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 21:06:11  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_Wrap_Group.cpp,v $
  15.  * Revision 1000.1  2004/06/01 21:06:11  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:40  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_Wrap_Group.cpp,v 1000.1 2004/06/01 21:06:11 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 <gui/widgets/FLU/Flu_Wrap_Group.h>
  40. #include <string.h>
  41. #include <stdio.h>
  42. #define MAX( x, y ) ( (x)>(y) ? (x) : (y) )
  43. #define SCROLL_SIZE 15
  44. Flu_Wrap_Group :: Scrollbar :: Scrollbar( int x, int y, int w, int h, const char *l )
  45.   : Fl_Scrollbar( x, y, w, h, l )
  46. {
  47. }
  48. int Flu_Wrap_Group :: Scrollbar :: handle( int event )
  49. {
  50.   if( event == FL_MOUSEWHEEL )
  51.     {
  52.       handle_drag( clamp( value() + linesize() * Fl::e_dy ) );
  53.       return 1;
  54.     }
  55.   else
  56.     return Fl_Scrollbar::handle( event );
  57. }
  58. Flu_Wrap_Group :: Flu_Wrap_Group( int x, int y, int w, int h, const char *l )
  59.   : Fl_Group( x, y, w, h, l ), scrollbar( x+w-SCROLL_SIZE, y, SCROLL_SIZE, h ), group( x, y, w-SCROLL_SIZE, h )
  60. {
  61.   offset( 0, 0 );
  62.   spacing( 0, 0 );
  63.   _type = FL_VERTICAL;
  64.   scrollTo = NULL;
  65.   Fl_Group::add( &scrollbar );
  66.   scrollbar.callback( _scrollCB, this );
  67.   scrollbar.linesize( 10 );
  68.   scrollbar.range( 0, 100 );
  69.   scrollbar.show();
  70.   Fl_Group::add( &group );
  71.   Fl_Group::resizable( group );
  72.   Fl_Group::end();
  73.   group.begin();
  74. }
  75. void Flu_Wrap_Group :: resize( int x, int y, int w, int h )
  76. {
  77.   group.resizable( NULL );
  78.   Fl_Group::resize( x, y, w, h );
  79.   if( type() == FL_VERTICAL )
  80.     {
  81.       scrollbar.resize( x+w-SCROLL_SIZE-Fl::box_dx(box()), y+Fl::box_dy(box()), SCROLL_SIZE, h-Fl::box_dh(box()) );
  82.       group.resize( x, y, w-SCROLL_SIZE-Fl::box_dx(box()), h );
  83.     }
  84.   else
  85.     {
  86.       scrollbar.resize( x+Fl::box_dx(box()), y+h-SCROLL_SIZE-Fl::box_dy(box()), w-Fl::box_dw(box()), SCROLL_SIZE );
  87.       group.resize( x, y, w, h-SCROLL_SIZE-Fl::box_dh(box()) );
  88.     }
  89.   Fl_Group::init_sizes();
  90.   redraw();
  91. }
  92. void Flu_Wrap_Group :: scroll_to( const Fl_Widget *w )
  93. {
  94.   scrollTo = w;
  95.   redraw();
  96. }
  97. void Flu_Wrap_Group :: scroll_to_beginning()
  98. {
  99.   ((Fl_Valuator*)&scrollbar)->value( scrollbar.minimum() );
  100. }
  101. void Flu_Wrap_Group :: scroll_to_end()
  102. {
  103.   ((Fl_Valuator*)&scrollbar)->value( scrollbar.maximum() );
  104. }
  105. void Flu_Wrap_Group :: type( int t )
  106. {
  107.   _type = t;
  108.   resize( x(), y(), w(), h() );
  109. }
  110. Fl_Widget* Flu_Wrap_Group :: next( Fl_Widget* w )
  111. {
  112.   for( int i = 0; i < group.children()-1; i++ )
  113.     {
  114.       if( w == group.child(i) )
  115. return group.child(i+1);
  116.     }
  117.   return NULL;
  118. }
  119. Fl_Widget* Flu_Wrap_Group :: previous( Fl_Widget* w )
  120. {
  121.   for( int i = 1; i < group.children(); i++ )
  122.     {
  123.       if( w == group.child(i) )
  124. return group.child(i-1);
  125.     }
  126.   return NULL;
  127. }
  128. Fl_Widget* Flu_Wrap_Group :: above( Fl_Widget* w )
  129. {
  130.   for( int i = 0; i < group.children(); i++ )
  131.     {
  132.       if( w == group.child(i) )
  133. {
  134.   int measure[2];
  135.   measure[0] = w->x() + w->w()/2;
  136.   measure[1] = w->y() - _spacing[1];
  137.   int index = layout( scrollbar.visible(), false, measure );
  138.   if( index >= 0 )
  139.     return group.child(index);
  140.   else
  141.     return group.child(0);
  142. }
  143.     }
  144.   return NULL;
  145. }
  146. Fl_Widget* Flu_Wrap_Group :: below( Fl_Widget* w )
  147. {
  148.   for( int i = 0; i < group.children(); i++ )
  149.     {
  150.       if( w == group.child(i) )
  151. {
  152.   int measure[2];
  153.   measure[0] = w->x() + w->w()/2;
  154.   measure[1] = w->y() + w->h() + _spacing[1];
  155.   int index = layout( scrollbar.visible(), false, measure );
  156.   if( index >= 0 )
  157.     return group.child(index);
  158.   else
  159.     return group.child(group.children()-1);
  160. }
  161.     }
  162.   return NULL;
  163. }
  164. Fl_Widget* Flu_Wrap_Group :: left( Fl_Widget* w )
  165. {
  166.   for( int i = 0; i < group.children(); i++ )
  167.     {
  168.       if( w == group.child(i) )
  169. {
  170.   int measure[2];
  171.   measure[0] = w->x() - _spacing[0];
  172.   measure[1] = w->y() + w->h()/2;
  173.   int index = layout( scrollbar.visible(), false, measure );
  174.   if( index >= 0 )
  175.     return group.child(index);
  176.   else
  177.     return group.child(0);
  178. }
  179.     }
  180.   return NULL;
  181. }
  182. Fl_Widget* Flu_Wrap_Group :: right( Fl_Widget* w )
  183. {
  184.   for( int i = 0; i < group.children(); i++ )
  185.     {
  186.       if( w == group.child(i) )
  187. {
  188.   int measure[2];
  189.   measure[0] = w->x() + w->w() + _spacing[0] + 1;
  190.   measure[1] = w->y() + w->h()/2;
  191.   int index = layout( scrollbar.visible(), false, measure );
  192.   if( index >= 0 )
  193.     return group.child(index);
  194.   else
  195.     return group.child(group.children()-1);
  196. }
  197.     }
  198.   return NULL;
  199. }
  200. int Flu_Wrap_Group :: layout( bool sbVisible, bool doScrollTo, int *measure )
  201. {
  202.   int xx = x()+Fl::box_dx(box()), yy = y()+Fl::box_dy(box()),
  203.     ww = w()-Fl::box_dw(box()), hh = h()-Fl::box_dh(box());
  204.   if( type() == FL_VERTICAL )
  205.     {
  206.       int i, X, Y, maxH, H, col, row, maxW, scrollY;
  207.       Fl_Widget *c;
  208.       scrollbar.type( FL_VERTICAL );
  209.     BEGIN_H:
  210.       X = xx+_offset[0];
  211.       Y = yy+_offset[1] - (sbVisible ? scrollbar.value() : 0);
  212.       maxH = _offset[1];
  213.       H = 0;
  214.       col = 0;
  215.       row = 0;
  216.       scrollY = 0;
  217.       maxW = xx + ww - (sbVisible ? scrollbar.w() : 0);
  218.       for( i = 0; i < group.children(); i++ )
  219. {
  220.   c = group.child(i);
  221.   if( !c->visible() )
  222.     continue;
  223.   H = MAX( H, c->h() );
  224.   if( col == 0 )
  225.     maxH += H + _spacing[1];
  226.   if( ( X + c->w() ) > maxW )
  227.     {
  228.       Y += H + _spacing[1];
  229.       scrollY += H + _spacing[1];
  230.       if( i == group.children()-1 )
  231. maxH += H + _spacing[1];
  232.       if( measure )
  233. {
  234.   if( xx+_offset[0] <= measure[0] && measure[0] <= xx+c->w()+_offset[0]+_spacing[0] &&
  235.       Y <= measure[1] && measure[1] <= Y+c->h()+_spacing[1] )
  236.     return i;
  237. }
  238.       else
  239. c->position( xx+_offset[0], Y );
  240.       col = 0;
  241.       row++;
  242.       H = 0;
  243.       X = xx+c->w() + _offset[0] + _spacing[0];
  244.     }
  245.   else
  246.     {
  247.       if( measure )
  248. {
  249.   if( X <= measure[0] && measure[0] <= X+c->w()+_spacing[0] &&
  250.       Y <= measure[1] && measure[1] <= Y+c->h()+_spacing[1] )
  251.     return i;
  252. }
  253.       else
  254. c->position( X, Y );
  255.       X += c->w() + _spacing[0];
  256.       col++;
  257.     }
  258.   if( doScrollTo && (c == scrollTo) )
  259.     {
  260.       if( scrollY > scrollbar.maximum() )
  261. scrollY = (int)scrollbar.maximum();
  262.       ((Fl_Valuator*)&scrollbar)->value( scrollY );
  263.       scrollTo = NULL;
  264.       goto BEGIN_H;
  265.     }
  266.   // if we exceed the height and the scrollbar is not visible,
  267.   // then it will soon become visible so we don't need to process anymore
  268.   if( !measure && !sbVisible && maxH > hh )
  269.     return 1;
  270. }
  271.       if( measure )
  272. return -1;
  273.       else if( maxH > hh )
  274. {
  275.   scrollbar.range( 0, maxH-hh );
  276.   scrollbar.slider_size( MAX( float(scrollbar.h()-(maxH-hh))/float(scrollbar.h()), 0.08f ) );
  277.   return 1;
  278. }
  279.       else
  280. return 0;
  281.     }
  282.   else
  283.     {
  284.       int i, X, Y, W, maxW, maxH, col, row, scrollX;
  285.       Fl_Widget *c;
  286.       scrollbar.type( FL_HORIZONTAL );
  287.     BEGIN_W:
  288.       X = xx+_offset[0] - (sbVisible ? scrollbar.value() : 0);
  289.       Y = yy+_offset[1];
  290.       maxW = _offset[0];
  291.       W = 0;
  292.       col = 0;
  293.       row = 0;
  294.       scrollX = 0;
  295.       maxH = yy + hh - (sbVisible ? scrollbar.h() : 0);
  296.       for( i = 0; i < group.children(); i++ )
  297. {
  298.   c = group.child(i);
  299.   if( !c->visible() )
  300.     continue;
  301.   W = MAX( W, c->w() );
  302.   if( row == 0 )
  303.     maxW += W + _spacing[0];
  304.   if( ( Y + c->h() ) > maxH )
  305.     {
  306.       X += W + _spacing[0];
  307.       scrollX += W + _spacing[0];
  308.       if( i == group.children()-1 )
  309. maxW += W + _spacing[0];
  310.       if( measure )
  311. {
  312.   if( X <= measure[0] && measure[0] <= X+c->w()+_spacing[0] &&
  313.       yy+_offset[1] <= measure[1] && measure[1] <= yy+c->h()+_offset[1]+_spacing[1] )
  314.     return i;
  315. }
  316.       else
  317. c->position( X, yy+_offset[1] );
  318.       row = 0;
  319.       col++;
  320.       W = 0;
  321.       Y = yy+c->h() + _offset[1] + _spacing[1];
  322.     }
  323.   else
  324.     {
  325.       if( measure )
  326. {
  327.   if( X <= measure[0] && measure[0] <= X+c->w()+_spacing[0] &&
  328.       Y <= measure[1] && measure[1] <= Y+c->h()+_spacing[1] )
  329.     return i;
  330. }
  331.       else
  332. c->position( X, Y );
  333.       Y += c->h() + _spacing[1];
  334.       row++;
  335.     }
  336.   if( doScrollTo && (c == scrollTo) )
  337.     {
  338.       if( scrollX > scrollbar.maximum() )
  339. scrollX = (int)scrollbar.maximum();
  340.       ((Fl_Valuator*)&scrollbar)->value( scrollX );
  341.       scrollTo = NULL;
  342.       goto BEGIN_W;
  343.     }
  344.   // if we exceed the width and the scrollbar is not visible,
  345.   // then it will soon become visible so we don't need to process anymore
  346.   if( !measure && !sbVisible && maxW > ww )
  347.     return 1;
  348. }
  349.       if( measure )
  350. return -1;
  351.       else if( maxW > ww )
  352. {
  353.   scrollbar.range( 0, maxW-ww );
  354.   scrollbar.slider_size( MAX( float(scrollbar.w()-(maxW-ww))/float(scrollbar.w()), 0.08f ) );
  355.   return 1;
  356. }
  357.       else
  358. return 0;
  359.     }
  360. }
  361. void Flu_Wrap_Group :: draw()
  362. {
  363.   // we first try to fit all children assuming no scrollbar. if they do not all fit, 
  364.   // we have to turn the scrollbar on and try again
  365.   if( layout( false, false ) )
  366.     {
  367.       scrollbar.show();
  368.       layout( true, false );
  369.     }
  370.   else
  371.     scrollbar.hide();
  372.   // hack to look right when resizing smaller
  373.   if( scrollbar.value() > scrollbar.maximum() )
  374.     {
  375.       ((Fl_Valuator*)&scrollbar)->value( scrollbar.maximum() );
  376.       layout( scrollbar.visible(), scrollTo!=NULL );
  377.     }
  378.   else if( scrollTo )
  379.     layout( scrollbar.visible(), true );
  380.   scrollTo = NULL;
  381.   if( damage() & ~FL_DAMAGE_CHILD)
  382.     {
  383.       draw_box();
  384.       draw_label();
  385.     }
  386.   fl_push_clip( x()+Fl::box_dx(box()), y()+Fl::box_dy(box()),
  387. w()-Fl::box_dw(box()), h()-Fl::box_dh(box()) );
  388.   draw_children();
  389.   fl_pop_clip();
  390. }