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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: status_bar.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 21:09:12  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.6
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: status_bar.cpp,v 1000.2 2004/06/01 21:09:12 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:  Mike DiCuccio
  35.  *
  36.  * File Description:
  37.  *
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <gui/widgets/fl/status_bar.hpp>
  41. #include <gui/widgets/fl/utils.hpp>
  42. #include <FL/Fl.H>
  43. #include <FL/fl_draw.H>
  44. BEGIN_NCBI_SCOPE
  45. ////////////////////////////////////////////////////////////////////////////////
  46. /// CStatusBar1
  47. static const int    kSlotSpacing = 6; // horz distance between adjasent slots
  48. static const int    kBorder = 2;
  49. static const Fl_Color   kStatusBarColor = fl_rgb_color(216, 216, 216);
  50. CStatusBar1::CStatusBar1(int x, int y, int w, int h)
  51. :   Fl_Group(x, y, w, h),
  52.     m_LastHandle(0)
  53. {
  54.     color(kStatusBarColor);    
  55.     box(FL_FLAT_BOX);
  56. }
  57. CStatusBar1::~CStatusBar1()
  58. {
  59.  //### delete everything
  60. }
  61. CStatusBar1::TSlotHandle    CStatusBar1::CreateSlot(int width)
  62. {
  63.    Fl_Group::current(0);
  64.    CSBSlot* slot = new CSBSlot();
  65.    return CreateSlot(slot, width);
  66. }
  67. // function assumes ownership of the given slot
  68. CStatusBar1::TSlotHandle    CStatusBar1::CreateSlot(ISBSlot* slot, int width)
  69. {
  70.     Fl_Widget* widget = dynamic_cast<Fl_Widget*>(slot);
  71.     if(widget)  {
  72.         TSlotHandle handle = ++m_LastHandle;
  73.         m_HandleToSlot[handle] = slot;
  74.                 
  75.         width = (width <= 0)  ? 50 : width;
  76.         m_HandleToWidth[handle] = width;
  77.         widget->resize(0, 0, width, 0);
  78.         add(widget); // add Fl_Group
  79.         
  80.         // here we handle layout
  81.         ReLayout();
  82.         return handle;
  83.     } else return 0;
  84. }
  85. bool    CStatusBar1::RemoveSlot(TSlotHandle handle)
  86. {
  87.     ISBSlot* slot = GetSlot(handle);
  88.     if(slot)    {
  89.         Fl_Widget* widget = dynamic_cast<Fl_Widget*>(slot);
  90.         remove(widget);
  91.         m_HandleToWidth.erase(handle);
  92.         m_HandleToSlot.erase(handle);
  93.         delete slot;
  94.         ReLayout();
  95.     }
  96.     return false;
  97. }
  98. ISBSlot*    CStatusBar1::GetSlot(TSlotHandle handle)
  99. {
  100.     THandleToSlotMap::iterator it = m_HandleToSlot.find(handle);
  101.     return (it == m_HandleToSlot.end()) ? NULL : it->second;
  102. }
  103. const ISBSlot*    CStatusBar1::GetSlot(TSlotHandle handle) const
  104. {
  105.     THandleToSlotMap::const_iterator it = m_HandleToSlot.find(handle);
  106.     return (it == m_HandleToSlot.end()) ? NULL : it->second;
  107. }
  108. void    CStatusBar1::SetSlotStyles(TSlotHandle handle, int styles)
  109. {
  110.     ISBSlot* slot = GetSlot(handle);
  111.     if(slot)    {
  112.         slot->SetStyles(styles);
  113.     }
  114. }
  115. int     CStatusBar1::GetSlotStyles(TSlotHandle handle)
  116. {
  117.     ISBSlot* slot = GetSlot(handle);
  118.     return slot ? slot->GetStyles() : 0;
  119. }
  120. void    CStatusBar1::SetSlotText(TSlotHandle handle, const string& text)
  121. {
  122.     ISBSlot* slot = GetSlot(handle);
  123.     if(slot)    {
  124.         slot->SetText(text);
  125.     }
  126. }
  127. string   CStatusBar1::GetSlotText(TSlotHandle handle) const
  128. {
  129.     const ISBSlot* slot = GetSlot(handle);
  130.     return slot ? slot->GetText() : "";
  131. }
  132. void    CStatusBar1::SetSlotTooltip(TSlotHandle handle, const string& tooltip)
  133. {
  134. }
  135. string   CStatusBar1::GetSlotTooltip(TSlotHandle handle) const
  136. {
  137.     return "";
  138. }
  139. void    CStatusBar1::SetSlotImage(TSlotHandle handle, CFLTKImageHandle image)
  140. {
  141.     ISBSlot* slot = GetSlot(handle);
  142.     if(slot)    {
  143.         slot->SetImage(image);
  144.     }
  145. }
  146. CFLTKImageHandle     CStatusBar1::GetSlotImage(TSlotHandle handle)
  147. {
  148.    ISBSlot* slot = GetSlot(handle);
  149.    return slot ? slot->GetImage() : CFLTKImageHandle();
  150. }
  151. void    CStatusBar1::SetSlotWidth(TSlotHandle handle, int width)
  152. {
  153.     THandleToWidthMap::iterator it = m_HandleToWidth.find(handle);
  154.     if(it != m_HandleToWidth.end()) {
  155.         it->second = width;
  156.     }
  157.     
  158. }
  159. int     CStatusBar1::GetSlotWidth(TSlotHandle handle) const
  160. {
  161.     THandleToWidthMap::const_iterator it = m_HandleToWidth.find(handle);
  162.     return (it != m_HandleToWidth.end()) ? it->second : 0;
  163. }
  164. void    CStatusBar1::ReLayout()
  165. {
  166.     x_Layout();
  167.     redraw();
  168. }
  169. void    CStatusBar1::draw()
  170. {
  171.     fl_push_clip(x(), y(), w(), h());
  172.     Fl_Group::draw();
  173.     
  174.     fl_pop_clip();
  175. }
  176. void    CStatusBar1::resize(int x, int y, int w, int h)
  177. {
  178.     Fl_Widget::resize(x, y, w, h);
  179.     x_Layout();
  180. }
  181. void    CStatusBar1::x_Layout()
  182. {
  183.     ISBSlot* resizable_slot = NULL;
  184.     int slots_w = 0; // width of all slots except resizable one
  185.     ITERATE(THandleToSlotMap, it, m_HandleToSlot)   {
  186.         int styles = it->second->GetStyles();
  187.         if(resizable_slot == NULL  &&  (styles & ISBSlot::fResizable))    {
  188.             resizable_slot = it->second; // found resizable slot
  189.         } else {
  190.             int width = m_HandleToWidth[it->first];
  191.             slots_w += width; // accumulate width
  192.         }
  193.         slots_w += kSlotSpacing;
  194.     }
  195.     slots_w -= kSlotSpacing; // N slots have N-1 spaces between them
  196.     int av_w = w() - 2 * kBorder; // total available for slots
  197.     int resizable_w = max(0, av_w - slots_w); // width of resizable slot
  198.     int pos_x = x() + kBorder;
  199.     int pos_y = y() + kBorder;
  200.     int height = h() - 2 * kBorder;
  201.     ITERATE(THandleToSlotMap, it, m_HandleToSlot)   {        
  202.         Fl_Widget* slot = dynamic_cast<Fl_Widget*>(it->second);
  203.         
  204.         int width = (it->second == resizable_slot) ? resizable_w : m_HandleToWidth[it->first];
  205.         if(av_w > 0)    {
  206.             width = min(width, av_w);
  207.         } else  {
  208.             width = 0;
  209.         }
  210.         slot->resize(pos_x, pos_y, width, height);
  211.         
  212.         pos_x += width + kSlotSpacing;
  213.     }   
  214. }
  215. static const int    kSlotOffsetX = 4;
  216. CSBSlot::CSBSlot()
  217. :   Fl_Group(0, 0, 0, 0)    
  218. {
  219.     labelfont(FL_HELVETICA);
  220.     labelsize(12);
  221.     
  222.     color(kStatusBarColor);    
  223.     SetStyles(0);
  224. }
  225. void    CSBSlot::draw()
  226. {
  227.     Fl_Group::draw();
  228.     x_Draw();
  229. }
  230. void    CSBSlot::SetStyles(int styles)
  231. {
  232.     m_Styles = styles;
  233. }
  234. int     CSBSlot::GetStyles() const
  235. {
  236.     return m_Styles;
  237. }
  238. void    CSBSlot::SetText(const string& text)
  239. {
  240.     m_Text = text;
  241.     redraw();
  242. }
  243. string  CSBSlot::GetText()  const
  244. {
  245.     return m_Text;
  246. }
  247. void    CSBSlot::SetImage(CFLTKImageHandle image)
  248. {
  249.     m_Image = image;
  250.     redraw();
  251. }
  252. CFLTKImageHandle     CSBSlot::GetImage()
  253. {
  254.     return m_Image;
  255. }
  256. void    CSBSlot::x_Draw()
  257. {
  258.     fl_clip(x(), y(), w(), h());
  259.  
  260.     x_DrawBackground();
  261.     x_DrawContent();   
  262.  
  263.     fl_pop_clip();
  264. }
  265. void    CSBSlot::x_DrawBackground()
  266. {
  267.     if(m_Styles & fDownBox) {
  268.         fl_draw_box(FL_THIN_DOWN_BOX, x(), y(), w(), h(), kStatusBarColor);
  269.     } else if(m_Styles & fUpBox) {
  270.         fl_draw_box(FL_THIN_UP_BOX, x(), y(), w(), h(), kStatusBarColor);
  271.     } else {
  272.         fl_color(kStatusBarColor);
  273.         fl_rectf(x(), y(), w(), h());
  274.         fl_color(fl_darker(kStatusBarColor));
  275.         fl_rect(x(), y(), w(), h());
  276.     }
  277. }
  278. void    CSBSlot::x_DrawContent()    
  279. {
  280.     int off = 1;
  281.     fl_clip(x() + off, y() + off, w() - 2 * off, h() - 2 * off);
  282.     int pos_x = x() + kSlotOffsetX;
  283.     int pos_y = y() + kBorder; //###
  284.     if(m_Image) {
  285.         CPNGImageExt* ext_image = dynamic_cast<CPNGImageExt*>(&(*m_Image));
  286.         if(ext_image)   {
  287.             ext_image->DrawTransparent(color(), pos_x, pos_y, ext_image->w(), ext_image->h());
  288.         } else {
  289.             m_Image->draw(pos_x, pos_y, ext_image->w(), ext_image->h());
  290.         }
  291.         pos_x += ext_image->w() + kSlotOffsetX;
  292.     }
  293.     // draw text
  294.     fl_color(FL_BLACK);
  295.     fl_font(labelfont(), labelsize());
  296.     
  297.     int text_space = (x() + w() - kSlotOffsetX) - pos_x;
  298.     int text_h = fl_height() - fl_descent();
  299.     int offset = 0;
  300.     if(m_Styles & fCenterText)  {
  301.         int width = fl_width(m_Text.c_str());
  302.         offset = (width < text_space) ? (text_space - width) / 2 : 0;       
  303.     }
  304.     int text_y = y() + (h() + text_h) / 2 - 1; //###
  305.     fl_draw_text(m_Text, pos_x + offset, text_y, text_space);
  306.     
  307.     fl_pop_clip();
  308. }
  309. ////////////////////////////////////////////////////////////////////////////////
  310. /// CStatusBar
  311. CStatusBar::CStatusBar(int x, int y, int w, int h, const char* label)
  312.     : Fl_Group(x, y, w, h, label)
  313. {
  314.     align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
  315. }
  316. void CStatusBar::label(const char* label)
  317. {
  318.     SetMessage(label);
  319. }
  320. const char* CStatusBar::label(void) const
  321. {
  322.     return Fl_Group::label();
  323. }
  324. void CStatusBar::SetMessage(const string& msg)
  325. {
  326.     CFastMutexGuard LOCK(m_Mutex);
  327.     if ( m_MsgStack.size() == 0) {
  328.         m_MsgStack.push_back(msg);
  329.     } else {
  330.         m_MsgStack.back() = msg;
  331.     }
  332.     Fl_Group::label(m_MsgStack.back().c_str());
  333.     redraw();
  334.     Fl::check();
  335. }
  336. void CStatusBar::Clear(void)
  337. {
  338.     CFastMutexGuard LOCK(m_Mutex);
  339.     m_MsgStack.clear();
  340.     Fl_Group::label("");
  341.     Fl::check();
  342. }
  343. void CStatusBar::PushMessage(const string& msg)
  344. {
  345.     CFastMutexGuard LOCK(m_Mutex);
  346.     m_MsgStack.push_back(msg);
  347.     Fl_Group::label(m_MsgStack.back().c_str());
  348.     Fl::check();
  349. }
  350. string CStatusBar::PopMessage()
  351. {
  352.     CFastMutexGuard LOCK(m_Mutex);
  353.     if (m_MsgStack.size() == 0) {
  354.         return string();
  355.     }
  356.     string ret = m_MsgStack.back();
  357.     m_MsgStack.pop_back();
  358.     if (m_MsgStack.size() == 0) {
  359.         Fl_Group::label(NULL);
  360.     } else {
  361.         Fl_Group::label(m_MsgStack.back().c_str());
  362.     }
  363.     Fl::check();
  364.     return ret;
  365. }
  366. CStatusBarGuard::CStatusBarGuard(CStatusBar& bar, const string& msg)
  367.     : m_Bar(bar)
  368. {
  369.     m_Bar.PushMessage(msg);
  370. }
  371. CStatusBarGuard::~CStatusBarGuard()
  372. {
  373.     m_Bar.PopMessage();
  374. }
  375. END_NCBI_SCOPE
  376. /*
  377.  * ===========================================================================
  378.  * $Log: status_bar.cpp,v $
  379.  * Revision 1000.2  2004/06/01 21:09:12  gouriano
  380.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.6
  381.  *
  382.  * Revision 1.6  2004/06/01 18:11:25  dicuccio
  383.  * Force redraw on changing message
  384.  *
  385.  * Revision 1.5  2004/05/21 22:27:53  gorelenk
  386.  * Added PCH ncbi_pch.hpp
  387.  *
  388.  * Revision 1.4  2004/05/13 17:22:39  yazhuk
  389.  * Implemented ISBSlot, CSBSlot and CStatusBar1 classes
  390.  *
  391.  * Revision 1.3  2004/04/14 20:57:22  johnson
  392.  * added Clear() to IReporter interface
  393.  *
  394.  * Revision 1.2  2004/04/07 13:08:05  dicuccio
  395.  * Set default alignment.  Added calls to Fl::check() to keep status bar alive
  396.  *
  397.  * Revision 1.1  2003/12/04 18:15:28  dicuccio
  398.  * Added status bar classes
  399.  *
  400.  * ===========================================================================
  401.  */