tab_control.cpp

来自「ncbi源码」· C++ 代码 · 共 782 行 · 第 1/2 页

CPP
782
字号
    int y1 = y() + p_descr->m_y;    int width = p_descr->m_w - 1 + 2 * off_x;    int height = p_descr->m_h - 2;    int x2 = x1 + width - 1;    int y2 = y1 + height - 1;                // draw Tab countour    fl_color(bActive ? m_ActiveBorderColor : m_BorderColor);        fl_xyline(x1, y1, x1, y2 - 2); // left vert    fl_line(x1, y2 - 2, x1 + 2, y2);    fl_xyline(x1 + 2, y2, x2 - 2, y2); // horz line    fl_line(x2 - 2, y2, x2, y2 - 2);        fl_xyline(x2, y1, x2, y2 - 2); // right vert        // fill tab's background    if(bActive) {        fl_color(m_ActiveBackColor);        fl_rectf(x1 + 1, y1, width - 2, height - 2);    } else  {        fl_color(m_BackColor);        fl_rectf(x1 + 1, y1 +1, width - 2, height - 3);    }                // tab's edge    fl_color(m_BackColor);    fl_xyline(x1 + 1, y2 - 2, x2 - 1);    fl_xyline(x1 + 2, y2 - 1, x2 - 2);                if(index == m_Selected)    {        // horizontal line closing client rect        fl_color(m_ActiveBorderColor);        int off = kClientOffset - 1;        fl_xyline(x() + off, y1, x1 - off);        fl_xyline(x2 + off, y1, x() + w() - 1 - off);    }    //draw label      int text_x = x1 + off_x + kTabOffsetX;    int text_y = y2 - kTabOffsetY;    int text_w = width - 2 * kTabOffsetX;    fl_push_clip(text_x, y1, text_w, height);        fl_color(bActive ? m_ActiveTextColor : m_TextColor);        fl_draw_text(p_descr->m_Label, text_x, text_y, text_w);     fl_pop_clip();   }void    CTabControl::resize(int new_x, int new_y, int new_w, int new_h){    bool b_size_changed = new_w != w()  || new_h != h();    bool b_pos_changed = new_x != x()  || new_y != y();        if(b_size_changed  ||  b_pos_changed)   {        Fl_Widget::resize(new_x, new_y, new_w, new_h);        if(b_size_changed)  {            x_Layout();                              redraw();        }    }}void    CTabControl::x_Layout(){    x_LayoutTabs();    // resize selected (visible) pane    Fl_Widget* pane = x_GetSelectedPane();    if(pane)    {        int cl_x, cl_y, cl_w, cl_h;        x_GetClientRect(cl_x, cl_y, cl_w, cl_h);        pane->resize(cl_x, cl_y, cl_w, cl_h);    } }void    CTabControl::x_LayoutTabs(){    bool b_multi = (m_ResizePolicies & fMultiRow) != 0;    bool b_expand = (m_ResizePolicies & fExpand) != 0;        bool b_shrink = (m_ResizePolicies & fShrink) != 0;            m_vRows.clear();    // mesuare all tabs    vector<int> widths;    int total_w = 0;    int n_tabs = x_GetTabsCount();     for ( int i = 0; i < n_tabs; i++  )   {        int width = x_MeasureTabWidth(i);        total_w += width;        widths.push_back(width);    }        int w_av = w() - 2 * (kTabSpaceX + kClientOffset);        int row_h = x_GetTabRowH();    int pos_x = kClientOffset + kTabSpaceX;        //assembling tabs in rows    if(b_multi) { // create multi-row layout        for ( int i = 0; i < n_tabs; i++  )   {            int width = widths[i];            if(i == 0  ||  pos_x + width > w_av)    { // start next row                m_vRows.push_back(TRowIndexes());                pos_x = kClientOffset + 1;            }            pos_x += width;                    m_vRows.back().push_back(i);        }    }   else {        if(b_shrink  &&  total_w > w_av) { // distributing space deficit            double K = ((double) w_av) / total_w; // reduction koeff.            int pos = 0;            for ( int i = 0; i < n_tabs; i++  )   {                int prev_pos = pos;                pos += widths[i];                                widths[i] = (int)(K * pos) - (int)(K * prev_pos);            }        }        m_vRows.push_back(TRowIndexes());        for ( int i = 0; i < n_tabs; i++  )   {            m_vRows.back().push_back(i);        }    }        //now we know how many rows we need    m_TabAreaH = kTabSpaceY + row_h * m_vRows.size();        // assign positions to rows    int pos_y = h() - m_TabAreaH + kTabSpaceY;                    for( size_t row = 0;  row < m_vRows.size();  row++ )  { // for each row        TRowIndexes& indexes = m_vRows[row];        pos_x = kClientOffset + kTabSpaceX;        int n_cols = indexes.size();        int row_w, delta, rest; // used in fExpand mode        if(b_expand)    {            row_w = 0;            for( int col = 0;  col < n_cols; col++ )    {                row_w += widths[indexes[col]];            }            int extra = w_av - row_w; // available extra space in a row            if(extra > 0)   {                delta = extra / n_cols;                rest = extra - delta * n_cols; // space that cannot be divided between all tabs            } else delta = rest = 0;        }        for( int col = 0;  col < n_cols; col++ )    { // for each tab in a row            int i_tab = indexes[col];            STabDescr*  p_descr = m_vDescrs[i_tab];              int tab_w = min(widths[i_tab], w_av); // not wider than control            if(b_expand)   {                tab_w += delta + ((col < rest) ? 1 : 0);            }            p_descr->m_x = pos_x;            p_descr->m_w = tab_w;            pos_x += tab_w;                        p_descr->m_y = pos_y;            p_descr->m_h = row_h;        }        pos_y += row_h;    }}int     CTabControl::x_GetTabAreaH() const{    return m_TabAreaH;}int     CTabControl::x_GetTabRowH()  const{    return kTabRowH;}int     CTabControl::x_MeasureTabWidth(int index){    STabDescr*  p_descr = m_vDescrs[index];    fl_font(FL_HELVETICA, 12);    const char* p_text = p_descr->m_Label.c_str();    int text_w = fl_width(p_text);    int width = text_w + 2 * kTabOffsetX + 1;    return width;}int  CTabControl::handle(int event){    m_Event.OnFLTKEvent(event);        int res = 0;    switch(event)   {    case FL_KEYDOWN:    case FL_KEYUP:  res = x_HandleKeyEvent(); break;    case FL_MOVE:   res = x_HandleMouseMove(); break;    case FL_PUSH:   res = x_HandleMousePush(); break;    case FL_DRAG: res = x_HandleMouseDrag(); break;    case FL_RELEASE: res = x_HandleMouseRelease(); break;    default: {        res = Fl_Group::handle(event);    }; break;    }    m_Tooltip.Handle(event);    return res;}bool    CTabControl::x_IsIndexValid(int index) const{    return index >= 0 && index < x_GetTabsCount();}void    CTabControl::x_GetClientRect(int& cl_x, int& cl_y, int& cl_w, int& cl_h){    cl_x = x() + kClientOffset;     cl_y = y() + kClientOffset;    cl_w = w() - 2 * kClientOffset;    cl_h = h() - x_GetTabAreaH() - 2 * kClientOffset;}bool inline PointInRect(int px, int py, int x, int y, int w, int h){    return px >= x  &&  px < x + w &&  py >= y  &&  py < y + h;}CTabControl::EHitResult  CTabControl::x_HitTest(int pos_x, int pos_y, int& i_tab){    i_tab = -1;    if(PointInRect(pos_x, pos_y, x(), y(), w(), h()))  {                int cl_x, cl_y, cl_w, cl_h;        x_GetClientRect(cl_x, cl_y, cl_w, cl_h);        if(PointInRect(pos_x, pos_y, cl_x, cl_y, cl_w, cl_h))   {            return eClient;        } else {            for( int i = 0; i < x_GetTabsCount(); i++ ) {                STabDescr*  p_descr = m_vDescrs[i];                int loc_x = pos_x - x();                int loc_y = pos_y - y();                if(PointInRect(loc_x, loc_y, p_descr->m_x, p_descr->m_y,                                 p_descr->m_w, p_descr->m_h)) {                    i_tab = i;                    return eTab;                }            }        }        return eEmptySpace;    }    return eNothing;            }int    CTabControl::x_HandleKeyEvent(){    return 0;}int    CTabControl::x_HandleMouseMove(){    return Fl_Group::handle(FL_MOVE);}int    CTabControl::x_HandleMousePush(){    int i_tab;    EHitResult hit_res = x_HitTest(Fl::event_x(), Fl::event_y(), i_tab);        switch(hit_res) {    case eClient:   return Fl_Group::handle(FL_PUSH);   break;    case eTab:    case eEmptySpace: {        int res = 0;        switch(m_Event.GetGUISignal()) {        // any mouse click event switches tabs        case    CGUIEvent::ePush:   //return true;        case    CGUIEvent::eSelectSignal:          case    CGUIEvent::ePopupSignal: {            if(i_tab != -1) {                x_SelectTab(i_tab);                res = 1;            }        }        }; // switch(m_Event.GetGUISignal())         if(m_Event.GetGUISignal() ==  CGUIEvent::ePopupSignal)   {            fl_cursor(FL_CURSOR_DEFAULT, FL_BLACK, FL_WHITE);             x_OnShowPopupMenu();            }        return res;            }; break;    }; // switch(hit_res) {    return 0;}int    CTabControl::x_HandleMouseDrag(){    return Fl_Group::handle(FL_DRAG);}int    CTabControl::x_HandleMouseRelease(){    int i_tab;    EHitResult hit_res = x_HitTest(Fl::event_x(), Fl::event_y(), i_tab);        bool b_handled = false;    CGUIEvent::EGUISignal signal = m_Event.GetGUISignal(); // remember        if(hit_res == eClient)  {        if(Fl_Group::handle(FL_RELEASE))            return true;    } else if(hit_res == eTab)  {        _ASSERT(i_tab != -1);        x_SelectTab(i_tab);    }    if((signal ==  CGUIEvent::ePopupSignal)  &&         (hit_res == eTab  || hit_res == eEmptySpace))   {        fl_cursor(FL_CURSOR_DEFAULT, FL_BLACK, FL_WHITE);         x_OnShowPopupMenu();            return 1;    }    return 0;}void    CTabControl::x_OnShowPopupMenu(){}bool    CTabControl::TC_NeedTooltip(int x, int y){    EHitResult hit_res = x_HitTest(Fl::event_x(), Fl::event_y(), m_iHitTab);        return hit_res == eTab;}string  CTabControl::TC_GetTooltip(int& x, int& y, int& w, int& h){    if(m_iHitTab != -1) {        _ASSERT(x_IsIndexValid(m_iHitTab));        STabDescr* p_descr = m_vDescrs[m_iHitTab];        x = p_descr->m_x;        y = p_descr->m_y;        w = p_descr->m_w;        h = p_descr->m_h;        return p_descr->m_Label;    }    return "";}END_NCBI_SCOPE/* * =========================================================================== * $Log: tab_control.cpp,v $ * Revision 1000.1  2004/06/01 21:09:17  gouriano * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.8 * * Revision 1.8  2004/05/21 22:27:53  gorelenk * Added PCH ncbi_pch.hpp * * Revision 1.7  2004/05/20 12:44:06  dicuccio * Added explicit call to end() - closes tab group correctly * * Revision 1.6  2004/05/13 17:20:32  yazhuk * Moved fl_draw_text() functions to utils.hpp; added end() to x_Init() * * Revision 1.5  2004/05/07 14:21:23  yazhuk * Fixed RemoveTab() * * Revision 1.4  2004/03/08 15:53:13  yazhuk * Fixed popup menu handling; clean-up * * Revision 1.3  2004/03/02 22:27:20  yazhuk * Popup menu fix for Mac * * Revision 1.2  2004/02/04 20:26:36  ucko * Fix capitalization of fl_draw.H. * * Revision 1.1  2004/02/04 20:01:20  yazhuk * Initial revision * * =========================================================================== */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?