X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d5d29b8a2250ee3097f31dfb8593374b89128ce2..488b2c29c0cf468f96f148003b21952611325dbf:/src/generic/treectlg.cpp?ds=sidebyside diff --git a/src/generic/treectlg.cpp b/src/generic/treectlg.cpp index 2e5ee1bf98..5a6c21a1b3 100644 --- a/src/generic/treectlg.cpp +++ b/src/generic/treectlg.cpp @@ -40,6 +40,10 @@ #include "wx/renderer.h" +#ifdef __WXMAC__ + #include "wx/mac/private.h" +#endif + // ----------------------------------------------------------------------------- // array types // ----------------------------------------------------------------------------- @@ -84,6 +88,13 @@ class WXDLLEXPORT wxTreeTextCtrl: public wxTextCtrl public: wxTreeTextCtrl(wxGenericTreeCtrl *owner, wxGenericTreeItem *item); + void StopEditing() + { + Finish(); + m_owner->OnRenameCancelled(m_itemEdited); + } + const wxGenericTreeItem* item() const { return m_itemEdited; } + protected: void OnChar( wxKeyEvent &event ); void OnKeyUp( wxKeyEvent &event ); @@ -97,6 +108,7 @@ private: wxGenericTreeItem *m_itemEdited; wxString m_startValue; bool m_finished; + bool m_aboutToFinish; DECLARE_EVENT_TABLE() DECLARE_NO_COPY_CLASS(wxTreeTextCtrl) @@ -150,7 +162,7 @@ public: void SetImage(int image, wxTreeItemIcon which) { m_images[which] = 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; } @@ -174,7 +186,7 @@ public: void DeleteChildren(wxGenericTreeCtrl *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(wxGenericTreeItem *child, size_t index) { m_children.Insert(child, index); } @@ -182,17 +194,17 @@ public: void GetSize( int &x, int &y, const wxGenericTreeCtrl* ); // 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 - // on the button's label + // true if the point belongs to the item's button, otherwise it lies + // on the item's label wxGenericTreeItem *HitTest( const wxPoint& point, const wxGenericTreeCtrl *, int &flags, 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(); } @@ -210,7 +222,7 @@ public: if ( !m_attr ) { m_attr = new wxTreeItemAttr; - m_ownsAttr = TRUE; + m_ownsAttr = true; } return *m_attr; } @@ -219,13 +231,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: @@ -243,12 +255,12 @@ private: // tree ctrl images for the normal, selected, expanded and // expanded+selected states - short m_images[wxTreeItemIcon_Max]; + int m_images[wxTreeItemIcon_Max]; wxCoord m_x; // (virtual) offset from top wxCoord m_y; // (virtual) offset from left - short m_width; // width of this item - unsigned char m_height; // height of this item + int m_width; // width of this item + int m_height; // height of this item // use bitfields to save size int m_isCollapsed :1; @@ -284,20 +296,20 @@ static void EventFlagsToSelType(long style, } // check if the given item is under another one -static bool IsDescendantOf(wxGenericTreeItem *parent, wxGenericTreeItem *item) +static bool IsDescendantOf(const wxGenericTreeItem *parent, const wxGenericTreeItem *item) { while ( item ) { if ( item == parent ) { // item is a descendant of parent - return TRUE; + return true; } item = item->GetParent(); } - return FALSE; + return false; } // ----------------------------------------------------------------------------- @@ -329,7 +341,8 @@ wxTreeTextCtrl::wxTreeTextCtrl(wxGenericTreeCtrl *owner, : m_itemEdited(item), m_startValue(item->GetText()) { m_owner = owner; - m_finished = FALSE; + m_finished = false; + m_aboutToFinish = false; int w = m_itemEdited->GetWidth(), h = m_itemEdited->GetHeight(); @@ -357,6 +370,16 @@ wxTreeTextCtrl::wxTreeTextCtrl(wxGenericTreeCtrl *owner, // FIXME: what are all these hardcoded 4, 8 and 11s really? x += image_w; w -= image_w + 4; +#ifdef __WXMAC__ + wxSize bs = DoGetBestSize() ; + // edit control height + if ( h > bs.y - 8 ) + { + int diff = h - ( bs.y - 8 ) ; + h -= diff ; + y += diff / 2 ; + } +#endif (void)Create(m_owner, wxID_ANY, m_startValue, wxPoint(x - 4, y - 4), wxSize(w + 11, h + 8)); @@ -369,32 +392,38 @@ bool wxTreeTextCtrl::AcceptChanges() if ( value == m_startValue ) { // nothing changed, always accept - return TRUE; + // when an item remains unchanged, the owner + // needs to be notified that the user decided + // not to change the tree item label, and that + // the edit has been cancelled + + m_owner->OnRenameCancelled(m_itemEdited); + return true; } if ( !m_owner->OnRenameAccept(m_itemEdited, value) ) { // vetoed by the user - return FALSE; + return false; } // accepted, do rename the item m_owner->SetItemText(m_itemEdited, value); - return TRUE; + return true; } void wxTreeTextCtrl::Finish() { - if ( !m_finished ) + if ( !m_finished && !m_aboutToFinish ) { m_owner->ResetTextControl(); wxPendingDelete.Append(this); - m_finished = TRUE; + m_finished = true; - m_owner->SetFocus(); // This doesn't work. TODO. + m_owner->SetFocusIgnoringChildren(); } } @@ -403,16 +432,15 @@ void wxTreeTextCtrl::OnChar( wxKeyEvent &event ) switch ( event.m_keyCode ) { case WXK_RETURN: - if ( !AcceptChanges() ) - { - // vetoed by the user, don't disappear - break; - } - //else: fall through + m_aboutToFinish = true; + // Notify the owner about the changes + AcceptChanges(); + // Even if vetoed, close the control (consistent with MSW) + Finish(); + break; case WXK_ESCAPE: - Finish(); - m_owner->OnRenameCancelled(m_itemEdited); + StopEditing(); break; default: @@ -434,7 +462,7 @@ void wxTreeTextCtrl::OnKeyUp( wxKeyEvent &event ) sx = parentSize.x - myPos.x; if (mySize.x > sx) sx = mySize.x; - SetSize(sx, -1); + SetSize(sx, wxDefaultCoord); } event.Skip(); @@ -442,16 +470,19 @@ void wxTreeTextCtrl::OnKeyUp( wxKeyEvent &event ) void wxTreeTextCtrl::OnKillFocus( wxFocusEvent &event ) { - if ( m_finished ) - { - event.Skip(); - return; - } - - if ( AcceptChanges() ) + if ( !m_finished ) { + // We must finish regardless of success, otherwise we'll get + // focus problems: Finish(); + + if ( !AcceptChanges() ) + m_owner->OnRenameCancelled( m_itemEdited ); } + + // We must let the native text control handle focus, too, otherwise + // it could have problems with the cursor (e.g., in wxGTK). + event.Skip(); } // ----------------------------------------------------------------------------- @@ -472,15 +503,15 @@ wxGenericTreeItem::wxGenericTreeItem(wxGenericTreeItem *parent, m_data = data; m_x = m_y = 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_parent = parent; m_attr = (wxTreeItemAttr *)NULL; - m_ownsAttr = FALSE; + m_ownsAttr = false; // We don't know the height here yet. m_width = 0; @@ -507,6 +538,8 @@ void wxGenericTreeItem::DeleteChildren(wxGenericTreeCtrl *tree) tree->SendDeleteEvent(child); child->DeleteChildren(tree); + if (child == tree->m_select_me) + tree->m_select_me = NULL; delete child; } @@ -578,8 +611,8 @@ wxGenericTreeItem *wxGenericTreeItem::HitTest(const wxPoint& point, HasPlus() && theCtrl->HasButtons() ) #else // 5 is the size of the plus sign - if ((point.x > xCross-5) && (point.x < xCross+5) && - (point.y > y_mid-5) && (point.y < y_mid+5) && + if ((point.x > xCross-6) && (point.x < xCross+6) && + (point.y > y_mid-6) && (point.y < y_mid+6) && HasPlus() && theCtrl->HasButtons() ) #endif { @@ -674,9 +707,10 @@ BEGIN_EVENT_TABLE(wxGenericTreeCtrl,wxScrolledWindow) EVT_CHAR (wxGenericTreeCtrl::OnChar) EVT_SET_FOCUS (wxGenericTreeCtrl::OnSetFocus) EVT_KILL_FOCUS (wxGenericTreeCtrl::OnKillFocus) + EVT_TREE_ITEM_GETTOOLTIP(wxID_ANY, wxGenericTreeCtrl::OnGetToolTip) END_EVENT_TABLE() -#if !defined(__WXMSW__) || defined(__WIN16__) || defined(__WXUNIVERSAL__) +#if !defined(__WXMSW__) || defined(__WXUNIVERSAL__) /* * wxTreeCtrl has to be a real class or we have problems with * the run-time information. @@ -692,8 +726,8 @@ IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl, wxGenericTreeCtrl) void wxGenericTreeCtrl::Init() { m_current = m_key_current = m_anchor = m_select_me = (wxGenericTreeItem *) NULL; - m_hasFocus = FALSE; - m_dirty = FALSE; + m_hasFocus = false; + m_dirty = false; m_lineHeight = 10; m_indent = 15; @@ -720,19 +754,28 @@ void wxGenericTreeCtrl::Init() m_imageListNormal = m_imageListButtons = m_imageListState = (wxImageList *) NULL; m_ownsImageListNormal = m_ownsImageListButtons = - m_ownsImageListState = FALSE; + m_ownsImageListState = false; m_dragCount = 0; - m_isDragging = FALSE; - m_dropTarget = m_oldSelection = (wxGenericTreeItem *)NULL; + m_isDragging = false; + m_dropTarget = m_oldSelection = NULL; + m_underMouse = NULL; m_textCtrl = NULL; m_renameTimer = NULL; + m_freezeCount = 0; + m_findTimer = NULL; - m_lastOnSame = FALSE; + m_dropEffectAboveItem = false; + + m_lastOnSame = false; +#ifdef __WXMAC_CARBON__ + m_normalFont.MacCreateThemeFont( kThemeViewsFont ) ; +#else m_normalFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ); +#endif m_boldFont = wxFont(m_normalFont.GetPointSize(), m_normalFont.GetFamily(), m_normalFont.GetStyle(), @@ -776,13 +819,18 @@ bool wxGenericTreeCtrl::Create(wxWindow *parent, SetValidator( validator ); #endif - SetForegroundColour( wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT) ); - SetBackgroundColour( wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX) ); + wxVisualAttributes attr = GetDefaultAttributes(); + SetOwnForegroundColour( attr.colFg ); + SetOwnBackgroundColour( attr.colBg ); + if (!m_hasFont) + SetOwnFont(attr.font); // m_dottedPen = wxPen( "grey", 0, wxDOT ); too slow under XFree86 m_dottedPen = wxPen( wxT("grey"), 0, 0 ); - return TRUE; + SetBestSize(size); + + return true; } wxGenericTreeCtrl::~wxGenericTreeCtrl() @@ -809,22 +857,37 @@ wxGenericTreeCtrl::~wxGenericTreeCtrl() size_t wxGenericTreeCtrl::GetCount() const { - return m_anchor == NULL ? 0u : m_anchor->GetChildrenCount(); + if ( !m_anchor ) + { + // the tree is empty + return 0; + } + + size_t count = m_anchor->GetChildrenCount(); + if ( !HasFlag(wxTR_HIDE_ROOT) ) + { + // take the root itself into account + count++; + } + + return count; } void wxGenericTreeCtrl::SetIndent(unsigned int indent) { m_indent = (unsigned short) indent; - m_dirty = TRUE; + m_dirty = true; } void wxGenericTreeCtrl::SetSpacing(unsigned int spacing) { m_spacing = (unsigned short) spacing; - m_dirty = TRUE; + m_dirty = true; } -size_t wxGenericTreeCtrl::GetChildrenCount(const wxTreeItemId& item, bool recursively) +size_t +wxGenericTreeCtrl::GetChildrenCount(const wxTreeItemId& item, + bool recursively) const { wxCHECK_MSG( item.IsOk(), 0u, wxT("invalid tree item") ); @@ -845,7 +908,7 @@ void wxGenericTreeCtrl::SetWindowStyle(const long styles) // 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; } // ----------------------------------------------------------------------------- @@ -854,7 +917,7 @@ void wxGenericTreeCtrl::SetWindowStyle(const long styles) wxString wxGenericTreeCtrl::GetItemText(const wxTreeItemId& item) const { - wxCHECK_MSG( item.IsOk(), wxT(""), wxT("invalid tree item") ); + wxCHECK_MSG( item.IsOk(), wxEmptyString, wxT("invalid tree item") ); return ((wxGenericTreeItem*) item.m_pItem)->GetText(); } @@ -927,6 +990,9 @@ void wxGenericTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *da { wxCHECK_RET( item.IsOk(), wxT("invalid tree item") ); + if (data) + data->SetId( item ); + ((wxGenericTreeItem*) item.m_pItem)->SetData(data); } @@ -952,6 +1018,25 @@ void wxGenericTreeCtrl::SetItemBold(const wxTreeItemId& item, bool bold) } } +void wxGenericTreeCtrl::SetItemDropHighlight(const wxTreeItemId& item, + bool highlight) +{ + wxCHECK_RET( item.IsOk(), wxT("invalid tree item") ); + + wxColour fg, bg; + + if (highlight) + { + bg = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT); + fg = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT); + } + + wxGenericTreeItem *pItem = (wxGenericTreeItem*) item.m_pItem; + pItem->Attr().SetTextColour(fg); + pItem->Attr().SetBackgroundColour(bg); + RefreshLine(pItem); +} + void wxGenericTreeCtrl::SetItemTextColour(const wxTreeItemId& item, const wxColour& col) { @@ -994,7 +1079,7 @@ bool wxGenericTreeCtrl::SetFont( const wxFont &font ) m_normalFont.GetFaceName(), m_normalFont.GetEncoding()); - return TRUE; + return true; } @@ -1004,7 +1089,7 @@ bool wxGenericTreeCtrl::SetFont( const wxFont &font ) bool wxGenericTreeCtrl::IsVisible(const wxTreeItemId& item) const { - wxCHECK_MSG( item.IsOk(), FALSE, wxT("invalid tree item") ); + wxCHECK_MSG( item.IsOk(), false, wxT("invalid tree item") ); // An item is only visible if it's not a descendant of a collapsed item wxGenericTreeItem *pItem = (wxGenericTreeItem*) item.m_pItem; @@ -1012,7 +1097,7 @@ bool wxGenericTreeCtrl::IsVisible(const wxTreeItemId& item) const while (parent) { if (!parent->IsExpanded()) - return FALSE; + return false; parent = parent->GetParent(); } @@ -1023,20 +1108,20 @@ bool wxGenericTreeCtrl::IsVisible(const wxTreeItemId& item) const wxRect rect; if (!GetBoundingRect(item, rect)) - return FALSE; + return false; if (rect.GetWidth() == 0 || rect.GetHeight() == 0) - return FALSE; + return false; if (rect.GetBottom() < 0 || rect.GetTop() > clientSize.y) - return FALSE; + return false; if (rect.GetRight() < 0 || rect.GetLeft() > clientSize.x) - return FALSE; + return false; - return TRUE; + return true; } bool wxGenericTreeCtrl::ItemHasChildren(const wxTreeItemId& item) const { - wxCHECK_MSG( item.IsOk(), FALSE, wxT("invalid tree item") ); + wxCHECK_MSG( item.IsOk(), false, wxT("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 @@ -1048,21 +1133,21 @@ bool wxGenericTreeCtrl::ItemHasChildren(const wxTreeItemId& item) const bool wxGenericTreeCtrl::IsExpanded(const wxTreeItemId& item) const { - wxCHECK_MSG( item.IsOk(), FALSE, wxT("invalid tree item") ); + wxCHECK_MSG( item.IsOk(), false, wxT("invalid tree item") ); return ((wxGenericTreeItem*) item.m_pItem)->IsExpanded(); } bool wxGenericTreeCtrl::IsSelected(const wxTreeItemId& item) const { - wxCHECK_MSG( item.IsOk(), FALSE, wxT("invalid tree item") ); + wxCHECK_MSG( item.IsOk(), false, wxT("invalid tree item") ); return ((wxGenericTreeItem*) item.m_pItem)->IsSelected(); } bool wxGenericTreeCtrl::IsBold(const wxTreeItemId& item) const { - wxCHECK_MSG( item.IsOk(), FALSE, wxT("invalid tree item") ); + wxCHECK_MSG( item.IsOk(), false, wxT("invalid tree item") ); return ((wxGenericTreeItem*) item.m_pItem)->IsBold(); } @@ -1257,7 +1342,7 @@ wxTreeItemId wxGenericTreeCtrl::GetPrevVisible(const wxTreeItemId& item) const // called by wxTextTreeCtrl when it marks itself for deletion void wxGenericTreeCtrl::ResetTextControl() { - m_textCtrl = NULL; + m_textCtrl = NULL; } // find the first item starting with the given prefix after the given item @@ -1323,7 +1408,7 @@ wxTreeItemId wxGenericTreeCtrl::DoInsertItem(const wxTreeItemId& parentId, return AddRoot(text, image, selImage, data); } - m_dirty = TRUE; // do this first so stuff below doesn't cause flicker + m_dirty = true; // do this first so stuff below doesn't cause flicker wxGenericTreeItem *item = new wxGenericTreeItem( parent, text, image, selImage, data ); @@ -1344,7 +1429,7 @@ wxTreeItemId wxGenericTreeCtrl::AddRoot(const wxString& text, { wxCHECK_MSG( !m_anchor, wxTreeItemId(), wxT("tree can have only one root") ); - m_dirty = TRUE; // do this first so stuff below doesn't cause flicker + m_dirty = true; // do this first so stuff below doesn't cause flicker m_anchor = new wxGenericTreeItem((wxGenericTreeItem *)NULL, text, image, selImage, data); @@ -1365,7 +1450,7 @@ wxTreeItemId wxGenericTreeCtrl::AddRoot(const wxString& text, if (!HasFlag(wxTR_MULTIPLE)) { m_current = m_key_current = m_anchor; - m_current->SetHilight( TRUE ); + m_current->SetHilight( true ); } return m_anchor; @@ -1443,20 +1528,46 @@ void wxGenericTreeCtrl::SendDeleteEvent(wxGenericTreeItem *item) ProcessEvent( event ); } +// Don't leave edit or selection on a child which is about to disappear +void wxGenericTreeCtrl::ChildrenClosing(wxGenericTreeItem* item) +{ + if (m_textCtrl != NULL && item != m_textCtrl->item() && IsDescendantOf(item, m_textCtrl->item())) { + m_textCtrl->StopEditing(); + } + if (item != m_key_current && IsDescendantOf(item, m_key_current)) { + m_key_current = NULL; + } + if (IsDescendantOf(item, m_select_me)) { + m_select_me = item; + } + if (item != m_current && IsDescendantOf(item, m_current)) { + m_current->SetHilight( false ); + m_current = NULL; + m_select_me = item; + } +} + void wxGenericTreeCtrl::DeleteChildren(const wxTreeItemId& itemId) { - m_dirty = TRUE; // do this first so stuff below doesn't cause flicker + m_dirty = true; // do this first so stuff below doesn't cause flicker wxGenericTreeItem *item = (wxGenericTreeItem*) itemId.m_pItem; + ChildrenClosing(item); item->DeleteChildren(this); } void wxGenericTreeCtrl::Delete(const wxTreeItemId& itemId) { - m_dirty = TRUE; // do this first so stuff below doesn't cause flicker + m_dirty = true; // do this first so stuff below doesn't cause flicker wxGenericTreeItem *item = (wxGenericTreeItem*) itemId.m_pItem; + if (m_textCtrl != NULL && IsDescendantOf(item, m_textCtrl->item())) + { + // can't delete the item being edited, cancel editing it first + m_textCtrl->StopEditing(); + } + wxGenericTreeItem *parent = item->GetParent(); // don't keep stale pointers around! @@ -1465,7 +1576,7 @@ void wxGenericTreeCtrl::Delete(const wxTreeItemId& itemId) // Don't silently change the selection: // do it properly in idle time, so event // handlers get called. - + // m_key_current = parent; m_key_current = NULL; } @@ -1482,7 +1593,7 @@ void wxGenericTreeCtrl::Delete(const wxTreeItemId& itemId) // Don't silently change the selection: // do it properly in idle time, so event // handlers get called. - + // m_current = parent; m_current = NULL; m_select_me = parent; @@ -1502,6 +1613,10 @@ void wxGenericTreeCtrl::Delete(const wxTreeItemId& itemId) // and delete all of its children and the item itself now item->DeleteChildren(this); SendDeleteEvent(item); + + if (item == m_select_me) + m_select_me = NULL; + delete item; } @@ -1584,6 +1699,7 @@ void wxGenericTreeCtrl::Collapse(const wxTreeItemId& itemId) return; } + ChildrenClosing(item); item->Collapse(); #if 0 // TODO why should items be collapsed recursively? @@ -1623,7 +1739,7 @@ void wxGenericTreeCtrl::Unselect() { if (m_current) { - m_current->SetHilight( FALSE ); + m_current->SetHilight( false ); RefreshLine( m_current ); m_current = NULL; @@ -1635,7 +1751,7 @@ void wxGenericTreeCtrl::UnselectAllChildren(wxGenericTreeItem *item) { if (item->IsSelected()) { - item->SetHilight(FALSE); + item->SetHilight(false); RefreshLine(item); } @@ -1681,7 +1797,7 @@ bool wxGenericTreeCtrl::TagNextChildren(wxGenericTreeItem *crt_item, wxGenericTr size_t count = children.Count(); for (size_t n=(size_t)(index+1); nHasChildren()) { @@ -1702,30 +1818,21 @@ bool wxGenericTreeCtrl::TagAllChildrenUntilLast(wxGenericTreeItem *crt_item, wxG for ( size_t n = 0; n < count; ++n ) { if (TagAllChildrenUntilLast(children[n], last_item, select)) - return TRUE; + return true; } } - return FALSE; + return false; } void wxGenericTreeCtrl::SelectItemRange(wxGenericTreeItem *item1, wxGenericTreeItem *item2) { - // item2 is not necessary after item1 - wxGenericTreeItem *first=NULL, *last=NULL; m_select_me = NULL; + // item2 is not necessary after item1 // choice first' and 'last' between item1 and item2 - if (item1->GetY()GetY()) - { - first=item1; - last=item2; - } - else - { - first=item2; - last=item1; - } + wxGenericTreeItem *first= (item1->GetY()GetY()) ? item1 : item2; + wxGenericTreeItem *last = (item1->GetY()GetY()) ? item2 : item1; bool select = m_current->IsSelected(); @@ -1735,14 +1842,14 @@ void wxGenericTreeCtrl::SelectItemRange(wxGenericTreeItem *item1, wxGenericTreeI TagNextChildren(first,last,select); } -void wxGenericTreeCtrl::SelectItem(const wxTreeItemId& itemId, - bool unselect_others, - bool extended_select) +void wxGenericTreeCtrl::DoSelectItem(const wxTreeItemId& itemId, + bool unselect_others, + bool extended_select) { wxCHECK_RET( itemId.IsOk(), wxT("invalid tree item") ); m_select_me = NULL; - + bool is_single=!(GetWindowStyleFlag() & wxTR_MULTIPLE); wxGenericTreeItem *item = (wxGenericTreeItem*) itemId.m_pItem; @@ -1754,8 +1861,8 @@ void wxGenericTreeCtrl::SelectItem(const wxTreeItemId& itemId, { if (item->IsSelected()) return; // nothing to do - unselect_others = TRUE; - extended_select = FALSE; + unselect_others = true; + extended_select = false; } else if ( unselect_others && item->IsSelected() ) { @@ -1805,7 +1912,7 @@ void wxGenericTreeCtrl::SelectItem(const wxTreeItemId& itemId, } else { - bool select=TRUE; // the default + bool select = true; // the default // Check if we need to toggle hilight (ctrl mode) if (!unselect_others) @@ -1820,6 +1927,22 @@ void wxGenericTreeCtrl::SelectItem(const wxTreeItemId& itemId, GetEventHandler()->ProcessEvent( event ); } +void wxGenericTreeCtrl::SelectItem(const wxTreeItemId& itemId, bool select) +{ + if ( select ) + { + DoSelectItem(itemId); + } + else // deselect + { + wxGenericTreeItem *item = (wxGenericTreeItem*) itemId.m_pItem; + wxCHECK_RET( item, wxT("SelectItem(): invalid tree item") ); + + item->SetHilight(false); + RefreshLine(item); + } +} + void wxGenericTreeCtrl::FillArray(wxGenericTreeItem *item, wxArrayTreeItemIds &array) const { @@ -1850,6 +1973,8 @@ size_t wxGenericTreeCtrl::GetSelections(wxArrayTreeItemIds &array) const void wxGenericTreeCtrl::EnsureVisible(const wxTreeItemId& item) { + wxCHECK_RET( item.IsOk(), wxT("invalid tree item") ); + if (!item.IsOk()) return; wxGenericTreeItem *gitem = (wxGenericTreeItem*) item.m_pItem; @@ -1886,8 +2011,12 @@ void wxGenericTreeCtrl::ScrollTo(const wxTreeItemId &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) wxYieldIfNeeded(); - + if (m_dirty) +#if defined( __WXMSW__ ) || defined(__WXMAC__) + Update(); +#else + wxYieldIfNeeded(); +#endif wxGenericTreeItem *gitem = (wxGenericTreeItem*) item.m_pItem; // now scroll to the item @@ -1958,7 +2087,7 @@ void wxGenericTreeCtrl::SortChildren(const wxTreeItemId& itemId) wxArrayGenericTreeItems& children = item->GetChildren(); if ( children.Count() > 1 ) { - m_dirty = TRUE; + m_dirty = true; s_treeBeingSorted = this; children.Sort(tree_ctrl_compare_func); @@ -2025,8 +2154,8 @@ void wxGenericTreeCtrl::SetImageList(wxImageList *imageList) { if (m_ownsImageListNormal) delete m_imageListNormal; m_imageListNormal = imageList; - m_ownsImageListNormal = FALSE; - m_dirty = TRUE; + m_ownsImageListNormal = false; + m_dirty = true; // Don't do any drawing if we're setting the list to NULL, // since we may be in the process of deleting the tree control. if (imageList) @@ -2037,34 +2166,34 @@ void wxGenericTreeCtrl::SetStateImageList(wxImageList *imageList) { if (m_ownsImageListState) delete m_imageListState; m_imageListState = imageList; - m_ownsImageListState = FALSE; + m_ownsImageListState = false; } void wxGenericTreeCtrl::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 wxGenericTreeCtrl::AssignImageList(wxImageList *imageList) { SetImageList(imageList); - m_ownsImageListNormal = TRUE; + m_ownsImageListNormal = true; } void wxGenericTreeCtrl::AssignStateImageList(wxImageList *imageList) { SetStateImageList(imageList); - m_ownsImageListState = TRUE; + m_ownsImageListState = true; } void wxGenericTreeCtrl::AssignButtonsImageList(wxImageList *imageList) { SetButtonsImageList(imageList); - m_ownsImageListButtons = TRUE; + m_ownsImageListButtons = true; } // ----------------------------------------------------------------------------- @@ -2328,6 +2457,12 @@ void wxGenericTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level 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, @@ -2335,9 +2470,7 @@ void wxGenericTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level wxRect(x - wImage/2, y_mid - hImage/2, wImage, hImage), - item->IsExpanded() - ? wxCONTROL_EXPANDED - : 0 + flag ); } } @@ -2363,7 +2496,7 @@ void wxGenericTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level if (HasButtons()) y_mid += 5; // Only draw the portion of the line that is visible, in case it is huge - wxCoord xOrigin=0, yOrigin=0, width, height; + wxCoord xOrigin=0, yOrigin=0, width, height; dc.GetDeviceOrigin(&xOrigin, &yOrigin); yOrigin = abs(yOrigin); GetClientSize(&width, &height); @@ -2396,7 +2529,7 @@ void wxGenericTreeCtrl::DrawDropEffect(wxGenericTreeItem *item) { // draw a line under the drop target because the item will be // dropped there - DrawLine(item, TRUE /* below */); + DrawLine(item, !m_dropEffectAboveItem ); } SetCursor(wxCURSOR_BULLSEYE); @@ -2446,7 +2579,7 @@ void wxGenericTreeCtrl::DrawLine(const wxTreeItemId &item, bool below) } // ----------------------------------------------------------------------------- -// wxWindows callbacks +// wxWidgets callbacks // ----------------------------------------------------------------------------- void wxGenericTreeCtrl::OnPaint( wxPaintEvent &WXUNUSED(event) ) @@ -2470,7 +2603,7 @@ void wxGenericTreeCtrl::OnPaint( wxPaintEvent &WXUNUSED(event) ) void wxGenericTreeCtrl::OnSetFocus( wxFocusEvent &event ) { - m_hasFocus = TRUE; + m_hasFocus = true; RefreshSelected(); @@ -2479,7 +2612,7 @@ void wxGenericTreeCtrl::OnSetFocus( wxFocusEvent &event ) void wxGenericTreeCtrl::OnKillFocus( wxFocusEvent &event ) { - m_hasFocus = FALSE; + m_hasFocus = false; RefreshSelected(); @@ -2507,7 +2640,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) bool is_multiple, extended_select, unselect_others; EventFlagsToSelType(GetWindowStyleFlag(), event.ShiftDown(), - event.ControlDown(), + event.CmdDown(), is_multiple, extended_select, unselect_others); // + : Expand @@ -2550,6 +2683,14 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) } break; + case WXK_MENU: + { + wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_MENU, GetId() ); + event.m_item = m_current; + event.SetEventObject( this ); + GetEventHandler()->ProcessEvent( event ); + break; + } case ' ': case WXK_RETURN: if ( !event.HasModifiers() ) @@ -2588,7 +2729,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) if (current == GetFirstChild( prev, cookie )) { // otherwise we return to where we came from - SelectItem( prev, unselect_others, extended_select ); + DoSelectItem( prev, unselect_others, extended_select ); m_key_current= (wxGenericTreeItem*) prev.m_pItem; break; } @@ -2605,7 +2746,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) } } - SelectItem( prev, unselect_others, extended_select ); + DoSelectItem( prev, unselect_others, extended_select ); m_key_current=(wxGenericTreeItem*) prev.m_pItem; } } @@ -2622,7 +2763,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) } if (prev) { - SelectItem( prev, unselect_others, extended_select ); + DoSelectItem( prev, unselect_others, extended_select ); } } break; @@ -2639,7 +2780,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) { wxTreeItemIdValue cookie; wxTreeItemId child = GetFirstChild( m_key_current, cookie ); - SelectItem( child, unselect_others, extended_select ); + DoSelectItem( child, unselect_others, extended_select ); m_key_current=(wxGenericTreeItem*) child.m_pItem; } else @@ -2656,7 +2797,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) } if (next) { - SelectItem( next, unselect_others, extended_select ); + DoSelectItem( next, unselect_others, extended_select ); m_key_current=(wxGenericTreeItem*) next.m_pItem; } } @@ -2674,7 +2815,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) // 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 + // true, but GetLastChild() returned invalid item if ( !lastChild ) break; @@ -2683,7 +2824,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) if ( last.IsOk() ) { - SelectItem( last, unselect_others, extended_select ); + DoSelectItem( last, unselect_others, extended_select ); } } break; @@ -2703,7 +2844,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) break; } - SelectItem( prev, unselect_others, extended_select ); + DoSelectItem( prev, unselect_others, extended_select ); } break; @@ -2715,9 +2856,9 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) (keyCode >= 'A' && keyCode <= 'Z' ))) { // find the next item starting with the given prefix - char ch = (char)keyCode; + wxChar ch = (wxChar)keyCode; - wxTreeItemId id = FindItem(m_current, m_findPrefix + (wxChar)ch); + wxTreeItemId id = FindItem(m_current, m_findPrefix + ch); if ( !id.IsOk() ) { // no such item @@ -2780,7 +2921,7 @@ bool wxGenericTreeCtrl::GetBoundingRect(const wxTreeItemId& item, wxRect& rect, bool WXUNUSED(textOnly)) const { - wxCHECK_MSG( item.IsOk(), FALSE, _T("invalid item in wxGenericTreeCtrl::GetBoundingRect") ); + wxCHECK_MSG( item.IsOk(), false, _T("invalid item in wxGenericTreeCtrl::GetBoundingRect") ); wxGenericTreeItem *i = (wxGenericTreeItem*) item.m_pItem; @@ -2793,7 +2934,7 @@ bool wxGenericTreeCtrl::GetBoundingRect(const wxTreeItemId& item, //rect.height = i->GetHeight(); rect.height = GetLineHeight(i); - return TRUE; + return true; } void wxGenericTreeCtrl::Edit( const wxTreeItemId& item ) @@ -2815,7 +2956,11 @@ void wxGenericTreeCtrl::Edit( const wxTreeItemId& item ) // question might just have been added and no screen // update taken place. if ( m_dirty ) +#if defined( __WXMSW__ ) || defined(__WXMAC__) + Update(); +#else wxYieldIfNeeded(); +#endif m_textCtrl = new wxTreeTextCtrl(this, itemEdit); @@ -2837,7 +2982,7 @@ bool wxGenericTreeCtrl::OnRenameAccept(wxGenericTreeItem *item, le.m_item = item; le.SetEventObject( this ); le.m_label = value; - le.m_editCancelled = FALSE; + le.m_editCancelled = false; return !GetEventHandler()->ProcessEvent( le ) || le.IsAllowed(); } @@ -2849,14 +2994,11 @@ void wxGenericTreeCtrl::OnRenameCancelled(wxGenericTreeItem *item) le.m_item = item; le.SetEventObject( this ); le.m_label = wxEmptyString; - le.m_editCancelled = TRUE; + le.m_editCancelled = true; GetEventHandler()->ProcessEvent( le ); } - - - void wxGenericTreeCtrl::OnRenameTimer() { Edit( m_current ); @@ -2866,6 +3008,62 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) { if ( !m_anchor ) return; + wxPoint pt = CalcUnscrolledPosition(event.GetPosition()); + + // Is the mouse over a tree item button? + int flags = 0; + wxGenericTreeItem *thisItem = m_anchor->HitTest(pt, this, flags, 0); + wxGenericTreeItem *underMouse = thisItem; +#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 + wxGenericTreeItem *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 = thisItem; + + // 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.m_item = hoverItem; + hevent.SetEventObject(this); + + if ( GetEventHandler()->ProcessEvent(hevent) && hevent.IsAllowed() ) + { + SetToolTip(hevent.m_label); + } + } +#endif + // 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 @@ -2881,9 +3079,8 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) return; } - wxPoint pt = CalcUnscrolledPosition(event.GetPosition()); - int flags = 0; + flags = 0; wxGenericTreeItem *item = m_anchor->HitTest(pt, this, flags, 0); if ( event.Dragging() && !m_isDragging ) @@ -2906,6 +3103,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) wxTreeEvent nevent( command, GetId() ); nevent.m_item = m_current; nevent.SetEventObject(this); + nevent.SetPoint(pt); // by default the dragging is not supported, the user code must // explicitly allow the event for it to take place @@ -2914,7 +3112,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) if ( GetEventHandler()->ProcessEvent(nevent) && nevent.IsAllowed() ) { // we're going to drag this item - m_isDragging = TRUE; + m_isDragging = true; // remember the old cursor because we will change it while // dragging @@ -2927,7 +3125,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) if ( m_oldSelection ) { - m_oldSelection->SetHilight(FALSE); + m_oldSelection->SetHilight(false); RefreshLine(m_oldSelection); } } @@ -2935,7 +3133,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) CaptureMouse(); } } - else if ( event.Moving() ) + else if ( event.Dragging() ) { if ( item != m_dropTarget ) { @@ -2947,7 +3145,11 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) // highlight the current drop target if any DrawDropEffect(m_dropTarget); +#if defined(__WXMSW__) || defined(__WXMAC__) || defined(__WXGTK20__) + Update(); +#else wxYieldIfNeeded(); +#endif } } else if ( (event.LeftUp() || event.RightUp()) && m_isDragging ) @@ -2957,7 +3159,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) if ( m_oldSelection ) { - m_oldSelection->SetHilight(TRUE); + m_oldSelection->SetHilight(true); RefreshLine(m_oldSelection); m_oldSelection = (wxGenericTreeItem *)NULL; } @@ -2971,17 +3173,31 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) (void)GetEventHandler()->ProcessEvent(event); - m_isDragging = FALSE; + m_isDragging = false; m_dropTarget = (wxGenericTreeItem *)NULL; ReleaseMouse(); SetCursor(m_oldCursor); +#if defined( __WXMSW__ ) || defined(__WXMAC__) + Update(); +#else wxYieldIfNeeded(); +#endif } else { + // If we got to this point, we are not dragging or moving the mouse. + // Because the code in carbon/toplevel.cpp will only set focus to the tree + // if we skip for EVT_LEFT_DOWN, we MUST skip this event here for focus to work. + // We skip even if we didn't hit an item because we still should + // restore focus to the tree control even if we didn't exactly hit an item. + if ( event.LeftDown() ) + { + event.Skip(); + } + // here we process only the messages which happen on tree items m_dragCount = 0; @@ -2990,11 +3206,18 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) if ( event.RightDown() ) { + // If the item is already selected, do not update the selection. + // Multi-selections should not be cleared if a selected item is clicked. + if (!IsSelected(item)) + { + DoSelectItem(item, true, false); + } + wxTreeEvent nevent(wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK, GetId()); nevent.m_item = item; nevent.m_pointDrag = CalcScrolledPosition(pt); nevent.SetEventObject(this); - GetEventHandler()->ProcessEvent(nevent); + event.Skip(!GetEventHandler()->ProcessEvent(nevent)); } else if ( event.LeftUp() ) { @@ -3006,10 +3229,10 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) size_t count = GetSelections(selections); if (count > 1 && - !event.ControlDown() && + !event.CmdDown() && !event.ShiftDown()) { - SelectItem(item, true, false); + DoSelectItem(item, true, false); } } @@ -3029,10 +3252,10 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) m_renameTimer = new wxTreeRenameTimer( this ); } - m_renameTimer->Start( wxTreeRenameTimer::DELAY, TRUE ); + m_renameTimer->Start( wxTreeRenameTimer::DELAY, true ); } - m_lastOnSame = FALSE; + m_lastOnSame = false; } } else // !RightDown() && !LeftUp() ==> LeftDown() || LeftDClick() @@ -3060,17 +3283,17 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) // user clicked outside of the present selection. // otherwise, perform the deselection on mouse-up. // this allows multiple drag and drop to work. - - if (!IsSelected(item)) + // but if Cmd is down, toggle selection of the clicked item + if (!IsSelected(item) || event.CmdDown()) { // how should the selection work for this event? bool is_multiple, extended_select, unselect_others; EventFlagsToSelType(GetWindowStyleFlag(), event.ShiftDown(), - event.ControlDown(), + event.CmdDown(), is_multiple, extended_select, unselect_others); - SelectItem(item, unselect_others, extended_select); + DoSelectItem(item, unselect_others, extended_select); } @@ -3082,7 +3305,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) if ( m_renameTimer ) m_renameTimer->Stop(); - m_lastOnSame = FALSE; + m_lastOnSame = false; // send activate event first wxTreeEvent nevent( wxEVT_COMMAND_TREE_ITEM_ACTIVATED, GetId() ); @@ -3107,7 +3330,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) void wxGenericTreeCtrl::OnInternalIdle() { wxWindow::OnInternalIdle(); - + // Check if we need to select the root item // because nothing else has been selected. // Delaying it means that we can invoke event handlers @@ -3124,8 +3347,9 @@ void wxGenericTreeCtrl::OnInternalIdle() * we actually redraw the tree when everything is over */ if (!m_dirty) return; + if (m_freezeCount) return; - m_dirty = FALSE; + m_dirty = false; CalculatePositions(); Refresh(); @@ -3142,6 +3366,8 @@ void wxGenericTreeCtrl::CalculateSize( wxGenericTreeItem *item, wxDC &dc ) dc.SetFont(attr->GetFont()); else if ( item->IsBold() ) dc.SetFont(m_boldFont); + else + dc.SetFont(m_normalFont); dc.GetTextExtent( item->GetText(), &text_w, &text_h ); text_h+=2; @@ -3233,6 +3459,7 @@ void wxGenericTreeCtrl::CalculatePositions() void wxGenericTreeCtrl::RefreshSubtree(wxGenericTreeItem *item) { if (m_dirty) return; + if (m_freezeCount) return; wxSize client = GetClientSize(); @@ -3241,7 +3468,7 @@ void wxGenericTreeCtrl::RefreshSubtree(wxGenericTreeItem *item) rect.width = client.x; rect.height = client.y; - Refresh(TRUE, &rect); + Refresh(true, &rect); AdjustMyScrollbars(); } @@ -3249,17 +3476,20 @@ void wxGenericTreeCtrl::RefreshSubtree(wxGenericTreeItem *item) void wxGenericTreeCtrl::RefreshLine( wxGenericTreeItem *item ) { if (m_dirty) return; + if (m_freezeCount) return; wxRect rect; CalcScrolledPosition(0, item->GetY(), NULL, &rect.y); rect.width = GetClientSize().x; rect.height = GetLineHeight(item); //dc.GetCharHeight() + 6; - Refresh(TRUE, &rect); + Refresh(true, &rect); } void wxGenericTreeCtrl::RefreshSelected() { + if (m_freezeCount) return; + // TODO: this is awfully inefficient, we should keep the list of all // selected items internally, should be much faster if ( m_anchor ) @@ -3268,6 +3498,8 @@ void wxGenericTreeCtrl::RefreshSelected() void wxGenericTreeCtrl::RefreshSelectedUnder(wxGenericTreeItem *item) { + if (m_freezeCount) return; + if ( item->IsSelected() ) RefreshLine(item); @@ -3279,6 +3511,21 @@ void wxGenericTreeCtrl::RefreshSelectedUnder(wxGenericTreeItem *item) } } +void wxGenericTreeCtrl::Freeze() +{ + m_freezeCount++; +} + +void wxGenericTreeCtrl::Thaw() +{ + wxCHECK_RET( m_freezeCount > 0, _T("thawing unfrozen tree control?") ); + + if ( !--m_freezeCount ) + { + Refresh(); + } +} + // ---------------------------------------------------------------------------- // changing colours: we need to refresh the tree control // ---------------------------------------------------------------------------- @@ -3286,21 +3533,93 @@ void wxGenericTreeCtrl::RefreshSelectedUnder(wxGenericTreeItem *item) bool wxGenericTreeCtrl::SetBackgroundColour(const wxColour& colour) { if ( !wxWindow::SetBackgroundColour(colour) ) - return FALSE; + return false; + + if (m_freezeCount) return true; Refresh(); - return TRUE; + return true; } bool wxGenericTreeCtrl::SetForegroundColour(const wxColour& colour) { if ( !wxWindow::SetForegroundColour(colour) ) - return FALSE; + return false; + + if (m_freezeCount) return true; Refresh(); - return TRUE; + return true; +} + +// Process the tooltip event, to speed up event processing. +// Doesn't actually get a tooltip. +void wxGenericTreeCtrl::OnGetToolTip( wxTreeEvent &event ) +{ + event.Veto(); +} + + +wxSize wxGenericTreeCtrl::DoGetBestSize() const +{ + // something is better than nothing... + // 100x80 is what the MSW version will get from the default + // wxControl::DoGetBestSize + return wxSize(100,80); +} + + +// NOTE: If using the wxListBox visual attributes works everywhere then this can +// be removed, as well as the #else case below. +#define _USE_VISATTR 0 + +#if _USE_VISATTR +#include "wx/listbox.h" +#endif + +//static +wxVisualAttributes +#if _USE_VISATTR +wxGenericTreeCtrl::GetClassDefaultAttributes(wxWindowVariant variant) +#else +wxGenericTreeCtrl::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant)) +#endif +{ +#if _USE_VISATTR + // Use the same color scheme as wxListBox + return wxListBox::GetClassDefaultAttributes(variant); +#else + wxVisualAttributes attr; + attr.colFg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); + attr.colBg = wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX); + attr.font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); + return attr; +#endif +} + +#if WXWIN_COMPATIBILITY_2_4 + +int wxGenericTreeCtrl::GetItemSelectedImage(const wxTreeItemId& item) const +{ + return GetItemImage(item, wxTreeItemIcon_Selected); +} + +void wxGenericTreeCtrl::SetItemSelectedImage(const wxTreeItemId& item, int image) +{ + SetItemImage(item, image, wxTreeItemIcon_Selected); +} + +#endif // WXWIN_COMPATIBILITY_2_4 + +#if WXWIN_COMPATIBILITY_2_2 + +wxTreeItemId wxGenericTreeCtrl::GetParent(const wxTreeItemId& item) const +{ + return GetItemParent( item ); } +#endif // WXWIN_COMPATIBILITY_2_2 + #endif // wxUSE_TREECTRL