X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ebadbb76d31a63d46a12b34ec2edcdff3030f9f8..923608c3ac95e2c705fb0f49ab48fbe62fc871bd:/src/generic/listctrl.cpp?ds=sidebyside diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp index 05ac0602d0..c6585cd069 100644 --- a/src/generic/listctrl.cpp +++ b/src/generic/listctrl.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: generic/listctrl.cpp +// Name: src/generic/listctrl.cpp // Purpose: generic implementation of wxListCtrl // Author: Robert Roebling // Vadim Zeitlin (virtual list control support) @@ -18,18 +18,11 @@ #include "wx/wxprec.h" #ifdef __BORLANDC__ -#pragma hdrstop + #pragma hdrstop #endif #if wxUSE_LISTCTRL -#ifndef WX_PRECOMP - #include "wx/app.h" - #include "wx/dynarray.h" - #include "wx/dcscreen.h" - #include "wx/textctrl.h" -#endif - // under Win32 we always use the native version and also may use the generic // one, however some things should be done only if we use only the generic // version @@ -51,9 +44,17 @@ IMPLEMENT_DYNAMIC_CLASS(wxListCtrl, wxGenericListCtrl) #endif // HAVE_NATIVE_LISTCTRL/!HAVE_NATIVE_LISTCTRL +#ifndef WX_PRECOMP + #include "wx/dynarray.h" + #include "wx/app.h" + #include "wx/dcscreen.h" + #include "wx/textctrl.h" + #include "wx/listbox.h" + #include "wx/math.h" +#endif + #include "wx/selstore.h" #include "wx/renderer.h" -#include "wx/math.h" #ifdef __WXMAC__ #include "wx/mac/private.h" @@ -412,7 +413,7 @@ class WXDLLEXPORT wxListHeaderWindow : public wxWindow { protected: wxListMainWindow *m_owner; - wxCursor *m_currentCursor; + const wxCursor *m_currentCursor; wxCursor *m_resizeCursor; bool m_isDragging; @@ -706,7 +707,7 @@ public: long FindItem( long start, const wxString& str, bool partial = false ); long FindItem( long start, wxUIntPtr data); long FindItem( const wxPoint& pt ); - long HitTest( int x, int y, int &flags ); + long HitTest( int x, int y, int &flags ) const; void InsertItem( wxListItem &item ); void InsertColumn( long col, wxListItem &item ); int GetItemWidthWithImage(wxListItem * item); @@ -960,7 +961,7 @@ bool wxListItemData::IsHit( int x, int y ) const { wxCHECK_MSG( m_rect, false, _T("can't be called in this mode") ); - return wxRect(GetX(), GetY(), GetWidth(), GetHeight()).Inside(x, y); + return wxRect(GetX(), GetY(), GetWidth(), GetHeight()).Contains(x, y); } int wxListItemData::GetX() const @@ -1583,7 +1584,7 @@ void wxListLineData::DrawTextFormatted(wxDC *dc, // continue until we have enough space or only one character left wxCoord w_c, h_c; - size_t len = text.Length(); + size_t len = text.length(); wxString drawntext = text.Left(len); while (len > 1) { @@ -1596,9 +1597,9 @@ void wxListLineData::DrawTextFormatted(wxDC *dc, } // if still not enough space, remove ellipsis characters - while (ellipsis.Length() > 0 && w + base_w > width) + while (ellipsis.length() > 0 && w + base_w > width) { - ellipsis = ellipsis.Left(ellipsis.Length() - 1); + ellipsis = ellipsis.Left(ellipsis.length() - 1); dc->GetTextExtent(ellipsis, &base_w, &h); } @@ -1697,11 +1698,27 @@ void wxListHeaderWindow::AdjustDC(wxDC& dc) int xpix; m_owner->GetScrollPixelsPerUnit( &xpix, NULL ); - int x; - m_owner->GetViewStart( &x, NULL ); + int view_start; + m_owner->GetViewStart( &view_start, NULL ); + + if (GetLayoutDirection() == wxLayout_RightToLeft) + { + // FIXME: we need a better way for RTL scrolling.. + int scroll_lines = m_owner->GetScrollLines( wxHORIZONTAL ); + if (scroll_lines) + { + int client_size = m_owner->GetClientSize().x; + view_start = scroll_lines - (client_size / xpix) - view_start; + view_start = -view_start; + } + } + + int org_x = 0; + int org_y = 0; + dc.GetDeviceOrigin( &org_x, &org_y ); // account for the horz scrollbar offset - dc.SetDeviceOrigin( -x * xpix, 0 ); + dc.SetDeviceOrigin( org_x - (view_start * xpix), org_y ); } void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) @@ -2033,6 +2050,8 @@ wxListTextCtrlWrapper::wxListTextCtrlWrapper(wxListMainWindow *owner, m_text->Create(owner, wxID_ANY, m_startValue, wxPoint(rectLabel.x-4,rectLabel.y-4), wxSize(rectLabel.width+11,rectLabel.height+8)); + m_text->SetFocus(); + m_text->PushEventHandler(this); } @@ -2042,10 +2061,10 @@ void wxListTextCtrlWrapper::Finish() { m_finished = true; - m_text->PopEventHandler(this); + m_text->RemoveEventHandler(this); m_owner->FinishEditing(m_text); - delete this; + wxPendingDelete.Append( this ); } } @@ -2087,8 +2106,8 @@ void wxListTextCtrlWrapper::OnChar( wxKeyEvent &event ) break; case WXK_ESCAPE: - Finish(); m_owner->OnRenameCancelled( m_itemEdited ); + Finish(); break; default: @@ -2123,16 +2142,13 @@ void wxListTextCtrlWrapper::OnKillFocus( wxFocusEvent &event ) { if ( !m_finished && !m_aboutToFinish ) { - // We must finish regardless of success, otherwise we'll get - // focus problems: - Finish(); - if ( !AcceptChanges() ) m_owner->OnRenameCancelled( m_itemEdited ); + + Finish(); } - // We must let the native text control handle focus, too, otherwise - // it could have problems with the cursor (e.g., in wxGTK). + // We must let the native text control handle focus event.Skip(); } @@ -2381,7 +2397,7 @@ long wxListMainWindow::HitTestLine(size_t line, int x, int y) const wxListLineData *ld = GetLine(line); - if ( ld->HasImage() && GetLineIconRect(line).Inside(x, y) ) + if ( ld->HasImage() && GetLineIconRect(line).Contains(x, y) ) return wxLIST_HITTEST_ONITEMICON; // VS: Testing for "ld->HasText() || InReportView()" instead of @@ -2392,7 +2408,7 @@ long wxListMainWindow::HitTestLine(size_t line, int x, int y) const wxRect rect = InReportView() ? GetLineRect(line) : GetLineLabelRect(line); - if ( rect.Inside(x, y) ) + if ( rect.Contains(x, y) ) return wxLIST_HITTEST_ONITEMLABEL; } @@ -2629,9 +2645,9 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) GetVisibleLinesRange(&visibleFrom, &visibleTo); wxRect rectLine; - wxCoord xOrig, yOrig; - CalcUnscrolledPosition(0, 0, &xOrig, &yOrig); - + int xOrig = dc.LogicalToDeviceX( 0 ); + int yOrig = dc.LogicalToDeviceY( 0 ); + // tell the caller cache to cache the data if ( IsVirtual() ) { @@ -2647,7 +2663,8 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) { rectLine = GetLineRect(line); - if ( !IsExposed(rectLine.x - xOrig, rectLine.y - yOrig, + + if ( !IsExposed(rectLine.x + xOrig, rectLine.y + yOrig, rectLine.width, rectLine.height) ) { // don't redraw unaffected lines to avoid flicker @@ -2858,6 +2875,7 @@ void wxListMainWindow::OnRenameCancelled(size_t itemEdit) void wxListMainWindow::OnMouse( wxMouseEvent &event ) { + #ifdef __WXMAC__ // On wxMac we can't depend on the EVT_KILL_FOCUS event to properly // shutdown the edit control when the mouse is clicked elsewhere on the @@ -2879,7 +2897,15 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event ) } if ( !HasCurrent() || IsEmpty() ) + { + if (event.RightDown()) + { + SendNotify( (size_t)-1, wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK, event.GetPosition() ); + // Allow generation of context menu event + event.Skip(); + } return; + } if (m_dirty) return; @@ -2950,6 +2976,18 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event ) if ( !hitResult ) { // outside of any item + if (event.RightDown()) + { + SendNotify( (size_t) -1, wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK, event.GetPosition() ); + // Allow generation of context menu event + event.Skip(); + } + else + { + // reset the selection and bail out + HighlightAll(false); + } + return; } @@ -3117,10 +3155,22 @@ void wxListMainWindow::MoveToItem(size_t item) } else // !report { - if (rect.x-view_x < 5) - Scroll( (rect.x - 5) / SCROLL_UNIT_X, -1 ); - if (rect.x + rect.width - 5 > view_x + client_w) - Scroll( (rect.x + rect.width - client_w + SCROLL_UNIT_X) / SCROLL_UNIT_X, -1 ); + if (GetLayoutDirection() == wxLayout_RightToLeft) + { +#if 0 + wxPrintf( wxT("rect %d %d %d %d view_x %d\n"), rect.x, rect.y, rect.width, rect.height, view_x ); + int virtual_width = GetVirtualSize().x; + view_x = virtual_width - view_x - client_w; + wxPrintf( wxT("virtual_width %d view_x = %d client_w = %d\n"), virtual_width, view_x, client_w ); +#endif + } + else + { + if (rect.x-view_x < 5) + Scroll( (rect.x - 5) / SCROLL_UNIT_X, -1 ); + if (rect.x + rect.width - 5 > view_x + client_w) + Scroll( (rect.x + rect.width - client_w + SCROLL_UNIT_X) / SCROLL_UNIT_X, -1 ); + } } } @@ -3239,7 +3289,19 @@ void wxListMainWindow::OnChar( wxKeyEvent &event ) return; } - switch (event.GetKeyCode()) + // don't use m_linesPerPage directly as it might not be computed yet + const int pageSize = GetCountPerPage(); + wxCHECK_RET( pageSize, _T("should have non zero page size") ); + + if (GetLayoutDirection() == wxLayout_RightToLeft) + { + if (event.GetKeyCode() == WXK_RIGHT) + event.m_keyCode = WXK_LEFT; + else if (event.GetKeyCode() == WXK_LEFT) + event.m_keyCode = WXK_RIGHT; + } + + switch ( event.GetKeyCode() ) { case WXK_UP: if ( m_current > 0 ) @@ -3261,9 +3323,10 @@ void wxListMainWindow::OnChar( wxKeyEvent &event ) OnArrowChar( 0, event ); break; - case WXK_PRIOR: + case WXK_PAGEUP: { - int steps = InReportView() ? m_linesPerPage - 1 : m_current % m_linesPerPage; + int steps = InReportView() ? pageSize - 1 + : m_current % pageSize; int index = m_current - steps; if (index < 0) @@ -3273,11 +3336,11 @@ void wxListMainWindow::OnChar( wxKeyEvent &event ) } break; - case WXK_NEXT: + case WXK_PAGEDOWN: { int steps = InReportView() - ? m_linesPerPage - 1 - : m_linesPerPage - (m_current % m_linesPerPage) - 1; + ? pageSize - 1 + : pageSize - (m_current % pageSize) - 1; size_t index = m_current + steps; size_t count = GetItemCount(); @@ -3291,7 +3354,7 @@ void wxListMainWindow::OnChar( wxKeyEvent &event ) case WXK_LEFT: if ( !InReportView() ) { - int index = m_current - m_linesPerPage; + int index = m_current - pageSize; if (index < 0) index = 0; @@ -3302,7 +3365,7 @@ void wxListMainWindow::OnChar( wxKeyEvent &event ) case WXK_RIGHT: if ( !InReportView() ) { - size_t index = m_current + m_linesPerPage; + size_t index = m_current + pageSize; size_t count = GetItemCount(); if ( index >= count ) @@ -4406,7 +4469,7 @@ long wxListMainWindow::FindItem( const wxPoint& pt ) return wxNOT_FOUND; } -long wxListMainWindow::HitTest( int x, int y, int &flags ) +long wxListMainWindow::HitTest( int x, int y, int &flags ) const { CalcUnscrolledPosition( x, y, &x, &y ); @@ -4934,11 +4997,18 @@ bool wxGenericListCtrl::SetItemState( long item, long state, long stateMask ) bool wxGenericListCtrl::SetItemImage( long item, int image, int WXUNUSED(selImage) ) +{ + return SetItemColumnImage(item, 0, image); +} + +bool +wxGenericListCtrl::SetItemColumnImage( long item, long column, int image ) { wxListItem info; info.m_image = image; info.m_mask = wxLIST_MASK_IMAGE; info.m_itemId = item; + info.m_col = column; m_mainWin->SetItem( info ); return true; } @@ -5018,10 +5088,12 @@ wxSize wxGenericListCtrl::GetItemSpacing() const return wxSize(spacing, spacing); } +#if WXWIN_COMPATIBILITY_2_6 int wxGenericListCtrl::GetItemSpacing( bool isSmall ) const { return m_mainWin->GetItemSpacing( isSmall ); } +#endif // WXWIN_COMPATIBILITY_2_6 void wxGenericListCtrl::SetItemTextColour( long item, const wxColour &col ) { @@ -5221,7 +5293,8 @@ long wxGenericListCtrl::FindItem( long WXUNUSED(start), const wxPoint& pt, return m_mainWin->FindItem( pt ); } -long wxGenericListCtrl::HitTest( const wxPoint &point, int &flags ) +// TODO: sub item hit testing +long wxGenericListCtrl::HitTest(const wxPoint& point, int& flags, long *) const { return m_mainWin->HitTest( (int)point.x, (int)point.y, flags ); } @@ -5336,10 +5409,10 @@ void wxGenericListCtrl::ResizeReportView(bool showHeader) { m_headerWin->SetSize( 0, 0, cw, m_headerHeight ); if(ch > m_headerHeight) - m_mainWin->SetSize( 0, m_headerHeight + 1, + m_mainWin->SetSize( 0, m_headerHeight + 1, cw, ch - m_headerHeight - 1 ); else - m_mainWin->SetSize( 0, m_headerHeight + 1, + m_mainWin->SetSize( 0, m_headerHeight + 1, cw, 0); } else // no header window @@ -5413,10 +5486,6 @@ bool wxGenericListCtrl::SetFont( const wxFont &font ) return true; } -#if _USE_VISATTR -#include "wx/listbox.h" -#endif - // static wxVisualAttributes wxGenericListCtrl::GetClassDefaultAttributes(wxWindowVariant variant) @@ -5478,12 +5547,12 @@ bool wxGenericListCtrl::DoPopupMenu( wxMenu *menu, int x, int y ) void wxGenericListCtrl::DoClientToScreen( int *x, int *y ) const { - return m_mainWin->DoClientToScreen(x, y); + m_mainWin->DoClientToScreen(x, y); } void wxGenericListCtrl::DoScreenToClient( int *x, int *y ) const { - return m_mainWin->DoScreenToClient(x, y); + m_mainWin->DoScreenToClient(x, y); } void wxGenericListCtrl::SetFocus() @@ -5618,4 +5687,3 @@ void wxGenericListCtrl::Thaw() } #endif // wxUSE_LISTCTRL -