fl_table.cpp
来自「ncbi源码」· C++ 代码 · 共 994 行 · 第 1/3 页
CPP
994 行
} } // Column header? if ( col_header() ) { // Inside a column heading? get_bounds(CONTEXT_COL_HEADER, X, Y, W, H); if ( Fl::event_inside(X, Y, W, H) ) { // Scan visible columns until found for ( C = leftcol; C <= rightcol; C++ ) { find_cell(CONTEXT_COL_HEADER, 0, C, X, Y, W, H); if ( Fl::event_x() >= X && Fl::event_x() < (X+W) ) { // Found column? // If cursor over resize boundary, and resize enabled, // enable the appropriate resize flag. // if ( col_resize() ) { if ( Fl::event_x() <= (X+3-0) ) { resizeflag = RESIZE_COL_LEFT; } if ( Fl::event_x() >= (X+W-3) ) { resizeflag = RESIZE_COL_RIGHT; } } return(CONTEXT_COL_HEADER); } } // Must be in column header dead zone return(CONTEXT_NONE); } } // Mouse somewhere in table? // Scan visible r/c's until we find it. // if ( Fl::event_inside(tox, toy, tow, toh) ) { for ( R = toprow; R <= botrow; R++ ) { for ( C = leftcol; C <= rightcol; C++ ) { find_cell(CONTEXT_CELL, R, C, X, Y, W, H); if ( Fl::event_inside(X, Y, W, H) ) { return(CONTEXT_CELL); } // found it } } // Must be in a dead zone of the table R = C = 0; return(CONTEXT_TABLE); } // Somewhere else return(CONTEXT_NONE);}// Find X/Y/W/H for cell at R/C// If R or C are out of range, returns -1 // with X/Y/W/H set to zero.//int Fl_Table::find_cell(TableContext context, int R, int C, int &X, int &Y, int &W, int &H){ if ( row_col_clamp(context, R, C) ) // row or col out of range? error { X=Y=W=H=0; return(-1); } X = col_scroll_position(C) - hscrollbar->value() + tix; Y = row_scroll_position(R) - vscrollbar->value() + tiy; W = col_width(C); H = row_height(R); switch ( context ) { case CONTEXT_COL_HEADER: Y = wiy; H = col_header_height(); return(0); case CONTEXT_ROW_HEADER: X = wix; W = row_header_width(); return(0); case CONTEXT_CELL: return(0); case CONTEXT_TABLE: return(0); // TODO -- HANDLE OTHER CONTEXTS default: fprintf(stderr, "Fl_Table::find_cell: unknown context %d\n", (int)context); return(-1); } //NOTREACHED}// Recalculate the window dimensionsvoid Fl_Table::recalc_dimensions(){ // Recal to* (Table Outer), ti* (Table Inner), wi* ( Widget Inner) wix = ( x() + Fl::box_dx(box())); tox = wix; tix = tox + Fl::box_dx(table->box()); wiy = ( y() + Fl::box_dy(box())); toy = wiy; tiy = toy + Fl::box_dy(table->box()); wiw = ( w() - Fl::box_dw(box())); tow = wiw; tiw = tow - Fl::box_dw(table->box()); wih = ( h() - Fl::box_dh(box())); toh = wih; tih = toh - Fl::box_dh(table->box()); // Trim window if headers enabled if ( col_header() ) { tiy += col_header_height(); toy += col_header_height(); tih -= col_header_height(); toh -= col_header_height(); } if ( row_header() ) { tix += row_header_width(); tox += row_header_width(); tiw -= row_header_width(); tow -= row_header_width(); } // Make scroll bars disappear if window large enough { // First pass: can hide via window size? int hidev = (table_h <= tih), hideh = (table_w <= tiw); // Second pass: Check for interference if ( !hideh & hidev ) { hidev = (( table_h - tih + SCROLLBAR_SIZE ) <= 0 ); } if ( !hidev & hideh ) { hideh = (( table_w - tiw + SCROLLBAR_SIZE ) <= 0 ); } // Determine scrollbar visibility, trim ti[xywh]/to[xywh] if ( hidev ) { vscrollbar->hide(); } else { vscrollbar->show(); tiw -= SCROLLBAR_SIZE; tow -= SCROLLBAR_SIZE; } if ( hideh ) { hscrollbar->hide(); } else { hscrollbar->show(); tih -= SCROLLBAR_SIZE; toh -= SCROLLBAR_SIZE;} } // Resize the child table table->resize(tox, toy, tow, toh); table->init_sizes();}// Recalculate internals after a scroll.//// Call this if table has been scrolled or resized.// Does not handle redraw().// TODO: Assumes ti[xywh] has already been recalculated.//void Fl_Table::table_scrolled(){ // Top row int y, row, voff = vscrollbar->value(); for ( row=y=0; row < _rows; row++ ) { y += row_height(row); if ( y >= voff ) { y -= row_height(row); break; } } _row_position = toprow = ( row >= _rows ) ? (row - 1) : row; toprow_scrollpos = y; // OPTIMIZATION: save for later use // Bottom row voff = vscrollbar->value() + tih; for ( ; row < _rows; row++ ) { y += row_height(row); if ( y >= voff ) { break; } } botrow = ( row >= _rows ) ? (row - 1) : row; // Left column int x, col, hoff = hscrollbar->value(); for ( col=x=0; col < _cols; col++ ) { x += col_width(col); if ( x >= hoff ) { x -= col_width(col); break; } } _col_position = leftcol = ( col >= _cols ) ? (col - 1) : col; leftcol_scrollpos = x; // OPTIMIZATION: save for later use // Right column // Work with data left over from leftcol calculation // hoff = hscrollbar->value() + tiw; for ( ; col < _cols; col++ ) { x += col_width(col); if ( x >= hoff ) { break; } } rightcol = ( col >= _cols ) ? (col - 1) : col; // First tell children to scroll draw_cell(CONTEXT_RC_RESIZE, 0,0,0,0,0,0);}// Table resized: recalc internal data// Call this whenever the window is resized.// Recalculates the scrollbar sizes.// Makes no assumptions about any pre-initialized data.//void Fl_Table::table_resized(){ table_h = row_scroll_position(rows()); table_w = col_scroll_position(cols()); recalc_dimensions(); // Recalc scrollbar sizes // Clamp scrollbar value() after a resize. // Resize scrollbars to enforce a constant trough width after a window resize. // { float vscrolltab = ( table_h == 0 || tih > table_h ) ? 1 : (float)tih / table_h; float hscrolltab = ( table_w == 0 || tiw > table_w ) ? 1 : (float)tiw / table_w; vscrollbar->bounds(0, table_h-tih); vscrollbar->precision(10); vscrollbar->slider_size(vscrolltab); vscrollbar->resize(wix+wiw-SCROLLBAR_SIZE, wiy, SCROLLBAR_SIZE, wih - ((hscrollbar->visible())?SCROLLBAR_SIZE:0)); vscrollbar->Fl_Valuator::value(vscrollbar->clamp(vscrollbar->value())); hscrollbar->bounds(0, table_w-tiw); hscrollbar->precision(10); hscrollbar->slider_size(hscrolltab); hscrollbar->resize(wix, wiy+wih-SCROLLBAR_SIZE, wiw - ((vscrollbar->visible())?SCROLLBAR_SIZE:0), SCROLLBAR_SIZE); hscrollbar->Fl_Valuator::value(hscrollbar->clamp(hscrollbar->value())); } // Tell FLTK child widgets were resized Fl_Group::init_sizes(); // Recalc top/bot/left/right table_scrolled(); // DO *NOT* REDRAW -- LEAVE THIS UP TO THE CALLER // redraw();}// Someone moved a scrollbarvoid Fl_Table::scroll_cb(Fl_Widget*w, void *data){ Fl_Table *o = (Fl_Table*)data; o->recalc_dimensions(); // recalc tix, tiy, etc. o->table_scrolled(); o->redraw();}// Set number of rowsvoid Fl_Table::rows(int val){ int oldrows = _rows; _rows = val; { int default_h = ( _rowheights.size() > 0 ) ? _rowheights.back() : 25; while ( val > (int)_rowheights.size() ) { _rowheights.push_back(default_h); } // enlarge while ( val < (int)_rowheights.size() ) { _rowheights.pop_back(); } // shrink } table_resized(); // OPTIMIZATION: redraw only if change is visible. if ( val >= oldrows && oldrows > botrow ) { /* NO REDRAW */ } else { redraw(); }}// Set number of colsvoid Fl_Table::cols(int val){ _cols = val; { int default_w = ( _colwidths.size() > 0 ) ? _colwidths[_colwidths.size()-1] : 80; while ( val > (int)_colwidths.size() ) { _colwidths.push_back(default_w); } // enlarge while ( val < (int)_colwidths.size() ) { _colwidths.pop_back(); } // shrink } table_resized(); redraw();}// Change mouse cursor to different typevoid Fl_Table::change_cursor(Fl_Cursor newcursor){ if ( newcursor != _last_cursor ) { fl_cursor(newcursor, FL_BLACK, FL_WHITE); _last_cursor = newcursor; }}// #define DEBUG 1#ifdef DEBUG#include "eventnames.h"#define PRINTEVENT \fprintf(stderr,"Table %s: ** Event: %s --\n", (label()?label():"none"), eventnames[event]);#else#define PRINTEVENT#endif// Handle FLTK eventsint Fl_Table::handle(int event){ PRINTEVENT; int ret = Fl_Group::handle(event); // let FLTK group handle events first // Which row/column are we over? int R, C; // row/column being worked on ResizeFlag resizeflag; // which resizing area are we over? (0=none) TableContext context = cursor2rowcol(R, C, resizeflag); switch ( event ) { case FL_PUSH: // Need this for eg. right click to pop up a menu if ( Fl_Widget::callback() && when() & FL_WHEN_CHANGED ) { do_callback(context, R, C); } switch ( context ) { case CONTEXT_CELL: // FL_PUSH on a cell? ret = 1; // express interest in FL_RELEASE break; case CONTEXT_COL_HEADER: // FL_PUSH on a column header? if ( Fl::event_button() == 1 && resizeflag ) { // Start resize if left click on column border. // "ret=1" ensures we get drag events from now on.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?