X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e8cf9a5f01ba57584f95934bdc3e18e06a4ae1cd..04bf2fb51514e3ec8631a1d8ea1f610fca851005:/src/generic/treectlg.cpp?ds=sidebyside diff --git a/src/generic/treectlg.cpp b/src/generic/treectlg.cpp index 70a21e2ced..2e2650bfed 100644 --- a/src/generic/treectlg.cpp +++ b/src/generic/treectlg.cpp @@ -17,10 +17,6 @@ // headers // ----------------------------------------------------------------------------- -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) - #pragma implementation "treectlg.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -31,6 +27,7 @@ #if wxUSE_TREECTRL #include "wx/treebase.h" +#include "wx/treectrl.h" #include "wx/generic/treectlg.h" #include "wx/timer.h" #include "wx/textctrl.h" @@ -60,6 +57,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 // ----------------------------------------------------------------------------- @@ -88,6 +88,24 @@ class WXDLLEXPORT wxTreeTextCtrl: public wxTextCtrl public: wxTreeTextCtrl(wxGenericTreeCtrl *owner, wxGenericTreeItem *item); + void EndEdit(bool discardChanges = false) + { + if ( discardChanges ) + { + StopEditing(); + } + else + { + m_aboutToFinish = true; + + // Notify the owner about the changes + AcceptChanges(); + + // Even if vetoed, close the control (consistent with MSW) + Finish(); + } + } + void StopEditing() { Finish(); @@ -108,6 +126,7 @@ private: wxGenericTreeItem *m_itemEdited; wxString m_startValue; bool m_finished; + bool m_aboutToFinish; DECLARE_EVENT_TABLE() DECLARE_NO_COPY_CLASS(wxTreeTextCtrl) @@ -262,12 +281,12 @@ private: int m_height; // height of this item // use bitfields to save size - int m_isCollapsed :1; - int m_hasHilight :1; // same as focused - int m_hasPlus :1; // used for item which doesn't have + unsigned int m_isCollapsed :1; + unsigned int m_hasHilight :1; // same as focused + unsigned int m_hasPlus :1; // used for item which doesn't have // children but has a [+] button - int m_isBold :1; // render the label in bold font - int m_ownsAttr :1; // delete attribute when done + unsigned int m_isBold :1; // render the label in bold font + unsigned int m_ownsAttr :1; // delete attribute when done DECLARE_NO_COPY_CLASS(wxGenericTreeItem) }; @@ -341,6 +360,7 @@ wxTreeTextCtrl::wxTreeTextCtrl(wxGenericTreeCtrl *owner, { m_owner = owner; m_finished = false; + m_aboutToFinish = false; int w = m_itemEdited->GetWidth(), h = m_itemEdited->GetHeight(); @@ -357,7 +377,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 { @@ -390,6 +410,12 @@ bool wxTreeTextCtrl::AcceptChanges() if ( value == m_startValue ) { // nothing changed, always accept + // 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; } @@ -407,7 +433,7 @@ bool wxTreeTextCtrl::AcceptChanges() void wxTreeTextCtrl::Finish() { - if ( !m_finished ) + if ( !m_finished ) { m_owner->ResetTextControl(); @@ -415,7 +441,7 @@ void wxTreeTextCtrl::Finish() m_finished = true; - m_owner->SetFocusIgnoringChildren(); + m_owner->SetFocus(); } } @@ -424,12 +450,7 @@ void wxTreeTextCtrl::OnChar( wxKeyEvent &event ) switch ( event.m_keyCode ) { case WXK_RETURN: - if ( AcceptChanges() ) - { - // Close the text control, changes were accepted - Finish(); - } - // else do nothing, do not accept and do not close + EndEdit(); break; case WXK_ESCAPE: @@ -463,16 +484,18 @@ void wxTreeTextCtrl::OnKeyUp( wxKeyEvent &event ) void wxTreeTextCtrl::OnKillFocus( wxFocusEvent &event ) { - if ( !m_finished ) + if ( !m_finished && !m_aboutToFinish ) { - AcceptChanges(); // 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): + // it could have problems with the cursor (e.g., in wxGTK). event.Skip(); } @@ -690,9 +713,9 @@ int wxGenericTreeItem::GetCurrentImage() const // wxGenericTreeCtrl implementation // ----------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxGenericTreeCtrl, wxScrolledWindow) +IMPLEMENT_DYNAMIC_CLASS(wxGenericTreeCtrl, wxControl) -BEGIN_EVENT_TABLE(wxGenericTreeCtrl,wxScrolledWindow) +BEGIN_EVENT_TABLE(wxGenericTreeCtrl, wxTreeCtrlBase) EVT_PAINT (wxGenericTreeCtrl::OnPaint) EVT_MOUSE_EVENTS (wxGenericTreeCtrl::OnMouse) EVT_CHAR (wxGenericTreeCtrl::OnChar) @@ -716,7 +739,10 @@ IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl, wxGenericTreeCtrl) void wxGenericTreeCtrl::Init() { - m_current = m_key_current = m_anchor = m_select_me = (wxGenericTreeItem *) NULL; + m_current = + m_key_current = + m_anchor = + m_select_me = (wxGenericTreeItem *) NULL; m_hasFocus = false; m_dirty = false; @@ -742,10 +768,8 @@ void wxGenericTreeCtrl::Init() wxSOLID ); - m_imageListNormal = m_imageListButtons = - m_imageListState = (wxImageList *) NULL; - m_ownsImageListNormal = m_ownsImageListButtons = - m_ownsImageListState = false; + m_imageListButtons = NULL; + m_ownsImageListButtons = false; m_dragCount = 0; m_isDragging = false; @@ -781,7 +805,7 @@ bool wxGenericTreeCtrl::Create(wxWindow *parent, const wxPoint& pos, const wxSize& size, long style, - const wxValidator& wxVALIDATOR_PARAM(validator), + const wxValidator& validator, const wxString& name ) { #ifdef __WXMAC__ @@ -794,8 +818,11 @@ bool wxGenericTreeCtrl::Create(wxWindow *parent, style |= wxTR_ROW_LINES; #endif // __WXMAC__ - wxScrolledWindow::Create( parent, id, pos, size, - style|wxHSCROLL|wxVSCROLL, name ); + if ( !wxControl::Create( parent, id, pos, size, + style|wxHSCROLL|wxVSCROLL, + validator, + name ) ) + return false; // If the tree display has no buttons, but does have // connecting lines, we can use a narrower layout. @@ -806,17 +833,12 @@ bool wxGenericTreeCtrl::Create(wxWindow *parent, m_spacing = 10; } -#if wxUSE_VALIDATORS - SetValidator( validator ); -#endif - 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 ); SetBestSize(size); @@ -834,10 +856,6 @@ wxGenericTreeCtrl::~wxGenericTreeCtrl() delete m_renameTimer; delete m_findTimer; - if (m_ownsImageListNormal) - delete m_imageListNormal; - if (m_ownsImageListState) - delete m_imageListState; if (m_ownsImageListButtons) delete m_imageListButtons; } @@ -870,12 +888,6 @@ void wxGenericTreeCtrl::SetIndent(unsigned int indent) m_dirty = true; } -void wxGenericTreeCtrl::SetSpacing(unsigned int spacing) -{ - m_spacing = (unsigned short) spacing; - m_dirty = true; -} - size_t wxGenericTreeCtrl::GetChildrenCount(const wxTreeItemId& item, bool recursively) const @@ -887,7 +899,8 @@ wxGenericTreeCtrl::GetChildrenCount(const wxTreeItemId& item, void wxGenericTreeCtrl::SetWindowStyle(const long styles) { - if (!HasFlag(wxTR_HIDE_ROOT) && (styles & wxTR_HIDE_ROOT)) + // Do not try to expand the root node if it hasn't been created yet + if (m_anchor && !HasFlag(wxTR_HIDE_ROOT) && (styles & wxTR_HIDE_ROOT)) { // if we will hide the root, make sure children are visible m_anchor->SetHasPlus(); @@ -908,7 +921,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(); } @@ -1009,6 +1022,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) { @@ -1040,7 +1072,7 @@ void wxGenericTreeCtrl::SetItemFont(const wxTreeItemId& item, const wxFont& font bool wxGenericTreeCtrl::SetFont( const wxFont &font ) { - wxScrolledWindow::SetFont(font); + wxTreeCtrlBase::SetFont(font); m_normalFont = font ; m_boldFont = wxFont(m_normalFont.GetPointSize(), @@ -1368,10 +1400,11 @@ wxTreeItemId wxGenericTreeCtrl::FindItem(const wxTreeItemId& idParent, // ----------------------------------------------------------------------------- wxTreeItemId wxGenericTreeCtrl::DoInsertItem(const wxTreeItemId& parentId, - size_t previous, - const wxString& text, - int image, int selImage, - wxTreeItemData *data) + size_t previous, + const wxString& text, + int image, + int selImage, + wxTreeItemData *data) { wxGenericTreeItem *parent = (wxGenericTreeItem*) parentId.m_pItem; if ( !parent ) @@ -1390,14 +1423,16 @@ wxTreeItemId wxGenericTreeCtrl::DoInsertItem(const wxTreeItemId& parentId, data->m_pItem = item; } - parent->Insert( item, previous ); + parent->Insert( item, previous == (size_t)-1 ? parent->GetChildren().size() + : previous ); return item; } wxTreeItemId wxGenericTreeCtrl::AddRoot(const wxString& text, - int image, int selImage, - wxTreeItemData *data) + int image, + int selImage, + wxTreeItemData *data) { wxCHECK_MSG( !m_anchor, wxTreeItemId(), wxT("tree can have only one root") ); @@ -1428,19 +1463,11 @@ wxTreeItemId wxGenericTreeCtrl::AddRoot(const wxString& text, return m_anchor; } -wxTreeItemId wxGenericTreeCtrl::PrependItem(const wxTreeItemId& parent, - const wxString& text, - int image, int selImage, - wxTreeItemData *data) -{ - return DoInsertItem(parent, 0u, text, image, selImage, data); -} - -wxTreeItemId wxGenericTreeCtrl::InsertItem(const wxTreeItemId& parentId, - const wxTreeItemId& idPrevious, - const wxString& text, - int image, int selImage, - wxTreeItemData *data) +wxTreeItemId wxGenericTreeCtrl::DoInsertAfter(const wxTreeItemId& parentId, + const wxTreeItemId& idPrevious, + const wxString& text, + int image, int selImage, + wxTreeItemData *data) { wxGenericTreeItem *parent = (wxGenericTreeItem*) parentId.m_pItem; if ( !parent ) @@ -1460,37 +1487,6 @@ wxTreeItemId wxGenericTreeCtrl::InsertItem(const wxTreeItemId& parentId, return DoInsertItem(parentId, (size_t)++index, text, image, selImage, data); } -wxTreeItemId wxGenericTreeCtrl::InsertItem(const wxTreeItemId& parentId, - size_t before, - const wxString& text, - int image, int selImage, - wxTreeItemData *data) -{ - wxGenericTreeItem *parent = (wxGenericTreeItem*) parentId.m_pItem; - if ( !parent ) - { - // should we give a warning here? - return AddRoot(text, image, selImage, data); - } - - return DoInsertItem(parentId, before, text, image, selImage, data); -} - -wxTreeItemId wxGenericTreeCtrl::AppendItem(const wxTreeItemId& parentId, - const wxString& text, - int image, int selImage, - wxTreeItemData *data) -{ - wxGenericTreeItem *parent = (wxGenericTreeItem*) 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); -} void wxGenericTreeCtrl::SendDeleteEvent(wxGenericTreeItem *item) { @@ -1862,8 +1858,6 @@ void wxGenericTreeCtrl::DoSelectItem(const wxTreeItemId& itemId, parent = GetItemParent( parent ); } - EnsureVisible( itemId ); - // ctrl press if (unselect_others) { @@ -1895,6 +1889,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 ); } @@ -1903,7 +1902,7 @@ void wxGenericTreeCtrl::SelectItem(const wxTreeItemId& itemId, bool select) { if ( select ) { - DoSelectItem(itemId); + DoSelectItem(itemId, !HasFlag(wxTR_MULTIPLE)); } else // deselect { @@ -2041,12 +2040,6 @@ static int LINKAGEMODE tree_ctrl_compare_func(wxGenericTreeItem **item1, return s_treeBeingSorted->OnCompareItems(*item1, *item2); } -int wxGenericTreeCtrl::OnCompareItems(const wxTreeItemId& item1, - const wxTreeItemId& item2) -{ - return wxStrcmp(GetItemText(item1), GetItemText(item2)); -} - void wxGenericTreeCtrl::SortChildren(const wxTreeItemId& itemId) { wxCHECK_RET( itemId.IsOk(), wxT("invalid tree item") ); @@ -2068,21 +2061,6 @@ void wxGenericTreeCtrl::SortChildren(const wxTreeItemId& itemId) //else: don't make the tree dirty as nothing changed } -wxImageList *wxGenericTreeCtrl::GetImageList() const -{ - return m_imageListNormal; -} - -wxImageList *wxGenericTreeCtrl::GetButtonsImageList() const -{ - return m_imageListButtons; -} - -wxImageList *wxGenericTreeCtrl::GetStateImageList() const -{ - return m_imageListState; -} - void wxGenericTreeCtrl::CalculateLineHeight() { wxClientDC dc(this); @@ -2150,18 +2128,6 @@ void wxGenericTreeCtrl::SetButtonsImageList(wxImageList *imageList) CalculateLineHeight(); } -void wxGenericTreeCtrl::AssignImageList(wxImageList *imageList) -{ - SetImageList(imageList); - m_ownsImageListNormal = true; -} - -void wxGenericTreeCtrl::AssignStateImageList(wxImageList *imageList) -{ - SetStateImageList(imageList); - m_ownsImageListState = true; -} - void wxGenericTreeCtrl::AssignButtonsImageList(wxImageList *imageList) { SetButtonsImageList(imageList); @@ -2218,7 +2184,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 { @@ -2227,6 +2193,7 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc) } int total_h = GetLineHeight(item); + bool drawItemBackground = false; if ( item->IsSelected() ) { @@ -2244,14 +2211,20 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc) #else dc.SetBrush(*(m_hasFocus ? m_hilightBrush : m_hilightUnfocusedBrush)); #endif + drawItemBackground = true; } else { wxColour colBg; if ( attr && attr->HasBackgroundColour() ) + { + drawItemBackground = true; colBg = attr->GetBackgroundColour(); + } else - colBg = m_backgroundColour; + { + colBg = GetBackgroundColour(); + } dc.SetBrush(wxBrush(colBg, wxSOLID)); } @@ -2275,7 +2248,10 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc) dc.DrawRectangle( item->GetX() + image_w - 2, item->GetY()+offset, item->GetWidth() - image_w + 2, total_h-offset ); } - else + // On GTK+ 2, drawing a 'normal' background is wrong for themes that + // don't allow backgrounds to be customized. Not drawing the background, + // except for custom item backgrounds, works for both kinds of theme. + else if (drawItemBackground) { dc.DrawRectangle( item->GetX()-2, item->GetY()+offset, item->GetWidth()+2, total_h-offset ); @@ -2357,7 +2333,15 @@ 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 + ) { colText = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT); } @@ -2612,7 +2596,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 @@ -2657,20 +2641,27 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) case WXK_MENU: { - wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_MENU, GetId() ); - event.m_item = m_current; - event.SetEventObject( this ); - GetEventHandler()->ProcessEvent( event ); + // Use the item's bounding rectangle to determine position for the event + wxRect ItemRect; + GetBoundingRect(m_current, ItemRect, true); + + wxTreeEvent eventMenu( wxEVT_COMMAND_TREE_ITEM_MENU, GetId() ); + eventMenu.m_item = 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; } case ' ': case WXK_RETURN: if ( !event.HasModifiers() ) { - wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_ACTIVATED, GetId() ); - event.m_item = m_current; - event.SetEventObject( this ); - GetEventHandler()->ProcessEvent( event ); + wxTreeEvent eventAct( wxEVT_COMMAND_TREE_ITEM_ACTIVATED, GetId() ); + eventAct.m_item = m_current; + eventAct.SetEventObject( this ); + GetEventHandler()->ProcessEvent( eventAct ); } // in any case, also generate the normal key event for this key, @@ -2858,7 +2849,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) } } -wxTreeItemId wxGenericTreeCtrl::HitTest(const wxPoint& point, int& flags) +wxTreeItemId wxGenericTreeCtrl::DoTreeHitTest(const wxPoint& point, int& flags) { // JACS: removed wxYieldIfNeeded() because it can cause the window // to be deleted from under us if a close window event is pending @@ -2891,7 +2882,7 @@ wxTreeItemId wxGenericTreeCtrl::HitTest(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") ); @@ -2900,18 +2891,34 @@ bool wxGenericTreeCtrl::GetBoundingRect(const wxTreeItemId& item, int startX, startY; GetViewStart(& startX, & startY); - rect.x = i->GetX() - startX*PIXELS_PER_UNIT; + if ( textOnly ) + { + rect.x = i->GetX() - startX*PIXELS_PER_UNIT; + 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.y = i->GetY() - startY*PIXELS_PER_UNIT; - rect.width = i->GetWidth(); - //rect.height = i->GetHeight(); rect.height = GetLineHeight(i); return true; } -void wxGenericTreeCtrl::Edit( const wxTreeItemId& item ) +wxTextCtrl *wxGenericTreeCtrl::EditLabel(const wxTreeItemId& item, + wxClassInfo * WXUNUSED(textCtrlClass)) { - wxCHECK_RET( item.IsOk(), _T("can't edit an invalid item") ); + wxCHECK_MSG( item.IsOk(), NULL, _T("can't edit an invalid item") ); wxGenericTreeItem *itemEdit = (wxGenericTreeItem *)item.m_pItem; @@ -2921,7 +2928,7 @@ void wxGenericTreeCtrl::Edit( const wxTreeItemId& item ) if ( GetEventHandler()->ProcessEvent( te ) && !te.IsAllowed() ) { // vetoed by user - return; + return NULL; } // We have to call this here because the label in @@ -2934,9 +2941,12 @@ void wxGenericTreeCtrl::Edit( const wxTreeItemId& item ) wxYieldIfNeeded(); #endif + // TODO: use textCtrlClass here to create the control of correct class m_textCtrl = new wxTreeTextCtrl(this, itemEdit); m_textCtrl->SetFocus(); + + return m_textCtrl; } // returns a pointer to the text edit control if the item is being @@ -2947,6 +2957,14 @@ wxTextCtrl* wxGenericTreeCtrl::GetEditControl() const return m_textCtrl; } +void wxGenericTreeCtrl::EndEditLabel(const wxTreeItemId& WXUNUSED(item), + bool discardChanges) +{ + wxCHECK_RET( m_textCtrl, _T("not editing label") ); + + m_textCtrl->EndEdit(discardChanges); +} + bool wxGenericTreeCtrl::OnRenameAccept(wxGenericTreeItem *item, const wxString& value) { @@ -2973,7 +2991,7 @@ void wxGenericTreeCtrl::OnRenameCancelled(wxGenericTreeItem *item) void wxGenericTreeCtrl::OnRenameTimer() { - Edit( m_current ); + EditLabel( m_current ); } void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) @@ -3075,6 +3093,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) wxTreeEvent nevent( command, GetId() ); nevent.m_item = m_current; nevent.SetEventObject(this); + nevent.SetPoint(CalcScrolledPosition(pt)); // by default the dragging is not supported, the user code must // explicitly allow the event for it to take place @@ -3136,13 +3155,13 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) } // generate the drag end event - wxTreeEvent event(wxEVT_COMMAND_TREE_END_DRAG, GetId()); + wxTreeEvent eventEndDrag(wxEVT_COMMAND_TREE_END_DRAG, GetId()); - event.m_item = item; - event.m_pointDrag = pt; - event.SetEventObject(this); + eventEndDrag.m_item = item; + eventEndDrag.m_pointDrag = CalcScrolledPosition(pt); + eventEndDrag.SetEventObject(this); - (void)GetEventHandler()->ProcessEvent(event); + (void)GetEventHandler()->ProcessEvent(eventEndDrag); m_isDragging = false; m_dropTarget = (wxGenericTreeItem *)NULL; @@ -3189,18 +3208,26 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) 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; + nevent2.m_pointDrag = CalcScrolledPosition(pt); + nevent2.SetEventObject(this); + GetEventHandler()->ProcessEvent(nevent2); } else if ( event.LeftUp() ) { // this facilitates multiple-item drag-and-drop - if (item && HasFlag(wxTR_MULTIPLE)) + if ( /* item && */ HasFlag(wxTR_MULTIPLE)) { wxArrayTreeItemIds selections; size_t count = GetSelections(selections); if (count > 1 && - !event.ControlDown() && + !event.CmdDown() && !event.ShiftDown()) { DoSelectItem(item, true, false); @@ -3254,14 +3281,14 @@ 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); DoSelectItem(item, unselect_others, extended_select); @@ -3354,7 +3381,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; } } @@ -3533,15 +3560,6 @@ 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 @@ -3584,13 +3602,4 @@ void wxGenericTreeCtrl::SetItemSelectedImage(const wxTreeItemId& item, int image #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