X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/642446e3bfa9364d8d2971f2f53a2d5588608c19..83c5d35ff3f22735f483edd56956b7a3baa6a798:/src/generic/treectlg.cpp diff --git a/src/generic/treectlg.cpp b/src/generic/treectlg.cpp index 87df794ad0..b0e71881b0 100644 --- a/src/generic/treectlg.cpp +++ b/src/generic/treectlg.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: treectlg.cpp +// Name: src/generic/treectlg.cpp // Purpose: generic tree control implementation // Author: Robert Roebling // Created: 01/02/97 @@ -26,14 +26,18 @@ #if wxUSE_TREECTRL -#include "wx/treebase.h" #include "wx/treectrl.h" + +#ifndef WX_PRECOMP + #include "wx/dcclient.h" + #include "wx/timer.h" + #include "wx/settings.h" + #include "wx/listbox.h" + #include "wx/textctrl.h" +#endif + #include "wx/generic/treectlg.h" -#include "wx/timer.h" -#include "wx/textctrl.h" #include "wx/imaglist.h" -#include "wx/settings.h" -#include "wx/dcclient.h" #include "wx/renderer.h" @@ -57,6 +61,9 @@ static const int NO_IMAGE = -1; static const int PIXELS_PER_UNIT = 10; +// the margin between the item image and the item text +static const int MARGIN_BETWEEN_IMAGE_AND_TEXT = 4; + // ----------------------------------------------------------------------------- // private classes // ----------------------------------------------------------------------------- @@ -196,9 +203,9 @@ public: wxGenericTreeItem *GetParent() const { return m_parent; } // operations - // deletes all children notifying the treectrl about it if !NULL - // pointer given - void DeleteChildren(wxGenericTreeCtrl *tree = NULL); + + // deletes all children notifying the treectrl about it + void DeleteChildren(wxGenericTreeCtrl *tree); // get count of all children (and grand children if 'recursively') size_t GetChildrenCount(bool recursively = true) const; @@ -374,7 +381,7 @@ wxTreeTextCtrl::wxTreeTextCtrl(wxGenericTreeCtrl *owner, if ( m_owner->m_imageListNormal ) { m_owner->m_imageListNormal->GetSize( image, image_w, image_h ); - image_w += 4; + image_w += MARGIN_BETWEEN_IMAGE_AND_TEXT; } else { @@ -545,11 +552,10 @@ void wxGenericTreeItem::DeleteChildren(wxGenericTreeCtrl *tree) for ( size_t n = 0; n < count; n++ ) { wxGenericTreeItem *child = m_children[n]; - if (tree) - tree->SendDeleteEvent(child); + tree->SendDeleteEvent(child); child->DeleteChildren(tree); - if (child == tree->m_select_me) + if ( child == tree->m_select_me ) tree->m_select_me = NULL; delete child; } @@ -747,6 +753,13 @@ void wxGenericTreeCtrl::Init() m_indent = 15; m_spacing = 18; +#ifdef __WXMAC__ + // OS X sel item highlight color differs from text highlight color, which is + // what wxSYS_COLOUR_HIGHLIGHT returns. + RGBColor hilight; + GetThemeBrushAsColor(kThemeBrushAlternatePrimaryHighlightColor, 32, true, &hilight); + m_hilightBrush = new wxBrush( wxColour(hilight.red, hilight.green, hilight.blue ), wxSOLID ); +#else m_hilightBrush = new wxBrush ( wxSystemSettings::GetColour @@ -755,7 +768,14 @@ void wxGenericTreeCtrl::Init() ), wxSOLID ); +#endif +#ifdef __WXMAC__ + // on Mac, this color also differs from the wxSYS_COLOUR_BTNSHADOW, enough to be noticable. + // I don't know if BTNSHADOW is appropriate in other contexts, so I'm just changing it here. + GetThemeBrushAsColor(kThemeBrushSecondaryHighlightColor, 32, true, &hilight); + m_hilightUnfocusedBrush = new wxBrush( wxColour(hilight.red, hilight.green, hilight.blue ), wxSOLID ); +#else m_hilightUnfocusedBrush = new wxBrush ( wxSystemSettings::GetColour @@ -764,7 +784,7 @@ void wxGenericTreeCtrl::Init() ), wxSOLID ); - +#endif m_imageListButtons = NULL; m_ownsImageListButtons = false; @@ -813,7 +833,14 @@ bool wxGenericTreeCtrl::Create(wxWindow *parent, style |= wxTR_NO_LINES; if (major < 10) style |= wxTR_ROW_LINES; + + if (style == 0 || style & wxTR_DEFAULT_STYLE) + style |= wxTR_FULL_ROW_HIGHLIGHT; + #endif // __WXMAC__ +#ifdef __WXGTK20__ + style |= wxTR_NO_LINES; +#endif if ( !wxControl::Create( parent, id, pos, size, style|wxHSCROLL|wxVSCROLL, @@ -861,7 +888,7 @@ wxGenericTreeCtrl::~wxGenericTreeCtrl() // accessors // ----------------------------------------------------------------------------- -size_t wxGenericTreeCtrl::GetCount() const +unsigned int wxGenericTreeCtrl::GetCount() const { if ( !m_anchor ) { @@ -869,7 +896,7 @@ size_t wxGenericTreeCtrl::GetCount() const return 0; } - size_t count = m_anchor->GetChildrenCount(); + unsigned int count = m_anchor->GetChildrenCount(); if ( !HasFlag(wxTR_HIDE_ROOT) ) { // take the root itself into account @@ -1015,6 +1042,12 @@ void wxGenericTreeCtrl::SetItemBold(const wxTreeItemId& item, bool bold) if ( pItem->IsBold() != bold ) { pItem->SetBold(bold); + + // recalculate the item size as bold and non bold fonts have different + // widths + wxClientDC dc(this); + CalculateSize(pItem, dc); + RefreshLine(pItem); } } @@ -1383,10 +1416,12 @@ wxTreeItemId wxGenericTreeCtrl::FindItem(const wxTreeItemId& idParent, } // and try all the items (stop when we get to the one we started from) - while ( id != idParent && !GetItemText(id).Lower().StartsWith(prefix) ) + while (id.IsOk() && id != idParent && !GetItemText(id).Lower().StartsWith(prefix) ) { id = GetNext(id); } + // If we haven't found the item, id.IsOk() will be false, as per + // documentation } return id; @@ -1487,9 +1522,7 @@ wxTreeItemId wxGenericTreeCtrl::DoInsertAfter(const wxTreeItemId& parentId, void wxGenericTreeCtrl::SendDeleteEvent(wxGenericTreeItem *item) { - wxTreeEvent event( wxEVT_COMMAND_TREE_DELETE_ITEM, GetId() ); - event.m_item = item; - event.SetEventObject( this ); + wxTreeEvent event(wxEVT_COMMAND_TREE_DELETE_ITEM, this, item); ProcessEvent( event ); } @@ -1607,9 +1640,7 @@ void wxGenericTreeCtrl::Expand(const wxTreeItemId& itemId) if ( item->IsExpanded() ) return; - wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_EXPANDING, GetId() ); - event.m_item = item; - event.SetEventObject( this ); + wxTreeEvent event(wxEVT_COMMAND_TREE_ITEM_EXPANDING, this, item); if ( ProcessEvent( event ) && !event.IsAllowed() ) { @@ -1626,25 +1657,6 @@ void wxGenericTreeCtrl::Expand(const wxTreeItemId& itemId) ProcessEvent( event ); } -void wxGenericTreeCtrl::ExpandAll(const wxTreeItemId& item) -{ - if ( !HasFlag(wxTR_HIDE_ROOT) || item != GetRootItem()) - { - Expand(item); - if ( !IsExpanded(item) ) - return; - } - - wxTreeItemIdValue cookie; - wxTreeItemId child = GetFirstChild(item, cookie); - while ( child.IsOk() ) - { - ExpandAll(child); - - child = GetNextChild(item, cookie); - } -} - void wxGenericTreeCtrl::Collapse(const wxTreeItemId& itemId) { wxCHECK_RET( !HasFlag(wxTR_HIDE_ROOT) || itemId != GetRootItem(), @@ -1655,9 +1667,7 @@ void wxGenericTreeCtrl::Collapse(const wxTreeItemId& itemId) if ( !item->IsExpanded() ) return; - wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_COLLAPSING, GetId() ); - event.m_item = item; - event.SetEventObject( this ); + wxTreeEvent event(wxEVT_COMMAND_TREE_ITEM_COLLAPSING, this, item); if ( ProcessEvent( event ) && !event.IsAllowed() ) { // cancelled by program @@ -1837,10 +1847,8 @@ void wxGenericTreeCtrl::DoSelectItem(const wxTreeItemId& itemId, return; } - wxTreeEvent event( wxEVT_COMMAND_TREE_SEL_CHANGING, GetId() ); - event.m_item = item; + wxTreeEvent event(wxEVT_COMMAND_TREE_SEL_CHANGING, this, item); event.m_itemOld = m_current; - event.SetEventObject( this ); // TODO : Here we don't send any selection mode yet ! if ( GetEventHandler()->ProcessEvent( event ) && !event.IsAllowed() ) @@ -1855,8 +1863,6 @@ void wxGenericTreeCtrl::DoSelectItem(const wxTreeItemId& itemId, parent = GetItemParent( parent ); } - EnsureVisible( itemId ); - // ctrl press if (unselect_others) { @@ -1888,6 +1894,11 @@ void wxGenericTreeCtrl::DoSelectItem(const wxTreeItemId& itemId, RefreshLine( m_current ); } + // This can cause idle processing to select the root + // if no item is selected, so it must be after the + // selection is set + EnsureVisible( itemId ); + event.SetEventType(wxEVT_COMMAND_TREE_SEL_CHANGED); GetEventHandler()->ProcessEvent( event ); } @@ -1902,9 +1913,16 @@ void wxGenericTreeCtrl::SelectItem(const wxTreeItemId& itemId, bool select) { wxGenericTreeItem *item = (wxGenericTreeItem*) itemId.m_pItem; wxCHECK_RET( item, wxT("SelectItem(): invalid tree item") ); + + wxTreeEvent event(wxEVT_COMMAND_TREE_SEL_CHANGING, this, item); + if ( GetEventHandler()->ProcessEvent( event ) && !event.IsAllowed() ) + return; item->SetHilight(false); RefreshLine(item); + + event.SetEventType(wxEVT_COMMAND_TREE_SEL_CHANGED); + GetEventHandler()->ProcessEvent( event ); } } @@ -1980,7 +1998,7 @@ void wxGenericTreeCtrl::ScrollTo(const wxTreeItemId &item) #if defined( __WXMSW__ ) || defined(__WXMAC__) Update(); #else - wxYieldIfNeeded(); + DoDirtyProcessing(); #endif wxGenericTreeItem *gitem = (wxGenericTreeItem*) item.m_pItem; @@ -2178,7 +2196,7 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc) if ( m_imageListNormal ) { m_imageListNormal->GetSize( image, image_w, image_h ); - image_w += 4; + image_w += MARGIN_BETWEEN_IMAGE_AND_TEXT; } else { @@ -2191,20 +2209,7 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc) if ( item->IsSelected() ) { -// under mac selections are only a rectangle in case they don't have the focus -#ifdef __WXMAC__ - if ( !m_hasFocus ) - { - dc.SetBrush( *wxTRANSPARENT_BRUSH ) ; - dc.SetPen( wxPen( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) , 1 , wxSOLID ) ) ; - } - else - { - dc.SetBrush( *m_hilightBrush ) ; - } -#else dc.SetBrush(*(m_hasFocus ? m_hilightBrush : m_hilightUnfocusedBrush)); -#endif drawItemBackground = true; } else @@ -2318,7 +2323,7 @@ void wxGenericTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level if (IsExposed(exposed_x, exposed_y, 10000, h)) // 10000 = very much { - wxPen *pen = + const wxPen *pen = #ifndef __WXMAC__ // don't draw rect outline if we already have the // background color under Mac @@ -2327,9 +2332,21 @@ void wxGenericTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level wxTRANSPARENT_PEN; wxColour colText; - if ( item->IsSelected() ) + if ( item->IsSelected() +#ifdef __WXMAC__ + // On wxMac, if the tree doesn't have the focus we draw an empty + // rectangle, so we want to make sure that the text is visible + // against the normal background, not the highlightbackground, so + // don't use the highlight text colour unless we have the focus. + && m_hasFocus +#endif + ) { +#ifdef __WXMAC__ + colText = *wxWHITE; +#else colText = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT); +#endif } else { @@ -2563,9 +2580,8 @@ void wxGenericTreeCtrl::OnKillFocus( wxFocusEvent &event ) void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) { - wxTreeEvent te( wxEVT_COMMAND_TREE_KEY_DOWN, GetId() ); + wxTreeEvent te( wxEVT_COMMAND_TREE_KEY_DOWN, this); te.m_evtKey = event; - te.SetEventObject( this ); if ( GetEventHandler()->ProcessEvent( te ) ) { // intercepted by the user code @@ -2585,6 +2601,14 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) event.CmdDown(), is_multiple, extended_select, unselect_others); + if (GetLayoutDirection() == wxLayout_RightToLeft) + { + if (event.GetKeyCode() == WXK_RIGHT) + event.m_keyCode = WXK_LEFT; + else if (event.GetKeyCode() == WXK_LEFT) + event.m_keyCode = WXK_RIGHT; + } + // + : Expand // - : Collaspe // * : Expand all/Collapse all @@ -2612,7 +2636,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) if ( !IsExpanded(m_current) ) { // expand all - ExpandAll(m_current); + ExpandAllChildren(m_current); break; } //else: fall through to Collapse() it @@ -2631,22 +2655,19 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) wxRect ItemRect; GetBoundingRect(m_current, ItemRect, true); - wxTreeEvent eventMenu( wxEVT_COMMAND_TREE_ITEM_MENU, GetId() ); - eventMenu.m_item = m_current; + wxTreeEvent eventMenu(wxEVT_COMMAND_TREE_ITEM_MENU, this, m_current); // Use the left edge, vertical middle eventMenu.m_pointDrag = wxPoint(ItemRect.GetX(), ItemRect.GetY() + ItemRect.GetHeight() / 2); - eventMenu.SetEventObject( this ); GetEventHandler()->ProcessEvent( eventMenu ); - break; } + break; + case ' ': case WXK_RETURN: if ( !event.HasModifiers() ) { - wxTreeEvent eventAct( wxEVT_COMMAND_TREE_ITEM_ACTIVATED, GetId() ); - eventAct.m_item = m_current; - eventAct.SetEventObject( this ); + wxTreeEvent eventAct(wxEVT_COMMAND_TREE_ITEM_ACTIVATED, this, m_current); GetEventHandler()->ProcessEvent( eventAct ); } @@ -2835,11 +2856,9 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) } } -wxTreeItemId wxGenericTreeCtrl::DoHitTest(const wxPoint& point, int& flags) +wxTreeItemId +wxGenericTreeCtrl::DoTreeHitTest(const wxPoint& point, int& flags) const { - // JACS: removed wxYieldIfNeeded() because it can cause the window - // to be deleted from under us if a close window event is pending - int w, h; GetSize(&w, &h); flags=0; @@ -2868,21 +2887,36 @@ wxTreeItemId wxGenericTreeCtrl::DoHitTest(const wxPoint& point, int& flags) // get the bounding rectangle of the item (or of its label only) bool wxGenericTreeCtrl::GetBoundingRect(const wxTreeItemId& item, wxRect& rect, - bool WXUNUSED(textOnly)) const + bool textOnly) const { wxCHECK_MSG( item.IsOk(), false, _T("invalid item in wxGenericTreeCtrl::GetBoundingRect") ); wxGenericTreeItem *i = (wxGenericTreeItem*) item.m_pItem; - int startX, startY; - GetViewStart(& startX, & startY); + if ( textOnly ) + { + rect.x = i->GetX(); + rect.width = i->GetWidth(); + + if ( m_imageListNormal ) + { + int image_w, image_h; + m_imageListNormal->GetSize( 0, image_w, image_h ); + rect.width += image_w + MARGIN_BETWEEN_IMAGE_AND_TEXT; + } + } + else // the entire line + { + rect.x = 0; + rect.width = GetClientSize().x; + } - 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.y = i->GetY(); rect.height = GetLineHeight(i); + // we have to return the logical coordinates, not physical ones + rect.SetTopLeft(CalcScrolledPosition(rect.GetTopLeft())); + return true; } @@ -2893,9 +2927,7 @@ wxTextCtrl *wxGenericTreeCtrl::EditLabel(const wxTreeItemId& item, wxGenericTreeItem *itemEdit = (wxGenericTreeItem *)item.m_pItem; - wxTreeEvent te( wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT, GetId() ); - te.m_item = itemEdit; - te.SetEventObject( this ); + wxTreeEvent te(wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT, this, itemEdit); if ( GetEventHandler()->ProcessEvent( te ) && !te.IsAllowed() ) { // vetoed by user @@ -2909,7 +2941,7 @@ wxTextCtrl *wxGenericTreeCtrl::EditLabel(const wxTreeItemId& item, #if defined( __WXMSW__ ) || defined(__WXMAC__) Update(); #else - wxYieldIfNeeded(); + DoDirtyProcessing(); #endif // TODO: use textCtrlClass here to create the control of correct class @@ -2939,9 +2971,7 @@ void wxGenericTreeCtrl::EndEditLabel(const wxTreeItemId& WXUNUSED(item), bool wxGenericTreeCtrl::OnRenameAccept(wxGenericTreeItem *item, const wxString& value) { - wxTreeEvent le( wxEVT_COMMAND_TREE_END_LABEL_EDIT, GetId() ); - le.m_item = item; - le.SetEventObject( this ); + wxTreeEvent le(wxEVT_COMMAND_TREE_END_LABEL_EDIT, this, item); le.m_label = value; le.m_editCancelled = false; @@ -2951,9 +2981,7 @@ bool wxGenericTreeCtrl::OnRenameAccept(wxGenericTreeItem *item, void wxGenericTreeCtrl::OnRenameCancelled(wxGenericTreeItem *item) { // let owner know that the edit was cancelled - wxTreeEvent le( wxEVT_COMMAND_TREE_END_LABEL_EDIT, GetId() ); - le.m_item = item; - le.SetEventObject( this ); + wxTreeEvent le(wxEVT_COMMAND_TREE_END_LABEL_EDIT, this, item); le.m_label = wxEmptyString; le.m_editCancelled = true; @@ -2967,7 +2995,7 @@ void wxGenericTreeCtrl::OnRenameTimer() void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) { - if ( !m_anchor ) return; + if ( !m_anchor )return; wxPoint pt = CalcUnscrolledPosition(event.GetPosition()); @@ -3014,9 +3042,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) 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); + wxTreeEvent hevent(wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP, this, hoverItem); if ( GetEventHandler()->ProcessEvent(hevent) && hevent.IsAllowed() ) { @@ -3025,11 +3051,12 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) } #endif - // we process left mouse up event (enables in-place edit), right down + // we process left mouse up event (enables in-place edit), middle/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.MiddleDown() || event.RightDown() || event.LeftDClick() || event.Dragging() || @@ -3061,10 +3088,8 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) ? wxEVT_COMMAND_TREE_BEGIN_RDRAG : wxEVT_COMMAND_TREE_BEGIN_DRAG; - wxTreeEvent nevent( command, GetId() ); - nevent.m_item = m_current; - nevent.SetEventObject(this); - nevent.SetPoint(pt); + wxTreeEvent nevent(command, this, m_current); + nevent.SetPoint(CalcScrolledPosition(pt)); // by default the dragging is not supported, the user code must // explicitly allow the event for it to take place @@ -3115,6 +3140,8 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) } else if ( (event.LeftUp() || event.RightUp()) && m_isDragging ) { + ReleaseMouse(); + // erase the highlighting DrawDropEffect(m_dropTarget); @@ -3126,19 +3153,15 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) } // generate the drag end event - wxTreeEvent eventEndDrag(wxEVT_COMMAND_TREE_END_DRAG, GetId()); + wxTreeEvent eventEndDrag(wxEVT_COMMAND_TREE_END_DRAG, this, item); - eventEndDrag.m_item = item; - eventEndDrag.m_pointDrag = pt; - eventEndDrag.SetEventObject(this); + eventEndDrag.m_pointDrag = CalcScrolledPosition(pt); (void)GetEventHandler()->ProcessEvent(eventEndDrag); m_isDragging = false; m_dropTarget = (wxGenericTreeItem *)NULL; - ReleaseMouse(); - SetCursor(m_oldCursor); #if defined( __WXMSW__ ) || defined(__WXMAC__) @@ -3174,20 +3197,22 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) DoSelectItem(item, true, false); } - wxTreeEvent nevent(wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK, GetId()); - nevent.m_item = item; + wxTreeEvent nevent(wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK, this, item); nevent.m_pointDrag = CalcScrolledPosition(pt); - nevent.SetEventObject(this); event.Skip(!GetEventHandler()->ProcessEvent(nevent)); // Consistent with MSW (for now), send the ITEM_MENU *after* // the RIGHT_CLICK event. TODO: This behavior may change. - wxTreeEvent nevent2(wxEVT_COMMAND_TREE_ITEM_MENU, GetId()); - nevent2.m_item = item; + wxTreeEvent nevent2(wxEVT_COMMAND_TREE_ITEM_MENU, this, item); nevent2.m_pointDrag = CalcScrolledPosition(pt); - nevent2.SetEventObject(this); GetEventHandler()->ProcessEvent(nevent2); } + else if ( event.MiddleDown() ) + { + wxTreeEvent nevent(wxEVT_COMMAND_TREE_ITEM_MIDDLE_CLICK, this, item); + nevent.m_pointDrag = CalcScrolledPosition(pt); + event.Skip(!GetEventHandler()->ProcessEvent(nevent)); + } else if ( event.LeftUp() ) { // this facilitates multiple-item drag-and-drop @@ -3227,7 +3252,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) m_lastOnSame = false; } } - else // !RightDown() && !LeftUp() ==> LeftDown() || LeftDClick() + else // !RightDown() && !MiddleDown() && !LeftUp() ==> LeftDown() || LeftDClick() { if ( event.LeftDown() ) { @@ -3277,10 +3302,8 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) m_lastOnSame = false; // send activate event first - wxTreeEvent nevent( wxEVT_COMMAND_TREE_ITEM_ACTIVATED, GetId() ); - nevent.m_item = item; + wxTreeEvent nevent(wxEVT_COMMAND_TREE_ITEM_ACTIVATED, this, item); nevent.m_pointDrag = CalcScrolledPosition(pt); - nevent.SetEventObject( this ); if ( !GetEventHandler()->ProcessEvent( nevent ) ) { // if the user code didn't process the activate event, @@ -3312,17 +3335,10 @@ void wxGenericTreeCtrl::OnInternalIdle() SelectItem(GetRootItem()); } - /* after all changes have been done to the tree control, - * we actually redraw the tree when everything is over */ - - if (!m_dirty) return; - if (m_freezeCount) return; - - m_dirty = false; - - CalculatePositions(); - Refresh(); - AdjustMyScrollbars(); + // after all changes have been done to the tree control, + // actually redraw the tree when everything is over + if (m_dirty) + DoDirtyProcessing(); } void wxGenericTreeCtrl::CalculateSize( wxGenericTreeItem *item, wxDC &dc ) @@ -3352,7 +3368,7 @@ void wxGenericTreeCtrl::CalculateSize( wxGenericTreeItem *item, wxDC &dc ) if ( m_imageListNormal ) { m_imageListNormal->GetSize( image, image_w, image_h ); - image_w += 4; + image_w += MARGIN_BETWEEN_IMAGE_AND_TEXT; } } @@ -3425,10 +3441,16 @@ void wxGenericTreeCtrl::CalculatePositions() CalculateLevel( m_anchor, dc, 0, y ); // start recursion } +void wxGenericTreeCtrl::Refresh(bool eraseBackground, const wxRect *rect) +{ + if ( !m_freezeCount ) + wxTreeCtrlBase::Refresh(eraseBackground, rect); +} + void wxGenericTreeCtrl::RefreshSubtree(wxGenericTreeItem *item) { - if (m_dirty) return; - if (m_freezeCount) return; + if (m_dirty || m_freezeCount) + return; wxSize client = GetClientSize(); @@ -3444,8 +3466,8 @@ void wxGenericTreeCtrl::RefreshSubtree(wxGenericTreeItem *item) void wxGenericTreeCtrl::RefreshLine( wxGenericTreeItem *item ) { - if (m_dirty) return; - if (m_freezeCount) return; + if (m_dirty || m_freezeCount) + return; wxRect rect; CalcScrolledPosition(0, item->GetY(), NULL, &rect.y); @@ -3457,7 +3479,8 @@ void wxGenericTreeCtrl::RefreshLine( wxGenericTreeItem *item ) void wxGenericTreeCtrl::RefreshSelected() { - if (m_freezeCount) return; + if (m_freezeCount) + return; // TODO: this is awfully inefficient, we should keep the list of all // selected items internally, should be much faster @@ -3467,7 +3490,8 @@ void wxGenericTreeCtrl::RefreshSelected() void wxGenericTreeCtrl::RefreshSelectedUnder(wxGenericTreeItem *item) { - if (m_freezeCount) return; + if (m_freezeCount) + return; if ( item->IsSelected() ) RefreshLine(item); @@ -3489,7 +3513,7 @@ void wxGenericTreeCtrl::Thaw() { wxCHECK_RET( m_freezeCount > 0, _T("thawing unfrozen tree control?") ); - if ( !--m_freezeCount ) + if ( --m_freezeCount == 0 ) { Refresh(); } @@ -3504,8 +3528,6 @@ bool wxGenericTreeCtrl::SetBackgroundColour(const wxColour& colour) if ( !wxWindow::SetBackgroundColour(colour) ) return false; - if (m_freezeCount) return true; - Refresh(); return true; @@ -3516,8 +3538,6 @@ bool wxGenericTreeCtrl::SetForegroundColour(const wxColour& colour) if ( !wxWindow::SetForegroundColour(colour) ) return false; - if (m_freezeCount) return true; - Refresh(); return true; @@ -3531,23 +3551,10 @@ void wxGenericTreeCtrl::OnGetToolTip( wxTreeEvent &event ) } -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 @@ -3582,4 +3589,16 @@ void wxGenericTreeCtrl::SetItemSelectedImage(const wxTreeItemId& item, int image #endif // WXWIN_COMPATIBILITY_2_4 +void wxGenericTreeCtrl::DoDirtyProcessing() +{ + if (m_freezeCount) + return; + + m_dirty = false; + + CalculatePositions(); + Refresh(); + AdjustMyScrollbars(); +} + #endif // wxUSE_TREECTRL