⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tooltip.cpp

📁 ncbi源码
💻 CPP
字号:
/* * =========================================================================== * PRODUCTION $Log: tooltip.cpp,v $ * PRODUCTION Revision 1000.1  2004/06/01 21:09:23  gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.10 * PRODUCTION * =========================================================================== *//*  $Id: tooltip.cpp,v 1000.1 2004/06/01 21:09:23 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:  Andrey Yazhuk * * File Description: */#include <ncbi_pch.hpp>#include <gui/widgets/fl/tooltip.hpp>#include <FL/fl_draw.H>#include <FL/forms.H>BEGIN_NCBI_SCOPE/////////////////////////////////////////////////////////////////////////////////// CTooltipCTooltip::CTooltip():   m_bActiveMode(false),    m_Mode(eHideOnMove),    m_Delay(0.8f),    m_bEnabled(true),    m_Widget(NULL),     m_TooltipWidget(NULL),    m_bRecentTooltip(0),        m_bRecursion(0){    m_Color = fl_color_cube(FL_NUM_RED - 1, FL_NUM_GREEN - 1, FL_NUM_BLUE - 2);    m_TextColor = FL_BLACK;    m_Font = FL_HELVETICA;    m_FontSize = FL_SMALL_SIZE;}CTooltip::~CTooltip(){    Deactivate(true);    delete m_TooltipWidget;}void    CTooltip::SetMode(EMode mode){    m_Mode = mode;}CTooltip::EMode   CTooltip::GetMode() const{    return m_Mode;}float CTooltip::GetDelay()  const   {     return m_Delay; }void  CTooltip::SetDelay(float delay) {     m_Delay = delay; }int   CTooltip::IsEnabled()   const   {     return m_bEnabled; }void  CTooltip::Enable(bool b_en) {     m_bEnabled = b_en;}void  CTooltip::Disable() {     m_bEnabled = false; }Fl_Widget* CTooltip::current() {     return m_Widget;    }int   CTooltip::GetFont()   const   {     return m_Font; }void  CTooltip::SetFont(int font) {     m_Font = font;     } int   CTooltip::GetFontSize()   const   {     return m_FontSize; }  void  CTooltip::SetFontSize(int size) {     m_FontSize = size; }void  CTooltip::SetColor(Fl_Color color)    {     m_Color = color; }Fl_Color CTooltip::GetColor()  const    {     return m_Color; }void CTooltip::SetTextColor(Fl_Color color) {     m_TextColor = color; }Fl_Color  CTooltip::GetTextColor()  const {     return m_TextColor; }const string&   CTooltip::GetText()   const{    return m_Text;}void    CTooltip::Activate(Fl_Widget* client, const string& text, int x, int y, int w, int h){    _ASSERT(client);    _ASSERT(! m_bActiveMode);        Fl::belowmouse(client);    x_Activate(client, x, y, w, h, text.c_str());}// hides tooltipvoid    CTooltip::Deactivate(bool b_reset){    Fl::remove_timeout(ShowTooltipTimeout);    if(m_Widget  ||  x_IsTooltipVisible()) {        /// hide tooltip and remove timer callbacks        if(x_IsTooltipVisible())     {            m_TooltipWidget->hide();        }            if(m_bRecentTooltip) { //needs to be reset            if(b_reset) {                m_bRecentTooltip = 0;  // clear immediately            } else {                Fl::add_timeout(.2f, ClearRecentTimeout, this); // clear after 0.2 sec            }        }        m_Widget = NULL;    }}bool    CTooltip::x_IsTooltipVisible(){    return m_TooltipWidget  &&  m_TooltipWidget->visible();}void  CTooltip::x_Activate(Fl_Widget* client, int x, int y, int w,int h, const string& text){    _ASSERT(! m_bActiveMode);    if(IsEnabled()  &&  ! m_bRecursion) {        bool b_changed = client != m_Widget  ||  text != m_Text                         ||  x != m_X  ||  y != m_Y                         ||  w != m_W  ||  h != m_H;        bool b_pos_changed = (m_MouseX != Fl::event_x()  || m_MouseY != Fl::event_y());        bool b_active = m_TooltipWidget  && m_TooltipWidget->visible();        ETooltipCmd cmd = eDoNothing;        if(m_Mode == eHideOnMove)  {            if(!b_active  || b_changed  ||  b_pos_changed)  {                cmd = eShowDelayed;            }        } else {            if(b_active)    {                if(b_changed  ||  (m_Mode == eTrackOnMove  &&  b_pos_changed))   {                    cmd = eUpdateAndMove;                }            } else {                cmd = m_bRecentTooltip ? eUpdateAndMove : eShowDelayed;            }        }                    if(cmd != eDoNothing)   {            Fl::remove_timeout(ShowTooltipTimeout);            Fl::remove_timeout(ClearRecentTimeout);                    m_Widget = client;                                 m_X = x;             m_Y = y;             m_W = w;             m_H = h;             m_MouseX = Fl::event_x();            m_MouseY = Fl::event_y();            m_Text = text;        }        switch(cmd)  {        case eUpdateAndMove: {            x_UpdateTooltipWidget(cmd); // show immediately        };  break;        case eShowDelayed: {            if(m_TooltipWidget  &&  m_TooltipWidget->visible())     {                m_TooltipWidget->hide();                        }            Fl::add_timeout(m_Delay, ShowTooltipTimeout, this); // show after delay        }; break;        default: break;        }    }}// callback for "recent" timer - after specified delay cleans m_bRecentTooltip void CTooltip::ClearRecentTimeout(void* ptr) {    CTooltip* pTooltip = reinterpret_cast<CTooltip*>(ptr);    _ASSERT(pTooltip);    pTooltip->m_bRecentTooltip = 0;}// callback for "delay" timervoid CTooltip::ShowTooltipTimeout(void* ptr) {    CTooltip* pTooltip = reinterpret_cast<CTooltip*>(ptr);    _ASSERT(pTooltip);    if(pTooltip->m_bActiveMode)   { // ask the client and may be show tooltip        pTooltip->x_AskClientAndUpdate();    } else { // we know that tootlip must be shown        pTooltip->x_UpdateTooltipWidget(eShowDelayed);    }}bool    CTooltip::EnableActiveMode(ITooltipClient* client){    if(client)  {        Deactivate(true);        m_IClient = client;        m_bActiveMode = true;        return true;    } else return false;}void    CTooltip::DisableActiveMode(){    if(m_bActiveMode)   {        Deactivate(true);                m_bActiveMode  = false;    }}const static int    kMouseJump = 4; // max mouse travel between two eventsint     CTooltip::Handle(int event){    switch(event)   {    case FL_MOVE:   {        if(m_bActiveMode)   {                        Fl_Widget* wid = dynamic_cast<Fl_Widget*>(m_IClient);            bool b_client_active = (Fl::belowmouse() == wid);                        int d_x = m_MouseX - Fl::event_x();            int d_y = m_MouseY - Fl::event_y();            bool jump = (d_x * d_x + d_y * d_y) > (kMouseJump * kMouseJump);                        m_MouseX = Fl::event_x();            m_MouseY = Fl::event_y();                        if(m_Mode == eHideOnMove  ||  jump)  { // hide and question client after delay                Deactivate(true);                if(b_client_active) {                    Fl::remove_timeout(ShowTooltipTimeout);                            Fl::add_timeout(m_Delay, ShowTooltipTimeout, this);                }            } else if(b_client_active)  {                if(x_IsTooltipVisible()  ||  m_bRecentTooltip)    {                    x_AskClientAndUpdate();  // update immediately                } else { // question client after delay                    Fl::add_timeout(m_Delay, ShowTooltipTimeout, this);                }            }        }    }; break;    case FL_PUSH:   case FL_DRAG:   case FL_RELEASE:    case FL_UNFOCUS:    case FL_LEAVE:  {        Deactivate(true);     }; break;        }    return 0;}// shows tooltip void CTooltip::x_UpdateTooltipWidget(ETooltipCmd cmd){    if(! m_bRecursion)  {        m_bRecursion = 1;        if (! m_TooltipWidget) {            m_TooltipWidget = new CTooltipWidget(this);        }                    if(cmd == eShowDelayed  ||  cmd == eUpdateAndMove)  {             // this cast bypasses the normal Fl_Window label() code:            ((Fl_Widget*)m_TooltipWidget)->label(m_Text.c_str());                     m_TooltipWidget->SetOrigin(Fl::event_x_root(), Fl::event_y_root());                    }        if(cmd != eDoNothing)   {            m_TooltipWidget->layout();        }        switch(cmd) {        case eUpdateAndMove:    {            if(m_TooltipWidget->visible())  {                m_TooltipWidget->damage(1);             } else {                m_TooltipWidget->show();            };        }; break;                 case eShowDelayed:  {            m_TooltipWidget->show();        }; break;        default: break;        }                Fl::remove_timeout(ClearRecentTimeout); // remove "recent" timer        m_bRecentTooltip = 1;        m_bRecursion = 0;    }}/// This functions queries the Client and shows tooltip if necessary. Funtion never/// delays showing (if function is called - delay have already elapsed)void    CTooltip::x_AskClientAndUpdate(){    if(m_IClient)   {        bool b_ok = m_IClient->TC_NeedTooltip(m_MouseX, m_MouseY);        if(b_ok)   { // show/update tooltip            int x = m_MouseX, y = m_MouseY, w = 1, h = 1;            string text = m_IClient->TC_GetTooltip(x, y, w, h);            bool b_changed = text != m_Text                         ||  x != m_X  ||  y != m_Y ||  w != m_W  ||  h != m_H;                                  ETooltipCmd cmd = eDoNothing;            if(! x_IsTooltipVisible())  {                cmd = eShowDelayed;            } else if(b_changed  ||  m_Mode == eTrackOnMove)    {                cmd = eUpdateAndMove;            }            if(cmd != eDoNothing)   {                m_Text = text;                m_X = x;                 m_Y = y;                 m_W = w;                 m_H = h;                x_UpdateTooltipWidget(cmd);            }        } else Deactivate(false); // client doesn't want any tootlips    }}/////////////////////////////////////////////////////////////////////////////////// CTooltipWidgetconst static int kSpaceX = 4;const static int kSpaceY = 2;const static int kOffsetY  = 24;CTooltipWidget::CTooltipWidget(CTooltip* tooltip):   Fl_Menu_Window(0, 0),    m_Tooltip(tooltip){    set_override();    end();    clear_flag(VISIBLE_FOCUS);}void    CTooltipWidget::SetOrigin(int x, int y){    m_OrigX = x;    m_OrigY = y;}#define MAX_WIDTH 400    void    CTooltipWidget::layout() {    fl_font(m_Tooltip->GetFont(), m_Tooltip->GetFontSize());    int width = MAX_WIDTH;    int height = 0;    fl_measure(m_Tooltip->GetText().c_str(), width, height,                 FL_ALIGN_LEFT | FL_ALIGN_WRAP | FL_ALIGN_INSIDE);    width += 2 * kSpaceX;     height += 2 * kSpaceY;    // horizontal positioning    int ox = m_OrigX;        if(ox + width > Fl::w()) {        ox = Fl::w() - width;    }    if(ox < 0)         ox = 0;    // vertical positioning    int oy = m_OrigY + kOffsetY;    if(oy + height > Fl::h())   {        oy = Fl::h() - height;    }    if(oy < 0 )     {        oy = 0;    }    if (oy < 0) {        oy = 0;    }    resize(ox, oy, width, height);}void CTooltipWidget::draw() {  draw_box(FL_BORDER_BOX, 0, 0, w(), h(), m_Tooltip->GetColor());  fl_color(m_Tooltip->GetTextColor());  fl_font(m_Tooltip->GetFont(), m_Tooltip->GetFontSize());  fl_draw(m_Tooltip->GetText().c_str(), kSpaceX, kSpaceY,           w() - 2* kSpaceX, h() - 2 * kSpaceY,           Fl_Align(FL_ALIGN_LEFT | FL_ALIGN_WRAP | FL_ALIGN_INSIDE));}void    CTooltipWidget::show() {    Fl_Menu_Window::show();}int     CTooltipWidget::handle(int event){    switch(event)   {    case FL_FOCUS: return 0;    default: return Fl_Menu_Window::handle(event);    }}END_NCBI_SCOPE/* * =========================================================================== * $Log: tooltip.cpp,v $ * Revision 1000.1  2004/06/01 21:09:23  gouriano * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.10 * * Revision 1.10  2004/05/21 22:27:53  gorelenk * Added PCH ncbi_pch.hpp * * Revision 1.9  2004/05/13 17:20:48  yazhuk * clean-up * * Revision 1.8  2004/05/03 19:49:28  yazhuk * Hide tooltip if mouse moves too fast * * Revision 1.7  2004/04/22 16:59:10  yazhuk * Clean-up * * Revision 1.6  2004/02/11 15:26:24  yazhuk * Event handling fix * * Revision 1.5  2004/02/04 22:26:31  yazhuk * Fixed event handling in active mode * * Revision 1.4  2004/01/27 18:48:23  dicuccio * Added call to DisableActiveMode() in destructor.  Make Deactivate() always * remove timeouts * * Revision 1.3  2004/01/21 14:23:20  rsmith * Remove debug output statement. * * Revision 1.2  2004/01/08 19:45:16  yazhuk * Implemented "active" tooltips, refactored code, added comments * * Revision 1.1  2003/12/29 21:12:22  yazhuk * Initial revision * * =========================================================================== */

⌨️ 快捷键说明

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