status_bar.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:11k
- /*
- * ===========================================================================
- * PRODUCTION $Log: status_bar.cpp,v $
- * PRODUCTION Revision 1000.2 2004/06/01 21:09:12 gouriano
- * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.6
- * PRODUCTION
- * ===========================================================================
- */
- /* $Id: status_bar.cpp,v 1000.2 2004/06/01 21:09:12 gouriano Exp $
- * ===========================================================================
- *
- * PUBLIC DOMAIN NOTICE
- * National Center for Biotechnology Information
- *
- * This software/database is a "United States Government Work" under the
- * terms of the United States Copyright Act. It was written as part of
- * the author's official duties as a United States Government employee and
- * thus cannot be copyrighted. This software/database is freely available
- * to the public for use. The National Library of Medicine and the U.S.
- * Government have not placed any restriction on its use or reproduction.
- *
- * Although all reasonable efforts have been taken to ensure the accuracy
- * and reliability of the software and data, the NLM and the U.S.
- * Government do not and cannot warrant the performance or results that
- * may be obtained by using this software or data. The NLM and the U.S.
- * Government disclaim all warranties, express or implied, including
- * warranties of performance, merchantability or fitness for any particular
- * purpose.
- *
- * Please cite the author in any work or product based on this material.
- *
- * ===========================================================================
- *
- * Authors: Mike DiCuccio
- *
- * File Description:
- *
- */
- #include <ncbi_pch.hpp>
- #include <gui/widgets/fl/status_bar.hpp>
- #include <gui/widgets/fl/utils.hpp>
- #include <FL/Fl.H>
- #include <FL/fl_draw.H>
- BEGIN_NCBI_SCOPE
- ////////////////////////////////////////////////////////////////////////////////
- /// CStatusBar1
- static const int kSlotSpacing = 6; // horz distance between adjasent slots
- static const int kBorder = 2;
- static const Fl_Color kStatusBarColor = fl_rgb_color(216, 216, 216);
- CStatusBar1::CStatusBar1(int x, int y, int w, int h)
- : Fl_Group(x, y, w, h),
- m_LastHandle(0)
- {
- color(kStatusBarColor);
- box(FL_FLAT_BOX);
- }
- CStatusBar1::~CStatusBar1()
- {
- //### delete everything
- }
- CStatusBar1::TSlotHandle CStatusBar1::CreateSlot(int width)
- {
- Fl_Group::current(0);
- CSBSlot* slot = new CSBSlot();
- return CreateSlot(slot, width);
- }
- // function assumes ownership of the given slot
- CStatusBar1::TSlotHandle CStatusBar1::CreateSlot(ISBSlot* slot, int width)
- {
- Fl_Widget* widget = dynamic_cast<Fl_Widget*>(slot);
- if(widget) {
- TSlotHandle handle = ++m_LastHandle;
- m_HandleToSlot[handle] = slot;
-
- width = (width <= 0) ? 50 : width;
- m_HandleToWidth[handle] = width;
- widget->resize(0, 0, width, 0);
- add(widget); // add Fl_Group
-
- // here we handle layout
- ReLayout();
- return handle;
- } else return 0;
- }
- bool CStatusBar1::RemoveSlot(TSlotHandle handle)
- {
- ISBSlot* slot = GetSlot(handle);
- if(slot) {
- Fl_Widget* widget = dynamic_cast<Fl_Widget*>(slot);
- remove(widget);
- m_HandleToWidth.erase(handle);
- m_HandleToSlot.erase(handle);
- delete slot;
- ReLayout();
- }
- return false;
- }
- ISBSlot* CStatusBar1::GetSlot(TSlotHandle handle)
- {
- THandleToSlotMap::iterator it = m_HandleToSlot.find(handle);
- return (it == m_HandleToSlot.end()) ? NULL : it->second;
- }
- const ISBSlot* CStatusBar1::GetSlot(TSlotHandle handle) const
- {
- THandleToSlotMap::const_iterator it = m_HandleToSlot.find(handle);
- return (it == m_HandleToSlot.end()) ? NULL : it->second;
- }
- void CStatusBar1::SetSlotStyles(TSlotHandle handle, int styles)
- {
- ISBSlot* slot = GetSlot(handle);
- if(slot) {
- slot->SetStyles(styles);
- }
- }
- int CStatusBar1::GetSlotStyles(TSlotHandle handle)
- {
- ISBSlot* slot = GetSlot(handle);
- return slot ? slot->GetStyles() : 0;
- }
- void CStatusBar1::SetSlotText(TSlotHandle handle, const string& text)
- {
- ISBSlot* slot = GetSlot(handle);
- if(slot) {
- slot->SetText(text);
- }
- }
- string CStatusBar1::GetSlotText(TSlotHandle handle) const
- {
- const ISBSlot* slot = GetSlot(handle);
- return slot ? slot->GetText() : "";
- }
- void CStatusBar1::SetSlotTooltip(TSlotHandle handle, const string& tooltip)
- {
- }
- string CStatusBar1::GetSlotTooltip(TSlotHandle handle) const
- {
- return "";
- }
- void CStatusBar1::SetSlotImage(TSlotHandle handle, CFLTKImageHandle image)
- {
- ISBSlot* slot = GetSlot(handle);
- if(slot) {
- slot->SetImage(image);
- }
- }
- CFLTKImageHandle CStatusBar1::GetSlotImage(TSlotHandle handle)
- {
- ISBSlot* slot = GetSlot(handle);
- return slot ? slot->GetImage() : CFLTKImageHandle();
- }
- void CStatusBar1::SetSlotWidth(TSlotHandle handle, int width)
- {
- THandleToWidthMap::iterator it = m_HandleToWidth.find(handle);
- if(it != m_HandleToWidth.end()) {
- it->second = width;
- }
-
- }
- int CStatusBar1::GetSlotWidth(TSlotHandle handle) const
- {
- THandleToWidthMap::const_iterator it = m_HandleToWidth.find(handle);
- return (it != m_HandleToWidth.end()) ? it->second : 0;
- }
- void CStatusBar1::ReLayout()
- {
- x_Layout();
- redraw();
- }
- void CStatusBar1::draw()
- {
- fl_push_clip(x(), y(), w(), h());
- Fl_Group::draw();
-
- fl_pop_clip();
- }
- void CStatusBar1::resize(int x, int y, int w, int h)
- {
- Fl_Widget::resize(x, y, w, h);
- x_Layout();
- }
- void CStatusBar1::x_Layout()
- {
- ISBSlot* resizable_slot = NULL;
- int slots_w = 0; // width of all slots except resizable one
- ITERATE(THandleToSlotMap, it, m_HandleToSlot) {
- int styles = it->second->GetStyles();
- if(resizable_slot == NULL && (styles & ISBSlot::fResizable)) {
- resizable_slot = it->second; // found resizable slot
- } else {
- int width = m_HandleToWidth[it->first];
- slots_w += width; // accumulate width
- }
- slots_w += kSlotSpacing;
- }
- slots_w -= kSlotSpacing; // N slots have N-1 spaces between them
- int av_w = w() - 2 * kBorder; // total available for slots
- int resizable_w = max(0, av_w - slots_w); // width of resizable slot
- int pos_x = x() + kBorder;
- int pos_y = y() + kBorder;
- int height = h() - 2 * kBorder;
- ITERATE(THandleToSlotMap, it, m_HandleToSlot) {
- Fl_Widget* slot = dynamic_cast<Fl_Widget*>(it->second);
-
- int width = (it->second == resizable_slot) ? resizable_w : m_HandleToWidth[it->first];
- if(av_w > 0) {
- width = min(width, av_w);
- } else {
- width = 0;
- }
- slot->resize(pos_x, pos_y, width, height);
-
- pos_x += width + kSlotSpacing;
- }
- }
- static const int kSlotOffsetX = 4;
- CSBSlot::CSBSlot()
- : Fl_Group(0, 0, 0, 0)
- {
- labelfont(FL_HELVETICA);
- labelsize(12);
-
- color(kStatusBarColor);
- SetStyles(0);
- }
- void CSBSlot::draw()
- {
- Fl_Group::draw();
- x_Draw();
- }
- void CSBSlot::SetStyles(int styles)
- {
- m_Styles = styles;
- }
- int CSBSlot::GetStyles() const
- {
- return m_Styles;
- }
- void CSBSlot::SetText(const string& text)
- {
- m_Text = text;
- redraw();
- }
- string CSBSlot::GetText() const
- {
- return m_Text;
- }
- void CSBSlot::SetImage(CFLTKImageHandle image)
- {
- m_Image = image;
- redraw();
- }
- CFLTKImageHandle CSBSlot::GetImage()
- {
- return m_Image;
- }
- void CSBSlot::x_Draw()
- {
- fl_clip(x(), y(), w(), h());
-
- x_DrawBackground();
- x_DrawContent();
-
- fl_pop_clip();
- }
- void CSBSlot::x_DrawBackground()
- {
- if(m_Styles & fDownBox) {
- fl_draw_box(FL_THIN_DOWN_BOX, x(), y(), w(), h(), kStatusBarColor);
- } else if(m_Styles & fUpBox) {
- fl_draw_box(FL_THIN_UP_BOX, x(), y(), w(), h(), kStatusBarColor);
- } else {
- fl_color(kStatusBarColor);
- fl_rectf(x(), y(), w(), h());
- fl_color(fl_darker(kStatusBarColor));
- fl_rect(x(), y(), w(), h());
- }
- }
- void CSBSlot::x_DrawContent()
- {
- int off = 1;
- fl_clip(x() + off, y() + off, w() - 2 * off, h() - 2 * off);
- int pos_x = x() + kSlotOffsetX;
- int pos_y = y() + kBorder; //###
- if(m_Image) {
- CPNGImageExt* ext_image = dynamic_cast<CPNGImageExt*>(&(*m_Image));
- if(ext_image) {
- ext_image->DrawTransparent(color(), pos_x, pos_y, ext_image->w(), ext_image->h());
- } else {
- m_Image->draw(pos_x, pos_y, ext_image->w(), ext_image->h());
- }
- pos_x += ext_image->w() + kSlotOffsetX;
- }
- // draw text
- fl_color(FL_BLACK);
- fl_font(labelfont(), labelsize());
-
- int text_space = (x() + w() - kSlotOffsetX) - pos_x;
- int text_h = fl_height() - fl_descent();
- int offset = 0;
- if(m_Styles & fCenterText) {
- int width = fl_width(m_Text.c_str());
- offset = (width < text_space) ? (text_space - width) / 2 : 0;
- }
- int text_y = y() + (h() + text_h) / 2 - 1; //###
- fl_draw_text(m_Text, pos_x + offset, text_y, text_space);
-
- fl_pop_clip();
- }
- ////////////////////////////////////////////////////////////////////////////////
- /// CStatusBar
- CStatusBar::CStatusBar(int x, int y, int w, int h, const char* label)
- : Fl_Group(x, y, w, h, label)
- {
- align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
- }
- void CStatusBar::label(const char* label)
- {
- SetMessage(label);
- }
- const char* CStatusBar::label(void) const
- {
- return Fl_Group::label();
- }
- void CStatusBar::SetMessage(const string& msg)
- {
- CFastMutexGuard LOCK(m_Mutex);
- if ( m_MsgStack.size() == 0) {
- m_MsgStack.push_back(msg);
- } else {
- m_MsgStack.back() = msg;
- }
- Fl_Group::label(m_MsgStack.back().c_str());
- redraw();
- Fl::check();
- }
- void CStatusBar::Clear(void)
- {
- CFastMutexGuard LOCK(m_Mutex);
- m_MsgStack.clear();
- Fl_Group::label("");
- Fl::check();
- }
- void CStatusBar::PushMessage(const string& msg)
- {
- CFastMutexGuard LOCK(m_Mutex);
- m_MsgStack.push_back(msg);
- Fl_Group::label(m_MsgStack.back().c_str());
- Fl::check();
- }
- string CStatusBar::PopMessage()
- {
- CFastMutexGuard LOCK(m_Mutex);
- if (m_MsgStack.size() == 0) {
- return string();
- }
- string ret = m_MsgStack.back();
- m_MsgStack.pop_back();
- if (m_MsgStack.size() == 0) {
- Fl_Group::label(NULL);
- } else {
- Fl_Group::label(m_MsgStack.back().c_str());
- }
- Fl::check();
- return ret;
- }
- CStatusBarGuard::CStatusBarGuard(CStatusBar& bar, const string& msg)
- : m_Bar(bar)
- {
- m_Bar.PushMessage(msg);
- }
- CStatusBarGuard::~CStatusBarGuard()
- {
- m_Bar.PopMessage();
- }
- END_NCBI_SCOPE
- /*
- * ===========================================================================
- * $Log: status_bar.cpp,v $
- * Revision 1000.2 2004/06/01 21:09:12 gouriano
- * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.6
- *
- * Revision 1.6 2004/06/01 18:11:25 dicuccio
- * Force redraw on changing message
- *
- * Revision 1.5 2004/05/21 22:27:53 gorelenk
- * Added PCH ncbi_pch.hpp
- *
- * Revision 1.4 2004/05/13 17:22:39 yazhuk
- * Implemented ISBSlot, CSBSlot and CStatusBar1 classes
- *
- * Revision 1.3 2004/04/14 20:57:22 johnson
- * added Clear() to IReporter interface
- *
- * Revision 1.2 2004/04/07 13:08:05 dicuccio
- * Set default alignment. Added calls to Fl::check() to keep status bar alive
- *
- * Revision 1.1 2003/12/04 18:15:28 dicuccio
- * Added status bar classes
- *
- * ===========================================================================
- */