From 33328cd8828baafa97e8623e005b471486b61cc7 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Tue, 12 Sep 2006 21:05:20 +0000 Subject: [PATCH] Updated the C++ code for wx.gizmos.TreeListCtrl from the wxCode project. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41181 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- wxPython/contrib/gizmos/_treelist.i | 689 +++ wxPython/contrib/gizmos/gizmos.i | 557 +- .../gizmos/wxCode/include/wx/treelistctrl.h | 434 +- .../gizmos/wxCode/src/treelistctrl.cpp | 4841 ++++++++--------- wxPython/demo/TreeListCtrl.py | 7 +- wxPython/docs/CHANGES.txt | 19 +- wxPython/setup.py | 3 +- 7 files changed, 3120 insertions(+), 3430 deletions(-) create mode 100644 wxPython/contrib/gizmos/_treelist.i diff --git a/wxPython/contrib/gizmos/_treelist.i b/wxPython/contrib/gizmos/_treelist.i new file mode 100644 index 0000000000..105f25b90d --- /dev/null +++ b/wxPython/contrib/gizmos/_treelist.i @@ -0,0 +1,689 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: _treelist.i +// Purpose: wxTreeListCtrl and helpers +// +// Author: Robin Dunn +// +// Created: 12-Sept-2006 +// RCS-ID: $Id$ +// Copyright: (c) 2006 by Total Control Software +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +// Not a %module + + +//--------------------------------------------------------------------------- + +%{ +#include "wx/treelistctrl.h" +#include "wx/wxPython/pytree.h" + +%} + +//--------------------------------------------------------------------------- +%newgroup + + +MAKE_CONST_WXSTRING2(TreeListCtrlNameStr, wxT("treelistctrl")); + + +//---------------------------------------------------------------------------- +// wxTreeListCtrl - the multicolumn tree control +//---------------------------------------------------------------------------- + + + +enum { + DEFAULT_COL_WIDTH = 100 +}; + +// modes for navigation +enum { + wxTL_MODE_NAV_FULLTREE, + wxTL_MODE_NAV_EXPANDED, + wxTL_MODE_NAV_VISIBLE, + wxTL_MODE_NAV_LEVEL +}; + +// modes for FindItem +enum { + wxTL_MODE_FIND_EXACT, + wxTL_MODE_FIND_PARTIAL, + wxTL_MODE_FIND_NOCASE +}; + +// additional flag for HitTest +enum { + wxTREE_HITTEST_ONITEMCOLUMN +}; +%pythoncode { wx.TREE_HITTEST_ONITEMCOLUMN = TREE_HITTEST_ONITEMCOLUMN } + + +// additional style flags +enum { + wxTR_COLUMN_LINES, // put border around items + wxTR_VIRTUAL // The application provides items text on demand. +}; +%pythoncode { + wx.TR_COLUMN_LINES = TR_COLUMN_LINES + wxTR_VIRTUAL = TR_VIRTUAL +} + + +%pythoncode { +%#// Compatibility aliases for old names/values +TL_ALIGN_LEFT = wx.ALIGN_LEFT +TL_ALIGN_RIGHT = wx.ALIGN_RIGHT +TL_ALIGN_CENTER = wx.ALIGN_CENTER + +TL_SEARCH_VISIBLE = TL_MODE_NAV_VISIBLE +TL_SEARCH_LEVEL = TL_MODE_NAV_LEVEL +TL_SEARCH_FULL = TL_MODE_FIND_EXACT +TL_SEARCH_PARTIAL = TL_MODE_FIND_PARTIAL +TL_SEARCH_NOCASE = TL_MODE_FIND_NOCASE + +TR_DONT_ADJUST_MAC = 0 +wx.TR_DONT_ADJUST_MAC = TR_DONT_ADJUST_MAC +} + + + + +class wxTreeListColumnInfo: public wxObject { +public: + wxTreeListColumnInfo(const wxString& text = wxPyEmptyString, + int width = DEFAULT_COL_WIDTH, + int flag = wxALIGN_LEFT, + int image = -1, + bool shown = true, + bool edit = false); + + ~wxTreeListColumnInfo(); + + int GetAlignment() const; + wxString GetText() const; + int GetImage() const; + int GetSelectedImage() const; + size_t GetWidth() const; + bool IsEditable() const { return m_edit; } + bool IsShown() const { return m_shown; } + + // TODO: These all actually return wxTreeListColumnInfo&, any problem with doing it for Python too? + void SetAlignment(int alignment); + void SetText(const wxString& text); + void SetImage(int image); + void SetSelectedImage(int image); + void SetWidth(size_t with); + void SetEditable (bool edit); + void SetShown(bool shown); + +}; + + + + +%{ // C++ version of Python aware control +class wxPyTreeListCtrl : public wxTreeListCtrl { + DECLARE_ABSTRACT_CLASS(wxPyTreeListCtrl); +public: + wxPyTreeListCtrl() : wxTreeListCtrl() {} + wxPyTreeListCtrl(wxWindow *parent, wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxValidator &validator, + const wxString& name) : + wxTreeListCtrl(parent, id, pos, size, style, validator, name) {} + + virtual int OnCompareItems(const wxTreeItemId& item1, + const wxTreeItemId& item2) { + int rval = 0; + bool found; + wxPyBlock_t blocked = wxPyBeginBlockThreads(); + if ((found = wxPyCBH_findCallback(m_myInst, "OnCompareItems"))) { + PyObject *o1 = wxPyConstructObject((void*)&item1, wxT("wxTreeItemId"), 0); + PyObject *o2 = wxPyConstructObject((void*)&item2, wxT("wxTreeItemId"), 0); + rval = wxPyCBH_callCallback(m_myInst, Py_BuildValue("(OO)",o1,o2)); + Py_DECREF(o1); + Py_DECREF(o2); + } + wxPyEndBlockThreads(blocked); + if (! found) + rval = wxTreeListCtrl::OnCompareItems(item1, item2); + return rval; + } + + virtual wxString OnGetItemText( wxTreeItemData* item, long column ) const { + wxString rval; + bool found; + wxPyBlock_t blocked = wxPyBeginBlockThreads(); + if ((found = wxPyCBH_findCallback(m_myInst, "OnGetItemText"))) { + PyObject* ro; + PyObject* itemo = wxPyConstructObject((void*)&item, wxT("wxTreeItemId"), 0); + ro = wxPyCBH_callCallbackObj(m_myInst, Py_BuildValue("(Oi)", itemo, column)); + Py_DECREF(itemo); + if (ro) { + rval = Py2wxString(ro); + Py_DECREF(ro); + } + } + wxPyEndBlockThreads(blocked); + if (! found) + rval = wxTreeListCtrl::OnGetItemText(item, column); + return rval; + } + + PYPRIVATE; +}; + +IMPLEMENT_ABSTRACT_CLASS(wxPyTreeListCtrl, wxTreeListCtrl) + +%} + + + + + + +MustHaveApp(wxPyTreeListCtrl); + +%rename(TreeListCtrl) wxPyTreeListCtrl; +class wxPyTreeListCtrl : public wxControl +{ +public: + %pythonAppend wxPyTreeListCtrl "self._setOORInfo(self);self._setCallbackInfo(self, TreeListCtrl)" + %pythonAppend wxPyTreeListCtrl() "" + + wxPyTreeListCtrl(wxWindow *parent, wxWindowID id = -1, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxTR_DEFAULT_STYLE, + const wxValidator &validator = wxDefaultValidator, + const wxString& name = wxPyTreeListCtrlNameStr ); + %RenameCtor(PreTreeListCtrl, wxPyTreeListCtrl()); + + bool Create(wxWindow *parent, wxWindowID id = -1, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxTR_DEFAULT_STYLE, + const wxValidator &validator = wxDefaultValidator, + const wxString& name = wxPyTreeListCtrlNameStr ); + + void _setCallbackInfo(PyObject* self, PyObject* _class); + + + // get the total number of items in the control + size_t GetCount() const; + + // indent is the number of pixels the children are indented relative to + // the parents position. SetIndent() also redraws the control + // immediately. + unsigned int GetIndent() const; + void SetIndent(unsigned int indent); + + // line spacing is the space above and below the text on each line + unsigned int GetLineSpacing() const; + void SetLineSpacing(unsigned int spacing); + + // image list: these functions allow to associate an image list with + // the control and retrieve it. Note that when assigned with + // SetImageList, the control does _not_ delete + // the associated image list when it's deleted in order to allow image + // lists to be shared between different controls. If you use + // AssignImageList, the control _does_ delete the image list. + // + // The normal image list is for the icons which correspond to the + // normal tree item state (whether it is selected or not). + // Additionally, the application might choose to show a state icon + // which corresponds to an app-defined item state (for example, + // checked/unchecked) which are taken from the state image list. + wxImageList *GetImageList() const; + wxImageList *GetStateImageList() const; + wxImageList *GetButtonsImageList() const; + + void SetImageList(wxImageList *imageList); + void SetStateImageList(wxImageList *imageList); + void SetButtonsImageList(wxImageList *imageList); + + %disownarg( wxImageList *imageList ); + void AssignImageList(wxImageList *imageList); + void AssignStateImageList(wxImageList *imageList); + void AssignButtonsImageList(wxImageList *imageList); + %cleardisown( wxImageList *imageList ); + + + // adds a column + void AddColumn (const wxString& text, + int width = DEFAULT_COL_WIDTH, + int flag = wxALIGN_LEFT, + int image = -1, + bool shown = true, + bool edit = false); + %Rename(AddColumnInfo, void, AddColumn(const wxTreeListColumnInfo& col)); + + // inserts a column before the given one + void InsertColumn (int before, + const wxString& text, + int width = DEFAULT_COL_WIDTH, + int flag = wxALIGN_LEFT, + int image = -1, + bool shown = true, + bool edit = false); + %Rename(InsertColumnInfo, void, InsertColumn(size_t before, const wxTreeListColumnInfo& col)); + + // deletes the given column - does not delete the corresponding column + // of each item + void RemoveColumn(size_t column); + + // returns the number of columns in the ctrl + size_t GetColumnCount() const; + + // tells which column is the "main" one, i.e. the "threaded" one + void SetMainColumn(size_t column); + size_t GetMainColumn() const; + + void SetColumn (int column, const wxTreeListColumnInfo& colInfo); + wxTreeListColumnInfo& GetColumn (int column); + + void SetColumnText (int column, const wxString& text); + wxString GetColumnText (int column) const; + + void SetColumnWidth (int column, int width); + int GetColumnWidth (int column) const; + + void SetColumnAlignment (int column, int flag); + int GetColumnAlignment (int column) const; + + void SetColumnImage (int column, int image); + int GetColumnImage (int column) const; + + void SetColumnShown (int column, bool shown = true); + bool IsColumnShown (int column) const; + %pythoncode { ShowColumn = SetColumnShown } + + void SetColumnEditable (int column, bool edit = true); + bool IsColumnEditable (int column) const; + + + + + %extend { + // retrieves item's label of the given column (main column by default) + wxString GetItemText(const wxTreeItemId& item, int column = -1) { + if (column < 0) column = self->GetMainColumn(); + return self->GetItemText(item, column); + } + + // get one of the images associated with the item (normal by default) + int GetItemImage(const wxTreeItemId& item, int column = -1, + wxTreeItemIcon which = wxTreeItemIcon_Normal) { + if (column < 0) column = self->GetMainColumn(); + return self->GetItemImage(item, column, which); + } + + // set item's label (main column by default) + void SetItemText(const wxTreeItemId& item, const wxString& text, int column = -1) { + if (column < 0) column = self->GetMainColumn(); + self->SetItemText(item, column, text); + } + + // set one of the images associated with the item (normal by default) + // the which parameter is ignored for all columns but the main one + void SetItemImage(const wxTreeItemId& item, int image, int column = -1, + wxTreeItemIcon which = wxTreeItemIcon_Normal) { + if (column < 0) column = self->GetMainColumn(); + self->SetItemImage(item, column, image, which); + } + + + // [Get|Set]ItemData substitutes. Automatically create wxPyTreeItemData + // if needed. + wxPyTreeItemData* GetItemData(const wxTreeItemId& item) { + wxPyTreeItemData* data = (wxPyTreeItemData*)self->GetItemData(item); + if (data == NULL) { + data = new wxPyTreeItemData(); + data->SetId(item); // set the id + self->SetItemData(item, data); + } + return data; + } + + %disownarg( wxPyTreeItemData* data ); + void SetItemData(const wxTreeItemId& item, wxPyTreeItemData* data) { + data->SetId(item); // set the id + self->SetItemData(item, data); + } + %cleardisown(wxPyTreeItemData* data ); + + // [Get|Set]ItemPyData are short-cuts. Also made somewhat crash-proof by + // automatically creating data classes. + PyObject* GetItemPyData(const wxTreeItemId& item) { + wxPyTreeItemData* data = (wxPyTreeItemData*)self->GetItemData(item); + if (data == NULL) { + data = new wxPyTreeItemData(); + data->SetId(item); // set the id + self->SetItemData(item, data); + } + return data->GetData(); + } + + void SetItemPyData(const wxTreeItemId& item, PyObject* obj) { + wxPyTreeItemData* data = (wxPyTreeItemData*)self->GetItemData(item); + if (data == NULL) { + data = new wxPyTreeItemData(obj); + data->SetId(item); // set the id + self->SetItemData(item, data); + } else + data->SetData(obj); + } + } + %pythoncode { GetPyData = GetItemPyData } + %pythoncode { SetPyData = SetItemPyData } + + + bool GetItemBold(const wxTreeItemId& item) const; + wxColour GetItemTextColour(const wxTreeItemId& item) const; + wxColour GetItemBackgroundColour(const wxTreeItemId& item) const; + wxFont GetItemFont(const wxTreeItemId& item) const; + + + // force appearance of [+] button near the item. This is useful to + // allow the user to expand the items which don't have any children now + // - but instead add them only when needed, thus minimizing memory + // usage and loading time. + void SetItemHasChildren(const wxTreeItemId& item, bool has = true); + + // the item will be shown in bold + void SetItemBold(const wxTreeItemId& item, bool bold = true); + + // set the item's text colour + void SetItemTextColour(const wxTreeItemId& item, const wxColour& colour); + + // set the item's background colour + void SetItemBackgroundColour(const wxTreeItemId& item, + const wxColour& colour); + + // set the item's font (should be of the same height for all items) + void SetItemFont(const wxTreeItemId& item, const wxFont& font); + + + + // is the item visible (it might be outside the view or not expanded)? + bool IsVisible(const wxTreeItemId& item) const; + + // does the item has any children? + bool HasChildren(const wxTreeItemId& item) const; + %pythoncode { ItemHasChildren = HasChildren } + + // is the item expanded (only makes sense if HasChildren())? + bool IsExpanded(const wxTreeItemId& item) const; + + // is this item currently selected (the same as has focus)? + bool IsSelected(const wxTreeItemId& item) const; + + // is item text in bold font? + bool IsBold(const wxTreeItemId& item) const; + + + // if 'recursively' is False, only immediate children count, otherwise + // the returned number is the number of all items in this branch + size_t GetChildrenCount(const wxTreeItemId& item, bool recursively = true); + + + // wxTreeItemId.IsOk() will return False if there is no such item + + // get the root tree item + wxTreeItemId GetRootItem() const; + + // get the item currently selected (may return NULL if no selection) + wxTreeItemId GetSelection() const; + + // get the items currently selected, return the number of such item + //size_t GetSelections(wxArrayTreeItemIds&) const; + %extend { + PyObject* GetSelections() { + wxPyBlock_t blocked = wxPyBeginBlockThreads(); + PyObject* rval = PyList_New(0); + wxArrayTreeItemIds array; + size_t num, x; + num = self->GetSelections(array); + for (x=0; x < num; x++) { + wxTreeItemId *tii = new wxTreeItemId(array.Item(x)); + PyObject* item = wxPyConstructObject((void*)tii, wxT("wxTreeItemId"), true); + PyList_Append(rval, item); + Py_DECREF(item); + } + wxPyEndBlockThreads(blocked); + return rval; + } + } + + + // get the parent of this item (may return NULL if root) + wxTreeItemId GetItemParent(const wxTreeItemId& item) const; + + // for this enumeration function you must pass in a "cookie" parameter + // which is opaque for the application but is necessary for the library + // to make these functions reentrant (i.e. allow more than one + // enumeration on one and the same object simultaneously). Of course, + // the "cookie" passed to GetFirstChild() and GetNextChild() should be + // the same! + + + // NOTE: These are a copy of the same methods in _treectrl.i, be sure to + // update both at the same time. (Or find a good way to refactor!) + %extend { + // Get the first child of this item. Returns a wxTreeItemId and an + // opaque "cookie" value that should be passed to GetNextChild in + // order to continue the search. + PyObject* GetFirstChild(const wxTreeItemId& item) { + void* cookie = 0; + wxTreeItemId* ritem = new wxTreeItemId(self->GetFirstChild(item, cookie)); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); + PyObject* tup = PyTuple_New(2); + PyTuple_SET_ITEM(tup, 0, wxPyConstructObject(ritem, wxT("wxTreeItemId"), true)); + PyTuple_SET_ITEM(tup, 1, wxPyMakeSwigPtr(cookie, wxT("void"))); + wxPyEndBlockThreads(blocked); + return tup; + } + + + // Get the next child of this item. The cookie parameter is the 2nd + // value returned from GetFirstChild or the previous GetNextChild. + // Returns a wxTreeItemId and an opaque "cookie" value that should be + // passed to GetNextChild in order to continue the search. + PyObject* GetNextChild(const wxTreeItemId& item, void* cookie) { + wxTreeItemId* ritem = new wxTreeItemId(self->GetNextChild(item, cookie)); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); + PyObject* tup = PyTuple_New(2); + PyTuple_SET_ITEM(tup, 0, wxPyConstructObject(ritem, wxT("wxTreeItemId"), true)); + PyTuple_SET_ITEM(tup, 1, wxPyMakeSwigPtr(cookie, wxT("void"))); + wxPyEndBlockThreads(blocked); + return tup; + } + + + PyObject* GetLastChild(const wxTreeItemId& item) { + void* cookie = 0; + wxTreeItemId* ritem = new wxTreeItemId(self->GetLastChild(item, cookie)); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); + PyObject* tup = PyTuple_New(2); + PyTuple_SET_ITEM(tup, 0, wxPyConstructObject(ritem, wxT("wxTreeItemId"), true)); + PyTuple_SET_ITEM(tup, 1, wxPyMakeSwigPtr(cookie, wxT("void"))); + wxPyEndBlockThreads(blocked); + return tup; + } + + + PyObject* GetPrevChild(const wxTreeItemId& item, void* cookie) { + wxTreeItemId* ritem = new wxTreeItemId(self->GetPrevChild(item, cookie)); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); + PyObject* tup = PyTuple_New(2); + PyTuple_SET_ITEM(tup, 0, wxPyConstructObject(ritem, wxT("wxTreeItemId"), true)); + PyTuple_SET_ITEM(tup, 1, wxPyMakeSwigPtr(cookie, wxT("void"))); + wxPyEndBlockThreads(blocked); + return tup; + } + } + + + // get the next sibling of this item + wxTreeItemId GetNextSibling(const wxTreeItemId& item) const; + + // get the previous sibling + wxTreeItemId GetPrevSibling(const wxTreeItemId& item) const; + + + // get item in the full tree (currently only for internal use) + wxTreeItemId GetNext(const wxTreeItemId& item) const; + wxTreeItemId GetPrev(const wxTreeItemId& item) const; + + // get expanded item, see IsExpanded() + wxTreeItemId GetFirstExpandedItem() const; + wxTreeItemId GetNextExpanded(const wxTreeItemId& item) const; + wxTreeItemId GetPrevExpanded(const wxTreeItemId& item) const; + + // get visible item, see IsVisible() + wxTreeItemId GetFirstVisibleItem(bool fullRow = false) const; + wxTreeItemId GetNextVisible(const wxTreeItemId& item, bool fullRow = false) const; + wxTreeItemId GetPrevVisible(const wxTreeItemId& item, bool fullRow = false) const; + + + + %disownarg( wxPyTreeItemData* data ); + + // add the root node to the tree + wxTreeItemId AddRoot(const wxString& text, + int image = -1, int selectedImage = -1, + wxPyTreeItemData *data = NULL); + + // insert a new item in as the first child of the parent + wxTreeItemId PrependItem(const wxTreeItemId& parent, + const wxString& text, + int image = -1, int selectedImage = -1, + wxPyTreeItemData *data = NULL); + + // insert a new item after a given one + wxTreeItemId InsertItem(const wxTreeItemId& parent, + const wxTreeItemId& idPrevious, + const wxString& text, + int image = -1, int selectedImage = -1, + wxPyTreeItemData *data = NULL); + + // insert a new item before the one with the given index + %Rename(InsertItemBefore, + wxTreeItemId, InsertItem(const wxTreeItemId& parent, + size_t index, + const wxString& text, + int image = -1, int selectedImage = -1, + wxPyTreeItemData *data = NULL)); + + // insert a new item in as the last child of the parent + wxTreeItemId AppendItem(const wxTreeItemId& parent, + const wxString& text, + int image = -1, int selectedImage = -1, + wxPyTreeItemData *data = NULL); + + %cleardisown(wxPyTreeItemData* data ); + + // delete this item and associated data if any + void Delete(const wxTreeItemId& item); + + // delete all children (but don't delete the item itself) + // NB: this won't send wxEVT_COMMAND_TREE_ITEM_DELETED events + void DeleteChildren(const wxTreeItemId& item); + + // delete all items from the tree + // NB: this won't send wxEVT_COMMAND_TREE_ITEM_DELETED events + void DeleteRoot(); + %pythoncode { DeleteAllItems = DeleteRoot } + + + + // expand this item + void Expand(const wxTreeItemId& item); + + // expand this item and all subitems recursively + void ExpandAll(const wxTreeItemId& item); + + // collapse the item without removing its children + void Collapse(const wxTreeItemId& item); + + // collapse the item and remove all children + void CollapseAndReset(const wxTreeItemId& item); + + // toggles the current state + void Toggle(const wxTreeItemId& item); + + // remove the selection from currently selected item (if any) + void Unselect(); + void UnselectAll(); + + // select this item + void SelectItem(const wxTreeItemId& item, + const wxTreeItemId& last = (wxTreeItemId*)NULL, + bool unselect_others=true); + + void SelectAll(); + + // make sure this item is visible (expanding the parent item and/or + // scrolling to this item if necessary) + void EnsureVisible(const wxTreeItemId& item); + + // scroll to this item (but don't expand its parent) + void ScrollTo(const wxTreeItemId& item); + + // Returns wxTreeItemId, flags, and column + wxTreeItemId HitTest(const wxPoint& point, int& OUTPUT, int& OUTPUT); + + %extend { + // get the bounding rectangle of the item (or of its label only) + PyObject* GetBoundingRect(const wxTreeItemId& item, bool textOnly = false) { + wxRect rect; + if (self->GetBoundingRect(item, rect, textOnly)) { + wxPyBlock_t blocked = wxPyBeginBlockThreads(); + wxRect* r = new wxRect(rect); + PyObject* val = wxPyConstructObject((void*)r, wxT("wxRect"), 1); + wxPyEndBlockThreads(blocked); + return val; + } + else { + RETURN_NONE(); + } + } + } + + + %extend { + // Start editing the item label: this (temporarily) replaces the item + // with a one line edit control. The item will be selected if it hadn't + // been before. + void EditLabel(const wxTreeItemId& item, int column = -1) { + if (column < 0) column = self->GetMainColumn(); + self->EditLabel(item, column); + } + } + %pythoncode { Edit = EditLabel } + + // sort the children of this item using OnCompareItems + void SortChildren(const wxTreeItemId& item); + + // searching + wxTreeItemId FindItem (const wxTreeItemId& item, const wxString& str, int flags = 0); + + // drop over item + void SetDragItem (const wxTreeItemId& item = (wxTreeItemId*)NULL); + + wxWindow* GetHeaderWindow() const; + wxScrolledWindow* GetMainWindow() const; + +}; + +//---------------------------------------------------------------------- + +%init %{ + wxPyPtrTypeMap_Add("wxTreeListCtrl", "wxPyTreeListCtrl"); +%} + +//---------------------------------------------------------------------- diff --git a/wxPython/contrib/gizmos/gizmos.i b/wxPython/contrib/gizmos/gizmos.i index 0c272612c7..faf2636617 100644 --- a/wxPython/contrib/gizmos/gizmos.i +++ b/wxPython/contrib/gizmos/gizmos.i @@ -32,9 +32,6 @@ #include #include -#include "wx/treelistctrl.h" -#include "wx/wxPython/pytree.h" - %} //--------------------------------------------------------------------------- @@ -47,7 +44,6 @@ MAKE_CONST_WXSTRING2(DynamicSashNameStr, wxT("dynamicSashWindow")); MAKE_CONST_WXSTRING2(EditableListBoxNameStr, wxT("editableListBox")); -MAKE_CONST_WXSTRING2(TreeListCtrlNameStr, wxT("treelistctrl")); MAKE_CONST_WXSTRING(StaticPictureNameStr); MAKE_CONST_WXSTRING_NOSWIG(EmptyString); @@ -417,553 +413,9 @@ public: -//---------------------------------------------------------------------------- -// wxTreeListCtrl - the multicolumn tree control -//---------------------------------------------------------------------------- - -enum wxTreeListColumnAlign { - wxTL_ALIGN_LEFT, - wxTL_ALIGN_RIGHT, - wxTL_ALIGN_CENTER -}; - - - -enum { - wxTREE_HITTEST_ONITEMCOLUMN -}; - - -enum { - // flags for FindItem - wxTL_SEARCH_VISIBLE, - wxTL_SEARCH_LEVEL, - wxTL_SEARCH_FULL, - wxTL_SEARCH_PARTIAL, - wxTL_SEARCH_NOCASE -}; - -enum { - // extra tree styles - wxTR_DONT_ADJUST_MAC -}; -%pythoncode { wx.TR_DONT_ADJUST_MAC = TR_DONT_ADJUST_MAC } - - -class wxTreeListColumnInfo: public wxObject { -public: - wxTreeListColumnInfo(const wxString& text = wxPyEmptyString, - int image = -1, - size_t width = 100, - bool shown = true, - wxTreeListColumnAlign alignment = wxTL_ALIGN_LEFT); - - ~wxTreeListColumnInfo(); - - bool GetShown() const; - wxTreeListColumnAlign GetAlignment() const; - wxString GetText() const; - int GetImage() const; - int GetSelectedImage() const; - size_t GetWidth() const; - - // TODO: These all actually return wxTreeListColumnInfo&, any problem with doing it for Python too? - void SetShown(bool shown); - void SetAlignment(wxTreeListColumnAlign alignment); - void SetText(const wxString& text); - void SetImage(int image); - void SetSelectedImage(int image); - void SetWidth(size_t with); -}; - - - - -%{ // C++ version of Python aware control -class wxPyTreeListCtrl : public wxTreeListCtrl { - DECLARE_ABSTRACT_CLASS(wxPyTreeListCtrl); -public: - wxPyTreeListCtrl() : wxTreeListCtrl() {} - wxPyTreeListCtrl(wxWindow *parent, wxWindowID id, - const wxPoint& pos, - const wxSize& size, - long style, - const wxValidator &validator, - const wxString& name) : - wxTreeListCtrl(parent, id, pos, size, style, validator, name) {} - - int OnCompareItems(const wxTreeItemId& item1, - const wxTreeItemId& item2) { - int rval = 0; - bool found; - wxPyBlock_t blocked = wxPyBeginBlockThreads(); - if ((found = wxPyCBH_findCallback(m_myInst, "OnCompareItems"))) { - PyObject *o1 = wxPyConstructObject((void*)&item1, wxT("wxTreeItemId"), 0); - PyObject *o2 = wxPyConstructObject((void*)&item2, wxT("wxTreeItemId"), 0); - rval = wxPyCBH_callCallback(m_myInst, Py_BuildValue("(OO)",o1,o2)); - Py_DECREF(o1); - Py_DECREF(o2); - } - wxPyEndBlockThreads(blocked); - if (! found) - rval = wxTreeListCtrl::OnCompareItems(item1, item2); - return rval; - } - PYPRIVATE; -}; - -IMPLEMENT_ABSTRACT_CLASS(wxPyTreeListCtrl, wxTreeListCtrl) - -%} - - - - - - -MustHaveApp(wxPyTreeListCtrl); - -%rename(TreeListCtrl) wxPyTreeListCtrl; -class wxPyTreeListCtrl : public wxControl -{ -public: - %pythonAppend wxPyTreeListCtrl "self._setOORInfo(self);self._setCallbackInfo(self, TreeListCtrl)" - %pythonAppend wxPyTreeListCtrl() "" - - wxPyTreeListCtrl(wxWindow *parent, wxWindowID id = -1, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = wxTR_DEFAULT_STYLE, - const wxValidator &validator = wxDefaultValidator, - const wxString& name = wxPyTreeListCtrlNameStr ); - %RenameCtor(PreTreeListCtrl, wxPyTreeListCtrl()); - - bool Create(wxWindow *parent, wxWindowID id = -1, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = wxTR_DEFAULT_STYLE, - const wxValidator &validator = wxDefaultValidator, - const wxString& name = wxPyTreeListCtrlNameStr ); - - void _setCallbackInfo(PyObject* self, PyObject* _class); - - - // get the total number of items in the control - size_t GetCount() const; - - // indent is the number of pixels the children are indented relative to - // the parents position. SetIndent() also redraws the control - // immediately. - unsigned int GetIndent() const; - void SetIndent(unsigned int indent); - - // line spacing is the space above and below the text on each line - unsigned int GetLineSpacing() const; - void SetLineSpacing(unsigned int spacing); - - // image list: these functions allow to associate an image list with - // the control and retrieve it. Note that when assigned with - // SetImageList, the control does _not_ delete - // the associated image list when it's deleted in order to allow image - // lists to be shared between different controls. If you use - // AssignImageList, the control _does_ delete the image list. - // - // The normal image list is for the icons which correspond to the - // normal tree item state (whether it is selected or not). - // Additionally, the application might choose to show a state icon - // which corresponds to an app-defined item state (for example, - // checked/unchecked) which are taken from the state image list. - wxImageList *GetImageList() const; - wxImageList *GetStateImageList() const; - wxImageList *GetButtonsImageList() const; - - void SetImageList(wxImageList *imageList); - void SetStateImageList(wxImageList *imageList); - void SetButtonsImageList(wxImageList *imageList); - - %disownarg( wxImageList *imageList ); - void AssignImageList(wxImageList *imageList); - void AssignStateImageList(wxImageList *imageList); - void AssignButtonsImageList(wxImageList *imageList); - %cleardisown( wxImageList *imageList ); - - - // adds a column - void AddColumn(const wxString& text); -// void AddColumn(const wxString& text, -// size_t width, -// wxTreeListColumnAlign alignment = wxTL_ALIGN_LEFT); - %Rename(AddColumnInfo, void, AddColumn(const wxTreeListColumnInfo& col)); - - // inserts a column before the given one - void InsertColumn(size_t before, const wxString& text); - %Rename(InsertColumnInfo, void, InsertColumn(size_t before, const wxTreeListColumnInfo& col)); - - // deletes the given column - does not delete the corresponding column - // of each item - void RemoveColumn(size_t column); - - // returns the number of columns in the ctrl - size_t GetColumnCount() const; - - void SetColumnWidth(size_t column, size_t width); - int GetColumnWidth(size_t column) const; - - // tells which column is the "main" one, i.e. the "threaded" one - void SetMainColumn(size_t column); - size_t GetMainColumn() const; - - void SetColumnText(size_t column, const wxString& text); - wxString GetColumnText(size_t column) const; - - void SetColumn(size_t column, const wxTreeListColumnInfo& info); - wxTreeListColumnInfo& GetColumn(size_t column); - - // other column-related methods - void SetColumnAlignment(size_t column, wxTreeListColumnAlign align); - wxTreeListColumnAlign GetColumnAlignment(size_t column) const; - - void SetColumnImage(size_t column, int image); - int GetColumnImage(size_t column) const; - - void ShowColumn(size_t column, bool shown); - bool IsColumnShown(size_t column) const; - - %extend { - // retrieves item's label of the given column (main column by default) - wxString GetItemText(const wxTreeItemId& item, int column = -1) { - if (column < 0) column = self->GetMainColumn(); - return self->GetItemText(item, column); - } - - // get one of the images associated with the item (normal by default) - int GetItemImage(const wxTreeItemId& item, int column = -1, - wxTreeItemIcon which = wxTreeItemIcon_Normal) { - if (column < 0) column = self->GetMainColumn(); - return self->GetItemImage(item, column, which); - } - - // set item's label (main column by default) - void SetItemText(const wxTreeItemId& item, const wxString& text, int column = -1) { - if (column < 0) column = self->GetMainColumn(); - self->SetItemText(item, column, text); - } - - // set one of the images associated with the item (normal by default) - // the which parameter is ignored for all columns but the main one - void SetItemImage(const wxTreeItemId& item, int image, int column = -1, - wxTreeItemIcon which = wxTreeItemIcon_Normal) { - if (column < 0) column = self->GetMainColumn(); - self->SetItemImage(item, column, image, which); - } - - - // [Get|Set]ItemData substitutes. Automatically create wxPyTreeItemData - // if needed. - wxPyTreeItemData* GetItemData(const wxTreeItemId& item) { - wxPyTreeItemData* data = (wxPyTreeItemData*)self->GetItemData(item); - if (data == NULL) { - data = new wxPyTreeItemData(); - data->SetId(item); // set the id - self->SetItemData(item, data); - } - return data; - } - - %disownarg( wxPyTreeItemData* data ); - void SetItemData(const wxTreeItemId& item, wxPyTreeItemData* data) { - data->SetId(item); // set the id - self->SetItemData(item, data); - } - %cleardisown(wxPyTreeItemData* data ); - - // [Get|Set]ItemPyData are short-cuts. Also made somewhat crash-proof by - // automatically creating data classes. - PyObject* GetItemPyData(const wxTreeItemId& item) { - wxPyTreeItemData* data = (wxPyTreeItemData*)self->GetItemData(item); - if (data == NULL) { - data = new wxPyTreeItemData(); - data->SetId(item); // set the id - self->SetItemData(item, data); - } - return data->GetData(); - } - - void SetItemPyData(const wxTreeItemId& item, PyObject* obj) { - wxPyTreeItemData* data = (wxPyTreeItemData*)self->GetItemData(item); - if (data == NULL) { - data = new wxPyTreeItemData(obj); - data->SetId(item); // set the id - self->SetItemData(item, data); - } else - data->SetData(obj); - } - } - %pythoncode { GetPyData = GetItemPyData } - %pythoncode { SetPyData = SetItemPyData } - - - // force appearance of [+] button near the item. This is useful to - // allow the user to expand the items which don't have any children now - // - but instead add them only when needed, thus minimizing memory - // usage and loading time. - void SetItemHasChildren(const wxTreeItemId& item, bool has = true); - - // the item will be shown in bold - void SetItemBold(const wxTreeItemId& item, bool bold = true); - - // set the item's text colour - void SetItemTextColour(const wxTreeItemId& item, const wxColour& colour); - - // set the item's background colour - void SetItemBackgroundColour(const wxTreeItemId& item, - const wxColour& colour); - - // set the item's font (should be of the same height for all items) - void SetItemFont(const wxTreeItemId& item, const wxFont& font); - - - bool GetItemBold(const wxTreeItemId& item) const; - wxColour GetItemTextColour(const wxTreeItemId& item) const; - wxColour GetItemBackgroundColour(const wxTreeItemId& item) const; - wxFont GetItemFont(const wxTreeItemId& item) const; - - // is the item visible (it might be outside the view or not expanded)? - bool IsVisible(const wxTreeItemId& item) const; - - // does the item has any children? - bool ItemHasChildren(const wxTreeItemId& item) const; - - // is the item expanded (only makes sense if HasChildren())? - bool IsExpanded(const wxTreeItemId& item) const; - - // is this item currently selected (the same as has focus)? - bool IsSelected(const wxTreeItemId& item) const; - - // is item text in bold font? - bool IsBold(const wxTreeItemId& item) const; - - // if 'recursively' is False, only immediate children count, otherwise - // the returned number is the number of all items in this branch - size_t GetChildrenCount(const wxTreeItemId& item, bool recursively = true); - - - // wxTreeItemId.IsOk() will return False if there is no such item - - // get the root tree item - wxTreeItemId GetRootItem() const; - - // get the item currently selected (may return NULL if no selection) - wxTreeItemId GetSelection() const; - - // get the items currently selected, return the number of such item - //size_t GetSelections(wxArrayTreeItemIds&) const; - %extend { - PyObject* GetSelections() { - wxPyBlock_t blocked = wxPyBeginBlockThreads(); - PyObject* rval = PyList_New(0); - wxArrayTreeItemIds array; - size_t num, x; - num = self->GetSelections(array); - for (x=0; x < num; x++) { - wxTreeItemId *tii = new wxTreeItemId(array.Item(x)); - PyObject* item = wxPyConstructObject((void*)tii, wxT("wxTreeItemId"), true); - PyList_Append(rval, item); - Py_DECREF(item); - } - wxPyEndBlockThreads(blocked); - return rval; - } - } - - - // get the parent of this item (may return NULL if root) - wxTreeItemId GetItemParent(const wxTreeItemId& item) const; - - // for this enumeration function you must pass in a "cookie" parameter - // which is opaque for the application but is necessary for the library - // to make these functions reentrant (i.e. allow more than one - // enumeration on one and the same object simultaneously). Of course, - // the "cookie" passed to GetFirstChild() and GetNextChild() should be - // the same! - - - // NOTE: These are a copy of the same methods in _treectrl.i, be sure to - // update both at the same time. (Or find a good way to refactor!) - %extend { - // Get the first child of this item. Returns a wxTreeItemId and an - // opaque "cookie" value that should be passed to GetNextChild in - // order to continue the search. - PyObject* GetFirstChild(const wxTreeItemId& item) { - void* cookie = 0; - wxTreeItemId* ritem = new wxTreeItemId(self->GetFirstChild(item, cookie)); - wxPyBlock_t blocked = wxPyBeginBlockThreads(); - PyObject* tup = PyTuple_New(2); - PyTuple_SET_ITEM(tup, 0, wxPyConstructObject(ritem, wxT("wxTreeItemId"), true)); - PyTuple_SET_ITEM(tup, 1, wxPyMakeSwigPtr(cookie, wxT("void"))); - wxPyEndBlockThreads(blocked); - return tup; - } - - - // Get the next child of this item. The cookie parameter is the 2nd - // value returned from GetFirstChild or the previous GetNextChild. - // Returns a wxTreeItemId and an opaque "cookie" value that should be - // passed to GetNextChild in order to continue the search. - PyObject* GetNextChild(const wxTreeItemId& item, void* cookie) { - wxTreeItemId* ritem = new wxTreeItemId(self->GetNextChild(item, cookie)); - wxPyBlock_t blocked = wxPyBeginBlockThreads(); - PyObject* tup = PyTuple_New(2); - PyTuple_SET_ITEM(tup, 0, wxPyConstructObject(ritem, wxT("wxTreeItemId"), true)); - PyTuple_SET_ITEM(tup, 1, wxPyMakeSwigPtr(cookie, wxT("void"))); - wxPyEndBlockThreads(blocked); - return tup; - } - - - // TODO: GetPrevChild - - } - - // get the last child of this item - this method doesn't use cookies - wxTreeItemId GetLastChild(const wxTreeItemId& item) const; - - // get the next sibling of this item - wxTreeItemId GetNextSibling(const wxTreeItemId& item) const; - - // get the previous sibling - wxTreeItemId GetPrevSibling(const wxTreeItemId& item) const; - - // get first visible item - wxTreeItemId GetFirstVisibleItem() const; - - // get the next visible item: item must be visible itself! - // see IsVisible() and wxTreeCtrl::GetFirstVisibleItem() - wxTreeItemId GetNextVisible(const wxTreeItemId& item) const; - - // get the previous visible item: item must be visible itself! - wxTreeItemId GetPrevVisible(const wxTreeItemId& item) const; - - // Only for internal use right now, but should probably be public - wxTreeItemId GetNext(const wxTreeItemId& item) const; - - - %disownarg( wxPyTreeItemData* data ); - - // add the root node to the tree - wxTreeItemId AddRoot(const wxString& text, - int image = -1, int selectedImage = -1, - wxPyTreeItemData *data = NULL); - - // insert a new item in as the first child of the parent - wxTreeItemId PrependItem(const wxTreeItemId& parent, - const wxString& text, - int image = -1, int selectedImage = -1, - wxPyTreeItemData *data = NULL); - - // insert a new item after a given one - wxTreeItemId InsertItem(const wxTreeItemId& parent, - const wxTreeItemId& idPrevious, - const wxString& text, - int image = -1, int selectedImage = -1, - wxPyTreeItemData *data = NULL); - - // insert a new item before the one with the given index - %Rename(InsertItemBefore, - wxTreeItemId, InsertItem(const wxTreeItemId& parent, - size_t index, - const wxString& text, - int image = -1, int selectedImage = -1, - wxPyTreeItemData *data = NULL)); - - // insert a new item in as the last child of the parent - wxTreeItemId AppendItem(const wxTreeItemId& parent, - const wxString& text, - int image = -1, int selectedImage = -1, - wxPyTreeItemData *data = NULL); - - %cleardisown(wxPyTreeItemData* data ); - - // delete this item and associated data if any - void Delete(const wxTreeItemId& item); - - // delete all children (but don't delete the item itself) - // NB: this won't send wxEVT_COMMAND_TREE_ITEM_DELETED events - void DeleteChildren(const wxTreeItemId& item); - - // delete all items from the tree - // NB: this won't send wxEVT_COMMAND_TREE_ITEM_DELETED events - void DeleteAllItems(); - - // expand this item - void Expand(const wxTreeItemId& item); - - // expand this item and all subitems recursively - void ExpandAll(const wxTreeItemId& item); - - // collapse the item without removing its children - void Collapse(const wxTreeItemId& item); - - // collapse the item and remove all children - void CollapseAndReset(const wxTreeItemId& item); - - // toggles the current state - void Toggle(const wxTreeItemId& item); - - // remove the selection from currently selected item (if any) - void Unselect(); - void UnselectAll(); - - // select this item - void SelectItem(const wxTreeItemId& item, bool unselect_others=true, - bool extended_select=false); - - void SelectAll(bool extended_select=false); - - // make sure this item is visible (expanding the parent item and/or - // scrolling to this item if necessary) - void EnsureVisible(const wxTreeItemId& item); - - // scroll to this item (but don't expand its parent) - void ScrollTo(const wxTreeItemId& item); - - // Returns wxTreeItemId, flags, and column - wxTreeItemId HitTest(const wxPoint& point, int& OUTPUT, int& OUTPUT); - - %extend { - // get the bounding rectangle of the item (or of its label only) - PyObject* GetBoundingRect(const wxTreeItemId& item, bool textOnly = false) { - wxRect rect; - if (self->GetBoundingRect(item, rect, textOnly)) { - wxPyBlock_t blocked = wxPyBeginBlockThreads(); - wxRect* r = new wxRect(rect); - PyObject* val = wxPyConstructObject((void*)r, wxT("wxRect"), 1); - wxPyEndBlockThreads(blocked); - return val; - } - else { - RETURN_NONE(); - } - } - } - - - // Start editing the item label: this (temporarily) replaces the item - // with a one line edit control. The item will be selected if it hadn't - // been before. - void EditLabel( const wxTreeItemId& item ); - void Edit( const wxTreeItemId& item ); - - // sort the children of this item using OnCompareItems - void SortChildren(const wxTreeItemId& item); - - // searching - wxTreeItemId FindItem (const wxTreeItemId& item, const wxString& str, int flags = 0); - - wxWindow* GetHeaderWindow() const; - wxScrolledWindow* GetMainWindow() const; +//---------------------------------------------------------------------- -}; +%include _treelist.i //---------------------------------------------------------------------- @@ -1020,14 +472,9 @@ public: //---------------------------------------------------------------------- %init %{ - wxPyPtrTypeMap_Add("wxTreeCompanionWindow", "wxPyTreeCompanionWindow"); - wxPyPtrTypeMap_Add("wxTreeListCtrl", "wxPyTreeListCtrl"); %} - -%pragma(python) include="_gizmoextras.py"; - //---------------------------------------------------------------------- //---------------------------------------------------------------------- diff --git a/wxPython/contrib/gizmos/wxCode/include/wx/treelistctrl.h b/wxPython/contrib/gizmos/wxCode/include/wx/treelistctrl.h index 1edc024eb0..79aa6fae14 100644 --- a/wxPython/contrib/gizmos/wxCode/include/wx/treelistctrl.h +++ b/wxPython/contrib/gizmos/wxCode/include/wx/treelistctrl.h @@ -2,10 +2,10 @@ // Name: treelistctrl.h // Purpose: wxTreeListCtrl class // Author: Robert Roebling -// Modified by: Alberto Griggio, 2002 +// Maintainer: Otto Wyss // Created: 01/02/97 // RCS-ID: $Id$ -// Copyright: (c) Robert Roebling, Julian Smart, Alberto Griggio, +// Copyright: (c) 2004 Robert Roebling, Julian Smart, Alberto Griggio, // Vadim Zeitlin, Otto Wyss // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// @@ -30,6 +30,8 @@ class GIZMODLLEXPORT wxTreeListItem; class GIZMODLLEXPORT wxTreeListHeaderWindow; class GIZMODLLEXPORT wxTreeListMainWindow; +#define wxTR_COLUMN_LINES 0x1000 // put border around items +#define wxTR_VIRTUAL 0x4000 // The application provides items text on demand. // Using this typedef removes an ambiguity when calling Remove() #ifdef __WXMSW__ @@ -40,96 +42,91 @@ typedef void *wxTreeItemIdValue; #endif #endif - -#define wxTR_DONT_ADJUST_MAC 0x0100 // Don't adjust the style for the Mac - //----------------------------------------------------------------------------- // wxTreeListColumnAttrs //----------------------------------------------------------------------------- -enum wxTreeListColumnAlign { - wxTL_ALIGN_LEFT, - wxTL_ALIGN_RIGHT, - wxTL_ALIGN_CENTER +enum { + DEFAULT_COL_WIDTH = 100 }; - class GIZMODLLEXPORT wxTreeListColumnInfo: public wxObject { -public: - enum { DEFAULT_COL_WIDTH = 100 }; - wxTreeListColumnInfo(const wxString &text = wxT(""), - int image = -1, - size_t width = DEFAULT_COL_WIDTH, - bool shown = true, - wxTreeListColumnAlign alignment = wxTL_ALIGN_LEFT) - { - m_image = image; - m_selected_image = -1; +public: + wxTreeListColumnInfo (const wxString &text = wxEmptyString, + int width = DEFAULT_COL_WIDTH, + int flag = wxALIGN_LEFT, + int image = -1, + bool shown = true, + bool edit = false) { m_text = text; m_width = width; + m_flag = flag; + m_image = image; + m_selected_image = -1; m_shown = shown; - m_alignment = alignment; + m_edit = edit; } - wxTreeListColumnInfo(const wxTreeListColumnInfo& other) - { - m_image = other.m_image; - m_selected_image = other.m_selected_image; + wxTreeListColumnInfo (const wxTreeListColumnInfo& other) { m_text = other.m_text; m_width = other.m_width; + m_flag = other.m_flag; + m_image = other.m_image; + m_selected_image = other.m_selected_image; m_shown = other.m_shown; - m_alignment = other.m_alignment; + m_edit = other.m_edit; } ~wxTreeListColumnInfo() {} - // getters - bool GetShown() const { return m_shown; } - wxTreeListColumnAlign GetAlignment() const { return m_alignment; } + // get/set wxString GetText() const { return m_text; } - int GetImage() const { return m_image; } - int GetSelectedImage() const { return m_selected_image; } - size_t GetWidth() const { return m_width; } + wxTreeListColumnInfo& SetText (const wxString& text) { m_text = text; return *this; } - // setters - wxTreeListColumnInfo& SetShown(bool shown) - { m_shown = shown; return *this; } + int GetWidth() const { return m_width; } + wxTreeListColumnInfo& SetWidth (int width) { m_width = width; return *this; } - wxTreeListColumnInfo& SetAlignment(wxTreeListColumnAlign alignment) - { m_alignment = alignment; return *this; } + int GetAlignment() const { return m_flag; } + wxTreeListColumnInfo& SetAlignment (int flag) { m_flag = flag; return *this; } - wxTreeListColumnInfo& SetText(const wxString& text) - { m_text = text; return *this; } + int GetImage() const { return m_image; } + wxTreeListColumnInfo& SetImage (int image) { m_image = image; return *this; } - wxTreeListColumnInfo& SetImage(int image) - { m_image = image; return *this; } + int GetSelectedImage() const { return m_selected_image; } + wxTreeListColumnInfo& SetSelectedImage (int image) { m_selected_image = image; return *this; } - wxTreeListColumnInfo& SetSelectedImage(int image) - { m_selected_image = image; return *this; } + bool IsEditable() const { return m_edit; } + wxTreeListColumnInfo& SetEditable (bool edit) + { m_edit = edit; return *this; } - wxTreeListColumnInfo& SetWidth(size_t with) - { m_width = with; return *this; } + bool IsShown() const { return m_shown; } + wxTreeListColumnInfo& SetShown(bool shown) { m_shown = shown; return *this; } private: - bool m_shown; - wxTreeListColumnAlign m_alignment; wxString m_text; + int m_width; + int m_flag; int m_image; int m_selected_image; - size_t m_width; + bool m_shown; + bool m_edit; }; //---------------------------------------------------------------------------- // wxTreeListCtrl - the multicolumn tree control //---------------------------------------------------------------------------- -// flags for FindItem -const int wxTL_SEARCH_VISIBLE = 0x0000; -const int wxTL_SEARCH_LEVEL = 0x0001; -const int wxTL_SEARCH_FULL = 0x0002; -const int wxTL_SEARCH_PARTIAL = 0x0010; -const int wxTL_SEARCH_NOCASE = 0x0020; +// modes for navigation +const int wxTL_MODE_NAV_FULLTREE = 0x0000; // default +const int wxTL_MODE_NAV_EXPANDED = 0x0001; +const int wxTL_MODE_NAV_VISIBLE = 0x0002; +const int wxTL_MODE_NAV_LEVEL = 0x0004; + +// modes for FindItem +const int wxTL_MODE_FIND_EXACT = 0x0000; // default +const int wxTL_MODE_FIND_PARTIAL = 0x0010; +const int wxTL_MODE_FIND_NOCASE = 0x0020; // additional flag for HitTest const int wxTREE_HITTEST_ONITEMCOLUMN = 0x2000; @@ -207,144 +204,147 @@ public: void AssignButtonsImageList(wxImageList *imageList); - // Functions to work with tree list ctrl columns + // Functions to work with columns // adds a column - void AddColumn(const wxString& text) - { AddColumn(wxTreeListColumnInfo(text)); } - void AddColumn(const wxString& text, - size_t width, - wxTreeListColumnAlign alignment = wxTL_ALIGN_LEFT) - { AddColumn(wxTreeListColumnInfo(text, - -1, - width, - true, - alignment)); } - void AddColumn(const wxTreeListColumnInfo& col); + void AddColumn (const wxString& text, + int width = DEFAULT_COL_WIDTH, + int flag = wxALIGN_LEFT, + int image = -1, + bool shown = true, + bool edit = false) { + AddColumn (wxTreeListColumnInfo (text, width, flag, image, shown, edit)); + } + void AddColumn (const wxTreeListColumnInfo& colInfo); // inserts a column before the given one - void InsertColumn(size_t before, const wxString& text) - { InsertColumn(before, wxTreeListColumnInfo(text)); } - void InsertColumn(size_t before, const wxTreeListColumnInfo& col); + void InsertColumn (int before, + const wxString& text, + int width = DEFAULT_COL_WIDTH, + int flag = wxALIGN_LEFT, + int image = -1, + bool shown = true, + bool edit = false) { + InsertColumn (before, + wxTreeListColumnInfo (text, width, flag, image, shown, edit)); + } + void InsertColumn (int before, const wxTreeListColumnInfo& colInfo); // deletes the given column - does not delete the corresponding column - // of each item - void RemoveColumn(size_t column); + void RemoveColumn (int column); // returns the number of columns in the ctrl - size_t GetColumnCount() const; - - void SetColumnWidth(size_t column, size_t width); - int GetColumnWidth(size_t column) const; + int GetColumnCount() const; // tells which column is the "main" one, i.e. the "threaded" one - void SetMainColumn(size_t column); - size_t GetMainColumn() const; + void SetMainColumn (int column); + int GetMainColumn() const; + + void SetColumn (int column, const wxTreeListColumnInfo& colInfo); + wxTreeListColumnInfo& GetColumn (int column); + const wxTreeListColumnInfo& GetColumn (int column) const; + + void SetColumnText (int column, const wxString& text); + wxString GetColumnText (int column) const; - void SetColumnText(size_t column, const wxString& text); - wxString GetColumnText(size_t column) const; + void SetColumnWidth (int column, int width); + int GetColumnWidth (int column) const; - void SetColumn(size_t column, const wxTreeListColumnInfo& info); - wxTreeListColumnInfo& GetColumn(size_t column); - const wxTreeListColumnInfo& GetColumn(size_t column) const; + void SetColumnAlignment (int column, int flag); + int GetColumnAlignment (int column) const; - // other column-related methods - void SetColumnAlignment(size_t column, wxTreeListColumnAlign align); - wxTreeListColumnAlign GetColumnAlignment(size_t column) const; + void SetColumnImage (int column, int image); + int GetColumnImage (int column) const; - void SetColumnImage(size_t column, int image); - int GetColumnImage(size_t column) const; + void SetColumnShown (int column, bool shown = true); + bool IsColumnShown (int column) const; - void ShowColumn(size_t column, bool shown); - bool IsColumnShown(size_t column) const; + void SetColumnEditable (int column, bool edit = true); + bool IsColumnEditable (int column) const; - // Functions to work with tree list ctrl items. + // Functions to work with items. // accessors // --------- // retrieve item's label (of the main column) - wxString GetItemText(const wxTreeItemId& item) const - { return GetItemText(item, GetMainColumn()); } + wxString GetItemText (const wxTreeItemId& item) const + { return GetItemText (item, GetMainColumn()); } // retrieves item's label of the given column - wxString GetItemText(const wxTreeItemId& item, size_t column) const; + wxString GetItemText (const wxTreeItemId& item, int column) const; // get one of the images associated with the item (normal by default) - int GetItemImage(const wxTreeItemId& item, - wxTreeItemIcon which = wxTreeItemIcon_Normal) const - { return GetItemImage(item, GetMainColumn(), which); } - int GetItemImage(const wxTreeItemId& item, size_t column, - wxTreeItemIcon which = wxTreeItemIcon_Normal) const; + int GetItemImage (const wxTreeItemId& item, + wxTreeItemIcon which = wxTreeItemIcon_Normal) const + { return GetItemImage (item, GetMainColumn(), which); } + int GetItemImage (const wxTreeItemId& item, int column, + wxTreeItemIcon which = wxTreeItemIcon_Normal) const; // get the data associated with the item - wxTreeItemData *GetItemData(const wxTreeItemId& item) const; + wxTreeItemData *GetItemData (const wxTreeItemId& item) const; - bool GetItemBold(const wxTreeItemId& item) const; - wxColour GetItemTextColour(const wxTreeItemId& item) const; - wxColour GetItemBackgroundColour(const wxTreeItemId& item) const; - wxFont GetItemFont(const wxTreeItemId& item) const; + bool GetItemBold (const wxTreeItemId& item) const; + wxColour GetItemTextColour (const wxTreeItemId& item) const; + wxColour GetItemBackgroundColour (const wxTreeItemId& item) const; + wxFont GetItemFont (const wxTreeItemId& item) const; // modifiers - // --------- // set item's label - void SetItemText(const wxTreeItemId& item, const wxString& text) - { SetItemText(item, GetMainColumn(), text); } - void SetItemText(const wxTreeItemId& item, size_t column, - const wxString& text); + void SetItemText (const wxTreeItemId& item, const wxString& text) + { SetItemText (item, GetMainColumn(), text); } + void SetItemText (const wxTreeItemId& item, int column, const wxString& text); // get one of the images associated with the item (normal by default) - void SetItemImage(const wxTreeItemId& item, int image, - wxTreeItemIcon which = wxTreeItemIcon_Normal) - { SetItemImage(item, GetMainColumn(), image, which); } + void SetItemImage (const wxTreeItemId& item, int image, + wxTreeItemIcon which = wxTreeItemIcon_Normal) + { SetItemImage (item, GetMainColumn(), image, which); } // the which parameter is ignored for all columns but the main one - void SetItemImage(const wxTreeItemId& item, size_t column, int image, - wxTreeItemIcon which = wxTreeItemIcon_Normal); + void SetItemImage (const wxTreeItemId& item, int column, int image, + wxTreeItemIcon which = wxTreeItemIcon_Normal); // associate some data with the item - void SetItemData(const wxTreeItemId& item, wxTreeItemData *data); + void SetItemData (const wxTreeItemId& item, wxTreeItemData *data); // force appearance of [+] button near the item. This is useful to // allow the user to expand the items which don't have any children now // - but instead add them only when needed, thus minimizing memory // usage and loading time. - void SetItemHasChildren(const wxTreeItemId& item, bool has = TRUE); + void SetItemHasChildren(const wxTreeItemId& item, bool has = true); // the item will be shown in bold - void SetItemBold(const wxTreeItemId& item, bool bold = TRUE); + void SetItemBold (const wxTreeItemId& item, bool bold = true); // set the item's text colour - void SetItemTextColour(const wxTreeItemId& item, const wxColour& colour); + void SetItemTextColour (const wxTreeItemId& item, const wxColour& colour); // set the item's background colour - void SetItemBackgroundColour(const wxTreeItemId& item, const wxColour& colour); + void SetItemBackgroundColour (const wxTreeItemId& item, const wxColour& colour); // set the item's font (should be of the same height for all items) - void SetItemFont(const wxTreeItemId& item, const wxFont& font); + void SetItemFont (const wxTreeItemId& item, const wxFont& font); // set the window font - virtual bool SetFont( const wxFont &font ); + virtual bool SetFont ( const wxFont &font ); // set the styles. - void SetWindowStyle(const long styles); + void SetWindowStyle (const long styles); long GetWindowStyle() const; - long GetWindowStyleFlag() const { return GetWindowStyle(); } + long GetWindowStyleFlag () const { return GetWindowStyle(); } // item status inquiries // --------------------- // is the item visible (it might be outside the view or not expanded)? - bool IsVisible(const wxTreeItemId& item) const; + bool IsVisible (const wxTreeItemId& item, bool fullRow = false) const; // does the item has any children? - bool HasChildren(const wxTreeItemId& item) const - { return ItemHasChildren(item); } - bool ItemHasChildren(const wxTreeItemId& item) const; + bool HasChildren (const wxTreeItemId& item) const; // is the item expanded (only makes sense if HasChildren())? - bool IsExpanded(const wxTreeItemId& item) const; + bool IsExpanded (const wxTreeItemId& item) const; // is this item currently selected (the same as has focus)? - bool IsSelected(const wxTreeItemId& item) const; + bool IsSelected (const wxTreeItemId& item) const; // is item text in bold font? - bool IsBold(const wxTreeItemId& item) const; + bool IsBold (const wxTreeItemId& item) const; // does the layout include space for a button? // number of children @@ -352,7 +352,7 @@ public: // if 'recursively' is FALSE, only immediate children count, otherwise // the returned number is the number of all items in this branch - size_t GetChildrenCount(const wxTreeItemId& item, bool recursively = TRUE); + size_t GetChildrenCount (const wxTreeItemId& item, bool recursively = true); // navigation // ---------- @@ -366,10 +366,10 @@ public: wxTreeItemId GetSelection() const; // get the items currently selected, return the number of such item - size_t GetSelections(wxArrayTreeItemIds&) const; + size_t GetSelections (wxArrayTreeItemIds&) const; // get the parent of this item (may return NULL if root) - wxTreeItemId GetItemParent(const wxTreeItemId& item) const; + wxTreeItemId GetItemParent (const wxTreeItemId& item) const; // for this enumeration function you must pass in a "cookie" parameter // which is opaque for the application but is necessary for the library @@ -378,175 +378,171 @@ public: // the "cookie" passed to GetFirstChild() and GetNextChild() should be // the same! - // get the first child of this item + // get child of this item #if !wxCHECK_VERSION(2, 5, 0) wxTreeItemId GetFirstChild(const wxTreeItemId& item, long& cookie) const; -#else - wxTreeItemId GetFirstChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const; -#endif - // get the next child -#if !wxCHECK_VERSION(2, 5, 0) wxTreeItemId GetNextChild(const wxTreeItemId& item, long& cookie) const; -#else - wxTreeItemId GetNextChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const; -#endif - // get the prev child -#if !wxCHECK_VERSION(2, 5, 0) wxTreeItemId GetPrevChild(const wxTreeItemId& item, long& cookie) const; + wxTreeItemId GetLastChild(const wxTreeItemId& item, long& cookie) const; #else + wxTreeItemId GetFirstChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const; + wxTreeItemId GetNextChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const; wxTreeItemId GetPrevChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const; + wxTreeItemId GetLastChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const; #endif - // get the last child of this item - this method doesn't use cookies - wxTreeItemId GetLastChild(const wxTreeItemId& item) const; - // get the next sibling of this item + // get sibling of this item wxTreeItemId GetNextSibling(const wxTreeItemId& item) const; - // get the previous sibling wxTreeItemId GetPrevSibling(const wxTreeItemId& item) const; - // get first visible item - wxTreeItemId GetFirstVisibleItem() const; - // get the next visible item: item must be visible itself! - // see IsVisible() and wxTreeCtrl::GetFirstVisibleItem() - wxTreeItemId GetNextVisible(const wxTreeItemId& item) const; - // get the previous visible item: item must be visible itself! - wxTreeItemId GetPrevVisible(const wxTreeItemId& item) const; - - // Only for internal use right now, but should probably be public + // get item in the full tree (currently only for internal use) wxTreeItemId GetNext(const wxTreeItemId& item) const; + wxTreeItemId GetPrev(const wxTreeItemId& item) const; + + // get expanded item, see IsExpanded() + wxTreeItemId GetFirstExpandedItem() const; + wxTreeItemId GetNextExpanded(const wxTreeItemId& item) const; + wxTreeItemId GetPrevExpanded(const wxTreeItemId& item) const; + + // get visible item, see IsVisible() + wxTreeItemId GetFirstVisibleItem(bool fullRow = false) const; + wxTreeItemId GetNextVisible(const wxTreeItemId& item, bool fullRow = false) const; + wxTreeItemId GetPrevVisible(const wxTreeItemId& item, bool fullRow = false) const; // operations // ---------- // add the root node to the tree - wxTreeItemId AddRoot(const wxString& text, - int image = -1, int selectedImage = -1, - wxTreeItemData *data = NULL); + wxTreeItemId AddRoot (const wxString& text, + int image = -1, int selectedImage = -1, + wxTreeItemData *data = NULL); // insert a new item in as the first child of the parent - wxTreeItemId PrependItem(const wxTreeItemId& parent, + wxTreeItemId PrependItem (const wxTreeItemId& parent, + const wxString& text, + int image = -1, int selectedImage = -1, + wxTreeItemData *data = NULL); + + // insert a new item after a given one + wxTreeItemId InsertItem (const wxTreeItemId& parent, + const wxTreeItemId& idPrevious, const wxString& text, int image = -1, int selectedImage = -1, wxTreeItemData *data = NULL); - // insert a new item after a given one - wxTreeItemId InsertItem(const wxTreeItemId& parent, - const wxTreeItemId& idPrevious, - const wxString& text, - int image = -1, int selectedImage = -1, - wxTreeItemData *data = NULL); - // insert a new item before the one with the given index - wxTreeItemId InsertItem(const wxTreeItemId& parent, - size_t index, - const wxString& text, - int image = -1, int selectedImage = -1, - wxTreeItemData *data = NULL); + wxTreeItemId InsertItem (const wxTreeItemId& parent, + size_t index, + const wxString& text, + int image = -1, int selectedImage = -1, + wxTreeItemData *data = NULL); // insert a new item in as the last child of the parent - wxTreeItemId AppendItem(const wxTreeItemId& parent, - const wxString& text, - int image = -1, int selectedImage = -1, - wxTreeItemData *data = NULL); + wxTreeItemId AppendItem (const wxTreeItemId& parent, + const wxString& text, + int image = -1, int selectedImage = -1, + wxTreeItemData *data = NULL); - // delete this item and associated data if any - void Delete(const wxTreeItemId& item); + // delete this item (except root) and associated data if any + void Delete (const wxTreeItemId& item); // delete all children (but don't delete the item itself) // NB: this won't send wxEVT_COMMAND_TREE_ITEM_DELETED events - void DeleteChildren(const wxTreeItemId& item); - // delete all items from the tree + void DeleteChildren (const wxTreeItemId& item); + // delete the root and all its children from the tree // NB: this won't send wxEVT_COMMAND_TREE_ITEM_DELETED events - void DeleteAllItems(); + void DeleteRoot(); // expand this item - void Expand(const wxTreeItemId& item); + void Expand (const wxTreeItemId& item); // expand this item and all subitems recursively - void ExpandAll(const wxTreeItemId& item); + void ExpandAll (const wxTreeItemId& item); // collapse the item without removing its children - void Collapse(const wxTreeItemId& item); + void Collapse (const wxTreeItemId& item); // collapse the item and remove all children - void CollapseAndReset(const wxTreeItemId& item); + void CollapseAndReset(const wxTreeItemId& item); //? TODO ??? // toggles the current state - void Toggle(const wxTreeItemId& item); + void Toggle (const wxTreeItemId& item); // remove the selection from currently selected item (if any) void Unselect(); void UnselectAll(); // select this item - void SelectItem(const wxTreeItemId& item, bool unselect_others=TRUE, - bool extended_select=FALSE); - void SelectAll(bool extended_select=FALSE); + void SelectItem (const wxTreeItemId& item, + const wxTreeItemId& last = (wxTreeItemId*)NULL, + bool unselect_others = true); + // select all items in the expanded tree + void SelectAll(); // make sure this item is visible (expanding the parent item and/or // scrolling to this item if necessary) - void EnsureVisible(const wxTreeItemId& item); + void EnsureVisible (const wxTreeItemId& item); // scroll to this item (but don't expand its parent) - void ScrollTo(const wxTreeItemId& item); - //void AdjustMyScrollbars(); + void ScrollTo (const wxTreeItemId& item); // The first function is more portable (because easier to implement // on other platforms), but the second one returns some extra info. - wxTreeItemId HitTest(const wxPoint& point) - { int dummy; return HitTest(point, dummy); } - wxTreeItemId HitTest(const wxPoint& point, int& flags) - { int col; return HitTest(point, flags, col); } - wxTreeItemId HitTest(const wxPoint& point, int& flags, int& column); + wxTreeItemId HitTest (const wxPoint& point) + { int flags; int column; return HitTest (point, flags, column); } + wxTreeItemId HitTest (const wxPoint& point, int& flags) + { int column; return HitTest (point, flags, column); } + wxTreeItemId HitTest (const wxPoint& point, int& flags, int& column); // get the bounding rectangle of the item (or of its label only) - bool GetBoundingRect(const wxTreeItemId& item, - wxRect& rect, - bool textOnly = FALSE) const; + bool GetBoundingRect (const wxTreeItemId& item, wxRect& rect, + bool textOnly = false) const; // Start editing the item label: this (temporarily) replaces the item // with a one line edit control. The item will be selected if it hadn't // been before. - void EditLabel( const wxTreeItemId& item ) { Edit( item ); } - void Edit( const wxTreeItemId& item ); + void EditLabel (const wxTreeItemId& item) + { EditLabel (item, GetMainColumn()); } + // edit item's label of the given column + void EditLabel (const wxTreeItemId& item, int column); + + // virtual mode + virtual wxString OnGetItemText( wxTreeItemData* item, long column ) const; // sorting // this function is called to compare 2 items and should return -1, 0 // or +1 if the first item is less than, equal to or greater than the // second one. The base class version performs alphabetic comparaison // of item labels (GetText) - virtual int OnCompareItems(const wxTreeItemId& item1, - const wxTreeItemId& item2); + virtual int OnCompareItems (const wxTreeItemId& item1, const wxTreeItemId& item2); // sort the children of this item using OnCompareItems - // // NB: this function is not reentrant and not MT-safe (FIXME)! void SortChildren(const wxTreeItemId& item); // searching - wxTreeItemId FindItem (const wxTreeItemId& item, const wxString& str, int flags = 0); + wxTreeItemId FindItem (const wxTreeItemId& item, const wxString& str, int mode = 0); // overridden base class virtuals - virtual bool SetBackgroundColour(const wxColour& colour); - virtual bool SetForegroundColour(const wxColour& colour); + virtual bool SetBackgroundColour (const wxColour& colour); + virtual bool SetForegroundColour (const wxColour& colour); + + // drop over item + void SetDragItem (const wxTreeItemId& item = (wxTreeItemId*)NULL); wxTreeListHeaderWindow* GetHeaderWindow() const - { return m_header_win; } + { return m_header_win; } wxTreeListMainWindow* GetMainWindow() const - { return m_main_win; } + { return m_main_win; } virtual wxSize DoGetBestSize() const; - + protected: // header window, responsible for column visualization and manipulation wxTreeListHeaderWindow* m_header_win; - // main window, the "true" tree ctrl - wxTreeListMainWindow* m_main_win; -// // the common part of all ctors -// void Init(); + // main window, the "true" tree ctrl + wxTreeListMainWindow* m_main_win; - void OnGetToolTip( wxTreeEvent &event ); - void OnSize(wxSizeEvent& event); void CalculateAndSetHeaderHeight(); void DoHeaderLayout(); + void OnSize(wxSizeEvent& event); private: - size_t fill_column; - size_t m_headerHeight; + int m_headerHeight; DECLARE_EVENT_TABLE() DECLARE_DYNAMIC_CLASS(wxTreeListCtrl) diff --git a/wxPython/contrib/gizmos/wxCode/src/treelistctrl.cpp b/wxPython/contrib/gizmos/wxCode/src/treelistctrl.cpp index 2d07d6b2d3..054a06683d 100644 --- a/wxPython/contrib/gizmos/wxCode/src/treelistctrl.cpp +++ b/wxPython/contrib/gizmos/wxCode/src/treelistctrl.cpp @@ -2,13 +2,12 @@ // Name: treelistctrl.cpp // Purpose: multi column tree control implementation // Author: Robert Roebling +// Maintainer: Otto Wyss // Created: 01/02/97 -// Modified: Alberto Griggio, 2002 -// 22/10/98 - almost total rewrite, simpler interface (VZ) -// Id: $Id$ -// Copyright: (c) Robert Roebling, Julian Smart, Alberto Griggio, +// RCS-ID: $Id$ +// Copyright: (c) 2004 Robert Roebling, Julian Smart, Alberto Griggio, // Vadim Zeitlin, Otto Wyss -// Licence: wxWindows licence +// Licence: wxWindows ///////////////////////////////////////////////////////////////////////////// // =========================================================================== @@ -19,6 +18,10 @@ // headers // --------------------------------------------------------------------------- +#if defined(__GNUG__) && !defined(__APPLE__) + #pragma implementation "treelistctrl.h" +#endif + // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -35,20 +38,16 @@ #include #include #include +#if wxCHECK_VERSION(2, 7, 0) #include -#include - -#include "wx/treelistctrl.h" - -#ifdef __WXGTK__ - #include - #include #endif #ifdef __WXMAC__ - #include "wx/mac/private.h" +#include "wx/mac/private.h" #endif +#include "wx/treelistctrl.h" + // --------------------------------------------------------------------------- // array types @@ -67,10 +66,6 @@ WX_DECLARE_OBJARRAY(wxTreeListColumnInfo, wxArrayTreeListColumnInfo); #include WX_DEFINE_OBJARRAY(wxArrayTreeListColumnInfo); -#if !wxCHECK_VERSION(2, 3, 3) -WX_DEFINE_ARRAY(short, wxArrayShort); -#endif - // -------------------------------------------------------------------------- // constants @@ -78,25 +73,22 @@ WX_DEFINE_ARRAY(short, wxArrayShort); static const int NO_IMAGE = -1; -const int LINEHEIGHT = 10; -const int PIXELS_PER_UNIT = 10; -const int LINEATROOT = 5; -const int MARGIN = 2; -const int MININDENT = 10; -const int BTNWIDTH = 9; //11; -const int BTNHEIGHT = 9; //11; - -// extra margins around the text label +static const int LINEHEIGHT = 10; +static const int LINEATROOT = 5; +static const int MARGIN = 2; +static const int MININDENT = 16; +static const int BTNWIDTH = 9; +static const int BTNHEIGHT = 9; static const int EXTRA_WIDTH = 4; static const int EXTRA_HEIGHT = 4; - -// offset for the header window static const int HEADER_OFFSET_X = 1; static const int HEADER_OFFSET_Y = 1; +static const int DRAG_TIMER_TICKS = 250; // minimum drag wait time in ms +static const int FIND_TIMER_TICKS = 500; // minimum find wait time in ms +static const int RENAME_TIMER_TICKS = 250; // minimum rename wait time in ms - -const wxChar* wxTreeListCtrlNameStr = wxT("treelistctrl"); +const wxChar* wxTreeListCtrlNameStr = _T("treelistctrl"); static wxTreeListColumnInfo wxInvalidTreeListColumnInfo; @@ -112,9 +104,9 @@ class wxTreeListHeaderWindow : public wxWindow { protected: wxTreeListMainWindow *m_owner; - const wxCursor *m_currentCursor; - wxCursor *m_resizeCursor; - bool m_isDragging; + const wxCursor *m_currentCursor; + const wxCursor *m_resizeCursor; + bool m_isDragging; // column being resized int m_column; @@ -141,7 +133,7 @@ public: const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = 0, - const wxString &name = wxT("wxtreelistctrlcolumntitles") ); + const wxString &name = _T("wxtreelistctrlcolumntitles") ); virtual ~wxTreeListHeaderWindow(); @@ -149,66 +141,74 @@ public: void DrawCurrent(); void AdjustDC(wxDC& dc); - void OnEraseBackground( wxEraseEvent& event ); void OnPaint( wxPaintEvent &event ); void OnMouse( wxMouseEvent &event ); void OnSetFocus( wxFocusEvent &event ); + // total width of all columns + int GetWidth() const { return m_total_col_width; } - // columns manipulation - - size_t GetColumnCount() const { return m_columns.GetCount(); } + // column manipulation + int GetColumnCount() const { return m_columns.GetCount(); } - void AddColumn(const wxTreeListColumnInfo& col); + void AddColumn (const wxTreeListColumnInfo& colInfo); - void InsertColumn(size_t before, const wxTreeListColumnInfo& col); + void InsertColumn (int before, const wxTreeListColumnInfo& colInfo); - void RemoveColumn(size_t column); + void RemoveColumn (int column); - void SetColumn(size_t column, const wxTreeListColumnInfo& info); - const wxTreeListColumnInfo& GetColumn(size_t column) const - { - wxCHECK_MSG(column < GetColumnCount(), wxInvalidTreeListColumnInfo, wxT("Invalid column")); + // column information manipulation + const wxTreeListColumnInfo& GetColumn (int column) const{ + wxCHECK_MSG ((column >= 0) && (column < GetColumnCount()), + wxInvalidTreeListColumnInfo, _T("Invalid column")); return m_columns[column]; } - wxTreeListColumnInfo& GetColumn(size_t column) - { - wxCHECK_MSG(column < GetColumnCount(), wxInvalidTreeListColumnInfo, wxT("Invalid column")); + wxTreeListColumnInfo& GetColumn (int column) { + wxCHECK_MSG ((column >= 0) && (column < GetColumnCount()), + wxInvalidTreeListColumnInfo, _T("Invalid column")); return m_columns[column]; } + void SetColumn (int column, const wxTreeListColumnInfo& info); - void SetColumnWidth(size_t column, size_t width); - - void SetColumnText(size_t column, const wxString& text) - { - wxCHECK_RET(column < GetColumnCount(), wxT("Invalid column")); - m_columns[column].SetText(text); + wxString GetColumnText (int column) const { + wxCHECK_MSG ((column >= 0) && (column < GetColumnCount()), + wxEmptyString, _T("Invalid column")); + return m_columns[column].GetText(); } - - void SetColumnShown(size_t column, bool shown) - { - wxCHECK_RET(column < GetColumnCount(), wxT("Invalid column")); - m_columns[column].SetShown(shown); + void SetColumnText (int column, const wxString& text) { + wxCHECK_RET ((column >= 0) && (column < GetColumnCount()), + _T("Invalid column")); + m_columns[column].SetText (text); } - wxString GetColumnText(size_t column) const - { - wxCHECK_MSG(column < GetColumnCount(), wxEmptyString, wxT("Invalid column")); - return m_columns[column].GetText(); + int GetColumnAlignment (int column) const { + wxCHECK_MSG ((column >= 0) && (column < GetColumnCount()), + wxALIGN_LEFT, _T("Invalid column")); + return m_columns[column].GetAlignment(); + } + void SetColumnAlignment (int column, int flag) { + wxCHECK_RET ((column >= 0) && (column < GetColumnCount()), + _T("Invalid column")); + m_columns[column].SetAlignment (flag); } - int GetColumnWidth(size_t column) const - { - wxCHECK_MSG(column < GetColumnCount(), -1, wxT("Invalid column")); + int GetColumnWidth (int column) const { + wxCHECK_MSG ((column >= 0) && (column < GetColumnCount()), + -1, _T("Invalid column")); return m_columns[column].GetWidth(); } + void SetColumnWidth (int column, int width); - int GetWidth() const { return m_total_col_width; } + bool IsColumnEditable (int column) const { + wxCHECK_MSG ((column >= 0) && (column < GetColumnCount()), + false, _T("Invalid column")); + return m_columns[column].IsEditable(); + } - int GetColumnShown(size_t column) const - { - wxCHECK_MSG(column < GetColumnCount(), -1, wxT("Invalid column")); - return m_columns[column].GetShown(); + bool IsColumnShown (int column) const { + wxCHECK_MSG ((column >= 0) && (column < GetColumnCount()), + true, _T("Invalid column")); + return m_columns[column].IsShown(); } // needs refresh @@ -233,15 +233,15 @@ public: // -------- wxTreeListMainWindow() { Init(); } - wxTreeListMainWindow(wxTreeListCtrl *parent, wxWindowID id = -1, + wxTreeListMainWindow (wxTreeListCtrl *parent, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTR_DEFAULT_STYLE, const wxValidator &validator = wxDefaultValidator, - const wxString& name = wxT("wxtreelistmainwindow")) + const wxString& name = _T("wxtreelistmainwindow")) { Init(); - Create(parent, id, pos, size, style, validator, name); + Create (parent, id, pos, size, style, validator, name); } virtual ~wxTreeListMainWindow(); @@ -251,11 +251,14 @@ public: const wxSize& size = wxDefaultSize, long style = wxTR_DEFAULT_STYLE, const wxValidator &validator = wxDefaultValidator, - const wxString& name = wxT("wxtreelistctrl")); + const wxString& name = _T("wxtreelistctrl")); // accessors // --------- + // return true if this is a virtual list control + bool IsVirtual() const { return HasFlag(wxTR_VIRTUAL); } + // get the total number of items in the control size_t GetCount() const; @@ -281,9 +284,9 @@ public: // Additionally, the application might choose to show a state icon // which corresponds to an app-defined item state (for example, // checked/unchecked) which are taken from the state image list. - wxImageList *GetImageList() const; - wxImageList *GetStateImageList() const; - wxImageList *GetButtonsImageList() const; + wxImageList *GetImageList() const { return m_imageListNormal; } + wxImageList *GetStateImageList() const { return m_imageListState; } + wxImageList *GetButtonsImageList() const { return m_imageListButtons; } void SetImageList(wxImageList *imageList); void SetStateImageList(wxImageList *imageList); @@ -298,12 +301,17 @@ public: // --------- // retrieve item's label - wxString GetItemText(const wxTreeItemId& item) const - { return GetItemText(item, GetMainColumn()); } + wxString GetItemText (const wxTreeItemId& item) const + { return GetItemText (item, GetMainColumn()); } + wxString GetItemText (const wxTreeItemId& item, int column) const; + wxString GetItemText (wxTreeItemData* item, int column) const; + // get one of the images associated with the item (normal by default) - int GetItemImage(const wxTreeItemId& item, - wxTreeItemIcon which = wxTreeItemIcon_Normal) const - { return GetItemImage(item, GetMainColumn(), which); } + int GetItemImage (const wxTreeItemId& item, + wxTreeItemIcon which = wxTreeItemIcon_Normal) const + { return GetItemImage (item, GetMainColumn(), which); } + int GetItemImage (const wxTreeItemId& item, int column, + wxTreeItemIcon which = wxTreeItemIcon_Normal) const; // get the data associated with the item wxTreeItemData *GetItemData(const wxTreeItemId& item) const; @@ -317,13 +325,16 @@ public: // --------- // set item's label - void SetItemText(const wxTreeItemId& item, const wxString& text) - { SetItemText(item, GetMainColumn(), text); } + void SetItemText (const wxTreeItemId& item, const wxString& text) + { SetItemText (item, GetMainColumn(), text); } + void SetItemText (const wxTreeItemId& item, int column, const wxString& text); // get one of the images associated with the item (normal by default) - void SetItemImage(const wxTreeItemId& item, int image, - wxTreeItemIcon which = wxTreeItemIcon_Normal) - { SetItemImage(item, GetMainColumn(), image, which); } + void SetItemImage (const wxTreeItemId& item, int image, + wxTreeItemIcon which = wxTreeItemIcon_Normal) + { SetItemImage (item, GetMainColumn(), image, which); } + void SetItemImage (const wxTreeItemId& item, int column, int image, + wxTreeItemIcon which = wxTreeItemIcon_Normal); // associate some data with the item void SetItemData(const wxTreeItemId& item, wxTreeItemData *data); @@ -332,10 +343,10 @@ public: // allow the user to expand the items which don't have any children now // - but instead add them only when needed, thus minimizing memory // usage and loading time. - void SetItemHasChildren(const wxTreeItemId& item, bool has = TRUE); + void SetItemHasChildren(const wxTreeItemId& item, bool has = true); // the item will be shown in bold - void SetItemBold(const wxTreeItemId& item, bool bold = TRUE); + void SetItemBold(const wxTreeItemId& item, bool bold = true); // set the item's text colour void SetItemTextColour(const wxTreeItemId& item, const wxColour& colour); @@ -357,11 +368,9 @@ public: // --------------------- // is the item visible (it might be outside the view or not expanded)? - bool IsVisible(const wxTreeItemId& item) const; + bool IsVisible(const wxTreeItemId& item, bool fullRow) const; // does the item has any children? - bool HasChildren(const wxTreeItemId& item) const - { return ItemHasChildren(item); } - bool ItemHasChildren(const wxTreeItemId& item) const; + bool HasChildren(const wxTreeItemId& item) const; // is the item expanded (only makes sense if HasChildren())? bool IsExpanded(const wxTreeItemId& item) const; // is this item currently selected (the same as has focus)? @@ -373,22 +382,22 @@ public: // number of children // ------------------ - // if 'recursively' is FALSE, only immediate children count, otherwise + // if 'recursively' is false, only immediate children count, otherwise // the returned number is the number of all items in this branch - size_t GetChildrenCount(const wxTreeItemId& item, bool recursively = TRUE); + size_t GetChildrenCount(const wxTreeItemId& item, bool recursively = true); // navigation // ---------- - // wxTreeItemId.IsOk() will return FALSE if there is no such item + // wxTreeItemId.IsOk() will return false if there is no such item // get the root tree item - wxTreeItemId GetRootItem() const { return m_anchor; } + wxTreeItemId GetRootItem() const { return m_rootItem; } - // get the item currently selected (may return NULL if no selection) - wxTreeItemId GetSelection() const { return m_current; } + // get the item currently selected, only if a single item is selected + wxTreeItemId GetSelection() const { return m_selectItem; } - // get the items currently selected, return the number of such item + // get all the items currently selected, return count of items size_t GetSelections(wxArrayTreeItemIds&) const; // get the parent of this item (may return NULL if root) @@ -401,50 +410,44 @@ public: // the "cookie" passed to GetFirstChild() and GetNextChild() should be // the same! - // get the first child of this item + // get child of this item #if !wxCHECK_VERSION(2, 5, 0) wxTreeItemId GetFirstChild(const wxTreeItemId& item, long& cookie) const; -#else - wxTreeItemId GetFirstChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const; -#endif - // get the next child -#if !wxCHECK_VERSION(2, 5, 0) wxTreeItemId GetNextChild(const wxTreeItemId& item, long& cookie) const; -#else - wxTreeItemId GetNextChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const; -#endif - // get the prev child -#if !wxCHECK_VERSION(2, 5, 0) wxTreeItemId GetPrevChild(const wxTreeItemId& item, long& cookie) const; + wxTreeItemId GetLastChild(const wxTreeItemId& item, long& cookie) const; #else + wxTreeItemId GetFirstChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const; + wxTreeItemId GetNextChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const; wxTreeItemId GetPrevChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const; + wxTreeItemId GetLastChild(const wxTreeItemId& item, wxTreeItemIdValue& cookie) const; #endif - // get the last child of this item - this method doesn't use cookies - wxTreeItemId GetLastChild(const wxTreeItemId& item) const; - // get the next sibling of this item + // get sibling of this item wxTreeItemId GetNextSibling(const wxTreeItemId& item) const; - // get the previous sibling wxTreeItemId GetPrevSibling(const wxTreeItemId& item) const; - // get first visible item - wxTreeItemId GetFirstVisibleItem() const; - // get the next visible item: item must be visible itself! - // see IsVisible() and wxTreeCtrl::GetFirstVisibleItem() - wxTreeItemId GetNextVisible(const wxTreeItemId& item) const; - // get the previous visible item: item must be visible itself! - wxTreeItemId GetPrevVisible(const wxTreeItemId& item) const; + // get item in the full tree (currently only for internal use) + wxTreeItemId GetNext(const wxTreeItemId& item, bool fulltree = true) const; + wxTreeItemId GetPrev(const wxTreeItemId& item, bool fulltree = true) const; + + // get expanded item, see IsExpanded() + wxTreeItemId GetFirstExpandedItem() const; + wxTreeItemId GetNextExpanded(const wxTreeItemId& item) const; + wxTreeItemId GetPrevExpanded(const wxTreeItemId& item) const; - // Only for internal use right now, but should probably be public - wxTreeItemId GetNext(const wxTreeItemId& item) const; + // get visible item, see IsVisible() + wxTreeItemId GetFirstVisibleItem(bool fullRow) const; + wxTreeItemId GetNextVisible(const wxTreeItemId& item, bool fullRow) const; + wxTreeItemId GetPrevVisible(const wxTreeItemId& item, bool fullRow) const; // operations // ---------- // add the root node to the tree - wxTreeItemId AddRoot(const wxString& text, - int image = -1, int selectedImage = -1, - wxTreeItemData *data = NULL); + wxTreeItemId AddRoot (const wxString& text, + int image = -1, int selectedImage = -1, + wxTreeItemData *data = NULL); // insert a new item in as the first child of the parent wxTreeItemId PrependItem(const wxTreeItemId& parent, @@ -477,9 +480,9 @@ public: // delete all children (but don't delete the item itself) // NB: this won't send wxEVT_COMMAND_TREE_ITEM_DELETED events void DeleteChildren(const wxTreeItemId& item); - // delete all items from the tree + // delete the root and all its children from the tree // NB: this won't send wxEVT_COMMAND_TREE_ITEM_DELETED events - void DeleteAllItems(); + void DeleteRoot(); // expand this item void Expand(const wxTreeItemId& item); @@ -496,9 +499,9 @@ public: void Unselect(); void UnselectAll(); // select this item - void SelectItem(const wxTreeItemId& item, bool unselect_others=TRUE, - bool extended_select=FALSE); - void SelectAll(bool extended_select=FALSE); + void SelectItem(const wxTreeItemId& item, const wxTreeItemId& prev = (wxTreeItemId*)NULL, + bool unselect_others = true); + void SelectAll(); // make sure this item is visible (expanding the parent item and/or // scrolling to this item if necessary) void EnsureVisible(const wxTreeItemId& item); @@ -508,24 +511,22 @@ public: // The first function is more portable (because easier to implement // on other platforms), but the second one returns some extra info. - wxTreeItemId HitTest(const wxPoint& point) - { int dummy; return HitTest(point, dummy); } - wxTreeItemId HitTest(const wxPoint& point, int& flags) - { int col; return HitTest(point, flags, col); } - // ALB - wxTreeItemId HitTest(const wxPoint& point, int& flags, int& column); + wxTreeItemId HitTest (const wxPoint& point) + { int flags; int column; return HitTest (point, flags, column); } + wxTreeItemId HitTest (const wxPoint& point, int& flags) + { int column; return HitTest (point, flags, column); } + wxTreeItemId HitTest (const wxPoint& point, int& flags, int& column); // get the bounding rectangle of the item (or of its label only) bool GetBoundingRect(const wxTreeItemId& item, wxRect& rect, - bool textOnly = FALSE) const; + bool textOnly = false) const; // Start editing the item label: this (temporarily) replaces the item // with a one line edit control. The item will be selected if it hadn't // been before. - void EditLabel( const wxTreeItemId& item ) { Edit( item ); } - void Edit( const wxTreeItemId& item ); + void EditLabel (const wxTreeItemId& item, int column); // sorting // this function is called to compare 2 items and should return -1, 0 @@ -540,15 +541,7 @@ public: void SortChildren(const wxTreeItemId& item); // searching - wxTreeItemId FindItem (const wxTreeItemId& item, const wxString& str, int flags = 0); - - // deprecated functions: use Set/GetItemImage directly - // get the selected item image - int GetItemSelectedImage(const wxTreeItemId& item) const - { return GetItemImage(item, wxTreeItemIcon_Selected); } - // set the selected item image - void SetItemSelectedImage(const wxTreeItemId& item, int image) - { SetItemImage(item, image, wxTreeItemIcon_Selected); } + wxTreeItemId FindItem (const wxTreeItemId& item, const wxString& str, int mode = 0); // implementation only from now on @@ -556,6 +549,9 @@ public: virtual bool SetBackgroundColour(const wxColour& colour); virtual bool SetForegroundColour(const wxColour& colour); + // drop over item + void SetDragItem (const wxTreeItemId& item = (wxTreeItemId*)NULL); + // callbacks void OnPaint( wxPaintEvent &event ); void OnSetFocus( wxFocusEvent &event ); @@ -563,51 +559,45 @@ public: void OnChar( wxKeyEvent &event ); void OnMouse( wxMouseEvent &event ); void OnIdle( wxIdleEvent &event ); - void OnScroll(wxScrollWinEvent& event); // ALB + void OnScroll(wxScrollWinEvent& event); // implementation helpers void SendDeleteEvent(wxTreeListItem *itemBeingDeleted); - void DoDirtyProcessing(); - - void DrawBorder(const wxTreeItemId& item); - void DrawLine(const wxTreeItemId& item, bool below); - - size_t GetColumnCount() const + int GetColumnCount() const { return m_owner->GetHeaderWindow()->GetColumnCount(); } - void SetMainColumn(size_t column) - { - if(column < GetColumnCount()) - m_main_column = column; - } - size_t GetMainColumn() const { return m_main_column; } + void SetMainColumn (int column) + { if ((column >= 0) && (column < GetColumnCount())) m_main_column = column; } - void SetItemText(const wxTreeItemId& item, size_t column, - const wxString& text); - wxString GetItemText(const wxTreeItemId& item, size_t column) const; + int GetMainColumn() const { return m_main_column; } - void SetItemImage(const wxTreeItemId& item, size_t column, int image, - wxTreeItemIcon which = wxTreeItemIcon_Normal); - int GetItemImage(const wxTreeItemId& item, size_t column, - wxTreeItemIcon which = wxTreeItemIcon_Normal) const; + int GetBestColumnWidth (int column, wxTreeItemId parent = wxTreeItemId()); + int GetItemWidth (int column, wxTreeListItem *item); + wxFont GetItemFont (wxTreeListItem *item); void SetFocus(); protected: - wxTreeListCtrl* m_owner; // ALB + wxTreeListCtrl* m_owner; - size_t m_main_column; // ALB + int m_main_column; friend class wxTreeListItem; friend class wxTreeListRenameTimer; - friend class wxTreeListTextCtrl; + friend class wxEditTextCtrl; wxFont m_normalFont; wxFont m_boldFont; - wxTreeListItem *m_anchor; - wxTreeListItem *m_current, *m_key_current, *m_currentEdit; + wxTreeListItem *m_rootItem; // root item + wxTreeListItem *m_curItem; // current item, either selected or marked + wxTreeListItem *m_shiftItem; // item, where the shift key was pressed + wxTreeListItem *m_editItem; // item, which is currently edited + wxTreeListItem *m_selectItem; // current selected item, not with wxTR_MULTIPLE + + int m_curColumn; + int m_btnWidth, m_btnWidth2; int m_btnHeight, m_btnHeight2; int m_imgWidth, m_imgWidth2; @@ -628,16 +618,15 @@ protected: bool m_isDragging; // true between BEGIN/END drag events bool m_renameAccept; bool m_lastOnSame; // last click on the same item as prev + bool m_left_down_selection; + wxImageList *m_imageListNormal, *m_imageListState, *m_imageListButtons; int m_dragCount; - wxPoint m_dragStart; - wxTreeListItem *m_dropTarget; - wxCursor m_oldCursor; // cursor is changed while dragging - wxTreeListItem *m_oldSelection; - wxTreeListItem *m_underMouse; // for visual effects + wxTimer *m_dragTimer; + wxTreeListItem *m_dragItem; wxTimer *m_renameTimer; wxString m_renameRes; @@ -656,42 +645,36 @@ protected: int image, int selectedImage, wxTreeItemData *data); bool HasButtons(void) const - { return (m_imageListButtons != NULL) || - HasFlag (wxTR_TWIST_BUTTONS|wxTR_HAS_BUTTONS); } + { return (m_imageListButtons) || HasFlag (wxTR_TWIST_BUTTONS|wxTR_HAS_BUTTONS); } protected: void CalculateLineHeight(); int GetLineHeight(wxTreeListItem *item) const; void PaintLevel( wxTreeListItem *item, wxDC& dc, int level, int &y, - int x_colstart); + int x_maincol); void PaintItem( wxTreeListItem *item, wxDC& dc); void CalculateLevel( wxTreeListItem *item, wxDC &dc, int level, int &y, - int x_colstart); + int x_maincol); void CalculatePositions(); void CalculateSize( wxTreeListItem *item, wxDC &dc ); - void RefreshSubtree( wxTreeListItem *item ); - void RefreshLine( wxTreeListItem *item ); + void RefreshSubtree (wxTreeListItem *item); + void RefreshLine (wxTreeListItem *item); // redraw all selected items void RefreshSelected(); // RefreshSelected() recursive helper - void RefreshSelectedUnder(wxTreeListItem *item); + void RefreshSelectedUnder (wxTreeListItem *item); void OnRenameTimer(); void OnRenameAccept(); void FillArray(wxTreeListItem*, wxArrayTreeItemIds&) const; - void SelectItemRange( wxTreeListItem *item1, wxTreeListItem *item2 ); - bool TagAllChildrenUntilLast(wxTreeListItem *crt_item, - wxTreeListItem *last_item, bool select); - bool TagNextChildren(wxTreeListItem *crt_item, wxTreeListItem *last_item, - bool select); - void UnselectAllChildren( wxTreeListItem *item ); - - void DrawDropEffect(wxTreeListItem *item); + bool TagAllChildrenUntilLast (wxTreeListItem *crt_item, wxTreeListItem *last_item); + bool TagNextChildren (wxTreeListItem *crt_item, wxTreeListItem *last_item); + void UnselectAllChildren (wxTreeListItem *item ); private: DECLARE_EVENT_TABLE() @@ -712,20 +695,20 @@ private: }; // control used for in-place edit -class wxTreeListTextCtrl: public wxTextCtrl +class wxEditTextCtrl: public wxTextCtrl { public: - wxTreeListTextCtrl( wxWindow *parent, - const wxWindowID id, - bool *accept, - wxString *res, - wxTreeListMainWindow *owner, - const wxString &value = wxEmptyString, - const wxPoint &pos = wxDefaultPosition, - const wxSize &size = wxDefaultSize, - int style = wxSIMPLE_BORDER, - const wxValidator& validator = wxDefaultValidator, - const wxString &name = wxTextCtrlNameStr ); + wxEditTextCtrl (wxWindow *parent, + const wxWindowID id, + bool *accept, + wxString *res, + wxTreeListMainWindow *owner, + const wxString &value = wxEmptyString, + const wxPoint &pos = wxDefaultPosition, + const wxSize &size = wxDefaultSize, + int style = 0, + const wxValidator& validator = wxDefaultValidator, + const wxString &name = wxTextCtrlNameStr ); void OnChar( wxKeyEvent &event ); void OnKeyUp( wxKeyEvent &event ); @@ -761,71 +744,78 @@ public: const wxString GetText() const { - if(m_text.GetCount() > 0) return m_text[0]; - return wxEmptyString; + return GetText(0); } - const wxString GetText(size_t col) const + const wxString GetText (int column) const { - if(m_text.GetCount() > col) return m_text[col]; + if(m_text.GetCount() > 0) + { + if( IsVirtual() ) return m_owner->GetItemText( m_data, column ); + else return m_text[column]; + } return wxEmptyString; } - int GetImage(wxTreeItemIcon which = wxTreeItemIcon_Normal) const + + int GetImage (wxTreeItemIcon which = wxTreeItemIcon_Normal) const { return m_images[which]; } - int GetImage(size_t col, wxTreeItemIcon which=wxTreeItemIcon_Normal) const + int GetImage (int column, wxTreeItemIcon which=wxTreeItemIcon_Normal) const { - if(col == m_owner->GetMainColumn()) return m_images[which]; - if(col < m_col_images.GetCount()) return m_col_images[col]; + if(column == m_owner->GetMainColumn()) return m_images[which]; + if(column < (int)m_col_images.GetCount()) return m_col_images[column]; return NO_IMAGE; } + wxTreeItemData *GetData() const { return m_data; } // returns the current image for the item (depending on its // selected/expanded/whatever state) int GetCurrentImage() const; - void SetText( const wxString &text ); - void SetText(size_t col, const wxString& text) // ALB + void SetText (const wxString &text ); + void SetText (int column, const wxString& text) { - if(col < m_text.GetCount()) - m_text[col] = text; - else if(col < m_owner->GetColumnCount()) { + if (column < (int)m_text.GetCount()) { + m_text[column] = text; + }else if (column < m_owner->GetColumnCount()) { int howmany = m_owner->GetColumnCount(); - for(int i = m_text.GetCount(); i < howmany; ++i) - m_text.Add(wxEmptyString); - m_text[col] = text; + for (int i = m_text.GetCount(); i < howmany; ++i) m_text.Add (wxEmptyString); + m_text[column] = text; } } - void SetImage(int image, wxTreeItemIcon which) { m_images[which] = image; } - void SetImage(size_t col, int image, wxTreeItemIcon which) + void SetImage (int image, wxTreeItemIcon which) { m_images[which] = image; } + void SetImage (int column, int image, wxTreeItemIcon which) { - if(col == m_owner->GetMainColumn()) m_images[which] = image; - else if(col < m_col_images.GetCount()) - m_col_images[col] = image; - else if(col < m_owner->GetColumnCount()) { + if (column == m_owner->GetMainColumn()) { + m_images[which] = image; + }else if (column < (int)m_col_images.GetCount()) { + m_col_images[column] = image; + }else if (column < m_owner->GetColumnCount()) { int howmany = m_owner->GetColumnCount(); - for(int i = m_col_images.GetCount(); i < howmany; ++i) - m_col_images.Add(NO_IMAGE); - m_col_images[col] = image; + for (int i = m_col_images.GetCount(); i < howmany; ++i) m_col_images.Add (NO_IMAGE); + m_col_images[column] = image; } } void SetData(wxTreeItemData *data) { m_data = data; } - void SetHasPlus(bool has = TRUE) { m_hasPlus = has; } + void SetHasPlus(bool has = true) { m_hasPlus = has; } void SetBold(bool bold) { m_isBold = bold; } int GetX() const { return m_x; } int GetY() const { return m_y; } - void SetX(int x) { m_x = x; } - void SetY(int y) { m_y = y; } + void SetX (int x) { m_x = x; } + void SetY (int y) { m_y = y; } int GetHeight() const { return m_height; } int GetWidth() const { return m_width; } - void SetHeight(int h) { m_height = h; } - void SetWidth(int w) { m_width = w; } + void SetHeight (int height) { m_height = height; } + void SetWidth (int width) { m_width = width; } + + int GetTextX() const { return m_text_x; } + void SetTextX (int text_x) { m_text_x = text_x; } wxTreeListItem *GetItemParent() const { return m_parent; } @@ -835,7 +825,7 @@ public: void DeleteChildren(wxTreeListMainWindow *tree = NULL); // get count of all children (and grand children if 'recursively') - size_t GetChildrenCount(bool recursively = TRUE) const; + size_t GetChildrenCount(bool recursively = true) const; void Insert(wxTreeListItem *child, size_t index) { m_children.Insert(child, index); } @@ -843,21 +833,16 @@ public: void GetSize( int &x, int &y, const wxTreeListMainWindow* ); // return the item at given position (or NULL if no item), onButton is - // TRUE if the point belongs to the item's button, otherwise it lies + // true if the point belongs to the item's button, otherwise it lies // on the button's label - wxTreeListItem *HitTest( const wxPoint& point, - const wxTreeListMainWindow *, - int &flags, - int level ); - wxTreeListItem *HitTest( const wxPoint& point, + wxTreeListItem *HitTest (const wxPoint& point, const wxTreeListMainWindow *, - int &flags, int& column /*ALB*/, - int level ); + int &flags, int& column, int level); - void Expand() { m_isCollapsed = FALSE; } - void Collapse() { m_isCollapsed = TRUE; } + void Expand() { m_isCollapsed = false; } + void Collapse() { m_isCollapsed = true; } - void SetHilight( bool set = TRUE ) { m_hasHilight = set; } + void SetHilight( bool set = true ) { m_hasHilight = set; } // status inquiries bool HasChildren() const { return !m_children.IsEmpty(); } @@ -865,6 +850,7 @@ public: bool IsExpanded() const { return !m_isCollapsed; } bool HasPlus() const { return m_hasPlus || HasChildren(); } bool IsBold() const { return m_isBold != 0; } + bool IsVirtual() const { return m_owner->IsVirtual(); } // attributes // get them - may be NULL @@ -875,7 +861,7 @@ public: if ( !m_attr ) { m_attr = new wxTreeItemAttr; - m_ownsAttr = TRUE; + m_ownsAttr = true; } return *m_attr; } @@ -884,13 +870,13 @@ public: { if ( m_ownsAttr ) delete m_attr; m_attr = attr; - m_ownsAttr = FALSE; + m_ownsAttr = false; } // set them and delete when done void AssignAttributes(wxTreeItemAttr *attr) { SetAttributes(attr); - m_ownsAttr = TRUE; + m_ownsAttr = true; } private: @@ -913,8 +899,10 @@ private: short m_images[wxTreeItemIcon_Max]; wxArrayShort m_col_images; // images for the various columns (!= main) - wxCoord m_x; // (virtual) offset from top - wxCoord m_y; // (virtual) offset from left + // main column item positions + wxCoord m_x; // (virtual) offset from left (vertical line) + wxCoord m_y; // (virtual) offset from top + wxCoord m_text_x; // item offset from left short m_width; // width of this item unsigned char m_height; // height of this item @@ -931,24 +919,6 @@ private: // implementation // =========================================================================== -// ---------------------------------------------------------------------------- -// private functions -// ---------------------------------------------------------------------------- - -// translate the key or mouse event flags to the type of selection we're -// dealing with -static void EventFlagsToSelType(long style, - bool shiftDown, - bool ctrlDown, - bool &is_multiple, - bool &extended_select, - bool &unselect_others) -{ - is_multiple = (style & wxTR_MULTIPLE) != 0; - extended_select = shiftDown && is_multiple; - unselect_others = !(extended_select || (ctrlDown && is_multiple)); -} - // --------------------------------------------------------------------------- // wxTreeListRenameTimer (internal) // --------------------------------------------------------------------------- @@ -964,42 +934,42 @@ void wxTreeListRenameTimer::Notify() } //----------------------------------------------------------------------------- -// wxTreeListTextCtrl (internal) +// wxEditTextCtrl (internal) //----------------------------------------------------------------------------- -BEGIN_EVENT_TABLE(wxTreeListTextCtrl,wxTextCtrl) - EVT_CHAR (wxTreeListTextCtrl::OnChar) - EVT_KEY_UP (wxTreeListTextCtrl::OnKeyUp) - EVT_KILL_FOCUS (wxTreeListTextCtrl::OnKillFocus) +BEGIN_EVENT_TABLE (wxEditTextCtrl,wxTextCtrl) + EVT_CHAR (wxEditTextCtrl::OnChar) + EVT_KEY_UP (wxEditTextCtrl::OnKeyUp) + EVT_KILL_FOCUS (wxEditTextCtrl::OnKillFocus) END_EVENT_TABLE() -wxTreeListTextCtrl::wxTreeListTextCtrl( wxWindow *parent, - const wxWindowID id, - bool *accept, - wxString *res, - wxTreeListMainWindow *owner, - const wxString &value, - const wxPoint &pos, - const wxSize &size, - int style, - const wxValidator& validator, - const wxString &name ) - : wxTextCtrl( parent, id, value, pos, size, style, validator, name ) +wxEditTextCtrl::wxEditTextCtrl (wxWindow *parent, + const wxWindowID id, + bool *accept, + wxString *res, + wxTreeListMainWindow *owner, + const wxString &value, + const wxPoint &pos, + const wxSize &size, + int style, + const wxValidator& validator, + const wxString &name) + : wxTextCtrl (parent, id, value, pos, size, style|wxSIMPLE_BORDER, validator, name) { m_res = res; m_accept = accept; m_owner = owner; - (*m_accept) = FALSE; + (*m_accept) = false; (*m_res) = wxEmptyString; m_startValue = value; - m_finished = FALSE; + m_finished = false; } -void wxTreeListTextCtrl::OnChar( wxKeyEvent &event ) +void wxEditTextCtrl::OnChar( wxKeyEvent &event ) { - if (event.m_keyCode == WXK_RETURN) + if (event.GetKeyCode() == WXK_RETURN) { - (*m_accept) = TRUE; + (*m_accept) = true; (*m_res) = GetValue(); if ((*m_res) != m_startValue) @@ -1008,20 +978,20 @@ void wxTreeListTextCtrl::OnChar( wxKeyEvent &event ) if (!wxPendingDelete.Member(this)) wxPendingDelete.Append(this); - m_finished = TRUE; + m_finished = true; m_owner->SetFocus(); // This doesn't work. TODO. return; } - if (event.m_keyCode == WXK_ESCAPE) + if (event.GetKeyCode() == WXK_ESCAPE) { - (*m_accept) = FALSE; + (*m_accept) = false; (*m_res) = wxEmptyString; if (!wxPendingDelete.Member(this)) wxPendingDelete.Append(this); - m_finished = TRUE; + m_finished = true; m_owner->SetFocus(); // This doesn't work. TODO. return; @@ -1029,7 +999,7 @@ void wxTreeListTextCtrl::OnChar( wxKeyEvent &event ) event.Skip(); } -void wxTreeListTextCtrl::OnKeyUp( wxKeyEvent &event ) +void wxEditTextCtrl::OnKeyUp( wxKeyEvent &event ) { if (m_finished) { @@ -1050,7 +1020,7 @@ void wxTreeListTextCtrl::OnKeyUp( wxKeyEvent &event ) event.Skip(); } -void wxTreeListTextCtrl::OnKillFocus( wxFocusEvent &event ) +void wxEditTextCtrl::OnKillFocus( wxFocusEvent &event ) { if (m_finished) { @@ -1061,7 +1031,7 @@ void wxTreeListTextCtrl::OnKillFocus( wxFocusEvent &event ) if (!wxPendingDelete.Member(this)) wxPendingDelete.Append(this); - (*m_accept) = TRUE; + (*m_accept) = true; (*m_res) = GetValue(); if ((*m_res) != m_startValue) @@ -1072,20 +1042,19 @@ void wxTreeListTextCtrl::OnKillFocus( wxFocusEvent &event ) // wxTreeListHeaderWindow //----------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxTreeListHeaderWindow,wxWindow) +IMPLEMENT_DYNAMIC_CLASS(wxTreeListHeaderWindow,wxWindow); BEGIN_EVENT_TABLE(wxTreeListHeaderWindow,wxWindow) - EVT_ERASE_BACKGROUND (wxTreeListHeaderWindow::OnEraseBackground) - EVT_PAINT (wxTreeListHeaderWindow::OnPaint) - EVT_MOUSE_EVENTS (wxTreeListHeaderWindow::OnMouse) - EVT_SET_FOCUS (wxTreeListHeaderWindow::OnSetFocus) + EVT_PAINT (wxTreeListHeaderWindow::OnPaint) + EVT_MOUSE_EVENTS (wxTreeListHeaderWindow::OnMouse) + EVT_SET_FOCUS (wxTreeListHeaderWindow::OnSetFocus) END_EVENT_TABLE() void wxTreeListHeaderWindow::Init() { m_currentCursor = (wxCursor *) NULL; - m_isDragging = FALSE; - m_dirty = FALSE; + m_isDragging = false; + m_dirty = false; m_total_col_width = 0; } @@ -1111,8 +1080,11 @@ wxTreeListHeaderWindow::wxTreeListHeaderWindow( wxWindow *win, m_owner = owner; m_resizeCursor = new wxCursor(wxCURSOR_SIZEWE); - SetBackgroundColour(wxSystemSettings::GetColour( - wxSYS_COLOUR_BTNFACE)); +#if !wxCHECK_VERSION(2, 5, 0) + SetBackgroundColour (wxSystemSettings::GetSystemColour (wxSYS_COLOUR_BTNFACE)); +#else + SetBackgroundColour (wxSystemSettings::GetColour (wxSYS_COLOUR_BTNFACE)); +#endif } wxTreeListHeaderWindow::~wxTreeListHeaderWindow() @@ -1122,49 +1094,26 @@ wxTreeListHeaderWindow::~wxTreeListHeaderWindow() void wxTreeListHeaderWindow::DoDrawRect( wxDC *dc, int x, int y, int w, int h ) { -#ifdef __WXGTK__ - GtkStateType state = m_parent->IsEnabled() ? GTK_STATE_NORMAL - : GTK_STATE_INSENSITIVE; - - x = dc->LogicalToDeviceX( x ); +#if !wxCHECK_VERSION(2, 5, 0) + wxPen pen (wxSystemSettings::GetSystemColour (wxSYS_COLOUR_BTNSHADOW ), 1, wxSOLID); +#else + wxPen pen (wxSystemSettings::GetColour (wxSYS_COLOUR_BTNSHADOW ), 1, wxSOLID); +#endif - gtk_paint_box (m_wxwindow->style, GTK_PIZZA(m_wxwindow)->bin_window, - state, GTK_SHADOW_OUT, - (GdkRectangle*) NULL, m_wxwindow, "button", - x-1, y-1, w+2, h+2); -#elif defined( __WXMAC__ ) const int m_corner = 1; dc->SetBrush( *wxTRANSPARENT_BRUSH ); - - dc->SetPen( wxPen(wxSystemSettings::GetColour( - wxSYS_COLOUR_BTNSHADOW), 1, wxSOLID)); - dc->DrawLine( x+w-m_corner+1, y, x+w, y+h ); // right (outer) - dc->DrawRectangle( x, y+h, w+1, 1 ); // bottom (outer) - - wxPen pen( wxColour( 0x88 , 0x88 , 0x88 ), 1, wxSOLID ); - - dc->SetPen( pen ); - dc->DrawLine( x+w-m_corner, y, x+w-1, y+h ); // right (inner) - dc->DrawRectangle( x+1, y+h-1, w-2, 1 ); // bottom (inner) - - dc->SetPen( *wxWHITE_PEN ); - dc->DrawRectangle( x, y, w-m_corner+1, 1 ); // top (outer) - dc->DrawRectangle( x, y, 1, h ); // left (outer) - dc->DrawLine( x, y+h-1, x+1, y+h-1 ); - dc->DrawLine( x+w-1, y, x+w-1, y+1 ); +#if defined( __WXMAC__ ) + dc->SetPen (pen); #else // !GTK, !Mac - const int m_corner = 1; - - dc->SetBrush( *wxTRANSPARENT_BRUSH ); - dc->SetPen( *wxBLACK_PEN ); +#endif dc->DrawLine( x+w-m_corner+1, y, x+w, y+h ); // right (outer) dc->DrawRectangle( x, y+h, w+1, 1 ); // bottom (outer) - wxPen pen(wxSystemSettings::GetColour( - wxSYS_COLOUR_BTNSHADOW ), 1, wxSOLID); - +#if defined( __WXMAC__ ) + wxPen pen( wxColour( 0x88 , 0x88 , 0x88 ), 1, wxSOLID ); +#endif dc->SetPen( pen ); dc->DrawLine( x+w-m_corner, y, x+w-1, y+h ); // right (inner) dc->DrawRectangle( x+1, y+h-1, w-2, 1 ); // bottom (inner) @@ -1174,7 +1123,6 @@ void wxTreeListHeaderWindow::DoDrawRect( wxDC *dc, int x, int y, int w, int h ) dc->DrawRectangle( x, y, 1, h ); // left (outer) dc->DrawLine( x, y+h-1, x+1, y+h-1 ); dc->DrawLine( x+w-1, y, x+w-1, y+1 ); -#endif } // shift the DC origin to match the position of the main window horz @@ -1183,7 +1131,6 @@ void wxTreeListHeaderWindow::AdjustDC(wxDC& dc) { int xpix; m_owner->GetScrollPixelsPerUnit( &xpix, NULL ); - int x; m_owner->GetViewStart( &x, NULL ); @@ -1191,11 +1138,6 @@ void wxTreeListHeaderWindow::AdjustDC(wxDC& dc) dc.SetDeviceOrigin( -x * xpix, 0 ); } - -void wxTreeListHeaderWindow::OnEraseBackground( wxEraseEvent& event ) -{ -} - void wxTreeListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) { #ifdef __WXGTK__ @@ -1204,31 +1146,31 @@ void wxTreeListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) wxPaintDC dc( this ); #endif + PrepareDC( dc ); AdjustDC( dc ); + dc.SetFont( GetFont() ); // width and height of the entire header window int w, h; GetClientSize( &w, &h ); m_owner->CalcUnscrolledPosition(w, 0, &w, NULL); - - dc.SetBackground(wxBrush(GetBackgroundColour())); - dc.Clear(); - - dc.SetFont( GetFont() ); dc.SetBackgroundMode(wxTRANSPARENT); // do *not* use the listctrl colour for headers - one day we will have a // function to set it separately //dc.SetTextForeground( *wxBLACK ); - dc.SetTextForeground(wxSystemSettings:: - GetColour( wxSYS_COLOUR_WINDOWTEXT )); +#if !wxCHECK_VERSION(2, 5, 0) + dc.SetTextForeground (wxSystemSettings::GetSystemColour( wxSYS_COLOUR_WINDOWTEXT )); +#else + dc.SetTextForeground (wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT )); +#endif int x = HEADER_OFFSET_X; int numColumns = GetColumnCount(); for ( int i = 0; i < numColumns && x < w; i++ ) { - if (!GetColumnShown (i)) continue; + if (!IsColumnShown (i)) continue; // do next colume if not shown wxTreeListColumnInfo& column = GetColumn(i); int wCol = column.GetWidth(); @@ -1237,113 +1179,107 @@ void wxTreeListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) // inside the column rect int cw = wCol - 2; +#if !wxCHECK_VERSION(2, 7, 0) dc.SetPen( *wxWHITE_PEN ); - - //DoDrawRect( &dc, x, HEADER_OFFSET_Y, cw, h-2 ); - wxRendererNative::Get().DrawHeaderButton( - this, dc, wxRect(x, HEADER_OFFSET_Y, cw, h - 2), - m_parent->IsEnabled() ? 0 : wxCONTROL_DISABLED); - + DoDrawRect( &dc, x, HEADER_OFFSET_Y, cw, h-2 ); +#else + wxRect rect(x, HEADER_OFFSET_Y, cw, h-2); + wxRendererNative::GetDefault().DrawHeaderButton (this, dc, rect); +#endif // if we have an image, draw it on the right of the label int image = column.GetImage(); //item.m_image; int ix = -2, iy = 0; wxImageList* imageList = m_owner->GetImageList(); - if(image != -1) { - if(imageList) { - imageList->GetSize(image, ix, iy); - } - //else: ignore the column image + if ((image != -1) && imageList) { + imageList->GetSize (image, ix, iy); } + // extra margins around the text label int text_width = 0; int text_x = x; int image_offset = cw - ix - 1; switch(column.GetAlignment()) { - case wxTL_ALIGN_LEFT: + case wxALIGN_LEFT: text_x += EXTRA_WIDTH; cw -= ix + 2; break; - case wxTL_ALIGN_RIGHT: - dc.GetTextExtent(column.GetText(), &text_width, NULL); - text_x += cw - text_width - EXTRA_WIDTH; + case wxALIGN_RIGHT: + dc.GetTextExtent (column.GetText(), &text_width, NULL); + text_x += cw - text_width - EXTRA_WIDTH - MARGIN; image_offset = 0; break; - case wxTL_ALIGN_CENTER: + case wxALIGN_CENTER: dc.GetTextExtent(column.GetText(), &text_width, NULL); text_x += (cw - text_width)/2 + ix + 2; - image_offset = (cw - text_width - ix - 2)/2; + image_offset = (cw - text_width - ix - 2)/2 - MARGIN; break; } // draw the image - if(image != -1 && imageList) { - imageList->Draw(image, dc, x + image_offset/*cw - ix - 1*/, - HEADER_OFFSET_Y + (h - 4 - iy)/2, - wxIMAGELIST_DRAW_TRANSPARENT); + if ((image != -1) && imageList) { + imageList->Draw (image, dc, x + image_offset/*cw - ix - 1*/, + HEADER_OFFSET_Y + (h - 4 - iy)/2, + wxIMAGELIST_DRAW_TRANSPARENT); } - // draw the text clipping it so that it doesn't overwrite the column - // boundary + // draw the text clipping it so that it doesn't overwrite the column boundary wxDCClipper clipper(dc, x, HEADER_OFFSET_Y, cw, h - 4 ); + dc.DrawText (column.GetText(), text_x, HEADER_OFFSET_Y + EXTRA_HEIGHT ); - dc.DrawText( column.GetText(), - text_x, HEADER_OFFSET_Y + EXTRA_HEIGHT ); - + // next column x += wCol; } - int more_w = m_owner->GetSize().x - x -1; - if (more_w > 0) - { - //DoDrawRect( &dc, x, HEADER_OFFSET_Y, more_w, h-2 ); - wxRendererNative::Get().DrawHeaderButton( - this, dc, wxRect(x, HEADER_OFFSET_Y, more_w, h-2), - m_parent->IsEnabled() ? 0 : wxCONTROL_DISABLED); + int more_w = m_owner->GetSize().x - x - HEADER_OFFSET_X; + if (more_w > 0) { +#if !wxCHECK_VERSION(2, 7, 0) + DoDrawRect (&dc, x, HEADER_OFFSET_Y, more_w, h-2 ); +#else + wxRect rect (x, HEADER_OFFSET_Y, more_w, h-2); + wxRendererNative::GetDefault().DrawHeaderButton (this, dc, rect); +#endif } + } void wxTreeListHeaderWindow::DrawCurrent() { int x1 = m_currentX; int y1 = 0; - ClientToScreen( &x1, &y1 ); + ClientToScreen (&x1, &y1); int x2 = m_currentX-1; #ifdef __WXMSW__ - ++x2; // but why ? + ++x2; // but why ???? #endif int y2 = 0; m_owner->GetClientSize( NULL, &y2 ); m_owner->ClientToScreen( &x2, &y2 ); wxScreenDC dc; - dc.SetLogicalFunction( wxINVERT ); - dc.SetPen( wxPen( *wxBLACK, 2, wxSOLID ) ); - dc.SetBrush( *wxTRANSPARENT_BRUSH ); + dc.SetLogicalFunction (wxINVERT); + dc.SetPen (wxPen (*wxBLACK, 2, wxSOLID)); + dc.SetBrush (*wxTRANSPARENT_BRUSH); AdjustDC(dc); - - dc.DrawLine( x1, y1, x2, y2 ); - - dc.SetLogicalFunction( wxCOPY ); - - dc.SetPen( wxNullPen ); - dc.SetBrush( wxNullBrush ); + dc.DrawLine (x1, y1, x2, y2); + dc.SetLogicalFunction (wxCOPY); + dc.SetPen (wxNullPen); + dc.SetBrush (wxNullBrush); } -void wxTreeListHeaderWindow::OnMouse( wxMouseEvent &event ) -{ +void wxTreeListHeaderWindow::OnMouse (wxMouseEvent &event) { + // we want to work with logical coords int x; m_owner->CalcUnscrolledPosition(event.GetX(), 0, &x, NULL); int y = event.GetY(); - if (m_isDragging) - { - SendListEvent(wxEVT_COMMAND_LIST_COL_DRAGGING, - event.GetPosition()); + if (m_isDragging) { + + SendListEvent (wxEVT_COMMAND_LIST_COL_DRAGGING, event.GetPosition()); // we don't draw the line beyond our window, but we allow dragging it // there @@ -1353,56 +1289,44 @@ void wxTreeListHeaderWindow::OnMouse( wxMouseEvent &event ) w -= 6; // erase the line if it was drawn - if ( m_currentX < w ) - DrawCurrent(); + if (m_currentX < w) DrawCurrent(); - if (event.ButtonUp()) - { - ReleaseMouse(); - m_isDragging = FALSE; - m_dirty = TRUE; - SetColumnWidth( m_column, m_currentX - m_minX ); + if (event.ButtonUp()) { + m_isDragging = false; + if (HasCapture()) ReleaseMouse(); + m_dirty = true; + SetColumnWidth (m_column, m_currentX - m_minX); Refresh(); - SendListEvent(wxEVT_COMMAND_LIST_COL_END_DRAG, - event.GetPosition()); - } - else - { - if (x > m_minX + 7) - m_currentX = x; - else - m_currentX = m_minX + 7; + SendListEvent (wxEVT_COMMAND_LIST_COL_END_DRAG, event.GetPosition()); + }else{ + m_currentX = wxMax (m_minX + 7, x); // draw in the new location - if ( m_currentX < w ) - DrawCurrent(); + if (m_currentX < w) DrawCurrent(); } - } - else // not dragging - { + + }else{ // not dragging + m_minX = 0; - bool hit_border = FALSE; + bool hit_border = false; // end of the current column int xpos = 0; - // find the column where this event occurred + // find the column where this event occured int countCol = GetColumnCount(); - for (int col = 0; col < countCol; col++) - { - if (!GetColumnShown (col)) continue; - xpos += GetColumnWidth (col); - m_column = col; + for (int column = 0; column < countCol; column++) { + if (!IsColumnShown (column)) continue; // do next if not shown - if ( (abs(x-xpos) < 3) && (y < 22) ) - { + xpos += GetColumnWidth (column); + m_column = column; + if ((abs (x-xpos) < 3) && (y < 22)) { // near the column border - hit_border = TRUE; + hit_border = true; break; } - if ( x < xpos ) - { + if (x < xpos) { // inside the column break; } @@ -1410,55 +1334,45 @@ void wxTreeListHeaderWindow::OnMouse( wxMouseEvent &event ) m_minX = xpos; } - if (event.LeftDown() || event.RightUp()) - { - if (hit_border && event.LeftDown()) - { - m_isDragging = TRUE; + if (event.LeftDown() || event.RightUp()) { + if (hit_border && event.LeftDown()) { + m_isDragging = true; + CaptureMouse(); m_currentX = x; DrawCurrent(); - CaptureMouse(); - SendListEvent(wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, - event.GetPosition()); - } - else // click on a column - { - SendListEvent( event.LeftDown() - ? wxEVT_COMMAND_LIST_COL_CLICK - : wxEVT_COMMAND_LIST_COL_RIGHT_CLICK, - event.GetPosition()); + SendListEvent (wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, event.GetPosition()); + }else{ // click on a column + wxEventType evt = event.LeftDown()? wxEVT_COMMAND_LIST_COL_CLICK: + wxEVT_COMMAND_LIST_COL_RIGHT_CLICK; + SendListEvent (evt, event.GetPosition()); } - } - else if (event.Moving()) - { + }else if (event.LeftDClick() && hit_border) { + SetColumnWidth (m_column, m_owner->GetBestColumnWidth (m_column)); + Refresh(); + + }else if (event.Moving()) { bool setCursor; - if (hit_border) - { + if (hit_border) { setCursor = m_currentCursor == wxSTANDARD_CURSOR; m_currentCursor = m_resizeCursor; - } - else - { + }else{ setCursor = m_currentCursor != wxSTANDARD_CURSOR; m_currentCursor = wxSTANDARD_CURSOR; } - - if ( setCursor ) - SetCursor(*m_currentCursor); + if (setCursor) SetCursor (*m_currentCursor); } + } } -void wxTreeListHeaderWindow::OnSetFocus( wxFocusEvent &WXUNUSED(event) ) -{ +void wxTreeListHeaderWindow::OnSetFocus (wxFocusEvent &WXUNUSED(event)) { m_owner->SetFocus(); } -void wxTreeListHeaderWindow::SendListEvent(wxEventType type, wxPoint pos) -{ +void wxTreeListHeaderWindow::SendListEvent (wxEventType type, wxPoint pos) { wxWindow *parent = GetParent(); - wxListEvent le( type, parent->GetId() ); - le.SetEventObject( parent ); + wxListEvent le (type, parent->GetId()); + le.SetEventObject (parent); le.m_pointDrag = pos; // the position should be relative to the parent window, not @@ -1466,348 +1380,272 @@ void wxTreeListHeaderWindow::SendListEvent(wxEventType type, wxPoint pos) // user code doesn't know anything at all about this header // window, so why should it get positions relative to it? le.m_pointDrag.y -= GetSize().y; - le.m_col = m_column; - parent->GetEventHandler()->ProcessEvent( le ); + parent->GetEventHandler()->ProcessEvent (le); } -void wxTreeListHeaderWindow::AddColumn(const wxTreeListColumnInfo& col) -{ - m_columns.Add(col); - m_total_col_width += col.GetWidth(); - //m_owner->GetHeaderWindow()->Refresh(); - //m_dirty = TRUE; +void wxTreeListHeaderWindow::AddColumn (const wxTreeListColumnInfo& colInfo) { + m_columns.Add (colInfo); + m_total_col_width += colInfo.GetWidth(); m_owner->AdjustMyScrollbars(); - m_owner->m_dirty = TRUE; - Refresh(); + m_owner->m_dirty = true; } -void wxTreeListHeaderWindow::SetColumnWidth(size_t column, size_t width) -{ - if(column < GetColumnCount()) { - m_total_col_width -= m_columns[column].GetWidth(); - m_columns[column].SetWidth(width); - m_total_col_width += width; - m_owner->AdjustMyScrollbars(); - m_owner->m_dirty = TRUE; - //m_dirty = TRUE; - Refresh(); - } +void wxTreeListHeaderWindow::SetColumnWidth (int column, int width) { + wxCHECK_RET ((column >= 0) && (column < GetColumnCount()), _T("Invalid column")); + m_total_col_width -= m_columns[column].GetWidth(); + m_columns[column].SetWidth(width); + m_total_col_width += width; + m_owner->AdjustMyScrollbars(); + m_owner->m_dirty = true; } - -void wxTreeListHeaderWindow::InsertColumn(size_t before, - const wxTreeListColumnInfo& col) -{ - wxCHECK_RET(before < GetColumnCount(), wxT("Invalid column index")); - m_columns.Insert(col, before); - m_total_col_width += col.GetWidth(); - //m_dirty = TRUE; - //m_owner->GetHeaderWindow()->Refresh(); +void wxTreeListHeaderWindow::InsertColumn (int before, const wxTreeListColumnInfo& colInfo) { + wxCHECK_RET ((before >= 0) && (before < GetColumnCount()), _T("Invalid column")); + m_columns.Insert (colInfo, before); + m_total_col_width += colInfo.GetWidth(); m_owner->AdjustMyScrollbars(); - m_owner->m_dirty = TRUE; - Refresh(); + m_owner->m_dirty = true; } -void wxTreeListHeaderWindow::RemoveColumn(size_t column) -{ - wxCHECK_RET(column < GetColumnCount(), wxT("Invalid column")); +void wxTreeListHeaderWindow::RemoveColumn (int column) { + wxCHECK_RET ((column >= 0) && (column < GetColumnCount()), _T("Invalid column")); m_total_col_width -= m_columns[column].GetWidth(); - m_columns.RemoveAt(column); - //m_dirty = TRUE; + m_columns.RemoveAt (column); m_owner->AdjustMyScrollbars(); - m_owner->m_dirty = TRUE; - Refresh(); + m_owner->m_dirty = true; } -void wxTreeListHeaderWindow::SetColumn(size_t column, - const wxTreeListColumnInfo& info) -{ - wxCHECK_RET(column < GetColumnCount(), wxT("Invalid column")); - size_t w = m_columns[column].GetWidth(); +void wxTreeListHeaderWindow::SetColumn (int column, const wxTreeListColumnInfo& info) { + wxCHECK_RET ((column >= 0) && (column < GetColumnCount()), _T("Invalid column")); + int w = m_columns[column].GetWidth(); m_columns[column] = info; - //m_owner->GetHeaderWindow()->Refresh(); - //m_dirty = TRUE; - if(w != info.GetWidth()) { + if (w != info.GetWidth()) { m_total_col_width += info.GetWidth() - w; m_owner->AdjustMyScrollbars(); - m_owner->m_dirty = TRUE; } - Refresh(); + m_owner->m_dirty = true; } // --------------------------------------------------------------------------- // wxTreeListItem // --------------------------------------------------------------------------- -wxTreeListItem::wxTreeListItem(wxTreeListMainWindow *owner, - wxTreeListItem *parent, - const wxArrayString& text, - int image, int selImage, - wxTreeItemData *data) - : m_text(text) -{ +wxTreeListItem::wxTreeListItem (wxTreeListMainWindow *owner, + wxTreeListItem *parent, + const wxArrayString& text, + int image, int selImage, + wxTreeItemData *data) + : m_text (text) { + m_images[wxTreeItemIcon_Normal] = image; m_images[wxTreeItemIcon_Selected] = selImage; m_images[wxTreeItemIcon_Expanded] = NO_IMAGE; m_images[wxTreeItemIcon_SelectedExpanded] = NO_IMAGE; m_data = data; - m_x = m_y = 0; + m_x = 0; + m_y = 0; + m_text_x = 0; - m_isCollapsed = TRUE; - m_hasHilight = FALSE; - m_hasPlus = FALSE; - m_isBold = FALSE; + m_isCollapsed = true; + m_hasHilight = false; + m_hasPlus = false; + m_isBold = false; m_owner = owner; - m_parent = parent; m_attr = (wxTreeItemAttr *)NULL; - m_ownsAttr = FALSE; + m_ownsAttr = false; // We don't know the height here yet. m_width = 0; m_height = 0; } -wxTreeListItem::~wxTreeListItem() -{ +wxTreeListItem::~wxTreeListItem() { delete m_data; - if (m_ownsAttr) delete m_attr; - wxASSERT_MSG( m_children.IsEmpty(), - wxT("please call DeleteChildren() before deleting the item") ); + wxASSERT_MSG( m_children.IsEmpty(), _T("please call DeleteChildren() before destructor")); } -void wxTreeListItem::DeleteChildren(wxTreeListMainWindow *tree) -{ +void wxTreeListItem::DeleteChildren (wxTreeListMainWindow *tree) { size_t count = m_children.Count(); - for ( size_t n = 0; n < count; n++ ) - { + for (size_t n = 0; n < count; n++) { wxTreeListItem *child = m_children[n]; - if (tree) - tree->SendDeleteEvent(child); - - child->DeleteChildren(tree); + if (tree) { + tree->SendDeleteEvent (child); + if (tree->m_selectItem == child) tree->m_selectItem = (wxTreeListItem*)NULL; + } + child->DeleteChildren (tree); delete child; } - m_children.Empty(); } -void wxTreeListItem::SetText( const wxString &text ) -{ - if(m_text.GetCount() > 0) m_text[0] = text; - else { - m_text.Add(text); +void wxTreeListItem::SetText (const wxString &text) { + if (m_text.GetCount() > 0) { + m_text[0] = text; + }else{ + m_text.Add (text); } } -size_t wxTreeListItem::GetChildrenCount(bool recursively) const -{ +size_t wxTreeListItem::GetChildrenCount (bool recursively) const { size_t count = m_children.Count(); - if ( !recursively ) - return count; + if (!recursively) return count; size_t total = count; - for (size_t n = 0; n < count; ++n) - { + for (size_t n = 0; n < count; ++n) { total += m_children[n]->GetChildrenCount(); } - return total; } -void wxTreeListItem::GetSize( int &x, int &y, - const wxTreeListMainWindow *theButton ) -{ - int bottomY=m_y+theButton->GetLineHeight(this); - if ( y < bottomY ) y = bottomY; +void wxTreeListItem::GetSize (int &x, int &y, const wxTreeListMainWindow *theButton) { + int bottomY = m_y + theButton->GetLineHeight (this); + if (y < bottomY) y = bottomY; int width = m_x + m_width; if ( x < width ) x = width; - if (IsExpanded()) - { + if (IsExpanded()) { size_t count = m_children.Count(); - for ( size_t n = 0; n < count; ++n ) - { - m_children[n]->GetSize( x, y, theButton ); + for (size_t n = 0; n < count; ++n ) { + m_children[n]->GetSize (x, y, theButton); } } } -wxTreeListItem *wxTreeListItem::HitTest(const wxPoint& point, - const wxTreeListMainWindow *theCtrl, - int &flags, - int level) -{ +wxTreeListItem *wxTreeListItem::HitTest (const wxPoint& point, + const wxTreeListMainWindow *theCtrl, + int &flags, int& column, int level) { + // for a hidden root node, don't evaluate it, but do evaluate children - if (!(theCtrl->HasFlag(wxTR_HIDE_ROOT) && (level == 0))) - { - // evaluate the item - int h = theCtrl->GetLineHeight(this); - if ((point.y > m_y) && (point.y <= m_y + h)) - { + if (!theCtrl->HasFlag(wxTR_HIDE_ROOT) || (level > 0)) { + + // reset any previous hit infos + flags = 0; + column = -1; + wxTreeListHeaderWindow* header_win = theCtrl->m_owner->GetHeaderWindow(); + + // check for right of all columns (outside) + if (point.x > header_win->GetWidth()) return (wxTreeListItem*) NULL; + + // evaluate if y-pos is okay + int h = theCtrl->GetLineHeight (this); + if ((point.y >= m_y) && (point.y <= m_y + h)) { + + int maincol = theCtrl->GetMainColumn(); + // check for above/below middle int y_mid = m_y + h/2; - if (point.y < y_mid ) + if (point.y < y_mid) { flags |= wxTREE_HITTEST_ONITEMUPPERPART; - else + }else{ flags |= wxTREE_HITTEST_ONITEMLOWERPART; + } // check for button hit - int xCross = m_x; // - theCtrl->GetLineSpacing(); -#ifdef __WXMAC__ - // according to the drawing code the triangels are drawn - // at -4 , -4 from the position up to +10/+10 max - if ((point.x > xCross-4) && (point.x < xCross+10) && - (point.y > y_mid-4) && (point.y < y_mid+10) && - HasPlus() && theCtrl->HasButtons() ) -#else - // 5 is the size of the plus sign - if ((point.x > xCross-6) && (point.x < xCross+6) && - (point.y > y_mid-6) && (point.y < y_mid+6) && - HasPlus() && theCtrl->HasButtons() ) -#endif - { - flags |= wxTREE_HITTEST_ONITEMBUTTON; - return this; + if (HasPlus() && theCtrl->HasButtons()) { + int bntX = m_x - theCtrl->m_btnWidth2; + int bntY = y_mid - theCtrl->m_btnHeight2; + if ((point.x >= bntX) && (point.x <= (bntX + theCtrl->m_btnWidth)) && + (point.y >= bntY) && (point.y <= (bntY + theCtrl->m_btnHeight))) { + flags |= wxTREE_HITTEST_ONITEMBUTTON; + column = maincol; + return this; + } } // check for image hit - if (theCtrl->m_imgWidth > 0 && GetImage() != NO_IMAGE) { - int imgX = m_x - theCtrl->m_imgWidth2; - if (HasPlus() && theCtrl->HasButtons()) - imgX += theCtrl->m_btnWidth + LINEATROOT; + if (theCtrl->m_imgWidth > 0) { + int imgX = m_text_x - theCtrl->m_imgWidth - MARGIN; int imgY = y_mid - theCtrl->m_imgHeight2; if ((point.x >= imgX) && (point.x <= (imgX + theCtrl->m_imgWidth)) && (point.y >= imgY) && (point.y <= (imgY + theCtrl->m_imgHeight))) { flags |= wxTREE_HITTEST_ONITEMICON; + column = maincol; return this; } } // check for label hit - int lblX = m_x - theCtrl->m_imgWidth2 + theCtrl->m_imgWidth + MARGIN; - if ((point.x >= lblX) && (point.x <= (m_x + m_width)) && - (point.y >= m_y) && (point.y <= (m_y + h))) { + if ((point.x >= m_text_x) && (point.x <= (m_text_x + m_width))) { flags |= wxTREE_HITTEST_ONITEMLABEL; + column = maincol; return this; } - // else check for indent + // check for indent hit after button and image hit if (point.x < m_x) { flags |= wxTREE_HITTEST_ONITEMINDENT; + column = -1; // considered not belonging to main column return this; } - // else check for item right??? - if (point.x > m_x + m_width) { + // check for right of label + int end = 0; + for (int i = 0; i <= maincol; ++i) end += header_win->GetColumnWidth (i); + if ((point.x > (m_text_x + m_width)) && (point.x <= end)) { flags |= wxTREE_HITTEST_ONITEMRIGHT; + column = -1; // considered not belonging to main column return this; } + // else check for each column except main + int x = 0; + for (int j = 0; j < theCtrl->GetColumnCount(); ++j) { + if (!header_win->IsColumnShown(j)) continue; + int w = header_win->GetColumnWidth (j); + if ((j != maincol) && (point.x >= x && point.x < x+w)) { + flags |= wxTREE_HITTEST_ONITEMCOLUMN; + column = j; + return this; + } + x += w; + } + + // no special flag or column found + return this; + } - // if children are expanded, fall through to evaluate them - if (m_isCollapsed) return (wxTreeListItem*) NULL; + // if children not expanded, return no item + if (!IsExpanded()) return (wxTreeListItem*) NULL; } - // evaluate children + // in any case evaluate children + wxTreeListItem *child; size_t count = m_children.Count(); - for ( size_t n = 0; n < count; n++ ) - { - wxTreeListItem *res = m_children[n]->HitTest(point, theCtrl, - flags, level + 1); - if ( res != NULL ) - return res; + for (size_t n = 0; n < count; n++) { + child = m_children[n]->HitTest (point, theCtrl, flags, column, level+1); + if (child) return child; } + // not found return (wxTreeListItem*) NULL; } -// ALB -wxTreeListItem *wxTreeListItem::HitTest(const wxPoint& point, - const wxTreeListMainWindow *theCtrl, - int &flags, int& column, int level) -{ - column = theCtrl->GetMainColumn(); //-1; - - wxTreeListItem* res = HitTest(point, theCtrl, flags, level); - if(!res) { - column = -1; - return res; - } - - wxTreeListHeaderWindow* header_win = theCtrl->m_owner->GetHeaderWindow(); - if (point.x >= header_win->GetWidth()) - column = -1; - else if(flags & wxTREE_HITTEST_ONITEMINDENT) { - int x = 0; - for(size_t i = 0; i < theCtrl->GetMainColumn(); ++i) { - if (!header_win->GetColumnShown(i)) continue; - int w = header_win->GetColumnWidth(i); - if(point.x >= x && point.x < x+w) { - flags ^= wxTREE_HITTEST_ONITEMINDENT; - flags |= wxTREE_HITTEST_ONITEMCOLUMN; - column = i; - return res; - } - } - } - else if(flags & wxTREE_HITTEST_ONITEMRIGHT) { - int x = 0; - size_t i; - for(i = 0; i < theCtrl->GetMainColumn()+1; ++i) { - if (!header_win->GetColumnShown(i)) continue; - x += header_win->GetColumnWidth(i); - } - for(i = theCtrl->GetMainColumn()+1; i < theCtrl->GetColumnCount(); ++i) { - if (!header_win->GetColumnShown(i)) continue; - int w = header_win->GetColumnWidth(i); - if(point.x >= x && point.x < x+w) { - flags ^= wxTREE_HITTEST_ONITEMRIGHT; - flags |= wxTREE_HITTEST_ONITEMCOLUMN; - column = i; - return res; - } - x += w; - } - } - - return res; -} - - -int wxTreeListItem::GetCurrentImage() const -{ +int wxTreeListItem::GetCurrentImage() const { int image = NO_IMAGE; - if ( IsExpanded() ) - { - if ( IsSelected() ) - { - image = GetImage(wxTreeItemIcon_SelectedExpanded); + if (IsExpanded()) { + if (IsSelected()) { + image = GetImage (wxTreeItemIcon_SelectedExpanded); + }else{ + image = GetImage (wxTreeItemIcon_Expanded); } - - if ( image == NO_IMAGE ) - { - // we usually fall back to the normal item, but try just the - // expanded one (and not selected) first in this case - image = GetImage(wxTreeItemIcon_Expanded); + }else{ // not expanded + if (IsSelected()) { + image = GetImage (wxTreeItemIcon_Selected); + }else{ + image = GetImage (wxTreeItemIcon_Normal); } } - else // not expanded - { - if ( IsSelected() ) - image = GetImage(wxTreeItemIcon_Selected); - } - // maybe it doesn't have the specific image we want, - // try the default one instead - if ( image == NO_IMAGE ) image = GetImage(); + // maybe it doesn't have the specific image, try the default one instead + if (image == NO_IMAGE) image = GetImage(); return image; } @@ -1833,56 +1671,57 @@ END_EVENT_TABLE() // construction/destruction // --------------------------------------------------------------------------- -void wxTreeListMainWindow::Init() -{ - m_current = m_key_current = m_anchor = (wxTreeListItem *) NULL; - m_hasFocus = FALSE; - m_dirty = FALSE; +void wxTreeListMainWindow::Init() { + + m_rootItem = (wxTreeListItem*)NULL; + m_curItem = (wxTreeListItem*)NULL; + m_shiftItem = (wxTreeListItem*)NULL; + m_editItem = (wxTreeListItem*)NULL; + m_selectItem = (wxTreeListItem*)NULL; + + m_curColumn = -1; // no current column + + m_hasFocus = false; + m_dirty = false; m_lineHeight = LINEHEIGHT; m_indent = MININDENT; // min. indent m_linespacing = 4; - m_imgWidth = 0, m_imgWidth2 = 0; - m_imgHeight = 0, m_imgHeight2 = 0; - m_hilightBrush = new wxBrush - ( - wxSystemSettings::GetColour - ( - wxSYS_COLOUR_HIGHLIGHT - ), - wxSOLID - ); - - m_hilightUnfocusedBrush = new wxBrush - ( - wxSystemSettings::GetColour - ( - wxSYS_COLOUR_BTNSHADOW - ), - wxSOLID - ); - - m_imageListNormal = m_imageListButtons = +#if !wxCHECK_VERSION(2, 5, 0) + m_hilightBrush = new wxBrush (wxSystemSettings::GetSystemColour (wxSYS_COLOUR_HIGHLIGHT), wxSOLID); + m_hilightUnfocusedBrush = new wxBrush (wxSystemSettings::GetSystemColour (wxSYS_COLOUR_BTNSHADOW), wxSOLID); +#else + m_hilightBrush = new wxBrush (wxSystemSettings::GetColour (wxSYS_COLOUR_HIGHLIGHT), wxSOLID); + m_hilightUnfocusedBrush = new wxBrush (wxSystemSettings::GetColour (wxSYS_COLOUR_BTNSHADOW), wxSOLID); +#endif + + m_imageListNormal = (wxImageList *) NULL; + m_imageListButtons = (wxImageList *) NULL; m_imageListState = (wxImageList *) NULL; m_ownsImageListNormal = m_ownsImageListButtons = - m_ownsImageListState = FALSE; + m_ownsImageListState = false; + + m_imgWidth = 0, m_imgWidth2 = 0; + m_imgHeight = 0, m_imgHeight2 = 0; + m_btnWidth = 0, m_btnWidth2 = 0; + m_btnHeight = 0, m_btnHeight2 = 0; m_dragCount = 0; - m_isDragging = FALSE; - m_dropTarget = m_oldSelection = (wxTreeListItem *)NULL; + m_isDragging = false; + m_dragTimer = new wxTimer (this, -1); + m_dragItem = (wxTreeListItem*)NULL; - m_renameTimer = new wxTreeListRenameTimer( this ); - m_lastOnSame = FALSE; + m_renameTimer = new wxTreeListRenameTimer (this); + m_lastOnSame = false; + m_left_down_selection = false; m_findTimer = new wxTimer (this, -1); - m_underMouse = NULL; - -#ifdef __WXMAC_CARBON__ - m_normalFont.MacCreateThemeFont( kThemeViewsFont ) ; +#if defined( __WXMAC__ ) && defined(__WXMAC_CARBON__) + m_normalFont.MacCreateThemeFont (kThemeViewsFont); #else - m_normalFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ); + m_normalFont = wxSystemSettings::GetFont (wxSYS_DEFAULT_GUI_FONT); #endif m_boldFont = wxFont( m_normalFont.GetPointSize(), m_normalFont.GetFamily(), @@ -1893,39 +1732,37 @@ void wxTreeListMainWindow::Init() m_normalFont.GetEncoding()); } +bool wxTreeListMainWindow::Create (wxTreeListCtrl *parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxValidator &validator, + const wxString& name) { -bool wxTreeListMainWindow::Create(wxTreeListCtrl *parent, - wxWindowID id, - const wxPoint& pos, - const wxSize& size, - long style, - const wxValidator &validator, - const wxString& name ) -{ #ifdef __WXMAC__ - if ( !(style & wxTR_DONT_ADJUST_MAC)) - { - int major,minor; - wxGetOsVersion( &major, &minor ); - - if (style & wxTR_HAS_BUTTONS) style |= wxTR_TWIST_BUTTONS; - if (style & wxTR_HAS_BUTTONS) style &= ~wxTR_HAS_BUTTONS; - style &= ~wxTR_LINES_AT_ROOT; - style |= wxTR_NO_LINES; - if (major < 10) - style |= wxTR_ROW_LINES; - } + if (style & wxTR_HAS_BUTTONS) style |= wxTR_MAC_BUTTONS; + if (style & wxTR_HAS_BUTTONS) style &= ~wxTR_HAS_BUTTONS; + style &= ~wxTR_LINES_AT_ROOT; + style |= wxTR_NO_LINES; + + int major,minor; + wxGetOsVersion( &major, &minor ); + if (major < 10) style |= wxTR_ROW_LINES; #endif - - wxScrolledWindow::Create( parent, id, pos, size, - style|wxHSCROLL|wxVSCROLL, name ); + + wxScrolledWindow::Create (parent, id, pos, size, style|wxHSCROLL|wxVSCROLL, name); #if wxUSE_VALIDATORS - SetValidator( validator ); + SetValidator(validator); +#endif + +#if !wxCHECK_VERSION(2, 5, 0) + SetBackgroundColour (wxSystemSettings::GetSystemColour (wxSYS_COLOUR_LISTBOX)); +#else + SetBackgroundColour (wxSystemSettings::GetColour (wxSYS_COLOUR_LISTBOX)); #endif - SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOX ) ); - #ifdef __WXMSW__ { int i, j; @@ -1945,213 +1782,170 @@ bool wxTreeListMainWindow::Create(wxTreeListCtrl *parent, m_dottedPen = wxPen(bmp, 1); } #else - //m_dottedPen = wxPen( *wxGREY_PEN, 1, wxDOT ); // too slow under XFree86 - m_dottedPen = wxPen( wxT("grey"), 0, 0 ); // Bitmap based pen is not supported by GTK! +//? m_dottedPen = wxPen( *wxGREY_PEN, 1, wxDOT ); // too slow under XFree86 + m_dottedPen = wxPen( _T("grey"), 0, 0 ); // Bitmap based pen is not supported by GTK! #endif - // ALB m_owner = parent; m_main_column = 0; - return TRUE; + return true; } -wxTreeListMainWindow::~wxTreeListMainWindow() -{ +wxTreeListMainWindow::~wxTreeListMainWindow() { delete m_hilightBrush; delete m_hilightUnfocusedBrush; - DeleteAllItems(); - + delete m_dragTimer; delete m_renameTimer; delete m_findTimer; if (m_ownsImageListNormal) delete m_imageListNormal; if (m_ownsImageListState) delete m_imageListState; if (m_ownsImageListButtons) delete m_imageListButtons; -} + DeleteRoot(); +} //----------------------------------------------------------------------------- // accessors //----------------------------------------------------------------------------- -size_t wxTreeListMainWindow::GetCount() const -{ - return m_anchor == NULL ? 0u : m_anchor->GetChildrenCount(); +size_t wxTreeListMainWindow::GetCount() const { + return m_rootItem == NULL? 0: m_rootItem->GetChildrenCount(); } -void wxTreeListMainWindow::SetIndent(unsigned int indent) -{ - m_indent = indent; - m_dirty = TRUE; +void wxTreeListMainWindow::SetIndent (unsigned int indent) { + m_indent = wxMax ((unsigned)MININDENT, indent); + m_dirty = true; } -void wxTreeListMainWindow::SetLineSpacing(unsigned int spacing) -{ +void wxTreeListMainWindow::SetLineSpacing (unsigned int spacing) { m_linespacing = spacing; - m_dirty = TRUE; + m_dirty = true; CalculateLineHeight(); } -size_t wxTreeListMainWindow::GetChildrenCount(const wxTreeItemId& item, - bool recursively) -{ - wxCHECK_MSG( item.IsOk(), 0u, wxT("invalid tree item") ); - - return ((wxTreeListItem*) item.m_pItem)->GetChildrenCount(recursively); +size_t wxTreeListMainWindow::GetChildrenCount (const wxTreeItemId& item, + bool recursively) { + wxCHECK_MSG (item.IsOk(), 0u, _T("invalid tree item")); + return ((wxTreeListItem*)item.m_pItem)->GetChildrenCount (recursively); } -void wxTreeListMainWindow::SetWindowStyle(const long styles) -{ +void wxTreeListMainWindow::SetWindowStyle (const long styles) { // right now, just sets the styles. Eventually, we may // want to update the inherited styles, but right now // none of the parents has updatable styles m_windowStyle = styles; - m_dirty = TRUE; + m_dirty = true; } //----------------------------------------------------------------------------- // functions to work with tree items //----------------------------------------------------------------------------- -int wxTreeListMainWindow::GetItemImage(const wxTreeItemId& item, size_t column, - wxTreeItemIcon which) const -{ - wxCHECK_MSG( item.IsOk(), -1, wxT("invalid tree item") ); - - return ((wxTreeListItem*) item.m_pItem)->GetImage(column, which); +int wxTreeListMainWindow::GetItemImage (const wxTreeItemId& item, int column, + wxTreeItemIcon which) const { + wxCHECK_MSG (item.IsOk(), -1, _T("invalid tree item")); + return ((wxTreeListItem*) item.m_pItem)->GetImage (column, which); } -wxTreeItemData *wxTreeListMainWindow::GetItemData(const wxTreeItemId& item) - const -{ - wxCHECK_MSG( item.IsOk(), NULL, wxT("invalid tree item") ); - +wxTreeItemData *wxTreeListMainWindow::GetItemData (const wxTreeItemId& item) const { + wxCHECK_MSG (item.IsOk(), NULL, _T("invalid tree item")); return ((wxTreeListItem*) item.m_pItem)->GetData(); } -bool wxTreeListMainWindow::GetItemBold(const wxTreeItemId& item) const -{ - wxCHECK_MSG(item.IsOk(), FALSE, wxT("invalid tree item")); +bool wxTreeListMainWindow::GetItemBold (const wxTreeItemId& item) const { + wxCHECK_MSG(item.IsOk(), false, _T("invalid tree item")); return ((wxTreeListItem *)item.m_pItem)->IsBold(); } -wxColour wxTreeListMainWindow::GetItemTextColour(const wxTreeItemId& item) - const -{ - wxCHECK_MSG( item.IsOk(), wxNullColour, wxT("invalid tree item") ); - +wxColour wxTreeListMainWindow::GetItemTextColour (const wxTreeItemId& item) const { + wxCHECK_MSG (item.IsOk(), wxNullColour, _T("invalid tree item")); wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem; return pItem->Attr().GetTextColour(); } -wxColour wxTreeListMainWindow::GetItemBackgroundColour( - const wxTreeItemId& item) const -{ - wxCHECK_MSG( item.IsOk(), wxNullColour, wxT("invalid tree item") ); - +wxColour wxTreeListMainWindow::GetItemBackgroundColour (const wxTreeItemId& item) const { + wxCHECK_MSG (item.IsOk(), wxNullColour, _T("invalid tree item")); wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem; return pItem->Attr().GetBackgroundColour(); } -wxFont wxTreeListMainWindow::GetItemFont(const wxTreeItemId& item) const -{ - wxCHECK_MSG( item.IsOk(), wxNullFont, wxT("invalid tree item") ); - +wxFont wxTreeListMainWindow::GetItemFont (const wxTreeItemId& item) const { + wxCHECK_MSG (item.IsOk(), wxNullFont, _T("invalid tree item")); wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem; return pItem->Attr().GetFont(); } - - -void wxTreeListMainWindow::SetItemImage(const wxTreeItemId& item, - size_t column, - int image, wxTreeItemIcon which) -{ - wxCHECK_RET( item.IsOk(), wxT("invalid tree item") ); - +void wxTreeListMainWindow::SetItemImage (const wxTreeItemId& item, int column, + int image, wxTreeItemIcon which) { + wxCHECK_RET (item.IsOk(), _T("invalid tree item")); wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem; - pItem->SetImage(column, image, which); - - wxClientDC dc(this); - CalculateSize(pItem, dc); - RefreshLine(pItem); + pItem->SetImage (column, image, which); + wxClientDC dc (this); + CalculateSize (pItem, dc); + RefreshLine (pItem); } -void wxTreeListMainWindow::SetItemData(const wxTreeItemId& item, - wxTreeItemData *data) -{ - wxCHECK_RET( item.IsOk(), wxT("invalid tree item") ); - +void wxTreeListMainWindow::SetItemData (const wxTreeItemId& item, + wxTreeItemData *data) { + wxCHECK_RET (item.IsOk(), _T("invalid tree item")); ((wxTreeListItem*) item.m_pItem)->SetData(data); } -void wxTreeListMainWindow::SetItemHasChildren(const wxTreeItemId& item, - bool has) -{ - wxCHECK_RET( item.IsOk(), wxT("invalid tree item") ); - +void wxTreeListMainWindow::SetItemHasChildren (const wxTreeItemId& item, + bool has) { + wxCHECK_RET (item.IsOk(), _T("invalid tree item")); wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem; - pItem->SetHasPlus(has); - RefreshLine(pItem); + pItem->SetHasPlus (has); + RefreshLine (pItem); } -void wxTreeListMainWindow::SetItemBold(const wxTreeItemId& item, bool bold) -{ - wxCHECK_RET( item.IsOk(), wxT("invalid tree item") ); - - // avoid redrawing the tree if no real change +void wxTreeListMainWindow::SetItemBold (const wxTreeItemId& item, bool bold) { + wxCHECK_RET (item.IsOk(), _T("invalid tree item")); wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem; - if ( pItem->IsBold() != bold ) - { - pItem->SetBold(bold); - RefreshLine(pItem); + if (pItem->IsBold() != bold) { // avoid redrawing if no real change + pItem->SetBold (bold); + RefreshLine (pItem); } } -void wxTreeListMainWindow::SetItemTextColour(const wxTreeItemId& item, - const wxColour& col) -{ - wxCHECK_RET( item.IsOk(), wxT("invalid tree item") ); - +void wxTreeListMainWindow::SetItemTextColour (const wxTreeItemId& item, + const wxColour& colour) { + wxCHECK_RET (item.IsOk(), _T("invalid tree item")); wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem; - pItem->Attr().SetTextColour(col); - RefreshLine(pItem); + pItem->Attr().SetTextColour (colour); + RefreshLine (pItem); } -void wxTreeListMainWindow::SetItemBackgroundColour(const wxTreeItemId& item, - const wxColour& col) -{ - wxCHECK_RET( item.IsOk(), wxT("invalid tree item") ); - +void wxTreeListMainWindow::SetItemBackgroundColour (const wxTreeItemId& item, + const wxColour& colour) { + wxCHECK_RET (item.IsOk(), _T("invalid tree item")); wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem; - pItem->Attr().SetBackgroundColour(col); - RefreshLine(pItem); + pItem->Attr().SetBackgroundColour (colour); + RefreshLine (pItem); } -void wxTreeListMainWindow::SetItemFont(const wxTreeItemId& item, - const wxFont& font) -{ - wxCHECK_RET( item.IsOk(), wxT("invalid tree item") ); - +void wxTreeListMainWindow::SetItemFont (const wxTreeItemId& item, + const wxFont& font) { + wxCHECK_RET (item.IsOk(), _T("invalid tree item")); wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem; - pItem->Attr().SetFont(font); - RefreshLine(pItem); + pItem->Attr().SetFont (font); + RefreshLine (pItem); } -bool wxTreeListMainWindow::SetFont( const wxFont &font ) -{ - wxScrolledWindow::SetFont(font); - - m_normalFont = font ; - m_boldFont = wxFont( m_normalFont.GetPointSize(), - m_normalFont.GetFamily(), - m_normalFont.GetStyle(), - wxBOLD, - m_normalFont.GetUnderlined()); - - return TRUE; +bool wxTreeListMainWindow::SetFont (const wxFont &font) { + wxScrolledWindow::SetFont (font); + m_normalFont = font; + m_boldFont = wxFont (m_normalFont.GetPointSize(), + m_normalFont.GetFamily(), + m_normalFont.GetStyle(), + wxBOLD, + m_normalFont.GetUnderlined(), + m_normalFont.GetFaceName()); + CalculateLineHeight(); + return true; } @@ -2159,41 +1953,30 @@ bool wxTreeListMainWindow::SetFont( const wxFont &font ) // item status inquiries // ---------------------------------------------------------------------------- -bool wxTreeListMainWindow::IsVisible(const wxTreeItemId& item) const -{ - wxCHECK_MSG( item.IsOk(), FALSE, wxT("invalid tree item") ); +bool wxTreeListMainWindow::IsVisible (const wxTreeItemId& item, bool fullRow) const { + wxCHECK_MSG (item.IsOk(), false, _T("invalid tree item")); // An item is only visible if it's not a descendant of a collapsed item wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem; wxTreeListItem* parent = pItem->GetItemParent(); - while (parent) - { - if (!parent->IsExpanded()) - return FALSE; + while (parent) { + if (parent == m_rootItem && HasFlag(wxTR_HIDE_ROOT)) break; + if (!parent->IsExpanded()) return false; parent = parent->GetItemParent(); } - int startX, startY; - GetViewStart(& startX, & startY); - wxSize clientSize = GetClientSize(); - wxRect rect; - if (!GetBoundingRect(item, rect)) - return FALSE; - if (rect.GetWidth() == 0 || rect.GetHeight() == 0) - return FALSE; - if (rect.GetBottom() < 0 || rect.GetTop() > clientSize.y) - return FALSE; - if (rect.GetRight() < 0 || rect.GetLeft() > clientSize.x) - return FALSE; + if ((!GetBoundingRect (item, rect)) || + ((!fullRow && rect.GetWidth() == 0) || rect.GetHeight() == 0) || + (rect.GetBottom() < 0 || rect.GetTop() > clientSize.y) || + (!fullRow && (rect.GetRight() < 0 || rect.GetLeft() > clientSize.x))) return false; - return TRUE; + return true; } -bool wxTreeListMainWindow::ItemHasChildren(const wxTreeItemId& item) const -{ - wxCHECK_MSG( item.IsOk(), FALSE, wxT("invalid tree item") ); +bool wxTreeListMainWindow::HasChildren (const wxTreeItemId& item) const { + wxCHECK_MSG (item.IsOk(), false, _T("invalid tree item")); // consider that the item does have children if it has the "+" button: it // might not have them (if it had never been expanded yet) but then it @@ -2203,24 +1986,18 @@ bool wxTreeListMainWindow::ItemHasChildren(const wxTreeItemId& item) const return ((wxTreeListItem*) item.m_pItem)->HasPlus(); } -bool wxTreeListMainWindow::IsExpanded(const wxTreeItemId& item) const -{ - wxCHECK_MSG( item.IsOk(), FALSE, wxT("invalid tree item") ); - +bool wxTreeListMainWindow::IsExpanded (const wxTreeItemId& item) const { + wxCHECK_MSG (item.IsOk(), false, _T("invalid tree item")); return ((wxTreeListItem*) item.m_pItem)->IsExpanded(); } -bool wxTreeListMainWindow::IsSelected(const wxTreeItemId& item) const -{ - wxCHECK_MSG( item.IsOk(), FALSE, wxT("invalid tree item") ); - +bool wxTreeListMainWindow::IsSelected (const wxTreeItemId& item) const { + wxCHECK_MSG (item.IsOk(), false, _T("invalid tree item")); return ((wxTreeListItem*) item.m_pItem)->IsSelected(); } -bool wxTreeListMainWindow::IsBold(const wxTreeItemId& item) const -{ - wxCHECK_MSG( item.IsOk(), FALSE, wxT("invalid tree item") ); - +bool wxTreeListMainWindow::IsBold (const wxTreeItemId& item) const { + wxCHECK_MSG (item.IsOk(), false, _T("invalid tree item")); return ((wxTreeListItem*) item.m_pItem)->IsBold(); } @@ -2228,195 +2005,172 @@ bool wxTreeListMainWindow::IsBold(const wxTreeItemId& item) const // navigation // ---------------------------------------------------------------------------- -wxTreeItemId wxTreeListMainWindow::GetItemParent(const wxTreeItemId& item) const -{ - wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") ); - +wxTreeItemId wxTreeListMainWindow::GetItemParent (const wxTreeItemId& item) const { + wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); return ((wxTreeListItem*) item.m_pItem)->GetItemParent(); } #if !wxCHECK_VERSION(2, 5, 0) -wxTreeItemId wxTreeListMainWindow::GetFirstChild(const wxTreeItemId& item, - long& cookie) const +wxTreeItemId wxTreeListMainWindow::GetFirstChild (const wxTreeItemId& item, + long& cookie) const { #else -wxTreeItemId wxTreeListMainWindow::GetFirstChild(const wxTreeItemId& item, - wxTreeItemIdValue& cookie) const +wxTreeItemId wxTreeListMainWindow::GetFirstChild (const wxTreeItemId& item, + wxTreeItemIdValue& cookie) const { #endif -{ - wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") ); - + wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); + wxArrayTreeListItems& children = ((wxTreeListItem*) item.m_pItem)->GetChildren(); cookie = 0; - return GetNextChild(item, cookie); + return (!children.IsEmpty())? wxTreeItemId(children.Item(0)): wxTreeItemId(); } #if !wxCHECK_VERSION(2, 5, 0) -wxTreeItemId wxTreeListMainWindow::GetNextChild(const wxTreeItemId& item, - long& cookie) const +wxTreeItemId wxTreeListMainWindow::GetNextChild (const wxTreeItemId& item, + long& cookie) const { #else -wxTreeItemId wxTreeListMainWindow::GetNextChild(const wxTreeItemId& item, - wxTreeItemIdValue& cookie) const +wxTreeItemId wxTreeListMainWindow::GetNextChild (const wxTreeItemId& item, + wxTreeItemIdValue& cookie) const { #endif -{ - wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") ); - + wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); wxArrayTreeListItems& children = ((wxTreeListItem*) item.m_pItem)->GetChildren(); - - // it's ok to cast cookie to size_t, we never have indices big enough to - // overflow "void *" - size_t *pIndex = (size_t *)&cookie; - if ( *pIndex < children.Count() ) - { - return children.Item((*pIndex)++); - } - else - { - // there are no more of them - return wxTreeItemId(); - } + // it's ok to cast cookie to long, we never have indices which overflow "void*" + long *pIndex = ((long*)&cookie); + return ((*pIndex)+1 < (long)children.Count())? wxTreeItemId(children.Item(++(*pIndex))): wxTreeItemId(); } #if !wxCHECK_VERSION(2, 5, 0) -wxTreeItemId wxTreeListMainWindow::GetPrevChild(const wxTreeItemId& item, - long& cookie) const +wxTreeItemId wxTreeListMainWindow::GetPrevChild (const wxTreeItemId& item, + long& cookie) const { #else -wxTreeItemId wxTreeListMainWindow::GetPrevChild(const wxTreeItemId& item, - wxTreeItemIdValue& cookie) const +wxTreeItemId wxTreeListMainWindow::GetPrevChild (const wxTreeItemId& item, + wxTreeItemIdValue& cookie) const { #endif -{ - wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") ); - + wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); wxArrayTreeListItems& children = ((wxTreeListItem*) item.m_pItem)->GetChildren(); - - // it's ok to cast cookie to size_t, we never have indices big enough to - // overflow "void *" - size_t *pIndex = (size_t *)&cookie; - if ( *pIndex > 0 ) - { - return children.Item(--(*pIndex)); - } - else - { - // there are no more of them - return wxTreeItemId(); - } + // it's ok to cast cookie to long, we never have indices which overflow "void*" + long *pIndex = (long*)&cookie; + return ((*pIndex)-1 >= 0)? wxTreeItemId(children.Item(--(*pIndex))): wxTreeItemId(); } -wxTreeItemId wxTreeListMainWindow::GetLastChild(const wxTreeItemId& item) const -{ - wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") ); - +#if !wxCHECK_VERSION(2, 5, 0) +wxTreeItemId wxTreeListMainWindow::GetLastChild (const wxTreeItemId& item, + long& cookie) const { +#else +wxTreeItemId wxTreeListMainWindow::GetLastChild (const wxTreeItemId& item, + wxTreeItemIdValue& cookie) const { +#endif + wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); wxArrayTreeListItems& children = ((wxTreeListItem*) item.m_pItem)->GetChildren(); - return (children.IsEmpty() ? wxTreeItemId() : wxTreeItemId(children.Last())); + // it's ok to cast cookie to long, we never have indices which overflow "void*" + long *pIndex = ((long*)&cookie); + (*pIndex) = children.Count(); + return (!children.IsEmpty())? wxTreeItemId(children.Last()): wxTreeItemId(); } -wxTreeItemId wxTreeListMainWindow::GetNextSibling(const wxTreeItemId& item) const -{ - wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") ); +wxTreeItemId wxTreeListMainWindow::GetNextSibling (const wxTreeItemId& item) const { + wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); + // get parent wxTreeListItem *i = (wxTreeListItem*) item.m_pItem; wxTreeListItem *parent = i->GetItemParent(); - if ( parent == NULL ) - { - // root item doesn't have any siblings - return wxTreeItemId(); - } + if (!parent) return wxTreeItemId(); // root item doesn't have any siblings + // get index wxArrayTreeListItems& siblings = parent->GetChildren(); - int index = siblings.Index(i); - wxASSERT( index != wxNOT_FOUND ); // I'm not a child of my parent? - - size_t n = (size_t)(index + 1); - return n == siblings.Count() ? wxTreeItemId() : wxTreeItemId(siblings[n]); + size_t index = siblings.Index (i); + wxASSERT (index != (size_t)wxNOT_FOUND); // I'm not a child of my parent? + return (index < siblings.Count()-1)? wxTreeItemId(siblings[index+1]): wxTreeItemId(); } -wxTreeItemId wxTreeListMainWindow::GetPrevSibling(const wxTreeItemId& item) - const -{ - wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") ); +wxTreeItemId wxTreeListMainWindow::GetPrevSibling (const wxTreeItemId& item) const { + wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); + // get parent wxTreeListItem *i = (wxTreeListItem*) item.m_pItem; wxTreeListItem *parent = i->GetItemParent(); - if ( parent == NULL ) - { - // root item doesn't have any siblings - return wxTreeItemId(); - } + if (!parent) return wxTreeItemId(); // root item doesn't have any siblings + // get index wxArrayTreeListItems& siblings = parent->GetChildren(); - int index = siblings.Index(i); - wxASSERT( index != wxNOT_FOUND ); // I'm not a child of my parent? - - return index == 0 ? wxTreeItemId() - : wxTreeItemId(siblings[(size_t)(index - 1)]); + size_t index = siblings.Index(i); + wxASSERT (index != (size_t)wxNOT_FOUND); // I'm not a child of my parent? + return (index >= 1)? wxTreeItemId(siblings[index-1]): wxTreeItemId(); } // Only for internal use right now, but should probably be public -wxTreeItemId wxTreeListMainWindow::GetNext(const wxTreeItemId& item) const -{ - wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") ); - - wxTreeListItem *i = (wxTreeListItem*) item.m_pItem; +wxTreeItemId wxTreeListMainWindow::GetNext (const wxTreeItemId& item, bool fulltree) const { + wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); - // First see if there are any children. - wxArrayTreeListItems& children = i->GetChildren(); - if (children.GetCount() > 0) - { - return children.Item(0); + // if there are any children, return first child + if (fulltree || ((wxTreeListItem*)item.m_pItem)->IsExpanded()) { + wxArrayTreeListItems& children = ((wxTreeListItem*)item.m_pItem)->GetChildren(); + if (children.GetCount() > 0) return children.Item (0); } - else - { - // Try a sibling of this or ancestor instead - wxTreeItemId p = item; - wxTreeItemId toFind; - do - { - toFind = GetNextSibling(p); - p = GetItemParent(p); - } while (p.IsOk() && !toFind.IsOk()); - return toFind; + + // get sibling of this item or of the ancestors instead + wxTreeItemId next; + wxTreeItemId parent = item; + do { + next = GetNextSibling (parent); + parent = GetItemParent (parent); + } while (!next.IsOk() && parent.IsOk()); + return next; +} + +// Only for internal use right now, but should probably be public +wxTreeItemId wxTreeListMainWindow::GetPrev (const wxTreeItemId& item, bool fulltree) const { + wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); + + // if there are any children, return last child + if (fulltree || ((wxTreeListItem*)item.m_pItem)->IsExpanded()) { + wxArrayTreeListItems& children = ((wxTreeListItem*)item.m_pItem)->GetChildren(); + if (children.GetCount() > 0) return children.Item (children.GetCount()-1); } + + // get sibling of this item or of the ancestors instead + wxTreeItemId next; + wxTreeItemId parent = item; + do { + next = GetPrevSibling (parent); + parent = GetItemParent (parent); + } while (!next.IsOk() && parent.IsOk()); + return next; } -wxTreeItemId wxTreeListMainWindow::GetFirstVisibleItem() const -{ - wxTreeItemId id = GetRootItem(); - if (!id.IsOk()) - return id; +wxTreeItemId wxTreeListMainWindow::GetFirstExpandedItem() const { + return GetNextExpanded (GetRootItem()); +} - do - { - if (IsVisible(id)) - return id; - id = GetNext(id); - } while (id.IsOk()); +wxTreeItemId wxTreeListMainWindow::GetNextExpanded (const wxTreeItemId& item) const { + wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); + return GetNext (item, false); +} - return wxTreeItemId(); +wxTreeItemId wxTreeListMainWindow::GetPrevExpanded (const wxTreeItemId& item) const { + wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); + return GetPrev (item, false); } -wxTreeItemId wxTreeListMainWindow::GetNextVisible(const wxTreeItemId& item) - const -{ - wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") ); +wxTreeItemId wxTreeListMainWindow::GetFirstVisibleItem (bool fullRow) const { + return GetNextVisible (GetRootItem(), fullRow); +} - wxTreeItemId id = item; - if (id.IsOk()) - { - while (id = GetNext(id), id.IsOk()) - { - if (IsVisible(id)) - return id; - } +wxTreeItemId wxTreeListMainWindow::GetNextVisible (const wxTreeItemId& item, bool fullRow) const { + wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); + wxTreeItemId id = GetNext (item, false); + while (id.IsOk()) { + if (IsVisible (id, fullRow)) return id; + id = GetNext (id, false); } return wxTreeItemId(); } -wxTreeItemId wxTreeListMainWindow::GetPrevVisible(const wxTreeItemId& item) - const -{ - wxCHECK_MSG( item.IsOk(), wxTreeItemId(), wxT("invalid tree item") ); - - wxFAIL_MSG(wxT("not implemented")); - +wxTreeItemId wxTreeListMainWindow::GetPrevVisible (const wxTreeItemId& item, bool fullRow) const { + wxCHECK_MSG (item.IsOk(), wxTreeItemId(), _T("invalid tree item")); + wxTreeItemId id = GetPrev (item, true); + while (id.IsOk()) { + if (IsVisible (id, fullRow)) return id; + id = GetPrev(id, true); + } return wxTreeItemId(); } @@ -2424,342 +2178,268 @@ wxTreeItemId wxTreeListMainWindow::GetPrevVisible(const wxTreeItemId& item) // operations // ---------------------------------------------------------------------------- -wxTreeItemId wxTreeListMainWindow::DoInsertItem(const wxTreeItemId& parentId, - size_t previous, - const wxString& text, - int image, int selImage, - wxTreeItemData *data) -{ - wxTreeListItem *parent = (wxTreeListItem*) parentId.m_pItem; - if ( !parent ) - { - // should we give a warning here? - return AddRoot(text, image, selImage, data); - } - - m_dirty = TRUE; // do this first so stuff below doesn't cause flicker +wxTreeItemId wxTreeListMainWindow::DoInsertItem (const wxTreeItemId& parentId, + size_t previous, + const wxString& text, + int image, int selImage, + wxTreeItemData *data) { + wxTreeListItem *parent = (wxTreeListItem*)parentId.m_pItem; + wxCHECK_MSG (parent, wxTreeItemId(), _T("item must have a parent, at least root!") ); + m_dirty = true; // do this first so stuff below doesn't cause flicker - // ALB wxArrayString arr; - arr.Alloc(GetColumnCount()); - for(size_t i = 0; i < GetColumnCount(); ++i) { - arr.Add(wxEmptyString); - } + arr.Alloc (GetColumnCount()); + for (int i = 0; i < (int)GetColumnCount(); ++i) arr.Add (wxEmptyString); arr[m_main_column] = text; - wxTreeListItem *item = - new wxTreeListItem( this, parent, arr, image, selImage, data ); - - if ( data != NULL ) - { - data->SetId((void*)item); + wxTreeListItem *item = new wxTreeListItem (this, parent, arr, image, selImage, data); + if (data != NULL) { +#if !wxCHECK_VERSION(2, 5, 0) + data->SetId ((long)item); +#else + data->SetId (item); +#endif } - - parent->Insert( item, previous ); + parent->Insert (item, previous); return item; } -wxTreeItemId wxTreeListMainWindow::AddRoot(const wxString& text, - int image, int selImage, - wxTreeItemData *data) -{ - wxCHECK_MSG(!m_anchor, wxTreeItemId(), wxT("tree can have only one root")); - wxCHECK_MSG(GetColumnCount(), wxTreeItemId(), wxT("Add column(s) before adding the root item")); - - m_dirty = TRUE; // do this first so stuff below doesn't cause flicker +wxTreeItemId wxTreeListMainWindow::AddRoot (const wxString& text, + int image, int selImage, + wxTreeItemData *data) { + wxCHECK_MSG(!m_rootItem, wxTreeItemId(), _T("tree can have only one root")); + wxCHECK_MSG(GetColumnCount(), wxTreeItemId(), _T("Add column(s) before adding the root item")); + m_dirty = true; // do this first so stuff below doesn't cause flicker - // ALB wxArrayString arr; - arr.Alloc(GetColumnCount()); - for(size_t i = 0; i < GetColumnCount(); ++i) { - arr.Add(wxEmptyString); - } + arr.Alloc (GetColumnCount()); + for (int i = 0; i < (int)GetColumnCount(); ++i) arr.Add (wxEmptyString); arr[m_main_column] = text; - m_anchor = new wxTreeListItem( this, (wxTreeListItem *)NULL, arr, - image, selImage, data); -#if 0 - if (HasFlag(wxTR_HIDE_ROOT)) - { - // if root is hidden, make sure we can navigate - // into children - m_anchor->SetHasPlus(); - Expand(m_anchor); - } + m_rootItem = new wxTreeListItem (this, (wxTreeListItem *)NULL, arr, image, selImage, data); + if (data != NULL) { +#if !wxCHECK_VERSION(2, 5, 0) + data->SetId((long)m_rootItem); +#else + data->SetId(m_rootItem); #endif - if ( data != NULL ) - { - data->SetId((void*)m_anchor); } - - if (!HasFlag(wxTR_MULTIPLE)) - { - m_current = m_key_current = m_anchor; - m_current->SetHilight( TRUE ); + if (HasFlag(wxTR_HIDE_ROOT)) { + // if we will hide the root, make sure children are visible + m_rootItem->SetHasPlus(); + m_rootItem->Expand(); +#if !wxCHECK_VERSION(2, 5, 0) + long cookie = 0; +#else + wxTreeItemIdValue cookie = 0; +#endif + m_curItem = (wxTreeListItem*)GetFirstChild (m_rootItem, cookie).m_pItem; } - - return m_anchor; + return m_rootItem; } -wxTreeItemId wxTreeListMainWindow::PrependItem(const wxTreeItemId& parent, - const wxString& text, - int image, int selImage, - wxTreeItemData *data) -{ - return DoInsertItem(parent, 0u, text, image, selImage, data); +wxTreeItemId wxTreeListMainWindow::PrependItem (const wxTreeItemId& parent, + const wxString& text, + int image, int selImage, + wxTreeItemData *data) { + return DoInsertItem (parent, 0u, text, image, selImage, data); } -wxTreeItemId wxTreeListMainWindow::InsertItem(const wxTreeItemId& parentId, - const wxTreeItemId& idPrevious, - const wxString& text, - int image, int selImage, - wxTreeItemData *data) -{ - wxTreeListItem *parent = (wxTreeListItem*) parentId.m_pItem; - if ( !parent ) - { - // should we give a warning here? - return AddRoot(text, image, selImage, data); - } +wxTreeItemId wxTreeListMainWindow::InsertItem (const wxTreeItemId& parentId, + const wxTreeItemId& idPrevious, + const wxString& text, + int image, int selImage, + wxTreeItemData *data) { + wxTreeListItem *parent = (wxTreeListItem*)parentId.m_pItem; + wxCHECK_MSG (parent, wxTreeItemId(), _T("item must have a parent, at least root!") ); int index = parent->GetChildren().Index((wxTreeListItem*) idPrevious.m_pItem); wxASSERT_MSG( index != wxNOT_FOUND, - wxT("previous item in wxTreeListMainWindow::InsertItem() is not a sibling") ); + _T("previous item in wxTreeListMainWindow::InsertItem() is not a sibling") ); - return DoInsertItem(parentId, (size_t)++index, text, image, selImage, data); + return DoInsertItem (parentId, ++index, text, image, selImage, data); } -wxTreeItemId wxTreeListMainWindow::InsertItem(const wxTreeItemId& parentId, - size_t before, - const wxString& text, - int image, int selImage, - wxTreeItemData *data) -{ - wxTreeListItem *parent = (wxTreeListItem*) parentId.m_pItem; - if ( !parent ) - { - // should we give a warning here? - return AddRoot(text, image, selImage, data); - } +wxTreeItemId wxTreeListMainWindow::InsertItem (const wxTreeItemId& parentId, + size_t before, + const wxString& text, + int image, int selImage, + wxTreeItemData *data) { + wxTreeListItem *parent = (wxTreeListItem*)parentId.m_pItem; + wxCHECK_MSG (parent, wxTreeItemId(), _T("item must have a parent, at least root!") ); - return DoInsertItem(parentId, before, text, image, selImage, data); + return DoInsertItem (parentId, before, text, image, selImage, data); } -wxTreeItemId wxTreeListMainWindow::AppendItem(const wxTreeItemId& parentId, - const wxString& text, - int image, int selImage, - wxTreeItemData *data) -{ +wxTreeItemId wxTreeListMainWindow::AppendItem (const wxTreeItemId& parentId, + const wxString& text, + int image, int selImage, + wxTreeItemData *data) { wxTreeListItem *parent = (wxTreeListItem*) parentId.m_pItem; - if ( !parent ) - { - // should we give a warning here? - return AddRoot(text, image, selImage, data); - } - - return DoInsertItem( parent, parent->GetChildren().Count(), text, - image, selImage, data); -} + wxCHECK_MSG (parent, wxTreeItemId(), _T("item must have a parent, at least root!") ); -void wxTreeListMainWindow::SendDeleteEvent(wxTreeListItem *item) -{ - wxTreeEvent event( wxEVT_COMMAND_TREE_DELETE_ITEM, m_owner->GetId() ); - event.SetItem((void*)item); - event.SetEventObject( /*this*/m_owner ); - m_owner->ProcessEvent( event ); + return DoInsertItem (parent, parent->GetChildren().Count(), text, image, selImage, data); } -void wxTreeListMainWindow::DeleteChildren(const wxTreeItemId& itemId) -{ - m_dirty = TRUE; // do this first so stuff below doesn't cause flicker - - wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem; - item->DeleteChildren(this); +void wxTreeListMainWindow::SendDeleteEvent (wxTreeListItem *item) { + // send event to user code + wxTreeEvent event (wxEVT_COMMAND_TREE_DELETE_ITEM, m_owner->GetId()); +#if !wxCHECK_VERSION(2, 5, 0) + event.SetItem ((long)item); +#else + event.SetItem (item); +#endif + event.SetEventObject (m_owner); + m_owner->ProcessEvent (event); } -void wxTreeListMainWindow::Delete(const wxTreeItemId& itemId) -{ - m_dirty = TRUE; // do this first so stuff below doesn't cause flicker - +void wxTreeListMainWindow::Delete (const wxTreeItemId& itemId) { wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem; - - // don't stay with invalid m_key_current or we will crash in - // the next call to OnChar() - bool changeKeyCurrent = FALSE; - wxTreeListItem *itemKey = m_key_current; - while ( itemKey ) - { - if ( itemKey == item ) - { - // m_key_current is a descendant of the item being deleted - changeKeyCurrent = TRUE; + wxCHECK_RET (item != m_rootItem, _T("invalid item, root may not be deleted this way!")); + m_dirty = true; // do this first so stuff below doesn't cause flicker + + // don't stay with invalid m_shiftItem or we will crash in the next call to OnChar() + bool changeKeyCurrent = false; + wxTreeListItem *itemKey = m_shiftItem; + while (itemKey) { + if (itemKey == item) { // m_shiftItem is a descendant of the item being deleted + changeKeyCurrent = true; break; } itemKey = itemKey->GetItemParent(); } wxTreeListItem *parent = item->GetItemParent(); - if ( parent ) - { - parent->GetChildren().Remove( item ); // remove by value - } - - if ( changeKeyCurrent ) - { - // may be NULL or not - m_key_current = parent; + if (parent) { + parent->GetChildren().Remove (item); // remove by value } + if (changeKeyCurrent) m_shiftItem = parent; - item->DeleteChildren(this); - SendDeleteEvent(item); + SendDeleteEvent (item); + if (m_selectItem == item) m_selectItem = (wxTreeListItem*)NULL; + item->DeleteChildren (this); delete item; } -void wxTreeListMainWindow::DeleteAllItems() -{ - if ( m_anchor ) - { - m_dirty = TRUE; +void wxTreeListMainWindow::DeleteChildren (const wxTreeItemId& itemId) { + wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem; + m_dirty = true; // do this first so stuff below doesn't cause flicker - m_anchor->DeleteChildren(this); - delete m_anchor; + item->DeleteChildren (this); +} - m_anchor = NULL; +void wxTreeListMainWindow::DeleteRoot() { + if (m_rootItem) { + m_dirty = true; + SendDeleteEvent (m_rootItem); + m_curItem = (wxTreeListItem*)NULL; + m_selectItem= (wxTreeListItem*)NULL; + m_rootItem->DeleteChildren (this); + delete m_rootItem; + m_rootItem = NULL; } } -void wxTreeListMainWindow::Expand(const wxTreeItemId& itemId) -{ +void wxTreeListMainWindow::Expand (const wxTreeItemId& itemId) { wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem; + wxCHECK_RET (item, _T("invalid item in wxTreeListMainWindow::Expand") ); - wxCHECK_RET( item, _T("invalid item in wxTreeListMainWindow::Expand") ); - - if ( !item->HasPlus() ) - return; - - if ( item->IsExpanded() ) - return; - - wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_EXPANDING, m_owner->GetId() ); - event.SetItem( (void*)item ); - event.SetEventObject( /*this*/m_owner ); + if (!item->HasPlus() || item->IsExpanded()) return; - if ( m_owner->ProcessEvent( event ) && !event.IsAllowed() ) - { - // cancelled by program - return; - } + // send event to user code + wxTreeEvent event (wxEVT_COMMAND_TREE_ITEM_EXPANDING, m_owner->GetId()); +#if !wxCHECK_VERSION(2, 5, 0) + event.SetItem ((long)item); +#else + event.SetItem (item); +#endif + event.SetEventObject (m_owner); + if (m_owner->ProcessEvent (event) && !event.IsAllowed()) return; // expand canceled item->Expand(); - CalculatePositions(); - - RefreshSubtree(item); + m_dirty = true; - event.SetEventType(wxEVT_COMMAND_TREE_ITEM_EXPANDED); - ProcessEvent( event ); + // send event to user code + event.SetEventType (wxEVT_COMMAND_TREE_ITEM_EXPANDED); + m_owner->ProcessEvent (event); } -void wxTreeListMainWindow::ExpandAll(const wxTreeItemId& item) -{ - Expand(item); - if ( IsExpanded(item) ) - { +void wxTreeListMainWindow::ExpandAll (const wxTreeItemId& itemId) { + Expand (itemId); + if (!IsExpanded (itemId)) return; #if !wxCHECK_VERSION(2, 5, 0) - long cookie; + long cookie; #else - wxTreeItemIdValue cookie; + wxTreeItemIdValue cookie; #endif - wxTreeItemId child = GetFirstChild(item, cookie); - while ( child.IsOk() ) - { - ExpandAll(child); - - child = GetNextChild(item, cookie); - } + wxTreeItemId child = GetFirstChild (itemId, cookie); + while (child.IsOk()) { + ExpandAll (child); + child = GetNextChild (itemId, cookie); } } -void wxTreeListMainWindow::Collapse(const wxTreeItemId& itemId) -{ +void wxTreeListMainWindow::Collapse (const wxTreeItemId& itemId) { wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem; + wxCHECK_RET (item, _T("invalid item in wxTreeListMainWindow::Collapse") ); - if ( !item->IsExpanded() ) - return; - - wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_COLLAPSING, m_owner->GetId() ); - event.SetItem( (void*)item ); - event.SetEventObject( /*this*/m_owner ); - if ( m_owner->ProcessEvent( event ) && !event.IsAllowed() ) - { - // cancelled by program - return; - } - - item->Collapse(); + if (!item->HasPlus() || !item->IsExpanded()) return; -#if 0 // TODO why should items be collapsed recursively? - wxArrayTreeListItems& children = item->GetChildren(); - size_t count = children.Count(); - for ( size_t n = 0; n < count; n++ ) - { - Collapse(children[n]); - } + // send event to user code + wxTreeEvent event (wxEVT_COMMAND_TREE_ITEM_COLLAPSING, m_owner->GetId() ); +#if !wxCHECK_VERSION(2, 5, 0) + event.SetItem ((long)item); +#else + event.SetItem (item); #endif + event.SetEventObject (m_owner); + if (m_owner->ProcessEvent (event) && !event.IsAllowed()) return; // collapse canceled - CalculatePositions(); - - RefreshSubtree(item); + item->Collapse(); + m_dirty = true; - event.SetEventType(wxEVT_COMMAND_TREE_ITEM_COLLAPSED); - ProcessEvent( event ); + // send event to user code + event.SetEventType (wxEVT_COMMAND_TREE_ITEM_COLLAPSED); + ProcessEvent (event); } -void wxTreeListMainWindow::CollapseAndReset(const wxTreeItemId& item) -{ - Collapse(item); - DeleteChildren(item); +void wxTreeListMainWindow::CollapseAndReset (const wxTreeItemId& item) { + Collapse (item); + DeleteChildren (item); } -void wxTreeListMainWindow::Toggle(const wxTreeItemId& itemId) -{ - wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem; - - if (item->IsExpanded()) - Collapse(itemId); - else - Expand(itemId); +void wxTreeListMainWindow::Toggle (const wxTreeItemId& itemId) { + if (IsExpanded (itemId)) { + Collapse (itemId); + }else{ + Expand (itemId); + } } -void wxTreeListMainWindow::Unselect() -{ - if (m_current) - { - m_current->SetHilight( FALSE ); - RefreshLine( m_current ); +void wxTreeListMainWindow::Unselect() { + if (m_selectItem) { + m_selectItem->SetHilight (false); + RefreshLine (m_selectItem); + m_selectItem = (wxTreeListItem*)NULL; } } -void wxTreeListMainWindow::UnselectAllChildren(wxTreeListItem *item) -{ - if (item->IsSelected()) - { - item->SetHilight(FALSE); - RefreshLine(item); +void wxTreeListMainWindow::UnselectAllChildren (wxTreeListItem *item) { + if (item->IsSelected()) { + item->SetHilight (false); + RefreshLine (item); + if (item == m_selectItem) m_selectItem = (wxTreeListItem*)NULL; } - - if (item->HasChildren()) - { + if (item->HasChildren()) { wxArrayTreeListItems& children = item->GetChildren(); size_t count = children.Count(); - for ( size_t n = 0; n < count; ++n ) - { - UnselectAllChildren(children[n]); + for (size_t n = 0; n < count; ++n) { + UnselectAllChildren (children[n]); } } } -void wxTreeListMainWindow::UnselectAll() -{ - UnselectAllChildren((wxTreeListItem*)GetRootItem().m_pItem); +void wxTreeListMainWindow::UnselectAll() { + UnselectAllChildren ((wxTreeListItem*)GetRootItem().m_pItem); } // Recursive function ! @@ -2768,178 +2448,131 @@ void wxTreeListMainWindow::UnselectAll() // Tag all next children, when no more children, // Move to parent (not to tag) // Keep going... if we found last_item, we stop. -bool wxTreeListMainWindow::TagNextChildren(wxTreeListItem *crt_item, wxTreeListItem *last_item, bool select) -{ +bool wxTreeListMainWindow::TagNextChildren (wxTreeListItem *crt_item, + wxTreeListItem *last_item) { wxTreeListItem *parent = crt_item->GetItemParent(); - if (parent == NULL) // This is root item - return TagAllChildrenUntilLast(crt_item, last_item, select); + if (!parent) {// This is root item + return TagAllChildrenUntilLast (crt_item, last_item); + } wxArrayTreeListItems& children = parent->GetChildren(); int index = children.Index(crt_item); - wxASSERT( index != wxNOT_FOUND ); // I'm not a child of my parent? + wxASSERT (index != wxNOT_FOUND); // I'm not a child of my parent? - size_t count = children.Count(); - for (size_t n=(size_t)(index+1); nHasChildren() && parent->IsExpanded()) || + ((parent == (wxTreeListItem*)GetRootItem().m_pItem) && HasFlag(wxTR_HIDE_ROOT))) { + size_t count = children.Count(); + for (size_t n = (index+1); n < count; ++n) { + if (TagAllChildrenUntilLast (children[n], last_item)) return true; + } } - return TagNextChildren(parent, last_item, select); + return TagNextChildren (parent, last_item); } -bool wxTreeListMainWindow::TagAllChildrenUntilLast(wxTreeListItem *crt_item, wxTreeListItem *last_item, bool select) -{ - crt_item->SetHilight(select); +bool wxTreeListMainWindow::TagAllChildrenUntilLast (wxTreeListItem *crt_item, + wxTreeListItem *last_item) { + crt_item->SetHilight (true); RefreshLine(crt_item); - if (crt_item==last_item) - return TRUE; + if (crt_item==last_item) return true; - if (crt_item->HasChildren()) - { + if (crt_item->HasChildren() && crt_item->IsExpanded()) { wxArrayTreeListItems& children = crt_item->GetChildren(); size_t count = children.Count(); - for ( size_t n = 0; n < count; ++n ) - { - if (TagAllChildrenUntilLast(children[n], last_item, select)) - return TRUE; + for (size_t n = 0; n < count; ++n) { + if (TagAllChildrenUntilLast (children[n], last_item)) return true; } } - return FALSE; + return false; } -void wxTreeListMainWindow::SelectItemRange(wxTreeListItem *item1, wxTreeListItem *item2) -{ - // item2 is not necessary after item1 - wxTreeListItem *first=NULL, *last=NULL; +void wxTreeListMainWindow::SelectItem (const wxTreeItemId& itemId, + const wxTreeItemId& lastId, + bool unselect_others) { + wxCHECK_RET (itemId.IsOk(), _T("invalid tree item") ); - // choice first' and 'last' between item1 and item2 - if (item1->GetY()GetY()) - { - first=item1; - last=item2; - } - else - { - first=item2; - last=item1; - } + bool is_single = !HasFlag(wxTR_MULTIPLE); + wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem; - bool select = m_current->IsSelected(); - - if ( TagAllChildrenUntilLast(first,last,select) ) - return; - - TagNextChildren(first,last,select); -} - -void wxTreeListMainWindow::SelectItem(const wxTreeItemId& itemId, - bool unselect_others, - bool extended_select) -{ - wxCHECK_RET( itemId.IsOk(), wxT("invalid tree item") ); - - bool is_single=!(GetWindowStyleFlag() & wxTR_MULTIPLE); - wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem; - - //wxCHECK_RET( ( (!unselect_others) && is_single), - // wxT("this is a single selection tree") ); - - // to keep going anyhow !!! - if (is_single) - { - if (item->IsSelected()) - return; // nothing to do - unselect_others = TRUE; - extended_select = FALSE; - } - else if ( unselect_others && item->IsSelected() ) - { - // selection change if there is more than one item currently selected - wxArrayTreeItemIds selected_items; - if ( GetSelections(selected_items) == 1 ) - return; - } + // single selection requires unselect others + if (is_single) unselect_others = true; + // send event to the user code wxTreeEvent event( wxEVT_COMMAND_TREE_SEL_CHANGING, m_owner->GetId() ); - event.SetItem( (void*)item ); - event.SetOldItem( (void*)m_current ); - event.SetEventObject( /*this*/m_owner ); - // TODO : Here we don't send any selection mode yet ! - - if(m_owner->GetEventHandler()->ProcessEvent( event ) && !event.IsAllowed()) - return; - - wxTreeItemId parent = GetItemParent( itemId ); - while (parent.IsOk()) - { - if (!IsExpanded(parent)) - Expand( parent ); - - parent = GetItemParent( parent ); +#if !wxCHECK_VERSION(2, 5, 0) + event.SetItem ((long)item); + event.SetOldItem ((long)m_curItem); +#else + event.SetItem (item); + event.SetOldItem (m_curItem); +#endif + event.SetEventObject (m_owner); + if (m_owner->GetEventHandler()->ProcessEvent (event) && !event.IsAllowed()) return; + + // unselect all if unselect other items + bool unselected = false; // see that UnselectAll is done only once + if (unselect_others) { + if (is_single) { + Unselect(); // to speed up thing + }else{ + UnselectAll(); + unselected = true; + } } - EnsureVisible( itemId ); + // select item or item range + if (lastId.IsOk() && (itemId != lastId)) { - // ctrl press - if (unselect_others) - { - if (is_single) Unselect(); // to speed up thing - else UnselectAll(); - } + if (!unselected) UnselectAll(); + wxTreeListItem *last = (wxTreeListItem*) lastId.m_pItem; - // shift press - if (extended_select) - { - if ( !m_current ) - { - m_current = m_key_current = (wxTreeListItem*)GetRootItem().m_pItem; + // ensure that the position of the item it calculated in any case + if (m_dirty) CalculatePositions(); + + // select item range according Y-position + if (last->GetY() < item->GetY()) { + if (!TagAllChildrenUntilLast (last, item)) { + TagNextChildren (last, item); + } + }else{ + if (!TagAllChildrenUntilLast (item, last)) { + TagNextChildren (item, last); + } } - // don't change the mark (m_current) - SelectItemRange(m_current, item); - } - else - { - bool select=TRUE; // the default + }else{ - // Check if we need to toggle hilight (ctrl mode) - if (!unselect_others) - select=!item->IsSelected(); + // select item according its old selection + item->SetHilight (!item->IsSelected()); + RefreshLine (item); + if (unselect_others) { + m_selectItem = (item->IsSelected())? item: (wxTreeListItem*)NULL; + } - m_current = m_key_current = item; - m_current->SetHilight(select); - RefreshLine( m_current ); } + // send event to user code event.SetEventType(wxEVT_COMMAND_TREE_SEL_CHANGED); - GetEventHandler()->ProcessEvent( event ); + m_owner->GetEventHandler()->ProcessEvent (event); } -void wxTreeListMainWindow::SelectAll(bool extended_select) -{ - wxCHECK_RET( GetWindowStyleFlag() & wxTR_MULTIPLE, wxT("invalid tree style, must have wxTR_MULTIPLE style to select all items") ); - - wxTreeEvent event( wxEVT_COMMAND_TREE_SEL_CHANGING, m_owner->GetId() ); - event.SetItem( GetRootItem() ); - event.SetOldItem( (void*) m_current ); - event.SetEventObject( /*this*/m_owner ); - // TODO : Here we don't send any selection mode yet ! - - if(m_owner->GetEventHandler()->ProcessEvent( event ) && !event.IsAllowed()) - return; - - // shift press - if (!extended_select) - { +void wxTreeListMainWindow::SelectAll() { + wxCHECK_RET (HasFlag(wxTR_MULTIPLE), _T("invalid tree style")); - } - else - { + // send event to user code + wxTreeEvent event (wxEVT_COMMAND_TREE_SEL_CHANGING, m_owner->GetId()); + event.SetItem (GetRootItem()); +#if !wxCHECK_VERSION(2, 5, 0) + event.SetOldItem ((long)m_curItem); +#else + event.SetOldItem (m_curItem); +#endif + event.SetEventObject (m_owner); + if (m_owner->GetEventHandler()->ProcessEvent (event) && !event.IsAllowed()) return; - } #if !wxCHECK_VERSION(2, 5, 0) long cookie = 0; #else @@ -2947,112 +2580,85 @@ void wxTreeListMainWindow::SelectAll(bool extended_select) #endif wxTreeItemId root = GetRootItem(); wxTreeListItem *first = (wxTreeListItem *)GetFirstChild (root, cookie).m_pItem; - wxTreeListItem *last = (wxTreeListItem *)GetLastChild (GetRootItem()).m_pItem; - if (!first || !last) return; - if (TagAllChildrenUntilLast (first, last, true)) return; - TagNextChildren (first, last, true); + wxTreeListItem *last = (wxTreeListItem *)GetLastChild (root, cookie).m_pItem; + if (!TagAllChildrenUntilLast (first, last)) { + TagNextChildren (first, last); + } - event.SetEventType(wxEVT_COMMAND_TREE_SEL_CHANGED); - GetEventHandler()->ProcessEvent( event ); + // send event to user code + event.SetEventType (wxEVT_COMMAND_TREE_SEL_CHANGED); + m_owner->GetEventHandler()->ProcessEvent (event); } -void wxTreeListMainWindow::FillArray(wxTreeListItem *item, - wxArrayTreeItemIds &array) const -{ - if ( item->IsSelected() ) - array.Add(wxTreeItemId(item)); +void wxTreeListMainWindow::FillArray (wxTreeListItem *item, + wxArrayTreeItemIds &array) const { + if (item->IsSelected()) array.Add (wxTreeItemId(item)); - if ( item->HasChildren() ) - { + if (item->HasChildren()) { wxArrayTreeListItems& children = item->GetChildren(); size_t count = children.GetCount(); - for ( size_t n = 0; n < count; ++n ) - FillArray(children[n], array); + for (size_t n = 0; n < count; ++n) FillArray (children[n], array); } } -size_t wxTreeListMainWindow::GetSelections(wxArrayTreeItemIds &array) const -{ +size_t wxTreeListMainWindow::GetSelections (wxArrayTreeItemIds &array) const { array.Empty(); wxTreeItemId idRoot = GetRootItem(); - if ( idRoot.IsOk() ) - { - FillArray((wxTreeListItem*) idRoot.m_pItem, array); - } - //else: the tree is empty, so no selections - + if (idRoot.IsOk()) FillArray ((wxTreeListItem*) idRoot.m_pItem, array); return array.Count(); } -void wxTreeListMainWindow::EnsureVisible(const wxTreeItemId& item) -{ - if (!item.IsOk()) return; - - wxTreeListItem *gitem = (wxTreeListItem*) item.m_pItem; +void wxTreeListMainWindow::EnsureVisible (const wxTreeItemId& item) { + if (!item.IsOk()) return; // do nothing if no item // first expand all parent branches + wxTreeListItem *gitem = (wxTreeListItem*) item.m_pItem; wxTreeListItem *parent = gitem->GetItemParent(); - while ( parent ) - { - Expand(parent); + while (parent) { + Expand (parent); parent = parent->GetItemParent(); } - //if (parent) CalculatePositions(); - - ScrollTo(item); + ScrollTo (item); + RefreshLine (gitem); } -void wxTreeListMainWindow::ScrollTo(const wxTreeItemId &item) -{ - if (!item.IsOk()) return; +void wxTreeListMainWindow::ScrollTo (const wxTreeItemId &item) { + if (!item.IsOk()) return; // do nothing if no item - // We have to call this here because the label in - // question might just have been added and no screen - // update taken place. - if (m_dirty) - DoDirtyProcessing(); + // ensure that the position of the item it calculated in any case + if (m_dirty) CalculatePositions(); wxTreeListItem *gitem = (wxTreeListItem*) item.m_pItem; // now scroll to the item int item_y = gitem->GetY(); + int xUnit, yUnit; + GetScrollPixelsPerUnit (&xUnit, &yUnit); int start_x = 0; int start_y = 0; - GetViewStart( &start_x, &start_y ); - start_y *= PIXELS_PER_UNIT; + GetViewStart (&start_x, &start_y); + start_y *= yUnit; int client_h = 0; int client_w = 0; - GetClientSize( &client_w, &client_h ); + GetClientSize (&client_w, &client_h); - if (item_y < start_y+3) - { - // going down - int x = 0; - int y = 0; - m_anchor->GetSize( x, y, this ); - x = m_owner->GetHeaderWindow()->GetWidth(); //m_total_col_width; // ALB - y += PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels - //x += PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels - int x_pos = GetScrollPos( wxHORIZONTAL ); - // Item should appear at top - SetScrollbars( PIXELS_PER_UNIT, PIXELS_PER_UNIT, x/PIXELS_PER_UNIT, y/PIXELS_PER_UNIT, x_pos, item_y/PIXELS_PER_UNIT ); - } - else if (item_y+GetLineHeight(gitem) > start_y+client_h) - { - // going up - int x = 0; - int y = 0; - m_anchor->GetSize( x, y, this ); - y += PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels - //x += PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels - x = m_owner->GetHeaderWindow()->GetWidth(); //m_total_col_width; // ALB - item_y += PIXELS_PER_UNIT+2; - int x_pos = GetScrollPos( wxHORIZONTAL ); - // Item should appear at bottom - SetScrollbars( PIXELS_PER_UNIT, PIXELS_PER_UNIT, x/PIXELS_PER_UNIT, y/PIXELS_PER_UNIT, x_pos, (item_y+GetLineHeight(gitem)-client_h)/PIXELS_PER_UNIT ); + int x = 0; + int y = 0; + m_rootItem->GetSize (x, y, this); + x = m_owner->GetHeaderWindow()->GetWidth(); + y += yUnit + 2; // one more scrollbar unit + 2 pixels + int x_pos = GetScrollPos( wxHORIZONTAL ); + + if (item_y < start_y+3) { + // going down, item should appear at top + SetScrollbars (xUnit, yUnit, xUnit ? x/xUnit : 0, yUnit ? y/yUnit : 0, x_pos, yUnit ? item_y/yUnit : 0); + }else if (item_y+GetLineHeight(gitem) > start_y+client_h) { + // going up, item should appear at bottom + item_y += yUnit + 2; + SetScrollbars (xUnit, yUnit, xUnit ? x/xUnit : 0, yUnit ? y/yUnit : 0, x_pos, yUnit ? (item_y+GetLineHeight(gitem)-client_h)/yUnit : 0 ); } } @@ -3062,7 +2668,7 @@ static wxTreeListMainWindow *s_treeBeingSorted = NULL; static int LINKAGEMODE tree_ctrl_compare_func(wxTreeListItem **item1, wxTreeListItem **item2) { - wxCHECK_MSG( s_treeBeingSorted, 0, wxT("bug in wxTreeListMainWindow::SortChildren()") ); + wxCHECK_MSG (s_treeBeingSorted, 0, _T("bug in wxTreeListMainWindow::SortChildren()") ); return s_treeBeingSorted->OnCompareItems(*item1, *item2); } @@ -3070,322 +2676,362 @@ static int LINKAGEMODE tree_ctrl_compare_func(wxTreeListItem **item1, int wxTreeListMainWindow::OnCompareItems(const wxTreeItemId& item1, const wxTreeItemId& item2) { - // ALB: delegate to m_owner, to let the user overrride the comparison - //return wxStrcmp(GetItemText(item1), GetItemText(item2)); - return m_owner->OnCompareItems(item1, item2); + return m_owner->OnCompareItems (item1, item2); } -void wxTreeListMainWindow::SortChildren(const wxTreeItemId& itemId) -{ - wxCHECK_RET( itemId.IsOk(), wxT("invalid tree item") ); +void wxTreeListMainWindow::SortChildren (const wxTreeItemId& itemId) { + wxCHECK_RET (itemId.IsOk(), _T("invalid tree item")); wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem; - wxCHECK_RET( !s_treeBeingSorted, - wxT("wxTreeListMainWindow::SortChildren is not reentrant") ); + wxCHECK_RET (!s_treeBeingSorted, + _T("wxTreeListMainWindow::SortChildren is not reentrant") ); wxArrayTreeListItems& children = item->GetChildren(); - if ( children.Count() > 1 ) - { - m_dirty = TRUE; - + if ( children.Count() > 1 ) { + m_dirty = true; s_treeBeingSorted = this; children.Sort(tree_ctrl_compare_func); s_treeBeingSorted = NULL; } - //else: don't make the tree dirty as nothing changed } -wxTreeItemId wxTreeListMainWindow::FindItem (const wxTreeItemId& item, const wxString& str, int flags) { +wxTreeItemId wxTreeListMainWindow::FindItem (const wxTreeItemId& item, const wxString& str, int mode) { + wxString itemText; + // determine start item + wxTreeItemId next = item; + if (next.IsOk()) { + if (mode & wxTL_MODE_NAV_LEVEL) { + next = GetNextSibling (next); + }else if (mode & wxTL_MODE_NAV_VISIBLE) { // + next = GetNextVisible (next, false); + }else if (mode & wxTL_MODE_NAV_EXPANDED) { + next = GetNextExpanded (next); + }else{ // (mode & wxTL_MODE_NAV_FULLTREE) default + next = GetNext (next, true); + } + } + #if !wxCHECK_VERSION(2, 5, 0) long cookie = 0; #else wxTreeItemIdValue cookie = 0; #endif - wxTreeItemId next = item; - if (!next.IsOk()) next = GetSelection(); if (!next.IsOk()) { + next = (wxTreeListItem*)GetRootItem().m_pItem; if (HasFlag(wxTR_HIDE_ROOT)) { next = (wxTreeListItem*)GetFirstChild (GetRootItem().m_pItem, cookie).m_pItem; - } else { - next = (wxTreeListItem*)GetRootItem().m_pItem; } } - if (!next.IsOk()) return item; + if (!next.IsOk()) return (wxTreeItemId*)NULL; // start checking the next items - wxString itemText; - while (next.IsOk()) { - itemText = GetItemText (next); - if (flags & wxTL_SEARCH_LEVEL) { - next = GetNextSibling (next); - }else if (flags & wxTL_SEARCH_FULL) { - wxTreeItemId n = GetFirstChild (next, cookie); - if (!n.IsOk()) - n = GetNextSibling (next); - if (!n.IsOk()) - n = GetNextSibling (GetItemParent (next)); - next = n; - }else{ // wxTL_SEARCH_VISIBLE - next = GetNextVisible (next); - } - if (!next.IsOk()) break; // done - if (flags & wxTL_SEARCH_PARTIAL) { + while (next.IsOk() && (next != item)) { + if (mode & wxTL_MODE_FIND_PARTIAL) { itemText = GetItemText (next).Mid (0, str.Length()); }else{ itemText = GetItemText (next); } - if (flags & wxTL_SEARCH_NOCASE) { + if (mode & wxTL_MODE_FIND_NOCASE) { if (itemText.CmpNoCase (str) == 0) return next; }else{ if (itemText.Cmp (str) == 0) return next; } + if (mode & wxTL_MODE_NAV_LEVEL) { + next = GetNextSibling (next); + }else if (mode & wxTL_MODE_NAV_VISIBLE) { // + next = GetNextVisible (next, false); + }else if (mode & wxTL_MODE_NAV_EXPANDED) { + next = GetNextExpanded (next); + }else{ // (mode & wxTL_MODE_NAV_FULLTREE) default + next = GetNext (next, true); + } + if (!next.IsOk() && item.IsOk()) { + next = (wxTreeListItem*)GetRootItem().m_pItem; + if (HasFlag(wxTR_HIDE_ROOT)) { + next = (wxTreeListItem*)GetNextChild (GetRootItem().m_pItem, cookie).m_pItem; + } + } } - return item; -} - -wxImageList *wxTreeListMainWindow::GetImageList() const -{ - return m_imageListNormal; -} - -wxImageList *wxTreeListMainWindow::GetButtonsImageList() const -{ - return m_imageListButtons; + return (wxTreeItemId*)NULL; } -wxImageList *wxTreeListMainWindow::GetStateImageList() const -{ - return m_imageListState; +void wxTreeListMainWindow::SetDragItem (const wxTreeItemId& item) { + wxTreeListItem *prevItem = m_dragItem; + m_dragItem = (wxTreeListItem*) item.m_pItem; + if (prevItem) RefreshLine (prevItem); + if (m_dragItem) RefreshLine (m_dragItem); } -void wxTreeListMainWindow::CalculateLineHeight() -{ - wxClientDC dc(this); - dc.SetFont( m_normalFont ); +void wxTreeListMainWindow::CalculateLineHeight() { + wxClientDC dc (this); + dc.SetFont (m_normalFont); m_lineHeight = (int)(dc.GetCharHeight() + m_linespacing); - if ( m_imageListNormal ) - { + if (m_imageListNormal) { // Calculate a m_lineHeight value from the normal Image sizes. // May be toggle off. Then wxTreeListMainWindow will spread when // necessary (which might look ugly). int n = m_imageListNormal->GetImageCount(); - for (int i = 0; i < n ; i++) - { + for (int i = 0; i < n ; i++) { int width = 0, height = 0; m_imageListNormal->GetSize(i, width, height); if (height > m_lineHeight) m_lineHeight = height + m_linespacing; } } - if (m_imageListButtons) - { + if (m_imageListButtons) { // Calculate a m_lineHeight value from the Button image sizes. // May be toggle off. Then wxTreeListMainWindow will spread when // necessary (which might look ugly). int n = m_imageListButtons->GetImageCount(); - for (int i = 0; i < n ; i++) - { + for (int i = 0; i < n ; i++) { int width = 0, height = 0; m_imageListButtons->GetSize(i, width, height); if (height > m_lineHeight) m_lineHeight = height + m_linespacing; } } -/*? FIXME: Don't get what this code is for... Adding a line space is already done!!! - if (m_lineHeight < 30) - m_lineHeight += 2; // at least 2 pixels - else - m_lineHeight += m_lineHeight/10; // otherwise 10% extra spacing -?*/ + if (m_lineHeight < 30) { // add 10% space if greater than 30 pixels + m_lineHeight += 2; // minimal 2 pixel space + }else{ + m_lineHeight += m_lineHeight / 10; // otherwise 10% space + } } -void wxTreeListMainWindow::SetImageList(wxImageList *imageList) -{ +void wxTreeListMainWindow::SetImageList (wxImageList *imageList) { if (m_ownsImageListNormal) delete m_imageListNormal; m_imageListNormal = imageList; - m_ownsImageListNormal = FALSE; - m_dirty = TRUE; + m_ownsImageListNormal = false; + m_dirty = true; CalculateLineHeight(); } -void wxTreeListMainWindow::SetStateImageList(wxImageList *imageList) -{ +void wxTreeListMainWindow::SetStateImageList (wxImageList *imageList) { if (m_ownsImageListState) delete m_imageListState; m_imageListState = imageList; - m_ownsImageListState = FALSE; + m_ownsImageListState = false; } -void wxTreeListMainWindow::SetButtonsImageList(wxImageList *imageList) -{ +void wxTreeListMainWindow::SetButtonsImageList (wxImageList *imageList) { if (m_ownsImageListButtons) delete m_imageListButtons; m_imageListButtons = imageList; - m_ownsImageListButtons = FALSE; - m_dirty = TRUE; + m_ownsImageListButtons = false; + m_dirty = true; CalculateLineHeight(); } -void wxTreeListMainWindow::AssignImageList(wxImageList *imageList) -{ +void wxTreeListMainWindow::AssignImageList (wxImageList *imageList) { SetImageList(imageList); - m_ownsImageListNormal = TRUE; + m_ownsImageListNormal = true; } -void wxTreeListMainWindow::AssignStateImageList(wxImageList *imageList) -{ +void wxTreeListMainWindow::AssignStateImageList (wxImageList *imageList) { SetStateImageList(imageList); - m_ownsImageListState = TRUE; + m_ownsImageListState = true; } -void wxTreeListMainWindow::AssignButtonsImageList(wxImageList *imageList) -{ +void wxTreeListMainWindow::AssignButtonsImageList (wxImageList *imageList) { SetButtonsImageList(imageList); - m_ownsImageListButtons = TRUE; + m_ownsImageListButtons = true; } // ---------------------------------------------------------------------------- // helpers // ---------------------------------------------------------------------------- -void wxTreeListMainWindow::AdjustMyScrollbars() -{ - if (m_anchor) - { +void wxTreeListMainWindow::AdjustMyScrollbars() { + if (m_rootItem) { + int xUnit, yUnit; + GetScrollPixelsPerUnit (&xUnit, &yUnit); + if (xUnit == 0) xUnit = GetCharWidth(); + if (yUnit == 0) yUnit = m_lineHeight; int x = 0, y = 0; - m_anchor->GetSize( x, y, this ); - y += PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels - //x += PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels - int x_pos = GetScrollPos( wxHORIZONTAL ); - int y_pos = GetScrollPos( wxVERTICAL ); + m_rootItem->GetSize (x, y, this); + y += yUnit + 2; // one more scrollbar unit + 2 pixels + int x_pos = GetScrollPos (wxHORIZONTAL); + int y_pos = GetScrollPos (wxVERTICAL); x = m_owner->GetHeaderWindow()->GetWidth() + 2; - if(x < GetClientSize().GetWidth()) x_pos = 0; - //m_total_col_width + 2; // ALB - SetScrollbars( PIXELS_PER_UNIT, PIXELS_PER_UNIT, x/PIXELS_PER_UNIT, - y/PIXELS_PER_UNIT, x_pos, y_pos ); - } - else - { - SetScrollbars( 0, 0, 0, 0 ); + if (x < GetClientSize().GetWidth()) x_pos = 0; + SetScrollbars (xUnit, yUnit, x/xUnit, y/yUnit, x_pos, y_pos); + }else{ + SetScrollbars (0, 0, 0, 0); } } -int wxTreeListMainWindow::GetLineHeight(wxTreeListItem *item) const -{ - if (GetWindowStyleFlag() & wxTR_HAS_VARIABLE_ROW_HEIGHT) +int wxTreeListMainWindow::GetLineHeight (wxTreeListItem *item) const { + if (GetWindowStyleFlag() & wxTR_HAS_VARIABLE_ROW_HEIGHT) { return item->GetHeight(); - else + }else{ return m_lineHeight; + } } -void wxTreeListMainWindow::PaintItem(wxTreeListItem *item, wxDC& dc) -{ +void wxTreeListMainWindow::PaintItem (wxTreeListItem *item, wxDC& dc) { + wxTreeItemAttr *attr = item->GetAttributes(); - if (attr && attr->HasFont()) { - dc.SetFont(attr->GetFont()); - }else if (item->IsBold()) { - dc.SetFont(m_boldFont); - } + + dc.SetFont (GetItemFont (item)); + wxColour colText; if (attr && attr->HasTextColour()) { colText = attr->GetTextColour(); }else{ colText = GetForegroundColour(); } +#if !wxCHECK_VERSION(2, 5, 0) + wxColour colTextHilight = wxSystemSettings::GetSystemColour (wxSYS_COLOUR_HIGHLIGHTTEXT); +#else + wxColour colTextHilight = wxSystemSettings::GetColour (wxSYS_COLOUR_HIGHLIGHTTEXT); +#endif - dc.SetPen(*wxTRANSPARENT_PEN); - - long text_w = 0, text_h = 0; + int total_w = m_owner->GetHeaderWindow()->GetWidth(); + int total_h = GetLineHeight(item); + int off_h = HasFlag(wxTR_ROW_LINES) ? 1 : 0; + int off_w = HasFlag(wxTR_COLUMN_LINES) ? 1 : 0; + wxDCClipper clipper (dc, 0, item->GetY(), total_w, total_h); // only within line + int text_w = 0, text_h = 0; dc.GetTextExtent( item->GetText(GetMainColumn()), &text_w, &text_h ); - int total_h = GetLineHeight(item); - - if (item->IsSelected() && HasFlag(wxTR_FULL_ROW_HIGHLIGHT)) { - dc.SetBrush(*(m_hasFocus ? m_hilightBrush : m_hilightUnfocusedBrush)); - dc.SetPen(*wxBLACK_PEN); - colText = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT); - } else { - wxColour colBg; - if (attr && attr->HasBackgroundColour()) { - colBg = attr->GetBackgroundColour(); - } else { - colBg = GetBackgroundColour(); + // determine background and show it + wxColour colBg; + if (attr && attr->HasBackgroundColour()) { + colBg = attr->GetBackgroundColour(); + }else{ + colBg = m_backgroundColour; + } + dc.SetBrush (wxBrush (colBg, wxSOLID)); + dc.SetPen (*wxTRANSPARENT_PEN); + if (HasFlag (wxTR_FULL_ROW_HIGHLIGHT)) { + if (item == m_dragItem) { + dc.SetBrush (*m_hilightBrush); +#ifndef __WXMAC__ // don't draw rect outline if we already have the background color + dc.SetPen ((item == m_dragItem)? *wxBLACK_PEN: *wxTRANSPARENT_PEN); +#endif // !__WXMAC__ + dc.SetTextForeground (colTextHilight); + }else if (item->IsSelected()) { + if (!m_isDragging && m_hasFocus) { + dc.SetBrush (*m_hilightBrush); +#ifndef __WXMAC__ // don't draw rect outline if we already have the background color + dc.SetPen (*wxBLACK_PEN); +#endif // !__WXMAC__ + }else{ + dc.SetBrush (*m_hilightUnfocusedBrush); +#ifndef __WXMAC__ // don't draw rect outline if we already have the background color + dc.SetPen (*wxTRANSPARENT_PEN); +#endif // !__WXMAC__ + } + dc.SetTextForeground (colTextHilight); + }else if (item == m_curItem) { + dc.SetPen (m_hasFocus? *wxBLACK_PEN: *wxTRANSPARENT_PEN); + }else{ + dc.SetTextForeground (colText); } - dc.SetBrush(wxBrush(colBg, wxSOLID)); + dc.DrawRectangle (0, item->GetY() + off_h, total_w, total_h - off_h); + }else{ + dc.SetTextForeground (colText); } - int offset = HasFlag(wxTR_ROW_LINES) ? 1 : 0; - dc.DrawRectangle(0, item->GetY() + offset, - m_owner->GetHeaderWindow()->GetWidth(), total_h-offset); - - dc.SetBackgroundMode(wxTRANSPARENT); int text_extraH = (total_h > text_h) ? (total_h - text_h)/2 : 0; int img_extraH = (total_h > m_imgHeight)? (total_h-m_imgHeight)/2: 0; int x_colstart = 0; - for ( size_t i = 0; i < GetColumnCount(); ++i ) { - if (!m_owner->GetHeaderWindow()->GetColumnShown(i)) continue; - int colwidth = m_owner->GetHeaderWindow()->GetColumnWidth(i); - int image; - int image_x = 0; + for (int i = 0; i < GetColumnCount(); ++i ) { + if (!m_owner->GetHeaderWindow()->IsColumnShown(i)) continue; + + int col_w = m_owner->GetHeaderWindow()->GetColumnWidth(i); + wxDCClipper clipper (dc, x_colstart, item->GetY(), col_w, total_h); // only within column + + int x = 0; + int image = NO_IMAGE; int image_w = 0; - if (i == GetMainColumn()) { - image = item->GetCurrentImage(); - if (item->HasPlus()) { - image_x = item->GetX() + (m_btnWidth-m_btnWidth2) + LINEATROOT; + if(i == GetMainColumn()) { + x = item->GetX() + MARGIN; + if (HasButtons()) { + x += (m_btnWidth-m_btnWidth2) + LINEATROOT; }else{ - image_x = item->GetX() - m_imgWidth2; + x -= m_indent/2; } - } - else - { + if (m_imageListNormal) image = item->GetCurrentImage(); + }else{ + x = x_colstart + MARGIN; image = item->GetImage(i); - image_x = x_colstart + MARGIN; } if (image != NO_IMAGE) image_w = m_imgWidth + MARGIN; // honor text alignment wxString text = item->GetText(i); + int w = 0; switch ( m_owner->GetHeaderWindow()->GetColumn(i).GetAlignment() ) { - case wxTL_ALIGN_LEFT: - // already left aligned + case wxALIGN_LEFT: + // nothing to do, already left aligned break; - case wxTL_ALIGN_RIGHT: - dc.GetTextExtent(text, &text_w, NULL); - image_x = x_colstart + colwidth - (image_w + text_w + MARGIN); + case wxALIGN_RIGHT: + dc.GetTextExtent (text, &text_w, NULL); + w = col_w - (image_w + text_w + off_w + MARGIN); + x += (w > 0)? w: 0; break; - case wxTL_ALIGN_CENTER: + case wxALIGN_CENTER: dc.GetTextExtent(text, &text_w, NULL); - int w = colwidth - image_w - text_w; - image_x = x_colstart + (w > 0)? w: 0; + w = (col_w - (image_w + text_w + off_w + MARGIN))/2; + x += (w > 0)? w: 0; break; } - int text_x = image_x + image_w; + int text_x = x + image_w; + if (i == GetMainColumn()) item->SetTextX (text_x); + + if (!HasFlag (wxTR_FULL_ROW_HIGHLIGHT)) { + if (i == GetMainColumn()) { + if (item == m_dragItem) { + dc.SetBrush (*m_hilightBrush); +#ifndef __WXMAC__ // don't draw rect outline if we already have the background color + dc.SetPen ((item == m_dragItem)? *wxBLACK_PEN: *wxTRANSPARENT_PEN); +#endif // !__WXMAC__ + dc.SetTextForeground (colTextHilight); + }else if (item->IsSelected()) { + if (!m_isDragging && m_hasFocus) { + dc.SetBrush (*m_hilightBrush); +#ifndef __WXMAC__ // don't draw rect outline if we already have the background color + dc.SetPen (*wxBLACK_PEN); +#endif // !__WXMAC__ + }else{ + dc.SetBrush (*m_hilightUnfocusedBrush); +#ifndef __WXMAC__ // don't draw rect outline if we already have the background color + dc.SetPen (*wxTRANSPARENT_PEN); +#endif // !__WXMAC__ + } + dc.SetTextForeground (colTextHilight); + }else if (item == m_curItem) { + dc.SetPen (m_hasFocus? *wxBLACK_PEN: *wxTRANSPARENT_PEN); + }else{ + dc.SetTextForeground (colText); + } + dc.DrawRectangle (text_x, item->GetY() + off_h, text_w, total_h - off_h); + }else{ + dc.SetTextForeground (colText); + } + } - if (item->IsSelected() && (i==GetMainColumn()) && !HasFlag(wxTR_FULL_ROW_HIGHLIGHT)) - { - dc.SetPen(*wxBLACK_PEN); - dc.SetBrush(*(m_hasFocus ? m_hilightBrush : m_hilightUnfocusedBrush)); - int offset = HasFlag (wxTR_ROW_LINES) ? 1 : 0; - int width = wxMin(text_w+2, colwidth - text_x - x_colstart); - dc.DrawRectangle(text_x-1, item->GetY() + offset, width, total_h-offset); - dc.SetBackgroundMode(wxTRANSPARENT); - dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT)); - }else{ - dc.SetTextForeground(colText); + if (HasFlag(wxTR_COLUMN_LINES)) { // vertical lines between columns +#if !wxCHECK_VERSION(2, 5, 0) + wxPen pen (wxSystemSettings::GetSystemColour (wxSYS_COLOUR_3DLIGHT ), 1, wxSOLID); +#else + wxPen pen (wxSystemSettings::GetColour (wxSYS_COLOUR_3DLIGHT ), 1, wxSOLID); +#endif + dc.SetPen ((GetBackgroundColour() == *wxWHITE)? pen: *wxWHITE_PEN); + dc.DrawLine (x_colstart+col_w-1, item->GetY(), x_colstart+col_w-1, item->GetY()+total_h); } - wxDCClipper clipper (dc, x_colstart, item->GetY(), colwidth, total_h); - if (image != NO_IMAGE) - { - int image_y = item->GetY() + img_extraH; - m_imageListNormal->Draw ( image, dc, image_x, image_y, - wxIMAGELIST_DRAW_TRANSPARENT ); + dc.SetBackgroundMode (wxTRANSPARENT); + + if (image != NO_IMAGE) { + int y = item->GetY() + img_extraH; + m_imageListNormal->Draw (image, dc, x, y, wxIMAGELIST_DRAW_TRANSPARENT ); } int text_y = item->GetY() + text_extraH; - dc.DrawText ( text, (wxCoord)text_x, (wxCoord)text_y ); + dc.DrawText (text, (wxCoord)text_x, (wxCoord)text_y); - x_colstart += colwidth; + x_colstart += col_w; } // restore normal font @@ -3394,39 +3040,37 @@ void wxTreeListMainWindow::PaintItem(wxTreeListItem *item, wxDC& dc) // Now y stands for the top of the item, whereas it used to stand for middle ! void wxTreeListMainWindow::PaintLevel (wxTreeListItem *item, wxDC &dc, - int level, int &y, int x_colstart ) -{ + int level, int &y, int x_maincol) { + // Handle hide root (only level 0) if (HasFlag(wxTR_HIDE_ROOT) && (level == 0)) { - // always expand hidden root wxArrayTreeListItems& children = item->GetChildren(); - int n; - for (n = 0; n < (int)children.Count(); n++) { - PaintLevel (children[n], dc, 1, y, x_colstart); + for (size_t n = 0; n < children.Count(); n++) { + PaintLevel (children[n], dc, 1, y, x_maincol); } // end after expanding root return; } // calculate position of vertical lines - int x = x_colstart + MARGIN; // start of column - if (HasFlag (wxTR_LINES_AT_ROOT)) x += LINEATROOT; // space for lines at root + int x = x_maincol + MARGIN; // start of column + if (HasFlag(wxTR_LINES_AT_ROOT)) x += LINEATROOT; // space for lines at root if (HasButtons()) { - x += m_btnWidth2; // middle of button + x += (m_btnWidth-m_btnWidth2); // half button space }else{ - if (m_imgWidth > 0) x += m_imgWidth2; // middle of image + x += (m_indent-m_indent/2); } - if (!HasFlag (wxTR_HIDE_ROOT)) { - x += m_indent * level; // indent according to level + if (HasFlag(wxTR_HIDE_ROOT)) { + x += m_indent * (level-1); // indent but not level 1 }else{ - if (level > 0) x += m_indent * (level-1); // but not level 1 + x += m_indent * level; // indent according to level } - // handle column text + // set position of vertical line item->SetX (x); item->SetY (y); - int h = GetLineHeight(item); + int h = GetLineHeight (item); int y_top = y; int y_mid = y_top + (h/2); y += h; @@ -3434,108 +3078,113 @@ void wxTreeListMainWindow::PaintLevel (wxTreeListItem *item, wxDC &dc, int exposed_x = dc.LogicalToDeviceX(0); int exposed_y = dc.LogicalToDeviceY(y_top); - if (IsExposed(exposed_x, exposed_y, 10000, h)) // 10000 = very much - { - // draw item - PaintItem(item, dc); + if (IsExposed(exposed_x, exposed_y, 10000, h)) { // 10000 = very much - if (HasFlag(wxTR_ROW_LINES)) - { + if (HasFlag(wxTR_ROW_LINES)) { // horizontal lines between rows //dc.DestroyClippingRegion(); int total_width = m_owner->GetHeaderWindow()->GetWidth(); // if the background colour is white, choose a // contrasting color for the lines - dc.SetPen(((GetBackgroundColour() == *wxWHITE) ? - wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT) : *wxWHITE_PEN)); - dc.DrawLine(0, y_top, total_width, y_top); - dc.DrawLine(0, y, total_width, y); +#if !wxCHECK_VERSION(2, 5, 0) + wxPen pen (wxSystemSettings::GetSystemColour (wxSYS_COLOUR_3DLIGHT ), 1, wxSOLID); +#else + wxPen pen (wxSystemSettings::GetColour (wxSYS_COLOUR_3DLIGHT ), 1, wxSOLID); +#endif + dc.SetPen ((GetBackgroundColour() == *wxWHITE)? pen: *wxWHITE_PEN); + dc.DrawLine (0, y_top, total_width, y_top); + dc.DrawLine (0, y_top+h, total_width, y_top+h); } + // draw item + PaintItem (item, dc); + // restore DC objects dc.SetBrush(*wxWHITE_BRUSH); dc.SetPen(m_dottedPen); - if (((level == 0) || ((level == 1) && HasFlag(wxTR_HIDE_ROOT))) && - HasFlag(wxTR_LINES_AT_ROOT) && !HasFlag(wxTR_NO_LINES)) { - int rootPos = x_colstart + MARGIN; - dc.DrawLine (rootPos, y_mid, rootPos+LINEATROOT, y_mid); - } - - size_t clip_width = m_owner->GetHeaderWindow()-> + // clip to the column width + int clip_width = m_owner->GetHeaderWindow()-> GetColumn(m_main_column).GetWidth(); + wxDCClipper clipper(dc, x_maincol, y_top, clip_width, 10000); - if (item->HasPlus() && HasButtons()) // should the item show a button? - { - // clip to the column width - wxDCClipper clipper(dc, x_colstart, y_top, clip_width, 10000); - - if ( !HasFlag(wxTR_NO_LINES) ) - { - // draw the horizontal line here - int x_start = x; - if (x > (signed)m_indent) - x_start -= m_indent; - else if (HasFlag(wxTR_LINES_AT_ROOT)) - x_start = 3; - dc.DrawLine(x_start, y_mid, x /*+ m_spacing*/, y_mid); + if (!HasFlag(wxTR_NO_LINES)) { // connection lines + + // draw the horizontal line here + dc.SetPen(m_dottedPen); + int x2 = x - m_indent; + if (x2 < (x_maincol + MARGIN)) x2 = x_maincol + MARGIN; + int x3 = x + (m_btnWidth-m_btnWidth2); + if (HasButtons()) { + if (item->HasPlus()) { + dc.DrawLine (x2, y_mid, x - m_btnWidth2, y_mid); + dc.DrawLine (x3, y_mid, x3 + LINEATROOT, y_mid); + }else{ + dc.DrawLine (x2, y_mid, x3 + LINEATROOT, y_mid); + } + }else{ + dc.DrawLine (x2, y_mid, x - m_indent/2, y_mid); } - - if (m_imageListButtons != NULL) - { + } + + if (item->HasPlus() && HasButtons()) { // should the item show a button? + + if (m_imageListButtons) { + // draw the image button here int image = wxTreeItemIcon_Normal; if (item->IsExpanded()) image = wxTreeItemIcon_Expanded; - if (item->IsSelected()) - image += wxTreeItemIcon_Selected - wxTreeItemIcon_Normal; - int xx = x + m_btnWidth2; + if (item->IsSelected()) image += wxTreeItemIcon_Selected - wxTreeItemIcon_Normal; + int xx = x - m_btnWidth2 + MARGIN; int yy = y_mid - m_btnHeight2; dc.SetClippingRegion(xx, yy, m_btnWidth, m_btnHeight); - m_imageListButtons->Draw(image, dc, xx, yy, - wxIMAGELIST_DRAW_TRANSPARENT); + m_imageListButtons->Draw (image, dc, xx, yy, wxIMAGELIST_DRAW_TRANSPARENT); dc.DestroyClippingRegion(); - } - else // no custom buttons - { - static const int wImage = 9; - static const int hImage = 9; - - int flag = 0; - if (item->IsExpanded()) - flag |= wxCONTROL_EXPANDED; - if (item == m_underMouse) - flag |= wxCONTROL_CURRENT; - - wxRendererNative::Get().DrawTreeItemButton( - this, dc, - wxRect(x - wImage/2, y_mid - hImage/2, wImage, hImage), - flag); - } - - if (!HasFlag(wxTR_NO_LINES)) { - if (/*!(level == 0) &&*/ !((level == 1) && HasFlag(wxTR_HIDE_ROOT))) { - if (m_imgWidth > 0) { - dc.DrawLine(x+m_btnWidth2, y_mid, x+m_indent-m_imgWidth2, y_mid); - }else{ - dc.DrawLine(x+m_btnWidth2, y_mid, x+m_btnWidth2+LINEATROOT-MARGIN, y_mid); - } - } - } - } - else if (!HasFlag(wxTR_NO_LINES)) // no button; maybe a line? - { - // clip to the column width - wxDCClipper clipper(dc, x_colstart, y_top, clip_width, 10000); - // draw the horizontal line here - if (/*!(level == 0) &&*/ !((level == 1) && HasFlag(wxTR_HIDE_ROOT))) { - int x2 = x - m_indent; - if (m_imgWidth > 0) { - dc.DrawLine(x2, y_mid, x2+m_indent-m_imgWidth2, y_mid); + }else if (HasFlag (wxTR_TWIST_BUTTONS)) { + + // draw the twisty button here + dc.SetPen(*wxBLACK_PEN); + dc.SetBrush(*m_hilightBrush); + wxPoint button[3]; + if (item->IsExpanded()) { + button[0].x = x - (m_btnWidth2+1); + button[0].y = y_mid - (m_btnHeight/3); + button[1].x = x + (m_btnWidth2+1); + button[1].y = button[0].y; + button[2].x = x; + button[2].y = button[0].y + (m_btnHeight2+1); }else{ - dc.DrawLine(x2, y_mid, x2+m_btnWidth2+LINEATROOT+MARGIN, y_mid); + button[0].x = x - (m_btnWidth/3); + button[0].y = y_mid - (m_btnHeight2+1); + button[1].x = button[0].x; + button[1].y = y_mid + (m_btnHeight2+1); + button[2].x = button[0].x + (m_btnWidth2+1); + button[2].y = y_mid; + } + dc.DrawPolygon(3, button); + + }else{ // if (HasFlag(wxTR_HAS_BUTTONS)) + + // draw the plus sign here +#if !wxCHECK_VERSION(2, 7, 0) + dc.SetPen(*wxGREY_PEN); + dc.SetBrush(*wxWHITE_BRUSH); + dc.DrawRectangle (x-m_btnWidth2, y_mid-m_btnHeight2, m_btnWidth, m_btnHeight); + dc.SetPen(*wxBLACK_PEN); + dc.DrawLine (x-(m_btnWidth2-2), y_mid, x+(m_btnWidth2-1), y_mid); + if (!item->IsExpanded()) { // change "-" to "+" + dc.DrawLine (x, y_mid-(m_btnHeight2-2), x, y_mid+(m_btnHeight2-1)); } +#else + wxRect rect (x-m_btnWidth2, y_mid-m_btnHeight2, m_btnWidth, m_btnHeight); + int flag = item->IsExpanded()? wxCONTROL_EXPANDED: 0; + wxRendererNative::GetDefault().DrawTreeItemButton (this, dc, rect, flag); +#endif + } + } + } // restore DC objects @@ -3546,110 +3195,48 @@ void wxTreeListMainWindow::PaintLevel (wxTreeListItem *item, wxDC &dc, if (item->IsExpanded()) { wxArrayTreeListItems& children = item->GetChildren(); - int count = children.Count(); - int n, oldY = 0; - // paint sublevel items first - for (n=0; n 0) - { - // clip to the column width - size_t clip_width = m_owner->GetHeaderWindow()->GetColumn(m_main_column).GetWidth(); - wxDCClipper clipper(dc, x_colstart, y_top, clip_width, 10000); - - // draw line down to last child - oldY += GetLineHeight(children[n-1]) >> 1; - if (HasButtons()) y_mid += 5; - dc.DrawLine(x, y_mid, x, oldY); - } - } -} + // clip to the column width + int clip_width = m_owner->GetHeaderWindow()-> + GetColumn(m_main_column).GetWidth(); -void wxTreeListMainWindow::DrawDropEffect(wxTreeListItem *item) -{ - if ( item ) - { - if ( item->HasPlus() ) - { - // it's a folder, indicate it by a border - DrawBorder(item); + // process lower levels + int oldY; + if (m_imgWidth > 0) { + oldY = y_mid + m_imgHeight2; + }else{ + oldY = y_mid + h/2; } - else - { - // draw a line under the drop target because the item will be - // dropped there - DrawLine(item, TRUE /* below */); + int y2; + for (size_t n = 0; n < children.Count(); ++n) { + + y2 = y + h/2; + PaintLevel (children[n], dc, level+1, y, x_maincol); + + // draw vertical line + wxDCClipper clipper(dc, x_maincol, y_top, clip_width, 10000); + if (!HasFlag (wxTR_NO_LINES)) { + x = item->GetX(); + dc.DrawLine (x, oldY, x, y2); + oldY = y2; + } } - - SetCursor(wxCURSOR_BULLSEYE); - } - else - { - // can't drop here - SetCursor(wxCURSOR_NO_ENTRY); } } -void wxTreeListMainWindow::DrawBorder(const wxTreeItemId &item) -{ - wxCHECK_RET( item.IsOk(), _T("invalid item in wxTreeListMainWindow::DrawLine") ); - - wxTreeListItem *i = (wxTreeListItem*) item.m_pItem; - - wxClientDC dc(this); - PrepareDC( dc ); - dc.SetLogicalFunction(wxINVERT); - dc.SetBrush(*wxTRANSPARENT_BRUSH); - - int w = i->GetWidth() + 2; - int h = GetLineHeight(i) + 2; - - dc.DrawRectangle( i->GetX() - 1, i->GetY() - 1, w, h); -} - -void wxTreeListMainWindow::DrawLine(const wxTreeItemId &item, bool below) -{ - wxCHECK_RET( item.IsOk(), _T("invalid item in wxTreeListMainWindow::DrawLine") ); - - wxTreeListItem *i = (wxTreeListItem*) item.m_pItem; - - wxClientDC dc(this); - PrepareDC( dc ); - dc.SetLogicalFunction(wxINVERT); - - int x = i->GetX(), - y = i->GetY(); - if ( below ) - { - y += GetLineHeight(i) - 1; - } - - dc.DrawLine( x, y, x + i->GetWidth(), y); -} // ---------------------------------------------------------------------------- // wxWindows callbacks // ---------------------------------------------------------------------------- -void wxTreeListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) -{ - wxPaintDC dc(this); +void wxTreeListMainWindow::OnPaint (wxPaintEvent &WXUNUSED(event)) { - PrepareDC( dc ); + wxPaintDC dc (this); + PrepareDC (dc); - if(!GetColumnCount()) return; // ALB - - if ( !m_anchor) - return; + if (!m_rootItem || (GetColumnCount() <= 0)) return; // calculate button size - m_btnWidth = 0, m_btnWidth2 = 0; - m_btnHeight = 0, m_btnHeight2 = 0; if (m_imageListButtons) { m_imageListButtons->GetSize (0, m_btnWidth, m_btnHeight); }else if (HasButtons()) { @@ -3660,351 +3247,260 @@ void wxTreeListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) m_btnHeight2 = m_btnHeight/2; // calculate image size - m_imgWidth = 0, m_imgWidth2 = 0; - m_imgHeight = 0, m_imgHeight2 = 0; if (m_imageListNormal) { m_imageListNormal->GetSize (0, m_imgWidth, m_imgHeight); - m_imgWidth += 4; //? ToDo: Why + 4? } m_imgWidth2 = m_imgWidth/2; m_imgHeight2 = m_imgHeight/2; // calculate indent size - int btnIndent = HasButtons()? m_btnWidth + LINEATROOT: 0; - m_indent = wxMax (MININDENT, wxMax (m_imgWidth, btnIndent)) + MARGIN; + if (m_imageListButtons) { + m_indent = wxMax (MININDENT, m_btnWidth + MARGIN); + }else if (HasButtons()) { + m_indent = wxMax (MININDENT, m_btnWidth + LINEATROOT); + } // set default values dc.SetFont( m_normalFont ); dc.SetPen( m_dottedPen ); - // this is now done dynamically - //if(GetImageList() == NULL) - // m_lineHeight = (int)(dc.GetCharHeight() + 4); - // calculate column start and paint - int x_colstart = 0; + int x_maincol = 0; int i = 0; for (i = 0; i < (int)GetMainColumn(); ++i) { - if (!m_owner->GetHeaderWindow()->GetColumnShown(i)) continue; - x_colstart += m_owner->GetHeaderWindow()->GetColumnWidth (i); + if (!m_owner->GetHeaderWindow()->IsColumnShown(i)) continue; + x_maincol += m_owner->GetHeaderWindow()->GetColumnWidth (i); } int y = 0; - PaintLevel ( m_anchor, dc, 0, y, x_colstart ); + PaintLevel (m_rootItem, dc, 0, y, x_maincol); } -void wxTreeListMainWindow::OnSetFocus( wxFocusEvent &event ) -{ - m_hasFocus = TRUE; +void wxTreeListMainWindow::OnSetFocus (wxFocusEvent &event) { + m_hasFocus = true; RefreshSelected(); - + if (m_curItem) RefreshLine (m_curItem); event.Skip(); } void wxTreeListMainWindow::OnKillFocus( wxFocusEvent &event ) { - m_hasFocus = FALSE; - + m_hasFocus = false; RefreshSelected(); - + if (m_curItem) RefreshLine (m_curItem); event.Skip(); } -void wxTreeListMainWindow::OnChar( wxKeyEvent &event ) -{ - wxTreeEvent te( wxEVT_COMMAND_TREE_KEY_DOWN, m_owner->GetId() ); - te.SetKeyEvent( event ); - te.SetEventObject( /*this*/m_owner ); - if ( m_owner->GetEventHandler()->ProcessEvent( te ) ) - { - // intercepted by the user code - return; - } +void wxTreeListMainWindow::OnChar (wxKeyEvent &event) { + // send event to user code + wxTreeEvent nevent (wxEVT_COMMAND_TREE_KEY_DOWN, m_owner->GetId()); + nevent.SetKeyEvent (event); + nevent.SetEventObject (m_owner); + if (m_owner->GetEventHandler()->ProcessEvent (nevent)) return; // handled in user code - if ( !m_current ) - { + // determine first current if none + bool curItemSet = false; + if (!m_curItem) { + m_curItem = (wxTreeListItem*)GetRootItem().m_pItem; if (HasFlag(wxTR_HIDE_ROOT)) { #if !wxCHECK_VERSION(2, 5, 0) long cookie = 0; #else wxTreeItemIdValue cookie = 0; #endif - m_current = m_key_current = (wxTreeListItem*)GetFirstChild (GetRootItem().m_pItem, cookie).m_pItem; - } - else - { - m_current = m_key_current = (wxTreeListItem*)GetRootItem().m_pItem; + m_curItem = (wxTreeListItem*)GetFirstChild (m_curItem, cookie).m_pItem; } + curItemSet = true; } + if (!m_curItem) return; // do nothing if empty tree - // how should the selection work for this event? - bool is_multiple, extended_select, unselect_others; - EventFlagsToSelType(GetWindowStyleFlag(), - event.ShiftDown(), - event.ControlDown(), - is_multiple, extended_select, unselect_others); - - // + : Expand (not on Win32) - // - : Collaspe (not on Win32) - // * : Expand all/Collapse all - // ' ' | return : activate - // up : go up (not last children!) - // down : go down - // left : go to parent (or collapse on Win32) - // right : open if parent and go next (or expand on Win32) - // home : go to root - // end : go to last item without opening parents - switch (event.GetKeyCode()) - { -#ifndef __WXMSW__ // mimic the standard win32 tree ctrl - case '+': - case WXK_ADD: - if (m_current->HasPlus() && !IsExpanded(m_current)) - { - Expand (m_current); - } - break; -#endif // __WXMSW__ + // remember item at shift down + if (HasFlag(wxTR_MULTIPLE) && event.ShiftDown()) { + if (!m_shiftItem) m_shiftItem = m_curItem; + }else{ + m_shiftItem = (wxTreeListItem*)NULL; + } - case '*': - case WXK_MULTIPLY: - if ( !IsExpanded(m_current) ) - { - // expand all - ExpandAll (m_current); - break; - } - //else: fall through to Collapse() it + // process all cases + wxTreeItemId newItem = (wxTreeItemId*)NULL; + switch (event.GetKeyCode()) { + + // '+': Expand subtree + case '+': + case WXK_ADD: { + if (m_curItem->HasPlus() && !IsExpanded (m_curItem)) Expand (m_curItem); + }break; -#ifndef __WXMSW__ // mimic the standard wxTreeCtrl behaviour + // '-': collapse subtree case '-': - case WXK_SUBTRACT: - if (IsExpanded(m_current)) - { - Collapse (m_current); - } - break; -#endif // __WXMSW__ - - case ' ': - case WXK_RETURN: - { - wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_ACTIVATED, - m_owner->GetId() ); - event.SetItem( (void*) m_current); - event.SetEventObject( /*this*/m_owner ); - m_owner->GetEventHandler()->ProcessEvent( event ); - } - break; + case WXK_SUBTRACT: { + if (m_curItem->HasPlus() && IsExpanded (m_curItem)) Collapse (m_curItem); + }break; - // backspace goes to the parent, sends "root" activation - case WXK_BACK: - { - wxTreeItemId prev = GetItemParent( m_current ); - if ((prev == GetRootItem()) && HasFlag(wxTR_HIDE_ROOT)) - { - // don't go to root if it is hidden - prev = GetPrevSibling( m_current ); - } - if (prev) - { - SelectItem( prev, unselect_others, extended_select ); - EnsureVisible( prev ); - } + // '*': expand/collapse all subtrees // TODO: Mak it more useful + case '*': + case WXK_MULTIPLY: { + if (m_curItem->HasPlus() && !IsExpanded (m_curItem)) { + ExpandAll (m_curItem); + }else if (m_curItem->HasPlus()) { + Collapse (m_curItem); // TODO: CollapseAll } - break; + }break; - // up goes to the previous sibling or to the last - // of its children if it's expanded - case WXK_UP: - { - wxTreeItemId prev = GetPrevSibling( m_key_current ); - if (!prev) - { - prev = GetItemParent( m_key_current ); - if ((prev == GetRootItem()) && HasFlag(wxTR_HIDE_ROOT)) - { - break; // don't go to root if it is hidden - } - if (prev) - { + // ' ': toggle current item + case ' ': { + SelectItem (m_curItem, (wxTreeListItem*)NULL, false); + }break; + + // : activate current item + case WXK_RETURN: { + wxTreeEvent aevent (wxEVT_COMMAND_TREE_ITEM_ACTIVATED, m_owner->GetId()); #if !wxCHECK_VERSION(2, 5, 0) - long cookie = 0; + aevent.SetItem ((long)m_curItem); #else - wxTreeItemIdValue cookie = 0; + aevent.SetItem (m_curItem); #endif - wxTreeItemId current = m_key_current; - // TODO: Huh? If we get here, we'd better be the first child of our parent. How else could it be? - if (current == GetFirstChild( prev, cookie )) - { - // otherwise we return to where we came from - SelectItem( prev, unselect_others, extended_select ); - m_key_current= (wxTreeListItem*) prev.m_pItem; - EnsureVisible( prev ); - break; - } - } - } - if (prev) - { - while ( IsExpanded(prev) && HasChildren(prev) ) - { - wxTreeItemId child = GetLastChild(prev); - if ( !child ) - { - break; - } - prev = child; - } - - SelectItem( prev, unselect_others, extended_select ); - m_key_current=(wxTreeListItem*) prev.m_pItem; - EnsureVisible( prev ); - } - } - break; - - // left arrow goes to the parent - case WXK_LEFT: - if (IsExpanded(m_current)) - { - Collapse(m_current); - } - else - { - wxTreeItemId prev = GetItemParent( m_current ); - if ((prev == GetRootItem()) && HasFlag(wxTR_HIDE_ROOT)) - { - // don't go to root if it is hidden - prev = GetPrevSibling( m_current ); - } - if (prev) - { - SelectItem( prev, unselect_others, extended_select ); - EnsureVisible( prev ); - } - } - break; - - case WXK_RIGHT: -#if defined(__WXMSW__) // mimic the standard win32 tree ctrl - if (m_current->HasPlus() && !IsExpanded(m_current)) - { - Expand(m_current); - break; + aevent.SetEventObject (m_owner); + m_owner->GetEventHandler()->ProcessEvent (aevent); + }break; + + // : go to the parent without collapsing + case WXK_BACK: { + newItem = GetItemParent (m_curItem); + if ((newItem == GetRootItem()) && HasFlag(wxTR_HIDE_ROOT)) { + newItem = GetPrevSibling (m_curItem); // get sibling instead of root } -#endif // __WXMSW__ + }break; - // this works the same as the down arrow except that we - // also expand the item if it wasn't expanded yet - Expand(m_current); - // fall through - - case WXK_DOWN: - { - if (IsExpanded(m_key_current) && HasChildren(m_key_current)) - { + // : go to the previous sibling or to the last of its children, to the parent + case WXK_UP: { + newItem = GetPrevSibling (m_curItem); + if (newItem) { #if !wxCHECK_VERSION(2, 5, 0) - long cookie = 0; + long cookie = 0; #else - wxTreeItemIdValue cookie = 0; + wxTreeItemIdValue cookie = 0; #endif - wxTreeItemId child = GetFirstChild( m_key_current, cookie ); - if (child) { - SelectItem( child, unselect_others, extended_select ); - m_key_current=(wxTreeListItem*) child.m_pItem; - EnsureVisible( child ); - break; - } - } - wxTreeItemId next = GetNextSibling( m_key_current ); - if (!next) - { - wxTreeItemId current = m_key_current; - while (current && !next) - { - current = GetItemParent( current ); - if (current) next = GetNextSibling( current ); - } + while (IsExpanded (newItem) && HasChildren (newItem)) { + newItem = GetLastChild (newItem, cookie); } - if (next) - { - SelectItem( next, unselect_others, extended_select ); - m_key_current=(wxTreeListItem*) next.m_pItem; - EnsureVisible( next ); + }else { + newItem = GetItemParent (m_curItem); + if ((newItem == GetRootItem()) && HasFlag(wxTR_HIDE_ROOT)) { + newItem = (wxTreeItemId*)NULL; // don't go to root if it is hidden } } - break; - - // selects the last visible tree item - case WXK_END: - { - wxTreeItemId last = GetRootItem(); - - while ( last.IsOk() && IsExpanded(last) ) - { - wxTreeItemId lastChild = GetLastChild(last); - - // it may happen if the item was expanded but then all of - // its children have been deleted - so IsExpanded() returned - // TRUE, but GetLastChild() returned invalid item - if ( !lastChild ) - break; + }break; - last = lastChild; + // : if expanded collapse subtree, else go to the parent + case WXK_LEFT: { + if (IsExpanded (m_curItem)) { + Collapse (m_curItem); + }else{ + newItem = GetItemParent (m_curItem); + if ((newItem == GetRootItem()) && HasFlag(wxTR_HIDE_ROOT)) { + newItem = GetPrevSibling (m_curItem); // go to sibling if it is hidden } + } + }break; - if ( last.IsOk() ) - { - SelectItem( last, unselect_others, extended_select ); - EnsureVisible( last ); + // : if possible expand subtree, else go go to the first child + case WXK_RIGHT: { + if (m_curItem->HasPlus() && !IsExpanded (m_curItem)) { + Expand (m_curItem); + }else{ + if (IsExpanded (m_curItem) && HasChildren (m_curItem)) { +#if !wxCHECK_VERSION(2, 5, 0) + long cookie = 0; +#else + wxTreeItemIdValue cookie = 0; +#endif + newItem = GetFirstChild (m_curItem, cookie); } } - break; + }break; - // selects the root item - case WXK_HOME: - { - wxTreeItemId prev = GetRootItem(); - if (!prev) break; - if (HasFlag(wxTR_HIDE_ROOT)) - { + // : if expanded go to the first child, else to the next sibling, ect + case WXK_DOWN: { + if (curItemSet) { + newItem = m_curItem; + }else{ + if (IsExpanded (m_curItem) && HasChildren (m_curItem)) { #if !wxCHECK_VERSION(2, 5, 0) long cookie = 0; #else wxTreeItemIdValue cookie = 0; #endif - prev = GetFirstChild(prev, cookie); - if (!prev) break; + newItem = GetFirstChild( m_curItem, cookie ); + } + if (!newItem) { + wxTreeItemId parent = m_curItem; + do { + newItem = GetNextSibling (parent); + parent = GetItemParent (parent); + } while (!newItem && parent); } - SelectItem( prev, unselect_others, extended_select ); - EnsureVisible( prev ); } - break; + }break; + + // : go to last item of the root + case WXK_END: { +#if !wxCHECK_VERSION(2, 5, 0) + long cookie = 0; +#else + wxTreeItemIdValue cookie = 0; +#endif + newItem = GetLastChild (GetRootItem(), cookie); + }break; + + // : go to root + case WXK_HOME: { + newItem = GetRootItem(); + if (HasFlag(wxTR_HIDE_ROOT)) { +#if !wxCHECK_VERSION(2, 5, 0) + long cookie = 0; +#else + wxTreeItemIdValue cookie = 0; +#endif + newItem = GetFirstChild (newItem, cookie); + } + }break; + // any char: go to the next matching string default: - if (event.m_keyCode >= (int)' ') { + if (event.GetKeyCode() >= (int)' ') { if (!m_findTimer->IsRunning()) m_findStr.Clear(); - m_findStr.Append (event.m_keyCode); - m_findTimer->Start (500, wxTIMER_ONE_SHOT); - wxTreeItemId dummy = (wxTreeItemId*)NULL; - wxTreeItemId item = FindItem (dummy, m_findStr, wxTL_SEARCH_VISIBLE | - wxTL_SEARCH_PARTIAL | - wxTL_SEARCH_NOCASE); - if (item.IsOk()) { - EnsureVisible (item); - SelectItem (item); - } + m_findStr.Append (event.GetKeyCode()); + m_findTimer->Start (FIND_TIMER_TICKS, wxTIMER_ONE_SHOT); + wxTreeItemId prev = m_curItem? (wxTreeItemId*)m_curItem: (wxTreeItemId*)NULL; + while (true) { + newItem = FindItem (prev, m_findStr, wxTL_MODE_NAV_EXPANDED | + wxTL_MODE_FIND_PARTIAL | + wxTL_MODE_FIND_NOCASE); + if (newItem || (m_findStr.Length() <= 1)) break; + m_findStr.RemoveLast(); + }; } event.Skip(); + } + + // select and show the new item + if (newItem) { + if (!event.ControlDown()) { + bool unselect_others = !((event.ShiftDown() || event.ControlDown()) && + HasFlag(wxTR_MULTIPLE)); + SelectItem (newItem, m_shiftItem, unselect_others); + } + EnsureVisible (newItem); + wxTreeListItem *oldItem = m_curItem; + m_curItem = (wxTreeListItem*)newItem.m_pItem; // make the new item the current item + RefreshLine (oldItem); + } + } -wxTreeItemId wxTreeListMainWindow::HitTest(const wxPoint& point, int& flags, - int& column) -{ - // JACS: removed wxYieldIfNeeded() because it can cause the window - // to be deleted from under us if a close window event is pending +wxTreeItemId wxTreeListMainWindow::HitTest (const wxPoint& point, int& flags, int& column) { int w, h; GetSize(&w, &h); @@ -4016,403 +3512,341 @@ wxTreeItemId wxTreeListMainWindow::HitTest(const wxPoint& point, int& flags, if (point.y>h) flags |= wxTREE_HITTEST_BELOW; if (flags) return wxTreeItemId(); - if (m_anchor == NULL) - { + if (!m_rootItem) { flags = wxTREE_HITTEST_NOWHERE; + column = -1; return wxTreeItemId(); } - wxTreeListItem *hit = m_anchor->HitTest(CalcUnscrolledPosition(point), - this, flags, column, 0); - if (hit == NULL) - { + wxTreeListItem *hit = m_rootItem->HitTest (CalcUnscrolledPosition(point), + this, flags, column, 0); + if (!hit) { flags = wxTREE_HITTEST_NOWHERE; + column = -1; return wxTreeItemId(); } return hit; } // get the bounding rectangle of the item (or of its label only) -bool wxTreeListMainWindow::GetBoundingRect(const wxTreeItemId& item, - wxRect& rect, - bool WXUNUSED(textOnly)) const -{ - wxCHECK_MSG( item.IsOk(), FALSE, _T("invalid item in wxTreeListMainWindow::GetBoundingRect") ); +bool wxTreeListMainWindow::GetBoundingRect (const wxTreeItemId& itemId, wxRect& rect, + bool WXUNUSED(textOnly)) const { + wxCHECK_MSG (itemId.IsOk(), false, _T("invalid item in wxTreeListMainWindow::GetBoundingRect") ); - wxTreeListItem *i = (wxTreeListItem*) item.m_pItem; + wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem; + int xUnit, yUnit; + GetScrollPixelsPerUnit (&xUnit, &yUnit); int startX, startY; GetViewStart(& startX, & startY); - rect.x = i->GetX() - startX*PIXELS_PER_UNIT; - rect.y = i->GetY() - startY*PIXELS_PER_UNIT; - rect.width = i->GetWidth(); - //rect.height = i->GetHeight(); - rect.height = GetLineHeight(i); + rect.x = item->GetX() - startX * xUnit; + rect.y = item->GetY() - startY * yUnit; + rect.width = item->GetWidth(); + rect.height = GetLineHeight (item); - return TRUE; + return true; } /* **** */ -void wxTreeListMainWindow::Edit( const wxTreeItemId& item ) -{ +void wxTreeListMainWindow::EditLabel (const wxTreeItemId& item, int column) { if (!item.IsOk()) return; + if (!((column >= 0) && (column < GetColumnCount()))) return; - m_currentEdit = (wxTreeListItem*) item.m_pItem; + m_editItem = (wxTreeListItem*) item.m_pItem; wxTreeEvent te( wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT, m_owner->GetId() ); - te.SetItem( (void*) m_currentEdit); - te.SetEventObject( /*this*/m_owner ); - m_owner->GetEventHandler()->ProcessEvent( te ); +#if !wxCHECK_VERSION(2, 5, 0) + te.SetItem ((long)m_editItem); +#else + te.SetItem (m_editItem); +#endif + te.SetInt (column); + te.SetEventObject (m_owner ); + m_owner->GetEventHandler()->ProcessEvent (te); if (!te.IsAllowed()) return; - // We have to call this here because the label in - // question might just have been added and no screen - // update taken place. - if (m_dirty) - DoDirtyProcessing(); - - wxString s = m_currentEdit->GetText(/*ALB*/m_main_column); - int x = m_currentEdit->GetX() + m_imgWidth2; - int y = m_currentEdit->GetY(); - int w = wxMin (m_currentEdit->GetWidth(), - m_owner->GetHeaderWindow()->GetWidth()) - m_imgWidth2; - int h = m_currentEdit->GetHeight() + 2; - wxClientDC dc(this); - PrepareDC( dc ); - x = dc.LogicalToDeviceX( x ); - y = dc.LogicalToDeviceY( y ); - - wxTreeListTextCtrl *text = new wxTreeListTextCtrl(this, -1, - &m_renameAccept, - &m_renameRes, - this, - s, - wxPoint (x,y), - wxSize (w,h)); + // ensure that the position of the item it calculated in any case + if (m_dirty) CalculatePositions(); + + wxTreeListHeaderWindow* header_win = m_owner->GetHeaderWindow(); + int x = 0; + int y = m_editItem->GetY() + 1; // wxTextCtrl needs 1 pixels above the text + int w = 0; + int h = m_editItem->GetHeight(); + long style = 0; + if (column == GetMainColumn()) { + x += m_editItem->GetTextX() - 2; // wxTextCtrl needs 2 pixels before the text + w = wxMin (m_editItem->GetWidth(), m_owner->GetHeaderWindow()->GetWidth() - x); + }else{ + for (int i = 0; i < column; ++i) x += header_win->GetColumnWidth (i); // start of column + switch (header_win->GetColumnAlignment (column)) { + case wxALIGN_LEFT: {style = wxTE_LEFT; break;} + case wxALIGN_RIGHT: {style = wxTE_RIGHT; break;} + case wxALIGN_CENTER: {style = wxTE_CENTER; break;} + } + w = header_win->GetColumnWidth (column); // width of column + } + + wxClientDC dc (this); + PrepareDC (dc); + x = dc.LogicalToDeviceX (x); + y = dc.LogicalToDeviceY (y); + + wxEditTextCtrl *text = new wxEditTextCtrl (this, -1, &m_renameAccept, &m_renameRes, + this, m_editItem->GetText (column), + wxPoint (x, y), wxSize (w, h), style); text->SetFocus(); } -void wxTreeListMainWindow::OnRenameTimer() -{ - Edit( m_current ); +void wxTreeListMainWindow::OnRenameTimer() { + EditLabel (m_curItem, m_curColumn); } -void wxTreeListMainWindow::OnRenameAccept() -{ +void wxTreeListMainWindow::OnRenameAccept() { + // TODO if the validator fails this causes a crash wxTreeEvent le( wxEVT_COMMAND_TREE_END_LABEL_EDIT, m_owner->GetId() ); - le.SetItem( (void*)m_currentEdit ); +#if !wxCHECK_VERSION(2, 5, 0) + le.SetItem((long)m_editItem); +#else + le.SetItem(m_editItem); +#endif le.SetEventObject( /*this*/m_owner ); le.SetLabel( m_renameRes ); m_owner->GetEventHandler()->ProcessEvent( le ); if (!le.IsAllowed()) return; - SetItemText( m_currentEdit, m_renameRes ); + SetItemText (m_editItem, m_curColumn, m_renameRes); } -void wxTreeListMainWindow::OnMouse( wxMouseEvent &event ) -{ - if ( !m_anchor ) return; - - wxPoint pt = CalcUnscrolledPosition(event.GetPosition()); - - // Is the mouse over a tree item button? - int flags = 0; - wxTreeListItem *item = m_anchor->HitTest(pt, this, flags, 0); - wxTreeListItem *underMouse = item; -#if wxUSE_TOOLTIPS - bool underMouseChanged = (underMouse != m_underMouse) ; -#endif // wxUSE_TOOLTIPS - - if (underMouse && (flags & wxTREE_HITTEST_ONITEMBUTTON) && - !event.LeftIsDown() && !m_isDragging && - (!m_renameTimer || !m_renameTimer->IsRunning())) - { - } - else - { - underMouse = NULL; - } - - if (underMouse != m_underMouse) - { - if (m_underMouse) - { - // unhighlight old item - wxTreeListItem *tmp = m_underMouse; - m_underMouse = NULL; - RefreshLine( tmp ); - } - - m_underMouse = underMouse; - if (m_underMouse) - RefreshLine( m_underMouse ); - } - -#if wxUSE_TOOLTIPS - // Determines what item we are hovering over and need a tooltip for - wxTreeItemId hoverItem = item; - - // We do not want a tooltip if we are dragging, or if the rename timer is running - if (underMouseChanged && hoverItem.IsOk() && !m_isDragging && (!m_renameTimer || !m_renameTimer->IsRunning())) - { - // Ask the tree control what tooltip (if any) should be shown - wxTreeEvent hevent(wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP, GetId()); - hevent.SetItem(hoverItem); - hevent.SetEventObject(this); - - if ( GetEventHandler()->ProcessEvent(hevent) && hevent.IsAllowed() ) - { - SetToolTip(hevent.GetLabel()); - } - } -#endif +void wxTreeListMainWindow::OnMouse (wxMouseEvent &event) { + if (!m_rootItem) return; // we process left mouse up event (enables in-place edit), right down // (pass to the user code), left dbl click (activate item) and // dragging/moving events for items drag-and-drop - if ( !(event.LeftDown() || - event.LeftUp() || - event.RightDown() || - event.LeftDClick() || - event.Dragging() || - ((event.Moving() || event.RightUp()) && m_isDragging)) ) - { - event.Skip(); + if (!(event.LeftDown() || + event.LeftUp() || + event.RightDown() || + event.RightUp() || + event.LeftDClick() || + event.Dragging() || + (event.GetWheelRotation() != 0 )/*? TODO || + event.Moving()?*/)) { + m_owner->GetEventHandler()->ProcessEvent (event); return; } - if ( event.LeftDown() ) - SetFocus(); - -// wxClientDC dc(this); -// PrepareDC(dc); -// wxCoord x = dc.DeviceToLogicalX( event.GetX() ); -// wxCoord y = dc.DeviceToLogicalY( event.GetY() ); - wxCoord &x = pt.x; - wxCoord &y = pt.y; + // set focus if window clicked + if (event.LeftDown() || event.RightDown()) SetFocus(); - if ( event.Dragging() && !m_isDragging ) - { - if (m_dragCount == 0) - m_dragStart = wxPoint(x,y); + // determine event + wxPoint p = wxPoint (event.GetX(), event.GetY()); + int flags = 0; + wxTreeListItem *item = m_rootItem->HitTest (CalcUnscrolledPosition (p), + this, flags, m_curColumn, 0); - m_dragCount++; + // we only process dragging here + if (event.Dragging()){ + if (m_isDragging) return; // nothing to do, already done + if (item == NULL) return; // we need an item to dragging - if (m_dragCount != 3) - { - // wait until user drags a bit further... - return; + // determine drag start + if (m_dragCount == 0) { + m_dragTimer->Start (DRAG_TIMER_TICKS, wxTIMER_ONE_SHOT); } + m_dragCount++; + if (m_dragCount < 3) return; // minimum drag 3 pixel + if (m_dragTimer->IsRunning()) return; - wxEventType command = event.RightIsDown() - ? wxEVT_COMMAND_TREE_BEGIN_RDRAG - : wxEVT_COMMAND_TREE_BEGIN_DRAG; + // we're going to drag + m_dragCount = 0; + m_isDragging = true; + CaptureMouse(); + RefreshSelected(); + + // send drag start event + wxEventType command = event.LeftIsDown() + ? wxEVT_COMMAND_TREE_BEGIN_DRAG + : wxEVT_COMMAND_TREE_BEGIN_RDRAG; + wxTreeEvent nevent (command, m_owner->GetId()); + nevent.SetEventObject (m_owner); +#if !wxCHECK_VERSION(2, 5, 0) + nevent.SetItem ((long)item); // the item the drag is ended +#else + nevent.SetItem (item); // the item the drag is ended +#endif + nevent.Veto(); // dragging must be explicit allowed! + m_owner->GetEventHandler()->ProcessEvent (nevent); - wxTreeEvent nevent( command,/*ALB*/ m_owner->GetId() ); - nevent.SetItem( (void*)m_current); - nevent.SetEventObject(/*this*/m_owner); // ALB - nevent.SetPoint(pt); + }else if (m_isDragging) { // any other event but not event.Dragging() - // by default the dragging is not supported, the user code must - // explicitly allow the event for it to take place - nevent.Veto(); + // end dragging + m_dragCount = 0; + m_isDragging = false; + if (HasCapture()) ReleaseMouse(); + RefreshSelected(); - if ( m_owner->GetEventHandler()->ProcessEvent(nevent) && - nevent.IsAllowed() ) - { - // we're going to drag this item - m_isDragging = TRUE; - - // remember the old cursor because we will change it while - // dragging - m_oldCursor = m_cursor; - - // in a single selection control, hide the selection temporarily - if ( !(GetWindowStyleFlag() & wxTR_MULTIPLE) ) - { - m_oldSelection = (wxTreeListItem*) GetSelection().m_pItem; - - if ( m_oldSelection ) - { - m_oldSelection->SetHilight(FALSE); - RefreshLine(m_oldSelection); - } - } + // send drag end event event + wxTreeEvent nevent (wxEVT_COMMAND_TREE_END_DRAG, m_owner->GetId()); + nevent.SetEventObject (m_owner); +#if !wxCHECK_VERSION(2, 5, 0) + nevent.SetItem ((long)item); // the item the drag is started +#else + nevent.SetItem (item); // the item the drag is started +#endif + nevent.SetPoint (p); + m_owner->GetEventHandler()->ProcessEvent (nevent); - CaptureMouse(); - } - } - else if ( event.Moving() ) - { - if ( item != m_dropTarget ) - { - // unhighlight the previous drop target - DrawDropEffect(m_dropTarget); + }else if (m_dragCount > 0) { // just in case dragging is initiated - m_dropTarget = item; + // end dragging + m_dragCount = 0; - // highlight the current drop target if any - DrawDropEffect(m_dropTarget); + } - DoDirtyProcessing(); - } + // we process only the messages which happen on tree items + if (item == NULL) { + m_owner->GetEventHandler()->ProcessEvent (event); + return; } - else if ( (event.LeftUp() || event.RightUp()) && m_isDragging ) - { - // erase the highlighting - DrawDropEffect(m_dropTarget); - if ( m_oldSelection ) - { - m_oldSelection->SetHilight(TRUE); - RefreshLine(m_oldSelection); - m_oldSelection = (wxTreeListItem *)NULL; - } + // remember item at shift down + if (event.ShiftDown()) { + if (!m_shiftItem) m_shiftItem = m_curItem; + }else{ + m_shiftItem = (wxTreeListItem*)NULL; + } - // generate the drag end event - wxTreeEvent event(wxEVT_COMMAND_TREE_END_DRAG,/*ALB*/m_owner->GetId()); + if (event.RightUp()) { - event.SetItem( (void*)item ); - event.SetPoint( wxPoint(x, y) ); - event.SetEventObject(/*this*/m_owner); + SetFocus(); + wxTreeEvent nevent (wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK, m_owner->GetId()); + nevent.SetEventObject (m_owner); +#if !wxCHECK_VERSION(2, 5, 0) + nevent.SetItem ((long)item); // the item clicked +#else + nevent.SetItem (item); // the item clicked +#endif + nevent.SetInt (m_curColumn); // the colum clicked + nevent.SetPoint (p); + m_owner->GetEventHandler()->ProcessEvent (nevent); - (void)m_owner->GetEventHandler()->ProcessEvent(event); + }else if (event.LeftUp()) { - m_isDragging = FALSE; - m_dropTarget = (wxTreeListItem *)NULL; + if (m_lastOnSame) { + if ((item == m_curItem) && (m_curColumn != -1) && + (m_owner->GetHeaderWindow()->IsColumnEditable (m_curColumn)) && + (flags & (wxTREE_HITTEST_ONITEMLABEL | wxTREE_HITTEST_ONITEMCOLUMN))){ + m_renameTimer->Start (RENAME_TIMER_TICKS, wxTIMER_ONE_SHOT); + } + m_lastOnSame = false; + } - ReleaseMouse(); + if (((flags & wxTREE_HITTEST_ONITEMBUTTON) || + (flags & wxTREE_HITTEST_ONITEMICON)) && + HasButtons() && item->HasPlus()) { - SetCursor(m_oldCursor); + // only toggle the item for a single click, double click on + // the button doesn't do anything (it toggles the item twice) + if (event.LeftDown()) Toggle (item); - DoDirtyProcessing(); - } - else - { - // here we process only the messages which happen on tree items + // don't select the item if the button was clicked + return; + } - m_dragCount = 0; + // determine the selection if not done by left down + if (!m_left_down_selection) { + bool unselect_others = !((event.ShiftDown() || event.ControlDown()) && + HasFlag(wxTR_MULTIPLE)); + SelectItem (item, m_shiftItem, unselect_others); + EnsureVisible (item); + m_curItem = item; // make the new item the current item + }else{ + m_left_down_selection = false; + } - if ( item == NULL ) return; /* we hit the blank area */ + }else if (event.LeftDown() || event.RightDown() || event.LeftDClick()) { - if ( event.RightDown() ) - { + if (event.LeftDown() || event.RightDown()) { SetFocus(); - wxTreeEvent nevent(wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK, - m_owner->GetId()); - nevent.SetItem( (void*)item ); - int nx, ny; - CalcScrolledPosition(x, y, &nx, &ny); - nevent.SetPoint( wxPoint(nx, ny)); - nevent.SetEventObject(/*this*/m_owner); - m_owner->GetEventHandler()->ProcessEvent(nevent); + m_lastOnSame = item == m_curItem; } - else if ( event.LeftUp() ) - { - if ( m_lastOnSame ) - { - if ( ( item == m_current ) && - ( flags & wxTREE_HITTEST_ONITEMLABEL ) && - HasFlag(wxTR_EDIT_LABELS ) ) - { - if ( m_renameTimer->IsRunning() ) - m_renameTimer->Stop(); - - m_renameTimer->Start( 100, TRUE ); - } - m_lastOnSame = FALSE; - } + if (((flags & wxTREE_HITTEST_ONITEMBUTTON) || + (flags & wxTREE_HITTEST_ONITEMICON)) && + item->HasPlus()) { + + // only toggle the item for a single click, double click on + // the button doesn't do anything (it toggles the item twice) + if (event.LeftDown()) Toggle (item); + + // don't select the item if the button was clicked + return; } - else // !RightDown() && !LeftUp() ==> LeftDown() || LeftDClick() - { - if ( event.LeftDown() ) - { - SetFocus(); - m_lastOnSame = item == m_current; - } - if ((flags & wxTREE_HITTEST_ONITEMBUTTON) || - ((flags & wxTREE_HITTEST_ONITEMICON)) && - !HasButtons() && item->HasPlus()) - { - // only toggle the item for a single click, double click on - // the button doesn't do anything (it toggles the item twice) - if ( event.LeftDown() ) - { - Toggle( item ); - } + // determine the selection if the current item is not selected + if (!item->IsSelected()) { + bool unselect_others = !((event.ShiftDown() || event.ControlDown()) && + HasFlag(wxTR_MULTIPLE)); + SelectItem (item, m_shiftItem, unselect_others); + EnsureVisible (item); + m_curItem = item; // make the new item the current item + m_left_down_selection = true; + } - // don't select the item if the button was clicked - return; - } + // For some reason, Windows isn't recognizing a left double-click, + // so we need to simulate it here. Allow 200 milliseconds for now. + if (event.LeftDClick()) { - // how should the selection work for this event? - bool is_multiple, extended_select, unselect_others; - EventFlagsToSelType(GetWindowStyleFlag(), - event.ShiftDown(), - event.ControlDown(), - is_multiple, extended_select, unselect_others); - - SelectItem (item, unselect_others, extended_select); - - // For some reason, Windows isn't recognizing a left double-click, - // so we need to simulate it here. Allow 200 milliseconds for now. - if ( event.LeftDClick() ) - { - // double clicking should not start editing the item label - m_renameTimer->Stop(); - m_lastOnSame = FALSE; - - // send activate event first - wxTreeEvent nevent( wxEVT_COMMAND_TREE_ITEM_ACTIVATED, - m_owner->GetId() ); - nevent.SetItem( (void*)item ); - int nx, ny; - CalcScrolledPosition(x, y, &nx, &ny); - nevent.SetPoint( wxPoint(nx, ny) ); - nevent.SetEventObject( /*this*/m_owner ); - if ( !m_owner->GetEventHandler()->ProcessEvent( nevent ) ) - { - // if the user code didn't process the activate event, - // handle it ourselves by toggling the item when it is - // double clicked - if ( item->HasPlus() ) - { - Toggle(item); - } - } + // double clicking should not start editing the item label + m_renameTimer->Stop(); + m_lastOnSame = false; + + // send activate event first + wxTreeEvent nevent (wxEVT_COMMAND_TREE_ITEM_ACTIVATED, m_owner->GetId()); + nevent.SetEventObject (m_owner); +#if !wxCHECK_VERSION(2, 5, 0) + nevent.SetItem ((long)item); // the item clicked +#else + nevent.SetItem (item); // the item clicked +#endif + nevent.SetInt (m_curColumn); // the colum clicked + nevent.SetPoint (p); + if (!m_owner->GetEventHandler()->ProcessEvent (nevent)) { + + // if the user code didn't process the activate event, + // handle it ourselves by toggling the item when it is + // double clicked + if (item->HasPlus()) Toggle(item); } } - } -} -void wxTreeListMainWindow::OnIdle( wxIdleEvent &WXUNUSED(event) ) -{ - DoDirtyProcessing(); + }else{ // any other event skip just in case + + event.Skip(); + + } } -void wxTreeListMainWindow::DoDirtyProcessing() -{ +void wxTreeListMainWindow::OnIdle (wxIdleEvent &WXUNUSED(event)) { /* after all changes have been done to the tree control, * we actually redraw the tree when everything is over */ if (!m_dirty) return; - m_dirty = FALSE; + m_dirty = false; CalculatePositions(); Refresh(); AdjustMyScrollbars(); } -void wxTreeListMainWindow::OnScroll(wxScrollWinEvent& event) -{ +void wxTreeListMainWindow::OnScroll (wxScrollWinEvent& event) { // FIXME #if defined(__WXGTK__) && !defined(__WXUNIVERSAL__) wxScrolledWindow::OnScroll(event); @@ -4420,49 +3854,52 @@ void wxTreeListMainWindow::OnScroll(wxScrollWinEvent& event) HandleOnScroll( event ); #endif - if(event.GetOrientation() == wxHORIZONTAL) - { + if(event.GetOrientation() == wxHORIZONTAL) { m_owner->GetHeaderWindow()->Refresh(); m_owner->GetHeaderWindow()->Update(); } } - -void wxTreeListMainWindow::CalculateSize( wxTreeListItem *item, wxDC &dc ) -{ +void wxTreeListMainWindow::CalculateSize (wxTreeListItem *item, wxDC &dc) { wxCoord text_w = 0; wxCoord text_h = 0; - if (item->IsBold()) - dc.SetFont(m_boldFont); + dc.SetFont (GetItemFont (item)); - dc.GetTextExtent( item->GetText(/*ALB*/m_main_column), &text_w, &text_h ); - text_h+=2; + dc.GetTextExtent (item->GetText (m_main_column), &text_w, &text_h); // restore normal font - dc.SetFont( m_normalFont ); + dc.SetFont (m_normalFont); int total_h = (m_imgHeight > text_h) ? m_imgHeight : text_h; + if (total_h < 30) { // add 10% space if greater than 30 pixels + total_h += 2; // minimal 2 pixel space + }else{ + total_h += total_h / 10; // otherwise 10% space + } - item->SetHeight(total_h); - if (total_h>m_lineHeight) - m_lineHeight=total_h; - + item->SetHeight (total_h); + if (total_h > m_lineHeight) m_lineHeight = total_h; item->SetWidth(m_imgWidth + text_w+2); } // ----------------------------------------------------------------------------- -// for developper : y is now the top of the level -// not the middle of it ! -void wxTreeListMainWindow::CalculateLevel( wxTreeListItem *item, wxDC &dc, - int level, int &y, int x_colstart ) -{ +void wxTreeListMainWindow::CalculateLevel (wxTreeListItem *item, wxDC &dc, + int level, int &y, int x_colstart) { + // calculate position of vertical lines int x = x_colstart + MARGIN; // start of column if (HasFlag(wxTR_LINES_AT_ROOT)) x += LINEATROOT; // space for lines at root - if (HasButtons()) x += m_btnWidth2; // space for buttons etc. - if (!HasFlag(wxTR_HIDE_ROOT)) x += m_indent; // indent root as well - x += m_indent * level; // indent according to level + if (HasButtons()) { + x += (m_btnWidth-m_btnWidth2); // half button space + }else{ + x += (m_indent-m_indent/2); + } + if (HasFlag(wxTR_HIDE_ROOT)) { + x += m_indent * (level-1); // indent but not level 1 + }else{ + x += m_indent * level; // indent according to level + } // a hidden root is not evaluated, but its children are always if (HasFlag(wxTR_HIDE_ROOT) && (level == 0)) goto Recurse; @@ -4479,15 +3916,15 @@ void wxTreeListMainWindow::CalculateLevel( wxTreeListItem *item, wxDC &dc, Recurse: wxArrayTreeListItems& children = item->GetChildren(); - size_t n, count = children.Count(); + long n, count = (long)children.Count(); ++level; - for (n = 0; n < count; ++n ) + for (n = 0; n < count; ++n) { CalculateLevel( children[n], dc, level, y, x_colstart ); // recurse + } } -void wxTreeListMainWindow::CalculatePositions() -{ - if ( !m_anchor ) return; +void wxTreeListMainWindow::CalculatePositions() { + if ( !m_rootItem ) return; wxClientDC dc(this); PrepareDC( dc ); @@ -4500,15 +3937,14 @@ void wxTreeListMainWindow::CalculatePositions() int y = 2; int x_colstart = 0; - for(size_t i = 0; i < GetMainColumn(); ++i) { - if (!m_owner->GetHeaderWindow()->GetColumnShown(i)) continue; + for (int i = 0; i < (int)GetMainColumn(); ++i) { + if (!m_owner->GetHeaderWindow()->IsColumnShown(i)) continue; x_colstart += m_owner->GetHeaderWindow()->GetColumnWidth(i); } - CalculateLevel( m_anchor, dc, 0, y, x_colstart ); // start recursion + CalculateLevel( m_rootItem, dc, 0, y, x_colstart ); // start recursion } -void wxTreeListMainWindow::RefreshSubtree(wxTreeListItem *item) -{ +void wxTreeListMainWindow::RefreshSubtree (wxTreeListItem *item) { if (m_dirty) return; wxClientDC dc(this); @@ -4516,7 +3952,7 @@ void wxTreeListMainWindow::RefreshSubtree(wxTreeListItem *item) int cw = 0; int ch = 0; - GetVirtualSize( &cw, &ch ); + GetVirtualSize( &cw, &ch ); wxRect rect; rect.x = dc.LogicalToDeviceX( 0 ); @@ -4524,13 +3960,11 @@ void wxTreeListMainWindow::RefreshSubtree(wxTreeListItem *item) rect.y = dc.LogicalToDeviceY( item->GetY() - 2 ); rect.height = ch; - Refresh( TRUE, &rect ); - + Refresh (true, &rect ); AdjustMyScrollbars(); } -void wxTreeListMainWindow::RefreshLine( wxTreeListItem *item ) -{ +void wxTreeListMainWindow::RefreshLine (wxTreeListItem *item) { if (m_dirty) return; wxClientDC dc(this); @@ -4538,7 +3972,7 @@ void wxTreeListMainWindow::RefreshLine( wxTreeListItem *item ) int cw = 0; int ch = 0; - GetVirtualSize( &cw, &ch ); + GetVirtualSize( &cw, &ch ); wxRect rect; rect.x = dc.LogicalToDeviceX( 0 ); @@ -4546,27 +3980,26 @@ void wxTreeListMainWindow::RefreshLine( wxTreeListItem *item ) rect.width = cw; rect.height = GetLineHeight(item); //dc.GetCharHeight() + 6; - Refresh( TRUE, &rect ); + Refresh (true, &rect); } -void wxTreeListMainWindow::RefreshSelected() -{ +void wxTreeListMainWindow::RefreshSelected() { // TODO: this is awfully inefficient, we should keep the list of all // selected items internally, should be much faster - if ( m_anchor ) - RefreshSelectedUnder(m_anchor); + if (m_rootItem) { + RefreshSelectedUnder (m_rootItem); + } } -void wxTreeListMainWindow::RefreshSelectedUnder(wxTreeListItem *item) -{ - if ( item->IsSelected() ) - RefreshLine(item); +void wxTreeListMainWindow::RefreshSelectedUnder (wxTreeListItem *item) { + if (item->IsSelected()) { + RefreshLine (item); + } const wxArrayTreeListItems& children = item->GetChildren(); - size_t count = children.GetCount(); - for ( size_t n = 0; n < count; n++ ) - { - RefreshSelectedUnder(children[n]); + long count = children.GetCount(); + for (long n = 0; n < count; n++ ) { + RefreshSelectedUnder (children[n]); } } @@ -4574,62 +4007,137 @@ void wxTreeListMainWindow::RefreshSelectedUnder(wxTreeListItem *item) // changing colours: we need to refresh the tree control // ---------------------------------------------------------------------------- -bool wxTreeListMainWindow::SetBackgroundColour(const wxColour& colour) -{ - if ( !wxWindow::SetBackgroundColour(colour) ) - return FALSE; +bool wxTreeListMainWindow::SetBackgroundColour (const wxColour& colour) { + if (!wxWindow::SetBackgroundColour(colour)) return false; Refresh(); - - return TRUE; + return true; } -bool wxTreeListMainWindow::SetForegroundColour(const wxColour& colour) -{ - if ( !wxWindow::SetForegroundColour(colour) ) - return FALSE; +bool wxTreeListMainWindow::SetForegroundColour (const wxColour& colour) { + if (!wxWindow::SetForegroundColour(colour)) return false; Refresh(); - - return TRUE; + return true; } -//----------- ALB ------------- -void wxTreeListMainWindow::SetItemText(const wxTreeItemId& item, size_t column, - const wxString& text) -{ - wxCHECK_RET( item.IsOk(), wxT("invalid tree item") ); +void wxTreeListMainWindow::SetItemText (const wxTreeItemId& itemId, int column, + const wxString& text) { + wxCHECK_RET (itemId.IsOk(), _T("invalid tree item")); - wxClientDC dc(this); - wxTreeListItem *pItem = (wxTreeListItem*) item.m_pItem; - pItem->SetText(column, text); - CalculateSize(pItem, dc); - RefreshLine(pItem); + wxClientDC dc (this); + wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem; + item->SetText (column, text); + CalculateSize (item, dc); + RefreshLine (item); } -wxString wxTreeListMainWindow::GetItemText(const wxTreeItemId& item, - size_t column) const -{ - wxCHECK_MSG( item.IsOk(), wxT(""), wxT("invalid tree item") ); +wxString wxTreeListMainWindow::GetItemText (const wxTreeItemId& itemId, + int column) const { + wxCHECK_MSG (itemId.IsOk(), _T(""), _T("invalid tree item") ); - return ((wxTreeListItem*) item.m_pItem)->GetText(column); + if( IsVirtual() ) return m_owner->OnGetItemText(((wxTreeListItem*) itemId.m_pItem)->GetData(),column); + else return ((wxTreeListItem*) itemId.m_pItem)->GetText (column); } -void wxTreeListMainWindow::SetFocus() -{ +wxString wxTreeListMainWindow::GetItemText (wxTreeItemData* item, +int column) const { + wxASSERT_MSG( IsVirtual(), _T("can be used only with virtual control") ); + return m_owner->OnGetItemText(item,column); +} + +void wxTreeListMainWindow::SetFocus() { wxWindow::SetFocus(); } +wxFont wxTreeListMainWindow::GetItemFont (wxTreeListItem *item) { + wxTreeItemAttr *attr = item->GetAttributes(); + + if (attr && attr->HasFont()) { + return attr->GetFont(); + }else if (item->IsBold()) { + return m_boldFont; + }else{ + return m_normalFont; + } +} + +int wxTreeListMainWindow::GetItemWidth (int column, wxTreeListItem *item) { + if (!item) return 0; + + // determine item width + int w = 0, h = 0; + wxFont font = GetItemFont (item); + GetTextExtent (item->GetText (column), &w, &h, NULL, NULL, font.Ok()? &font: NULL); + w += 2*MARGIN; + + // calculate width + int width = w + 2*MARGIN; + if (column == GetMainColumn()) { + width += MARGIN; + if (HasFlag(wxTR_LINES_AT_ROOT)) width += LINEATROOT; + if (HasButtons()) width += m_btnWidth + LINEATROOT; + if (item->GetCurrentImage() != NO_IMAGE) width += m_imgWidth; + + // count indent level + int level = 0; + wxTreeListItem *parent = item->GetItemParent(); + wxTreeListItem *root = (wxTreeListItem*)GetRootItem().m_pItem; + while (parent && (!HasFlag(wxTR_HIDE_ROOT) || (parent != root))) { + level++; + parent = parent->GetItemParent(); + } + if (level) width += level * GetIndent(); + } + + return width; +} + +int wxTreeListMainWindow::GetBestColumnWidth (int column, wxTreeItemId parent) { + int maxWidth, h; + GetClientSize (&maxWidth, &h); + int width = 0; + + // get root if on item + if (!parent.IsOk()) parent = GetRootItem(); + + // add root width + if (!HasFlag(wxTR_HIDE_ROOT)) { + int w = GetItemWidth (column, (wxTreeListItem*)parent.m_pItem); + if (width < w) width = w; + if (width > maxWidth) return maxWidth; + } + + wxTreeItemIdValue cookie = 0; + wxTreeItemId item = GetFirstChild (parent, cookie); + while (item.IsOk()) { + int w = GetItemWidth (column, (wxTreeListItem*)item.m_pItem); + if (width < w) width = w; + if (width > maxWidth) return maxWidth; + + // check the children of this item + if (((wxTreeListItem*)item.m_pItem)->IsExpanded()) { + int w = GetBestColumnWidth (column, item); + if (width < w) width = w; + if (width > maxWidth) return maxWidth; + } + + // next sibling + item = GetNextChild (parent, cookie); + } + + return width; +} + //----------------------------------------------------------------------------- // wxTreeListCtrl //----------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxTreeListCtrl, wxControl) +IMPLEMENT_DYNAMIC_CLASS(wxTreeListCtrl, wxControl); BEGIN_EVENT_TABLE(wxTreeListCtrl, wxControl) EVT_SIZE(wxTreeListCtrl::OnSize) - EVT_TREE_ITEM_GETTOOLTIP(wxID_ANY, wxTreeListCtrl::OnGetToolTip) END_EVENT_TABLE(); bool wxTreeListCtrl::Create(wxWindow *parent, wxWindowID id, @@ -4638,37 +4146,35 @@ bool wxTreeListCtrl::Create(wxWindow *parent, wxWindowID id, long style, const wxValidator &validator, const wxString& name) { - long main_style = style & ~(wxRAISED_BORDER|wxSUNKEN_BORDER - |wxSIMPLE_BORDER|wxNO_BORDER|wxDOUBLE_BORDER - |wxSTATIC_BORDER); + long main_style = style & ~(wxSIMPLE_BORDER|wxSUNKEN_BORDER|wxDOUBLE_BORDER| + wxRAISED_BORDER|wxSTATIC_BORDER); long ctrl_style = style & ~(wxVSCROLL|wxHSCROLL); if (!wxControl::Create(parent, id, pos, size, ctrl_style, validator, name)) { return false; } - m_main_win = new wxTreeListMainWindow(this, -1, wxPoint(0, 0), size, - main_style, validator); - m_header_win = new wxTreeListHeaderWindow(this, -1, m_main_win, - wxPoint(0, 0), wxDefaultSize, - wxTAB_TRAVERSAL); + m_main_win = new wxTreeListMainWindow (this, -1, wxPoint(0, 0), size, + main_style, validator); + m_header_win = new wxTreeListHeaderWindow (this, -1, m_main_win, + wxPoint(0, 0), wxDefaultSize, + wxTAB_TRAVERSAL); CalculateAndSetHeaderHeight(); - return TRUE; + return true; } void wxTreeListCtrl::CalculateAndSetHeaderHeight() { - if ( m_header_win ) - { + if (m_header_win) { + // we use 'g' to get the descent, too int w, h, d; - m_header_win->GetTextExtent(wxT("Hg"), &w, &h, &d); + m_header_win->GetTextExtent(_T("Hg"), &w, &h, &d); h += d + 2 * HEADER_OFFSET_Y + EXTRA_HEIGHT; // only update if changed - if ( h != (int)m_headerHeight ) - { - m_headerHeight = (size_t)h; - m_header_win->SetSize(m_header_win->GetSize().x, m_headerHeight); + if (h != m_headerHeight) { + m_headerHeight = h; + DoHeaderLayout(); } } } @@ -4677,21 +4183,20 @@ void wxTreeListCtrl::DoHeaderLayout() { int w, h; GetClientSize(&w, &h); - if (m_header_win) - { - m_header_win->SetSize(0, 0, w, m_headerHeight); - m_header_win->Refresh(false); + if (m_header_win) { + m_header_win->SetSize (0, 0, w, m_headerHeight); + m_header_win->Refresh(); + } + if (m_main_win) { + m_main_win->SetSize (0, m_headerHeight + 1, w, h - m_headerHeight - 1); } - if (m_main_win) - m_main_win->SetSize(0, m_headerHeight + 1, w, h - m_headerHeight - 1); -} +} void wxTreeListCtrl::OnSize(wxSizeEvent& WXUNUSED(event)) { DoHeaderLayout(); } - size_t wxTreeListCtrl::GetCount() const { return m_main_win->GetCount(); } unsigned int wxTreeListCtrl::GetIndent() const @@ -4733,11 +4238,10 @@ void wxTreeListCtrl::AssignStateImageList(wxImageList* imageList) void wxTreeListCtrl::AssignButtonsImageList(wxImageList* imageList) { m_main_win->AssignButtonsImageList(imageList); } -wxString wxTreeListCtrl::GetItemText(const wxTreeItemId& item, size_t column) - const -{ return m_main_win->GetItemText(item, column); } +wxString wxTreeListCtrl::GetItemText(const wxTreeItemId& item, int column) const +{ return m_main_win->GetItemText (item, column); } -int wxTreeListCtrl::GetItemImage(const wxTreeItemId& item, size_t column, +int wxTreeListCtrl::GetItemImage(const wxTreeItemId& item, int column, wxTreeItemIcon which) const { return m_main_win->GetItemImage(item, column, which); } @@ -4758,12 +4262,12 @@ wxFont wxTreeListCtrl::GetItemFont(const wxTreeItemId& item) const { return m_main_win->GetItemFont(item); } -void wxTreeListCtrl::SetItemText(const wxTreeItemId& item, size_t column, +void wxTreeListCtrl::SetItemText(const wxTreeItemId& item, int column, const wxString& text) -{ m_main_win->SetItemText(item, column, text); } +{ m_main_win->SetItemText (item, column, text); } void wxTreeListCtrl::SetItemImage(const wxTreeItemId& item, - size_t column, + int column, int image, wxTreeItemIcon which) { m_main_win->SetItemImage(item, column, image, which); } @@ -4779,12 +4283,12 @@ void wxTreeListCtrl::SetItemBold(const wxTreeItemId& item, bool bold) { m_main_win->SetItemBold(item, bold); } void wxTreeListCtrl::SetItemTextColour(const wxTreeItemId& item, - const wxColour& col) -{ m_main_win->SetItemTextColour(item, col); } + const wxColour& colour) +{ m_main_win->SetItemTextColour(item, colour); } void wxTreeListCtrl::SetItemBackgroundColour(const wxTreeItemId& item, - const wxColour& col) -{ m_main_win->SetItemBackgroundColour(item, col); } + const wxColour& colour) +{ m_main_win->SetItemBackgroundColour(item, colour); } void wxTreeListCtrl::SetItemFont(const wxTreeItemId& item, const wxFont& font) @@ -4792,20 +4296,23 @@ void wxTreeListCtrl::SetItemFont(const wxTreeItemId& item, bool wxTreeListCtrl::SetFont(const wxFont& font) { - if (m_header_win) - { + if (m_header_win) { m_header_win->SetFont(font); CalculateAndSetHeaderHeight(); + m_header_win->Refresh(); } - if (m_main_win) + if (m_main_win) { return m_main_win->SetFont(font); - else return FALSE; + }else{ + return false; + } } void wxTreeListCtrl::SetWindowStyle(const long style) { if(m_main_win) m_main_win->SetWindowStyle(style); + m_windowStyle = style; // TODO: provide something like wxTL_NO_HEADERS to hide m_header_win } @@ -4817,11 +4324,11 @@ long wxTreeListCtrl::GetWindowStyle() const return style; } -bool wxTreeListCtrl::IsVisible(const wxTreeItemId& item) const -{ return m_main_win->IsVisible(item); } +bool wxTreeListCtrl::IsVisible(const wxTreeItemId& item, bool fullRow) const +{ return m_main_win->IsVisible(item, fullRow); } -bool wxTreeListCtrl::ItemHasChildren(const wxTreeItemId& item) const -{ return m_main_win->ItemHasChildren(item); } +bool wxTreeListCtrl::HasChildren(const wxTreeItemId& item) const +{ return m_main_win->HasChildren(item); } bool wxTreeListCtrl::IsExpanded(const wxTreeItemId& item) const { return m_main_win->IsExpanded(item); } @@ -4848,34 +4355,41 @@ wxTreeItemId wxTreeListCtrl::GetItemParent(const wxTreeItemId& item) const { return m_main_win->GetItemParent(item); } #if !wxCHECK_VERSION(2, 5, 0) -wxTreeItemId wxTreeListCtrl::GetFirstChild(const wxTreeItemId& item, - long& cookie) const +wxTreeItemId wxTreeListCtrl::GetFirstChild (const wxTreeItemId& item, + long& cookie) const #else -wxTreeItemId wxTreeListCtrl::GetFirstChild(const wxTreeItemId& item, - wxTreeItemIdValue& cookie) const +wxTreeItemId wxTreeListCtrl::GetFirstChild (const wxTreeItemId& item, + wxTreeItemIdValue& cookie) const #endif { return m_main_win->GetFirstChild(item, cookie); } #if !wxCHECK_VERSION(2, 5, 0) -wxTreeItemId wxTreeListCtrl::GetNextChild(const wxTreeItemId& item, - long& cookie) const +wxTreeItemId wxTreeListCtrl::GetNextChild (const wxTreeItemId& item, + long& cookie) const #else -wxTreeItemId wxTreeListCtrl::GetNextChild(const wxTreeItemId& item, - wxTreeItemIdValue& cookie) const +wxTreeItemId wxTreeListCtrl::GetNextChild (const wxTreeItemId& item, + wxTreeItemIdValue& cookie) const #endif { return m_main_win->GetNextChild(item, cookie); } #if !wxCHECK_VERSION(2, 5, 0) -wxTreeItemId wxTreeListCtrl::GetPrevChild(const wxTreeItemId& item, - long& cookie) const +wxTreeItemId wxTreeListCtrl::GetPrevChild (const wxTreeItemId& item, + long& cookie) const #else -wxTreeItemId wxTreeListCtrl::GetPrevChild(const wxTreeItemId& item, - wxTreeItemIdValue& cookie) const +wxTreeItemId wxTreeListCtrl::GetPrevChild (const wxTreeItemId& item, + wxTreeItemIdValue& cookie) const #endif { return m_main_win->GetPrevChild(item, cookie); } -wxTreeItemId wxTreeListCtrl::GetLastChild(const wxTreeItemId& item) const -{ return m_main_win->GetLastChild(item); } +#if !wxCHECK_VERSION(2, 5, 0) +wxTreeItemId wxTreeListCtrl::GetLastChild (const wxTreeItemId& item, + long& cookie) const +#else +wxTreeItemId wxTreeListCtrl::GetLastChild (const wxTreeItemId& item, + wxTreeItemIdValue& cookie) const +#endif +{ return m_main_win->GetLastChild(item, cookie); } + wxTreeItemId wxTreeListCtrl::GetNextSibling(const wxTreeItemId& item) const { return m_main_win->GetNextSibling(item); } @@ -4883,21 +4397,33 @@ wxTreeItemId wxTreeListCtrl::GetNextSibling(const wxTreeItemId& item) const wxTreeItemId wxTreeListCtrl::GetPrevSibling(const wxTreeItemId& item) const { return m_main_win->GetPrevSibling(item); } -wxTreeItemId wxTreeListCtrl::GetFirstVisibleItem() const -{ return m_main_win->GetFirstVisibleItem(); } +wxTreeItemId wxTreeListCtrl::GetNext(const wxTreeItemId& item) const +{ return m_main_win->GetNext(item, true); } -wxTreeItemId wxTreeListCtrl::GetNextVisible(const wxTreeItemId& item) const -{ return m_main_win->GetNextVisible(item); } +wxTreeItemId wxTreeListCtrl::GetPrev(const wxTreeItemId& item) const +{ return m_main_win->GetPrev(item, true); } -wxTreeItemId wxTreeListCtrl::GetPrevVisible(const wxTreeItemId& item) const -{ return m_main_win->GetPrevVisible(item); } +wxTreeItemId wxTreeListCtrl::GetFirstExpandedItem() const +{ return m_main_win->GetFirstExpandedItem(); } -wxTreeItemId wxTreeListCtrl::GetNext(const wxTreeItemId& item) const -{ return m_main_win->GetNext(item); } +wxTreeItemId wxTreeListCtrl::GetNextExpanded(const wxTreeItemId& item) const +{ return m_main_win->GetNextExpanded(item); } + +wxTreeItemId wxTreeListCtrl::GetPrevExpanded(const wxTreeItemId& item) const +{ return m_main_win->GetPrevExpanded(item); } + +wxTreeItemId wxTreeListCtrl::GetFirstVisibleItem(bool fullRow) const +{ return m_main_win->GetFirstVisibleItem(fullRow); } -wxTreeItemId wxTreeListCtrl::AddRoot(const wxString& text, int image, - int selectedImage, wxTreeItemData* data) -{ return m_main_win->AddRoot(text, image, selectedImage, data); } +wxTreeItemId wxTreeListCtrl::GetNextVisible(const wxTreeItemId& item, bool fullRow) const +{ return m_main_win->GetNextVisible(item, fullRow); } + +wxTreeItemId wxTreeListCtrl::GetPrevVisible(const wxTreeItemId& item, bool fullRow) const +{ return m_main_win->GetPrevVisible(item, fullRow); } + +wxTreeItemId wxTreeListCtrl::AddRoot (const wxString& text, int image, + int selectedImage, wxTreeItemData* data) +{ return m_main_win->AddRoot (text, image, selectedImage, data); } wxTreeItemId wxTreeListCtrl::PrependItem(const wxTreeItemId& parent, const wxString& text, int image, @@ -4937,8 +4463,8 @@ void wxTreeListCtrl::Delete(const wxTreeItemId& item) void wxTreeListCtrl::DeleteChildren(const wxTreeItemId& item) { m_main_win->DeleteChildren(item); } -void wxTreeListCtrl::DeleteAllItems() -{ m_main_win->DeleteAllItems(); } +void wxTreeListCtrl::DeleteRoot() +{ m_main_win->DeleteRoot(); } void wxTreeListCtrl::Expand(const wxTreeItemId& item) { m_main_win->Expand(item); } @@ -4961,12 +4487,12 @@ void wxTreeListCtrl::Unselect() void wxTreeListCtrl::UnselectAll() { m_main_win->UnselectAll(); } -void wxTreeListCtrl::SelectItem(const wxTreeItemId& item, bool unselect_others, - bool extended_select) -{ m_main_win->SelectItem(item, unselect_others, extended_select); } +void wxTreeListCtrl::SelectItem(const wxTreeItemId& item, const wxTreeItemId& last, + bool unselect_others) +{ m_main_win->SelectItem (item, last, unselect_others); } -void wxTreeListCtrl::SelectAll(bool extended_select) -{ m_main_win->SelectAll(extended_select); } +void wxTreeListCtrl::SelectAll() +{ m_main_win->SelectAll(); } void wxTreeListCtrl::EnsureVisible(const wxTreeItemId& item) { m_main_win->EnsureVisible(item); } @@ -4974,23 +4500,23 @@ void wxTreeListCtrl::EnsureVisible(const wxTreeItemId& item) void wxTreeListCtrl::ScrollTo(const wxTreeItemId& item) { m_main_win->ScrollTo(item); } -wxTreeItemId wxTreeListCtrl::HitTest(const wxPoint& pos, int& flags, - int& column) +wxTreeItemId wxTreeListCtrl::HitTest(const wxPoint& pos, int& flags, int& column) { - return m_main_win->HitTest(pos, flags, column); + wxPoint p = m_main_win->ScreenToClient (ClientToScreen (pos)); + return m_main_win->HitTest (p, flags, column); } bool wxTreeListCtrl::GetBoundingRect(const wxTreeItemId& item, wxRect& rect, bool textOnly) const { return m_main_win->GetBoundingRect(item, rect, textOnly); } -void wxTreeListCtrl::Edit(const wxTreeItemId& item) -{ m_main_win->Edit(item); } +void wxTreeListCtrl::EditLabel (const wxTreeItemId& item, int column) +{ m_main_win->EditLabel (item, column); } int wxTreeListCtrl::OnCompareItems(const wxTreeItemId& item1, const wxTreeItemId& item2) { - // ALB: do the comparison here, and not delegate to m_main_win, in order + // do the comparison here, and not delegate to m_main_win, in order // to let the user override it //return m_main_win->OnCompareItems(item1, item2); return wxStrcmp(GetItemText(item1), GetItemText(item2)); @@ -4999,120 +4525,141 @@ int wxTreeListCtrl::OnCompareItems(const wxTreeItemId& item1, void wxTreeListCtrl::SortChildren(const wxTreeItemId& item) { m_main_win->SortChildren(item); } -wxTreeItemId wxTreeListCtrl::FindItem (const wxTreeItemId& item, const wxString& str, int flags) -{ return m_main_win->FindItem (item, str, flags); } +wxTreeItemId wxTreeListCtrl::FindItem (const wxTreeItemId& item, const wxString& str, int mode) +{ return m_main_win->FindItem (item, str, mode); } + +void wxTreeListCtrl::SetDragItem (const wxTreeItemId& item) +{ m_main_win->SetDragItem (item); } bool wxTreeListCtrl::SetBackgroundColour(const wxColour& colour) -{ +{ if (!m_main_win) return false; - return m_main_win->SetBackgroundColour(colour); + return m_main_win->SetBackgroundColour(colour); } bool wxTreeListCtrl::SetForegroundColour(const wxColour& colour) -{ +{ if (!m_main_win) return false; - return m_main_win->SetForegroundColour(colour); + return m_main_win->SetForegroundColour(colour); } -size_t wxTreeListCtrl::GetColumnCount() const +int wxTreeListCtrl::GetColumnCount() const { return m_main_win->GetColumnCount(); } -void wxTreeListCtrl::SetColumnWidth(size_t column, size_t width) -{ m_header_win->SetColumnWidth(column, width); } +void wxTreeListCtrl::SetColumnWidth(int column, int width) +{ + m_header_win->SetColumnWidth (column, width); + m_header_win->Refresh(); +} -int wxTreeListCtrl::GetColumnWidth(size_t column) const +int wxTreeListCtrl::GetColumnWidth(int column) const { return m_header_win->GetColumnWidth(column); } -void wxTreeListCtrl::SetMainColumn(size_t column) +void wxTreeListCtrl::SetMainColumn(int column) { m_main_win->SetMainColumn(column); } -size_t wxTreeListCtrl::GetMainColumn() const +int wxTreeListCtrl::GetMainColumn() const { return m_main_win->GetMainColumn(); } -void wxTreeListCtrl::SetColumnText(size_t column, const wxString& text) +void wxTreeListCtrl::SetColumnText(int column, const wxString& text) { - m_header_win->SetColumnText(column, text); + m_header_win->SetColumnText (column, text); m_header_win->Refresh(); } -wxString wxTreeListCtrl::GetColumnText(size_t column) const +wxString wxTreeListCtrl::GetColumnText(int column) const { return m_header_win->GetColumnText(column); } -void wxTreeListCtrl::AddColumn(const wxTreeListColumnInfo& col) +void wxTreeListCtrl::AddColumn(const wxTreeListColumnInfo& colInfo) { - m_header_win->AddColumn(col); + m_header_win->AddColumn (colInfo); DoHeaderLayout(); } -void wxTreeListCtrl::InsertColumn(size_t before, - const wxTreeListColumnInfo& col) -{ m_header_win->InsertColumn(before, col); } +void wxTreeListCtrl::InsertColumn(int before, const wxTreeListColumnInfo& colInfo) +{ + m_header_win->InsertColumn (before, colInfo); + m_header_win->Refresh(); +} -void wxTreeListCtrl::RemoveColumn(size_t column) -{ m_header_win->RemoveColumn(column); } +void wxTreeListCtrl::RemoveColumn(int column) +{ + m_header_win->RemoveColumn (column); + m_header_win->Refresh(); +} -void wxTreeListCtrl::SetColumn(size_t column, const wxTreeListColumnInfo& col) -{ m_header_win->SetColumn(column, col); } +void wxTreeListCtrl::SetColumn(int column, const wxTreeListColumnInfo& colInfo) +{ + m_header_win->SetColumn (column, colInfo); + m_header_win->Refresh(); +} -const wxTreeListColumnInfo& wxTreeListCtrl::GetColumn(size_t column) const +const wxTreeListColumnInfo& wxTreeListCtrl::GetColumn(int column) const { return m_header_win->GetColumn(column); } -wxTreeListColumnInfo& wxTreeListCtrl::GetColumn(size_t column) +wxTreeListColumnInfo& wxTreeListCtrl::GetColumn(int column) { return m_header_win->GetColumn(column); } -void wxTreeListCtrl::SetColumnImage(size_t column, int image) +void wxTreeListCtrl::SetColumnImage(int column, int image) { - m_header_win->SetColumn(column, GetColumn(column).SetImage(image)); + m_header_win->SetColumn (column, GetColumn(column).SetImage(image)); + m_header_win->Refresh(); } -int wxTreeListCtrl::GetColumnImage(size_t column) const +int wxTreeListCtrl::GetColumnImage(int column) const { return m_header_win->GetColumn(column).GetImage(); } -void wxTreeListCtrl::ShowColumn(size_t column, bool shown) +void wxTreeListCtrl::SetColumnEditable(int column, bool shown) +{ + m_header_win->SetColumn (column, GetColumn(column).SetEditable(shown)); +} + +void wxTreeListCtrl::SetColumnShown(int column, bool shown) +{ + wxASSERT_MSG (column != GetMainColumn(), _T("The main column may not be hidden") ); + m_header_win->SetColumn (column, GetColumn(column).SetShown(GetMainColumn()==column? true: shown)); + m_header_win->Refresh(); +} + +bool wxTreeListCtrl::IsColumnEditable(int column) const { - wxASSERT_MSG( column != GetMainColumn(), - wxT("The main column may not be hidden") ); - m_header_win->SetColumn(column, GetColumn(column).SetShown(GetMainColumn()? true: shown)); + return m_header_win->GetColumn(column).IsEditable(); } -bool wxTreeListCtrl::IsColumnShown(size_t column) const +bool wxTreeListCtrl::IsColumnShown(int column) const { - return m_header_win->GetColumn(column).GetShown(); + return m_header_win->GetColumn(column).IsShown(); } -void wxTreeListCtrl::SetColumnAlignment(size_t column, - wxTreeListColumnAlign align) +void wxTreeListCtrl::SetColumnAlignment (int column, int flag) { - m_header_win->SetColumn(column, GetColumn(column).SetAlignment(align)); + m_header_win->SetColumn(column, GetColumn(column).SetAlignment(flag)); + m_header_win->Refresh(); } -wxTreeListColumnAlign wxTreeListCtrl::GetColumnAlignment(size_t column) const +int wxTreeListCtrl::GetColumnAlignment(int column) const { return m_header_win->GetColumn(column).GetAlignment(); } void wxTreeListCtrl::Refresh(bool erase, const wxRect* rect) { - m_main_win->Refresh(erase, rect); - m_header_win->Refresh(erase, rect); + m_main_win->Refresh (erase, rect); + m_header_win->Refresh (erase, rect); } void wxTreeListCtrl::SetFocus() { m_main_win->SetFocus(); } - wxSize wxTreeListCtrl::DoGetBestSize() const { // something is better than nothing... - return wxSize(100,80); + return wxSize (200,200); // but it should be specified values! FIXME } -// Process the tooltip event, to speed up event processing. -// Doesn't actually get a tooltip. -void wxTreeListCtrl::OnGetToolTip( wxTreeEvent &event ) +wxString wxTreeListCtrl::OnGetItemText( wxTreeItemData* WXUNUSED(item), long WXUNUSED(column)) const { - event.Veto(); + return wxEmptyString; } - diff --git a/wxPython/demo/TreeListCtrl.py b/wxPython/demo/TreeListCtrl.py index 10bc4576e8..f0de0e1e90 100644 --- a/wxPython/demo/TreeListCtrl.py +++ b/wxPython/demo/TreeListCtrl.py @@ -16,14 +16,9 @@ class TestPanel(wx.Panel): wx.TR_DEFAULT_STYLE #wx.TR_TWIST_BUTTONS #| wx.TR_ROW_LINES + #| wx.TR_COLUMN_LINES #| wx.TR_NO_LINES | wx.TR_FULL_ROW_HIGHLIGHT - - # By default the style will be adjusted on - # Mac to use twisty buttons and no lines. If - # you would rather control this yourself then - # add this style. - #| wx.TR_DONT_ADJUST_MAC ) isz = (16,16) diff --git a/wxPython/docs/CHANGES.txt b/wxPython/docs/CHANGES.txt index cd4001a50f..323c44f48d 100644 --- a/wxPython/docs/CHANGES.txt +++ b/wxPython/docs/CHANGES.txt @@ -196,7 +196,7 @@ wx.BitmapFromBufferRGBA factory functions. They enable loading of an image or bitmap directly from a Python object that implements the buffer interface, such as strings, arrays, etc. -Added wx.App.DisplayAvailable() which can be used to determine if a +Added wx.App.IsDisplayAvailable() which can be used to determine if a GUI can be created in the current environment. (Still need an implementation for wxMSW...) @@ -232,7 +232,22 @@ restrictions in how/where the toolbar can be used. Added wx.Window.IsVisible. - +Added Python properties for many of the getter/setter methods of wx +classes. In order for the names to be predicatble for somebody +already familiar with wxPython the property names are simply the name +of the getter with the "Get" dropped. For example, wx.Window has a +property named "Size" that maps to GetSize and SetSize. So far there +is only one known name conflict using this naming convention, and that +is wx.KeyEvent.KeyCode, however since KeyCode was formerly a +compatibility alias for GetKeyCode (and has been for a long time) it +was decided to just switch it to a property. If you want to use the +method then change your calls to event.KeyCode() to +event.GetKeyCode(), otherwise you can use it as a property just by +dropping the parentheses. + +Updated the C++ code for wx.gizmos.TreeListCtrl from the wxCode +project. This has resulted in some minor API changes, most of which +were handled in the wrapper code. diff --git a/wxPython/setup.py b/wxPython/setup.py index 951b307e1d..34b0b5dacc 100755 --- a/wxPython/setup.py +++ b/wxPython/setup.py @@ -684,7 +684,8 @@ if BUILD_GIZMOS: location = 'contrib/gizmos' swig_sources = run_swig(['gizmos.i'], location, GENDIR, PKGDIR, - USE_SWIG, swig_force, swig_args, swig_deps) + USE_SWIG, swig_force, swig_args, swig_deps + + [ '%s/_treelist.i' % location]) ext = Extension('_gizmos', [ '%s/treelistctrl.cpp' % opj(location, 'wxCode/src') ] + swig_sources, -- 2.45.2