X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6f02a879ed7efc5fcf6328ff47a1352ec82812b7..05a98b6d5d201eb8edea04b1ab022e4a9a46e9f0:/src/generic/listctrl.cpp diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp index 3ebe7d921a..d47af77952 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,42 +18,35 @@ #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 -#if defined(__WIN32__) && !defined(__WXUNIVERSAL__) - #define HAVE_NATIVE_LISTCTRL -#endif - -// if we have the native control, wx/listctrl.h declares it and not this one -#ifdef HAVE_NATIVE_LISTCTRL - #include "wx/generic/listctrl.h" -#else // !HAVE_NATIVE_LISTCTRL - #include "wx/listctrl.h" +#include "wx/listctrl.h" +#if (!defined(__WXMSW__) || defined(__WXUNIVERSAL__)) && !defined(__WXMAC__) // if we have a native version, its implementation file does all this IMPLEMENT_DYNAMIC_CLASS(wxListItem, wxObject) IMPLEMENT_DYNAMIC_CLASS(wxListView, wxListCtrl) IMPLEMENT_DYNAMIC_CLASS(wxListEvent, wxNotifyEvent) IMPLEMENT_DYNAMIC_CLASS(wxListCtrl, wxGenericListCtrl) -#endif // HAVE_NATIVE_LISTCTRL/!HAVE_NATIVE_LISTCTRL +#endif + +#ifndef WX_PRECOMP + #include "wx/scrolwin.h" + #include "wx/timer.h" + #include "wx/settings.h" + #include "wx/dynarray.h" + #include "wx/dcclient.h" + #include "wx/dcscreen.h" + #include "wx/math.h" +#endif +#include "wx/imaglist.h" #include "wx/selstore.h" #include "wx/renderer.h" -#include "wx/math.h" #ifdef __WXMAC__ #include "wx/mac/private.h" @@ -65,35 +58,6 @@ #define _USE_VISATTR 0 -// ---------------------------------------------------------------------------- -// events -// ---------------------------------------------------------------------------- - -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_DRAG) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_RDRAG) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_END_LABEL_EDIT) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_DELETE_ITEM) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS) -#if WXWIN_COMPATIBILITY_2_4 -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_GET_INFO) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_SET_INFO) -#endif -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_SELECTED) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_DESELECTED) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_KEY_DOWN) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_INSERT_ITEM) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_CLICK) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_RIGHT_CLICK) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_BEGIN_DRAG) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_DRAGGING) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_END_DRAG) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_ACTIVATED) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_FOCUSED) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_CACHE_HINT) - // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- @@ -268,7 +232,7 @@ private: // wxListLineData (internal) //----------------------------------------------------------------------------- -WX_DECLARE_LIST(wxListItemData, wxListItemDataList); +WX_DECLARE_EXPORTED_LIST(wxListItemData, wxListItemDataList); #include "wx/listimpl.cpp" WX_DEFINE_LIST(wxListItemDataList) @@ -392,7 +356,12 @@ private: // draw the text on the DC with the correct justification; also add an // ellipsis if the text is too large to fit in the current width - void DrawTextFormatted(wxDC *dc, const wxString &text, int col, int x, int y, int width); + void DrawTextFormatted(wxDC *dc, + const wxString &text, + int col, + int x, + int yMid, // this is middle, not top, of the text + int width); }; WX_DECLARE_EXPORTED_OBJARRAY(wxListLineData, wxListLineDataArray); @@ -407,7 +376,7 @@ class WXDLLEXPORT wxListHeaderWindow : public wxWindow { protected: wxListMainWindow *m_owner; - wxCursor *m_currentCursor; + const wxCursor *m_currentCursor; wxCursor *m_resizeCursor; bool m_isDragging; @@ -471,13 +440,18 @@ public: }; //----------------------------------------------------------------------------- -// wxListTextCtrl (internal) +// wxListTextCtrlWrapper: wraps a wxTextCtrl to make it work for inline editing //----------------------------------------------------------------------------- -class WXDLLEXPORT wxListTextCtrl: public wxTextCtrl +class WXDLLEXPORT wxListTextCtrlWrapper : public wxEvtHandler { public: - wxListTextCtrl(wxListMainWindow *owner, size_t itemEdit); + // NB: text must be a valid object but not Create()d yet + wxListTextCtrlWrapper(wxListMainWindow *owner, + wxTextCtrl *text, + size_t itemEdit); + + wxTextCtrl *GetText() const { return m_text; } void AcceptChangesAndFinish(); @@ -491,6 +465,7 @@ protected: private: wxListMainWindow *m_owner; + wxTextCtrl *m_text; wxString m_startValue; size_t m_itemEdited; bool m_finished; @@ -503,7 +478,7 @@ private: // wxListMainWindow (internal) //----------------------------------------------------------------------------- -WX_DECLARE_LIST(wxListHeaderData, wxListHeaderDataList); +WX_DECLARE_EXPORTED_LIST(wxListHeaderData, wxListHeaderDataList); #include "wx/listimpl.cpp" WX_DEFINE_LIST(wxListHeaderDataList) @@ -598,7 +573,19 @@ public: void MoveToFocus() { MoveToItem(m_current); } // start editing the label of the given item - void EditLabel( long item ); + wxTextCtrl *EditLabel(long item, + wxClassInfo* textControlClass = CLASSINFO(wxTextCtrl)); + wxTextCtrl *GetEditControl() const + { + return m_textctrlWrapper ? m_textctrlWrapper->GetText() : NULL; + } + + void FinishEditing(wxTextCtrl *text) + { + delete text; + m_textctrlWrapper = NULL; + SetFocusIgnoringChildren(); + } // suspend/resume redrawing the control void Freeze(); @@ -625,7 +612,7 @@ public: void GetImageSize( int index, int &width, int &height ) const; int GetTextLength( const wxString &s ) const; - void SetImageList( wxImageListType *imageList, int which ); + void SetImageList( wxImageList *imageList, int which ); void SetItemSpacing( int spacing, bool isSmall = false ); int GetItemSpacing( bool isSmall = false ); @@ -683,7 +670,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); @@ -757,8 +744,8 @@ public: bool m_dirty; wxColour *m_highlightColour; - wxImageListType *m_small_image_list; - wxImageListType *m_normal_image_list; + wxImageList *m_small_image_list; + wxImageList *m_normal_image_list; int m_small_spacing; int m_normal_spacing; bool m_hasFocus; @@ -775,8 +762,6 @@ public: m_lineBeforeLastClicked, m_lineSelectSingleOnUp; - wxListTextCtrl* m_textctrl; - protected: wxWindow *GetMainWindowOfCompositeControl() { return GetParent(); } @@ -849,6 +834,11 @@ private: // if this is > 0, the control is frozen and doesn't redraw itself size_t m_freezeCount; + // wrapper around the text control currently used for in place editing or + // NULL if no item is being edited + wxListTextCtrlWrapper *m_textctrlWrapper; + + DECLARE_DYNAMIC_CLASS(wxListMainWindow) DECLARE_EVENT_TABLE() @@ -934,7 +924,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 @@ -1477,7 +1467,7 @@ void wxListLineData::DrawInReportMode( wxDC *dc, dc->DrawRectangle( rectHL ); wxCoord x = rect.x + HEADER_OFFSET_X, - y = rect.y + (LINE_SPACING + EXTRA_HEIGHT) / 2; + yMid = rect.y + rect.height/2; size_t col = 0; for ( wxListItemDataList::compatibility_iterator node = m_items.GetFirst(); @@ -1493,8 +1483,8 @@ void wxListLineData::DrawInReportMode( wxDC *dc, if ( item->HasImage() ) { int ix, iy; - m_owner->DrawImage( item->GetImage(), dc, xOld, y ); m_owner->GetImageSize( item->GetImage(), ix, iy ); + m_owner->DrawImage( item->GetImage(), dc, xOld, yMid - iy/2 ); ix += IMAGE_MARGIN_IN_REPORT_MODE; @@ -1502,10 +1492,8 @@ void wxListLineData::DrawInReportMode( wxDC *dc, width -= ix; } - wxDCClipper clipper(*dc, xOld, y, width - 8, rect.height); - if ( item->HasText() ) - DrawTextFormatted(dc, item->GetText(), col, xOld, y, width - 8); + DrawTextFormatted(dc, item->GetText(), col, xOld, yMid, width - 8); } } @@ -1513,18 +1501,21 @@ void wxListLineData::DrawTextFormatted(wxDC *dc, const wxString &text, int col, int x, - int y, + int yMid, int width) { - wxString drawntext, ellipsis; - wxCoord w, h, base_w; - wxListItem item; + wxCoord w, h; + dc->GetTextExtent(text, &w, &h); + + const wxCoord y = yMid - (h + 1)/2; + + wxDCClipper clipper(*dc, x, y, width, h); // determine if the string can fit inside the current width - dc->GetTextExtent(text, &w, &h); if (w <= width) { // it can, draw it using the items alignment + wxListItem item; m_owner->GetColumn(col, item); switch ( item.GetAlign() ) { @@ -1550,13 +1541,14 @@ void wxListLineData::DrawTextFormatted(wxDC *dc, else // otherwise, truncate and add an ellipsis if possible { // determine the base width - ellipsis = wxString(wxT("...")); + wxString ellipsis(wxT("...")); + wxCoord base_w; dc->GetTextExtent(ellipsis, &base_w, &h); // continue until we have enough space or only one character left wxCoord w_c, h_c; - size_t len = text.Length(); - drawntext = text.Left(len); + size_t len = text.length(); + wxString drawntext = text.Left(len); while (len > 1) { dc->GetTextExtent(drawntext.Last(), &w_c, &h_c); @@ -1568,9 +1560,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); } @@ -1669,11 +1661,26 @@ 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 ); + + + 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 ); +#ifdef __WXGTK__ + if (GetLayoutDirection() == wxLayout_RightToLeft) + { + // Maybe we just have to check for m_signX + // in the DC, but I leave the #ifdef __WXGTK__ + // for now + dc.SetDeviceOrigin( org_x + (view_start * xpix), org_y ); + } + else +#endif + dc.SetDeviceOrigin( org_x - (view_start * xpix), org_y ); } void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) @@ -1732,7 +1739,7 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) static const int MARGIN_BETWEEN_TEXT_AND_ICON = 2; int ix = 0, iy = 0; // init them just to suppress the compiler warnings const int image = item.m_image; - wxImageListType *imageList; + wxImageList *imageList; if ( image != -1 ) { imageList = m_owner->m_small_image_list; @@ -1977,20 +1984,23 @@ void wxListRenameTimer::Notify() } //----------------------------------------------------------------------------- -// wxListTextCtrl (internal) +// wxListTextCtrlWrapper (internal) //----------------------------------------------------------------------------- -BEGIN_EVENT_TABLE(wxListTextCtrl,wxTextCtrl) - EVT_CHAR (wxListTextCtrl::OnChar) - EVT_KEY_UP (wxListTextCtrl::OnKeyUp) - EVT_KILL_FOCUS (wxListTextCtrl::OnKillFocus) +BEGIN_EVENT_TABLE(wxListTextCtrlWrapper, wxEvtHandler) + EVT_CHAR (wxListTextCtrlWrapper::OnChar) + EVT_KEY_UP (wxListTextCtrlWrapper::OnKeyUp) + EVT_KILL_FOCUS (wxListTextCtrlWrapper::OnKillFocus) END_EVENT_TABLE() -wxListTextCtrl::wxListTextCtrl(wxListMainWindow *owner, size_t itemEdit) +wxListTextCtrlWrapper::wxListTextCtrlWrapper(wxListMainWindow *owner, + wxTextCtrl *text, + size_t itemEdit) : m_startValue(owner->GetItemText(itemEdit)), m_itemEdited(itemEdit) { m_owner = owner; + m_text = text; m_finished = false; m_aboutToFinish = false; @@ -1999,27 +2009,30 @@ wxListTextCtrl::wxListTextCtrl(wxListMainWindow *owner, size_t itemEdit) m_owner->CalcScrolledPosition(rectLabel.x, rectLabel.y, &rectLabel.x, &rectLabel.y); - (void)Create(owner, wxID_ANY, m_startValue, - wxPoint(rectLabel.x-4,rectLabel.y-4), - wxSize(rectLabel.width+11,rectLabel.height+8)); + 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); } -void wxListTextCtrl::Finish() +void wxListTextCtrlWrapper::Finish() { if ( !m_finished ) { - wxPendingDelete.Append(this); - m_owner->m_textctrl = NULL; - m_finished = true; - m_owner->SetFocusIgnoringChildren(); + m_text->RemoveEventHandler(this); + m_owner->FinishEditing(m_text); + + wxPendingDelete.Append( this ); } } -bool wxListTextCtrl::AcceptChanges() +bool wxListTextCtrlWrapper::AcceptChanges() { - const wxString value = GetValue(); + const wxString value = m_text->GetValue(); if ( value == m_startValue ) // nothing changed, always accept @@ -2035,7 +2048,7 @@ bool wxListTextCtrl::AcceptChanges() return true; } -void wxListTextCtrl::AcceptChangesAndFinish() +void wxListTextCtrlWrapper::AcceptChangesAndFinish() { m_aboutToFinish = true; @@ -2046,7 +2059,7 @@ void wxListTextCtrl::AcceptChangesAndFinish() Finish(); } -void wxListTextCtrl::OnChar( wxKeyEvent &event ) +void wxListTextCtrlWrapper::OnChar( wxKeyEvent &event ) { switch ( event.m_keyCode ) { @@ -2055,8 +2068,8 @@ void wxListTextCtrl::OnChar( wxKeyEvent &event ) break; case WXK_ESCAPE: - Finish(); m_owner->OnRenameCancelled( m_itemEdited ); + Finish(); break; default: @@ -2064,7 +2077,7 @@ void wxListTextCtrl::OnChar( wxKeyEvent &event ) } } -void wxListTextCtrl::OnKeyUp( wxKeyEvent &event ) +void wxListTextCtrlWrapper::OnKeyUp( wxKeyEvent &event ) { if (m_finished) { @@ -2074,33 +2087,30 @@ void wxListTextCtrl::OnKeyUp( wxKeyEvent &event ) // auto-grow the textctrl: wxSize parentSize = m_owner->GetSize(); - wxPoint myPos = GetPosition(); - wxSize mySize = GetSize(); + wxPoint myPos = m_text->GetPosition(); + wxSize mySize = m_text->GetSize(); int sx, sy; - GetTextExtent(GetValue() + _T("MM"), &sx, &sy); + m_text->GetTextExtent(m_text->GetValue() + _T("MM"), &sx, &sy); if (myPos.x + sx > parentSize.x) sx = parentSize.x - myPos.x; if (mySize.x > sx) sx = mySize.x; - SetSize(sx, wxDefaultCoord); + m_text->SetSize(sx, wxDefaultCoord); event.Skip(); } -void wxListTextCtrl::OnKillFocus( wxFocusEvent &event ) +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(); } @@ -2131,8 +2141,8 @@ void wxListMainWindow::Init() m_headerWidth = m_lineHeight = 0; - m_small_image_list = (wxImageListType *) NULL; - m_normal_image_list = (wxImageListType *) NULL; + m_small_image_list = (wxImageList *) NULL; + m_normal_image_list = (wxImageList *) NULL; m_small_spacing = 30; m_normal_spacing = 40; @@ -2143,7 +2153,7 @@ void wxListMainWindow::Init() m_lastOnSame = false; m_renameTimer = new wxListRenameTimer( this ); - m_textctrl = NULL; + m_textctrlWrapper = NULL; m_current = m_lineLastClicked = @@ -2349,7 +2359,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 @@ -2360,7 +2370,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; } @@ -2564,7 +2574,7 @@ void wxListMainWindow::Thaw() { wxCHECK_RET( m_freezeCount > 0, _T("thawing unfrozen list control?") ); - if ( !--m_freezeCount ) + if ( --m_freezeCount == 0 ) Refresh(); } @@ -2597,9 +2607,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() ) { @@ -2615,7 +2625,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 @@ -2751,31 +2762,37 @@ void wxListMainWindow::ChangeCurrent(size_t current) SendNotify(current, wxEVT_COMMAND_LIST_ITEM_FOCUSED); } -void wxListMainWindow::EditLabel( long item ) +wxTextCtrl *wxListMainWindow::EditLabel(long item, wxClassInfo* textControlClass) { - wxCHECK_RET( (item >= 0) && ((size_t)item < GetItemCount()), + wxCHECK_MSG( (item >= 0) && ((size_t)item < GetItemCount()), NULL, wxT("wrong index in wxGenericListCtrl::EditLabel()") ); + wxASSERT_MSG( textControlClass->IsKindOf(CLASSINFO(wxTextCtrl)), + wxT("EditLabel() needs a text control") ); + size_t itemEdit = (size_t)item; wxListEvent le( wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT, GetParent()->GetId() ); le.SetEventObject( GetParent() ); le.m_itemIndex = item; wxListLineData *data = GetLine(itemEdit); - wxCHECK_RET( data, _T("invalid index in EditLabel()") ); + wxCHECK_MSG( data, NULL, _T("invalid index in EditLabel()") ); data->GetItem( 0, le.m_item ); if ( GetParent()->GetEventHandler()->ProcessEvent( le ) && !le.IsAllowed() ) + { // vetoed by user code - return; + return NULL; + } // 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 ) wxSafeYield(); - m_textctrl = new wxListTextCtrl(this, itemEdit); - m_textctrl->SetFocus(); + wxTextCtrl * const text = (wxTextCtrl *)textControlClass->CreateObject(); + m_textctrlWrapper = new wxListTextCtrlWrapper(this, text, item); + return m_textctrlWrapper->GetText(); } void wxListMainWindow::OnRenameTimer() @@ -2820,14 +2837,15 @@ 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 // listctrl because the order of events is different (or something like // that), so explicitly end the edit if it is active. - if ( event.LeftDown() && m_textctrl) - m_textctrl->AcceptChangesAndFinish(); -#endif + if ( event.LeftDown() && m_textctrlWrapper ) + m_textctrlWrapper->AcceptChangesAndFinish(); +#endif // __WXMAC__ event.SetEventObject( GetParent() ); if ( GetParent()->GetEventHandler()->ProcessEvent( event) ) @@ -2841,7 +2859,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; @@ -2912,6 +2938,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; } @@ -3201,7 +3239,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 ) @@ -3223,9 +3273,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) @@ -3235,11 +3286,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(); @@ -3253,7 +3304,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; @@ -3264,7 +3315,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 ) @@ -3396,7 +3447,7 @@ int wxListMainWindow::GetTextLength( const wxString &s ) const return lw + AUTOSIZE_COL_MARGIN; } -void wxListMainWindow::SetImageList( wxImageListType *imageList, int which ) +void wxListMainWindow::SetImageList( wxImageList *imageList, int which ) { m_dirty = true; @@ -4368,7 +4419,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 ); @@ -4631,9 +4682,9 @@ END_EVENT_TABLE() wxGenericListCtrl::wxGenericListCtrl() { - m_imageListNormal = (wxImageListType *) NULL; - m_imageListSmall = (wxImageListType *) NULL; - m_imageListState = (wxImageListType *) NULL; + m_imageListNormal = (wxImageList *) NULL; + m_imageListSmall = (wxImageList *) NULL; + m_imageListState = (wxImageList *) NULL; m_ownsImageListNormal = m_ownsImageListSmall = @@ -4673,10 +4724,10 @@ void wxGenericListCtrl::CalculateAndSetHeaderHeight() { m_headerHeight = h; - m_headerWin->SetSize(m_headerWin->GetSize().x, m_headerHeight); - if ( HasHeader() ) ResizeReportView(true); + else //why is this needed if it doesn't have a header? + m_headerWin->SetSize(m_headerWin->GetSize().x, m_headerHeight); } } } @@ -4703,7 +4754,7 @@ bool wxGenericListCtrl::Create(wxWindow *parent, { m_imageListNormal = m_imageListSmall = - m_imageListState = (wxImageListType *) NULL; + m_imageListState = (wxImageList *) NULL; m_ownsImageListNormal = m_ownsImageListSmall = m_ownsImageListState = false; @@ -4896,11 +4947,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; } @@ -4980,10 +5038,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 ) { @@ -5060,7 +5120,7 @@ long wxGenericListCtrl::GetNextItem( long item, int geom, int state ) const return m_mainWin->GetNextItem( item, geom, state ); } -wxImageListType *wxGenericListCtrl::GetImageList(int which) const +wxImageList *wxGenericListCtrl::GetImageList(int which) const { if (which == wxIMAGE_LIST_NORMAL) return m_imageListNormal; @@ -5069,10 +5129,10 @@ wxImageListType *wxGenericListCtrl::GetImageList(int which) const else if (which == wxIMAGE_LIST_STATE) return m_imageListState; - return (wxImageListType *) NULL; + return (wxImageList *) NULL; } -void wxGenericListCtrl::SetImageList( wxImageListType *imageList, int which ) +void wxGenericListCtrl::SetImageList( wxImageList *imageList, int which ) { if ( which == wxIMAGE_LIST_NORMAL ) { @@ -5099,7 +5159,7 @@ void wxGenericListCtrl::SetImageList( wxImageListType *imageList, int which ) m_mainWin->SetImageList( imageList, which ); } -void wxGenericListCtrl::AssignImageList(wxImageListType *imageList, int which) +void wxGenericListCtrl::AssignImageList(wxImageList *imageList, int which) { SetImageList(imageList, which); if ( which == wxIMAGE_LIST_NORMAL ) @@ -5150,9 +5210,15 @@ bool wxGenericListCtrl::DeleteColumn( int col ) return true; } -void wxGenericListCtrl::Edit( long item ) +wxTextCtrl *wxGenericListCtrl::EditLabel(long item, + wxClassInfo* textControlClass) +{ + return m_mainWin->EditLabel( item, textControlClass ); +} + +wxTextCtrl *wxGenericListCtrl::GetEditControl() const { - m_mainWin->EditLabel( item ); + return m_mainWin->GetEditControl(); } bool wxGenericListCtrl::EnsureVisible( long item ) @@ -5177,7 +5243,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 ); } @@ -5291,7 +5358,12 @@ void wxGenericListCtrl::ResizeReportView(bool showHeader) if ( showHeader ) { m_headerWin->SetSize( 0, 0, cw, m_headerHeight ); - m_mainWin->SetSize( 0, m_headerHeight + 1, cw, ch - m_headerHeight - 1 ); + if(ch > m_headerHeight) + m_mainWin->SetSize( 0, m_headerHeight + 1, + cw, ch - m_headerHeight - 1 ); + else + m_mainWin->SetSize( 0, m_headerHeight + 1, + cw, 0); } else // no header window { @@ -5364,10 +5436,6 @@ bool wxGenericListCtrl::SetFont( const wxFont &font ) return true; } -#if _USE_VISATTR -#include "wx/listbox.h" -#endif - // static wxVisualAttributes wxGenericListCtrl::GetClassDefaultAttributes(wxWindowVariant variant) @@ -5427,6 +5495,16 @@ bool wxGenericListCtrl::DoPopupMenu( wxMenu *menu, int x, int y ) #endif } +void wxGenericListCtrl::DoClientToScreen( int *x, int *y ) const +{ + m_mainWin->DoClientToScreen(x, y); +} + +void wxGenericListCtrl::DoScreenToClient( int *x, int *y ) const +{ + m_mainWin->DoScreenToClient(x, y); +} + void wxGenericListCtrl::SetFocus() { // The test in window.cpp fails as we are a composite @@ -5559,4 +5637,3 @@ void wxGenericListCtrl::Thaw() } #endif // wxUSE_LISTCTRL -