menu_item.cpp

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

CPP
507
字号
/* * =========================================================================== * PRODUCTION $Log: menu_item.cpp,v $ * PRODUCTION Revision 1000.0  2004/06/01 21:29:16  gouriano * PRODUCTION PRODUCTION: IMPORTED [GCC34_MSVC7] Dev-tree R1.6 * PRODUCTION * =========================================================================== *//*  $Id: menu_item.cpp,v 1000.0 2004/06/01 21:29:16 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 *   */#include <ncbi_pch.hpp>#include <corelib/ncbistd.hpp>#include <gui/widgets/fl/menu_item.hpp>#include <FL/fl_draw.H>BEGIN_NCBI_SCOPE////////////////////////////////////////////////////////////////////////////////// CMenuItemCMenuItem::CMenuItem(): m_ItemNode(this){    Init(eSeparator);}CMenuItem::CMenuItem(const string& label, const string& image_alias): m_ItemNode(this){    Init(eSubmenu, label, eCmdNone, image_alias);}CMenuItem::CMenuItem(const string& label, TCmdID cmd, const string& image_alias, int state): m_ItemNode(this){    Init(eItem, label, cmd, image_alias, state);}CMenuItem::CMenuItem(EType type, const string& label, TCmdID cmd, const string& image_alias, int state): m_ItemNode(this){    Init(type, label, cmd, image_alias, state);}///copy contsructor - copes just attributes, not the subitemsCMenuItem::CMenuItem(const CMenuItem& item): m_ItemNode(this){    Init(item.m_Type, item.m_Label, item.m_CommandID, item.m_ImageAlias, item.m_State);}CMenuItem::~CMenuItem(){    for( TItemNode::TNodeList_I it = m_ItemNode.SubNodeBegin();        it != m_ItemNode.SubNodeEnd();  )   {        TItemNode::TNodeList_I it2 = it++;        TItemNode* node = m_ItemNode.DetachNode(*it2);            delete node->GetValue();    }}void    CMenuItem::Init(EType type, const string& label, TCmdID cmd,                         const string& image_alias, int state){    m_Type = type;    m_Label = label;    m_CommandID = cmd;    m_ImageAlias = image_alias;    m_State = state;}void    CMenuItem::InitPopup(const string& label, const string& image_alias){    Init(eSubmenu, label, eCmdNone, image_alias);}void    CMenuItem::InitItem(const string& label, TCmdID cmd, const string& image_alias, int state){    Init(eItem, label, cmd, image_alias, state);}void    CMenuItem::InitSeparator(){    Init(eSeparator);}bool    CMenuItem::Equal(const CMenuItem& item) const{    return m_Type == item.m_Type  &&  m_Label == item.m_Label              &&  m_CommandID == item.m_CommandID  && m_ImageAlias == item.m_ImageAlias;}CMenuItem*  CMenuItem::Clone() const{    CMenuItem* p_clone = new CMenuItem(*this);    for(TChildItem_CI    it = SubItemsBegin();  it != SubItemsEnd(); it++ )  {       CMenuItem* p_subitem = (*it)->GetValue();       p_clone->AddSubItem(p_subitem->Clone());    }    return p_clone;}CMenuItem::EType   CMenuItem::GetType()   const{    return m_Type;}void    CMenuItem::SetType(EType type){    m_Type = type;}bool    CMenuItem::IsItem()    const{    return m_Type == eItem;}bool    CMenuItem::IsSubmenu() const{    return m_Type == eSubmenu;}bool    CMenuItem::IsSeparator() const{    return m_Type == eSeparator;}const string&   CMenuItem::GetLabel() const{    return m_Label;}void    CMenuItem::SetLabel(const string& label){    m_Label = label;} const TCmdID&  CMenuItem::GetCommand()    const{    return m_CommandID;}void    CMenuItem::SetCommand(TCmdID cmd){    m_CommandID = cmd;}bool            CMenuItem::HasImage()  const{    return m_ImageAlias.size() > 0;}const string&   CMenuItem::GetImageAlias() const{    return m_ImageAlias;}void    CMenuItem::SetImageAlias(const string& image_alias){    m_ImageAlias = image_alias;}int  CMenuItem::GetState()  const{    return m_State;}void    CMenuItem::SetState(int state)  {    m_State = state;}bool    CMenuItem::IsEnabled() const{    return (m_State & eDisabled) == 0;}void    CMenuItem::Enable(bool b_en){    x_SetState(eDisabled, ! b_en);}bool    CMenuItem::IsCheckType()   const{    return (m_State & eCheckItem) != 0;}bool    CMenuItem::IsChecked() const{    return (m_State & eCheckItem)  &&  m_State & eSet;}void    CMenuItem::SetCheck(bool b_set){    x_SetState(eCheckItem | eRadioItem, eCheckItem);    x_SetState(eSet, b_set);}bool    CMenuItem::IsRadioType()   const{    return (m_State & eRadioItem) != 0;}bool    CMenuItem::IsRadioSelected() const{   return m_State & eRadioItem  &&  m_State & eSet;}void    CMenuItem::SelectRadio(bool b_set){    x_SetState(eCheckItem | eRadioItem, eRadioItem);    x_SetState(eSet, b_set);}bool    CMenuItem::IsValid() const{    bool b_check = IsCheckType();    bool b_radio = IsRadioType();        if(b_check  &&  b_radio)    {        return false; // cannot be both at the same time    } else if((b_check  ||  b_radio)  &&  ! IsItem())   {        return false;    } /*else if((m_State & eHideIfEmpty)  &&  ! IsSubmenu())  {        return false;    }*/ else if(! IsSeparator()  &&  m_Label.size()==0)   {        return false; // label must not be empty    }    return true;}/// Menu Item trees are merged based on item's labels. Labels specify unique path/// to an item (similarly to paths in file systems).void    CMenuItem::Merge(const CMenuItem& item){    // this and "item" must be submenus with the same label    if(GetLabel() == item.GetLabel())   {          if(IsSubmenu()  &&  item.IsSubmenu())   {            // for every subitem in the given menu            for( TChildItem_CI it = item.SubItemsBegin(); it != item.SubItemsEnd(); it++ )   {                const CMenuItem* sub_item = (*it)->GetValue();                TChildItem_I it_target = FindSubItem(sub_item->GetLabel());                            if(it_target != SubItemsEnd())   { // found potential target for merge                    CMenuItem* target_sub_item = (*it_target)->GetValue();                                    if(target_sub_item->IsSubmenu())    { // submenu - merge recursively                        target_sub_item->Merge(*sub_item);                     } else if(target_sub_item->IsItem()) { // command item                        string s_error;                        if(! sub_item->IsItem()) {                            s_error = ", because it is not a command item.";                                                         } else if(target_sub_item->GetCommand() != sub_item->GetCommand())    {                            s_error = ", because they have different commands.";                        }                         if(s_error.size())  {                            ERR_POST("CMenuItem::Merge() cannot merge item "                                      << sub_item->GetLabel()                                      << " into " << target_sub_item->GetLabel()                                      << s_error);                        }                        // else, do nothing, because sub_item is identical to target_sub_item                    }                } else { // sub_item is not found - add                    if(sub_item->GetType() != eSeparator)    {                        AddSubItem(sub_item->Clone());                    }                }            } //for        } else {            ERR_POST("CMenuItem::Merge() cannot merge item " << item.GetLabel()                      << " into " << GetLabel() << ", because they are not submenus.");        }    } else {        ERR_POST("CMenuItem::Merge() cannot merge item " << item.GetLabel()                 << " into " << GetLabel() << ", because they have different labels.");         }}CMenuItem*  CMenuItem::GetParent(){    TItemNode* parent_node = m_ItemNode.GetParent();    return parent_node ? parent_node->GetValue() : NULL;}const   CMenuItem*  CMenuItem::GetParent() const{    const TItemNode* parent_node = m_ItemNode.GetParent();    return parent_node ? parent_node->GetValue() : NULL;}CMenuItem*    CMenuItem::AddSubItem(CMenuItem* item){    _ASSERT(IsSubmenu());    if(item)    {        TItemNode* node = & item->m_ItemNode;        m_ItemNode.AddNode(node);    }     return item;}CMenuItem*  CMenuItem::AddSubItem(){    CMenuItem* item = new CMenuItem();    return AddSubItem(item);}CMenuItem*  CMenuItem::AddSubMenu(const string& label, const string& image_alias){    CMenuItem* item = new CMenuItem(label, image_alias);    return AddSubItem(item);}CMenuItem*  CMenuItem::AddSubItem(const string& label, TCmdID cmd,  const string& image_alias, int state){    CMenuItem* item = new CMenuItem(label, cmd, image_alias, state);    return AddSubItem(item);}bool    CMenuItem::IsSubmenuEmpty(){    return m_ItemNode.SubNodeBegin() == m_ItemNode.SubNodeEnd();}CMenuItem::TChildItem_I    CMenuItem::SubItemsBegin(){    return m_ItemNode.SubNodeBegin();}CMenuItem::TChildItem_I    CMenuItem::SubItemsEnd(){    return m_ItemNode.SubNodeEnd();}CMenuItem::TChildItem_CI    CMenuItem::SubItemsBegin()  const{    return m_ItemNode.SubNodeBegin();}CMenuItem::TChildItem_CI    CMenuItem::SubItemsEnd() const{    return m_ItemNode.SubNodeEnd();}CMenuItem*  CMenuItem::FindEqualSubItem(const CMenuItem& item){    for(TChildItem_I it = SubItemsBegin(); it != SubItemsEnd(); ++it)  {        CMenuItem* curr = (*it)->GetValue();        if(curr->Equal(item))            return curr;    }    return NULL;}const CMenuItem*  CMenuItem::FindEqualSubItem(const CMenuItem& item) const{    for(TChildItem_CI it = SubItemsBegin(); it != SubItemsEnd(); ++it)  {        const CMenuItem* curr = (*it)->GetValue();        if(curr->Equal(item))            return curr;    }    return NULL;}CMenuItem::TChildItem_I    CMenuItem::FindSubItem(const CMenuItem& item){    for(TChildItem_I it = SubItemsBegin(); it != SubItemsEnd(); ++it)  {        if((*it)->GetValue() == &item)            return it;    }    return SubItemsEnd();}CMenuItem::TChildItem_CI   CMenuItem::FindSubItem(const CMenuItem& item) const{    for(TChildItem_CI it = SubItemsBegin(); it != SubItemsEnd(); ++it)  {        if((*it)->GetValue() == &item)            return it;    }    return SubItemsEnd();}CMenuItem::TChildItem_I    CMenuItem::FindSubItem(const string& label){    for(TChildItem_I it = SubItemsBegin(); it != SubItemsEnd(); ++it)  {        if((*it)->GetValue()->GetLabel() == label)            return it;    }    return SubItemsEnd();}CMenuItem::TChildItem_CI   CMenuItem::FindSubItem(const string& label) const{    for(TChildItem_CI it = SubItemsBegin(); it != SubItemsEnd(); ++it)  {        if((*it)->GetValue()->GetLabel() == label)            return it;    }    return SubItemsEnd();}///////////////////////////////////////////////////////////////////////////////////CMenuItem*  CreateMenuItems(const SMenuItemRec* items){    if(items)   {        CMenuItem* root = NULL;        vector<CMenuItem*>  path;                const SMenuItemRec* p_rec = items;                while(p_rec)    {            CMenuItem* item = NULL;            if(p_rec->IsSubMenu())  {                // create Submenu and add to path                item = new CMenuItem(p_rec->m_Label, p_rec->m_ImageAlias);                if(path.size()) {                    path.back()->AddSubItem(item);                }   else {                    root = item;                }                path.push_back(item);            } else if(p_rec->IsSubMenuEnd())  {                //end current submenu and eject it from path                path.pop_back();                if(path.empty())                    return root;            } else if(p_rec->m_Type == CMenuItem::eItem)    {                // add command item                item = new CMenuItem(p_rec->m_Label, p_rec->m_CommandID,                                      p_rec->m_ImageAlias, p_rec->m_State);                path.back()->AddSubItem(item);            } else if(p_rec->m_Type == CMenuItem::eSeparator)    {                // add separator                item = new CMenuItem();                path.back()->AddSubItem(item);            }            p_rec++;        }            }    return  NULL;        }END_NCBI_SCOPE/* * =========================================================================== * $Log: menu_item.cpp,v $ * Revision 1000.0  2004/06/01 21:29:16  gouriano * PRODUCTION: IMPORTED [GCC34_MSVC7] Dev-tree R1.6 * * Revision 1.6  2004/05/21 22:27:53  gorelenk * Added PCH ncbi_pch.hpp * * Revision 1.5  2004/05/13 17:30:37  yazhuk * Removed eHideIfEmpty support * * Revision 1.4  2004/05/07 14:18:43  yazhuk * Added Merge(), FindSubItem(string) * * Revision 1.3  2004/05/03 19:44:09  yazhuk * Refactoring; fixed IsChecked() * * Revision 1.2  2004/04/28 19:28:29  tereshko * Fixed test for a checked state of radio button * * Revision 1.1  2004/04/22 16:56:25  yazhuk * Moved from menu.cpp, added support for images * * =========================================================================== */

⌨️ 快捷键说明

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