status_bar.cpp

来自「ncbi源码」· C++ 代码 · 共 483 行

CPP
483
字号
/* * =========================================================================== * 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/////////////////////////////////////////////////////////////////////////////////// CStatusBar1static const int    kSlotSpacing = 6; // horz distance between adjasent slotsstatic 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 slotCStatusBar1::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();}/////////////////////////////////////////////////////////////////////////////////// CStatusBarCStatusBar::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 * * =========================================================================== */

⌨️ 快捷键说明

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