📄 table_panel.hpp
字号:
bool operator() (const Data& d0, const Data& d1) const { return (*d0 < *d1); }};template <class Data>struct SCompareByValue { bool operator() (const Data& d0, const Data& d1) const { return (d0 < d1); }};//// class CListPanel extends CTablePanel by creating a multi-column list panel.//// This panel has a few features not found in CTablePanel:// - It stores all data in the widget itself, rather than relying on a virtual// accessor mechanism.// - It provides a means of sorting by columns. -1 = sort by original data.//template <class Data, class Comparator = SCompareByPtr<Data> >class CListPanel : public CTablePanel{public: // typedefs and nested classes for our columns and data // NB: these are public to avoid compiler errors regarding use of a // protected typedef in a protected nested class typedef vector<string> TColumns; class CRow { public: Data m_Data; string m_RowHeader; TColumns m_Columns; }; typedef CRow TRow; typedef vector<TRow> TTable; CListPanel(int x, int y, int w, int h, const char* label = NULL); virtual ~CListPanel() {} // sort by a given column void SortByCol(int col); // get/set the row headers void SetRowHeader(int row, const string& header); const string& GetRowHeader(int row) const; // access the data for a given row Data GetData(int row) { return m_Data[row].m_Data; }protected: // our data TTable m_Data; // predicate for sorting our table data by a given column struct SColSorter { int m_Col; bool m_Ascending; EColumnType type; Comparator m_Comparator; SColSorter(int col, bool ascending, EColumnType type) : m_Col(col) , m_Ascending(ascending) , type(type) {} bool operator() (const TRow& row0, const TRow& row1) const { bool comp = false; switch (type) { case eString: if (row0.m_Columns[m_Col] != row1.m_Columns[m_Col]) { comp = (row0.m_Columns[m_Col] < row1.m_Columns[m_Col]); } else { comp = m_Comparator(row0.m_Data, row1.m_Data); } break; case eNumeric: { int r0 = 0; int r1 = 0; if ( !row0.m_Columns[m_Col].empty() ) { r0 = NStr::StringToInt(row0.m_Columns[m_Col], 10, NStr::eCheck_Skip); } if ( !row1.m_Columns[m_Col].empty() ) { r1 = NStr::StringToInt(row1.m_Columns[m_Col], 10, NStr::eCheck_Skip); } if (r0 != r1) { comp = (r0 < r1); } else { comp = m_Comparator(row0.m_Data, row1.m_Data); } } break; } return (m_Ascending ? comp : !comp); } }; // predicate for sorting our table data by the underlying data object struct SDataSorter { bool m_Ascending; Comparator m_Comp; SDataSorter(bool ascending) : m_Ascending(ascending) {} bool operator() (const TRow& row0, const TRow& row1) const { return (m_Ascending ? ( m_Comp(row0.m_Data, row1.m_Data) ): ( m_Comp(row1.m_Data, row0.m_Data) ) ); } }; // FLTK overloads virtual int handle(int event); virtual void draw_cell(TableContext ctx, int row, int col, int x, int y, int w, int h);};//// default ctor//template <class Data, class Comparator>inline CListPanel<Data, Comparator>::CListPanel(int x, int y, int w, int h, const char* label) : CTablePanel(x, y, w, h, label){}//// Utility function: sort by a given column// NOTE: the 'column' here is the *actual* column. The one exception is the// special column '-1', which indicates 'sort by underlying data'//template <class Data, class Comparator>inline void CListPanel<Data, Comparator>::SortByCol(int col){ if (col >= 0) { if (col >= int (m_ColInfo.size())) { return; } bool ascending = false; if (m_ColInfo[col].sort_state != eAscending) { ascending = true; } NON_CONST_ITERATE (TColInfo, iter, m_ColInfo) { iter->sort_state = eNotSorted; } m_ColInfo[col].sort_state = (ascending ? eAscending : eDescending); // string sort by column // we need to map our visible column to our underlying data column std::sort(m_Data.begin(), m_Data.end(), SColSorter(col, ascending, m_ColInfo[col].type)); } else { // sort by data std::sort(m_Data.begin(), m_Data.end(), SDataSorter(true)); }}//// SetRowHeader()// Set the header for a given row//template <class Data, class Comparator>inline voidCListPanel<Data, Comparator>::SetRowHeader(int row, const string& header){ if (int (m_Data.size()) <= row) { m_Data.resize(row + 1); } m_Data[row].m_RowHeader = header;}//// GetRowHeader()// Return the header for a given row//template <class Data, class Comparator>inline const string&CListPanel<Data, Comparator>::GetRowHeader(int row) const{ return m_Data[row].m_RowHeader;}//// Flek overload: draw_cell()// This actually does the work of drawing our data//template <class Data, class Comparator>inline void CListPanel<Data, Comparator>::draw_cell(TableContext ctx, int row, int col, int x, int y, int w, int h){ // transform col (virtual col) to actual table column int actual_col = 0; if (col < m_VirtCols.size() ) { actual_col = m_VirtCols[col]; } switch (ctx) { case CONTEXT_STARTPAGE: fl_font(labelfont(), labelsize()); break; case CONTEXT_ROW_HEADER: fl_push_clip(x, y, w, h); {{ fl_draw_box(m_HeaderBox, x, y, w, h, row_header_color()); fl_color(labelcolor()); if (row < m_Data.size()) { fl_draw(m_Data[row].m_RowHeader.c_str(), x, y, w, h, FL_ALIGN_CENTER); } }} fl_pop_clip(); break; case CONTEXT_COL_HEADER: fl_push_clip(x, y, w, h); {{ fl_draw_box(m_HeaderBox, x, y, w, h, col_header_color()); if (actual_col < m_ColInfo.size()) { fl_color(labelcolor()); fl_draw(m_ColInfo[actual_col].header.c_str(), x, y, w, h, FL_ALIGN_CENTER); } }} fl_pop_clip(); break; case CONTEXT_CELL: fl_push_clip(x, y, w, h); {{ // BG COLOR fl_color(row_selected(row) ? selection_color() : FL_BACKGROUND2_COLOR); fl_rectf(x, y, w, h); // TEXT if (row < m_Data.size() && actual_col < m_Data[row].m_Columns.size()) { fl_color(labelcolor()); const char *p = m_Data[row].m_Columns[actual_col].c_str(); fl_draw(p, x + Fl::box_dx(m_CellBox), y + Fl::box_dy(m_CellBox), w - Fl::box_dw(m_CellBox), h - Fl::box_dh(m_CellBox), GetColAlign(actual_col)); } // BORDER fl_draw_box(m_CellBox, x, y, w, h, FL_LIGHT2); }} fl_pop_clip(); break; default: break; }}//// overloaded event handler// here we trigger column sorting//template <class Data, class Comparator>inline int CListPanel<Data, Comparator>::handle(int event){ int row = -1; int col = -1; switch (event) { case FL_PUSH: /** FIXME row = get_row(Fl::event_x(), Fl::event_y()); if (row != -1 || Fl::event_clicks() != 1) { break; } col = get_col(Fl::event_x(), Fl::event_y()); SortByCol(m_VirtCols[col]); redraw(); **/ break; default: break; }; return Fl_Table_Row::handle(event);}#endifEND_NCBI_SCOPE/* @} *//* * =========================================================================== * $Log: table_panel.hpp,v $ * Revision 1000.4 2004/06/01 19:52:33 gouriano * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.15 * * Revision 1.15 2004/05/28 14:54:54 dicuccio * Added functions to take CFltkUtils::EBoxType directly * * Revision 1.14 2004/05/25 17:06:39 dicuccio * MOved border drawing code outside of row check. Changed ascending/descending * sort arrows to meet user expectations * * Revision 1.13 2004/05/11 18:55:14 dicuccio * Added doxygen modules info * * Revision 1.12 2004/05/07 15:44:47 dicuccio * Fixed compiler warning about type conversion * * Revision 1.11 2004/05/03 12:47:08 dicuccio * Added #include for gui/gui.hpp. gui/utils ->gui/objutils where needed. * * Revision 1.10 2004/04/22 15:08:08 gorelenk * Fixed compilation error in implementation of 'CTablePanel<RowData>::SetRow' * * Revision 1.9 2004/04/22 14:21:41 gorelenk * Fixed compilation errors on MSVC7. * * Revision 1.8 2004/04/16 14:32:54 dicuccio * Added IsRowSelected() - const wrapper around non-const function * * Revision 1.7 2004/04/07 12:42:08 dicuccio * Call SetRows() in RemoveRow(). Make sure that draw_cell() will be entered even * if no items are present (insures that column headers will be drawn) * * Revision 1.6 2004/03/19 18:02:17 dicuccio * Added SetWidth()/GetWidth() - width of a column in pixels. Added better * (smooth) handling of resize() - resize columns to fit only if they are less * than the current width. * * Revision 1.5 2004/03/19 17:00:12 dicuccio * Fix for resize() - preserve virtual width of the table * * Revision 1.4 2004/03/11 17:22:41 dicuccio * Reinstaed virtual columns * * Revision 1.3 2004/03/05 17:28:26 dicuccio * Added standard handlers for cut/copy/paste events. Added abiluty to remove * rows * * Revision 1.2 2004/01/20 18:11:11 dicuccio * Changed SetColumns() to SetCols(). Introduced GetRows()/SetRows()/SetCols() * as virtual replacements for rows()/cols(). Added sorting of columns on * double-click of header. Added standard virtual hooks for trapping click * events inside of cells / headers. Added more natural API to SetCells(). * * Revision 1.1 2003/12/09 15:54:10 dicuccio * Deprecated Fl_Tree_Browser - use Flu_Tree_Browser instead * * Revision 1.22 2003/12/05 02:03:14 ucko * Add missing definitions of CTablePanel::{Get,Set}RowHeader(size_t), * and fix the other definition of GetRowHeader to avoid looping forever. * * Revision 1.21 2003/12/04 18:07:48 dicuccio * Removed direct access to underlying data component in CTablePanel<> - makes * the class more tightly encapsulated * * Revision 1.20 2003/09/29 15:16:02 dicuccio * Added typename where required * * Revision 1.19 2003/09/24 18:21:56 dicuccio * Introduce new base class interposed between CTablePanel<> and Fl_Table_Row; * this class incorporates most of the generic features of CTablePanel<> and * allows for easier extension of list views * * Revision 1.18 2003/09/17 16:19:58 dicuccio * Make sure to set the row height appropriately for the font when setting rows * * Revision 1.17 2003/08/18 14:53:04 dicuccio * Code clean-up. Made interface class for table data cleaner, more * comprehensive * * Revision 1.16 2003/07/28 11:53:29 dicuccio * Rewrote CTablePanel<> to be more flexible and better contained * * Revision 1.15 2003/07/25 13:40:46 dicuccio * Replaced Flv_Table with Fl_Table * * Revision 1.14 2003/06/25 16:59:42 dicuccio * Changed CPluginHandle into a pointer-to-implementation (the previous * implementation is now the pointer held). Lots of #include file clean-ups. * * Revision 1.13 2003/03/17 14:58:33 dicuccio * Eliminated annoying compiler warning about unsigned-signed compare * * Revision 1.12 2003/03/10 17:49:04 kuznets * iterate->ITERATE * * Revision 1.11 2003/02/25 14:43:20 dicuccio * Added smart resizing of multicolumn list widget * * Revision 1.10 2003/02/20 19:43:13 dicuccio * Changed column sort to be triggered on double-click, not single-click * * Revision 1.9 2003/01/17 21:09:49 dicuccio * Altered sorting - fall back to feature sort order if sort returns * equivalence * * Revision 1.8 2003/01/15 17:48:32 dicuccio * Fixed thinko: don't try to numerically convert an empty column string * * Revision 1.7 2003/01/13 13:11:44 dicuccio * Namespace clean-up. Retired namespace gui -> converted to namespace ncbi. * Moved all FLUID-generated code into namespace ncbi. * * Revision 1.6 2003/01/08 20:19:19 dicuccio * Fix for solaris builds: cannot use protected typedefs in protected nested * classes. * * Revision 1.5 2003/01/08 14:47:45 dicuccio * Moved column selection dialog into internal directory. Made column * selection dialog part of the base class; it is expressible via * CTablePanel::ShowColSelectDlg(). Added ability to specify type of data * stored in column (currently string or numeric); added ability to sort based * on underlying type. * * Revision 1.4 2003/01/03 18:38:08 dicuccio * Fixed compilation error in WIndows - can't reference protected enum from * nested protected class. * * Revision 1.3 2003/01/03 13:28:14 dicuccio * Lots of clean-up. Added stored sort state. Added new class to hold all * info for one virtual column. Added dialog box for selecting visible * columns. * * Revision 1.2 2002/12/30 20:18:14 dicuccio * Added Win32 export specifier. Rearranged #include directives * * Revision 1.1 2002/12/30 18:42:39 dicuccio * Initial revision * * =========================================================================== */#endif // GUI_WIDGETS_TABLE___TABLE_PANEL__HPP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -