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 + -
显示快捷键?