X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/14f355c2b5c71fc7c3d680aea366582d2ac60f7b..02a8e64ca3a617d776e6e5f881f915aadbd47c4c:/src/generic/treectlg.cpp diff --git a/src/generic/treectlg.cpp b/src/generic/treectlg.cpp index 11236650e4..69637e09c0 100644 --- a/src/generic/treectlg.cpp +++ b/src/generic/treectlg.cpp @@ -40,13 +40,17 @@ #include "wx/renderer.h" +#ifdef __WXMAC__ + #include "wx/mac/private.h" +#endif + // ----------------------------------------------------------------------------- // array types // ----------------------------------------------------------------------------- class WXDLLEXPORT wxGenericTreeItem; -WX_DEFINE_EXPORTED_ARRAY_NO_PTR(wxGenericTreeItem *, wxArrayGenericTreeItems); +WX_DEFINE_EXPORTED_ARRAY_PTR(wxGenericTreeItem *, wxArrayGenericTreeItems); // ---------------------------------------------------------------------------- // constants @@ -183,7 +187,7 @@ public: // 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 + // on the item's label wxGenericTreeItem *HitTest( const wxPoint& point, const wxGenericTreeCtrl *, int &flags, @@ -569,11 +573,19 @@ wxGenericTreeItem *wxGenericTreeItem::HitTest(const wxPoint& point, else flags |= wxTREE_HITTEST_ONITEMLOWERPART; - // 5 is the size of the plus sign int xCross = m_x - theCtrl->GetSpacing(); - if ((point.x > xCross-5) && (point.x < xCross+5) && - (point.y > y_mid-5) && (point.y < y_mid+5) && +#ifdef __WXMAC__ + // according to the drawing code the triangels are drawn + // at -4 , -4 from the position up to +10/+10 max + if ((point.x > xCross-4) && (point.x < xCross+10) && + (point.y > y_mid-4) && (point.y < y_mid+10) && HasPlus() && theCtrl->HasButtons() ) +#else + // 5 is the size of the plus sign + if ((point.x > xCross-6) && (point.x < xCross+6) && + (point.y > y_mid-6) && (point.y < y_mid+6) && + HasPlus() && theCtrl->HasButtons() ) +#endif { flags |= wxTREE_HITTEST_ONITEMBUTTON; return this; @@ -666,9 +678,10 @@ BEGIN_EVENT_TABLE(wxGenericTreeCtrl,wxScrolledWindow) EVT_CHAR (wxGenericTreeCtrl::OnChar) EVT_SET_FOCUS (wxGenericTreeCtrl::OnSetFocus) EVT_KILL_FOCUS (wxGenericTreeCtrl::OnKillFocus) + EVT_TREE_ITEM_GETTOOLTIP(-1, 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. @@ -716,15 +729,22 @@ void wxGenericTreeCtrl::Init() m_dragCount = 0; m_isDragging = FALSE; - m_dropTarget = m_oldSelection = (wxGenericTreeItem *)NULL; + m_dropTarget = m_oldSelection = NULL; + m_underMouse = NULL; m_textCtrl = NULL; m_renameTimer = NULL; + m_freezeCount = 0; + m_findTimer = NULL; m_lastOnSame = FALSE; +#if defined( __WXMAC__ ) && __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(), @@ -739,7 +759,7 @@ bool wxGenericTreeCtrl::Create(wxWindow *parent, const wxPoint& pos, const wxSize& size, long style, - const wxValidator &validator, + const wxValidator& wxVALIDATOR_PARAM(validator), const wxString& name ) { #ifdef __WXMAC__ @@ -919,6 +939,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); } @@ -1703,21 +1726,12 @@ bool wxGenericTreeCtrl::TagAllChildrenUntilLast(wxGenericTreeItem *crt_item, wxG 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(); @@ -1727,9 +1741,9 @@ 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") ); @@ -1812,6 +1826,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 { @@ -1878,8 +1908,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 @@ -2317,9 +2351,15 @@ void wxGenericTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level } else // no custom buttons { - static const int wImage = 10; - static const int hImage = 12; - + 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, @@ -2327,9 +2367,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 ); } } @@ -2580,7 +2618,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; } @@ -2597,7 +2635,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; } } @@ -2614,7 +2652,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) } if (prev) { - SelectItem( prev, unselect_others, extended_select ); + DoSelectItem( prev, unselect_others, extended_select ); } } break; @@ -2631,7 +2669,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 @@ -2648,7 +2686,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; } } @@ -2675,7 +2713,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) if ( last.IsOk() ) { - SelectItem( last, unselect_others, extended_select ); + DoSelectItem( last, unselect_others, extended_select ); } } break; @@ -2695,7 +2733,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) break; } - SelectItem( prev, unselect_others, extended_select ); + DoSelectItem( prev, unselect_others, extended_select ); } break; @@ -2807,7 +2845,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); @@ -2858,6 +2900,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 @@ -2873,9 +2971,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 ) @@ -2939,7 +3036,11 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) // highlight the current drop target if any DrawDropEffect(m_dropTarget); +#if defined( __WXMSW__ ) || defined(__WXMAC__) + Update(); +#else wxYieldIfNeeded(); +#endif } } else if ( (event.LeftUp() || event.RightUp()) && m_isDragging ) @@ -2970,7 +3071,11 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) SetCursor(m_oldCursor); +#if defined( __WXMSW__ ) || defined(__WXMAC__) + Update(); +#else wxYieldIfNeeded(); +#endif } else { @@ -3001,7 +3106,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) !event.ControlDown() && !event.ShiftDown()) { - SelectItem(item, true, false); + DoSelectItem(item, true, false); } } @@ -3062,7 +3167,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) event.ControlDown(), is_multiple, extended_select, unselect_others); - SelectItem(item, unselect_others, extended_select); + DoSelectItem(item, unselect_others, extended_select); } @@ -3116,7 +3221,8 @@ void wxGenericTreeCtrl::OnInternalIdle() * we actually redraw the tree when everything is over */ if (!m_dirty) return; - + if (m_freezeCount) return; + m_dirty = FALSE; CalculatePositions(); @@ -3134,6 +3240,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; @@ -3225,6 +3333,7 @@ void wxGenericTreeCtrl::CalculatePositions() void wxGenericTreeCtrl::RefreshSubtree(wxGenericTreeItem *item) { if (m_dirty) return; + if (m_freezeCount) return; wxSize client = GetClientSize(); @@ -3241,6 +3350,7 @@ 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); @@ -3252,6 +3362,8 @@ void wxGenericTreeCtrl::RefreshLine( wxGenericTreeItem *item ) 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 ) @@ -3260,6 +3372,8 @@ void wxGenericTreeCtrl::RefreshSelected() void wxGenericTreeCtrl::RefreshSelectedUnder(wxGenericTreeItem *item) { + if (m_freezeCount) return; + if ( item->IsSelected() ) RefreshLine(item); @@ -3271,6 +3385,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 // ---------------------------------------------------------------------------- @@ -3280,6 +3409,8 @@ bool wxGenericTreeCtrl::SetBackgroundColour(const wxColour& colour) if ( !wxWindow::SetBackgroundColour(colour) ) return FALSE; + if (m_freezeCount) return TRUE; + Refresh(); return TRUE; @@ -3290,9 +3421,18 @@ bool wxGenericTreeCtrl::SetForegroundColour(const wxColour& colour) if ( !wxWindow::SetForegroundColour(colour) ) return FALSE; + if (m_freezeCount) return TRUE; + Refresh(); return TRUE; } +// Process the tooltip event, to speed up event processing. +// Doesn't actually get a tooltip. +void wxGenericTreeCtrl::OnGetToolTip( wxTreeEvent &event ) +{ + event.Veto(); +} + #endif // wxUSE_TREECTRL