X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f7c6f947cf77ebfd11a860e7d07262e6de31e2a1..9814d926198c75333d972f408fa527f84e9355d3:/src/generic/treectlg.cpp diff --git a/src/generic/treectlg.cpp b/src/generic/treectlg.cpp index b27512a242..bdd3003ec1 100644 --- a/src/generic/treectlg.cpp +++ b/src/generic/treectlg.cpp @@ -108,6 +108,7 @@ private: wxGenericTreeItem *m_itemEdited; wxString m_startValue; bool m_finished; + bool m_aboutToFinish; DECLARE_EVENT_TABLE() DECLARE_NO_COPY_CLASS(wxTreeTextCtrl) @@ -341,6 +342,7 @@ wxTreeTextCtrl::wxTreeTextCtrl(wxGenericTreeCtrl *owner, { m_owner = owner; m_finished = false; + m_aboutToFinish = false; int w = m_itemEdited->GetWidth(), h = m_itemEdited->GetHeight(); @@ -390,6 +392,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 +415,7 @@ bool wxTreeTextCtrl::AcceptChanges() void wxTreeTextCtrl::Finish() { - if ( !m_finished ) + if ( !m_finished ) { m_owner->ResetTextControl(); @@ -424,12 +432,11 @@ 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 + m_aboutToFinish = true; + // Notify the owner about the changes + AcceptChanges(); + // Even if vetoed, close the control (consistent with MSW) + Finish(); break; case WXK_ESCAPE: @@ -463,16 +470,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(); } @@ -758,9 +767,11 @@ void wxGenericTreeCtrl::Init() m_findTimer = NULL; + m_dropEffectAboveItem = false; + m_lastOnSame = false; -#ifdef __WXMAC_CARBON__ +#ifdef __WXMAC_CARBON__ m_normalFont.MacCreateThemeFont( kThemeViewsFont ) ; #else m_normalFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ); @@ -906,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(); } @@ -1007,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) { @@ -1586,7 +1616,7 @@ void wxGenericTreeCtrl::Delete(const wxTreeItemId& itemId) if (item == m_select_me) m_select_me = NULL; - + delete item; } @@ -1901,7 +1931,7 @@ void wxGenericTreeCtrl::SelectItem(const wxTreeItemId& itemId, bool select) { if ( select ) { - DoSelectItem(itemId); + DoSelectItem(itemId, !HasFlag(wxTR_MULTIPLE)); } else // deselect { @@ -2225,6 +2255,7 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc) } int total_h = GetLineHeight(item); + bool drawItemBackground = false; if ( item->IsSelected() ) { @@ -2242,14 +2273,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; + } dc.SetBrush(wxBrush(colBg, wxSOLID)); } @@ -2273,7 +2310,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 ); @@ -2499,7 +2539,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); @@ -2610,7 +2650,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 @@ -2655,8 +2695,15 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) case WXK_MENU: { + // Use the item's bounding rectangle to determine position for the event + wxRect ItemRect; + GetBoundingRect(m_current, ItemRect, true); + wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_MENU, GetId() ); event.m_item = m_current; + // Use the left edge, vertical middle + event.m_pointDrag = wxPoint(ItemRect.GetX(), + ItemRect.GetY() + ItemRect.GetHeight() / 2); event.SetEventObject( this ); GetEventHandler()->ProcessEvent( event ); break; @@ -3073,6 +3120,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 @@ -3102,7 +3150,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) CaptureMouse(); } } - else if ( event.Moving() ) + else if ( event.Dragging() ) { if ( item != m_dropTarget ) { @@ -3114,7 +3162,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) // highlight the current drop target if any DrawDropEffect(m_dropTarget); -#if defined( __WXMSW__ ) || defined(__WXMAC__) +#if defined(__WXMSW__) || defined(__WXMAC__) || defined(__WXGTK20__) Update(); #else wxYieldIfNeeded(); @@ -3175,23 +3223,38 @@ 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)); + + // 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); @@ -3245,14 +3308,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); @@ -3561,4 +3624,27 @@ wxGenericTreeCtrl::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant)) #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