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