X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ccdbdc893684dee60877f35132c5ec5d8ec23446..001ad728a48bcfc7a763027b41f10ba1a25ce276:/src/generic/listctrl.cpp diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp index 4f76d244cb..c485403edb 100644 --- a/src/generic/listctrl.cpp +++ b/src/generic/listctrl.cpp @@ -52,12 +52,6 @@ #include "wx/mac/private.h" #endif -#ifdef __WXGTK__ - #include "wx/gtk/private.h" - #include "wx/gtk/win_gtk.h" -#endif - - // NOTE: If using the wxListBox visual attributes works everywhere then this can // be removed, as well as the #else case below. @@ -209,6 +203,7 @@ public: void SetItem( const wxListItem &item ); void SetPosition( int x, int y ); void SetWidth( int w ); + void SetState( int state ); void SetFormat( int format ); void SetHeight( int h ); bool HasImage() const; @@ -223,6 +218,7 @@ public: int GetImage() const; int GetWidth() const; int GetFormat() const; + int GetState() const; protected: long m_mask; @@ -233,6 +229,7 @@ protected: int m_xpos, m_ypos; int m_height; + int m_state; private: void Init(); @@ -612,6 +609,7 @@ public: void OnChar( wxKeyEvent &event ); void OnKeyDown( wxKeyEvent &event ); + void OnKeyUp( wxKeyEvent &event ); void OnSetFocus( wxFocusEvent &event ); void OnKillFocus( wxFocusEvent &event ); void OnScroll( wxScrollWinEvent& event ); @@ -730,7 +728,7 @@ public: { return m_hasFocus ? m_highlightBrush : m_highlightUnfocusedBrush; } - + bool HasFocus() const { return m_hasFocus; @@ -1008,6 +1006,7 @@ void wxListHeaderData::Init() m_xpos = 0; m_ypos = 0; m_height = 0; + m_state = 0; } wxListHeaderData::wxListHeaderData() @@ -1037,6 +1036,9 @@ void wxListHeaderData::SetItem( const wxListItem &item ) if ( m_mask & wxLIST_MASK_WIDTH ) SetWidth(item.m_width); + + if ( m_mask & wxLIST_MASK_STATE ) + SetState(item.m_state); } void wxListHeaderData::SetPosition( int x, int y ) @@ -1055,6 +1057,11 @@ void wxListHeaderData::SetWidth( int w ) m_width = w < 0 ? WIDTH_COL_DEFAULT : w; } +void wxListHeaderData::SetState( int flag ) +{ + m_state = flag; +} + void wxListHeaderData::SetFormat( int format ) { m_format = format; @@ -1077,6 +1084,7 @@ void wxListHeaderData::GetItem( wxListItem& item ) item.m_image = m_image; item.m_format = m_format; item.m_width = m_width; + item.m_state = m_state; } int wxListHeaderData::GetImage() const @@ -1094,6 +1102,11 @@ int wxListHeaderData::GetFormat() const return m_format; } +int wxListHeaderData::GetState() const +{ + return m_state; +} + //----------------------------------------------------------------------------- // wxListLineData //----------------------------------------------------------------------------- @@ -1397,7 +1410,11 @@ bool wxListLineData::SetAttributes(wxDC *dc, if ( highlighted ) #ifdef __WXMAC__ { - if (m_owner->HasFocus()) + if (m_owner->HasFocus() +#ifdef __WXMAC__ + && IsControlActive( (ControlRef)m_owner->GetHandle() ) +#endif + ) colText = *wxWHITE; else colText = *wxBLACK; @@ -1448,7 +1465,7 @@ void wxListLineData::Draw( wxDC *dc ) wxListItemAttr *attr = GetAttr(); if ( SetAttributes(dc, attr, highlighted) ) -#ifndef __WXGTK__ +#if ( !defined(__WXGTK20__) && !defined(__WXMAC__) ) { dc->DrawRectangle( m_gi->m_rectHighlight ); } @@ -1456,17 +1473,15 @@ void wxListLineData::Draw( wxDC *dc ) { if (highlighted) { - wxRect rect2( m_gi->m_rectHighlight ); - m_owner->CalcScrolledPosition( rect2.x, rect2.y, &rect2.x, &rect2.y ); - - gtk_paint_flat_box( m_owner->m_widget->style, - GTK_PIZZA(m_owner->m_wxwindow)->bin_window, - GTK_STATE_SELECTED, - GTK_SHADOW_NONE, - NULL, - m_owner->m_wxwindow, - "cell_even", - rect2.x, rect2.y, rect2.width, rect2.height ); + int flags = wxCONTROL_SELECTED; + if (m_owner->HasFocus() +#ifdef __WXMAC__ + && IsControlActive( (ControlRef)m_owner->GetHandle() ) +#endif + ) + flags |= wxCONTROL_FOCUSED; + wxRendererNative::Get().DrawItemSelectionRect( m_owner, *dc, m_gi->m_rectHighlight, flags ); + } else { @@ -1513,7 +1528,7 @@ void wxListLineData::DrawInReportMode( wxDC *dc, // GetAttr() and move these lines into the loop below wxListItemAttr *attr = GetAttr(); if ( SetAttributes(dc, attr, highlighted) ) -#ifndef __WXGTK__ +#if ( !defined(__WXGTK20__) && !defined(__WXMAC__) ) { dc->DrawRectangle( rectHL ); } @@ -1521,17 +1536,14 @@ void wxListLineData::DrawInReportMode( wxDC *dc, { if (highlighted) { - wxRect rect2( rectHL ); - m_owner->CalcScrolledPosition( rect2.x, rect2.y, &rect2.x, &rect2.y ); - - gtk_paint_flat_box( m_owner->m_widget->style, - GTK_PIZZA(m_owner->m_wxwindow)->bin_window, - GTK_STATE_SELECTED, - GTK_SHADOW_NONE, - NULL, - m_owner->m_wxwindow, - "cell_even", - rect2.x, rect2.y, rect2.width, rect2.height ); + int flags = wxCONTROL_SELECTED; + if (m_owner->HasFocus() +#ifdef __WXMAC__ + && IsControlActive( (ControlRef)m_owner->GetHandle() ) +#endif + ) + flags |= wxCONTROL_FOCUSED; + wxRendererNative::Get().DrawItemSelectionRect( m_owner, *dc, rectHL, flags ); } else { @@ -1798,13 +1810,26 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) int ch = h - 2; #endif + int flags = 0; + if (!m_parent->IsEnabled()) + flags |= wxCONTROL_DISABLED; + +// 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 +// other platforms, please go ahead and revise or remove the #ifdef. +#ifdef __WXMAC__ + if ( !m_owner->IsVirtual() && (item.m_mask & wxLIST_MASK_STATE) && + (item.m_state & wxLIST_STATE_SELECTED) ) + flags |= wxCONTROL_SELECTED; +#endif + wxRendererNative::Get().DrawHeaderButton ( this, dc, wxRect(x, HEADER_OFFSET_Y, cw, ch), - m_parent->IsEnabled() ? 0 - : (int)wxCONTROL_DISABLED + flags ); // see if we have enough space for the column label @@ -2000,6 +2025,22 @@ void wxListHeaderWindow::OnMouse( wxMouseEvent &event ) } else // click on a column { + // record the selected state of the columns + if (event.LeftDown()) + { + for (int i=0; i < m_owner->GetColumnCount(); i++) + { + wxListItem colItem; + m_owner->GetColumn(i, colItem); + long state = colItem.GetState(); + if (i == m_column) + colItem.SetState(state | wxLIST_STATE_SELECTED); + else + colItem.SetState(state & ~wxLIST_STATE_SELECTED); + m_owner->SetColumn(i, colItem); + } + } + SendListEvent( event.LeftDown() ? wxEVT_COMMAND_LIST_COL_CLICK : wxEVT_COMMAND_LIST_COL_RIGHT_CLICK, @@ -2205,6 +2246,7 @@ BEGIN_EVENT_TABLE(wxListMainWindow,wxScrolledWindow) EVT_MOUSE_EVENTS (wxListMainWindow::OnMouse) EVT_CHAR (wxListMainWindow::OnChar) EVT_KEY_DOWN (wxListMainWindow::OnKeyDown) + EVT_KEY_UP (wxListMainWindow::OnKeyUp) EVT_SET_FOCUS (wxListMainWindow::OnSetFocus) EVT_KILL_FOCUS (wxListMainWindow::OnKillFocus) EVT_SCROLLWIN (wxListMainWindow::OnScroll) @@ -2262,14 +2304,6 @@ wxListMainWindow::wxListMainWindow( wxWindow *parent, { Init(); - -#ifdef __WXMAC__ - // OS X sel item highlight color differs from text highlight color, which is - // what wxSYS_COLOUR_HIGHLIGHT returns. - RGBColor hilight; - GetThemeBrushAsColor(kThemeBrushAlternatePrimaryHighlightColor, 32, true, &hilight); - m_highlightBrush = new wxBrush( wxColour(hilight.red, hilight.green, hilight.blue ), wxSOLID ); -#else m_highlightBrush = new wxBrush ( wxSystemSettings::GetColour @@ -2278,14 +2312,7 @@ wxListMainWindow::wxListMainWindow( wxWindow *parent, ), wxSOLID ); -#endif -#ifdef __WXMAC__ - // on Mac, this color also differs from the wxSYS_COLOUR_BTNSHADOW, enough to be noticable. - // I don't know if BTNSHADOW is appropriate in other contexts, so I'm just changing it here. - GetThemeBrushAsColor(kThemeBrushSecondaryHighlightColor, 32, true, &hilight); - m_highlightUnfocusedBrush = new wxBrush( wxColour(hilight.red, hilight.green, hilight.blue ), wxSOLID ); -#else m_highlightUnfocusedBrush = new wxBrush ( wxSystemSettings::GetColour @@ -2294,7 +2321,6 @@ wxListMainWindow::wxListMainWindow( wxWindow *parent, ), wxSOLID ); -#endif SetScrollbars( 0, 0, 0, 0, 0, 0 ); @@ -2705,7 +2731,7 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) wxRect rectLine; int xOrig = dc.LogicalToDeviceX( 0 ); int yOrig = dc.LogicalToDeviceY( 0 ); - + // tell the caller cache to cache the data if ( IsVirtual() ) { @@ -2796,21 +2822,13 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) if ( m_hasFocus ) { wxRect rect( GetLineHighlightRect( m_current ) ); -#ifndef __WXGTK__ +#ifndef __WXGTK20__ dc.SetPen( *wxBLACK_PEN ); dc.SetBrush( *wxTRANSPARENT_BRUSH ); dc.DrawRectangle( rect ); #else - CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y ); - - gtk_paint_focus( m_widget->style, - GTK_PIZZA(m_wxwindow)->bin_window, - GTK_STATE_SELECTED, - NULL, - m_wxwindow, - "treeview", - rect.x, rect.y, rect.width, rect.height ); - + wxRendererNative::Get().DrawItemSelectionRect( this, dc, rect, wxCONTROL_CURRENT|wxCONTROL_FOCUSED ); + #endif } } @@ -2842,6 +2860,7 @@ void wxListMainWindow::SendNotify( size_t line, { wxListEvent le( command, GetParent()->GetId() ); le.SetEventObject( GetParent() ); + le.m_itemIndex = line; // set only for events which have position @@ -2852,7 +2871,7 @@ void wxListMainWindow::SendNotify( size_t line, // program has it anyhow and if we did it would result in accessing all // the lines, even those which are not visible now and this is precisely // what we're trying to avoid - if ( !IsVirtual() && (command != wxEVT_COMMAND_LIST_DELETE_ITEM) ) + if ( !IsVirtual() ) { if ( line != (size_t)-1 ) { @@ -2869,6 +2888,11 @@ void wxListMainWindow::ChangeCurrent(size_t current) { m_current = current; + // as the current item changed, we shouldn't start editing it when the + // "slow click" timer expires as the click happened on another item + if ( m_renameTimer->IsRunning() ) + m_renameTimer->Stop(); + SendNotify(current, wxEVT_COMMAND_LIST_ITEM_FOCUSED); } @@ -2898,8 +2922,15 @@ wxTextCtrl *wxListMainWindow::EditLabel(long item, wxClassInfo* textControlClass // 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(); + // Pending events dispatched by wxSafeYield might have changed the item + // count + if ( (size_t)item >= GetItemCount() ) + return NULL; + } + wxTextCtrl * const text = (wxTextCtrl *)textControlClass->CreateObject(); m_textctrlWrapper = new wxListTextCtrlWrapper(this, text, item); return m_textctrlWrapper->GetText(); @@ -2957,6 +2988,9 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event ) m_textctrlWrapper->AcceptChangesAndFinish(); #endif // __WXMAC__ + if ( event.LeftDown() ) + SetFocus(); + event.SetEventObject( GetParent() ); if ( GetParent()->GetEventHandler()->ProcessEvent( event) ) return; @@ -3066,7 +3100,9 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event ) bool forceClick = false; if (event.ButtonDClick()) { - m_renameTimer->Stop(); + if ( m_renameTimer->IsRunning() ) + m_renameTimer->Stop(); + m_lastOnSame = false; if ( current == m_lineLastClicked ) @@ -3304,6 +3340,25 @@ void wxListMainWindow::OnKeyDown( wxKeyEvent &event ) event.Skip(); } +void wxListMainWindow::OnKeyUp( wxKeyEvent &event ) +{ + wxWindow *parent = GetParent(); + + // propagate the key event upwards + wxKeyEvent ke( wxEVT_KEY_UP ); + ke.m_shiftDown = event.m_shiftDown; + ke.m_controlDown = event.m_controlDown; + ke.m_altDown = event.m_altDown; + ke.m_metaDown = event.m_metaDown; + ke.m_keyCode = event.m_keyCode; + ke.m_x = event.m_x; + ke.m_y = event.m_y; + ke.SetEventObject( parent ); + if (parent->GetEventHandler()->ProcessEvent( ke )) return; + + event.Skip(); +} + void wxListMainWindow::OnChar( wxKeyEvent &event ) { wxWindow *parent = GetParent(); @@ -4335,8 +4390,8 @@ void wxListMainWindow::DeleteItem( long lindex ) if ( InReportView() ) { - // mark the Column Max Width cache as dirty if the items in the line - // we're deleting contain the Max Column Width + // mark the Column Max Width cache as dirty if the items in the line + // we're deleting contain the Max Column Width wxListLineData * const line = GetLine(index); wxListItemDataList::compatibility_iterator n; wxListItemData *itemData; @@ -4358,6 +4413,8 @@ void wxListMainWindow::DeleteItem( long lindex ) ResetVisibleLinesRange(); } + SendNotify( index, wxEVT_COMMAND_LIST_DELETE_ITEM, wxDefaultPosition ); + if ( IsVirtual() ) { m_countVirt--; @@ -4371,8 +4428,6 @@ void wxListMainWindow::DeleteItem( long lindex ) // we need to refresh the (vert) scrollbar as the number of items changed m_dirty = true; - SendNotify( index, wxEVT_COMMAND_LIST_DELETE_ITEM ); - RefreshAfter(index); } @@ -4475,10 +4530,13 @@ void wxListMainWindow::EnsureVisible( long index ) MoveToItem((size_t)index); } -long wxListMainWindow::FindItem(long start, const wxString& str, bool WXUNUSED(partial) ) +long wxListMainWindow::FindItem(long start, const wxString& str, bool partial ) { + if (str.empty()) + return wxNOT_FOUND; + long pos = start; - wxString tmp = str; + wxString str_upper = str.Upper(); if (pos < 0) pos = 0; @@ -4486,8 +4544,17 @@ long wxListMainWindow::FindItem(long start, const wxString& str, bool WXUNUSED(p for ( size_t i = (size_t)pos; i < count; i++ ) { wxListLineData *line = GetLine(i); - if ( line->GetText(0) == tmp ) - return i; + wxString line_upper = line->GetText(0).Upper(); + if (!partial) + { + if (line_upper == str_upper ) + return i; + } + else + { + if (line_upper.find(str_upper) == 0) + return i; + } } return wxNOT_FOUND; @@ -5187,6 +5254,16 @@ wxColour wxGenericListCtrl::GetItemBackgroundColour( long item ) const return info.GetBackgroundColour(); } +int wxGenericListCtrl::GetScrollPos( int orient ) const +{ + return m_mainWin->GetScrollPos( orient ); +} + +void wxGenericListCtrl::SetScrollPos( int orient, int pos, bool refresh ) +{ + m_mainWin->SetScrollPos( orient, pos, refresh ); +} + void wxGenericListCtrl::SetItemFont( long item, const wxFont &f ) { wxListItem info;