menu_item.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:14k
- /*
- * ===========================================================================
- * 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
- ////////////////////////////////////////////////////////////////////////////////
- // CMenuItem
- CMenuItem::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 subitems
- CMenuItem::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
- *
- * ===========================================================================
- */