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 + -
显示快捷键?