X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ed84dc74d9bd041c9c446cb87e598c2c4df0fa2f..b54a0e3913d919ed1ed2b51acb0ebbe5e4c0bb11:/src/generic/listctrl.cpp diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp index 008ee79078..03e26f11e5 100644 --- a/src/generic/listctrl.cpp +++ b/src/generic/listctrl.cpp @@ -25,15 +25,6 @@ #include "wx/listctrl.h" -#if ((!defined(__WXMSW__) && !(defined(__WXMAC__) && wxOSX_USE_CARBON)) || defined(__WXUNIVERSAL__)) - // 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 - #ifndef WX_PRECOMP #include "wx/scrolwin.h" #include "wx/timer.h" @@ -696,7 +687,10 @@ void wxListLineData::ApplyAttributes(wxDC *dc, else colText = *wxBLACK; #else - colText = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT); + if ( hasFocus ) + colText = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT); + else + colText = wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOXHIGHLIGHTTEXT); #endif } else if ( attr && attr->HasTextColour() ) @@ -804,7 +798,8 @@ void wxListLineData::DrawInReportMode( wxDC *dc, int xOld = x; x += width; - const int wText = width - 8; + width -= 8; + const int wText = width; wxDCClipper clipper(*dc, xOld, rect.y, wText, rect.height); if ( item->HasImage() ) @@ -820,7 +815,7 @@ void wxListLineData::DrawInReportMode( wxDC *dc, } if ( item->HasText() ) - DrawTextFormatted(dc, item->GetText(), col, xOld, yMid, wText); + DrawTextFormatted(dc, item->GetText(), col, xOld, yMid, width); } } @@ -1051,7 +1046,7 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) // NB: The code below is not really Mac-specific, but since we are close // to 2.8 release and I don't have time to test on other platforms, I -// defined this only for wxMac. If this behavior is desired on +// defined this only for wxMac. If this behaviour is desired on // other platforms, please go ahead and revise or remove the #ifdef. #ifdef __WXMAC__ if ( !m_owner->IsVirtual() && (item.m_mask & wxLIST_MASK_STATE) && @@ -1407,23 +1402,31 @@ wxListTextCtrlWrapper::wxListTextCtrlWrapper(wxListMainWindow *owner, m_text->PushEventHandler(this); } -void wxListTextCtrlWrapper::EndEdit(bool discardChanges) +void wxListTextCtrlWrapper::EndEdit(EndReason reason) { m_aboutToFinish = true; - if ( discardChanges ) + switch ( reason ) { - m_owner->OnRenameCancelled(m_itemEdited); + case End_Accept: + // Notify the owner about the changes + AcceptChanges(); - Finish( true ); - } - else - { - // Notify the owner about the changes - AcceptChanges(); + // Even if vetoed, close the control (consistent with MSW) + Finish( true ); + break; + + case End_Discard: + m_owner->OnRenameCancelled(m_itemEdited); - // Even if vetoed, close the control (consistent with MSW) - Finish( true ); + Finish( true ); + break; + + case End_Destroy: + // Don't generate any notifications for the control being destroyed + // and don't set focus to it neither. + Finish(false); + break; } } @@ -1458,20 +1461,28 @@ bool wxListTextCtrlWrapper::AcceptChanges() } void wxListTextCtrlWrapper::OnChar( wxKeyEvent &event ) +{ + if ( !CheckForEndEditKey(event) ) + event.Skip(); +} + +bool wxListTextCtrlWrapper::CheckForEndEditKey(const wxKeyEvent& event) { switch ( event.m_keyCode ) { case WXK_RETURN: - EndEdit( false ); + EndEdit( End_Accept ); break; case WXK_ESCAPE: - EndEdit( true ); + EndEdit( End_Discard ); break; default: - event.Skip(); + return false; } + + return true; } void wxListTextCtrlWrapper::OnKeyUp( wxKeyEvent &event ) @@ -1515,6 +1526,7 @@ void wxListTextCtrlWrapper::OnKillFocus( wxFocusEvent &event ) BEGIN_EVENT_TABLE(wxListMainWindow, wxWindow) EVT_PAINT (wxListMainWindow::OnPaint) EVT_MOUSE_EVENTS (wxListMainWindow::OnMouse) + EVT_CHAR_HOOK (wxListMainWindow::OnCharHook) EVT_CHAR (wxListMainWindow::OnChar) EVT_KEY_DOWN (wxListMainWindow::OnKeyDown) EVT_KEY_UP (wxListMainWindow::OnKeyUp) @@ -1600,6 +1612,9 @@ wxListMainWindow::wxListMainWindow( wxWindow *parent, wxListMainWindow::~wxListMainWindow() { + if ( m_textctrlWrapper ) + m_textctrlWrapper->EndEdit(wxListTextCtrlWrapper::End_Destroy); + DoDeleteAllItems(); WX_CLEAR_LIST(wxListHeaderDataList, m_columns); WX_CLEAR_ARRAY(m_aColWidths); @@ -2273,7 +2288,7 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event ) // 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_textctrlWrapper ) - m_textctrlWrapper->EndEdit( false ); + m_textctrlWrapper->EndEdit(wxListTextCtrlWrapper::End_Accept); #endif // __WXMAC__ if ( event.LeftDown() ) @@ -2682,6 +2697,16 @@ void wxListMainWindow::OnKeyDown( wxKeyEvent &event ) if (parent->GetEventHandler()->ProcessEvent( ke )) return; + // send a list event + wxListEvent le( wxEVT_COMMAND_LIST_KEY_DOWN, parent->GetId() ); + le.m_itemIndex = m_current; + if (HasCurrent()) + GetLine(m_current)->GetItem( 0, le.m_item ); + le.m_code = event.GetKeyCode(); + le.SetEventObject( parent ); + if (parent->GetEventHandler()->ProcessEvent( le )) + return; + event.Skip(); } @@ -2697,21 +2722,26 @@ void wxListMainWindow::OnKeyUp( wxKeyEvent &event ) event.Skip(); } -void wxListMainWindow::OnChar( wxKeyEvent &event ) +void wxListMainWindow::OnCharHook( wxKeyEvent &event ) { - wxWindow *parent = GetParent(); - - // send a list_key event up - if ( HasCurrent() ) + if ( m_textctrlWrapper ) { - wxListEvent le( wxEVT_COMMAND_LIST_KEY_DOWN, GetParent()->GetId() ); - le.m_itemIndex = m_current; - GetLine(m_current)->GetItem( 0, le.m_item ); - le.m_code = event.GetKeyCode(); - le.SetEventObject( parent ); - parent->GetEventHandler()->ProcessEvent( le ); + // When an in-place editor is active we should ensure that it always + // gets the key events that are special to it. + if ( m_textctrlWrapper->CheckForEndEditKey(event) ) + { + // Skip the call to wxEvent::Skip() below. + return; + } } + event.Skip(); +} + +void wxListMainWindow::OnChar( wxKeyEvent &event ) +{ + wxWindow *parent = GetParent(); + // propagate the char event upwards wxKeyEvent ke(event); ke.SetEventObject( parent ); @@ -4022,6 +4052,19 @@ void wxListMainWindow::InsertItem( wxListItem &item ) wxListLineData *line = new wxListLineData(this); line->SetItem( item.m_col, item ); + if ( item.m_mask & wxLIST_MASK_IMAGE ) + { + // Reset the buffered height if it's not big enough for the new image. + int image = item.GetImage(); + if ( m_small_image_list && image != -1 && InReportView() ) + { + int imageWidth, imageHeight; + m_small_image_list->GetSize(image, imageWidth, imageHeight); + + if ( imageHeight > m_lineHeight ) + m_lineHeight = 0; + } + } m_lines.Insert( line, id ); @@ -4848,7 +4891,9 @@ long wxGenericListCtrl::InsertItem( long index, const wxString &label, int image wxListItem info; info.m_text = label; info.m_image = imageIndex; - info.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_IMAGE; + info.m_mask = wxLIST_MASK_TEXT; + if (imageIndex > -1) + info.m_mask |= wxLIST_MASK_IMAGE; info.m_itemId = index; return InsertItem( info ); } @@ -5050,12 +5095,22 @@ bool wxGenericListCtrl::DoPopupMenu( wxMenu *menu, int x, int y ) void wxGenericListCtrl::DoClientToScreen( int *x, int *y ) const { - m_mainWin->DoClientToScreen(x, y); + // It's not clear whether this can be called before m_mainWin is created + // but it seems better to be on the safe side and check. + if ( m_mainWin ) + m_mainWin->DoClientToScreen(x, y); + else + wxControl::DoClientToScreen(x, y); } void wxGenericListCtrl::DoScreenToClient( int *x, int *y ) const { - m_mainWin->DoScreenToClient(x, y); + // At least in wxGTK/Univ build this method can be called before m_mainWin + // is created so avoid crashes in this case. + if ( m_mainWin ) + m_mainWin->DoScreenToClient(x, y); + else + wxControl::DoScreenToClient(x, y); } void wxGenericListCtrl::SetFocus()