tab_control.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:21k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: tab_control.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 21:09:17  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.8
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: tab_control.cpp,v 1000.1 2004/06/01 21:09:17 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Authors:  Andrey Yazhuk
  35.  *
  36.  * File Description:
  37.  */
  38.  
  39. #include <ncbi_pch.hpp>
  40. #include <gui/widgets/fl/tab_control.hpp>
  41. #include <gui/widgets/fl/menu.hpp>
  42. #include <FL/fl_draw.H>
  43. BEGIN_NCBI_SCOPE
  44. ///////////////////////////////////////////////////////////////////////////////
  45. /// CTabControl
  46. CTabControl::CTabControl()
  47. :   Fl_Group(0, 0, 0, 0),
  48.     m_Selected(-1),
  49.     m_TabAreaH(0)
  50. {
  51.     x_Init();
  52.     end();
  53. }
  54. CTabControl::CTabControl(int x, int y, int w, int h, const char* label)
  55. :   Fl_Group(x, y, w, h, label),
  56.     m_Selected(-1),
  57.     m_TabAreaH(0)
  58. {
  59.     x_Init();
  60.     end();
  61. }
  62. CTabControl::~CTabControl()
  63. {
  64. }
  65. static const int kScrollBarSize = 15;
  66. void    CTabControl::x_Init()
  67. {
  68.     end();
  69.     m_ResizePolicies = fShrink;//|fExpand ;
  70.     box(FL_NO_BOX);
  71.     m_Event.StandardConfig();
  72.     m_BorderColor =  fl_rgb_color(127, 127, 127);
  73.     m_ActiveBorderColor =  fl_rgb_color(96, 96, 96);
  74.     
  75.     m_BackColor =  fl_rgb_color(224, 224, 224);
  76.     m_ActiveBackColor = fl_rgb_color(240, 240, 240);
  77.     
  78.     m_TextColor =  fl_rgb_color(64, 64, 64);
  79.     m_ActiveTextColor =  fl_rgb_color(0, 0, 0);
  80.     m_Tooltip.SetMode(CTooltip::eStayOnMove);
  81.     m_Tooltip.EnableActiveMode(this);
  82. }
  83. void    CTabControl::SetResizePolicies(int policies)
  84. {
  85.     if(m_ResizePolicies != policies)    {
  86.         m_ResizePolicies = policies;
  87.         x_Layout();
  88.         redraw();
  89.     }
  90. }
  91. bool    CTabControl::AddTab(Fl_Widget* pane, const char* label)
  92. {
  93.     if(pane)    {
  94.         int count = x_GetTabsCount();
  95.         return x_InsertTab(pane, count, label, "");
  96.     }
  97.     return false;
  98. }
  99. bool    CTabControl::InsertTab(Fl_Widget* pane, int index, const char* label)
  100. {
  101.     int count = x_GetTabsCount();
  102.     if(pane  &&  index >=0  &&  index <= count)   {
  103.         return x_InsertTab(pane, index, label, "");
  104.     } 
  105.     return false;
  106. }
  107. bool    CTabControl::RemoveTab(Fl_Widget* pane)
  108. {
  109.     int index = x_GetTabIndex(pane);
  110.     if(index >= 0)   {
  111.         return x_RemoveTab(index);
  112.     }
  113.     return false;
  114. }
  115. bool    CTabControl::RemoveTab(int index)
  116. {
  117.     return x_RemoveTab(index);
  118. }
  119. void    CTabControl::RemoveAllTabs()
  120. {
  121.     x_RemoveAllTabs();
  122. }
  123. int     CTabControl::GetTabsCount()  const
  124. {
  125.     return x_GetTabsCount();
  126. }
  127.     
  128. Fl_Widget*  CTabControl::GetTab(int index)
  129. {
  130.     return x_GetPane(index);
  131. }
  132. string  CTabControl::GetTabLabel(int index)  const
  133. {
  134.     if(x_IsIndexValid(index))   {
  135.         return m_vDescrs[index]->m_Label;
  136.     } else return "";
  137. }
  138. string  CTabControl::GetTabTooltip(int index)  const
  139. {
  140.     if(x_IsIndexValid(index))   {
  141.         return m_vDescrs[index]->m_Tooltip;
  142.     } else return "";
  143. }
  144. void    CTabControl::SetTabLabel(int index, const char* label)
  145. {
  146.     if(x_IsIndexValid(index))   {
  147.         m_vDescrs[index]->m_Label = label ? label : "";
  148.         x_Layout();
  149.     }
  150. }   
  151. void    CTabControl::SetTabTooltip(int index, const char* tooltip)
  152. {
  153.     if(x_IsIndexValid(index))   {
  154.         m_vDescrs[index]->m_Tooltip = tooltip ? tooltip : "";
  155.         x_Layout();
  156.     }
  157. }
  158. int     CTabControl::GetSelectedTab() const
  159. {
  160.     return m_Selected;
  161. }
  162. void    CTabControl::SelectTab(int index)
  163. {
  164.     x_SelectTab(index);
  165. }
  166. Fl_Widget*    CTabControl::x_GetPane(int index)
  167. {
  168.     if(x_IsIndexValid(index))   {
  169.         return m_vDescrs[index]->m_pPane;
  170.     }
  171.     _ASSERT(false);
  172.     return false;
  173. }
  174. CTabControl::STabDescr*  CTabControl::x_GetTab(int index)
  175. {
  176.     if(x_IsIndexValid(index))   {
  177.         return m_vDescrs[index];
  178.     }
  179.     _ASSERT(false);
  180.     return NULL;
  181. }
  182. int     CTabControl::x_GetTabIndex(Fl_Widget* pane)  const
  183. {
  184.     for( int i = 0; i < x_GetTabsCount(); i++ ) {
  185.         if(m_vDescrs[i]->m_pPane == pane)
  186.             return i;
  187.     }
  188.     return -1;
  189. }
  190. bool    CTabControl::x_InsertTab(Fl_Widget* pane, int index, const char* label, 
  191.                         const char* tooltip)
  192. {
  193.     bool b_valid = index >= 0  && index <= x_GetTabsCount();
  194.     _ASSERT(b_valid);
  195.     if(b_valid) {
  196.         STabDescr* p_descr = new STabDescr;
  197.         p_descr->m_pPane = pane;
  198.         p_descr->m_Label = label ? label : "";
  199.         p_descr->m_Tooltip = tooltip ? tooltip : "";
  200.         pane->hide();
  201.         Fl_Group::add(pane);
  202.         m_vDescrs.insert(m_vDescrs.begin() + index, p_descr);
  203.     
  204.         x_LayoutTabs();
  205.         x_SelectTab(index);
  206.         return true;
  207.     } else return false;
  208. }
  209. bool    CTabControl::x_RemoveTab(int index)
  210. {
  211.     _ASSERT(x_IsIndexValid(index));
  212.     if(x_IsIndexValid(index))    {
  213.         STabDescr* p_descr = m_vDescrs[index];
  214.     
  215.         p_descr->m_pPane->hide();
  216.         Fl_Group::remove(p_descr->m_pPane);    
  217.         delete p_descr;
  218.         m_vDescrs.erase(m_vDescrs.begin() + index);
  219.         x_LayoutTabs();
  220.         // adjust selected
  221.         if(index < m_Selected)  {
  222.             m_Selected--;
  223.         }
  224.         bool b_reselect = (index == m_Selected);        
  225.         if(index == x_GetTabsCount()) 
  226.             index--;
  227.         if(b_reselect)  {    
  228.             m_Selected = -1;
  229.             x_SelectTab(index);    
  230.         }        
  231.         redraw();   
  232.         return true;
  233.     } else return false;
  234. }
  235. void    CTabControl::x_RemoveAllTabs()
  236. {
  237.     while(! m_vDescrs.empty())  {
  238.         STabDescr* p_descr = m_vDescrs.back();
  239.         
  240.         Fl_Group::remove(p_descr->m_pPane);
  241.         m_vDescrs.pop_back();
  242.     }
  243. }
  244. void    CTabControl::x_SelectTab(int index)
  245. {    
  246.     _ASSERT(index >= -1  &&  index < (int) x_GetTabsCount());
  247.     if(index != m_Selected) {
  248.         Fl_Widget* curr_w = x_GetSelectedPane();
  249.         if(curr_w)  {
  250.             curr_w->hide();
  251.         }
  252.         m_Selected = index;
  253.         
  254.         curr_w = x_GetSelectedPane();
  255.     
  256.         if(curr_w)  {    
  257.             int cl_x, cl_y, cl_w, cl_h;
  258.             x_GetClientRect(cl_x, cl_y, cl_w, cl_h);
  259.             curr_w->resize(cl_x, cl_y, cl_w, cl_h);
  260.             curr_w->show();
  261.         }
  262.         redraw();
  263.     }
  264. }
  265. CTabControl::STabDescr*   CTabControl::x_GetSelectedTab()
  266. {
  267.     if(x_IsIndexValid(m_Selected))  {
  268.         return m_vDescrs[m_Selected];
  269.     } else return NULL;
  270. }
  271. Fl_Widget*   CTabControl::x_GetSelectedPane()
  272. {
  273.     if(x_IsIndexValid(m_Selected))  {
  274.         return m_vDescrs[m_Selected]->m_pPane;
  275.     } else return NULL;
  276. }
  277. const static int    kClientOffset = 2; // client inset
  278. const static int    kTabRowH = 24; // height of a single row of tabs
  279. const static int    kTabOffsetX  = 8;
  280. const static int    kTabOffsetY  = 6;
  281. const static int    kTabSpaceY = 4; // vertical spacing between client and tab rectangle
  282. const static int    kTabSpaceX = 2; // space between client frame and tab rectangles
  283. void    CTabControl::draw()
  284. {
  285.     fl_push_clip(x(), y(), w(), h());
  286.     if (damage() & ~FL_DAMAGE_CHILD) { // redraw the entire thing:          
  287.         
  288.         int has_tabs = x_GetTabsCount() > 0;
  289.         int x2 = x() + w() - 1;
  290.         int y2 = y() + h() - 1;        
  291.         if(has_tabs)   {    // outer frame - backround color            
  292.             fl_color(m_BackColor);
  293.             fl_xyline(x(), y(), x2);        
  294.             fl_xyline(x(), y(), x(), y2);        
  295.             fl_xyline(x2,  y(), x2,  y2);    
  296.         } else { // fill entire area
  297.             fl_rectf(x(), y(), w(), h(), m_BackColor);                
  298.         }
  299.         int tab_top = y() + h() - x_GetTabAreaH();
  300.         int tab_bottom = y() + h();
  301.         int row_h = x_GetTabRowH();
  302.         // fill Tab area
  303.         int area_h = x_GetTabAreaH() + kClientOffset;
  304.         int area_w = w() - 2 * kClientOffset;
  305.         
  306.         int highlight_h = kTabSpaceY;
  307.         
  308.         int off = kClientOffset - 1;        
  309.         if(m_Selected != -1)    {
  310.             STabDescr* p_descr = m_vDescrs[m_Selected];
  311.             highlight_h = p_descr->m_y - (h() - x_GetTabAreaH() - kClientOffset);
  312.             y2 = y() + p_descr->m_y;
  313.         } else y2 -= off;
  314.         
  315.         int y3 =  tab_top - kClientOffset;
  316.         fl_rectf(x() + kClientOffset, y3, area_w, highlight_h, m_ActiveBackColor);
  317.         fl_rectf(x(), y3 + highlight_h, w(), area_h - highlight_h, m_BackColor);        
  318.         
  319.         // draw inner frame with border color
  320.         fl_color(m_ActiveBorderColor);
  321.         fl_xyline(x() + off, y() + off, x2 - off);        
  322.         fl_xyline(x() + off, y() + off , x() + off, y2);        
  323.         fl_xyline(x2 - off, y() + off, x2 - off, y2);    
  324.         if(! has_tabs)  {
  325.             fl_xyline(x() + off, y2, x2 - off, y2);    
  326.         }
  327.         // draw tabs
  328.         fl_font(FL_HELVETICA, 12);    
  329.         for( int i = 0; i < x_GetTabsCount(); i++ )   {
  330.             x_DrawTab(i);
  331.         }
  332.     }
  333.     Fl_Group::draw();    
  334.     fl_pop_clip();
  335. }
  336. /// draws Tab corresponding to a given index
  337. void    CTabControl::x_DrawTab(int index)   
  338. {
  339.     STabDescr* p_descr = m_vDescrs[index];
  340.     
  341.     bool bActive = (index == m_Selected);
  342.     int off_x = bActive ? 2 : 0;
  343.     int x1 = x() + p_descr->m_x - off_x;
  344.     int y1 = y() + p_descr->m_y;
  345.     int width = p_descr->m_w - 1 + 2 * off_x;
  346.     int height = p_descr->m_h - 2;
  347.     int x2 = x1 + width - 1;
  348.     int y2 = y1 + height - 1;        
  349.     
  350.     // draw Tab countour
  351.     fl_color(bActive ? m_ActiveBorderColor : m_BorderColor);
  352.     
  353.     fl_xyline(x1, y1, x1, y2 - 2); // left vert
  354.     fl_line(x1, y2 - 2, x1 + 2, y2);
  355.     fl_xyline(x1 + 2, y2, x2 - 2, y2); // horz line
  356.     fl_line(x2 - 2, y2, x2, y2 - 2);    
  357.     fl_xyline(x2, y1, x2, y2 - 2); // right vert
  358.     
  359.     // fill tab's background
  360.     if(bActive) {
  361.         fl_color(m_ActiveBackColor);
  362.         fl_rectf(x1 + 1, y1, width - 2, height - 2);
  363.     } else  {
  364.         fl_color(m_BackColor);
  365.         fl_rectf(x1 + 1, y1 +1, width - 2, height - 3);
  366.     }
  367.             
  368.     // tab's edge
  369.     fl_color(m_BackColor);
  370.     fl_xyline(x1 + 1, y2 - 2, x2 - 1);
  371.     fl_xyline(x1 + 2, y2 - 1, x2 - 2);       
  372.      
  373.     if(index == m_Selected)    {
  374.         // horizontal line closing client rect
  375.         fl_color(m_ActiveBorderColor);
  376.         int off = kClientOffset - 1;
  377.         fl_xyline(x() + off, y1, x1 - off);
  378.         fl_xyline(x2 + off, y1, x() + w() - 1 - off);
  379.     }
  380.     //draw label  
  381.     int text_x = x1 + off_x + kTabOffsetX;
  382.     int text_y = y2 - kTabOffsetY;
  383.     int text_w = width - 2 * kTabOffsetX;
  384.     fl_push_clip(text_x, y1, text_w, height);
  385.     
  386.     fl_color(bActive ? m_ActiveTextColor : m_TextColor);    
  387.     fl_draw_text(p_descr->m_Label, text_x, text_y, text_w); 
  388.     fl_pop_clip();   
  389. }
  390. void    CTabControl::resize(int new_x, int new_y, int new_w, int new_h)
  391. {
  392.     bool b_size_changed = new_w != w()  || new_h != h();
  393.     bool b_pos_changed = new_x != x()  || new_y != y();
  394.     
  395.     if(b_size_changed  ||  b_pos_changed)   {
  396.         Fl_Widget::resize(new_x, new_y, new_w, new_h);
  397.         if(b_size_changed)  {
  398.             x_Layout();                  
  399.             redraw();
  400.         }
  401.     }
  402. }
  403. void    CTabControl::x_Layout()
  404. {
  405.     x_LayoutTabs();
  406.     // resize selected (visible) pane
  407.     Fl_Widget* pane = x_GetSelectedPane();
  408.     if(pane)    {
  409.         int cl_x, cl_y, cl_w, cl_h;
  410.         x_GetClientRect(cl_x, cl_y, cl_w, cl_h);
  411.         pane->resize(cl_x, cl_y, cl_w, cl_h);
  412.     } 
  413. }
  414. void    CTabControl::x_LayoutTabs()
  415. {
  416.     bool b_multi = (m_ResizePolicies & fMultiRow) != 0;
  417.     bool b_expand = (m_ResizePolicies & fExpand) != 0;    
  418.     bool b_shrink = (m_ResizePolicies & fShrink) != 0;    
  419.     
  420.     m_vRows.clear();
  421.     // mesuare all tabs
  422.     vector<int> widths;
  423.     int total_w = 0;
  424.     int n_tabs = x_GetTabsCount(); 
  425.     for ( int i = 0; i < n_tabs; i++  )   {
  426.         int width = x_MeasureTabWidth(i);
  427.         total_w += width;
  428.         widths.push_back(width);
  429.     }
  430.     
  431.     int w_av = w() - 2 * (kTabSpaceX + kClientOffset);    
  432.     int row_h = x_GetTabRowH();
  433.     int pos_x = kClientOffset + kTabSpaceX;
  434.     
  435.     //assembling tabs in rows
  436.     if(b_multi) { // create multi-row layout
  437.         for ( int i = 0; i < n_tabs; i++  )   {
  438.             int width = widths[i];
  439.             if(i == 0  ||  pos_x + width > w_av)    { // start next row
  440.                 m_vRows.push_back(TRowIndexes());
  441.                 pos_x = kClientOffset + 1;
  442.             }
  443.             pos_x += width;        
  444.             m_vRows.back().push_back(i);
  445.         }
  446.     }   else {
  447.         if(b_shrink  &&  total_w > w_av) { // distributing space deficit
  448.             double K = ((double) w_av) / total_w; // reduction koeff.
  449.             int pos = 0;
  450.             for ( int i = 0; i < n_tabs; i++  )   {
  451.                 int prev_pos = pos;
  452.                 pos += widths[i];                
  453.                 widths[i] = (int)(K * pos) - (int)(K * prev_pos);
  454.             }
  455.         }
  456.         m_vRows.push_back(TRowIndexes());
  457.         for ( int i = 0; i < n_tabs; i++  )   {
  458.             m_vRows.back().push_back(i);
  459.         }
  460.     }
  461.     
  462.     //now we know how many rows we need
  463.     m_TabAreaH = kTabSpaceY + row_h * m_vRows.size();
  464.     
  465.     // assign positions to rows
  466.     int pos_y = h() - m_TabAreaH + kTabSpaceY;            
  467.     
  468.     for( size_t row = 0;  row < m_vRows.size();  row++ )  { // for each row
  469.         TRowIndexes& indexes = m_vRows[row];
  470.         pos_x = kClientOffset + kTabSpaceX;
  471.         int n_cols = indexes.size();
  472.         int row_w, delta, rest; // used in fExpand mode
  473.         if(b_expand)    {
  474.             row_w = 0;
  475.             for( int col = 0;  col < n_cols; col++ )    {
  476.                 row_w += widths[indexes[col]];
  477.             }
  478.             int extra = w_av - row_w; // available extra space in a row
  479.             if(extra > 0)   {
  480.                 delta = extra / n_cols;
  481.                 rest = extra - delta * n_cols; // space that cannot be divided between all tabs
  482.             } else delta = rest = 0;
  483.         }
  484.         for( int col = 0;  col < n_cols; col++ )    { // for each tab in a row
  485.             int i_tab = indexes[col];
  486.             STabDescr*  p_descr = m_vDescrs[i_tab];  
  487.             int tab_w = min(widths[i_tab], w_av); // not wider than control
  488.             if(b_expand)   {
  489.                 tab_w += delta + ((col < rest) ? 1 : 0);
  490.             }
  491.             p_descr->m_x = pos_x;
  492.             p_descr->m_w = tab_w;
  493.             pos_x += tab_w;
  494.             
  495.             p_descr->m_y = pos_y;
  496.             p_descr->m_h = row_h;
  497.         }
  498.         pos_y += row_h;
  499.     }
  500. }
  501. int     CTabControl::x_GetTabAreaH() const
  502. {
  503.     return m_TabAreaH;
  504. }
  505. int     CTabControl::x_GetTabRowH()  const
  506. {
  507.     return kTabRowH;
  508. }
  509. int     CTabControl::x_MeasureTabWidth(int index)
  510. {
  511.     STabDescr*  p_descr = m_vDescrs[index];
  512.     fl_font(FL_HELVETICA, 12);
  513.     const char* p_text = p_descr->m_Label.c_str();
  514.     int text_w = fl_width(p_text);
  515.     int width = text_w + 2 * kTabOffsetX + 1;
  516.     return width;
  517. }
  518. int  CTabControl::handle(int event)
  519. {
  520.     m_Event.OnFLTKEvent(event);
  521.     
  522.     int res = 0;
  523.     switch(event)   {
  524.     case FL_KEYDOWN:
  525.     case FL_KEYUP:  res = x_HandleKeyEvent(); break;
  526.     case FL_MOVE:   res = x_HandleMouseMove(); break;
  527.     case FL_PUSH:   res = x_HandleMousePush(); break;
  528.     case FL_DRAG: res = x_HandleMouseDrag(); break;
  529.     case FL_RELEASE: res = x_HandleMouseRelease(); break;
  530.     default: {
  531.         res = Fl_Group::handle(event);
  532.     }; break;
  533.     }
  534.     m_Tooltip.Handle(event);
  535.     return res;
  536. }
  537. bool    CTabControl::x_IsIndexValid(int index) const
  538. {
  539.     return index >= 0 && index < x_GetTabsCount();
  540. }
  541. void    CTabControl::x_GetClientRect(int& cl_x, int& cl_y, int& cl_w, int& cl_h)
  542. {
  543.     cl_x = x() + kClientOffset; 
  544.     cl_y = y() + kClientOffset;
  545.     cl_w = w() - 2 * kClientOffset;
  546.     cl_h = h() - x_GetTabAreaH() - 2 * kClientOffset;
  547. }
  548. bool inline PointInRect(int px, int py, int x, int y, int w, int h)
  549. {
  550.     return px >= x  &&  px < x + w &&  py >= y  &&  py < y + h;
  551. }
  552. CTabControl::EHitResult  CTabControl::x_HitTest(int pos_x, int pos_y, int& i_tab)
  553. {
  554.     i_tab = -1;
  555.     if(PointInRect(pos_x, pos_y, x(), y(), w(), h()))  {
  556.         
  557.         int cl_x, cl_y, cl_w, cl_h;
  558.         x_GetClientRect(cl_x, cl_y, cl_w, cl_h);
  559.         if(PointInRect(pos_x, pos_y, cl_x, cl_y, cl_w, cl_h))   {
  560.             return eClient;
  561.         } else {
  562.             for( int i = 0; i < x_GetTabsCount(); i++ ) {
  563.                 STabDescr*  p_descr = m_vDescrs[i];
  564.                 int loc_x = pos_x - x();
  565.                 int loc_y = pos_y - y();
  566.                 if(PointInRect(loc_x, loc_y, p_descr->m_x, p_descr->m_y, 
  567.                                 p_descr->m_w, p_descr->m_h)) {
  568.                     i_tab = i;
  569.                     return eTab;
  570.                 }
  571.             }
  572.         }
  573.         return eEmptySpace;
  574.     }
  575.     return eNothing;            
  576. }
  577. int    CTabControl::x_HandleKeyEvent()
  578. {
  579.     return 0;
  580. }
  581. int    CTabControl::x_HandleMouseMove()
  582. {
  583.     return Fl_Group::handle(FL_MOVE);
  584. }
  585. int    CTabControl::x_HandleMousePush()
  586. {
  587.     int i_tab;
  588.     EHitResult hit_res = x_HitTest(Fl::event_x(), Fl::event_y(), i_tab);
  589.     
  590.     switch(hit_res) {
  591.     case eClient:   return Fl_Group::handle(FL_PUSH);   break;
  592.     case eTab:
  593.     case eEmptySpace: {
  594.         int res = 0;
  595.         switch(m_Event.GetGUISignal()) {
  596.         // any mouse click event switches tabs
  597.         case    CGUIEvent::ePush:   //return true;
  598.         case    CGUIEvent::eSelectSignal:  
  599.         case    CGUIEvent::ePopupSignal: {
  600.             if(i_tab != -1) {
  601.                 x_SelectTab(i_tab);
  602.                 res = 1;
  603.             }
  604.         }
  605.         }; // switch(m_Event.GetGUISignal()) 
  606.         if(m_Event.GetGUISignal() ==  CGUIEvent::ePopupSignal)   {
  607.             fl_cursor(FL_CURSOR_DEFAULT, FL_BLACK, FL_WHITE); 
  608.             x_OnShowPopupMenu();    
  609.         }
  610.         return res;        
  611.     }; break;
  612.     }; // switch(hit_res) {
  613.     return 0;
  614. }
  615. int    CTabControl::x_HandleMouseDrag()
  616. {
  617.     return Fl_Group::handle(FL_DRAG);
  618. }
  619. int    CTabControl::x_HandleMouseRelease()
  620. {
  621.     int i_tab;
  622.     EHitResult hit_res = x_HitTest(Fl::event_x(), Fl::event_y(), i_tab);
  623.     
  624.     bool b_handled = false;
  625.     CGUIEvent::EGUISignal signal = m_Event.GetGUISignal(); // remember
  626.     
  627.     if(hit_res == eClient)  {
  628.         if(Fl_Group::handle(FL_RELEASE))
  629.             return true;
  630.     } else if(hit_res == eTab)  {
  631.         _ASSERT(i_tab != -1);
  632.         x_SelectTab(i_tab);
  633.     }
  634.     if((signal ==  CGUIEvent::ePopupSignal)  && 
  635.         (hit_res == eTab  || hit_res == eEmptySpace))   {
  636.         fl_cursor(FL_CURSOR_DEFAULT, FL_BLACK, FL_WHITE); 
  637.         x_OnShowPopupMenu();    
  638.         return 1;
  639.     }
  640.     return 0;
  641. }
  642. void    CTabControl::x_OnShowPopupMenu()
  643. {
  644. }
  645. bool    CTabControl::TC_NeedTooltip(int x, int y)
  646. {
  647.     EHitResult hit_res = x_HitTest(Fl::event_x(), Fl::event_y(), m_iHitTab);    
  648.     return hit_res == eTab;
  649. }
  650. string  CTabControl::TC_GetTooltip(int& x, int& y, int& w, int& h)
  651. {
  652.     if(m_iHitTab != -1) {
  653.         _ASSERT(x_IsIndexValid(m_iHitTab));
  654.         STabDescr* p_descr = m_vDescrs[m_iHitTab];
  655.         x = p_descr->m_x;
  656.         y = p_descr->m_y;
  657.         w = p_descr->m_w;
  658.         h = p_descr->m_h;
  659.         return p_descr->m_Label;
  660.     }
  661.     return "";
  662. }
  663. END_NCBI_SCOPE
  664. /*
  665.  * ===========================================================================
  666.  * $Log: tab_control.cpp,v $
  667.  * Revision 1000.1  2004/06/01 21:09:17  gouriano
  668.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.8
  669.  *
  670.  * Revision 1.8  2004/05/21 22:27:53  gorelenk
  671.  * Added PCH ncbi_pch.hpp
  672.  *
  673.  * Revision 1.7  2004/05/20 12:44:06  dicuccio
  674.  * Added explicit call to end() - closes tab group correctly
  675.  *
  676.  * Revision 1.6  2004/05/13 17:20:32  yazhuk
  677.  * Moved fl_draw_text() functions to utils.hpp; added end() to x_Init()
  678.  *
  679.  * Revision 1.5  2004/05/07 14:21:23  yazhuk
  680.  * Fixed RemoveTab()
  681.  *
  682.  * Revision 1.4  2004/03/08 15:53:13  yazhuk
  683.  * Fixed popup menu handling; clean-up
  684.  *
  685.  * Revision 1.3  2004/03/02 22:27:20  yazhuk
  686.  * Popup menu fix for Mac
  687.  *
  688.  * Revision 1.2  2004/02/04 20:26:36  ucko
  689.  * Fix capitalization of fl_draw.H.
  690.  *
  691.  * Revision 1.1  2004/02/04 20:01:20  yazhuk
  692.  * Initial revision
  693.  *
  694.  * ===========================================================================
  695.  */