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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: table_panel.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 21:09:19  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.7
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: table_panel.cpp,v 1000.2 2004/06/01 21:09:19 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Authors:  Mike DiCuccio
  35.  *
  36.  * File Description:
  37.  *    CTablePanel -- Extends Fl_Table_Row to provide notions of hidden and
  38.  *                   visible columns
  39.  */
  40. #include <ncbi_pch.hpp>
  41. #include <gui/widgets/fl/table_panel.hpp>
  42. #include <FL/Fl.H>
  43. #include <FL/fl_draw.H>
  44. #include "colselect_dlg.hpp"
  45. BEGIN_NCBI_SCOPE
  46. //
  47. // default ctor
  48. //
  49. CTablePanelBase::CTablePanelBase(int x, int y, int w, int h, const char* label)
  50.     : Fl_Table_Row(x, y, w, h, label),
  51.       m_CellBox(FL_NO_BOX),
  52.       m_RowHeaderBox(FL_THIN_UP_BOX),
  53.       m_ColHeaderBox(FL_THIN_UP_BOX)
  54. {
  55.     m_Handler.StandardConfig();
  56.     col_resize(RESIZE_COL_RIGHT);
  57.     color(FL_BACKGROUND2_COLOR);
  58.     selection_color(FL_BLUE);
  59. }
  60. bool CTablePanelBase::IsRowSelected(size_t row) const
  61. {
  62.     return const_cast<CTablePanelBase*>(this)->row_selected(row) ? true : false;
  63. }
  64. //
  65. // overloaded rows() handler
  66. //
  67. void CTablePanelBase::SetRows(size_t r)
  68. {
  69.     Fl_Table_Row::rows(r);
  70.     int orig_font = fl_font();
  71.     int orig_size = fl_size();
  72.     fl_font(labelfont(), labelsize());
  73.     row_height_all(fl_height() + fl_descent() +
  74.                    Fl::box_dh(GetCellBox()) + 2);
  75.     fl_font(orig_font, orig_size);
  76. }
  77. size_t CTablePanelBase::GetRows() const
  78. {
  79.     return Fl_Table_Row::rows();
  80. }
  81. void CTablePanelBase::SetCols(size_t c)
  82. {
  83.     Fl_Table_Row::cols(c);
  84. }
  85. size_t CTablePanelBase::GetCols() const
  86. {
  87.     return Fl_Table_Row::cols();
  88. }
  89. void CTablePanelBase::rows(int r)
  90. {
  91.     SetRows(r);
  92. }
  93. int CTablePanelBase::rows() const
  94. {
  95.     return GetRows();
  96. }
  97. void CTablePanelBase::cols(int c)
  98. {
  99.     SetCols(c);
  100. }
  101. int CTablePanelBase::cols() const
  102. {
  103.     return GetCols();
  104. }
  105. //
  106. // overloaded draw() - enforces clipping.  Fl_Table_Row does not clip itself
  107. // properly and will overwrite neighboring widgets
  108. //
  109. void CTablePanelBase::draw()
  110. {
  111.     fl_push_clip(x(), y(), w(), h());
  112.     Fl_Table_Row::draw();
  113.     fl_pop_clip();
  114. }
  115. //
  116. // overloaded handle() - trap header clicks
  117. //
  118. int CTablePanelBase::handle(int event)
  119. {
  120.     m_Handler.OnFLTKEvent(event);
  121.     switch (event) {
  122.     case FL_FOCUS:
  123.     case FL_UNFOCUS:
  124.         return 1;
  125.     case FL_PUSH:
  126.         Fl::focus(this);
  127.         break;
  128.     default:
  129.         break;
  130.     }
  131.     switch (m_Handler.GetGUIState()) {
  132.     case CGUIEvent::eSelectState:
  133.         if (Fl::event_clicks()  &&
  134.             m_Handler.GetGUISignal()== CGUIEvent::eRelease) {
  135.             int row;
  136.             int col;
  137.             ResizeFlag resize_flag;
  138.             switch (cursor2rowcol(row, col, resize_flag)) {
  139.             case CONTEXT_ROW_HEADER:
  140.                 if (x_HandleRowHeaderClick(row)) {
  141.                     return 1;
  142.                 }
  143.                 break;
  144.             case CONTEXT_COL_HEADER:
  145.                 if (x_HandleColHeaderClick(col)) {
  146.                     return 1;
  147.                 }
  148.                 break;
  149.             case CONTEXT_CELL:
  150.                 if (x_HandleCellClick(row, col)) {
  151.                     return 1;
  152.                 }
  153.                 break;
  154.             default:
  155.                 break;
  156.             }
  157.         }
  158.         break;
  159.     case CGUIEvent::eCopyState:
  160.         if (x_OnCopy()) {
  161.             return 1;
  162.         }
  163.         break;
  164.     case CGUIEvent::eCutState:
  165.         if (x_OnCut()) {
  166.             return 1;
  167.         }
  168.         break;
  169.     case CGUIEvent::ePasteState:
  170.         if (x_OnPaste()) {
  171.             return 1;
  172.         }
  173.         break;
  174.     default:
  175.         break;
  176.     }
  177.     return Fl_Table_Row::handle(event);
  178. }
  179. int CTablePanelBase::x_OnCopy()
  180. {
  181.     return 0;
  182. }
  183. int CTablePanelBase::x_OnCut()
  184. {
  185.     return 0;
  186. }
  187. int CTablePanelBase::x_OnPaste()
  188. {
  189.     return 0;
  190. }
  191. //
  192. // virtual event handlers for trapping cell/row clicks
  193. //
  194. int CTablePanelBase::x_HandleRowHeaderClick(size_t row)
  195. {
  196.     return 0;
  197. }
  198. int CTablePanelBase::x_HandleColHeaderClick(size_t col)
  199. {
  200.     return 0;
  201. }
  202. int CTablePanelBase::x_HandleCellClick(size_t row, size_t col)
  203. {
  204.     return 0;
  205. }
  206. //
  207. // access cell box types
  208. //
  209. void CTablePanelBase::SetCellBox(CFltkUtils::EBoxType box)
  210. {
  211.     m_CellBox = static_cast<Fl_Boxtype>(static_cast<int>(box));
  212. }
  213. void CTablePanelBase::SetCellBox(Fl_Boxtype box)
  214. {
  215.     m_CellBox = box;
  216. }
  217. Fl_Boxtype CTablePanelBase::GetCellBox(void) const
  218. {
  219.     return m_CellBox;
  220. }
  221. void CTablePanelBase::SetRowHeaderBox(Fl_Boxtype box)
  222. {
  223.     m_RowHeaderBox = box;
  224. }
  225. void CTablePanelBase::SetRowHeaderBox(CFltkUtils::EBoxType box)
  226. {
  227.     m_RowHeaderBox = static_cast<Fl_Boxtype>(static_cast<int>(box));
  228. }
  229. Fl_Boxtype CTablePanelBase::GetRowHeaderBox(void) const
  230. {
  231.     return m_RowHeaderBox;
  232. }
  233. void CTablePanelBase::SetColHeaderBox(Fl_Boxtype box)
  234. {
  235.     m_ColHeaderBox = box;
  236. }
  237. void CTablePanelBase::SetColHeaderBox(CFltkUtils::EBoxType box)
  238. {
  239.     m_ColHeaderBox = static_cast<Fl_Boxtype>(static_cast<int>(box));
  240. }
  241. Fl_Boxtype CTablePanelBase::GetColHeaderBox(void) const
  242. {
  243.     return m_ColHeaderBox;
  244. }
  245. void CTablePanelBase::SetHeaderBox(Fl_Boxtype box)
  246. {
  247.     SetRowHeaderBox(box);
  248.     SetColHeaderBox(box);
  249. }
  250. void CTablePanelBase::SetHeaderBox(CFltkUtils::EBoxType box)
  251. {
  252.     SetRowHeaderBox(box);
  253.     SetColHeaderBox(box);
  254. }
  255. #if 0
  256. //
  257. // x_SetNumColumns()
  258. // internal function to adjust the number of (actual) columns
  259. //
  260. void CTablePanel::x_SetNumColumns(int cols)
  261. {
  262.     m_ColInfo.resize(cols);
  263. }
  264. //
  265. // SetColType()
  266. // set the type of data represented in the column.  This determines how the
  267. // column is sorted.
  268. //
  269. void CTablePanel::SetColType(int col, EColumnType type)
  270. {
  271.     if (int (m_ColInfo.size()) <= col) {
  272.         x_SetNumColumns(col + 1);
  273.     }
  274.     m_ColInfo[col].m_Type = type;
  275. }
  276. //
  277. // GetColType()
  278. // Return the type of data used in a given column
  279. // 
  280. CTablePanel::EColumnType CTablePanel::GetColType(int col) const
  281. {
  282.     return m_ColInfo[col].m_Type;
  283. }
  284. //
  285. // SetRelWidth()
  286. // Set the relative width of a given column.  The relative width only
  287. // makes sense in the context of the sum of the relative widths of all the
  288. // other visible columns.
  289. //
  290. void CTablePanel::SetRelWidth(int col, float width)
  291. {
  292.     if (int (m_ColInfo.size()) <= col) {
  293.         x_SetNumColumns(col + 1);
  294.     }
  295.     m_ColInfo[col].m_Width = width;
  296. }
  297. //
  298. // GetRelWidth()
  299. // Returns the relative width of a given column.  The number returned only
  300. // makes sense in the context of the sum of the relative widths of all the
  301. // other visible columns.
  302. //
  303. float CTablePanel::GetRelWidth(int col) const
  304. {
  305.     return m_ColInfo[col].m_Width;
  306. }
  307. //
  308. // SetColAlign()
  309. // set the default alignment for a given column
  310. //
  311. void CTablePanel::SetColAlign(int col, Fl_Align align)
  312. {
  313.     if (int (m_ColInfo.size()) <= col) {
  314.         x_SetNumColumns(col + 1);
  315.     }
  316.     m_ColInfo[col].m_Align = align;
  317. }
  318. //
  319. // GetColAlign()
  320. // Return the current slignment setting for a given column
  321. //
  322. Fl_Align CTablePanel::GetColAlign(int col) const
  323. {
  324.     return m_ColInfo[col].m_Align;
  325. }
  326. //
  327. // SetColumn()
  328. // This function sets all column properties; internally, it just calls other
  329. // functions to set individual properties on the selected column.
  330. //
  331. void CTablePanel::SetColumn(int col, const string& header, EColumnType type,
  332.                             Fl_Align align, float rel_width)
  333. {
  334.     SetColHeader(col, header);
  335.     SetColType  (col, type);
  336.     SetColAlign (col, align);
  337.     SetRelWidth (col, rel_width);
  338. }
  339. // set the virtual column for a given index
  340. void CTablePanel::SetVirtualCol(int visible_col, int actual_col)
  341. {
  342.     if (int (m_VirtCols.size()) <= visible_col) {
  343.         m_VirtCols.resize(visible_col + 1, -1);
  344.     }
  345.     m_VirtCols[visible_col] = actual_col;
  346. }
  347. //
  348. // resize()
  349. // overloaded from Fl_Widget; handles resize events for the widget as a whole
  350. //
  351. void CTablePanel::resize(int x, int y, int wid, int ht)
  352. {
  353.     // determine the ratio of expansion / contraction of our columns
  354.     int orig_width = w();
  355.     float ratio = float (wid) / float (orig_width);
  356.     // call the base class
  357.     Fl_Table_Row::resize(x, y, wid, ht);
  358.     // now, fit our columns to maintain their width, if need be
  359.     int total_width = 0;
  360.     int i;
  361.     for ( i = 0;  i < cols();  ++i) {
  362.         total_width += col_width(i);
  363.     }
  364.     total_width = int (total_width * ratio);
  365.     for (i = 0;  i < cols() - 1;  ++i) {
  366.         col_width(i, int (col_width(i) * ratio));
  367.         total_width -= col_width(i);
  368.     }
  369.     col_width(cols() - 1, total_width);
  370. }
  371. //
  372. // x_SetupColumns()
  373. // Internal function to correctly set column widths and alignments.  This is
  374. // intended to be called any time the column setup changes - i.e., any time the
  375. // user selects a different set of visible columns.
  376. //
  377. void CTablePanel::x_SetupColumns()
  378. {
  379.     cols(m_VirtCols.size());
  380.     float sum = 0;
  381.     ITERATE(vector<int>, iter, m_VirtCols) {
  382.         sum += GetRelWidth(*iter);
  383.     }
  384.     float widget_width = w() - 1;
  385.     float total_rel_width = 0.0f;
  386.     ITERATE(vector<int>, iter, m_VirtCols) {
  387.         int actual_col = *iter;
  388.         float prev_rel_width = total_rel_width;
  389.         total_rel_width += GetRelWidth(actual_col);
  390.         int prev_width  = int (widget_width * prev_rel_width / sum);
  391.         int total_width = int (widget_width * total_rel_width / sum);
  392.         int width = total_width - prev_width;
  393.         // actually set our width
  394.         // we take this opportunity to set the column style as well
  395.         int idx = iter - m_VirtCols.begin();
  396.         col_width(idx, width);
  397.     }
  398. }
  399. //
  400. // ShowColSelectDlg()
  401. // This handles the business of showing a dialog box that allows selection of
  402. // an arbitrary number of visible columns
  403. //
  404. void CTablePanel::ShowColSelectDlg()
  405. {
  406.     if ( !m_SelectDlg.get() ) {
  407.         m_SelectDlg.reset(new CColumnSelectDlg());
  408.     }
  409.     // this is brute-force and potentially slow for a large number of columns
  410.     m_SelectDlg->Clear();
  411.     ITERATE (TColInfo, col_iter, m_ColInfo) {
  412.         int idx = col_iter - m_ColInfo.begin();
  413.         bool checked =
  414.             (std::find(m_VirtCols.begin(), m_VirtCols.end(), idx) !=
  415.              m_VirtCols.end());
  416.         m_SelectDlg->AddColumn(col_iter->m_Header, idx, checked);
  417.     }
  418.     if (m_SelectDlg->Show() == eOK) {
  419.         m_VirtCols = m_SelectDlg->GetSelected();
  420.         x_SetupColumns();
  421.         redraw();
  422.     }
  423. }
  424. #endif
  425. END_NCBI_SCOPE
  426. /*
  427.  * ===========================================================================
  428.  * $Log: table_panel.cpp,v $
  429.  * Revision 1000.2  2004/06/01 21:09:19  gouriano
  430.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.7
  431.  *
  432.  * Revision 1.7  2004/05/28 15:09:49  dicuccio
  433.  * Added finctions to set box styles using CFltkUtils::EBoxType
  434.  *
  435.  * Revision 1.6  2004/05/21 22:27:53  gorelenk
  436.  * Added PCH ncbi_pch.hpp
  437.  *
  438.  * Revision 1.5  2004/04/16 14:49:40  dicuccio
  439.  * Set background and selection color to defaults in ctor.  Added IsRowSelected()
  440.  *
  441.  * Revision 1.4  2004/03/11 17:52:15  dicuccio
  442.  * Implemented virtual columns.  Fixed double-click detection for sort
  443.  *
  444.  * Revision 1.3  2004/03/05 17:39:39  dicuccio
  445.  * Added handling of standard cut/copy/paste events
  446.  *
  447.  * Revision 1.2  2004/01/20 18:20:52  dicuccio
  448.  * Added handle() - report click events to virtual overrides.  Introduced new
  449.  * virtual APIs to trap calls to non-virtual rows()/cols()
  450.  *
  451.  * Revision 1.1  2003/12/09 15:51:51  dicuccio
  452.  * Deprecated Fl_Toggle_Tree - replaced with Flu_Tree_Browser.  Added CTreeBrowser
  453.  * as a standard tree interface
  454.  *
  455.  * Revision 1.12  2003/12/04 18:15:57  dicuccio
  456.  * Changed row height to take descent into account
  457.  *
  458.  * Revision 1.11  2003/09/24 18:35:49  dicuccio
  459.  * Reinstated implementation file with new table panel base class
  460.  *
  461.  * Revision 1.10  2003/07/28 11:51:51  dicuccio
  462.  * Rewrote CTablePanel<> to be more flexible and better contained.  Added standard
  463.  * multicolumn list dialog.  Deprecated use of COutputDlg.
  464.  *
  465.  * Revision 1.9  2003/07/25 13:39:11  dicuccio
  466.  * Replaced Flv_Table with the cleaner Fl_Table.
  467.  *
  468.  * Revision 1.8  2003/03/11 15:27:11  kuznets
  469.  * iterate -> ITERATE
  470.  *
  471.  * Revision 1.7  2003/02/25 14:48:35  dicuccio
  472.  * Added smart resizing of multicolumn list widgets
  473.  *
  474.  * Revision 1.6  2003/01/13 13:10:14  dicuccio
  475.  * Namespace clean-up.  Retired namespace gui -> converted all to namespace ncbi.
  476.  * Moved all FLUID-generated code into namespace ncbi.
  477.  *
  478.  * Revision 1.5  2003/01/10 18:21:51  dicuccio
  479.  * Added comments for each function
  480.  *
  481.  * Revision 1.4  2003/01/10 17:39:28  dicuccio
  482.  * Remove setting of table selection color - handle this in fluid instead
  483.  *
  484.  * Revision 1.3  2003/01/08 15:05:44  dicuccio
  485.  * Added column selection dialog to base class.  Store type parameter with each
  486.  * column - permits sorting absed on type (string vs. numeric)
  487.  *
  488.  * Revision 1.2  2003/01/03 17:37:02  dicuccio
  489.  * Added accessors for various items in a virtual table.  Added more consistent
  490.  * and easier way to configure columns
  491.  *
  492.  * Revision 1.1  2002/12/30 18:42:21  dicuccio
  493.  * Initial revision.
  494.  *
  495.  * ===========================================================================
  496.  */