X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/419875a6f5efa6c16b75d4a5e104ae6d88ed08fc..acd32ffcdb319f162633c20e0202db3f8542998a:/src/generic/treectlg.cpp diff --git a/src/generic/treectlg.cpp b/src/generic/treectlg.cpp index 0e14dc2830..393231673c 100644 --- a/src/generic/treectlg.cpp +++ b/src/generic/treectlg.cpp @@ -86,7 +86,7 @@ public: private: wxGenericTreeCtrl *m_owner; - DECLARE_NO_COPY_CLASS(wxTreeRenameTimer) + wxDECLARE_NO_COPY_CLASS(wxTreeRenameTimer); }; // control used for in-place edit @@ -114,7 +114,7 @@ private: bool m_aboutToFinish; DECLARE_EVENT_TABLE() - DECLARE_NO_COPY_CLASS(wxTreeTextCtrl) + wxDECLARE_NO_COPY_CLASS(wxTreeTextCtrl); }; // timer used to clear wxGenericTreeCtrl::m_findPrefix if no key was pressed @@ -132,7 +132,7 @@ public: private: wxGenericTreeCtrl *m_owner; - DECLARE_NO_COPY_CLASS(wxTreeFindTimer) + wxDECLARE_NO_COPY_CLASS(wxTreeFindTimer); }; // a tree item @@ -355,7 +355,7 @@ private: 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) + wxDECLARE_NO_COPY_CLASS(wxGenericTreeItem); }; // ============================================================================= @@ -429,45 +429,32 @@ wxTreeTextCtrl::wxTreeTextCtrl(wxGenericTreeCtrl *owner, m_owner = owner; m_aboutToFinish = false; - int w = m_itemEdited->GetWidth(), - h = m_itemEdited->GetHeight(); - - int x, y; - m_owner->CalcScrolledPosition(item->GetX(), item->GetY(), &x, &y); - - int image_h = 0, - image_w = 0; - - int image = item->GetCurrentImage(); - if ( image != NO_IMAGE ) - { - if ( m_owner->m_imageListNormal ) - { - m_owner->m_imageListNormal->GetSize( image, image_w, image_h ); - image_w += MARGIN_BETWEEN_IMAGE_AND_TEXT; - } - else - { - wxFAIL_MSG(_T("you must create an image list to use images!")); - } - } + wxRect rect; + m_owner->GetBoundingRect(m_itemEdited, rect, true); - // FIXME: what are all these hardcoded 4, 8 and 11s really? - x += image_w; - w -= image_w + 4; -#ifdef __WXMAC__ - wxSize bs = DoGetBestSize() ; - // edit control height - if ( h > bs.y - 8 ) - { - int diff = h - ( bs.y - 8 ) ; - h -= diff ; - y += diff / 2 ; - } -#endif + // corrects position and size for better appearance +#ifdef __WXMSW__ + rect.x -= 5; + rect.width += 10; +#elif defined(__WXGTK__) + rect.x -= 5; + rect.y -= 2; + rect.width += 8; + rect.height += 4; +#elif defined(__WXMAC__) + int bestHeight = GetBestSize().y - 8; + if ( rect.height > bestHeight ) + { + int diff = rect.height - bestHeight; + rect.height -= diff; + rect.y += diff / 2; + } +#endif // platforms (void)Create(m_owner, wxID_ANY, m_startValue, - wxPoint(x - 4, y - 4), wxSize(w + 11, h + 8)); + rect.GetPosition(), rect.GetSize()); + + SetSelection(-1, -1); } void wxTreeTextCtrl::EndEdit(bool discardChanges) @@ -605,7 +592,7 @@ wxGenericTreeItem::wxGenericTreeItem(wxGenericTreeItem *parent, m_parent = parent; - m_attr = (wxTreeItemAttr *)NULL; + m_attr = NULL; m_ownsAttr = false; // We don't know the height here yet. @@ -758,7 +745,7 @@ wxGenericTreeItem *wxGenericTreeItem::HitTest(const wxPoint& point, } // if children are expanded, fall through to evaluate them - if (m_isCollapsed) return (wxGenericTreeItem*) NULL; + if (m_isCollapsed) return NULL; } // evaluate children @@ -773,7 +760,7 @@ wxGenericTreeItem *wxGenericTreeItem::HitTest(const wxPoint& point, return res; } - return (wxGenericTreeItem*) NULL; + return NULL; } int wxGenericTreeItem::GetCurrentImage() const @@ -853,37 +840,27 @@ wxGenericTreeItem::DoCalculateSize(wxGenericTreeCtrl* control, int text_h = m_heightText + 2; - int image_h = 0; - int image_w = 0; + int image_h = 0, image_w = 0; int image = GetCurrentImage(); - if ( image != NO_IMAGE ) + if ( image != NO_IMAGE && control->m_imageListNormal ) { - if ( control->m_imageListNormal ) - { - control->m_imageListNormal->GetSize( image, image_w, image_h ); - image_w += MARGIN_BETWEEN_IMAGE_AND_TEXT; - } + control->m_imageListNormal->GetSize(image, image_w, image_h); + image_w += MARGIN_BETWEEN_IMAGE_AND_TEXT; } int state_h = 0, state_w = 0; int state = GetState(); - if ( state != wxTREE_ITEMSTATE_NONE ) + if ( state != wxTREE_ITEMSTATE_NONE && control->m_imageListState ) { - if ( control->m_imageListState ) - { - control->m_imageListState->GetSize( state, state_w, state_h ); - if ( image != NO_IMAGE ) - state_w += MARGIN_BETWEEN_STATE_AND_IMAGE; - else - state_w += MARGIN_BETWEEN_IMAGE_AND_TEXT; - } + control->m_imageListState->GetSize(state, state_w, state_h); + if ( image_w != 0 ) + state_w += MARGIN_BETWEEN_STATE_AND_IMAGE; else - { - state = wxTREE_ITEMSTATE_NONE; - } + state_w += MARGIN_BETWEEN_IMAGE_AND_TEXT; } - m_height = (image_h > text_h) ? image_h : text_h; + int img_h = wxMax(state_h, image_h); + m_height = wxMax(img_h, text_h); if (m_height < 30) m_height += 2; // at least 2 pixels @@ -949,7 +926,7 @@ void wxGenericTreeCtrl::Init() m_current = m_key_current = m_anchor = - m_select_me = (wxGenericTreeItem *) NULL; + m_select_me = NULL; m_hasFocus = false; m_dirty = false; @@ -990,10 +967,13 @@ void wxGenericTreeCtrl::Init() m_dropEffectAboveItem = false; + m_dndEffect = NoEffect; + m_dndEffectItem = NULL; + m_lastOnSame = false; #if defined( __WXMAC__ ) -#if wxOSX_USE_CARBON +#if wxOSX_USE_ATSU_TEXT m_normalFont.MacCreateFromThemeFont( kThemeViewsFont ) ; #else m_normalFont.MacCreateFromUIFont( kCTFontViewsFontType ) ; @@ -1686,7 +1666,7 @@ wxTreeItemId wxGenericTreeCtrl::AddRoot(const wxString& text, m_dirty = true; // do this first so stuff below doesn't cause flicker - m_anchor = new wxGenericTreeItem((wxGenericTreeItem *)NULL, text, + m_anchor = new wxGenericTreeItem(NULL, text, image, selImage, data); if ( data != NULL ) { @@ -1795,6 +1775,16 @@ void wxGenericTreeCtrl::Delete(const wxTreeItemId& itemId) } wxGenericTreeItem *parent = item->GetParent(); + + // if the selected item will be deleted, select the parent ... + wxGenericTreeItem *to_be_selected = parent; + if (parent) + { + // .. unless there is a next sibling like wxMSW does it + int pos = parent->GetChildren().Index( item ); + if ((int)(parent->GetChildren().GetCount()) > pos+1) + to_be_selected = parent->GetChildren().Item( pos+1 ); + } // don't keep stale pointers around! if ( IsDescendantOf(item, m_key_current) ) @@ -1811,7 +1801,7 @@ void wxGenericTreeCtrl::Delete(const wxTreeItemId& itemId) // a different item, in idle time. if ( m_select_me && IsDescendantOf(item, m_select_me) ) { - m_select_me = parent; + m_select_me = to_be_selected; } if ( IsDescendantOf(item, m_current) ) @@ -1822,7 +1812,7 @@ void wxGenericTreeCtrl::Delete(const wxTreeItemId& itemId) // m_current = parent; m_current = NULL; - m_select_me = parent; + m_select_me = to_be_selected; } // remove the item from the tree @@ -2465,6 +2455,7 @@ int wxGenericTreeCtrl::GetLineHeight(wxGenericTreeItem *item) const void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc) { item->SetFont(this, dc); + item->CalculateSize(this, dc); wxCoord text_h = item->GetTextHeight(); @@ -2474,7 +2465,7 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc) { if ( m_imageListNormal ) { - m_imageListNormal->GetSize( image, image_w, image_h ); + m_imageListNormal->GetSize(image, image_w, image_h); image_w += MARGIN_BETWEEN_IMAGE_AND_TEXT; } else @@ -2489,8 +2480,8 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc) { if ( m_imageListState ) { - m_imageListState->GetSize( state, state_w, state_h ); - if ( image != NO_IMAGE ) + m_imageListState->GetSize(state, state_w, state_h); + if ( image_w != 0 ) state_w += MARGIN_BETWEEN_STATE_AND_IMAGE; else state_w += MARGIN_BETWEEN_IMAGE_AND_TEXT; @@ -2587,8 +2578,10 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc) // except for custom item backgrounds, works for both kinds of theme. else if (drawItemBackground) { - wxRect rect( item->GetX()-2, item->GetY()+offset, - item->GetWidth()+2, total_h-offset ); + wxRect rect( item->GetX() + state_w + image_w - 2, + item->GetY() + offset, + item->GetWidth() - state_w - image_w + 2, + total_h - offset ); if ( hasBgColour ) { dc.DrawRectangle( rect ); @@ -2642,6 +2635,40 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc) // restore normal font dc.SetFont( m_normalFont ); + + if (item == m_dndEffectItem) + { + dc.SetPen( *wxBLACK_PEN ); + // DnD visual effects + switch (m_dndEffect) + { + case BorderEffect: + { + dc.SetBrush(*wxTRANSPARENT_BRUSH); + int w = item->GetWidth() + 2; + int h = total_h + 2; + dc.DrawRectangle( item->GetX() - 1, item->GetY() - 1, w, h); + break; + } + case AboveEffect: + { + int x = item->GetX(), + y = item->GetY(); + dc.DrawLine( x, y, x + item->GetWidth(), y); + break; + } + case BelowEffect: + { + int x = item->GetX(), + y = item->GetY(); + y += total_h - 1; + dc.DrawLine( x, y, x + item->GetWidth(), y); + break; + } + case NoEffect: + break; + } + } } void @@ -2863,7 +2890,7 @@ void wxGenericTreeCtrl::DrawDropEffect(wxGenericTreeItem *item) DrawLine(item, !m_dropEffectAboveItem ); } - SetCursor(wxCURSOR_BULLSEYE); + SetCursor(*wxSTANDARD_CURSOR); } else { @@ -2878,15 +2905,20 @@ void wxGenericTreeCtrl::DrawBorder(const wxTreeItemId &item) wxGenericTreeItem *i = (wxGenericTreeItem*) item.m_pItem; - wxClientDC dc(this); - PrepareDC( dc ); - dc.SetLogicalFunction(wxINVERT); - dc.SetBrush(*wxTRANSPARENT_BRUSH); - - int w = i->GetWidth() + 2; - int h = GetLineHeight(i) + 2; + if (m_dndEffect == NoEffect) + { + m_dndEffect = BorderEffect; + m_dndEffectItem = i; + } + else + { + m_dndEffect = NoEffect; + m_dndEffectItem = NULL; + } - dc.DrawRectangle( i->GetX() - 1, i->GetY() - 1, w, h); + wxRect rect( i->GetX()-1, i->GetY()-1, i->GetWidth()+2, GetLineHeight(i)+2 ); + CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y ); + RefreshRect( rect ); } void wxGenericTreeCtrl::DrawLine(const wxTreeItemId &item, bool below) @@ -2895,18 +2927,23 @@ void wxGenericTreeCtrl::DrawLine(const wxTreeItemId &item, bool below) wxGenericTreeItem *i = (wxGenericTreeItem*) item.m_pItem; - wxClientDC dc(this); - PrepareDC( dc ); - dc.SetLogicalFunction(wxINVERT); - - int x = i->GetX(), - y = i->GetY(); - if ( below ) + if (m_dndEffect == NoEffect) { - y += GetLineHeight(i) - 1; + if (below) + m_dndEffect = BelowEffect; + else + m_dndEffect = AboveEffect; + m_dndEffectItem = i; + } + else + { + m_dndEffect = NoEffect; + m_dndEffectItem = NULL; } - dc.DrawLine( x, y, x + i->GetWidth(), y); + wxRect rect( i->GetX()-1, i->GetY()-1, i->GetWidth()+2, GetLineHeight(i)+2 ); + CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y ); + RefreshRect( rect ); } // ----------------------------------------------------------------------------- @@ -3292,15 +3329,28 @@ bool wxGenericTreeCtrl::GetBoundingRect(const wxTreeItemId& item, if ( textOnly ) { - rect.x = i->GetX(); - rect.width = i->GetWidth(); + int image_h = 0, image_w = 0; + int image = ((wxGenericTreeItem*) item.m_pItem)->GetCurrentImage(); + if ( image != NO_IMAGE && m_imageListNormal ) + { + m_imageListNormal->GetSize( image, image_w, image_h ); + image_w += MARGIN_BETWEEN_IMAGE_AND_TEXT; + } - if ( m_imageListNormal ) + int state_h = 0, state_w = 0; + int state = ((wxGenericTreeItem*) item.m_pItem)->GetState(); + if ( state != wxTREE_ITEMSTATE_NONE && m_imageListState ) { - int image_w, image_h; - m_imageListNormal->GetSize( 0, image_w, image_h ); - rect.width += image_w + MARGIN_BETWEEN_IMAGE_AND_TEXT; + m_imageListState->GetSize( state, state_w, state_h ); + if ( image_w != 0 ) + state_w += MARGIN_BETWEEN_STATE_AND_IMAGE; + else + state_w += MARGIN_BETWEEN_IMAGE_AND_TEXT; } + + rect.x = i->GetX() + state_w + image_w; + rect.width = i->GetWidth() - state_w - image_w; + } else // the entire line { @@ -3536,6 +3586,8 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) #if defined(__WXMSW__) || defined(__WXMAC__) || defined(__WXGTK20__) Update(); #else + // TODO: remove this call or use wxEventLoopBase::GetActive()->YieldFor(wxEVT_CATEGORY_UI) + // instead (needs to be tested!) wxYieldIfNeeded(); #endif } @@ -3551,7 +3603,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) { m_oldSelection->SetHilight(true); RefreshLine(m_oldSelection); - m_oldSelection = (wxGenericTreeItem *)NULL; + m_oldSelection = NULL; } // generate the drag end event @@ -3562,13 +3614,15 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) (void)GetEventHandler()->ProcessEvent(eventEndDrag); m_isDragging = false; - m_dropTarget = (wxGenericTreeItem *)NULL; + m_dropTarget = NULL; SetCursor(m_oldCursor); -#if defined( __WXMSW__ ) || defined(__WXMAC__) +#if defined( __WXMSW__ ) || defined(__WXMAC__) || defined(__WXGTK20__) Update(); #else + // TODO: remove this call or use wxEventLoopBase::GetActive()->YieldFor(wxEVT_CATEGORY_UI) + // instead (needs to be tested!) wxYieldIfNeeded(); #endif } @@ -3937,7 +3991,7 @@ wxGenericTreeCtrl::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant)) return wxListBox::GetClassDefaultAttributes(variant); #else wxVisualAttributes attr; - attr.colFg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); + attr.colFg = wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOXTEXT); attr.colBg = wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX); attr.font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); return attr;