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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: Fl_Table_Row.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 21:06:21  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.3
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*
  10.  * This is a third-party file, and is maintained and copyrighted as below.
  11.  * Please see LICENSE at the root of the NCBI C++ toolkit for details on its
  12.  * redistribution
  13.  *
  14.  * ===========================================================================
  15.  * $Log: Fl_Table_Row.cpp,v $
  16.  * Revision 1000.1  2004/06/01 21:06:21  gouriano
  17.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.3
  18.  *
  19.  * Revision 1.3  2004/05/21 22:27:51  gorelenk
  20.  * Added PCH ncbi_pch.hpp
  21.  *
  22.  * Revision 1.2  2003/08/01 19:02:21  dicuccio
  23.  * Retabified / reindented.  Changed calling of callback in Fl_Table::handle() -
  24.  * was called only if the release happened in the same row as the initial push,
  25.  * which prevenets a callback on click-drag-release for selection
  26.  *
  27.  * Revision 1.1  2003/07/25 13:37:45  dicuccio
  28.  * Initial revision
  29.  *
  30.  * Revision 1.1  2003/07/25 13:36:26  dicuccio
  31.  * Initial revision
  32.  *
  33.  * ===========================================================================
  34.  */
  35. //
  36. // Fl_Table_Row -- A row oriented table widget
  37. //
  38. //    A class specializing in a table of rows.
  39. //    Handles row-specific selection behavior.
  40. //
  41. // Copyright 2002 by Greg Ercolano.
  42. //
  43. // This library is free software; you can redistribute it and/or
  44. // modify it under the terms of the GNU Library General Public
  45. // License as published by the Free Software Foundation; either
  46. // version 2 of the License, or (at your option) any later version.
  47. //
  48. // This library is distributed in the hope that it will be useful,
  49. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  50. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  51. // Library General Public License for more details.
  52. //
  53. // You should have received a copy of the GNU Library General Public
  54. // License along with this library; if not, write to the Free Software
  55. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  56. // USA.
  57. //
  58. // Please report all bugs and problems to "erco at seriss dot com".
  59. //
  60. //
  61. // TODO:
  62. //    o Row headings (only column headings supported currently)
  63. //
  64. #include <ncbi_pch.hpp>
  65. #include <FL/Fl.H>
  66. #include <FL/fl_draw.H>
  67. #include <gui/widgets/Fl_Table/Fl_Table_Row.H>
  68. // Is row selected?
  69. int Fl_Table_Row::row_selected(int row)
  70. {
  71.     if ( row < 0 || row >= rows() ) return(-1);
  72.     return(_rowselect[row]);
  73. }
  74. // Change selection state for row
  75. //
  76. //     flag:
  77. //        0 - clear selection
  78. //        1 - set selection
  79. //        2 - toggle selection
  80. //
  81. //     Returns:
  82. //        0 - selection state did not change
  83. //        1 - selection state changed
  84. //       -1 - row out of range
  85. //
  86. int Fl_Table_Row::select_row(int row, int flag)
  87. {
  88.     if ( row < 0 || row >= rows() ) { return(-1); }
  89.     int oldval = _rowselect[row];
  90.     if ( flag == 2 ) { _rowselect[row] ^= 1; }
  91.     else             { _rowselect[row] = flag; }
  92.     if ( _rowselect[row] != oldval )        // select state changed?
  93.     {
  94.         if ( row >= toprow && row <= botrow )   // row visible?
  95.         {
  96.             // Extend partial redraw range
  97.             redraw_range(row, row, leftcol, rightcol);
  98.         }
  99.         return(1);
  100.     }
  101.     return(0);
  102. }
  103. // Select all rows to a known state
  104. void Fl_Table_Row::select_all_rows(int flag)
  105. {
  106.     char changed = 0;
  107.     if ( flag == 2 )
  108.     {
  109.         for ( int row=0; row<(int)_rowselect.size(); row++ )
  110.         { _rowselect[row] ^= 1; }
  111.         changed = 1;
  112.     }
  113.     else
  114.     {
  115.         for ( int row=0; row<(int)_rowselect.size(); row++ )
  116.         {
  117.             changed |= (_rowselect[row] != flag)?1:0;
  118.             _rowselect[row] = flag; 
  119.         }
  120.     }
  121.     if ( changed )
  122.     { redraw(); }
  123. }
  124. // Set number of rows
  125. void Fl_Table_Row::rows(int val)
  126. {
  127.     Fl_Table::rows(val);
  128.     while ( val > (int)_rowselect.size() ) { _rowselect.push_back(0); } // enlarge
  129.     while ( val < (int)_rowselect.size() ) { _rowselect.pop_back(); }   // shrink
  130. }
  131. // #include "eventnames.h"      // debugging
  132. // #include <stdio.h>
  133. // Handle events
  134. int Fl_Table_Row::handle(int event)
  135. {
  136.     //    fprintf(stderr, "** EVENT: %s: EVENT XY=%d,%dn", 
  137.     //        eventnames[event], Fl::event_x(), Fl::event_y()); // debugging
  138.     // Let base class handle event
  139.     int ret = Fl_Table::handle(event);
  140.     // The following code disables cell selection.. why was it added? -erco 05/18/03
  141.     // if ( ret ) { _last_y = Fl::event_y(); return(1); }   // base class 'handled' it (eg. column resize)
  142.     int shiftstate = (Fl::event_state() & FL_CTRL) ? FL_CTRL :
  143.         (Fl::event_state() & FL_SHIFT) ? FL_SHIFT : 0;
  144.     // Which row/column are we over?
  145.     int R, C;               // row/column being worked on
  146.     ResizeFlag resizeflag;      // which resizing area are we over? (0=none)
  147.     TableContext context = cursor2rowcol(R, C, resizeflag);
  148.     switch ( event )
  149.     {
  150.     case FL_PUSH:
  151.         if ( Fl::event_button() == 1 )
  152.         {
  153.             _last_push_x = Fl::event_x();   // save regardless of context
  154.             _last_push_y = Fl::event_y();   // " "
  155.             // Handle selection in table.
  156.             //     Select cell under cursor, and enable drag selection mode.
  157.             //
  158.             if ( context == CONTEXT_CELL )
  159.             {
  160.                 // Ctrl key? Toggle selection state
  161.                 switch ( shiftstate )
  162.                 {
  163.                 case FL_CTRL:
  164.                     select_row(R, 2);   // toggle
  165.                     break;
  166.                 case FL_SHIFT:
  167.                     {
  168.                         select_row(R, 1);
  169.                         if ( _last_row > -1 )
  170.                         {
  171.                             int srow = R, erow = _last_row;
  172.                             if ( srow > erow ) 
  173.                             { srow = _last_row; erow = R; }
  174.                             for ( int row = srow; row <= erow; row++ )
  175.                             { select_row(row, 1); }
  176.                         }
  177.                         break;
  178.                     }
  179.                 default:
  180.                     select_all_rows(0); // clear all previous selections
  181.                     select_row(R, 1);
  182.                     break;
  183.                 }
  184.                 _last_row = R;
  185.                 _dragging_select = 1;
  186.                 ret = 1;      // FL_PUSH handled (ensures FL_DRAG will be sent)
  187.                 // redraw();  // redraw() handled by select_row()
  188.             }
  189.         }
  190.         break;
  191.     case FL_DRAG:
  192.         {
  193.             // if ( ! is_resizing() )
  194.             if ( _dragging_select )
  195.             {
  196.                 // Dragged off table edges? Handle scrolling
  197.                 int offtop = toy - _last_y,         // >0 if off top of table
  198.                 offbot = _last_y - (toy + toh);     // >0 if off bottom of table
  199.                 if ( offtop > 0 && row_position() > 0 )
  200.                 {
  201.                     // Only scroll in upward direction
  202.                     int diff = _last_y - Fl::event_y();
  203.                     if ( diff < 1 )
  204.                     { ret = 1; break; }
  205.                     row_position(row_position() - diff);
  206.                     context = CONTEXT_CELL; C = 0; R = row_position();  // HACK: fake it
  207.                     if ( R < 0 || R > rows() ) { ret = 1; break; }      // HACK: ugly
  208.                 }
  209.                 else if ( offbot > 0 && botrow < rows() )
  210.                 {
  211.                     // Only scroll in downward direction
  212.                     int diff = Fl::event_y() - _last_y;
  213.                     if ( diff < 1 )
  214.                     { ret = 1; break; }
  215.                     row_position(row_position() + diff);
  216.                     context = CONTEXT_CELL; C = 0; R = botrow;      // HACK: fake it
  217.                     if ( R < 0 || R > rows() ) { ret = 1; break; }  // HACK: ugly
  218.                 }
  219.                 if ( context == CONTEXT_CELL )
  220.                 {
  221.                     switch ( shiftstate )
  222.                     {
  223.                     case FL_CTRL:
  224.                         if ( R != _last_row )      // toggle if dragged to new row
  225.                         { select_row(R, 2); }  // 2=toggle
  226.                         break;
  227.                     case FL_SHIFT:
  228.                     default:
  229.                         select_row(R, 1);
  230.                         if ( _last_row > -1 )
  231.                         {
  232.                             int srow = R, erow = _last_row;
  233.                             if ( srow > erow ) 
  234.                             { srow = _last_row; erow = R; }
  235.                             for ( int row = srow; row <= erow; row++ )
  236.                             { select_row(row, 1); }
  237.                         }
  238.                         break;
  239.                     }
  240.                     ret = 1;                // drag handled
  241.                     _last_row = R;
  242.                 }
  243.             }
  244.             break;
  245.         }
  246.     case FL_RELEASE:
  247.         if ( Fl::event_button() == 1 )
  248.         {
  249.             _dragging_select = 0;
  250.             ret = 1;            // release handled
  251.             // Clicked off edges of data table? 
  252.             //    A way for user to clear the current selection.
  253.             //
  254.             int databot = tiy + table_h,
  255.             dataright = tix + table_w;
  256.             if ( 
  257.                 ( _last_push_x > dataright && Fl::event_x() > dataright )
  258.                 ||
  259.                 ( _last_push_y > databot && Fl::event_y() > databot )
  260.                )
  261.             {
  262.                 select_all_rows(0);         // clear previous selections
  263.             }
  264.         }
  265.         break;
  266.     default:
  267.         break;
  268.     }
  269.     _last_y = Fl::event_y();
  270.     return(ret);
  271. }