-//---------------------------------------------------------------------------\r
-// $RCSfile: wxTreeMultiCtrl.cpp,v $\r
-// $Source: /cvs/creatis/bbtk/kernel/src/ThirdParty/wx/treemultictrl/wxTreeMultiCtrl.cpp,v $\r
-// $Revision: 1.1 $\r
-// $Date: 2008/03/28 13:42:19 $\r
-//---------------------------------------------------------------------------\r
-// Author: Jorgen Bodde\r
-// Copyright: (c) Jorgen Bodde\r
-// License: wxWidgets License\r
-//---------------------------------------------------------------------------\r
-\r
-#ifdef __GNUG__\r
- #pragma implementation "wxTreeMultiCtrl.h"\r
-#endif\r
-\r
-// For compilers that support precompilation, includes "wx/wx.h".\r
-#include "wx/wxprec.h"\r
-#include "wx/treebase.h"\r
-\r
-#ifdef __BORLANDC__\r
- #pragma hdrstop\r
-#endif\r
-\r
-#include "wx/arrimpl.cpp"\r
-\r
-#include "wx/treemultictrl/wxTreeMultiCtrl.h"\r
-#include "wx/treemultictrl/wxTreeMultiEvent.h"\r
-#include "tmcimages.h"\r
-\r
-\r
-\r
-//----------------------------------------------------------------------------\r
-// wxTreeMultiItem\r
-//----------------------------------------------------------------------------\r
-\r
-WX_DEFINE_OBJARRAY(wxArrayTreeMultiItem);\r
-\r
-//----------------------------------------------------------------------------\r
-// wxTreeMultiCtrl\r
-//----------------------------------------------------------------------------\r
-\r
-IMPLEMENT_DYNAMIC_CLASS(wxTreeMultiCtrl, wxScrolledWindow)\r
-\r
-// WDR: event table for wxTreeMultiCtrl\r
-BEGIN_EVENT_TABLE(wxTreeMultiCtrl, wxScrolledWindow)\r
- EVT_LEFT_DOWN (wxTreeMultiCtrl::OnMouseClick)\r
- EVT_LEFT_DCLICK(wxTreeMultiCtrl::OnMouseClick)\r
- EVT_RIGHT_DOWN (wxTreeMultiCtrl::OnRightMouseClick)\r
- EVT_PAINT(wxTreeMultiCtrl::OnPaint)\r
- EVT_SIZE(wxTreeMultiCtrl::OnSize)\r
-// EVT_KEY_UP(wxTreeMultiCtrl::OnKey)\r
-END_EVENT_TABLE()\r
-\r
-bool wxTreeMultiCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos,\r
- const wxSize& size, long style, const wxValidator & WXUNUSED(validator),\r
- const wxString& name )\r
-{\r
- wxScrolledWindow::Create( parent, id, pos, size, style | wxTAB_TRAVERSAL, name);\r
-\r
- _create_called = true;\r
-\r
- // do the init\r
- Init();\r
-\r
- return TRUE;\r
-}\r
-\r
-void wxTreeMultiCtrl::Init()\r
-{\r
- _root.Clear();\r
-\r
- _expandBmp = 0;\r
- _collBmp = 0;\r
-\r
-#if(CHECKBOXVIEW)\r
- _checkBmp = 0;\r
- _uncheckBmp = 0;\r
- _tristateBmp = 0;\r
-\r
- _checkHeight = 11;\r
- _checkWidth = 11;\r
-\r
- _checkboxView = false;\r
-#endif\r
-\r
- _gutterWidth = WXTMC_GUTTER_DEFAULT;\r
- _iconWidth = 11;\r
- _iconHeight = 11;\r
- _maxHeight = 1;;\r
- _iconDeltaY = 2;\r
- _spacingY = WXTMC_YSPACING_DEFAULT;\r
- _captionHeight = 13;\r
-\r
- // create two bitmap nodes for drawing\r
-\r
- _expandBmp = new wxBitmap(expand_xpm);\r
- _collBmp = new wxBitmap(collapse_xpm);\r
-\r
- // calculate average font height for bitmap centering\r
-\r
- _iconWidth = _expandBmp->GetWidth();\r
- _iconHeight = _expandBmp->GetHeight();\r
-\r
-#if(CHECKBOXVIEW)\r
- // create bitmaps for checkboxes\r
- _checkBmp = new wxBitmap(checked_icon);\r
- _uncheckBmp = new wxBitmap(unchecked_icon);\r
- _tristateBmp = new wxBitmap(tristate_icon);\r
-\r
- // adjust the height if the checkboxes are higher\r
- // so that everything is alligned properly\r
- _checkHeight = _checkBmp->GetHeight();\r
- _checkWidth = _checkBmp->GetWidth();\r
-#endif\r
-\r
- // remember the highest of the two bitmaps so there is\r
- // always enough room\r
- _maxHeight = _iconHeight;\r
-\r
-#if(CHECKBOXVIEW)\r
- if(_maxHeight < _checkHeight)\r
- _maxHeight = _checkHeight;\r
-#endif\r
-\r
- // set standard highlighting brush\r
- this->m_HilightBrush = new wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT),wxSOLID);\r
-\r
- // set standard DC font\r
- _captionFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);\r
-\r
- // adjust bitmap icon y position so they are centered\r
- AdjustIconsDeltaY();\r
-\r
- // set virtual size to this window size\r
- if (_create_called) {\r
- wxSize wndsize = GetSize();\r
- SetVirtualSize(wndsize.GetWidth(), wndsize.GetWidth());\r
- }\r
-}\r
-\r
-void wxTreeMultiCtrl::SetCaptionFont(const wxFont &font)\r
-{\r
- _captionFont = font;\r
-\r
- // adjust the icons so that they are in the middle\r
- AdjustIconsDeltaY();\r
-\r
- RedrawFromNode(0);\r
-};\r
-\r
-void wxTreeMultiCtrl::AdjustIconsDeltaY()\r
-{\r
- int x = 0, y = 0;\r
-\r
- if(_captionFont.Ok())\r
- GetTextExtent(wxT("jG"), &x, &y, 0, 0, &_captionFont);\r
- _captionHeight = y;\r
-\r
- if(_maxHeight < _captionHeight)\r
- _maxHeight = _captionHeight;\r
-\r
- // determine the center pos for the [+]\r
- _iconDeltaY = abs(_maxHeight - _iconHeight) / 2 + 1;\r
- if(_iconDeltaY < 1)\r
- _iconDeltaY = 1;\r
-\r
-#if(CHECKBOXVIEW)\r
- // determine the center pos for the checkbox\r
- _checkDeltaY = abs(_maxHeight - _checkHeight) / 2 + 1;\r
- if(_checkDeltaY < 1)\r
- _checkDeltaY = 1;\r
-#endif\r
-}\r
-\r
-wxTreeMultiCtrl::~wxTreeMultiCtrl()\r
-{\r
- // delete the bitmap resources\r
- delete _expandBmp;\r
- delete _collBmp;\r
-\r
-#if(CHECKBOXVIEW)\r
- delete _checkBmp;\r
- delete _uncheckBmp;\r
- delete _tristateBmp;\r
-#endif\r
-}\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::AddRoot(const wxString &caption, const wxString &name)\r
-{\r
- wxTreeMultiItem result((TreeMultiItemBase *)&_root);\r
- result = AppendNode(result, caption, name);\r
-\r
- return result;\r
-}\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::AppendWindow(const wxTreeMultiItem &ParentItem, wxWindow *window, const wxString &name, const wxTreeMultiWindowInfo &info, int flags)\r
-{\r
- // add window only if the parent item is valid and...\r
- wxCHECK(ParentItem.IsOk(), wxTreeMultiItem(0));\r
-\r
- TreeMultiItemNode* parent = ParentItem.GetItem()->IsTreeMultiItemNode(); // also roots are nodes\r
-\r
- // ... is a node\r
- wxCHECK(parent != NULL, wxTreeMultiItem(0));\r
-\r
- // now, append node to the tree control:\r
- wxTreeMultiItem NewWindowItem(this->InsertWindow(parent,wx_static_cast(size_t,parent->GetNodeCount()),window,name,info,flags));\r
- // redraw the stucture:\r
- this->RedrawFromNode(parent);\r
- // return the new window\r
- return NewWindowItem;\r
-}\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::InsertWindow(wxTreeMultiItem const& ParentItem, size_t Position, wxWindow *window, wxString const& name, wxTreeMultiWindowInfo const& info, int flags)\r
-{\r
- // add window only if the parent item is valid and...\r
- wxCHECK(ParentItem.IsOk(), wxTreeMultiItem(0));\r
-\r
- TreeMultiItemNode* parent = ParentItem.GetItem()->IsTreeMultiItemNode(); // also roots are nodes\r
-\r
- // ... is a node\r
- wxCHECK(parent != NULL, wxTreeMultiItem(0));\r
-\r
- // now, append node to the tree control:\r
- wxTreeMultiItem NewWindowItem(this->InsertWindow(parent,Position,window,name,info,flags));\r
- // redraw the stucture:\r
- this->RedrawFromNode(parent);\r
- // return the new window\r
- return NewWindowItem;\r
-} /* wxTreeMultiCtrl::InsertWindow(wxTreeMultiItem const&, size_t, wxWindow*, wxString const&, wxTreeMultiWindowInfo const&, int) */\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::PrependWindow(wxTreeMultiItem const& ParentItem, wxWindow *window, const wxString &name, wxTreeMultiWindowInfo const& info, int flags)\r
-{\r
- // add window only if the parent item is valid and...\r
- wxCHECK(ParentItem.IsOk(), wxTreeMultiItem(0));\r
-\r
- TreeMultiItemNode* parent = ParentItem.GetItem()->IsTreeMultiItemNode(); // also roots are nodes\r
-\r
- // ... is a node\r
- wxCHECK(parent != NULL, wxTreeMultiItem(0));\r
-\r
- // now, append node to the tree control:\r
- wxTreeMultiItem NewWindowItem(this->InsertWindow(parent,0,window,name,info,flags));\r
- // redraw the stucture:\r
- this->RedrawFromNode(parent);\r
- // return the new window\r
- return NewWindowItem;\r
-} /* wxTreeMultiCtrl::PrependWindow(wxTreeMultiItem const&, wxWindow*, const wxString &, wxTreeMultiWindowInfo const&, int) */\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::AppendNode(wxTreeMultiItem const& ParentItem, const wxString &caption, const wxString &name)\r
-{\r
- // add window only if the parent item is valid and...\r
- wxCHECK(ParentItem.IsOk(), wxTreeMultiItem(0));\r
-\r
- TreeMultiItemNode* parent = ParentItem.GetItem()->IsTreeMultiItemNode(); // also roots are nodes\r
-\r
- // ... is a node\r
- wxCHECK(parent != NULL, wxTreeMultiItem(0));\r
-\r
- // now, append node to the tree control:\r
- wxTreeMultiItem NewNodeItem(this->InsertNode(parent,wx_static_cast(size_t,parent->GetNodeCount()),caption,name));\r
- // redraw the structure:\r
- this->RedrawFromNode(parent);\r
- // return the new node:\r
- return NewNodeItem;\r
-} /* wxTreeMultiCtrl::AppendNode(wxTreeMultiItem const&, const wxString &, const wxString&) */\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::InsertNode(wxTreeMultiItem const& ParentItem, size_t Position, wxString const& caption, wxString const& name)\r
-{\r
- // add window only if the parent item is valid and...\r
- wxCHECK(ParentItem.IsOk(), wxTreeMultiItem(0));\r
-\r
- TreeMultiItemNode* parent = ParentItem.GetItem()->IsTreeMultiItemNode(); // also roots are nodes\r
-\r
- // ... is a node\r
- wxCHECK(parent != NULL, wxTreeMultiItem(0));\r
-\r
- // now, append node to the tree control:\r
- wxTreeMultiItem NewNodeItem(this->InsertNode(parent,Position,caption,name));\r
- // redraw the structure:\r
- this->RedrawFromNode(parent);\r
- // return the new node:\r
- return NewNodeItem;\r
-} /* wxTreeMultiCtrl::InsertNode(wxTreeMultiItem const&, size_t, wxString const&, wxString const&) */\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::PrependNode(wxTreeMultiItem const& ParentItem, wxString const& caption, wxString const& name)\r
-{\r
- // add window only if the parent item is valid and...\r
- wxCHECK(ParentItem.IsOk(), wxTreeMultiItem(0));\r
-\r
- TreeMultiItemNode* parent = ParentItem.GetItem()->IsTreeMultiItemNode(); // also roots are nodes\r
-\r
- // ... is a node\r
- wxCHECK(parent != NULL, wxTreeMultiItem(0));\r
-\r
- // now, append node to the tree control:\r
- wxTreeMultiItem NewNodeItem(this->InsertNode(parent,0,caption,name));\r
- // redraw the structure:\r
- this->RedrawFromNode(parent);\r
- // return the new node:\r
- return NewNodeItem;\r
-} /* wxTreeMultiCtrl::PrependNode(wxTreeMultiItem const&, wxString const&, wxString const&) */\r
-\r
-bool wxTreeMultiCtrl::Delete(wxTreeMultiItem &item)\r
-{\r
- bool redraw = true;\r
- wxCHECK(item.IsOk(), false);\r
-\r
- wxTreeMultiItem nullItem(0);\r
-\r
-\r
- // if item has been selected, remove it from the selected list:\r
- size_t ItemIndex(this->GetSelectedItemIndex(item));\r
-\r
- if (ItemIndex != this->GetSelectedItemCount())\r
- this->m_SelectedItems.RemoveAt(ItemIndex);\r
-\r
- // get parent, to delete item from\r
- TreeMultiItemNode *p = item.GetItem()->GetParent();\r
-\r
- // first check if it was visible, if so from the parent off\r
- // it needs redrawing\r
- redraw = item.GetItem()->IsVisible();\r
- if(p)\r
- p->DeleteNode(item.GetItem());\r
- else\r
- _root.DeleteNode(item.GetItem());\r
-\r
- item = nullItem;\r
-\r
- // do redraw when node was visible\r
- if(redraw)\r
- RedrawFromNode(p);\r
-\r
- return true;\r
-}\r
-\r
-void wxTreeMultiCtrl::DeleteChildren(const wxTreeMultiItem &item)\r
-{\r
- if(item.IsNodeItem())\r
- {\r
- TreeMultiItemNode *n = (TreeMultiItemNode *)item.GetItem();\r
-\r
- // remove all children from the selected item list:\r
- if (n->GetNodeCount() > 0)\r
- {\r
- // variable definitions and initializations:\r
- int Cookie;\r
- wxTreeMultiItem FirstItemIterator(this->GetFirstChild(item,Cookie)), LastItemIterator(this->GetLastChild(item));\r
-\r
- for (;;)\r
- {\r
- size_t ItemIndex(this->GetSelectedItemIndex(item)); // variable definition and initialization\r
-\r
- if (ItemIndex != this->GetSelectedItemCount())\r
- this->m_SelectedItems.RemoveAt(ItemIndex);\r
- if (FirstItemIterator == LastItemIterator)\r
- break; // all children checked\r
- else\r
- FirstItemIterator = this->GetNext(FirstItemIterator);\r
- } /* for */\r
- } /* if */\r
- // delete children:\r
- n->Clear();\r
- // redraw:\r
- RedrawFromNode(n);\r
- }\r
-}\r
-\r
-void wxTreeMultiCtrl::Expand(const wxTreeMultiItem &item, bool recursive)\r
-{\r
- if(item.IsOk())\r
- {\r
- TreeMultiItemNode *n = item.GetItem()->IsTreeMultiItemNode();\r
- if(!n)\r
- n = item.GetItem()->GetParent();\r
- DoFold(n, true, recursive);\r
- RedrawFromNode(item.GetItem()->IsTreeMultiItemNode());\r
- }\r
-}\r
-\r
-void wxTreeMultiCtrl::Collapse(const wxTreeMultiItem &item, bool recursive)\r
-{\r
- if(item.IsOk())\r
- {\r
- TreeMultiItemNode *n = item.GetItem()->IsTreeMultiItemNode();\r
- if(!n)\r
- n = item.GetItem()->GetParent();\r
- DoFold(n, false, recursive);\r
- RedrawFromNode(item.GetItem()->IsTreeMultiItemNode());\r
- }\r
-}\r
-\r
-\r
-void wxTreeMultiCtrl::ExpandNodes(bool recursive)\r
-{\r
- // go through all children and call DoFold recursively\r
- for(int i = 0; i < _root.GetNodeCount(); i++)\r
- DoFold(_root.GetNode(i), true, recursive);\r
- RedrawFromNode(0);\r
-}\r
-\r
-void wxTreeMultiCtrl::CollapseNodes(bool recursive)\r
-{\r
- // go through all children and call DoFold recursively\r
- for(int i = 0; i < _root.GetNodeCount(); i++)\r
- DoFold(_root.GetNode(i), false, recursive);\r
- RedrawFromNode(0);\r
-}\r
-\r
-void wxTreeMultiCtrl::CollapseAndReset(const wxTreeMultiItem &item)\r
-{\r
- if(item.IsNodeItem())\r
- {\r
- TreeMultiItemNode *n = (TreeMultiItemNode *)item.GetItem();\r
-\r
- // delete all kids\r
- n->Clear();\r
- Collapse(item, false);\r
- }\r
-}\r
-\r
-// Selection manipulation\r
-wxTreeMultiItem wxTreeMultiCtrl::GetFirstSelectedItem(void) const\r
-{\r
- if (this->GetSelectedItemCount() > 0)\r
- return this->m_SelectedItems[0];\r
- else\r
- return wxTreeMultiItem();\r
-} /* wxTreeMultiCtrl::GetFirstSelectedItem(void) const */\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::GetLastSelectedItem(void) const\r
-{\r
- if (this->GetSelectedItemCount() > 0)\r
- return this->m_SelectedItems[this->GetSelectedItemCount()-1];\r
- else\r
- return wxTreeMultiItem();\r
-} /* wxTreeMultiCtrl::GetLastSelectedItem(void) const */\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::GetSelectedItem(size_t Index) const\r
-{\r
- if (Index < this->GetSelectedItemCount())\r
- return this->m_SelectedItems[Index];\r
- else\r
- return wxTreeMultiItem();\r
-} /* wxTreeMultiCtrl::GetSelectedItem(size_t Index) const */\r
-\r
-size_t wxTreeMultiCtrl::GetSelectedItemIndex(wxTreeMultiItem const& Item) const\r
-{\r
- // attention: the function wxArray::Index() can NOT be used in a save manner as it only checks the address of an item\r
- // element but it is not guaranteed that Item may not be a copy of the originally inserted item\r
- const size_t NoOfSelectedItems = this->GetSelectedItemCount();\r
-\r
- size_t Index(0);\r
-\r
-\r
- while ((Index < NoOfSelectedItems) && (this->m_SelectedItems[Index] != Item))\r
- ++Index;\r
- return Index;\r
-} /* wxTreeMultiCtrl::GetSelectedItemIndex(wxTreeMultiItem const&) const */\r
-\r
-void wxTreeMultiCtrl::SelectItem(wxTreeMultiItem const& Item, bool UnselectOthers, bool ExpandSelection)\r
-{\r
- TreeMultiItemNode* NodePtr(Item.GetItem()->IsTreeMultiItemNode());\r
-\r
-\r
- // only nodes can be selected and they can only be selected if they are not already selected:\r
- if ((NodePtr == NULL) || NodePtr->IsSelected())\r
- return;\r
-\r
- // inform that we are about to change:\r
- wxTreeMultiEvent Event(wxEVT_COMMAND_TREE_MULTI_SEL_CHANGING,Item); // variable definition and initialization\r
-\r
- if (this->m_SelectedItems.GetCount() > 0) // the last item in the array is always the latest inserted item\r
- Event.SetOldItem(this->m_SelectedItems.Last());\r
- Event.SetEventObject(this);\r
- if (this->GetEventHandler()->ProcessEvent(Event) && !(Event.IsAllowed()))\r
- return; // vetoed\r
-\r
- // make sure that the to be selected item can be seen:\r
- this->Include(Item);\r
-\r
- // variable definition and initialization:\r
- wxTreeMultiItem ExcludedParent(this->GetExcludedParent(Item));\r
-\r
- while (ExcludedParent.IsOk())\r
- {\r
- this->Include(ExcludedParent);\r
- ExcludedParent = this->GetExcludedParent(Item);\r
- } /* while */\r
-\r
- // unselect items if necessary:\r
- if (UnselectOthers)\r
- this->UnselectAll();\r
- // expand selection if necessary:\r
- if (ExpandSelection)\r
- {\r
- // variable definition:\r
- wxTreeMultiItem FirstItemIterator, LastItemIterator;\r
- wxTreeMultiItem LastSelectedItem;\r
-\r
- // determine the last selected item or the first item in case nothing has been selected before:\r
- if (this->m_SelectedItems.GetCount() > 0)\r
- LastSelectedItem = this->m_SelectedItems.Last();\r
- else\r
- LastSelectedItem = this->GetFirstRoot();\r
- // determine the item from which to start and the one with which to end the selection:\r
- if (Item.GetItem()->GetY() > LastSelectedItem.GetItem()->GetY())\r
- {\r
- FirstItemIterator = LastSelectedItem;\r
- LastItemIterator = Item;\r
- } /* if */\r
- else\r
- {\r
- FirstItemIterator = Item;\r
- LastItemIterator = LastSelectedItem;\r
- } /* if */\r
- // select all items that are a node and are placed between the two limiting iterators (included the limits):\r
- for (;;)\r
- {\r
- if (!(FirstItemIterator.IsSelected()) && FirstItemIterator.IsNodeItem())\r
- {\r
- FirstItemIterator.GetItem()->Select();\r
- this->m_SelectedItems.Add(FirstItemIterator);\r
- this->RefreshRect(wxRect(FirstItemIterator.GetItem()->GetX(), FirstItemIterator.GetItem()->GetY(),\r
- FirstItemIterator.GetItem()->GetWidth(),FirstItemIterator.GetItem()->GetHeight()));\r
- } /* if */\r
- if (FirstItemIterator == LastItemIterator)\r
- break; // done\r
- // continue iterating:\r
- FirstItemIterator = this->GetNext(FirstItemIterator);\r
- } /* for */\r
- } /* if */\r
- else // select passed item only\r
- {\r
- NodePtr->Select();\r
- this->m_SelectedItems.Add(NodePtr);\r
- this->RefreshRect(wxRect(NodePtr->GetX(),NodePtr->GetY(),NodePtr->GetWidth(),NodePtr->GetHeight()));\r
- } /* if */\r
-\r
- // inform that we have selected the item:\r
- Event.SetEventType(wxEVT_COMMAND_TREE_MULTI_SEL_CHANGED);\r
- this->GetEventHandler()->ProcessEvent(Event);\r
-} /* wxTreeMultiCtrl::SelectItem(wxTreeMultiItem const&, bool, bool) */\r
-\r
-void wxTreeMultiCtrl::UnselectAll(void)\r
-{\r
- const size_t NoOfSelectedItems = this->m_SelectedItems.GetCount();\r
-\r
-\r
- for (size_t i=0; i<NoOfSelectedItems; ++i)\r
- {\r
- this->RefreshRect(wxRect(this->m_SelectedItems[i].GetItem()->GetX(), this->m_SelectedItems[i].GetItem()->GetY(),\r
- this->m_SelectedItems[i].GetItem()->GetWidth(),this->m_SelectedItems[i].GetItem()->GetHeight()));\r
- this->m_SelectedItems[i].GetItem()->Unselect();\r
- } /* for */\r
- this->m_SelectedItems.Clear();\r
-} /* wxTreeMultiCtrl::UnselectAll(void) */\r
-\r
-void wxTreeMultiCtrl::Unselect(wxTreeMultiItem const& Item)\r
-{\r
- size_t ItemIndex(this->GetSelectedItemIndex(Item));\r
-\r
-\r
- if (ItemIndex != this->GetSelectedItemCount())\r
- {\r
- Item.GetItem()->Unselect();\r
- this->m_SelectedItems.RemoveAt(ItemIndex);\r
- this->RefreshRect(wxRect(Item.GetItem()->GetX(),Item.GetItem()->GetY(),Item.GetItem()->GetWidth(),Item.GetItem()->GetHeight()));\r
- } /* if */\r
-} /* wxTreeMultiCtrl::Unselect(wxTreeMultiItem const&) */\r
-\r
-void wxTreeMultiCtrl::DoFold(TreeMultiItemBase *item, bool expand, bool recursive)\r
-{\r
-\r
- // go through all node objects on this level, and expand or\r
- // collapse them\r
-\r
- if(item == 0)\r
- return;\r
-\r
- // if this is a node, use it to go through all the subnodes (if needed)\r
- // if not, then just exit.\r
-\r
- TreeMultiItemNode *node = item->IsTreeMultiItemNode();\r
- if(node)\r
- {\r
- node->Fold(expand);\r
-\r
- // go recursive\r
- if(recursive)\r
- {\r
- TreeMultiItemNode *p;\r
- for(int i = 0; i < node->GetNodeCount(); i++)\r
- {\r
- // get node, and if a real node, then call fold\r
- p = node->GetNode(i)->IsTreeMultiItemNode();\r
- if(p)\r
- p->Fold(expand);\r
-\r
- // go recursive for every node\r
- DoFold(p, expand, recursive);\r
- }\r
- }\r
- }\r
-}\r
-\r
-void wxTreeMultiCtrl::Exclude(const wxTreeMultiItem &item)\r
-{\r
- wxCHECK2(item.IsOk(), return);\r
-\r
- // exclude the item, and refresh\r
- // if already excluded, skip\r
-\r
- if(!item.GetItem()->IsExcluded())\r
- {\r
- item.GetItem()->SetExcluded(true);\r
- RedrawFromParentNode(item.GetItem());\r
- }\r
-}\r
-\r
-void wxTreeMultiCtrl::Include(const wxTreeMultiItem &item)\r
-{\r
- wxCHECK2(item.IsOk(), return);\r
-\r
- // include the item, and refresh. If not\r
- // excluded, do nothing\r
-\r
- if(item.GetItem()->IsExcluded())\r
- {\r
- item.GetItem()->SetExcluded(false);\r
- RedrawFromParentNode(item.GetItem());\r
- }\r
-}\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::GetExcludedParent(const wxTreeMultiItem &item)\r
-{\r
- wxCHECK(item.IsOk(), wxTreeMultiItem(0));\r
-\r
- // go find the parent (including this one) that\r
- // can be the excluded one\r
-\r
- TreeMultiItemNode *n = item.GetItem()->IsTreeMultiItemNode();\r
- if(n && n->IsExcluded())\r
- return wxTreeMultiItem(n);\r
-\r
- n = item.GetItem()->GetParent();\r
- while(n)\r
- {\r
- if(n->IsExcluded())\r
- return wxTreeMultiItem(n);\r
- else\r
- n = n->GetParent();\r
- }\r
-\r
- return wxTreeMultiItem(0);\r
-}\r
-\r
-void wxTreeMultiCtrl::OnSize(wxSizeEvent &WXUNUSED(event))\r
-{\r
- RecalculateSpanSizes();\r
-}\r
-\r
-void wxTreeMultiCtrl::OnPaint(wxPaintEvent& WXUNUSED(event) )\r
-{\r
- wxPaintDC dc(this);\r
-\r
- PrepareDC(dc);\r
-\r
- // go recursive and draw the whole visible tree.\r
- dc.SetFont(_captionFont);\r
- for(int i = 0; i < _root.GetNodeCount(); i++)\r
- DrawNode(_root.GetNode(i), dc);\r
-}\r
-\r
-void wxTreeMultiCtrl::DrawNode(TreeMultiItemBase *b, wxDC &dc)\r
-{\r
- // go through this item .. if it is a node, draw\r
- // the caption, else reposition the window.\r
-\r
- if(!b)\r
- return;\r
-\r
- // forget it if this node is not visible\r
- if(b->IsVisible())\r
- {\r
- int bmpOffsetX = b->GetX() - (_gutterWidth + _iconWidth);\r
-\r
-#if(CHECKBOXVIEW)\r
- // now draw the checkbox if there is any, in the proper state\r
- if(b->GetCheckbox())\r
- {\r
- DrawCheckbox(b, dc);\r
-\r
- // adjust the bmpOffset because we also have a checkbox\r
- bmpOffsetX -= _checkWidth;\r
- }\r
-#endif\r
-\r
- if(b->IsTreeMultiItemNode())\r
- {\r
- // draw the node icon and the caption\r
- TreeMultiItemNode *n = (TreeMultiItemNode *)b;\r
-\r
- // set background of caption item\r
- if (n->IsSelected())\r
- {\r
- dc.SetBrush(*(this->m_HilightBrush));\r
- dc.SetPen(wxPen(this->m_HilightBrush->GetColour(),1,wxSOLID));\r
- } /* if */\r
- else\r
- {\r
- dc.SetBrush(wxBrush(*wxWHITE,wxSOLID));\r
- dc.SetPen(wxPen(*wxWHITE,1,wxSOLID));\r
- } /* if */\r
- dc.DrawRectangle(n->GetX(),n->GetY(),n->GetWidth(),n->GetHeight());\r
- // draw caption\r
- dc.DrawText(n->GetCaption(), n->GetX(), n->GetY());\r
-\r
- // draw the bitmap for the state\r
- if(n->IsExpanded())\r
- dc.DrawBitmap(*_expandBmp, bmpOffsetX, n->GetY() + _iconDeltaY, true);\r
- else\r
- dc.DrawBitmap(*_collBmp, bmpOffsetX, n->GetY() + _iconDeltaY, true);\r
-\r
- // now go through all the subnodes\r
- for(int i = 0; i < n->GetNodeCount(); i++)\r
- DrawNode(n->GetNode(i), dc);\r
-\r
- }\r
- }\r
-}\r
-\r
-#if(CHECKBOXVIEW)\r
-\r
-void wxTreeMultiCtrl::DrawCheckbox(TreeMultiItemBase *b, wxDC &dc, bool convertScrolled)\r
-{\r
- wxCHECK2(b, return);\r
-\r
- wxBitmap *bmp;\r
- int bmpOffsetX = b->GetX() - (_gutterWidth + _iconWidth);\r
-\r
- switch(b->GetCheckboxState())\r
- {\r
- case 0:\r
- bmp = _uncheckBmp;\r
- break;\r
- case 1:\r
- bmp = _checkBmp;\r
- break;\r
- default:\r
- bmp = _tristateBmp;\r
- break;\r
- }\r
-\r
- int x, xx, y, yy;\r
-\r
- if(b->IsTreeMultiItemWindow())\r
- {\r
- xx = x = bmpOffsetX - ((TreeMultiItemWindow *)b)->GetFrontSpacing() + _checkWidth;\r
- yy = y = b->GetY() + _checkDeltaY;\r
- }\r
- else\r
- {\r
- xx = x = bmpOffsetX;\r
- yy = y = b->GetY() + _checkDeltaY;\r
- }\r
-\r
- if(convertScrolled)\r
- CalcScrolledPosition(x, y, &xx, &yy);\r
-\r
- dc.DrawBitmap(*bmp, xx, yy, true);\r
-}\r
-\r
-#endif // #if(CHECKBOXVIEW)\r
-\r
-void wxTreeMultiCtrl::OnKey(wxKeyEvent &event)\r
-{\r
- // check if we need to traverse to upper or lower\r
- // control in the list\r
- if(event.GetKeyCode() == WXK_TAB)\r
- {\r
- wxTreeMultiItem item = GetFocus();\r
- if(item.IsOk())\r
- {\r
- // traverse down direction\r
- if(!event.ShiftDown())\r
- item = FindNextVisibleWindowItem(item.GetItem());\r
- //else // traverse in up direction\r
- // item = FindPreviousVisibleWindowItem(item);\r
-\r
- if(item.IsOk())\r
- {\r
- TreeMultiItemWindow *w = item.GetItem()->IsTreeMultiItemWindow();\r
- if(w)\r
- {\r
- wxWindow *wnd = w->GetWindow();\r
- wnd->SetFocus();\r
- }\r
- }\r
- }\r
- }\r
- else\r
- event.Skip();\r
-}\r
-\r
-void wxTreeMultiCtrl::OnMouseClick( wxMouseEvent &event )\r
-{\r
- // react on double click and left mouse down\r
- if(event.LeftDown() || event.LeftDClick())\r
- {\r
- // get translation point\r
- wxPoint pt( event.GetPosition() );\r
-\r
- int x = 0, y = 0;\r
- CalcUnscrolledPosition( pt.x, pt.y, &x, &y );\r
-\r
- // go check if we clicked a treenode\r
- int flags;\r
- wxPoint p(x,y);\r
- wxTreeMultiItem id = HitTest(p, flags);\r
-\r
-#if(CHECKBOXVIEW)\r
- if(flags == wxTMC_HITTEST_CHECKBOX)\r
- {\r
- // toggle the checkbox, and redraw\r
- if(id.IsOk())\r
- {\r
- TreeMultiItemBase *b = id.GetItem();\r
- b->SetCheckboxState((b->GetCheckboxState()+1) & 0x1);\r
-\r
- TreeMultiItemWindow *w = b->IsTreeMultiItemWindow();\r
- if(w)\r
- {\r
- // try to force a focus on the window. This could\r
- // be extended by searching for the first edit control\r
- // class but for now, just a focus is tried.\r
- w->GetWindow()->Enable(b->GetCheckboxState() == 1);\r
- w->GetWindow()->SetFocus();\r
-\r
- // draw the checkbox in the state needed\r
- wxClientDC dc(this);\r
- DrawCheckbox(b, dc, true);\r
-\r
- // TODO: determine if the upper parents should be\r
- // tristated or not\r
-\r
- ScanTristateCheckstates(b);\r
-\r
- }\r
- else if(b->IsTreeMultiItemNode())\r
- {\r
- // descend to all the children and set the state of the parent\r
- SetRecursiveCheckState((TreeMultiItemNode *)b, b->GetCheckboxState() == 1);\r
- RedrawFromNode((TreeMultiItemNode *)b);\r
- }\r
- }\r
- }\r
- else\r
-#endif // #if(CHECKBOXVIEW)\r
- {\r
- // react on left mouse button, to fold and on\r
- // right for caption doubleclick\r
- int area = -1;\r
-\r
-// adjust behaviour for Linux (single click = always fold)\r
-#ifndef LINUX\r
- if(event.LeftDClick())\r
- area = wxTMC_HITTEST_CAPTION;\r
- else\r
- area = wxTMC_HITTEST_GUTTER;\r
-#else\r
- area = flags;\r
-#endif\r
-\r
-// Linux (single or double click -> always fold\r
- if (id.IsOk())\r
- {\r
-#ifdef LINUX\r
- // we have a valid item, if it is a node, then fold\r
- TreeMultiItemNode *n = id.GetItem()->IsTreeMultiItemNode();\r
- if(n)\r
- {\r
- this->SelectItem(id);\r
- Fold(n, !n->IsExpanded());\r
- } /* if */\r
-#else\r
- if (event.LeftDown())\r
- if (flags == wxTMC_HITTEST_GUTTER)\r
- {\r
- TreeMultiItemNode *n = id.GetItem()->IsTreeMultiItemNode(); // for some reasons also windows may have set the flag\r
-\r
- if (n != NULL)\r
- Fold(n, !n->IsExpanded());\r
- } /* if */\r
- else if (flags == wxTMC_HITTEST_CAPTION)\r
- {\r
- TreeMultiItemNode *n = id.GetItem()->IsTreeMultiItemNode(); // for some reasons also windows may have set the flag\r
-\r
- if (n != NULL)\r
- {\r
- this->SelectItem(id);\r
- this->RedrawFromNode(n);\r
- } /* if */\r
- } /* if */\r
-#endif\r
- } /* if */\r
- else\r
- this->UnselectAll();\r
- }\r
- }\r
-}\r
-\r
-void wxTreeMultiCtrl::OnRightMouseClick(wxMouseEvent& Event)\r
-{\r
- if (Event.RightDown())\r
- if (Event.Dragging())\r
- this->UnselectAll();\r
- else\r
- {\r
- // variable definitions:\r
- int Flags;\r
- wxPoint Point;\r
-\r
- // translate mouse coordinates:\r
- CalcUnscrolledPosition(Event.GetPosition().x,Event.GetPosition().y,&(Point.x),&(Point.y));\r
- // check if the mouse is above the caption of an item:\r
- wxTreeMultiItem Item(this->HitTest(Point,Flags)); // variable definition and initialization\r
-\r
- if (Item.IsOk() && (Flags == wxTMC_HITTEST_CAPTION))\r
- {\r
- this->SelectItem(Item);\r
- this->RedrawFromNode(Item.GetItem()->IsTreeMultiItemNode());\r
- Event.Skip(); // window will convert right mouse click to a context menu event or proceed with\r
- // a right mouse click event if the context menu event cannot be processed\r
- } /* if */\r
- else\r
- this->UnselectAll();\r
- } /* if */\r
- else\r
- this->UnselectAll();\r
-} /* wxTreeMultiCtrl::OnRightMouseClick(wxMouseEvent&) */\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::HitTest(wxPoint const& pt, int &flags)\r
-{\r
- // scan all nodes to see which one matches\r
- TreeMultiItemBase *b = 0;\r
- for(int i = 0; i < _root.GetNodeCount() && !b; i++)\r
- b = FindNodeByPoint(_root.GetNode(i), pt, flags);\r
-\r
- if(!b)\r
- {\r
- // none found, reset\r
- flags = 0;\r
- return wxTreeMultiItem(0);\r
- }\r
-\r
- // return an item\r
- return wxTreeMultiItem(b);\r
-}\r
-\r
-TreeMultiItemBase *wxTreeMultiCtrl::FindNodeByPoint(TreeMultiItemBase *b, wxPoint const& pt, int &area)\r
-{\r
- wxCHECK(b, 0);\r
-\r
- // if this layer is not visible, return with nothing.\r
- if(!b->IsVisible())\r
- return 0;\r
-\r
- area = 0;\r
-\r
- // now see if our y is matching the mouse\r
- if(pt.y >= b->GetY() && pt.y < (b->GetY() + b->GetHeight()))\r
- {\r
-#if(CHECKBOXVIEW)\r
- // if we are checkboxed, calculate the checkbox position\r
- if(b->GetCheckbox())\r
- {\r
- int extraSpacing = 0, extraWidth = 0;\r
-\r
- // now for a windows item, this is minus the gutter. For a normal node it is X minus checkbox\r
- if(b->IsTreeMultiItemWindow())\r
- {\r
- extraWidth = _checkWidth;\r
- extraSpacing = ((TreeMultiItemWindow *)b)->GetFrontSpacing();\r
- }\r
- else\r
- extraSpacing = 4;\r
-\r
- if(pt.x > (b->GetX() - extraSpacing - _checkWidth) && pt.x < (b->GetX() - extraSpacing + extraWidth))\r
- {\r
- area = wxTMC_HITTEST_CHECKBOX;\r
- return b;\r
- }\r
- }\r
-#endif\r
-\r
- // allrighty we have something, now where and what is it (look with x)\r
- if(pt.x < b->GetX())\r
- area = wxTMC_HITTEST_GUTTER;\r
-\r
- /** \todo Match only the real part of the caption, window (we assume x > GetX() which is the rest)\r
- HOWEVER the window probably doesn't propagate the click event back to the parent, so we might\r
- leave it like this so the use can click behind a window so it will be selected.\r
- */\r
- else\r
- {\r
- // inside area, return proper flag\r
- if(b->IsTreeMultiItemNode())\r
- area = wxTMC_HITTEST_CAPTION;\r
- else\r
- area = wxTMC_HITTEST_WINDOW;\r
- }\r
-\r
- return b;\r
- }\r
- else\r
- {\r
- // not found, let's try our children if we have some\r
- TreeMultiItemNode *n = b->IsTreeMultiItemNode();\r
- if(n)\r
- {\r
- TreeMultiItemBase *bb = 0;\r
- for(int i = 0; i < n->GetNodeCount() && !bb; i++)\r
- bb = FindNodeByPoint(n->GetNode(i), pt, area);\r
-\r
- // keep returning result to caller\r
- return bb;\r
- }\r
- }\r
-\r
- return 0;\r
-}\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::GetFocus()\r
-{\r
- wxWindow *wnd = wxWindow::FindFocus();\r
-\r
- // now find window that holds this item. if not\r
- // visible it cannot have focus (should not have)\r
-\r
- wxTreeMultiItem item = FindWindowNode(wnd);\r
- if(item.IsOk() && item.GetItem()->IsVisible())\r
- return item;\r
-\r
- return wxTreeMultiItem(0);\r
-}\r
-\r
-#if(CHECKBOXVIEW)\r
-\r
-void wxTreeMultiCtrl::SetRecursiveCheckState(TreeMultiItemNode *n, bool check)\r
-{\r
- int state = 0;\r
- if(check)\r
- state++;\r
-\r
- // go check all kids on this level\r
- for(int i = 0; i < n->GetNodeCount(); i++)\r
- {\r
- // check all the nodes, and go deeper\r
- n->GetNode(i)->SetCheckboxState(state);\r
- if(n->GetNode(i)->IsTreeMultiItemNode())\r
- SetRecursiveCheckState((TreeMultiItemNode *)n->GetNode(i), check);\r
- }\r
-}\r
-\r
-void wxTreeMultiCtrl::ScanTristateCheckstates(TreeMultiItemBase *b)\r
-{\r
- // check from the parent on, all node entries and see if they are\r
- // checked or cleared or scattered\r
- TreeMultiItemNode *p = b->GetParent();\r
-\r
- if(p && p->GetCheckbox())\r
- {\r
- bool foundcheck = false, foundclear = false;\r
- for(size_t i = 0; i < (size_t)p->GetNodeCount(); ++i)\r
- {\r
- // only evaluate when checkboxed\r
- if(p->GetNode(i)->IsTreeMultiItemWindow() && p->GetNode(i)->GetCheckbox())\r
- {\r
- // record instance of a cleared checkbox\r
- if(!p->GetNode(i)->GetCheckboxState())\r
- foundclear = true;\r
- // record instance of checked checkbox\r
- if(p->GetNode(i)->GetCheckboxState() == 1)\r
- foundcheck = true;\r
- }\r
- }\r
-\r
- // if we have both check and clear, go tristate\r
- // if all clear, clear parent and if all set, then set parent\r
- if(foundclear && !foundcheck)\r
- p->SetCheckboxState(0);\r
- else if(!foundclear && foundcheck)\r
- p->SetCheckboxState(1);\r
- else if(foundclear && foundcheck)\r
- p->SetCheckboxState(2);\r
-\r
- //wxClientDC dc;\r
- //DrawCheckbox(p, dc, false);\r
- RedrawFromNode(p);\r
- }\r
-}\r
-\r
-#endif // #if(CHECKBOXVIEW)\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::InsertNode(TreeMultiItemNode* ParentPtr, size_t Position, wxString const& Caption, wxString const& Name)\r
-{\r
- int extX, extY;\r
-\r
- TreeMultiItemNode* NodePtr(new TreeMultiItemNode(ParentPtr,Caption,Name)); // generate new node pointer\r
-\r
-\r
- // continue with initializing the new node:\r
-#if(CHECKBOXVIEW)\r
- // if checkbox view is desired, tag this item as a checkbox\r
- // and set the state as 'false'\r
- NodePtr->SetCheckbox(_checkboxView);\r
- NodePtr->SetCheckboxState(0);\r
-#endif\r
- // calculate the height and width\r
- this->GetTextExtent(Caption,&extX,&extY,0,0,&(this->_captionFont));\r
- NodePtr->SetHeight(extY);\r
- NodePtr->SetWidth(extX);\r
- // finally, insert node:\r
- if (Position < (size_t)ParentPtr->GetNodeCount())\r
- ParentPtr->InsertNode(NodePtr,Position);\r
- else\r
- ParentPtr->AddNode(NodePtr);\r
- // return the newly created node:\r
- return wxTreeMultiItem(NodePtr);\r
-} /* wxTreeMultiCtrl::InsertNode(TreeMultiItemNode*, size_t, wxString const&, wxString const&) */\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::InsertWindow(TreeMultiItemNode* ParentPtr, size_t Position, wxWindow* WindowPtr, wxString const& Name, wxTreeMultiWindowInfo const& Info, int Flags)\r
-{\r
- int WindowFlags;\r
-\r
- TreeMultiItemWindow* NewWindowPtr = new TreeMultiItemWindow(ParentPtr,Name); // generate new window pointer\r
-\r
-\r
- // get flags from passed variable "Flags"; in case this variable does not contain any flags use the window's information flags:\r
- if (Flags != 0)\r
- WindowFlags = Flags;\r
- else\r
- WindowFlags = Info.GetFlags();\r
-\r
- // continue with initializing the new window:\r
-#if(CHECKBOXVIEW)\r
- // if checkbox view is desired, tag this item as a checkbox\r
- // and set the state as 'false'\r
- NewWindowPtr->SetCheckbox(_checkboxView);\r
-#endif\r
- // if style wants us to change background, set it to our background\r
- if (WindowFlags & wxTMC_BG_ADJUST_ALL)\r
- {\r
- // go through all children of this window, and set the\r
- // background of it (recursively)\r
- this->SetWindowBackgroundColour(WindowPtr,this->GetBackgroundColour(),WindowFlags);\r
- } /* if */\r
-\r
- // set the spacing:\r
- NewWindowPtr->SetTopSpacing(Info.GetTopSpacing());\r
-#if(CHECKBOXVIEW)\r
- // make sure that the checkboxes are at least indented enough\r
- if (this->_checkboxView)\r
- NewWindowPtr->SetFrontSpacing(Info.GetFrontSpacing() + this->_checkWidth);\r
- else\r
-#endif\r
- NewWindowPtr->SetFrontSpacing(Info.GetFrontSpacing());\r
- // assign finally the window:\r
- NewWindowPtr->AssignWindow(WindowPtr);\r
-\r
-#if(CHECKBOXVIEW)\r
- // set the checkbox state after the window is assigned\r
- NewWindowPtr->SetCheckboxState(Info.GetDefaultCheckState());\r
-#endif\r
-\r
- // if the window is not visible, set hide flag\r
- this->ShowTreeMultiWindow(NewWindowPtr,NewWindowPtr->IsVisible());\r
-\r
- // finally, insert the newly constructed window:\r
- if (Position < (size_t)ParentPtr->GetNodeCount())\r
- ParentPtr->InsertNode(NewWindowPtr,Position);\r
- else\r
- ParentPtr->AddNode(NewWindowPtr);\r
- // return the newly created window:\r
- return wxTreeMultiItem(NewWindowPtr);\r
-} /* wxTreeMultiCtrl::InsertWindow(TreeMultiItemNode*, size_t, wxWindow*, wxString const&, wxTreeMultiWindowInfo const&, int) */\r
-\r
-void wxTreeMultiCtrl::RedrawFromParentNode(TreeMultiItemBase *n)\r
-{\r
- TreeMultiItemNode *p = 0;\r
- if(n)\r
- p = n->GetParent();\r
-\r
- RedrawFromNode(p);\r
-}\r
-\r
-void wxTreeMultiCtrl::RedrawFromNode(TreeMultiItemNode *n)\r
-{\r
- static int recalcMutex = 0;\r
- bool visible = true;\r
-\r
- if(recalcMutex > 0)\r
- return;\r
-\r
- recalcMutex ++;\r
-\r
- // when node is not visible or excluded\r
- // then don't redraw.\r
-\r
- if(n)\r
- visible = n->IsVisible();\r
-\r
- if(visible)\r
- {\r
- int h, h1,w, w1;\r
- GetVirtualSize(&w, &h);\r
-\r
- UpdateAllWindowVisibility();\r
- RecalculateNodePositions();\r
- RecalculateVirtualSize();\r
-\r
- // why is this needed? Because folding or collapsing can change\r
- // the state. When the virtual area gets smaller, we need to keep\r
- // the largest one and the other way atound. And since we do not\r
- // know here we are folding or collapsing, we remember the biggest\r
- GetVirtualSize(&w1, &h1);\r
-\r
- if(h1 > h)\r
- h = h1;\r
-\r
- // only refresh the part from x,y down\r
- if(n)\r
- {\r
- int x, y;\r
- CalcScrolledPosition(n->GetX(), n->GetY(), &x, &y);\r
- if(h - y > 0)\r
- {\r
- wxRect rect(0, y, w, h - y);\r
- RefreshRect(rect);\r
- }\r
- else\r
- Refresh();\r
- }\r
- else\r
- Refresh(); // do a full refresh\r
- }\r
-\r
- recalcMutex --;\r
-}\r
-\r
-void wxTreeMultiCtrl::RecalculateNodePositions()\r
-{\r
- int currentY = _spacingY;\r
- // go recursive on every node, and store the information in the node\r
-\r
- for(int i = 0; i < _root.GetNodeCount(); i++)\r
- currentY += CalculateNodeDimensions(_root.GetNode(i), currentY, 0);\r
-}\r
-\r
-int wxTreeMultiCtrl::CalculateNodeDimensions(TreeMultiItemBase *b, int currentY, int level)\r
-{\r
- int gutter = (_gutterWidth * 2) + _iconWidth;\r
- int y = 0, topSpacing = 0;\r
-\r
- // return same if no proper object\r
- wxCHECK(b, 0);\r
-\r
-#if(CHECKBOXVIEW)\r
- if(b->GetCheckbox())\r
- gutter += _checkWidth;\r
-#endif\r
-\r
- // if we are not visible, skip recalculation and descending\r
- if(b->IsVisible())\r
- {\r
- b->SetY(currentY);\r
-\r
- // if level is 0, calculate with front gutter, else without\r
- y = currentY + b->GetHeight();\r
- if(b->IsTreeMultiItemNode())\r
- {\r
- TreeMultiItemNode *n = (TreeMultiItemNode *)b;\r
-\r
- if(level == 0)\r
- b->SetX(gutter);\r
- else\r
- b->SetX(gutter + (level * (_gutterWidth + _iconWidth)));\r
-\r
- // now do children of this node\r
-\r
- for(int i = 0; i < n->GetNodeCount(); i++)\r
- y += CalculateNodeDimensions(n->GetNode(i), y + _spacingY, level+1);\r
- }\r
- else if(b->IsTreeMultiItemWindow())\r
- {\r
- TreeMultiItemWindow *w = (TreeMultiItemWindow *)b;\r
-\r
- if(level == 0)\r
- b->SetX(gutter + w->GetFrontSpacing());\r
- else\r
- b->SetX(_gutterWidth + (level * (_gutterWidth + _iconWidth)) + w->GetFrontSpacing());\r
-\r
- topSpacing = w->GetTopSpacing();\r
-\r
- // reposition the window\r
-\r
- wxWindow *wnd = w->GetWindow();\r
- if(wnd)\r
- {\r
- int x = 0, y = 0;\r
- CalcScrolledPosition(w->GetX(), w->GetY(), &x, &y);\r
- wnd->SetSize(x, y, w->GetWidth(), w->GetHeight());\r
- }\r
- }\r
-\r
- if(y > 0)\r
- return (y - currentY) + _spacingY + topSpacing; // return delta\r
- else\r
- return 0;\r
- }\r
-\r
- return 0; // not visible, thus we skip calculations\r
-}\r
-\r
-void wxTreeMultiCtrl::RecalculateSpanSizes()\r
-{\r
- for(int i = 0; i < _root.GetNodeCount(); i++)\r
- CalculateNodeSpanning(_root.GetNode(i));\r
-}\r
-\r
-void wxTreeMultiCtrl::CalculateNodeSpanning(TreeMultiItemBase *b)\r
-{\r
- // return same if no proper object\r
- wxCHECK2(b, return);\r
-\r
- if(b->IsTreeMultiItemNode())\r
- {\r
- TreeMultiItemNode *n = (TreeMultiItemNode *)b;\r
-\r
- // now do children of this node\r
-\r
- for(int i = 0; i < n->GetNodeCount(); i++)\r
- CalculateNodeSpanning(n->GetNode(i));\r
- }\r
- else if(b->IsTreeMultiItemWindow())\r
- {\r
- TreeMultiItemWindow *w = (TreeMultiItemWindow *)b;\r
- wxWindow *wnd = w->GetWindow();\r
- if(wnd)\r
- {\r
- // if the window is spanning, we adjust the width to the max width of the control\r
- if(w->GetHorizontalSpan())\r
- {\r
- wxSize tmcsize = GetClientSize();\r
- int maxwidth = tmcsize.GetWidth() - w->GetX() - 8; // extract 3 for border\r
-\r
- wxSizer *sz = wnd->GetSizer();\r
- if(sz)\r
- {\r
- if(maxwidth < sz->GetMinSize().GetWidth())\r
- maxwidth = sz->GetMinSize().GetWidth();\r
- }\r
-\r
- // prevent a size of 0\r
- if(maxwidth < 1)\r
- maxwidth = 1;\r
-\r
- // set the size\r
- w->SetWidth(maxwidth);\r
- wnd->SetSize(w->GetWidth(), w->GetHeight());\r
-\r
- // layout by sizer (not sure if this is needed)\r
- if(wnd->GetSizer())\r
- wnd->GetSizer()->Layout();\r
- }\r
- }\r
- }\r
-}\r
-\r
-void wxTreeMultiCtrl::RecalculateVirtualSize()\r
-{\r
- // go through all the nodes, and store the largest x and largest y\r
-\r
- int x = 0, y = 0;\r
- RecalculateVirtualSizeFromNode(&_root, x, y);\r
-\r
- // now adjust virtual size\r
- SetVirtualSize(x, y);\r
- AdjustScrollbars(x, y);\r
-}\r
-\r
-void wxTreeMultiCtrl::AdjustScrollbars(int x, int y)\r
-{\r
- // adjust scrollbars\r
- // courtesy of treectrlg.cpp\r
-\r
- y += WXTMC_PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels\r
- x += WXTMC_PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels\r
- int x_pos = GetScrollPos( wxHORIZONTAL );\r
- int y_pos = GetScrollPos( wxVERTICAL );\r
- SetScrollbars( WXTMC_PIXELS_PER_UNIT, WXTMC_PIXELS_PER_UNIT, x/WXTMC_PIXELS_PER_UNIT,\r
- y/WXTMC_PIXELS_PER_UNIT, x_pos, y_pos, true );\r
-}\r
-\r
-void wxTreeMultiCtrl::RecalculateVirtualSizeFromNode(const TreeMultiItemNode *node, int &x, int &y)\r
-{\r
- if(node->IsExcluded())\r
- return;\r
-\r
- // if calulate this node's dimensions\r
- if(x < (node->GetWidth() + node->GetX()))\r
- x = node->GetWidth() + node->GetX();\r
-\r
- y = node->GetY() + node->GetHeight();\r
-\r
- // if this node is collapsed, no subnodes are visible, else\r
- // go through all subnodes as well, node needs to be included as well\r
- if(node->IsExpanded())\r
- {\r
- TreeMultiItemBase *b;\r
- for(int i = 0; i < node->GetNodeCount(); i++)\r
- {\r
- b = node->GetNode(i);\r
-\r
- // calculate x and y\r
- if(x < (b->GetWidth() + b->GetX()))\r
- x = b->GetWidth() + b->GetX();\r
-\r
- y = b->GetY() + b->GetHeight();\r
-\r
- if(b->IsTreeMultiItemNode())\r
- RecalculateVirtualSizeFromNode((TreeMultiItemNode *)b, x, y);\r
- }\r
- }\r
-}\r
-\r
-void wxTreeMultiCtrl::SetWindowBackgroundColour(wxWindow *wnd, const wxColour &col, int flags)\r
-{\r
- if(wnd)\r
- {\r
- // if we cannot change a button, make sure all button\r
- // classes are not changed\r
-\r
- wxButton *btn = wxDynamicCast(wnd, wxButton);\r
- if(!btn || ((flags & wxTMC_BG_ADJUST_BTN) != 0))\r
- wnd->SetBackgroundColour(col);\r
-\r
- // get every window, and make the background equal to the given one\r
- wxWindowListNode *node = wnd->GetChildren().GetFirst();\r
- while (node)\r
- {\r
- SetWindowBackgroundColour(node->GetData(), col, flags);\r
- node = node->GetNext();\r
- }\r
- }\r
-}\r
-\r
-void wxTreeMultiCtrl::ShowTreeMultiWindow(TreeMultiItemWindow *window, bool show)\r
-{\r
- // show or hide window\r
- if(window && window->GetWindow())\r
- window->GetWindow()->Show(show);\r
-}\r
-\r
-void wxTreeMultiCtrl::UpdateAllWindowVisibility()\r
-{\r
- // all roots are visible, but what lies beneath ... who knows\r
- for(int i = 0; i < _root.GetNodeCount(); i++)\r
- UpdateTreeMultiWindowVisibility(_root.GetNode(i), true);\r
-}\r
-\r
-void wxTreeMultiCtrl::UpdateTreeMultiWindowVisibility(TreeMultiItemBase *b, bool show)\r
-{\r
- if(b)\r
- {\r
- // this is done for performance issues. IsVisible can go all\r
- // the way up the tree to check. However if show is already\r
- // false, there is no need to check (some higher one is collapsed)\r
- bool showMe = show;\r
-\r
- if(showMe)\r
- showMe = b->IsVisible();\r
-\r
- if(b->IsTreeMultiItemWindow())\r
- {\r
- // if this level must be hidden, hide\r
- ShowTreeMultiWindow((TreeMultiItemWindow*)b, showMe);\r
- }\r
- else if(b->IsTreeMultiItemNode())\r
- {\r
- TreeMultiItemNode *node = (TreeMultiItemNode *)b;\r
-\r
- // if hidden, descend and hide all windows\r
- for(int i = 0; i < node->GetNodeCount(); i++)\r
- UpdateTreeMultiWindowVisibility(node->GetNode(i), showMe);\r
- }\r
- }\r
-}\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::FindItem(const wxTreeMultiItem &item, const wxString &name, bool ignoreCase, bool skipFirst)\r
-{\r
- if(item.IsOk())\r
- {\r
- TreeMultiItemBase *b = item.GetItem();\r
-\r
- // check this item first (or not)\r
-\r
- if(!skipFirst)\r
- {\r
- if(b->GetName().IsSameAs(name, !ignoreCase))\r
- return wxTreeMultiItem(b);\r
- }\r
-\r
- if(b->IsTreeMultiItemNode())\r
- {\r
- // now check whether we are a node, then go check children\r
-\r
- TreeMultiItemNode *n = (TreeMultiItemNode *)b;\r
- wxTreeMultiItem result(0);\r
- for(int i = 0; i < n->GetNodeCount() && !result.IsOk(); i++)\r
- result = FindItem(wxTreeMultiItem(n->GetNode(i)), name, ignoreCase, false);\r
-\r
- return result;\r
- }\r
- }\r
-\r
- return wxTreeMultiItem(0);\r
-}\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::FindWindowNode(wxWindow *wnd, TreeMultiItemNode *n)\r
-{\r
- wxCHECK(wnd, wxTreeMultiItem(0));\r
-\r
- // take root node if not assigned one\r
-\r
- if(!n)\r
- n = (TreeMultiItemNode *)&_root;\r
-\r
- // check on this level for the wxWindow pointer\r
-\r
- TreeMultiItemWindow *w;\r
- wxTreeMultiItem result(0);\r
- for(int i = 0; i < n->GetNodeCount() && !result.IsOk(); i++)\r
- {\r
- // if window node\r
- w = n->GetNode(i)->IsTreeMultiItemWindow();\r
- if(w && w->GetWindow() == wnd)\r
- return wxTreeMultiItem(n);\r
-\r
- // if node, go deeper\r
- if(n->GetNode(i)->IsTreeMultiItemNode())\r
- result = FindWindowNode(wnd, (TreeMultiItemNode*)n->GetNode(i));\r
- }\r
-\r
- return result;\r
-}\r
-\r
-TreeMultiItemWindow *wxTreeMultiCtrl::FindNextVisibleWindowItem(TreeMultiItemBase *b, int index)\r
-{\r
- wxCHECK(b, 0);\r
-\r
- // check on this level, go deeper with every node we got. When a node is not\r
- // visible anymore, skip the node.\r
-\r
- TreeMultiItemWindow *value = 0;\r
- if(b->IsVisible())\r
- {\r
- // if we are already searching on a node with an index\r
-\r
- TreeMultiItemBase *bn = 0;\r
- TreeMultiItemNode *n = b->IsTreeMultiItemNode();\r
- if(n)\r
- {\r
- for(int i = index + 1; i < n->GetNodeCount() && !value; i++)\r
- {\r
- bn = n->GetNode(i);\r
- value = bn->IsTreeMultiItemWindow();\r
-\r
- // assume a node, root when not a a window\r
- if(!value)\r
- value = FindNextVisibleWindowItem(bn, -1);\r
- }\r
-\r
- }\r
- else\r
- {\r
- if(b->IsTreeMultiItemWindow())\r
- {\r
- // get parent first, and locate child as ptr\r
- TreeMultiItemNode *p = b->GetParent();\r
- wxCHECK(p, 0);\r
-\r
- // go scan the parent from the given index, if\r
- // the index is valid else there is no child with that index\r
-\r
- int idx = p->Index(b);\r
- wxCHECK(idx >= 0, 0);\r
-\r
- value = FindNextVisibleWindowItem(p, idx);\r
- }\r
- }\r
- }\r
-\r
- return value;\r
-\r
-}\r
-\r
-bool wxTreeMultiCtrl::GetBooleanValue(int wndId)\r
-{\r
- wxWindow *wnd = wxWindow::FindWindow(wndId);\r
- wxCHECK(wnd, false);\r
-\r
- // try a radio button\r
- wxRadioButton *b = wxDynamicCast(wnd, wxRadioButton);\r
- if(b)\r
- return b->GetValue();\r
-\r
- // try a check box\r
- wxCheckBox *c = wxDynamicCast(wnd, wxCheckBox);\r
- if(c)\r
- return c->GetValue();\r
-\r
- /** \todo For custom controls we should put something in wxMultiTreeItemData class\r
- which can be overridden to retrieve the boolean value. It will also be passed\r
- the pointer to the window, so the derived class can figure out how to get a boolean\r
- value.\r
- */\r
-\r
- // generate assert or just return with false\r
- wxCHECK(0, false);\r
-}\r
-\r
-void wxTreeMultiCtrl::SetBooleanValue(int wndId, bool value)\r
-{\r
- wxWindow *wnd = wxWindow::FindWindow(wndId);\r
- wxCHECK2(wnd, return);\r
-\r
- // try a radio button\r
- wxRadioButton *b = wxDynamicCast(wnd, wxRadioButton);\r
- if(b)\r
- {\r
- b->SetValue(value);\r
- return;\r
- }\r
-\r
- // try a check box\r
- wxCheckBox *c = wxDynamicCast(wnd, wxCheckBox);\r
- if(c)\r
- {\r
- c->SetValue(value);\r
- return;\r
- }\r
-\r
- /** \todo For custom controls we should put something in wxMultiTreeItemData class\r
- which can be overridden to retrieve the boolean value. It will also be passed\r
- the pointer to the window, so the derived class can figure out how to get a boolean\r
- value.\r
- */\r
-\r
- // generate assert\r
- wxCHECK2(0, return);\r
-}\r
-\r
-void wxTreeMultiCtrl::SetTextValue(int wndId, const wxString &value)\r
-{\r
- wxWindow *wnd = wxWindow::FindWindow(wndId);\r
- wxCHECK2(wnd, return);\r
-\r
- // try a radio button\r
- wxTextCtrl *t = wxDynamicCast(wnd, wxTextCtrl);\r
- if(t)\r
- {\r
- t->SetValue(value);\r
- return;\r
- }\r
-\r
- /** \todo For custom controls we should put something in wxMultiTreeItemData class\r
- which can be overridden to retrieve the boolean value. It will also be passed\r
- the pointer to the window, so the derived class can figure out how to get a boolean\r
- value.\r
- */\r
-\r
- // generate assert\r
- wxCHECK2(0, return);\r
-}\r
-\r
-wxString wxTreeMultiCtrl::GetTextValue(int wndId)\r
-{\r
- wxWindow *wnd = wxWindow::FindWindow(wndId);\r
- wxCHECK(wnd, wxEmptyString);\r
-\r
- // try a radio button\r
- wxTextCtrl *t = wxDynamicCast(wnd, wxTextCtrl);\r
- if(t)\r
- return t->GetValue();\r
-\r
- // try a choice box\r
- wxChoice *c1 = wxDynamicCast(wnd, wxChoice);\r
- if(c1)\r
- return c1->GetStringSelection();\r
-\r
- // try a combo box\r
- wxComboBox *c2 = wxDynamicCast(wnd, wxComboBox);\r
- if(c2)\r
- return c2->GetStringSelection();\r
-\r
- // try a listbox\r
- wxListBox *l = wxDynamicCast(wnd, wxListBox);\r
- if(l)\r
- return l->GetStringSelection();\r
-\r
- /** \todo For custom controls we should put something in wxMultiTreeItemData class\r
- which can be overridden to retrieve the boolean value. It will also be passed\r
- the pointer to the window, so the derived class can figure out how to get a boolean\r
- value.\r
- */\r
-\r
- // generate assert or just return with string\r
- wxCHECK(0, wxEmptyString);\r
-}\r
-\r
-int wxTreeMultiCtrl::GetSelectionValue(int wndId)\r
-{\r
- wxWindow *wnd = wxWindow::FindWindow(wndId);\r
- wxCHECK(wnd, -1);\r
-\r
- // try a choice box\r
- wxChoice *c1 = wxDynamicCast(wnd, wxChoice);\r
- if(c1)\r
- return c1->GetSelection();\r
-\r
- // try a combo box\r
- wxComboBox *c2 = wxDynamicCast(wnd, wxComboBox);\r
- if(c2)\r
- return c2->GetSelection();\r
-\r
- // try a listbox\r
- wxListBox *l = wxDynamicCast(wnd, wxListBox);\r
- if(l)\r
- return l->GetSelection();\r
-\r
- /** \todo For custom controls we should put something in wxMultiTreeItemData class\r
- which can be overridden to retrieve the boolean value. It will also be passed\r
- the pointer to the window, so the derived class can figure out how to get a boolean\r
- value.\r
- */\r
-\r
- // generate assert or just return with string\r
- wxCHECK(0, -1);\r
-}\r
-\r
-void wxTreeMultiCtrl::GetSelectionValues(int wndId, wxArrayInt &sels)\r
-{\r
- sels.Clear();\r
-\r
- wxWindow *wnd = wxWindow::FindWindow(wndId);\r
- wxCHECK2(wnd, return);\r
-\r
- // try a listbox\r
- wxListBox *l = wxDynamicCast(wnd, wxListBox);\r
- if(l)\r
- {\r
- l->GetSelections(sels);\r
- return;\r
- }\r
-\r
- /** \todo For custom controls we should put something in wxMultiTreeItemData class\r
- which can be overridden to retrieve the boolean value. It will also be passed\r
- the pointer to the window, so the derived class can figure out how to get a boolean\r
- value.\r
- */\r
-\r
- // generate assert or just return with string\r
- wxCHECK2(0, return);\r
-}\r
-\r
-void wxTreeMultiCtrl::SetSelectionValue(int wndId, int sel)\r
-{\r
- wxWindow *wnd = wxWindow::FindWindow(wndId);\r
- wxCHECK2(wnd, return);\r
-\r
- // try a choice box\r
- wxChoice *c1 = wxDynamicCast(wnd, wxChoice);\r
- if(c1)\r
- {\r
- c1->SetSelection(sel);\r
- return;\r
- }\r
-\r
- // try a combo box\r
- wxComboBox *c2 = wxDynamicCast(wnd, wxComboBox);\r
- if(c2)\r
- {\r
- c2->SetSelection(sel);\r
- return;\r
- }\r
-\r
- // try a listbox\r
- wxListBox *l = wxDynamicCast(wnd, wxListBox);\r
- if(l)\r
- {\r
- l->SetSelection(sel);\r
- return;\r
- }\r
-\r
- /** \todo For custom controls we should put something in wxMultiTreeItemData class\r
- which can be overridden to retrieve the boolean value. It will also be passed\r
- the pointer to the window, so the derived class can figure out how to get a boolean\r
- value.\r
- */\r
-\r
- // generate assert or just return with string\r
- wxCHECK2(0, return);\r
-}\r
-\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::GetParent(wxTreeMultiItem const& item) const\r
-{\r
- // check if valid or root item has been passed, both do not have parents:\r
- if (!(item.IsOk()) || item.GetItem()->IsTreeMultiItemRoot())\r
- return wxTreeMultiItem();\r
- else\r
- return wxTreeMultiItem(item.GetItem()->GetParent()); // GetParent() returns a valid pointer in case of a root item!!\r
- // therefore, the check if the passed item is a root item is necessary\r
-} /* wxTreeMultiCtrl::GetParent(wxTreeMultiItem const& item) const */\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::GetFirstChild(const wxTreeMultiItem &item, int &cookie) const\r
-{\r
- if(item.IsNodeItem())\r
- {\r
- TreeMultiItemNode *n = (TreeMultiItemNode *)item.GetItem();\r
-\r
- if(n->GetNodeCount() > 0)\r
- {\r
- cookie = 0;\r
- return wxTreeMultiItem(n->GetNode(0));\r
- }\r
- }\r
-\r
- // no children or no valid node\r
- cookie = -1;\r
- return wxTreeMultiItem(0);\r
-}\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::GetNextChild(const wxTreeMultiItem &item, int &cookie) const\r
-{\r
- if(item.IsNodeItem())\r
- {\r
- TreeMultiItemNode *n = (TreeMultiItemNode *)item.GetItem();\r
-\r
- if(cookie >= 0 && cookie < (n->GetNodeCount()-1))\r
- {\r
- // increment cookie, return node\r
- cookie ++;\r
- return wxTreeMultiItem(n->GetNode(cookie));\r
- }\r
- }\r
-\r
- // end of query, or no valid node\r
- cookie = -1;\r
- return wxTreeMultiItem(0);\r
-}\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::GetLastChild(const wxTreeMultiItem &item) const\r
-{\r
- if(item.IsNodeItem())\r
- {\r
- TreeMultiItemNode *n = (TreeMultiItemNode *)item.GetItem();\r
-\r
- if(n->GetNodeCount() > 0)\r
- return wxTreeMultiItem(n->GetNode(n->GetNodeCount()-1));\r
- }\r
-\r
- return wxTreeMultiItem(0);\r
-}\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::GetNextSibling(wxTreeMultiItem const& item) const\r
-{\r
- // check if a valid item has been passed:\r
- if (!(item.IsOk()))\r
- return wxTreeMultiItem();\r
-\r
- TreeMultiItemNode* ParentPtr(item.GetItem()->GetParent());\r
-\r
-\r
- if (ParentPtr != NULL) // the parent pointer is only null if the passed item is the root\r
- {\r
- // find the current item in the parent's list; the next sibling has an index that is one higher than the one of the current item:\r
- int NextItemIndex(ParentPtr->Index(item.GetItem())+1); // variable definition and initialization\r
-\r
- if (NextItemIndex < ParentPtr->GetNodeCount())\r
- return ParentPtr->GetNode(NextItemIndex);\r
- else\r
- return wxTreeMultiItem();\r
- } /* if */\r
- else\r
- return wxTreeMultiItem();\r
-} /* wxTreeMultiCtrl::GetNextSibling(wxTreeMultiItem const&) const */\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::GetPrevSibling(wxTreeMultiItem const& item) const\r
-{\r
- // check if a valid item has been passed:\r
- if (!(item.IsOk()))\r
- return wxTreeMultiItem();\r
-\r
- TreeMultiItemNode* ParentPtr(item.GetItem()->GetParent());\r
-\r
-\r
- if (ParentPtr != NULL)\r
- {\r
- // find the current item in the parent's list; the next sibling has an index that is one higher than the one of the current item:\r
- int PrevItemIndex(ParentPtr->Index(item.GetItem())-1); // variable definition and initialization\r
-\r
- if (PrevItemIndex >= 0)\r
- return ParentPtr->GetNode(PrevItemIndex);\r
- else\r
- return wxTreeMultiItem();\r
- } /* if */\r
- else\r
- return wxTreeMultiItem();\r
-} /* wxTreeMultiCtrl::GetPrevSibling(wxTreeMultiItem const&) const */\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::GetNext(wxTreeMultiItem const& item) const\r
-{\r
- // check if a valid item has been passed:\r
- if (!(item.IsOk()))\r
- return wxTreeMultiItem();\r
-\r
- TreeMultiItemNode* NodePtr(item.GetItem()->IsTreeMultiItemNode()); // variable definition and initialization\r
-\r
- if ((NodePtr != NULL) && (NodePtr->GetNodeCount() > 0))\r
- return wxTreeMultiItem(NodePtr->First());\r
- else\r
- {\r
- // variable definitions and initializations:\r
- wxTreeMultiItem Parent(item);\r
- wxTreeMultiItem Sibling;\r
-\r
- do\r
- {\r
- Sibling = this->GetNextSibling(Parent); // try to find next sibling\r
- Parent = this->GetParent(Parent); // get next ancestor\r
- } while (!(Sibling.IsOk()) && Parent.IsOk());\r
- // in case the loop ended with Sibling.IsOk() "Sibling" contains a valid sibling otherwise an invalid\r
- return Sibling;\r
- } /* if */\r
-} /* wxTreeMultiCtrl::GetNextSibling(wxTreeMultiItem const&) const */\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::GetPrevious(wxTreeMultiItem const& item) const\r
-{\r
- // check if a valid item has been passed:\r
- if (!(item.IsOk()))\r
- return wxTreeMultiItem();\r
-\r
- TreeMultiItemNode* NodePtr(item.GetItem()->IsTreeMultiItemNode()); // variable definition and initialization\r
-\r
- if ((NodePtr != NULL) && (NodePtr->GetNodeCount() > 0))\r
- return wxTreeMultiItem(NodePtr->Last());\r
- else\r
- {\r
- // variable definitions and initializations:\r
- wxTreeMultiItem Parent(item);\r
- wxTreeMultiItem Sibling;\r
-\r
- do\r
- {\r
- Sibling = this->GetPrevSibling(Parent); // try to find next sibling\r
- Parent = this->GetParent(Parent); // get next ancestor\r
- } while (!(Sibling.IsOk()) && Parent.IsOk());\r
- // in case the loop ended with Sibling.IsOk() "Sibling" contains a valid sibling otherwise an invalid\r
- return Sibling;\r
- } /* if */\r
-} /* wxTreeMultiCtrl::GetPrevious(wxTreeMultiItem const&) const */\r
-\r
-// WDR: handler implementations for wxTreeMultiCtrl\r
-\r
-void wxTreeMultiCtrl::OnDraw(wxDC& dc)\r
-{\r
- // go recursive and draw the whole visible tree.\r
- dc.SetFont(_captionFont);\r
- for(int i = 0; i < _root.GetNodeCount(); i++)\r
- DrawNode(_root.GetNode(i), dc);\r
-} /* */\r
+//---------------------------------------------------------------------------
+// $RCSfile: wxTreeMultiCtrl.cpp,v $
+// $Source: /cvs/creatis/bbtk/kernel/src/ThirdParty/wx/treemultictrl/wxTreeMultiCtrl.cpp,v $
+// $Revision: 1.2 $
+// $Date: 2009/10/05 22:44:50 $
+//---------------------------------------------------------------------------
+// Author: Jorgen Bodde
+// Copyright: (c) Jorgen Bodde
+// License: wxWidgets License
+//---------------------------------------------------------------------------
+
+#ifdef __GNUG__
+ #pragma implementation "wxTreeMultiCtrl.h"
+#endif
+
+// For compilers that support precompilation, includes "wx/wx.h".
+#include "wx/wxprec.h"
+#include "wx/treebase.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#include "wx/arrimpl.cpp"
+
+#include "wx/treemultictrl/wxTreeMultiCtrl.h"
+#include "wx/treemultictrl/wxTreeMultiEvent.h"
+#include "tmcimages.h"
+
+
+
+//----------------------------------------------------------------------------
+// wxTreeMultiItem
+//----------------------------------------------------------------------------
+
+WX_DEFINE_OBJARRAY(wxArrayTreeMultiItem);
+
+//----------------------------------------------------------------------------
+// wxTreeMultiCtrl
+//----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxTreeMultiCtrl, wxScrolledWindow)
+
+// WDR: event table for wxTreeMultiCtrl
+BEGIN_EVENT_TABLE(wxTreeMultiCtrl, wxScrolledWindow)
+ EVT_LEFT_DOWN (wxTreeMultiCtrl::OnMouseClick)
+ EVT_LEFT_DCLICK(wxTreeMultiCtrl::OnMouseClick)
+ EVT_RIGHT_DOWN (wxTreeMultiCtrl::OnRightMouseClick)
+ EVT_PAINT(wxTreeMultiCtrl::OnPaint)
+ EVT_SIZE(wxTreeMultiCtrl::OnSize)
+// EVT_KEY_UP(wxTreeMultiCtrl::OnKey)
+END_EVENT_TABLE()
+
+bool wxTreeMultiCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos,
+ const wxSize& size, long style, const wxValidator & WXUNUSED(validator),
+ const wxString& name )
+{
+ wxScrolledWindow::Create( parent, id, pos, size, style | wxTAB_TRAVERSAL, name);
+
+ _create_called = true;
+
+ // do the init
+ Init();
+
+ return TRUE;
+}
+
+void wxTreeMultiCtrl::Init()
+{
+ _root.Clear();
+
+ _expandBmp = 0;
+ _collBmp = 0;
+
+#if(CHECKBOXVIEW)
+ _checkBmp = 0;
+ _uncheckBmp = 0;
+ _tristateBmp = 0;
+
+ _checkHeight = 11;
+ _checkWidth = 11;
+
+ _checkboxView = false;
+#endif
+
+ _gutterWidth = WXTMC_GUTTER_DEFAULT;
+ _iconWidth = 11;
+ _iconHeight = 11;
+ _maxHeight = 1;;
+ _iconDeltaY = 2;
+ _spacingY = WXTMC_YSPACING_DEFAULT;
+ _captionHeight = 13;
+
+ // create two bitmap nodes for drawing
+
+ _expandBmp = new wxBitmap(expand_xpm);
+ _collBmp = new wxBitmap(collapse_xpm);
+
+ // calculate average font height for bitmap centering
+
+ _iconWidth = _expandBmp->GetWidth();
+ _iconHeight = _expandBmp->GetHeight();
+
+#if(CHECKBOXVIEW)
+ // create bitmaps for checkboxes
+ _checkBmp = new wxBitmap(checked_icon);
+ _uncheckBmp = new wxBitmap(unchecked_icon);
+ _tristateBmp = new wxBitmap(tristate_icon);
+
+ // adjust the height if the checkboxes are higher
+ // so that everything is alligned properly
+ _checkHeight = _checkBmp->GetHeight();
+ _checkWidth = _checkBmp->GetWidth();
+#endif
+
+ // remember the highest of the two bitmaps so there is
+ // always enough room
+ _maxHeight = _iconHeight;
+
+#if(CHECKBOXVIEW)
+ if(_maxHeight < _checkHeight)
+ _maxHeight = _checkHeight;
+#endif
+
+ // set standard highlighting brush
+ this->m_HilightBrush = new wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT),wxSOLID);
+
+ // set standard DC font
+ _captionFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
+
+ // adjust bitmap icon y position so they are centered
+ AdjustIconsDeltaY();
+
+ // set virtual size to this window size
+ if (_create_called) {
+ wxSize wndsize = GetSize();
+ SetVirtualSize(wndsize.GetWidth(), wndsize.GetWidth());
+ }
+}
+
+void wxTreeMultiCtrl::SetCaptionFont(const wxFont &font)
+{
+ _captionFont = font;
+
+ // adjust the icons so that they are in the middle
+ AdjustIconsDeltaY();
+
+ RedrawFromNode(0);
+};
+
+void wxTreeMultiCtrl::AdjustIconsDeltaY()
+{
+ int x = 0, y = 0;
+
+ if(_captionFont.Ok())
+ GetTextExtent(wxT("jG"), &x, &y, 0, 0, &_captionFont);
+ _captionHeight = y;
+
+ if(_maxHeight < _captionHeight)
+ _maxHeight = _captionHeight;
+
+ // determine the center pos for the [+]
+ _iconDeltaY = abs(_maxHeight - _iconHeight) / 2 + 1;
+ if(_iconDeltaY < 1)
+ _iconDeltaY = 1;
+
+#if(CHECKBOXVIEW)
+ // determine the center pos for the checkbox
+ _checkDeltaY = abs(_maxHeight - _checkHeight) / 2 + 1;
+ if(_checkDeltaY < 1)
+ _checkDeltaY = 1;
+#endif
+}
+
+wxTreeMultiCtrl::~wxTreeMultiCtrl()
+{
+ // delete the bitmap resources
+ delete _expandBmp;
+ delete _collBmp;
+
+#if(CHECKBOXVIEW)
+ delete _checkBmp;
+ delete _uncheckBmp;
+ delete _tristateBmp;
+#endif
+}
+
+wxTreeMultiItem wxTreeMultiCtrl::AddRoot(const wxString &caption, const wxString &name)
+{
+ wxTreeMultiItem result((TreeMultiItemBase *)&_root);
+ result = AppendNode(result, caption, name);
+
+ return result;
+}
+
+wxTreeMultiItem wxTreeMultiCtrl::AppendWindow(const wxTreeMultiItem &ParentItem, wxWindow *window, const wxString &name, const wxTreeMultiWindowInfo &info, int flags)
+{
+ // add window only if the parent item is valid and...
+ wxCHECK(ParentItem.IsOk(), wxTreeMultiItem(0));
+
+ TreeMultiItemNode* parent = ParentItem.GetItem()->IsTreeMultiItemNode(); // also roots are nodes
+
+ // ... is a node
+ wxCHECK(parent != NULL, wxTreeMultiItem(0));
+
+ // now, append node to the tree control:
+ wxTreeMultiItem NewWindowItem(this->InsertWindow(parent,wx_static_cast(size_t,parent->GetNodeCount()),window,name,info,flags));
+ // redraw the stucture:
+ this->RedrawFromNode(parent);
+ // return the new window
+ return NewWindowItem;
+}
+
+wxTreeMultiItem wxTreeMultiCtrl::InsertWindow(wxTreeMultiItem const& ParentItem, size_t Position, wxWindow *window, wxString const& name, wxTreeMultiWindowInfo const& info, int flags)
+{
+ // add window only if the parent item is valid and...
+ wxCHECK(ParentItem.IsOk(), wxTreeMultiItem(0));
+
+ TreeMultiItemNode* parent = ParentItem.GetItem()->IsTreeMultiItemNode(); // also roots are nodes
+
+ // ... is a node
+ wxCHECK(parent != NULL, wxTreeMultiItem(0));
+
+ // now, append node to the tree control:
+ wxTreeMultiItem NewWindowItem(this->InsertWindow(parent,Position,window,name,info,flags));
+ // redraw the stucture:
+ this->RedrawFromNode(parent);
+ // return the new window
+ return NewWindowItem;
+} /* wxTreeMultiCtrl::InsertWindow(wxTreeMultiItem const&, size_t, wxWindow*, wxString const&, wxTreeMultiWindowInfo const&, int) */
+
+wxTreeMultiItem wxTreeMultiCtrl::PrependWindow(wxTreeMultiItem const& ParentItem, wxWindow *window, const wxString &name, wxTreeMultiWindowInfo const& info, int flags)
+{
+ // add window only if the parent item is valid and...
+ wxCHECK(ParentItem.IsOk(), wxTreeMultiItem(0));
+
+ TreeMultiItemNode* parent = ParentItem.GetItem()->IsTreeMultiItemNode(); // also roots are nodes
+
+ // ... is a node
+ wxCHECK(parent != NULL, wxTreeMultiItem(0));
+
+ // now, append node to the tree control:
+ wxTreeMultiItem NewWindowItem(this->InsertWindow(parent,0,window,name,info,flags));
+ // redraw the stucture:
+ this->RedrawFromNode(parent);
+ // return the new window
+ return NewWindowItem;
+} /* wxTreeMultiCtrl::PrependWindow(wxTreeMultiItem const&, wxWindow*, const wxString &, wxTreeMultiWindowInfo const&, int) */
+
+wxTreeMultiItem wxTreeMultiCtrl::AppendNode(wxTreeMultiItem const& ParentItem, const wxString &caption, const wxString &name)
+{
+ // add window only if the parent item is valid and...
+ wxCHECK(ParentItem.IsOk(), wxTreeMultiItem(0));
+
+ TreeMultiItemNode* parent = ParentItem.GetItem()->IsTreeMultiItemNode(); // also roots are nodes
+
+ // ... is a node
+ wxCHECK(parent != NULL, wxTreeMultiItem(0));
+
+ // now, append node to the tree control:
+ wxTreeMultiItem NewNodeItem(this->InsertNode(parent,wx_static_cast(size_t,parent->GetNodeCount()),caption,name));
+ // redraw the structure:
+ this->RedrawFromNode(parent);
+ // return the new node:
+ return NewNodeItem;
+} /* wxTreeMultiCtrl::AppendNode(wxTreeMultiItem const&, const wxString &, const wxString&) */
+
+wxTreeMultiItem wxTreeMultiCtrl::InsertNode(wxTreeMultiItem const& ParentItem, size_t Position, wxString const& caption, wxString const& name)
+{
+ // add window only if the parent item is valid and...
+ wxCHECK(ParentItem.IsOk(), wxTreeMultiItem(0));
+
+ TreeMultiItemNode* parent = ParentItem.GetItem()->IsTreeMultiItemNode(); // also roots are nodes
+
+ // ... is a node
+ wxCHECK(parent != NULL, wxTreeMultiItem(0));
+
+ // now, append node to the tree control:
+ wxTreeMultiItem NewNodeItem(this->InsertNode(parent,Position,caption,name));
+ // redraw the structure:
+ this->RedrawFromNode(parent);
+ // return the new node:
+ return NewNodeItem;
+} /* wxTreeMultiCtrl::InsertNode(wxTreeMultiItem const&, size_t, wxString const&, wxString const&) */
+
+wxTreeMultiItem wxTreeMultiCtrl::PrependNode(wxTreeMultiItem const& ParentItem, wxString const& caption, wxString const& name)
+{
+ // add window only if the parent item is valid and...
+ wxCHECK(ParentItem.IsOk(), wxTreeMultiItem(0));
+
+ TreeMultiItemNode* parent = ParentItem.GetItem()->IsTreeMultiItemNode(); // also roots are nodes
+
+ // ... is a node
+ wxCHECK(parent != NULL, wxTreeMultiItem(0));
+
+ // now, append node to the tree control:
+ wxTreeMultiItem NewNodeItem(this->InsertNode(parent,0,caption,name));
+ // redraw the structure:
+ this->RedrawFromNode(parent);
+ // return the new node:
+ return NewNodeItem;
+} /* wxTreeMultiCtrl::PrependNode(wxTreeMultiItem const&, wxString const&, wxString const&) */
+
+bool wxTreeMultiCtrl::Delete(wxTreeMultiItem &item)
+{
+ bool redraw = true;
+ wxCHECK(item.IsOk(), false);
+
+ wxTreeMultiItem nullItem(0);
+
+
+ // if item has been selected, remove it from the selected list:
+ size_t ItemIndex(this->GetSelectedItemIndex(item));
+
+ if (ItemIndex != this->GetSelectedItemCount())
+ this->m_SelectedItems.RemoveAt(ItemIndex);
+
+ // get parent, to delete item from
+ TreeMultiItemNode *p = item.GetItem()->GetParent();
+
+ // first check if it was visible, if so from the parent off
+ // it needs redrawing
+ redraw = item.GetItem()->IsVisible();
+ if(p)
+ p->DeleteNode(item.GetItem());
+ else
+ _root.DeleteNode(item.GetItem());
+
+ item = nullItem;
+
+ // do redraw when node was visible
+ if(redraw)
+ RedrawFromNode(p);
+
+ return true;
+}
+
+void wxTreeMultiCtrl::DeleteChildren(const wxTreeMultiItem &item)
+{
+ if(item.IsNodeItem())
+ {
+ TreeMultiItemNode *n = (TreeMultiItemNode *)item.GetItem();
+
+ // remove all children from the selected item list:
+ if (n->GetNodeCount() > 0)
+ {
+ // variable definitions and initializations:
+ int Cookie;
+ wxTreeMultiItem FirstItemIterator(this->GetFirstChild(item,Cookie)), LastItemIterator(this->GetLastChild(item));
+
+ for (;;)
+ {
+ size_t ItemIndex(this->GetSelectedItemIndex(item)); // variable definition and initialization
+
+ if (ItemIndex != this->GetSelectedItemCount())
+ this->m_SelectedItems.RemoveAt(ItemIndex);
+ if (FirstItemIterator == LastItemIterator)
+ break; // all children checked
+ else
+ FirstItemIterator = this->GetNext(FirstItemIterator);
+ } /* for */
+ } /* if */
+ // delete children:
+ n->Clear();
+ // redraw:
+ RedrawFromNode(n);
+ }
+}
+
+void wxTreeMultiCtrl::Expand(const wxTreeMultiItem &item, bool recursive)
+{
+ if(item.IsOk())
+ {
+ TreeMultiItemNode *n = item.GetItem()->IsTreeMultiItemNode();
+ if(!n)
+ n = item.GetItem()->GetParent();
+ DoFold(n, true, recursive);
+ RedrawFromNode(item.GetItem()->IsTreeMultiItemNode());
+ }
+}
+
+void wxTreeMultiCtrl::Collapse(const wxTreeMultiItem &item, bool recursive)
+{
+ if(item.IsOk())
+ {
+ TreeMultiItemNode *n = item.GetItem()->IsTreeMultiItemNode();
+ if(!n)
+ n = item.GetItem()->GetParent();
+ DoFold(n, false, recursive);
+ RedrawFromNode(item.GetItem()->IsTreeMultiItemNode());
+ }
+}
+
+
+void wxTreeMultiCtrl::ExpandNodes(bool recursive)
+{
+ // go through all children and call DoFold recursively
+ for(int i = 0; i < _root.GetNodeCount(); i++)
+ DoFold(_root.GetNode(i), true, recursive);
+ RedrawFromNode(0);
+}
+
+void wxTreeMultiCtrl::CollapseNodes(bool recursive)
+{
+ // go through all children and call DoFold recursively
+ for(int i = 0; i < _root.GetNodeCount(); i++)
+ DoFold(_root.GetNode(i), false, recursive);
+ RedrawFromNode(0);
+}
+
+void wxTreeMultiCtrl::CollapseAndReset(const wxTreeMultiItem &item)
+{
+ if(item.IsNodeItem())
+ {
+ TreeMultiItemNode *n = (TreeMultiItemNode *)item.GetItem();
+
+ // delete all kids
+ n->Clear();
+ Collapse(item, false);
+ }
+}
+
+// Selection manipulation
+wxTreeMultiItem wxTreeMultiCtrl::GetFirstSelectedItem(void) const
+{
+ if (this->GetSelectedItemCount() > 0)
+ return this->m_SelectedItems[0];
+ else
+ return wxTreeMultiItem();
+} /* wxTreeMultiCtrl::GetFirstSelectedItem(void) const */
+
+wxTreeMultiItem wxTreeMultiCtrl::GetLastSelectedItem(void) const
+{
+ if (this->GetSelectedItemCount() > 0)
+ return this->m_SelectedItems[this->GetSelectedItemCount()-1];
+ else
+ return wxTreeMultiItem();
+} /* wxTreeMultiCtrl::GetLastSelectedItem(void) const */
+
+wxTreeMultiItem wxTreeMultiCtrl::GetSelectedItem(size_t Index) const
+{
+ if (Index < this->GetSelectedItemCount())
+ return this->m_SelectedItems[Index];
+ else
+ return wxTreeMultiItem();
+} /* wxTreeMultiCtrl::GetSelectedItem(size_t Index) const */
+
+size_t wxTreeMultiCtrl::GetSelectedItemIndex(wxTreeMultiItem const& Item) const
+{
+ // attention: the function wxArray::Index() can NOT be used in a save manner as it only checks the address of an item
+ // element but it is not guaranteed that Item may not be a copy of the originally inserted item
+ const size_t NoOfSelectedItems = this->GetSelectedItemCount();
+
+ size_t Index(0);
+
+
+ while ((Index < NoOfSelectedItems) && (this->m_SelectedItems[Index] != Item))
+ ++Index;
+ return Index;
+} /* wxTreeMultiCtrl::GetSelectedItemIndex(wxTreeMultiItem const&) const */
+
+void wxTreeMultiCtrl::SelectItem(wxTreeMultiItem const& Item, bool UnselectOthers, bool ExpandSelection)
+{
+ TreeMultiItemNode* NodePtr(Item.GetItem()->IsTreeMultiItemNode());
+
+
+ // only nodes can be selected and they can only be selected if they are not already selected:
+ if ((NodePtr == NULL) || NodePtr->IsSelected())
+ return;
+
+ // inform that we are about to change:
+ wxTreeMultiEvent Event(wxEVT_COMMAND_TREE_MULTI_SEL_CHANGING,Item); // variable definition and initialization
+
+ if (this->m_SelectedItems.GetCount() > 0) // the last item in the array is always the latest inserted item
+ Event.SetOldItem(this->m_SelectedItems.Last());
+ Event.SetEventObject(this);
+ if (this->GetEventHandler()->ProcessEvent(Event) && !(Event.IsAllowed()))
+ return; // vetoed
+
+ // make sure that the to be selected item can be seen:
+ this->Include(Item);
+
+ // variable definition and initialization:
+ wxTreeMultiItem ExcludedParent(this->GetExcludedParent(Item));
+
+ while (ExcludedParent.IsOk())
+ {
+ this->Include(ExcludedParent);
+ ExcludedParent = this->GetExcludedParent(Item);
+ } /* while */
+
+ // unselect items if necessary:
+ if (UnselectOthers)
+ this->UnselectAll();
+ // expand selection if necessary:
+ if (ExpandSelection)
+ {
+ // variable definition:
+ wxTreeMultiItem FirstItemIterator, LastItemIterator;
+ wxTreeMultiItem LastSelectedItem;
+
+ // determine the last selected item or the first item in case nothing has been selected before:
+ if (this->m_SelectedItems.GetCount() > 0)
+ LastSelectedItem = this->m_SelectedItems.Last();
+ else
+ LastSelectedItem = this->GetFirstRoot();
+ // determine the item from which to start and the one with which to end the selection:
+ if (Item.GetItem()->GetY() > LastSelectedItem.GetItem()->GetY())
+ {
+ FirstItemIterator = LastSelectedItem;
+ LastItemIterator = Item;
+ } /* if */
+ else
+ {
+ FirstItemIterator = Item;
+ LastItemIterator = LastSelectedItem;
+ } /* if */
+ // select all items that are a node and are placed between the two limiting iterators (included the limits):
+ for (;;)
+ {
+ if (!(FirstItemIterator.IsSelected()) && FirstItemIterator.IsNodeItem())
+ {
+ FirstItemIterator.GetItem()->Select();
+ this->m_SelectedItems.Add(FirstItemIterator);
+ this->RefreshRect(wxRect(FirstItemIterator.GetItem()->GetX(), FirstItemIterator.GetItem()->GetY(),
+ FirstItemIterator.GetItem()->GetWidth(),FirstItemIterator.GetItem()->GetHeight()));
+ } /* if */
+ if (FirstItemIterator == LastItemIterator)
+ break; // done
+ // continue iterating:
+ FirstItemIterator = this->GetNext(FirstItemIterator);
+ } /* for */
+ } /* if */
+ else // select passed item only
+ {
+ NodePtr->Select();
+ this->m_SelectedItems.Add(NodePtr);
+ this->RefreshRect(wxRect(NodePtr->GetX(),NodePtr->GetY(),NodePtr->GetWidth(),NodePtr->GetHeight()));
+ } /* if */
+
+ // inform that we have selected the item:
+ Event.SetEventType(wxEVT_COMMAND_TREE_MULTI_SEL_CHANGED);
+ this->GetEventHandler()->ProcessEvent(Event);
+} /* wxTreeMultiCtrl::SelectItem(wxTreeMultiItem const&, bool, bool) */
+
+void wxTreeMultiCtrl::UnselectAll(void)
+{
+ const size_t NoOfSelectedItems = this->m_SelectedItems.GetCount();
+
+
+ for (size_t i=0; i<NoOfSelectedItems; ++i)
+ {
+ this->RefreshRect(wxRect(this->m_SelectedItems[i].GetItem()->GetX(), this->m_SelectedItems[i].GetItem()->GetY(),
+ this->m_SelectedItems[i].GetItem()->GetWidth(),this->m_SelectedItems[i].GetItem()->GetHeight()));
+ this->m_SelectedItems[i].GetItem()->Unselect();
+ } /* for */
+ this->m_SelectedItems.Clear();
+} /* wxTreeMultiCtrl::UnselectAll(void) */
+
+void wxTreeMultiCtrl::Unselect(wxTreeMultiItem const& Item)
+{
+ size_t ItemIndex(this->GetSelectedItemIndex(Item));
+
+
+ if (ItemIndex != this->GetSelectedItemCount())
+ {
+ Item.GetItem()->Unselect();
+ this->m_SelectedItems.RemoveAt(ItemIndex);
+ this->RefreshRect(wxRect(Item.GetItem()->GetX(),Item.GetItem()->GetY(),Item.GetItem()->GetWidth(),Item.GetItem()->GetHeight()));
+ } /* if */
+} /* wxTreeMultiCtrl::Unselect(wxTreeMultiItem const&) */
+
+void wxTreeMultiCtrl::DoFold(TreeMultiItemBase *item, bool expand, bool recursive)
+{
+
+ // go through all node objects on this level, and expand or
+ // collapse them
+
+ if(item == 0)
+ return;
+
+ // if this is a node, use it to go through all the subnodes (if needed)
+ // if not, then just exit.
+
+ TreeMultiItemNode *node = item->IsTreeMultiItemNode();
+ if(node)
+ {
+ node->Fold(expand);
+
+ // go recursive
+ if(recursive)
+ {
+ TreeMultiItemNode *p;
+ for(int i = 0; i < node->GetNodeCount(); i++)
+ {
+ // get node, and if a real node, then call fold
+ p = node->GetNode(i)->IsTreeMultiItemNode();
+ if(p)
+ p->Fold(expand);
+
+ // go recursive for every node
+ DoFold(p, expand, recursive);
+ }
+ }
+ }
+}
+
+void wxTreeMultiCtrl::Exclude(const wxTreeMultiItem &item)
+{
+ wxCHECK2(item.IsOk(), return);
+
+ // exclude the item, and refresh
+ // if already excluded, skip
+
+ if(!item.GetItem()->IsExcluded())
+ {
+ item.GetItem()->SetExcluded(true);
+ RedrawFromParentNode(item.GetItem());
+ }
+}
+
+void wxTreeMultiCtrl::Include(const wxTreeMultiItem &item)
+{
+ wxCHECK2(item.IsOk(), return);
+
+ // include the item, and refresh. If not
+ // excluded, do nothing
+
+ if(item.GetItem()->IsExcluded())
+ {
+ item.GetItem()->SetExcluded(false);
+ RedrawFromParentNode(item.GetItem());
+ }
+}
+
+wxTreeMultiItem wxTreeMultiCtrl::GetExcludedParent(const wxTreeMultiItem &item)
+{
+ wxCHECK(item.IsOk(), wxTreeMultiItem(0));
+
+ // go find the parent (including this one) that
+ // can be the excluded one
+
+ TreeMultiItemNode *n = item.GetItem()->IsTreeMultiItemNode();
+ if(n && n->IsExcluded())
+ return wxTreeMultiItem(n);
+
+ n = item.GetItem()->GetParent();
+ while(n)
+ {
+ if(n->IsExcluded())
+ return wxTreeMultiItem(n);
+ else
+ n = n->GetParent();
+ }
+
+ return wxTreeMultiItem(0);
+}
+
+void wxTreeMultiCtrl::OnSize(wxSizeEvent &WXUNUSED(event))
+{
+ RecalculateSpanSizes();
+}
+
+void wxTreeMultiCtrl::OnPaint(wxPaintEvent& WXUNUSED(event) )
+{
+ wxPaintDC dc(this);
+
+ PrepareDC(dc);
+
+ // go recursive and draw the whole visible tree.
+ dc.SetFont(_captionFont);
+ for(int i = 0; i < _root.GetNodeCount(); i++)
+ DrawNode(_root.GetNode(i), dc);
+}
+
+void wxTreeMultiCtrl::DrawNode(TreeMultiItemBase *b, wxDC &dc)
+{
+ // go through this item .. if it is a node, draw
+ // the caption, else reposition the window.
+
+ if(!b)
+ return;
+
+ // forget it if this node is not visible
+ if(b->IsVisible())
+ {
+ int bmpOffsetX = b->GetX() - (_gutterWidth + _iconWidth);
+
+#if(CHECKBOXVIEW)
+ // now draw the checkbox if there is any, in the proper state
+ if(b->GetCheckbox())
+ {
+ DrawCheckbox(b, dc);
+
+ // adjust the bmpOffset because we also have a checkbox
+ bmpOffsetX -= _checkWidth;
+ }
+#endif
+
+ if(b->IsTreeMultiItemNode())
+ {
+ // draw the node icon and the caption
+ TreeMultiItemNode *n = (TreeMultiItemNode *)b;
+
+ // set background of caption item
+ if (n->IsSelected())
+ {
+ dc.SetBrush(*(this->m_HilightBrush));
+ dc.SetPen(wxPen(this->m_HilightBrush->GetColour(),1,wxSOLID));
+ } /* if */
+ else
+ {
+ dc.SetBrush(wxBrush(*wxWHITE,wxSOLID));
+ dc.SetPen(wxPen(*wxWHITE,1,wxSOLID));
+ } /* if */
+ dc.DrawRectangle(n->GetX(),n->GetY(),n->GetWidth(),n->GetHeight());
+ // draw caption
+ dc.DrawText(n->GetCaption(), n->GetX(), n->GetY());
+
+ // draw the bitmap for the state
+ if(n->IsExpanded())
+ dc.DrawBitmap(*_expandBmp, bmpOffsetX, n->GetY() + _iconDeltaY, true);
+ else
+ dc.DrawBitmap(*_collBmp, bmpOffsetX, n->GetY() + _iconDeltaY, true);
+
+ // now go through all the subnodes
+ for(int i = 0; i < n->GetNodeCount(); i++)
+ DrawNode(n->GetNode(i), dc);
+
+ }
+ }
+}
+
+#if(CHECKBOXVIEW)
+
+void wxTreeMultiCtrl::DrawCheckbox(TreeMultiItemBase *b, wxDC &dc, bool convertScrolled)
+{
+ wxCHECK2(b, return);
+
+ wxBitmap *bmp;
+ int bmpOffsetX = b->GetX() - (_gutterWidth + _iconWidth);
+
+ switch(b->GetCheckboxState())
+ {
+ case 0:
+ bmp = _uncheckBmp;
+ break;
+ case 1:
+ bmp = _checkBmp;
+ break;
+ default:
+ bmp = _tristateBmp;
+ break;
+ }
+
+ int x, xx, y, yy;
+
+ if(b->IsTreeMultiItemWindow())
+ {
+ xx = x = bmpOffsetX - ((TreeMultiItemWindow *)b)->GetFrontSpacing() + _checkWidth;
+ yy = y = b->GetY() + _checkDeltaY;
+ }
+ else
+ {
+ xx = x = bmpOffsetX;
+ yy = y = b->GetY() + _checkDeltaY;
+ }
+
+ if(convertScrolled)
+ CalcScrolledPosition(x, y, &xx, &yy);
+
+ dc.DrawBitmap(*bmp, xx, yy, true);
+}
+
+#endif // #if(CHECKBOXVIEW)
+
+void wxTreeMultiCtrl::OnKey(wxKeyEvent &event)
+{
+ // check if we need to traverse to upper or lower
+ // control in the list
+ if(event.GetKeyCode() == WXK_TAB)
+ {
+ wxTreeMultiItem item = GetFocus();
+ if(item.IsOk())
+ {
+ // traverse down direction
+ if(!event.ShiftDown())
+ item = FindNextVisibleWindowItem(item.GetItem());
+ //else // traverse in up direction
+ // item = FindPreviousVisibleWindowItem(item);
+
+ if(item.IsOk())
+ {
+ TreeMultiItemWindow *w = item.GetItem()->IsTreeMultiItemWindow();
+ if(w)
+ {
+ wxWindow *wnd = w->GetWindow();
+ wnd->SetFocus();
+ }
+ }
+ }
+ }
+ else
+ event.Skip();
+}
+
+void wxTreeMultiCtrl::OnMouseClick( wxMouseEvent &event )
+{
+ // react on double click and left mouse down
+ if(event.LeftDown() || event.LeftDClick())
+ {
+ // get translation point
+ wxPoint pt( event.GetPosition() );
+
+ int x = 0, y = 0;
+ CalcUnscrolledPosition( pt.x, pt.y, &x, &y );
+
+ // go check if we clicked a treenode
+ int flags;
+ wxPoint p(x,y);
+ wxTreeMultiItem id = HitTest(p, flags);
+
+#if(CHECKBOXVIEW)
+ if(flags == wxTMC_HITTEST_CHECKBOX)
+ {
+ // toggle the checkbox, and redraw
+ if(id.IsOk())
+ {
+ TreeMultiItemBase *b = id.GetItem();
+ b->SetCheckboxState((b->GetCheckboxState()+1) & 0x1);
+
+ TreeMultiItemWindow *w = b->IsTreeMultiItemWindow();
+ if(w)
+ {
+ // try to force a focus on the window. This could
+ // be extended by searching for the first edit control
+ // class but for now, just a focus is tried.
+ w->GetWindow()->Enable(b->GetCheckboxState() == 1);
+ w->GetWindow()->SetFocus();
+
+ // draw the checkbox in the state needed
+ wxClientDC dc(this);
+ DrawCheckbox(b, dc, true);
+
+ // TODO: determine if the upper parents should be
+ // tristated or not
+
+ ScanTristateCheckstates(b);
+
+ }
+ else if(b->IsTreeMultiItemNode())
+ {
+ // descend to all the children and set the state of the parent
+ SetRecursiveCheckState((TreeMultiItemNode *)b, b->GetCheckboxState() == 1);
+ RedrawFromNode((TreeMultiItemNode *)b);
+ }
+ }
+ }
+ else
+#endif // #if(CHECKBOXVIEW)
+ {
+ // react on left mouse button, to fold and on
+ // right for caption doubleclick
+ int area = -1;
+
+// adjust behaviour for Linux (single click = always fold)
+#ifndef LINUX
+ if(event.LeftDClick())
+ area = wxTMC_HITTEST_CAPTION;
+ else
+ area = wxTMC_HITTEST_GUTTER;
+#else
+ area = flags;
+#endif
+
+// Linux (single or double click -> always fold
+ if (id.IsOk())
+ {
+#ifdef LINUX
+ // we have a valid item, if it is a node, then fold
+ TreeMultiItemNode *n = id.GetItem()->IsTreeMultiItemNode();
+ if(n)
+ {
+ this->SelectItem(id);
+ Fold(n, !n->IsExpanded());
+ } /* if */
+#else
+ if (event.LeftDown())
+ if (flags == wxTMC_HITTEST_GUTTER)
+ {
+ TreeMultiItemNode *n = id.GetItem()->IsTreeMultiItemNode(); // for some reasons also windows may have set the flag
+
+ if (n != NULL)
+ Fold(n, !n->IsExpanded());
+ } /* if */
+ else if (flags == wxTMC_HITTEST_CAPTION)
+ {
+ TreeMultiItemNode *n = id.GetItem()->IsTreeMultiItemNode(); // for some reasons also windows may have set the flag
+
+ if (n != NULL)
+ {
+ this->SelectItem(id);
+ this->RedrawFromNode(n);
+ } /* if */
+ } /* if */
+#endif
+ } /* if */
+ else
+ this->UnselectAll();
+ }
+ }
+}
+
+void wxTreeMultiCtrl::OnRightMouseClick(wxMouseEvent& Event)
+{
+ if (Event.RightDown())
+ if (Event.Dragging())
+ this->UnselectAll();
+ else
+ {
+ // variable definitions:
+ int Flags;
+ wxPoint Point;
+
+ // translate mouse coordinates:
+ CalcUnscrolledPosition(Event.GetPosition().x,Event.GetPosition().y,&(Point.x),&(Point.y));
+ // check if the mouse is above the caption of an item:
+ wxTreeMultiItem Item(this->HitTest(Point,Flags)); // variable definition and initialization
+
+ if (Item.IsOk() && (Flags == wxTMC_HITTEST_CAPTION))
+ {
+ this->SelectItem(Item);
+ this->RedrawFromNode(Item.GetItem()->IsTreeMultiItemNode());
+ Event.Skip(); // window will convert right mouse click to a context menu event or proceed with
+ // a right mouse click event if the context menu event cannot be processed
+ } /* if */
+ else
+ this->UnselectAll();
+ } /* if */
+ else
+ this->UnselectAll();
+} /* wxTreeMultiCtrl::OnRightMouseClick(wxMouseEvent&) */
+
+wxTreeMultiItem wxTreeMultiCtrl::HitTest(wxPoint const& pt, int &flags)
+{
+ // scan all nodes to see which one matches
+ TreeMultiItemBase *b = 0;
+ for(int i = 0; i < _root.GetNodeCount() && !b; i++)
+ b = FindNodeByPoint(_root.GetNode(i), pt, flags);
+
+ if(!b)
+ {
+ // none found, reset
+ flags = 0;
+ return wxTreeMultiItem(0);
+ }
+
+ // return an item
+ return wxTreeMultiItem(b);
+}
+
+TreeMultiItemBase *wxTreeMultiCtrl::FindNodeByPoint(TreeMultiItemBase *b, wxPoint const& pt, int &area)
+{
+ wxCHECK(b, 0);
+
+ // if this layer is not visible, return with nothing.
+ if(!b->IsVisible())
+ return 0;
+
+ area = 0;
+
+ // now see if our y is matching the mouse
+ if(pt.y >= b->GetY() && pt.y < (b->GetY() + b->GetHeight()))
+ {
+#if(CHECKBOXVIEW)
+ // if we are checkboxed, calculate the checkbox position
+ if(b->GetCheckbox())
+ {
+ int extraSpacing = 0, extraWidth = 0;
+
+ // now for a windows item, this is minus the gutter. For a normal node it is X minus checkbox
+ if(b->IsTreeMultiItemWindow())
+ {
+ extraWidth = _checkWidth;
+ extraSpacing = ((TreeMultiItemWindow *)b)->GetFrontSpacing();
+ }
+ else
+ extraSpacing = 4;
+
+ if(pt.x > (b->GetX() - extraSpacing - _checkWidth) && pt.x < (b->GetX() - extraSpacing + extraWidth))
+ {
+ area = wxTMC_HITTEST_CHECKBOX;
+ return b;
+ }
+ }
+#endif
+
+ // allrighty we have something, now where and what is it (look with x)
+ if(pt.x < b->GetX())
+ area = wxTMC_HITTEST_GUTTER;
+
+ /** \todo Match only the real part of the caption, window (we assume x > GetX() which is the rest)
+ HOWEVER the window probably doesn't propagate the click event back to the parent, so we might
+ leave it like this so the use can click behind a window so it will be selected.
+ */
+ else
+ {
+ // inside area, return proper flag
+ if(b->IsTreeMultiItemNode())
+ area = wxTMC_HITTEST_CAPTION;
+ else
+ area = wxTMC_HITTEST_WINDOW;
+ }
+
+ return b;
+ }
+ else
+ {
+ // not found, let's try our children if we have some
+ TreeMultiItemNode *n = b->IsTreeMultiItemNode();
+ if(n)
+ {
+ TreeMultiItemBase *bb = 0;
+ for(int i = 0; i < n->GetNodeCount() && !bb; i++)
+ bb = FindNodeByPoint(n->GetNode(i), pt, area);
+
+ // keep returning result to caller
+ return bb;
+ }
+ }
+
+ return 0;
+}
+
+wxTreeMultiItem wxTreeMultiCtrl::GetFocus()
+{
+ wxWindow *wnd = wxWindow::FindFocus();
+
+ // now find window that holds this item. if not
+ // visible it cannot have focus (should not have)
+
+ wxTreeMultiItem item = FindWindowNode(wnd);
+ if(item.IsOk() && item.GetItem()->IsVisible())
+ return item;
+
+ return wxTreeMultiItem(0);
+}
+
+#if(CHECKBOXVIEW)
+
+void wxTreeMultiCtrl::SetRecursiveCheckState(TreeMultiItemNode *n, bool check)
+{
+ int state = 0;
+ if(check)
+ state++;
+
+ // go check all kids on this level
+ for(int i = 0; i < n->GetNodeCount(); i++)
+ {
+ // check all the nodes, and go deeper
+ n->GetNode(i)->SetCheckboxState(state);
+ if(n->GetNode(i)->IsTreeMultiItemNode())
+ SetRecursiveCheckState((TreeMultiItemNode *)n->GetNode(i), check);
+ }
+}
+
+void wxTreeMultiCtrl::ScanTristateCheckstates(TreeMultiItemBase *b)
+{
+ // check from the parent on, all node entries and see if they are
+ // checked or cleared or scattered
+ TreeMultiItemNode *p = b->GetParent();
+
+ if(p && p->GetCheckbox())
+ {
+ bool foundcheck = false, foundclear = false;
+ for(size_t i = 0; i < (size_t)p->GetNodeCount(); ++i)
+ {
+ // only evaluate when checkboxed
+ if(p->GetNode(i)->IsTreeMultiItemWindow() && p->GetNode(i)->GetCheckbox())
+ {
+ // record instance of a cleared checkbox
+ if(!p->GetNode(i)->GetCheckboxState())
+ foundclear = true;
+ // record instance of checked checkbox
+ if(p->GetNode(i)->GetCheckboxState() == 1)
+ foundcheck = true;
+ }
+ }
+
+ // if we have both check and clear, go tristate
+ // if all clear, clear parent and if all set, then set parent
+ if(foundclear && !foundcheck)
+ p->SetCheckboxState(0);
+ else if(!foundclear && foundcheck)
+ p->SetCheckboxState(1);
+ else if(foundclear && foundcheck)
+ p->SetCheckboxState(2);
+
+ //wxClientDC dc;
+ //DrawCheckbox(p, dc, false);
+ RedrawFromNode(p);
+ }
+}
+
+#endif // #if(CHECKBOXVIEW)
+
+wxTreeMultiItem wxTreeMultiCtrl::InsertNode(TreeMultiItemNode* ParentPtr, size_t Position, wxString const& Caption, wxString const& Name)
+{
+ int extX, extY;
+
+ TreeMultiItemNode* NodePtr(new TreeMultiItemNode(ParentPtr,Caption,Name)); // generate new node pointer
+
+
+ // continue with initializing the new node:
+#if(CHECKBOXVIEW)
+ // if checkbox view is desired, tag this item as a checkbox
+ // and set the state as 'false'
+ NodePtr->SetCheckbox(_checkboxView);
+ NodePtr->SetCheckboxState(0);
+#endif
+ // calculate the height and width
+ this->GetTextExtent(Caption,&extX,&extY,0,0,&(this->_captionFont));
+ NodePtr->SetHeight(extY);
+ NodePtr->SetWidth(extX);
+ // finally, insert node:
+ if (Position < (size_t)ParentPtr->GetNodeCount())
+ ParentPtr->InsertNode(NodePtr,Position);
+ else
+ ParentPtr->AddNode(NodePtr);
+ // return the newly created node:
+ return wxTreeMultiItem(NodePtr);
+} /* wxTreeMultiCtrl::InsertNode(TreeMultiItemNode*, size_t, wxString const&, wxString const&) */
+
+wxTreeMultiItem wxTreeMultiCtrl::InsertWindow(TreeMultiItemNode* ParentPtr, size_t Position, wxWindow* WindowPtr, wxString const& Name, wxTreeMultiWindowInfo const& Info, int Flags)
+{
+ int WindowFlags;
+
+ TreeMultiItemWindow* NewWindowPtr = new TreeMultiItemWindow(ParentPtr,Name); // generate new window pointer
+
+
+ // get flags from passed variable "Flags"; in case this variable does not contain any flags use the window's information flags:
+ if (Flags != 0)
+ WindowFlags = Flags;
+ else
+ WindowFlags = Info.GetFlags();
+
+ // continue with initializing the new window:
+#if(CHECKBOXVIEW)
+ // if checkbox view is desired, tag this item as a checkbox
+ // and set the state as 'false'
+ NewWindowPtr->SetCheckbox(_checkboxView);
+#endif
+ // if style wants us to change background, set it to our background
+ if (WindowFlags & wxTMC_BG_ADJUST_ALL)
+ {
+ // go through all children of this window, and set the
+ // background of it (recursively)
+ this->SetWindowBackgroundColour(WindowPtr,this->GetBackgroundColour(),WindowFlags);
+ } /* if */
+
+ // set the spacing:
+ NewWindowPtr->SetTopSpacing(Info.GetTopSpacing());
+#if(CHECKBOXVIEW)
+ // make sure that the checkboxes are at least indented enough
+ if (this->_checkboxView)
+ NewWindowPtr->SetFrontSpacing(Info.GetFrontSpacing() + this->_checkWidth);
+ else
+#endif
+ NewWindowPtr->SetFrontSpacing(Info.GetFrontSpacing());
+ // assign finally the window:
+ NewWindowPtr->AssignWindow(WindowPtr);
+
+#if(CHECKBOXVIEW)
+ // set the checkbox state after the window is assigned
+ NewWindowPtr->SetCheckboxState(Info.GetDefaultCheckState());
+#endif
+
+ // if the window is not visible, set hide flag
+ this->ShowTreeMultiWindow(NewWindowPtr,NewWindowPtr->IsVisible());
+
+ // finally, insert the newly constructed window:
+ if (Position < (size_t)ParentPtr->GetNodeCount())
+ ParentPtr->InsertNode(NewWindowPtr,Position);
+ else
+ ParentPtr->AddNode(NewWindowPtr);
+ // return the newly created window:
+ return wxTreeMultiItem(NewWindowPtr);
+} /* wxTreeMultiCtrl::InsertWindow(TreeMultiItemNode*, size_t, wxWindow*, wxString const&, wxTreeMultiWindowInfo const&, int) */
+
+void wxTreeMultiCtrl::RedrawFromParentNode(TreeMultiItemBase *n)
+{
+ TreeMultiItemNode *p = 0;
+ if(n)
+ p = n->GetParent();
+
+ RedrawFromNode(p);
+}
+
+void wxTreeMultiCtrl::RedrawFromNode(TreeMultiItemNode *n)
+{
+ static int recalcMutex = 0;
+ bool visible = true;
+
+ if(recalcMutex > 0)
+ return;
+
+ recalcMutex ++;
+
+ // when node is not visible or excluded
+ // then don't redraw.
+
+ if(n)
+ visible = n->IsVisible();
+
+ if(visible)
+ {
+ int h, h1,w, w1;
+ GetVirtualSize(&w, &h);
+
+ UpdateAllWindowVisibility();
+ RecalculateNodePositions();
+ RecalculateVirtualSize();
+
+ // why is this needed? Because folding or collapsing can change
+ // the state. When the virtual area gets smaller, we need to keep
+ // the largest one and the other way atound. And since we do not
+ // know here we are folding or collapsing, we remember the biggest
+ GetVirtualSize(&w1, &h1);
+
+ if(h1 > h)
+ h = h1;
+
+ // only refresh the part from x,y down
+ if(n)
+ {
+ int x, y;
+ CalcScrolledPosition(n->GetX(), n->GetY(), &x, &y);
+ if(h - y > 0)
+ {
+ wxRect rect(0, y, w, h - y);
+ RefreshRect(rect);
+ }
+ else
+ Refresh();
+ }
+ else
+ Refresh(); // do a full refresh
+ }
+
+ recalcMutex --;
+}
+
+void wxTreeMultiCtrl::RecalculateNodePositions()
+{
+ int currentY = _spacingY;
+ // go recursive on every node, and store the information in the node
+
+ for(int i = 0; i < _root.GetNodeCount(); i++)
+ currentY += CalculateNodeDimensions(_root.GetNode(i), currentY, 0);
+}
+
+int wxTreeMultiCtrl::CalculateNodeDimensions(TreeMultiItemBase *b, int currentY, int level)
+{
+ int gutter = (_gutterWidth * 2) + _iconWidth;
+ int y = 0, topSpacing = 0;
+
+ // return same if no proper object
+ wxCHECK(b, 0);
+
+#if(CHECKBOXVIEW)
+ if(b->GetCheckbox())
+ gutter += _checkWidth;
+#endif
+
+ // if we are not visible, skip recalculation and descending
+ if(b->IsVisible())
+ {
+ b->SetY(currentY);
+
+ // if level is 0, calculate with front gutter, else without
+ y = currentY + b->GetHeight();
+ if(b->IsTreeMultiItemNode())
+ {
+ TreeMultiItemNode *n = (TreeMultiItemNode *)b;
+
+ if(level == 0)
+ b->SetX(gutter);
+ else
+ b->SetX(gutter + (level * (_gutterWidth + _iconWidth)));
+
+ // now do children of this node
+
+ for(int i = 0; i < n->GetNodeCount(); i++)
+ y += CalculateNodeDimensions(n->GetNode(i), y + _spacingY, level+1);
+ }
+ else if(b->IsTreeMultiItemWindow())
+ {
+ TreeMultiItemWindow *w = (TreeMultiItemWindow *)b;
+
+ if(level == 0)
+ b->SetX(gutter + w->GetFrontSpacing());
+ else
+ b->SetX(_gutterWidth + (level * (_gutterWidth + _iconWidth)) + w->GetFrontSpacing());
+
+ topSpacing = w->GetTopSpacing();
+
+ // reposition the window
+
+ wxWindow *wnd = w->GetWindow();
+ if(wnd)
+ {
+ int x = 0, y = 0;
+ CalcScrolledPosition(w->GetX(), w->GetY(), &x, &y);
+ wnd->SetSize(x, y, w->GetWidth(), w->GetHeight());
+ }
+ }
+
+ if(y > 0)
+ return (y - currentY) + _spacingY + topSpacing; // return delta
+ else
+ return 0;
+ }
+
+ return 0; // not visible, thus we skip calculations
+}
+
+void wxTreeMultiCtrl::RecalculateSpanSizes()
+{
+ for(int i = 0; i < _root.GetNodeCount(); i++)
+ CalculateNodeSpanning(_root.GetNode(i));
+}
+
+void wxTreeMultiCtrl::CalculateNodeSpanning(TreeMultiItemBase *b)
+{
+ // return same if no proper object
+ wxCHECK2(b, return);
+
+ if(b->IsTreeMultiItemNode())
+ {
+ TreeMultiItemNode *n = (TreeMultiItemNode *)b;
+
+ // now do children of this node
+
+ for(int i = 0; i < n->GetNodeCount(); i++)
+ CalculateNodeSpanning(n->GetNode(i));
+ }
+ else if(b->IsTreeMultiItemWindow())
+ {
+ TreeMultiItemWindow *w = (TreeMultiItemWindow *)b;
+ wxWindow *wnd = w->GetWindow();
+ if(wnd)
+ {
+ // if the window is spanning, we adjust the width to the max width of the control
+ if(w->GetHorizontalSpan())
+ {
+ wxSize tmcsize = GetClientSize();
+ int maxwidth = tmcsize.GetWidth() - w->GetX() - 8; // extract 3 for border
+
+ wxSizer *sz = wnd->GetSizer();
+ if(sz)
+ {
+ if(maxwidth < sz->GetMinSize().GetWidth())
+ maxwidth = sz->GetMinSize().GetWidth();
+ }
+
+ // prevent a size of 0
+ if(maxwidth < 1)
+ maxwidth = 1;
+
+ // set the size
+ w->SetWidth(maxwidth);
+ wnd->SetSize(w->GetWidth(), w->GetHeight());
+
+ // layout by sizer (not sure if this is needed)
+ if(wnd->GetSizer())
+ wnd->GetSizer()->Layout();
+ }
+ }
+ }
+}
+
+void wxTreeMultiCtrl::RecalculateVirtualSize()
+{
+ // go through all the nodes, and store the largest x and largest y
+
+ int x = 0, y = 0;
+ RecalculateVirtualSizeFromNode(&_root, x, y);
+
+ // now adjust virtual size
+ SetVirtualSize(x, y);
+ AdjustScrollbars(x, y);
+}
+
+void wxTreeMultiCtrl::AdjustScrollbars(int x, int y)
+{
+ // adjust scrollbars
+ // courtesy of treectrlg.cpp
+
+ y += WXTMC_PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels
+ x += WXTMC_PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels
+ int x_pos = GetScrollPos( wxHORIZONTAL );
+ int y_pos = GetScrollPos( wxVERTICAL );
+ SetScrollbars( WXTMC_PIXELS_PER_UNIT, WXTMC_PIXELS_PER_UNIT, x/WXTMC_PIXELS_PER_UNIT,
+ y/WXTMC_PIXELS_PER_UNIT, x_pos, y_pos, true );
+}
+
+void wxTreeMultiCtrl::RecalculateVirtualSizeFromNode(const TreeMultiItemNode *node, int &x, int &y)
+{
+ if(node->IsExcluded())
+ return;
+
+ // if calulate this node's dimensions
+ if(x < (node->GetWidth() + node->GetX()))
+ x = node->GetWidth() + node->GetX();
+
+ y = node->GetY() + node->GetHeight();
+
+ // if this node is collapsed, no subnodes are visible, else
+ // go through all subnodes as well, node needs to be included as well
+ if(node->IsExpanded())
+ {
+ TreeMultiItemBase *b;
+ for(int i = 0; i < node->GetNodeCount(); i++)
+ {
+ b = node->GetNode(i);
+
+ // calculate x and y
+ if(x < (b->GetWidth() + b->GetX()))
+ x = b->GetWidth() + b->GetX();
+
+ y = b->GetY() + b->GetHeight();
+
+ if(b->IsTreeMultiItemNode())
+ RecalculateVirtualSizeFromNode((TreeMultiItemNode *)b, x, y);
+ }
+ }
+}
+
+void wxTreeMultiCtrl::SetWindowBackgroundColour(wxWindow *wnd, const wxColour &col, int flags)
+{
+ if(wnd)
+ {
+ // if we cannot change a button, make sure all button
+ // classes are not changed
+
+ wxButton *btn = wxDynamicCast(wnd, wxButton);
+ if(!btn || ((flags & wxTMC_BG_ADJUST_BTN) != 0))
+ wnd->SetBackgroundColour(col);
+
+ // get every window, and make the background equal to the given one
+ wxWindowListNode *node = wnd->GetChildren().GetFirst();
+ while (node)
+ {
+ SetWindowBackgroundColour(node->GetData(), col, flags);
+ node = node->GetNext();
+ }
+ }
+}
+
+void wxTreeMultiCtrl::ShowTreeMultiWindow(TreeMultiItemWindow *window, bool show)
+{
+ // show or hide window
+ if(window && window->GetWindow())
+ window->GetWindow()->Show(show);
+}
+
+void wxTreeMultiCtrl::UpdateAllWindowVisibility()
+{
+ // all roots are visible, but what lies beneath ... who knows
+ for(int i = 0; i < _root.GetNodeCount(); i++)
+ UpdateTreeMultiWindowVisibility(_root.GetNode(i), true);
+}
+
+void wxTreeMultiCtrl::UpdateTreeMultiWindowVisibility(TreeMultiItemBase *b, bool show)
+{
+ if(b)
+ {
+ // this is done for performance issues. IsVisible can go all
+ // the way up the tree to check. However if show is already
+ // false, there is no need to check (some higher one is collapsed)
+ bool showMe = show;
+
+ if(showMe)
+ showMe = b->IsVisible();
+
+ if(b->IsTreeMultiItemWindow())
+ {
+ // if this level must be hidden, hide
+ ShowTreeMultiWindow((TreeMultiItemWindow*)b, showMe);
+ }
+ else if(b->IsTreeMultiItemNode())
+ {
+ TreeMultiItemNode *node = (TreeMultiItemNode *)b;
+
+ // if hidden, descend and hide all windows
+ for(int i = 0; i < node->GetNodeCount(); i++)
+ UpdateTreeMultiWindowVisibility(node->GetNode(i), showMe);
+ }
+ }
+}
+
+wxTreeMultiItem wxTreeMultiCtrl::FindItem(const wxTreeMultiItem &item, const wxString &name, bool ignoreCase, bool skipFirst)
+{
+ if(item.IsOk())
+ {
+ TreeMultiItemBase *b = item.GetItem();
+
+ // check this item first (or not)
+
+ if(!skipFirst)
+ {
+ if(b->GetName().IsSameAs(name, !ignoreCase))
+ return wxTreeMultiItem(b);
+ }
+
+ if(b->IsTreeMultiItemNode())
+ {
+ // now check whether we are a node, then go check children
+
+ TreeMultiItemNode *n = (TreeMultiItemNode *)b;
+ wxTreeMultiItem result(0);
+ for(int i = 0; i < n->GetNodeCount() && !result.IsOk(); i++)
+ result = FindItem(wxTreeMultiItem(n->GetNode(i)), name, ignoreCase, false);
+
+ return result;
+ }
+ }
+
+ return wxTreeMultiItem(0);
+}
+
+wxTreeMultiItem wxTreeMultiCtrl::FindWindowNode(wxWindow *wnd, TreeMultiItemNode *n)
+{
+ wxCHECK(wnd, wxTreeMultiItem(0));
+
+ // take root node if not assigned one
+
+ if(!n)
+ n = (TreeMultiItemNode *)&_root;
+
+ // check on this level for the wxWindow pointer
+
+ TreeMultiItemWindow *w;
+ wxTreeMultiItem result(0);
+ for(int i = 0; i < n->GetNodeCount() && !result.IsOk(); i++)
+ {
+ // if window node
+ w = n->GetNode(i)->IsTreeMultiItemWindow();
+ if(w && w->GetWindow() == wnd)
+ return wxTreeMultiItem(n);
+
+ // if node, go deeper
+ if(n->GetNode(i)->IsTreeMultiItemNode())
+ result = FindWindowNode(wnd, (TreeMultiItemNode*)n->GetNode(i));
+ }
+
+ return result;
+}
+
+TreeMultiItemWindow *wxTreeMultiCtrl::FindNextVisibleWindowItem(TreeMultiItemBase *b, int index)
+{
+ wxCHECK(b, 0);
+
+ // check on this level, go deeper with every node we got. When a node is not
+ // visible anymore, skip the node.
+
+ TreeMultiItemWindow *value = 0;
+ if(b->IsVisible())
+ {
+ // if we are already searching on a node with an index
+
+ TreeMultiItemBase *bn = 0;
+ TreeMultiItemNode *n = b->IsTreeMultiItemNode();
+ if(n)
+ {
+ for(int i = index + 1; i < n->GetNodeCount() && !value; i++)
+ {
+ bn = n->GetNode(i);
+ value = bn->IsTreeMultiItemWindow();
+
+ // assume a node, root when not a a window
+ if(!value)
+ value = FindNextVisibleWindowItem(bn, -1);
+ }
+
+ }
+ else
+ {
+ if(b->IsTreeMultiItemWindow())
+ {
+ // get parent first, and locate child as ptr
+ TreeMultiItemNode *p = b->GetParent();
+ wxCHECK(p, 0);
+
+ // go scan the parent from the given index, if
+ // the index is valid else there is no child with that index
+
+ int idx = p->Index(b);
+ wxCHECK(idx >= 0, 0);
+
+ value = FindNextVisibleWindowItem(p, idx);
+ }
+ }
+ }
+
+ return value;
+
+}
+
+bool wxTreeMultiCtrl::GetBooleanValue(int wndId)
+{
+ wxWindow *wnd = wxWindow::FindWindow(wndId);
+ wxCHECK(wnd, false);
+
+ // try a radio button
+ wxRadioButton *b = wxDynamicCast(wnd, wxRadioButton);
+ if(b)
+ return b->GetValue();
+
+ // try a check box
+ wxCheckBox *c = wxDynamicCast(wnd, wxCheckBox);
+ if(c)
+ return c->GetValue();
+
+ /** \todo For custom controls we should put something in wxMultiTreeItemData class
+ which can be overridden to retrieve the boolean value. It will also be passed
+ the pointer to the window, so the derived class can figure out how to get a boolean
+ value.
+ */
+
+ // generate assert or just return with false
+ wxCHECK(0, false);
+}
+
+void wxTreeMultiCtrl::SetBooleanValue(int wndId, bool value)
+{
+ wxWindow *wnd = wxWindow::FindWindow(wndId);
+ wxCHECK2(wnd, return);
+
+ // try a radio button
+ wxRadioButton *b = wxDynamicCast(wnd, wxRadioButton);
+ if(b)
+ {
+ b->SetValue(value);
+ return;
+ }
+
+ // try a check box
+ wxCheckBox *c = wxDynamicCast(wnd, wxCheckBox);
+ if(c)
+ {
+ c->SetValue(value);
+ return;
+ }
+
+ /** \todo For custom controls we should put something in wxMultiTreeItemData class
+ which can be overridden to retrieve the boolean value. It will also be passed
+ the pointer to the window, so the derived class can figure out how to get a boolean
+ value.
+ */
+
+ // generate assert
+ wxCHECK2(0, return);
+}
+
+void wxTreeMultiCtrl::SetTextValue(int wndId, const wxString &value)
+{
+ wxWindow *wnd = wxWindow::FindWindow(wndId);
+ wxCHECK2(wnd, return);
+
+ // try a radio button
+ wxTextCtrl *t = wxDynamicCast(wnd, wxTextCtrl);
+ if(t)
+ {
+ t->SetValue(value);
+ return;
+ }
+
+ /** \todo For custom controls we should put something in wxMultiTreeItemData class
+ which can be overridden to retrieve the boolean value. It will also be passed
+ the pointer to the window, so the derived class can figure out how to get a boolean
+ value.
+ */
+
+ // generate assert
+ wxCHECK2(0, return);
+}
+
+wxString wxTreeMultiCtrl::GetTextValue(int wndId)
+{
+ wxWindow *wnd = wxWindow::FindWindow(wndId);
+ wxCHECK(wnd, wxEmptyString);
+
+ // try a radio button
+ wxTextCtrl *t = wxDynamicCast(wnd, wxTextCtrl);
+ if(t)
+ return t->GetValue();
+
+ // try a choice box
+ wxChoice *c1 = wxDynamicCast(wnd, wxChoice);
+ if(c1)
+ return c1->GetStringSelection();
+
+ // try a combo box
+ wxComboBox *c2 = wxDynamicCast(wnd, wxComboBox);
+ if(c2)
+ return c2->GetStringSelection();
+
+ // try a listbox
+ wxListBox *l = wxDynamicCast(wnd, wxListBox);
+ if(l)
+ return l->GetStringSelection();
+
+ /** \todo For custom controls we should put something in wxMultiTreeItemData class
+ which can be overridden to retrieve the boolean value. It will also be passed
+ the pointer to the window, so the derived class can figure out how to get a boolean
+ value.
+ */
+
+ // generate assert or just return with string
+ wxCHECK(0, wxEmptyString);
+}
+
+int wxTreeMultiCtrl::GetSelectionValue(int wndId)
+{
+ wxWindow *wnd = wxWindow::FindWindow(wndId);
+ wxCHECK(wnd, -1);
+
+ // try a choice box
+ wxChoice *c1 = wxDynamicCast(wnd, wxChoice);
+ if(c1)
+ return c1->GetSelection();
+
+ // try a combo box
+ wxComboBox *c2 = wxDynamicCast(wnd, wxComboBox);
+ if(c2)
+ return c2->GetSelection();
+
+ // try a listbox
+ wxListBox *l = wxDynamicCast(wnd, wxListBox);
+ if(l)
+ return l->GetSelection();
+
+ /** \todo For custom controls we should put something in wxMultiTreeItemData class
+ which can be overridden to retrieve the boolean value. It will also be passed
+ the pointer to the window, so the derived class can figure out how to get a boolean
+ value.
+ */
+
+ // generate assert or just return with string
+ wxCHECK(0, -1);
+}
+
+void wxTreeMultiCtrl::GetSelectionValues(int wndId, wxArrayInt &sels)
+{
+ sels.Clear();
+
+ wxWindow *wnd = wxWindow::FindWindow(wndId);
+ wxCHECK2(wnd, return);
+
+ // try a listbox
+ wxListBox *l = wxDynamicCast(wnd, wxListBox);
+ if(l)
+ {
+ l->GetSelections(sels);
+ return;
+ }
+
+ /** \todo For custom controls we should put something in wxMultiTreeItemData class
+ which can be overridden to retrieve the boolean value. It will also be passed
+ the pointer to the window, so the derived class can figure out how to get a boolean
+ value.
+ */
+
+ // generate assert or just return with string
+ wxCHECK2(0, return);
+}
+
+void wxTreeMultiCtrl::SetSelectionValue(int wndId, int sel)
+{
+ wxWindow *wnd = wxWindow::FindWindow(wndId);
+ wxCHECK2(wnd, return);
+
+ // try a choice box
+ wxChoice *c1 = wxDynamicCast(wnd, wxChoice);
+ if(c1)
+ {
+ c1->SetSelection(sel);
+ return;
+ }
+
+ // try a combo box
+ wxComboBox *c2 = wxDynamicCast(wnd, wxComboBox);
+ if(c2)
+ {
+ c2->SetSelection(sel);
+ return;
+ }
+
+ // try a listbox
+ wxListBox *l = wxDynamicCast(wnd, wxListBox);
+ if(l)
+ {
+ l->SetSelection(sel);
+ return;
+ }
+
+ /** \todo For custom controls we should put something in wxMultiTreeItemData class
+ which can be overridden to retrieve the boolean value. It will also be passed
+ the pointer to the window, so the derived class can figure out how to get a boolean
+ value.
+ */
+
+ // generate assert or just return with string
+ wxCHECK2(0, return);
+}
+
+
+wxTreeMultiItem wxTreeMultiCtrl::GetParent(wxTreeMultiItem const& item) const
+{
+ // check if valid or root item has been passed, both do not have parents:
+ if (!(item.IsOk()) || item.GetItem()->IsTreeMultiItemRoot())
+ return wxTreeMultiItem();
+ else
+ return wxTreeMultiItem(item.GetItem()->GetParent()); // GetParent() returns a valid pointer in case of a root item!!
+ // therefore, the check if the passed item is a root item is necessary
+} /* wxTreeMultiCtrl::GetParent(wxTreeMultiItem const& item) const */
+
+wxTreeMultiItem wxTreeMultiCtrl::GetFirstChild(const wxTreeMultiItem &item, int &cookie) const
+{
+ if(item.IsNodeItem())
+ {
+ TreeMultiItemNode *n = (TreeMultiItemNode *)item.GetItem();
+
+ if(n->GetNodeCount() > 0)
+ {
+ cookie = 0;
+ return wxTreeMultiItem(n->GetNode(0));
+ }
+ }
+
+ // no children or no valid node
+ cookie = -1;
+ return wxTreeMultiItem(0);
+}
+
+wxTreeMultiItem wxTreeMultiCtrl::GetNextChild(const wxTreeMultiItem &item, int &cookie) const
+{
+ if(item.IsNodeItem())
+ {
+ TreeMultiItemNode *n = (TreeMultiItemNode *)item.GetItem();
+
+ if(cookie >= 0 && cookie < (n->GetNodeCount()-1))
+ {
+ // increment cookie, return node
+ cookie ++;
+ return wxTreeMultiItem(n->GetNode(cookie));
+ }
+ }
+
+ // end of query, or no valid node
+ cookie = -1;
+ return wxTreeMultiItem(0);
+}
+
+wxTreeMultiItem wxTreeMultiCtrl::GetLastChild(const wxTreeMultiItem &item) const
+{
+ if(item.IsNodeItem())
+ {
+ TreeMultiItemNode *n = (TreeMultiItemNode *)item.GetItem();
+
+ if(n->GetNodeCount() > 0)
+ return wxTreeMultiItem(n->GetNode(n->GetNodeCount()-1));
+ }
+
+ return wxTreeMultiItem(0);
+}
+
+wxTreeMultiItem wxTreeMultiCtrl::GetNextSibling(wxTreeMultiItem const& item) const
+{
+ // check if a valid item has been passed:
+ if (!(item.IsOk()))
+ return wxTreeMultiItem();
+
+ TreeMultiItemNode* ParentPtr(item.GetItem()->GetParent());
+
+
+ if (ParentPtr != NULL) // the parent pointer is only null if the passed item is the root
+ {
+ // find the current item in the parent's list; the next sibling has an index that is one higher than the one of the current item:
+ int NextItemIndex(ParentPtr->Index(item.GetItem())+1); // variable definition and initialization
+
+ if (NextItemIndex < ParentPtr->GetNodeCount())
+ return ParentPtr->GetNode(NextItemIndex);
+ else
+ return wxTreeMultiItem();
+ } /* if */
+ else
+ return wxTreeMultiItem();
+} /* wxTreeMultiCtrl::GetNextSibling(wxTreeMultiItem const&) const */
+
+wxTreeMultiItem wxTreeMultiCtrl::GetPrevSibling(wxTreeMultiItem const& item) const
+{
+ // check if a valid item has been passed:
+ if (!(item.IsOk()))
+ return wxTreeMultiItem();
+
+ TreeMultiItemNode* ParentPtr(item.GetItem()->GetParent());
+
+
+ if (ParentPtr != NULL)
+ {
+ // find the current item in the parent's list; the next sibling has an index that is one higher than the one of the current item:
+ int PrevItemIndex(ParentPtr->Index(item.GetItem())-1); // variable definition and initialization
+
+ if (PrevItemIndex >= 0)
+ return ParentPtr->GetNode(PrevItemIndex);
+ else
+ return wxTreeMultiItem();
+ } /* if */
+ else
+ return wxTreeMultiItem();
+} /* wxTreeMultiCtrl::GetPrevSibling(wxTreeMultiItem const&) const */
+
+wxTreeMultiItem wxTreeMultiCtrl::GetNext(wxTreeMultiItem const& item) const
+{
+ // check if a valid item has been passed:
+ if (!(item.IsOk()))
+ return wxTreeMultiItem();
+
+ TreeMultiItemNode* NodePtr(item.GetItem()->IsTreeMultiItemNode()); // variable definition and initialization
+
+ if ((NodePtr != NULL) && (NodePtr->GetNodeCount() > 0))
+ return wxTreeMultiItem(NodePtr->First());
+ else
+ {
+ // variable definitions and initializations:
+ wxTreeMultiItem Parent(item);
+ wxTreeMultiItem Sibling;
+
+ do
+ {
+ Sibling = this->GetNextSibling(Parent); // try to find next sibling
+ Parent = this->GetParent(Parent); // get next ancestor
+ } while (!(Sibling.IsOk()) && Parent.IsOk());
+ // in case the loop ended with Sibling.IsOk() "Sibling" contains a valid sibling otherwise an invalid
+ return Sibling;
+ } /* if */
+} /* wxTreeMultiCtrl::GetNextSibling(wxTreeMultiItem const&) const */
+
+wxTreeMultiItem wxTreeMultiCtrl::GetPrevious(wxTreeMultiItem const& item) const
+{
+ // check if a valid item has been passed:
+ if (!(item.IsOk()))
+ return wxTreeMultiItem();
+
+ TreeMultiItemNode* NodePtr(item.GetItem()->IsTreeMultiItemNode()); // variable definition and initialization
+
+ if ((NodePtr != NULL) && (NodePtr->GetNodeCount() > 0))
+ return wxTreeMultiItem(NodePtr->Last());
+ else
+ {
+ // variable definitions and initializations:
+ wxTreeMultiItem Parent(item);
+ wxTreeMultiItem Sibling;
+
+ do
+ {
+ Sibling = this->GetPrevSibling(Parent); // try to find next sibling
+ Parent = this->GetParent(Parent); // get next ancestor
+ } while (!(Sibling.IsOk()) && Parent.IsOk());
+ // in case the loop ended with Sibling.IsOk() "Sibling" contains a valid sibling otherwise an invalid
+ return Sibling;
+ } /* if */
+} /* wxTreeMultiCtrl::GetPrevious(wxTreeMultiItem const&) const */
+
+// WDR: handler implementations for wxTreeMultiCtrl
+
+void wxTreeMultiCtrl::OnDraw(wxDC& dc)
+{
+ // go recursive and draw the whole visible tree.
+ dc.SetFont(_captionFont);
+ for(int i = 0; i < _root.GetNodeCount(); i++)
+ DrawNode(_root.GetNode(i), dc);
+} /* */
-//---------------------------------------------------------------------------\r
-// $RCSfile: wxTreeMultiCtrl.h,v $\r
-// $Source: /cvs/creatis/bbtk/kernel/src/ThirdParty/wx/treemultictrl/wxTreeMultiCtrl.h,v $\r
-// $Revision: 1.1 $\r
-// $Date: 2008/03/28 13:42:19 $\r
-//---------------------------------------------------------------------------\r
-// Author: Jorgen Bodde\r
-// Copyright: (c) Jorgen Bodde\r
+//---------------------------------------------------------------------------
+// $RCSfile: wxTreeMultiCtrl.h,v $
+// $Source: /cvs/creatis/bbtk/kernel/src/ThirdParty/wx/treemultictrl/wxTreeMultiCtrl.h,v $
+// $Revision: 1.2 $
+// $Date: 2009/10/05 22:44:50 $
+//---------------------------------------------------------------------------
+// Author: Jorgen Bodde
+// Copyright: (c) Jorgen Bodde
// License: wxWidgets License
//---------------------------------------------------------------------------
wxTreeMultiItem(TreeMultiItemBase *ptr) {
_item = ptr;
- };\r
-\r
- // Returns the TreeMultiItemBase class. This shoult *NOT* be\r
- // used if you don't know what you are doing! This means never use it. */\r
- TreeMultiItemBase *GetItem() const {\r
- return _item;\r
- };\r
+ };
+
+ // Returns the TreeMultiItemBase class. This shoult *NOT* be
+ // used if you don't know what you are doing! This means never use it. */
+ TreeMultiItemBase *GetItem() const {
+ return _item;
+ };
#endif // _NO_DOXYGEN_
classes from the wxTreeMultiCtrl.
*/
void operator=(const wxTreeMultiItem &item) {
- _item = item._item;\r
- };\r
-\r
- /** Equality operator. It returns true if the items are identical or if both items are invalid. */\r
- bool operator==(wxTreeMultiItem const& item) const {return (this->GetItem() == item.GetItem());}\r
-\r
- /** Inequality operator. It returns true if the items are different or one of them is invalid. */\r
- bool operator!=(wxTreeMultiItem const& item) const {return (this->GetItem() != item.GetItem());}\r
-\r
- /** Returns the parent of the current wxTreeMultiItem. This means the wxTreeMultiNode is returned. It can\r
- be useful to check or clear the checkbox at this level. */\r
- wxTreeMultiItem GetParent() const{\r
- wxCHECK(IsOk(), wxTreeMultiItem(0));\r
- return wxTreeMultiItem(_item->GetParent());\r
- };\r
+ _item = item._item;
+ };
+
+ /** Equality operator. It returns true if the items are identical or if both items are invalid. */
+ bool operator==(wxTreeMultiItem const& item) const {return (this->GetItem() == item.GetItem());}
+
+ /** Inequality operator. It returns true if the items are different or one of them is invalid. */
+ bool operator!=(wxTreeMultiItem const& item) const {return (this->GetItem() != item.GetItem());}
+
+ /** Returns the parent of the current wxTreeMultiItem. This means the wxTreeMultiNode is returned. It can
+ be useful to check or clear the checkbox at this level. */
+ wxTreeMultiItem GetParent() const{
+ wxCHECK(IsOk(), wxTreeMultiItem(0));
+ return wxTreeMultiItem(_item->GetParent());
+ };
/** Validates if the wxTreeMultiItem is a valid instance to use in the wxTreeMultiCtrl. Returns TRUE when there
is a member value is associated with it, or FALSE when not. This value can also be checked when this class is returned from a wxTreeMultiCtrl operation. For example:
Use wxTreeMultiCtrl::GetExcludedParent() to get the node that hides this one. */
bool IsExcluded() {
wxCHECK(_item, false);
- return _item->IsExcluded();\r
- }\r
-\r
- /** Returns true if the item is selected.\r
- Please note that currently only nodes can be selected.\r
- */\r
- bool IsSelected(void) const\r
- {\r
- wxCHECK(this->GetItem(),false);\r
- return this->GetItem()->IsSelected();\r
- }\r
- /** Returns true if this node is visible. Please note that when this node is a child node of a collapsed\r
- node, it is not visible. Also if this node is a child node of an excluded node, it is also not visible.\r
- It does <b>NOT</b> return false when it's drawn somewhere outside of the visible area. */\r
+ return _item->IsExcluded();
+ }
+
+ /** Returns true if the item is selected.
+ Please note that currently only nodes can be selected.
+ */
+ bool IsSelected(void) const
+ {
+ wxCHECK(this->GetItem(),false);
+ return this->GetItem()->IsSelected();
+ }
+ /** Returns true if this node is visible. Please note that when this node is a child node of a collapsed
+ node, it is not visible. Also if this node is a child node of an excluded node, it is also not visible.
+ It does <b>NOT</b> return false when it's drawn somewhere outside of the visible area. */
bool IsVisible() {
wxCHECK(_item, false);
return _item->IsVisible();
}
-\r
-};\r
-\r
-WX_DECLARE_OBJARRAY(wxTreeMultiItem,wxArrayTreeMultiItem);\r
-\r
-/** \class wxTreeMultiWindowInfo\r
- \ingroup classes\r
- \brief This class contains information for every Window node to be added.\r
+
+};
+
+WX_DECLARE_OBJARRAY(wxTreeMultiItem,wxArrayTreeMultiItem);
+
+/** \class wxTreeMultiWindowInfo
+ \ingroup classes
+ \brief This class contains information for every Window node to be added.
This class can be used to modify the behaviour of the Window node to be added, and can be reused to pass along
upon every wxTreeMultiCtrl::AppendWindow call. For example:
#if(CHECKBOXVIEW)
/** Checkstate for checkboxed property sheets */
bool _checkState;
-#endif\r
-\r
-public:\r
-#if(CHECKBOXVIEW)\r
- wxTreeMultiWindowInfo(int flags, int frontSpacing, int topSpacing, bool checkState = false)\r
- : _flags(flags)\r
- , _frontSpacing(frontSpacing)\r
- , _frontSpacingOrg(frontSpacing)\r
- , _topSpacing(topSpacing)\r
- , _checkState(checkState)\r
-#else\r
- wxTreeMultiWindowInfo(int flags, int frontSpacing, int topSpacing)\r
- : _flags(flags)\r
- , _frontSpacing(frontSpacing)\r
- , _frontSpacingOrg(frontSpacing)\r
- , _topSpacing(topSpacing)\r
-#endif\r
- {\r
- // constructor\r
+#endif
+
+public:
+#if(CHECKBOXVIEW)
+ wxTreeMultiWindowInfo(int flags, int frontSpacing, int topSpacing, bool checkState = false)
+ : _flags(flags)
+ , _frontSpacing(frontSpacing)
+ , _frontSpacingOrg(frontSpacing)
+ , _topSpacing(topSpacing)
+ , _checkState(checkState)
+#else
+ wxTreeMultiWindowInfo(int flags, int frontSpacing, int topSpacing)
+ : _flags(flags)
+ , _frontSpacing(frontSpacing)
+ , _frontSpacingOrg(frontSpacing)
+ , _topSpacing(topSpacing)
+#endif
+ {
+ // constructor
}
/** Adds indent to original front spacing and increments it with that value (quick extra indent).
The original value of FrontSpacing (see SetFrontSpacing() gets indented by multiplying
bool _checkboxView;
/** Height and weight for checkbox */
- int _checkHeight, _checkWidth;\r
-#endif\r
-\r
- /** brush for highlighting nodes */\r
- wxBrush* m_HilightBrush;\r
-\r
- /** This captionFont is made equal to the font of the wxScrolledWindow. As extra the bold face\r
- is set on it when this is wanted by the user (see flags) */\r
- wxFont _captionFont;\r
-\r
- /** list of selected items */\r
- wxArrayTreeMultiItem m_SelectedItems;\r
-\r
- /** Does the actual collapsing / expanding. So that Expand and Collapse aren't using the same code twice */\r
- void DoFold(TreeMultiItemBase *item, bool expand, bool recursive);\r
-\r
+ int _checkHeight, _checkWidth;
+#endif
+
+ /** brush for highlighting nodes */
+ wxBrush* m_HilightBrush;
+
+ /** This captionFont is made equal to the font of the wxScrolledWindow. As extra the bold face
+ is set on it when this is wanted by the user (see flags) */
+ wxFont _captionFont;
+
+ /** list of selected items */
+ wxArrayTreeMultiItem m_SelectedItems;
+
+ /** Does the actual collapsing / expanding. So that Expand and Collapse aren't using the same code twice */
+ void DoFold(TreeMultiItemBase *item, bool expand, bool recursive);
+
/** Redraws and recalculates the nodes from the current node. It will also clear all 'dirty' flags when
they are recalculated */
void RedrawFromNode(TreeMultiItemNode *n);
/** Recalculates totally needed virtual size of the wxTreeMultiCtrl. It will scan for
the largest window, with the biggest size, and report that back */
- void RecalculateVirtualSize();\r
-\r
- /** Adjusts scrollbars in window, usually done after virtual size (x,y) is recalculated */\r
- using wxScrolledWindow::AdjustScrollbars;\r
- virtual void AdjustScrollbars(int x, int y);\r
-\r
- /** Recalculates and accumulates largest x and y */\r
+ void RecalculateVirtualSize();
+
+ /** Adjusts scrollbars in window, usually done after virtual size (x,y) is recalculated */
+ using wxScrolledWindow::AdjustScrollbars;
+ virtual void AdjustScrollbars(int x, int y);
+
+ /** Recalculates and accumulates largest x and y */
void RecalculateVirtualSizeFromNode(const TreeMultiItemNode *node, int &x, int &y);
-\r
- /** Scans for TreeMultiItemBase node that contains x,y and in area returns a hittest constant to\r
- indicate what matched */\r
- TreeMultiItemBase *FindNodeByPoint(TreeMultiItemBase *b, wxPoint const& pt, int &area);\r
-\r
- /** Scans for TreeMultiItemWindow that holds the wxWindow pointer. Does not scan in panels or does\r
- a deep search. Reason, this function is used to advance to next TreeMultiItemWindow for focus\r
+
+ /** Scans for TreeMultiItemBase node that contains x,y and in area returns a hittest constant to
+ indicate what matched */
+ TreeMultiItemBase *FindNodeByPoint(TreeMultiItemBase *b, wxPoint const& pt, int &area);
+
+ /** Scans for TreeMultiItemWindow that holds the wxWindow pointer. Does not scan in panels or does
+ a deep search. Reason, this function is used to advance to next TreeMultiItemWindow for focus
on this wxScrolledWindow. If a sub window is found, it will skip other windows on that same level */
wxTreeMultiItem FindWindowNode(wxWindow *wnd, TreeMultiItemNode *n = 0);
/** Finds next visible window item in chain. If not found use FindFirstVisibleItem to start from the
- beginning */\r
- TreeMultiItemWindow *FindNextVisibleWindowItem(TreeMultiItemBase *b, int index = -1);\r
-\r
- /** Adjust the centering of the bitmap icons (collapse / expand) when the caption font changes. They need to\r
- be centered in the middle of the font, so a bit of deltaY adjustment is needed */\r
- void AdjustIconsDeltaY();\r
+ beginning */
+ TreeMultiItemWindow *FindNextVisibleWindowItem(TreeMultiItemBase *b, int index = -1);
+
+ /** Adjust the centering of the bitmap icons (collapse / expand) when the caption font changes. They need to
+ be centered in the middle of the font, so a bit of deltaY adjustment is needed */
+ void AdjustIconsDeltaY();
/** Calculate the spanning of the individual nodes */
void CalculateNodeSpanning(TreeMultiItemBase *b);
will get tristate if the checked items are scattered (some are some aren't). If all nodes in this
node are checked, the parent node gets checked all the way up to the last one that matches
criteria. If all are cleared, parent node gets cleared */
- void ScanTristateCheckstates(TreeMultiItemBase *b);\r
-#endif\r
-\r
- /** \name Private add and delete methods\r
- @{\r
- */\r
-\r
- /** Inserts a node into the parent's node at the specified position.\r
- As this is a private method error checking is limited. Therefore, it has to be guaranteed that this method\r
- is only called with a valid parent node pointer.\r
- The position is zero based. In case the position is equal or larger than the current number of\r
- parent's elements the new node is appended.\r
- The newly inserted node is being returned.\r
- */\r
- wxTreeMultiItem InsertNode(TreeMultiItemNode* ParentPtr, size_t Position, wxString const& Caption, wxString const& Name);\r
-\r
- /** Inserts a window into the parent's node at the specified position.\r
- As this is a private method error checking is limited. Therefore, it has to be guaranteed that this method\r
- is only called with a valid parent node and window pointer.\r
- The position is zero based. In case the position is equal or larger than the current number of\r
- parent's elements the new node is appended.\r
- The newly inserted window is being returned.\r
- */\r
- wxTreeMultiItem InsertWindow(TreeMultiItemNode* ParentPtr, size_t Position, wxWindow* WindowPtr, wxString const& Name,\r
- wxTreeMultiWindowInfo const& Info, int Flags);\r
-\r
- /** @}\r
- */\r
-private:\r
- void Init();\r
-\r
+ void ScanTristateCheckstates(TreeMultiItemBase *b);
+#endif
+
+ /** \name Private add and delete methods
+ @{
+ */
+
+ /** Inserts a node into the parent's node at the specified position.
+ As this is a private method error checking is limited. Therefore, it has to be guaranteed that this method
+ is only called with a valid parent node pointer.
+ The position is zero based. In case the position is equal or larger than the current number of
+ parent's elements the new node is appended.
+ The newly inserted node is being returned.
+ */
+ wxTreeMultiItem InsertNode(TreeMultiItemNode* ParentPtr, size_t Position, wxString const& Caption, wxString const& Name);
+
+ /** Inserts a window into the parent's node at the specified position.
+ As this is a private method error checking is limited. Therefore, it has to be guaranteed that this method
+ is only called with a valid parent node and window pointer.
+ The position is zero based. In case the position is equal or larger than the current number of
+ parent's elements the new node is appended.
+ The newly inserted window is being returned.
+ */
+ wxTreeMultiItem InsertWindow(TreeMultiItemNode* ParentPtr, size_t Position, wxWindow* WindowPtr, wxString const& Name,
+ wxTreeMultiWindowInfo const& Info, int Flags);
+
+ /** @}
+ */
+private:
+ void Init();
+
// handlers
//---------
- //virtual void OnDraw(wxDC& dc);\r
- void OnPaint(wxPaintEvent &event);\r
- void OnMouseClick (wxMouseEvent& event);\r
- void OnRightMouseClick(wxMouseEvent& Event);\r
- void OnKey(wxKeyEvent &event);\r
- void OnSize(wxSizeEvent &event);\r
-\r
+ //virtual void OnDraw(wxDC& dc);
+ void OnPaint(wxPaintEvent &event);
+ void OnMouseClick (wxMouseEvent& event);
+ void OnRightMouseClick(wxMouseEvent& Event);
+ void OnKey(wxKeyEvent &event);
+ void OnSize(wxSizeEvent &event);
+
/** Recalculates the spanning controls */
void RecalculateSpanSizes();
*/
/** Adds a root node to the wxTreeMultiItem. There can be many root nodes. Use this wxTreeMultiNode pointer to add
- more subnodes to it. */\r
- wxTreeMultiItem AddRoot(const wxString &caption, const wxString &name = wxEmptyString);\r
-\r
- /** Adds a window to the tree control. Use this wxTreeMultiItem method to add a window class to the\r
- current wxTreeMultiItem. The wxTreeMultiItem must point to a Node class. If this is not the case\r
- an empty wxTreeMultiItem is returned. The mask is used to override the mask settings of the\r
- wxTreeMultiWindowInfo class. This can be handy to set or clear extra flags only needed for certain\r
- situations */\r
- wxTreeMultiItem AppendWindow(const wxTreeMultiItem &ParentItem, wxWindow *window = NULL, const wxString &name = wxEmptyString,\r
- wxTreeMultiWindowInfo const& info = wxTreeMultiWindowInfoDefault, int flags = 0);\r
-\r
- /** Adds a window to the tree control. Use this method to add a window class at the specified position\r
- of the parent's wxTreeMultiItem. In case the position is smaller than the current number of children all elements\r
- are shifted upwards, otherwise the new window is appended to the parent's wxTreeMultiItem.\r
- The parent wxTreeMultiItem must point to a Node class. If this is not the case an\r
- empty wxTreeMultiItem is returned.\r
- */\r
- wxTreeMultiItem InsertWindow(wxTreeMultiItem const& ParentItem, size_t Position, wxWindow *window = NULL, wxString const& Name = wxEmptyString,\r
- wxTreeMultiWindowInfo const& info = wxTreeMultiWindowInfoDefault, int flags = 0);\r
-\r
- /** Adds a window to the tree control. Use this method to add a window class as the first element\r
- of the parent's wxTreeMultiItem. The parent wxTreeMultiItem must point to a Node class. If this is not the case an\r
- empty wxTreeMultiItem is returned.\r
- */\r
- wxTreeMultiItem PrependWindow(wxTreeMultiItem const& ParentItem, wxWindow *window = NULL, const wxString &name = wxEmptyString,\r
- wxTreeMultiWindowInfo const& info = wxTreeMultiWindowInfoDefault, int flags = 0);\r
-\r
- /** Adds a node to the tree control. Use this wxTreeMultiItem method to add a recursive subnode class as the last element\r
- of the parent's wxTreeMultiItem. The parent wxTreeMultiItem must point to a Node class. If this is not the case\r
- an empty wxTreeMultiItem is returned. A node can contain multiple nodes or window classes */\r
- wxTreeMultiItem AppendNode(wxTreeMultiItem const& ParentItem, const wxString &caption = wxEmptyString,\r
- const wxString &name = wxEmptyString);\r
-\r
- /** Adds a node to the tree control. Use this method to add a recursive subnode class at the specified position\r
- of the parent's wxTreeMultiItem. In case the position is smaller than the current number of nodes all elements\r
- are shifted upwards, otherwise the new node is appended to the parent's wxTreeMultiItem.\r
- The parent wxTreeMultiItem must point to a Node class. If this is not the case an\r
- empty wxTreeMultiItem is returned. A node can contain multiple nodes or window classes.\r
- */\r
- wxTreeMultiItem InsertNode(wxTreeMultiItem const& ParentItem, size_t Position, wxString const& caption, wxString const& name);\r
-\r
- /** Adds a node to the tree control. Use this method to add a recursive subnode class as the first element\r
- of the parent's wxTreeMultiItem. The parent wxTreeMultiItem must point to a Node class. If this is not the case an\r
- empty wxTreeMultiItem is returned. A node can contain multiple nodes or window classes.\r
- */\r
- wxTreeMultiItem PrependNode(wxTreeMultiItem const& ParentItem, wxString const& caption = wxEmptyString,\r
- wxString const& name = wxEmptyString);\r
-\r
- /** Delete item from the tree control. Whenever it is present, delete it. If not, return false. After\r
- deletion the wxTreeMultiItem is 0, thus IsOk will return false */\r
- bool Delete(wxTreeMultiItem &item);\r
-\r
- /** Deletes all the items from the wxTreeMultiCtrl. */\r
- void DeleteAllItems(void)\r
- {\r
- this->_root.Clear();\r
- this->m_SelectedItems.Clear();\r
- Refresh();\r
- };\r
-\r
+ more subnodes to it. */
+ wxTreeMultiItem AddRoot(const wxString &caption, const wxString &name = wxEmptyString);
+
+ /** Adds a window to the tree control. Use this wxTreeMultiItem method to add a window class to the
+ current wxTreeMultiItem. The wxTreeMultiItem must point to a Node class. If this is not the case
+ an empty wxTreeMultiItem is returned. The mask is used to override the mask settings of the
+ wxTreeMultiWindowInfo class. This can be handy to set or clear extra flags only needed for certain
+ situations */
+ wxTreeMultiItem AppendWindow(const wxTreeMultiItem &ParentItem, wxWindow *window = NULL, const wxString &name = wxEmptyString,
+ wxTreeMultiWindowInfo const& info = wxTreeMultiWindowInfoDefault, int flags = 0);
+
+ /** Adds a window to the tree control. Use this method to add a window class at the specified position
+ of the parent's wxTreeMultiItem. In case the position is smaller than the current number of children all elements
+ are shifted upwards, otherwise the new window is appended to the parent's wxTreeMultiItem.
+ The parent wxTreeMultiItem must point to a Node class. If this is not the case an
+ empty wxTreeMultiItem is returned.
+ */
+ wxTreeMultiItem InsertWindow(wxTreeMultiItem const& ParentItem, size_t Position, wxWindow *window = NULL, wxString const& Name = wxEmptyString,
+ wxTreeMultiWindowInfo const& info = wxTreeMultiWindowInfoDefault, int flags = 0);
+
+ /** Adds a window to the tree control. Use this method to add a window class as the first element
+ of the parent's wxTreeMultiItem. The parent wxTreeMultiItem must point to a Node class. If this is not the case an
+ empty wxTreeMultiItem is returned.
+ */
+ wxTreeMultiItem PrependWindow(wxTreeMultiItem const& ParentItem, wxWindow *window = NULL, const wxString &name = wxEmptyString,
+ wxTreeMultiWindowInfo const& info = wxTreeMultiWindowInfoDefault, int flags = 0);
+
+ /** Adds a node to the tree control. Use this wxTreeMultiItem method to add a recursive subnode class as the last element
+ of the parent's wxTreeMultiItem. The parent wxTreeMultiItem must point to a Node class. If this is not the case
+ an empty wxTreeMultiItem is returned. A node can contain multiple nodes or window classes */
+ wxTreeMultiItem AppendNode(wxTreeMultiItem const& ParentItem, const wxString &caption = wxEmptyString,
+ const wxString &name = wxEmptyString);
+
+ /** Adds a node to the tree control. Use this method to add a recursive subnode class at the specified position
+ of the parent's wxTreeMultiItem. In case the position is smaller than the current number of nodes all elements
+ are shifted upwards, otherwise the new node is appended to the parent's wxTreeMultiItem.
+ The parent wxTreeMultiItem must point to a Node class. If this is not the case an
+ empty wxTreeMultiItem is returned. A node can contain multiple nodes or window classes.
+ */
+ wxTreeMultiItem InsertNode(wxTreeMultiItem const& ParentItem, size_t Position, wxString const& caption, wxString const& name);
+
+ /** Adds a node to the tree control. Use this method to add a recursive subnode class as the first element
+ of the parent's wxTreeMultiItem. The parent wxTreeMultiItem must point to a Node class. If this is not the case an
+ empty wxTreeMultiItem is returned. A node can contain multiple nodes or window classes.
+ */
+ wxTreeMultiItem PrependNode(wxTreeMultiItem const& ParentItem, wxString const& caption = wxEmptyString,
+ wxString const& name = wxEmptyString);
+
+ /** Delete item from the tree control. Whenever it is present, delete it. If not, return false. After
+ deletion the wxTreeMultiItem is 0, thus IsOk will return false */
+ bool Delete(wxTreeMultiItem &item);
+
+ /** Deletes all the items from the wxTreeMultiCtrl. */
+ void DeleteAllItems(void)
+ {
+ this->_root.Clear();
+ this->m_SelectedItems.Clear();
+ Refresh();
+ };
+
/** Deletes all children of the current node. The wxTreeMultiItem needs to be of type Node to
do this. Call GetParentNode to get the parent wxTreeMultiItem which is always a node. */
void DeleteChildren(const wxTreeMultiItem &item);
Collapse(item, false);
};
- /** @}\r
- */\r
-\r
- /** @name Selection manipulation\r
- These methods allow you to select, unselect or test wxTreeMultiItems on selection.\r
- Currently only items of type Node can be manipulated.\r
- @{\r
- */\r
-\r
- /** Returns the number of selected items. */\r
- size_t GetSelectedItemCount(void) const {return this->m_SelectedItems.GetCount();}\r
-\r
- /** Returns the first selected item.\r
- If there is no selected item an invalid tree multi item is returned.\r
- */\r
- wxTreeMultiItem GetFirstSelectedItem(void) const;\r
-\r
- /** Returns the last selected item.\r
- If there is no selected item an invalid tree multi item is returned.\r
- */\r
- wxTreeMultiItem GetLastSelectedItem(void) const;\r
-\r
- /** Returns a selected item with the specified index.\r
- If there is no selected item with the passed index an invalide tree multi item is returned.\r
- */\r
- wxTreeMultiItem GetSelectedItem(size_t Index) const;\r
-\r
- /** Returns the index of the selected item.\r
- In case the item is not selected "GetSelectedItemCount()" - which is an invalid index - is returned.\r
- */\r
- size_t GetSelectedItemIndex(wxTreeMultiItem const& Item) const;\r
-\r
- /** Selects the specified item AND in case\r
- - UnselectOthers is set all other selected items are going to be unselected;\r
- - ExpandSelection is set all items between the last selected item and the passed item\r
- are selected, too (in case there this is the first selection all items between the first root\r
- and the passed item are selected).\r
- If the passed item is already selected the other parameters are ignored.\r
- Please not that currently only nodes can be selected, therefore, if any other item is passed nothing will happen.\r
- */\r
- void SelectItem(wxTreeMultiItem const& Item, bool UnselectOthers=true, bool ExpandSelection=false);\r
-\r
- /** Unselect all selected items. */\r
- void UnselectAll(void);\r
-\r
- /** Unselect specified item */\r
- void Unselect(wxTreeMultiItem const& Item);\r
-\r
- /** @}\r
- */\r
-\r
-\r
- /** \name Visibility manipulation\r
- These methods allow you to manipulate a certain wxTreeMultiItem to temporarily exclude or to include\r
- the node from drawing. Whenever it is excluded, all operations can still be performed, however\r
+ /** @}
+ */
+
+ /** @name Selection manipulation
+ These methods allow you to select, unselect or test wxTreeMultiItems on selection.
+ Currently only items of type Node can be manipulated.
+ @{
+ */
+
+ /** Returns the number of selected items. */
+ size_t GetSelectedItemCount(void) const {return this->m_SelectedItems.GetCount();}
+
+ /** Returns the first selected item.
+ If there is no selected item an invalid tree multi item is returned.
+ */
+ wxTreeMultiItem GetFirstSelectedItem(void) const;
+
+ /** Returns the last selected item.
+ If there is no selected item an invalid tree multi item is returned.
+ */
+ wxTreeMultiItem GetLastSelectedItem(void) const;
+
+ /** Returns a selected item with the specified index.
+ If there is no selected item with the passed index an invalide tree multi item is returned.
+ */
+ wxTreeMultiItem GetSelectedItem(size_t Index) const;
+
+ /** Returns the index of the selected item.
+ In case the item is not selected "GetSelectedItemCount()" - which is an invalid index - is returned.
+ */
+ size_t GetSelectedItemIndex(wxTreeMultiItem const& Item) const;
+
+ /** Selects the specified item AND in case
+ - UnselectOthers is set all other selected items are going to be unselected;
+ - ExpandSelection is set all items between the last selected item and the passed item
+ are selected, too (in case there this is the first selection all items between the first root
+ and the passed item are selected).
+ If the passed item is already selected the other parameters are ignored.
+ Please not that currently only nodes can be selected, therefore, if any other item is passed nothing will happen.
+ */
+ void SelectItem(wxTreeMultiItem const& Item, bool UnselectOthers=true, bool ExpandSelection=false);
+
+ /** Unselect all selected items. */
+ void UnselectAll(void);
+
+ /** Unselect specified item */
+ void Unselect(wxTreeMultiItem const& Item);
+
+ /** @}
+ */
+
+
+ /** \name Visibility manipulation
+ These methods allow you to manipulate a certain wxTreeMultiItem to temporarily exclude or to include
+ the node from drawing. Whenever it is excluded, all operations can still be performed, however
the node may not be visible.
@{
*/
\li wxTMC_HITTEST_GUTTER If the front part of the item is clicked (where the node is)
\li wxTMC_HITTEST_WINDOW If located in the window area
\li wxTMC_HITTEST_CAPTION If located on the caption of the MultiTreeItemNode
-\r
- Returned is the item which is located under the mouse, or none (IsOk = false) if\r
- no item under the mouse */\r
- wxTreeMultiItem HitTest(wxPoint const& pt, int &flags);\r
-\r
- /** @name Find methods\r
- These methods are used for finding a node in the wxTreeMultiCtrl.\r
+
+ Returned is the item which is located under the mouse, or none (IsOk = false) if
+ no item under the mouse */
+ wxTreeMultiItem HitTest(wxPoint const& pt, int &flags);
+
+ /** @name Find methods
+ These methods are used for finding a node in the wxTreeMultiCtrl.
@{
*/
#if(CHECKBOXVIEW)
/** Gets the checkbox state of the wxTreeMultiItem pointed out by "item". If the item does not have a checkbox
- associated (or the item is not ok), it will return -1. If the checkbox is checked it will return 1,\r
- unchecked is 0, and tri-state (usually only for caption nodes) it will return 2. <b>This needs USE_CHECKBOXVIEW\r
- set to YES, or CHECKBOXVIEW=1 during compile</b>*/\r
- int GetCheckboxState(const wxTreeMultiItem &item, bool WXUNUSED(recursive)) {\r
- wxCHECK(item.IsOk(), -1);\r
-\r
- // return the checkbox state\r
+ associated (or the item is not ok), it will return -1. If the checkbox is checked it will return 1,
+ unchecked is 0, and tri-state (usually only for caption nodes) it will return 2. <b>This needs USE_CHECKBOXVIEW
+ set to YES, or CHECKBOXVIEW=1 during compile</b>*/
+ int GetCheckboxState(const wxTreeMultiItem &item, bool WXUNUSED(recursive)) {
+ wxCHECK(item.IsOk(), -1);
+
+ // return the checkbox state
TreeMultiItemBase *b = item.GetItem();
if(b->GetCheckbox())
return b->GetCheckboxState();
#endif
/** @}
- */\r
-\r
- /** @name Iteration methods\r
- Allows the user to iterate through a wxTreeMultiCtrl node, and get all the children or siblings.\r
- To start an iteration from the lowest level the functions GetFirstRoot and GetLastRoot are provided.\r
- @{\r
- */\r
-\r
- /** Returns the first root. */\r
- wxTreeMultiItem GetFirstRoot(void) const {return wxTreeMultiItem(this->_root.First());}\r
-\r
- /** Returns the last root. */\r
- wxTreeMultiItem GetLastRoot(void) const {return wxTreeMultiItem(this->_root.Last());}\r
-\r
- /** Returns the items parent. */\r
- wxTreeMultiItem GetParent(wxTreeMultiItem const& item) const;\r
-\r
- /** Returns the first child of this node. The type of wxTreeMultiItem needs to be of Node. Whenever not succesful,\r
- the item returned is not ok (IsOk = false). Upon success, a valid child is returned. The cookie variable doesn't\r
- need to be initialized */\r
+ */
+
+ /** @name Iteration methods
+ Allows the user to iterate through a wxTreeMultiCtrl node, and get all the children or siblings.
+ To start an iteration from the lowest level the functions GetFirstRoot and GetLastRoot are provided.
+ @{
+ */
+
+ /** Returns the first root. */
+ wxTreeMultiItem GetFirstRoot(void) const {return wxTreeMultiItem(this->_root.First());}
+
+ /** Returns the last root. */
+ wxTreeMultiItem GetLastRoot(void) const {return wxTreeMultiItem(this->_root.Last());}
+
+ /** Returns the items parent. */
+ wxTreeMultiItem GetParent(wxTreeMultiItem const& item) const;
+
+ /** Returns the first child of this node. The type of wxTreeMultiItem needs to be of Node. Whenever not succesful,
+ the item returned is not ok (IsOk = false). Upon success, a valid child is returned. The cookie variable doesn't
+ need to be initialized */
wxTreeMultiItem GetFirstChild(const wxTreeMultiItem &item, int &cookie) const;
/** Returns the next child in the iteration on the level of 'item'. Make sure you called GetFirstChild first
wxTreeMultiItem GetNextChild(const wxTreeMultiItem &item, int &cookie) const;
/** Returns the last child of this node. The type of 'item' needs to be of Node. Whenever not succesful,
- the item returned is not ok (IsOk = false). Upon success, a valid last child is returned. */\r
- wxTreeMultiItem GetLastChild(const wxTreeMultiItem &item) const;\r
-\r
- /** Returns the next sibling of the passed item. */\r
- wxTreeMultiItem GetNextSibling(wxTreeMultiItem const& item) const;\r
-\r
- /** Returns the previous sibling of the passed item. */\r
- wxTreeMultiItem GetPrevSibling(wxTreeMultiItem const& item) const;\r
-\r
- /** Returns the next item. "Next" is defined by the following order:\r
- - in case the current item has a child it is the first child of the current item;\r
- - in case the current item has a next sibling as the next sibling;\r
- - as the parent's (or one of its ancestor's) next sibling.\r
- */\r
- wxTreeMultiItem GetNext(wxTreeMultiItem const& item) const;\r
-\r
- /** Returns the previous item. "Previous" is defined by the following order:\r
- - in case the current item has a child it is the last child of the current item;\r
- - in case the current item has a previous sibling it is the previous sibling;\r
- - as the parent's (or one of its ancestor's) previous sibling.\r
- */\r
- wxTreeMultiItem GetPrevious(wxTreeMultiItem const& item) const;\r
-\r
-\r
- /** @}\r
- */\r
-\r
+ the item returned is not ok (IsOk = false). Upon success, a valid last child is returned. */
+ wxTreeMultiItem GetLastChild(const wxTreeMultiItem &item) const;
+
+ /** Returns the next sibling of the passed item. */
+ wxTreeMultiItem GetNextSibling(wxTreeMultiItem const& item) const;
+
+ /** Returns the previous sibling of the passed item. */
+ wxTreeMultiItem GetPrevSibling(wxTreeMultiItem const& item) const;
+
+ /** Returns the next item. "Next" is defined by the following order:
+ - in case the current item has a child it is the first child of the current item;
+ - in case the current item has a next sibling as the next sibling;
+ - as the parent's (or one of its ancestor's) next sibling.
+ */
+ wxTreeMultiItem GetNext(wxTreeMultiItem const& item) const;
+
+ /** Returns the previous item. "Previous" is defined by the following order:
+ - in case the current item has a child it is the last child of the current item;
+ - in case the current item has a previous sibling it is the previous sibling;
+ - as the parent's (or one of its ancestor's) previous sibling.
+ */
+ wxTreeMultiItem GetPrevious(wxTreeMultiItem const& item) const;
+
+
+ /** @}
+ */
+
/** @name Get and set methods
These methods allow you to set or get certain properties of the wxTreeMultiCtrl.
@{
beginning. */
void SetCaptionFont(const wxFont &font);
- /** @}\r
- */\r
-\r
- void OnDraw(wxDC& dc);\r
-\r
-private:\r
- DECLARE_EVENT_TABLE()\r
-};\r
+ /** @}
+ */
+
+ void OnDraw(wxDC& dc);
+
+private:
+ DECLARE_EVENT_TABLE()
+};
#endif