X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/5cb3a695e0f65d71fe0c315766e0d6dafd4c312a..c7ea5a0c7edbdb777640e2613bfaac5f649b3340:/src/generic/treectlg.cpp diff --git a/src/generic/treectlg.cpp b/src/generic/treectlg.cpp index da93936fdf..4539b8972d 100644 --- a/src/generic/treectlg.cpp +++ b/src/generic/treectlg.cpp @@ -4,7 +4,6 @@ // Author: Robert Roebling // Created: 01/02/97 // Modified: 22/10/98 - almost total rewrite, simpler interface (VZ) -// Id: $Id$ // Copyright: (c) 1998 Robert Roebling and Julian Smart // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -127,7 +126,7 @@ public: wxTreeFindTimer( wxGenericTreeCtrl *owner ) { m_owner = owner; } - virtual void Notify() { m_owner->m_findPrefix.clear(); } + virtual void Notify() { m_owner->ResetFindState(); } private: wxGenericTreeCtrl *m_owner; @@ -423,8 +422,8 @@ BEGIN_EVENT_TABLE(wxTreeTextCtrl,wxTextCtrl) END_EVENT_TABLE() wxTreeTextCtrl::wxTreeTextCtrl(wxGenericTreeCtrl *owner, - wxGenericTreeItem *item) - : m_itemEdited(item), m_startValue(item->GetText()) + wxGenericTreeItem *itm) + : m_itemEdited(itm), m_startValue(itm->GetText()) { m_owner = owner; m_aboutToFinish = false; @@ -441,7 +440,7 @@ wxTreeTextCtrl::wxTreeTextCtrl(wxGenericTreeCtrl *owner, rect.y -= 2; rect.width += 8; rect.height += 4; -#elif defined(__WXMAC__) +#elif defined(wxOSX_USE_CARBON) && wxOSX_USE_CARBON int bestHeight = GetBestSize().y - 8; if ( rect.height > bestHeight ) { @@ -454,7 +453,7 @@ wxTreeTextCtrl::wxTreeTextCtrl(wxGenericTreeCtrl *owner, (void)Create(m_owner, wxID_ANY, m_startValue, rect.GetPosition(), rect.GetSize()); - SetSelection(-1, -1); + SelectAll(); } void wxTreeTextCtrl::EndEdit(bool discardChanges) @@ -902,21 +901,13 @@ BEGIN_EVENT_TABLE(wxGenericTreeCtrl, wxTreeCtrlBase) EVT_PAINT (wxGenericTreeCtrl::OnPaint) EVT_SIZE (wxGenericTreeCtrl::OnSize) EVT_MOUSE_EVENTS (wxGenericTreeCtrl::OnMouse) + EVT_KEY_DOWN (wxGenericTreeCtrl::OnKeyDown) 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(__WXUNIVERSAL__) -/* - * wxTreeCtrl has to be a real class or we have problems with - * the run-time information. - */ - -IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl, wxGenericTreeCtrl) -#endif - // ----------------------------------------------------------------------------- // construction/destruction // ----------------------------------------------------------------------------- @@ -964,6 +955,7 @@ void wxGenericTreeCtrl::Init() m_renameTimer = NULL; m_findTimer = NULL; + m_findBell = 0; // default is to not ring bell at all m_dropEffectAboveItem = false; @@ -973,17 +965,11 @@ void wxGenericTreeCtrl::Init() m_lastOnSame = false; #if defined( __WXMAC__ ) - m_normalFont.CreateSystemFont(wxOSX_SYSTEM_FONT_VIEWS); + m_normalFont = wxFont(wxOSX_SYSTEM_FONT_VIEWS); #else m_normalFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ); #endif - m_boldFont = wxFont(m_normalFont.GetPointSize(), - m_normalFont.GetFamily(), - m_normalFont.GetStyle(), - wxBOLD, - m_normalFont.GetUnderlined(), - m_normalFont.GetFaceName(), - m_normalFont.GetEncoding()); + m_boldFont = m_normalFont.Bold(); } bool wxGenericTreeCtrl::Create(wxWindow *parent, @@ -1011,7 +997,7 @@ bool wxGenericTreeCtrl::Create(wxWindow *parent, #endif if ( !wxControl::Create( parent, id, pos, size, - style|wxHSCROLL|wxVSCROLL, + style|wxHSCROLL|wxVSCROLL|wxWANTS_CHARS, validator, name ) ) return false; @@ -1059,6 +1045,11 @@ wxGenericTreeCtrl::~wxGenericTreeCtrl() delete m_imageListButtons; } +void wxGenericTreeCtrl::EnableBellOnNoMatch( bool on ) +{ + m_findBell = on; +} + // ----------------------------------------------------------------------------- // accessors // ----------------------------------------------------------------------------- @@ -1298,14 +1289,8 @@ bool wxGenericTreeCtrl::SetFont( const wxFont &font ) { wxTreeCtrlBase::SetFont(font); - m_normalFont = font ; - m_boldFont = wxFont(m_normalFont.GetPointSize(), - m_normalFont.GetFamily(), - m_normalFont.GetStyle(), - wxBOLD, - m_normalFont.GetUnderlined(), - m_normalFont.GetFaceName(), - m_normalFont.GetEncoding()); + m_normalFont = font; + m_boldFont = m_normalFont.Bold(); if (m_anchor) m_anchor->RecursiveResetTextSize(); @@ -1504,16 +1489,16 @@ wxTreeItemId wxGenericTreeCtrl::GetNext(const wxTreeItemId& item) const wxTreeItemId wxGenericTreeCtrl::GetFirstVisibleItem() const { - wxTreeItemId id = GetRootItem(); - if (!id.IsOk()) - return id; + wxTreeItemId itemid = GetRootItem(); + if (!itemid.IsOk()) + return itemid; do { - if (IsVisible(id)) - return id; - id = GetNext(id); - } while (id.IsOk()); + if (IsVisible(itemid)) + return itemid; + itemid = GetNext(itemid); + } while (itemid.IsOk()); return wxTreeItemId(); } @@ -1577,6 +1562,13 @@ void wxGenericTreeCtrl::ResetTextControl() m_textCtrl = NULL; } +void wxGenericTreeCtrl::ResetFindState() +{ + m_findPrefix.clear(); + if ( m_findBell ) + m_findBell = 1; +} + // find the first item starting with the given prefix after the given item wxTreeItemId wxGenericTreeCtrl::FindItem(const wxTreeItemId& idParent, const wxString& prefixOrig) const @@ -1590,40 +1582,44 @@ wxTreeItemId wxGenericTreeCtrl::FindItem(const wxTreeItemId& idParent, // allows to switch between two items starting with the same letter just by // pressing it) but we shouldn't jump to the next one if the user is // continuing to type as otherwise he might easily skip the item he wanted - wxTreeItemId id = idParent; + wxTreeItemId itemid = idParent; if ( prefix.length() == 1 ) { - id = GetNext(id); + itemid = GetNext(itemid); } // look for the item starting with the given prefix after it - while ( id.IsOk() && !GetItemText(id).Lower().StartsWith(prefix) ) + while ( itemid.IsOk() && !GetItemText(itemid).Lower().StartsWith(prefix) ) { - id = GetNext(id); + itemid = GetNext(itemid); } // if we haven't found anything... - if ( !id.IsOk() ) + if ( !itemid.IsOk() ) { // ... wrap to the beginning - id = GetRootItem(); + itemid = GetRootItem(); if ( HasFlag(wxTR_HIDE_ROOT) ) { // can't select virtual root - id = GetNext(id); + itemid = GetNext(itemid); } // and try all the items (stop when we get to the one we started from) - while ( id.IsOk() && id != idParent && - !GetItemText(id).Lower().StartsWith(prefix) ) + while ( itemid.IsOk() && itemid != idParent && + !GetItemText(itemid).Lower().StartsWith(prefix) ) + { + itemid = GetNext(itemid); + } + // If we haven't found the item but wrapped back to the one we started + // from, id.IsOk() must be false + if ( itemid == idParent ) { - id = GetNext(id); + itemid = wxTreeItemId(); } - // If we haven't found the item, id.IsOk() will be false, as per - // documentation } - return id; + return itemid; } // ----------------------------------------------------------------------------- @@ -1725,7 +1721,7 @@ wxTreeItemId wxGenericTreeCtrl::DoInsertAfter(const wxTreeItemId& parentId, void wxGenericTreeCtrl::SendDeleteEvent(wxGenericTreeItem *item) { - wxTreeEvent event(wxEVT_COMMAND_TREE_DELETE_ITEM, this, item); + wxTreeEvent event(wxEVT_TREE_DELETE_ITEM, this, item); GetEventHandler()->ProcessEvent( event ); } @@ -1864,7 +1860,7 @@ void wxGenericTreeCtrl::Expand(const wxTreeItemId& itemId) if ( item->IsExpanded() ) return; - wxTreeEvent event(wxEVT_COMMAND_TREE_ITEM_EXPANDING, this, item); + wxTreeEvent event(wxEVT_TREE_ITEM_EXPANDING, this, item); if ( GetEventHandler()->ProcessEvent( event ) && !event.IsAllowed() ) { @@ -1884,7 +1880,7 @@ void wxGenericTreeCtrl::Expand(const wxTreeItemId& itemId) m_dirty = true; } - event.SetEventType(wxEVT_COMMAND_TREE_ITEM_EXPANDED); + event.SetEventType(wxEVT_TREE_ITEM_EXPANDED); GetEventHandler()->ProcessEvent( event ); } @@ -1898,7 +1894,7 @@ void wxGenericTreeCtrl::Collapse(const wxTreeItemId& itemId) if ( !item->IsExpanded() ) return; - wxTreeEvent event(wxEVT_COMMAND_TREE_ITEM_COLLAPSING, this, item); + wxTreeEvent event(wxEVT_TREE_ITEM_COLLAPSING, this, item); if ( GetEventHandler()->ProcessEvent( event ) && !event.IsAllowed() ) { // cancelled by program @@ -1921,7 +1917,7 @@ void wxGenericTreeCtrl::Collapse(const wxTreeItemId& itemId) RefreshSubtree(item); - event.SetEventType(wxEVT_COMMAND_TREE_ITEM_COLLAPSED); + event.SetEventType(wxEVT_TREE_ITEM_COLLAPSED); GetEventHandler()->ProcessEvent( event ); } @@ -1953,6 +1949,20 @@ void wxGenericTreeCtrl::Unselect() } } +void wxGenericTreeCtrl::ClearFocusedItem() +{ + wxTreeItemId item = GetFocusedItem(); + if ( item.IsOk() ) + SelectItem(item, false); +} + +void wxGenericTreeCtrl::SetFocusedItem(const wxTreeItemId& item) +{ + wxCHECK_RET( item.IsOk(), wxT("invalid tree item") ); + + SelectItem(item, true); +} + void wxGenericTreeCtrl::UnselectAllChildren(wxGenericTreeItem *item) { if (item->IsSelected()) @@ -2000,7 +2010,7 @@ void wxGenericTreeCtrl::SelectChildren(const wxTreeItemId& parent) wxGenericTreeItem * item = (wxGenericTreeItem*) ((wxTreeItemId)children[0]).m_pItem; - wxTreeEvent event(wxEVT_COMMAND_TREE_SEL_CHANGING, this, item); + wxTreeEvent event(wxEVT_TREE_SEL_CHANGING, this, item); event.m_itemOld = m_current; if ( GetEventHandler()->ProcessEvent( event ) && !event.IsAllowed() ) @@ -2014,7 +2024,7 @@ void wxGenericTreeCtrl::SelectChildren(const wxTreeItemId& parent) } - event.SetEventType(wxEVT_COMMAND_TREE_SEL_CHANGED); + event.SetEventType(wxEVT_TREE_SEL_CHANGED); GetEventHandler()->ProcessEvent( event ); } @@ -2060,7 +2070,8 @@ wxGenericTreeCtrl::TagAllChildrenUntilLast(wxGenericTreeItem *crt_item, if (crt_item==last_item) return true; - if (crt_item->HasChildren()) + // We should leave the not shown children of collapsed items alone. + if (crt_item->HasChildren() && crt_item->IsExpanded()) { wxArrayGenericTreeItems& children = crt_item->GetChildren(); size_t count = children.GetCount(); @@ -2123,7 +2134,7 @@ void wxGenericTreeCtrl::DoSelectItem(const wxTreeItemId& itemId, return; } - wxTreeEvent event(wxEVT_COMMAND_TREE_SEL_CHANGING, this, item); + wxTreeEvent event(wxEVT_TREE_SEL_CHANGING, this, item); event.m_itemOld = m_current; // TODO : Here we don't send any selection mode yet ! @@ -2176,7 +2187,7 @@ void wxGenericTreeCtrl::DoSelectItem(const wxTreeItemId& itemId, // selection is set EnsureVisible( itemId ); - event.SetEventType(wxEVT_COMMAND_TREE_SEL_CHANGED); + event.SetEventType(wxEVT_TREE_SEL_CHANGED); GetEventHandler()->ProcessEvent( event ); } @@ -2192,14 +2203,14 @@ void wxGenericTreeCtrl::SelectItem(const wxTreeItemId& itemId, bool select) } else // deselect { - wxTreeEvent event(wxEVT_COMMAND_TREE_SEL_CHANGING, this, item); + wxTreeEvent event(wxEVT_TREE_SEL_CHANGING, this, item); if ( GetEventHandler()->ProcessEvent( event ) && !event.IsAllowed() ) return; item->SetHilight(false); RefreshLine(item); - event.SetEventType(wxEVT_COMMAND_TREE_SEL_CHANGED); + event.SetEventType(wxEVT_TREE_SEL_CHANGED); GetEventHandler()->ProcessEvent( event ); } } @@ -2272,12 +2283,17 @@ void wxGenericTreeCtrl::ScrollTo(const wxTreeItemId &item) // update the control before scrolling it if (m_dirty) -#if defined( __WXMSW__ ) || defined(__WXMAC__) + { +#if defined( __WXMSW__ ) + Update(); +#elif defined(__WXMAC__) Update(); + DoDirtyProcessing(); #else DoDirtyProcessing(); #endif - + } + wxGenericTreeItem *gitem = (wxGenericTreeItem*) item.m_pItem; int itemY = gitem->GetY(); @@ -2294,6 +2310,12 @@ void wxGenericTreeCtrl::ScrollTo(const wxTreeItemId &item) { // need to scroll up by enough to show this item fully itemY += itemHeight - clientHeight; +#ifdef __WXOSX__ + // because itemY below will be divided by PIXELS_PER_UNIT it may + // be rounded down, with the result of the item still only being + // partially visible, so make sure we are rounding up + itemY += PIXELS_PER_UNIT-1; +#endif } else if ( itemY > start_y*PIXELS_PER_UNIT ) { @@ -2765,7 +2787,10 @@ wxGenericTreeCtrl::PaintLevel(wxGenericTreeItem *item, #ifdef __WXMAC__ colText = *wxWHITE; #else - colText = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT); + if (m_hasFocus) + colText = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT); + else + colText = wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOXHIGHLIGHTTEXT); #endif } else @@ -2881,7 +2906,7 @@ wxGenericTreeCtrl::PaintLevel(wxGenericTreeItem *item, yOrigin = abs(yOrigin); GetClientSize(&width, &height); - // Move end points to the begining/end of the view? + // Move end points to the beginning/end of the view? if (y_mid < yOrigin) y_mid = yOrigin; if (oldY > yOrigin + height) @@ -3019,16 +3044,19 @@ void wxGenericTreeCtrl::OnKillFocus( wxFocusEvent &event ) event.Skip(); } -void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) +void wxGenericTreeCtrl::OnKeyDown( wxKeyEvent &event ) { - wxTreeEvent te( wxEVT_COMMAND_TREE_KEY_DOWN, this); + // send a tree event + wxTreeEvent te( wxEVT_TREE_KEY_DOWN, this); te.m_evtKey = event; if ( GetEventHandler()->ProcessEvent( te ) ) - { - // intercepted by the user code return; - } + event.Skip(); +} + +void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) +{ if ( (m_current == 0) || (m_key_current == 0) ) { event.Skip(); @@ -3062,6 +3090,21 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) // end : go to last item without opening parents // alnum : start or continue searching for the item with this prefix int keyCode = event.GetKeyCode(); + +#ifdef __WXOSX__ + // Make the keys work as they do in the native control: + // right => expand + // left => collapse if current item is expanded + if (keyCode == WXK_RIGHT) + { + keyCode = '+'; + } + else if (keyCode == WXK_LEFT && IsExpanded(m_current)) + { + keyCode = '-'; + } +#endif // __WXOSX__ + switch ( keyCode ) { case '+': @@ -3098,7 +3141,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) GetBoundingRect(m_current, ItemRect, true); wxTreeEvent - eventMenu(wxEVT_COMMAND_TREE_ITEM_MENU, this, m_current); + eventMenu(wxEVT_TREE_ITEM_MENU, this, m_current); // Use the left edge, vertical middle eventMenu.m_pointDrag = wxPoint(ItemRect.GetX(), ItemRect.GetY() + @@ -3112,7 +3155,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) if ( !event.HasModifiers() ) { wxTreeEvent - eventAct(wxEVT_COMMAND_TREE_ITEM_ACTIVATED, this, m_current); + eventAct(wxEVT_TREE_ITEM_ACTIVATED, this, m_current); GetEventHandler()->ProcessEvent( eventAct ); } @@ -3278,21 +3321,28 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) if ( !event.HasModifiers() && ((keyCode >= '0' && keyCode <= '9') || (keyCode >= 'a' && keyCode <= 'z') || - (keyCode >= 'A' && keyCode <= 'Z' ))) + (keyCode >= 'A' && keyCode <= 'Z') || + (keyCode == '_'))) { // find the next item starting with the given prefix wxChar ch = (wxChar)keyCode; + wxTreeItemId id; - wxTreeItemId id = FindItem(m_current, m_findPrefix + ch); - if ( !id.IsOk() ) + // if the same character is typed multiple times then go to the + // next entry starting with that character instead of searching + // for an item starting with multiple copies of this character, + // this is more useful and is how it works under Windows. + if ( m_findPrefix.length() == 1 && m_findPrefix[0] == ch ) { - // no such item - break; + id = FindItem(m_current, ch); + } + else + { + const wxString newPrefix(m_findPrefix + ch); + id = FindItem(m_current, newPrefix); + if ( id.IsOk() ) + m_findPrefix = newPrefix; } - - SelectItem(id); - - m_findPrefix += ch; // also start the timer to reset the current prefix if the user // doesn't press any more alnum keys soon -- we wouldn't want @@ -3302,7 +3352,32 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) m_findTimer = new wxTreeFindTimer(this); } + // Notice that we should start the timer even if we didn't find + // anything to make sure we reset the search state later. m_findTimer->Start(wxTreeFindTimer::DELAY, wxTIMER_ONE_SHOT); + + if ( id.IsOk() ) + { + SelectItem(id); + + // Reset the bell flag if it had been temporarily disabled + // before. + if ( m_findBell ) + m_findBell = 1; + } + else // No such item + { + // Signal it with a bell if enabled. + if ( m_findBell == 1 ) + { + ::wxBell(); + + // Disable it for the next unsuccessful match, we only + // beep once, this is usually enough and continuing to + // do it would be annoying. + m_findBell = -1; + } + } } else { @@ -3396,7 +3471,7 @@ wxTextCtrl *wxGenericTreeCtrl::EditLabel(const wxTreeItemId& item, wxGenericTreeItem *itemEdit = (wxGenericTreeItem *)item.m_pItem; - wxTreeEvent te(wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT, this, itemEdit); + wxTreeEvent te(wxEVT_TREE_BEGIN_LABEL_EDIT, this, itemEdit); if ( GetEventHandler()->ProcessEvent( te ) && !te.IsAllowed() ) { // vetoed by user @@ -3407,11 +3482,7 @@ wxTextCtrl *wxGenericTreeCtrl::EditLabel(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 DoDirtyProcessing(); -#endif // TODO: use textCtrlClass here to create the control of correct class m_textCtrl = new wxTreeTextCtrl(this, itemEdit); @@ -3440,7 +3511,7 @@ void wxGenericTreeCtrl::EndEditLabel(const wxTreeItemId& WXUNUSED(item), bool wxGenericTreeCtrl::OnRenameAccept(wxGenericTreeItem *item, const wxString& value) { - wxTreeEvent le(wxEVT_COMMAND_TREE_END_LABEL_EDIT, this, item); + wxTreeEvent le(wxEVT_TREE_END_LABEL_EDIT, this, item); le.m_label = value; le.m_editCancelled = false; @@ -3450,7 +3521,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, this, item); + wxTreeEvent le(wxEVT_TREE_END_LABEL_EDIT, this, item); le.m_label = wxEmptyString; le.m_editCancelled = true; @@ -3516,11 +3587,23 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) { // Ask the tree control what tooltip (if any) should be shown wxTreeEvent - hevent(wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP, this, hoverItem); + hevent(wxEVT_TREE_ITEM_GETTOOLTIP, this, hoverItem); - if ( GetEventHandler()->ProcessEvent(hevent) && hevent.IsAllowed() ) + // setting a tooltip upon leaving a view is getting the tooltip displayed + // on the neighbouring view ... +#ifdef __WXOSX__ + if ( event.Leaving() ) + SetToolTip(NULL); + else +#endif + if ( GetEventHandler()->ProcessEvent(hevent) ) { - SetToolTip(hevent.m_label); + // If the user permitted the tooltip change, update it, otherwise + // remove any old tooltip we might have. + if ( hevent.IsAllowed() ) + SetToolTip(hevent.m_label); + else + SetToolTip(NULL); } } #endif @@ -3559,8 +3642,8 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) } wxEventType command = event.RightIsDown() - ? wxEVT_COMMAND_TREE_BEGIN_RDRAG - : wxEVT_COMMAND_TREE_BEGIN_DRAG; + ? wxEVT_TREE_BEGIN_RDRAG + : wxEVT_TREE_BEGIN_DRAG; wxTreeEvent nevent(command, this, m_current); nevent.SetPoint(CalcScrolledPosition(pt)); @@ -3629,7 +3712,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) } // generate the drag end event - wxTreeEvent eventEndDrag(wxEVT_COMMAND_TREE_END_DRAG, this, item); + wxTreeEvent eventEndDrag(wxEVT_TREE_END_DRAG, this, item); eventEndDrag.m_pointDrag = CalcScrolledPosition(pt); @@ -3679,20 +3762,20 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) } wxTreeEvent - nevent(wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK, this, item); + nevent(wxEVT_TREE_ITEM_RIGHT_CLICK, this, item); nevent.m_pointDrag = CalcScrolledPosition(pt); 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, this, item); + // the RIGHT_CLICK event. TODO: This behaviour may change. + wxTreeEvent nevent2(wxEVT_TREE_ITEM_MENU, this, item); nevent2.m_pointDrag = CalcScrolledPosition(pt); GetEventHandler()->ProcessEvent(nevent2); } else if ( event.MiddleDown() ) { wxTreeEvent - nevent(wxEVT_COMMAND_TREE_ITEM_MIDDLE_CLICK, this, item); + nevent(wxEVT_TREE_ITEM_MIDDLE_CLICK, this, item); nevent.m_pointDrag = CalcScrolledPosition(pt); event.Skip(!GetEventHandler()->ProcessEvent(nevent)); } @@ -3701,7 +3784,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) if (flags & wxTREE_HITTEST_ONITEMSTATEICON) { wxTreeEvent - nevent(wxEVT_COMMAND_TREE_STATE_IMAGE_CLICK, this, item); + nevent(wxEVT_TREE_STATE_IMAGE_CLICK, this, item); GetEventHandler()->ProcessEvent(nevent); } @@ -3747,7 +3830,14 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) // ==> LeftDown() || LeftDClick() if ( event.LeftDown() ) { - m_lastOnSame = item == m_current; + // If we click on an already selected item but do it to return + // the focus to the control, it shouldn't start editing the + // item label because it's too easy to start editing + // accidentally (and also because nobody else does it like + // this). So only set this flag, used to decide whether we + // should start editing the label later, if we already have + // focus. + m_lastOnSame = item == m_current && HasFocus(); } if ( flags & wxTREE_HITTEST_ONITEMBUTTON ) @@ -3796,7 +3886,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) // send activate event first wxTreeEvent - nevent(wxEVT_COMMAND_TREE_ITEM_ACTIVATED, this, item); + nevent(wxEVT_TREE_ITEM_ACTIVATED, this, item); nevent.m_pointDrag = CalcScrolledPosition(pt); if ( !GetEventHandler()->ProcessEvent( nevent ) ) { @@ -3988,11 +4078,24 @@ bool wxGenericTreeCtrl::SetForegroundColour(const wxColour& colour) return true; } -// Process the tooltip event, to speed up event processing. -// Doesn't actually get a tooltip. void wxGenericTreeCtrl::OnGetToolTip( wxTreeEvent &event ) { - event.Veto(); +#if wxUSE_TOOLTIPS + wxTreeItemId itemId = event.GetItem(); + const wxGenericTreeItem* const pItem = (wxGenericTreeItem*)itemId.m_pItem; + + // Check if the item fits into the client area: + if ( pItem->GetX() + pItem->GetWidth() > GetClientSize().x ) + { + // If it doesn't, show its full text in the tooltip. + event.SetLabel(pItem->GetText()); + } + else +#endif // wxUSE_TOOLTIPS + { + // veto processing the event, nixing any tooltip + event.Veto(); + } }