X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ddba340ddfd7f4d49a3e0700e922bcbad0e46027..24b3cc2c9632b7c6f0f0dd8f935688bd4d5e36f0:/src/generic/listctrl.cpp diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp index 850879e1ce..38a9a92ce0 100644 --- a/src/generic/listctrl.cpp +++ b/src/generic/listctrl.cpp @@ -124,7 +124,7 @@ static const int IMAGE_MARGIN_IN_REPORT_MODE = 5; int CMPFUNC_CONV wxSizeTCmpFn(size_t n1, size_t n2) { return n1 - n2; } -WX_DEFINE_SORTED_EXPORTED_ARRAY(size_t, wxIndexArray); +WX_DEFINE_SORTED_EXPORTED_ARRAY_LONG(size_t, wxIndexArray); // this class is used to store the selected items in the virtual list control // (but it is not tied to list control and so can be used with other controls @@ -435,7 +435,7 @@ protected: wxCursor *m_resizeCursor; bool m_isDragging; - // column being resized + // column being resized or -1 int m_column; // divider line position in logical (unscrolled) coords @@ -473,6 +473,8 @@ private: // common part of all ctors void Init(); + void SendListEvent(wxEventType type, wxPoint pos); + DECLARE_DYNAMIC_CLASS(wxListHeaderWindow) DECLARE_EVENT_TABLE() }; @@ -518,7 +520,7 @@ public: void OnKillFocus( wxFocusEvent &event ); private: - DECLARE_DYNAMIC_CLASS(wxListTextCtrl); + DECLARE_DYNAMIC_CLASS(wxListTextCtrl) DECLARE_EVENT_TABLE() }; @@ -626,7 +628,7 @@ public: // suspend/resume redrawing the control void Freeze(); void Thaw(); - + void SetFocus(); void OnRenameTimer(); @@ -859,7 +861,7 @@ private: // if this is > 0, the control is frozen and doesn't redraw itself size_t m_freezeCount; - DECLARE_DYNAMIC_CLASS(wxListMainWindow); + DECLARE_DYNAMIC_CLASS(wxListMainWindow) DECLARE_EVENT_TABLE() }; @@ -1447,8 +1449,8 @@ void wxListLineData::SetPosition( int x, int y, if ( item->HasImage() ) { - m_gi->m_rectIcon.x = m_gi->m_rectAll.x + 4 - + (spacing - m_gi->m_rectIcon.width)/2; + m_gi->m_rectIcon.x = m_gi->m_rectAll.x + 4 + + (m_gi->m_rectAll.width - m_gi->m_rectIcon.width) / 2; m_gi->m_rectIcon.y = m_gi->m_rectAll.y + 4; } @@ -1751,7 +1753,7 @@ void wxListLineData::ReverseHighlight( void ) // wxListHeaderWindow //----------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxListHeaderWindow,wxWindow); +IMPLEMENT_DYNAMIC_CLASS(wxListHeaderWindow,wxWindow) BEGIN_EVENT_TABLE(wxListHeaderWindow,wxWindow) EVT_PAINT (wxListHeaderWindow::OnPaint) @@ -1983,6 +1985,9 @@ void wxListHeaderWindow::OnMouse( wxMouseEvent &event ) if (m_isDragging) { + SendListEvent(wxEVT_COMMAND_LIST_COL_DRAGGING, + event.GetPosition()); + // we don't draw the line beyond our window, but we allow dragging it // there int w = 0; @@ -2000,6 +2005,8 @@ void wxListHeaderWindow::OnMouse( wxMouseEvent &event ) m_isDragging = FALSE; m_dirty = TRUE; m_owner->SetColumnWidth( m_column, m_currentX - m_minX ); + SendListEvent(wxEVT_COMMAND_LIST_COL_END_DRAG, + event.GetPosition()); } else { @@ -2022,8 +2029,9 @@ void wxListHeaderWindow::OnMouse( wxMouseEvent &event ) int xpos = 0; // find the column where this event occured - int countCol = m_owner->GetColumnCount(); - for (int col = 0; col < countCol; col++) + int col, + countCol = m_owner->GetColumnCount(); + for (col = 0; col < countCol; col++) { xpos += m_owner->GetColumnWidth( col ); m_column = col; @@ -2044,6 +2052,9 @@ void wxListHeaderWindow::OnMouse( wxMouseEvent &event ) m_minX = xpos; } + if ( col == countCol ) + m_column = -1; + if (event.LeftDown() || event.RightUp()) { if (hit_border && event.LeftDown()) @@ -2052,25 +2063,15 @@ void wxListHeaderWindow::OnMouse( wxMouseEvent &event ) m_currentX = x; DrawCurrent(); CaptureMouse(); + SendListEvent(wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, + event.GetPosition()); } else // click on a column { - wxWindow *parent = GetParent(); - wxListEvent le( event.LeftDown() + SendListEvent( event.LeftDown() ? wxEVT_COMMAND_LIST_COL_CLICK : wxEVT_COMMAND_LIST_COL_RIGHT_CLICK, - parent->GetId() ); - le.SetEventObject( parent ); - le.m_pointDrag = event.GetPosition(); - - // the position should be relative to the parent window, not - // this one for compatibility with MSW and common sense: the - // user code doesn't know anything at all about this header - // window, so why should it get positions relative to it? - le.m_pointDrag.y -= GetSize().y; - - le.m_col = m_column; - parent->GetEventHandler()->ProcessEvent( le ); + event.GetPosition()); } } else if (event.Moving()) @@ -2098,6 +2099,23 @@ void wxListHeaderWindow::OnSetFocus( wxFocusEvent &WXUNUSED(event) ) m_owner->SetFocus(); } +void wxListHeaderWindow::SendListEvent(wxEventType type, wxPoint pos) +{ + wxWindow *parent = GetParent(); + wxListEvent le( type, parent->GetId() ); + le.SetEventObject( parent ); + le.m_pointDrag = pos; + + // the position should be relative to the parent window, not + // this one for compatibility with MSW and common sense: the + // user code doesn't know anything at all about this header + // window, so why should it get positions relative to it? + le.m_pointDrag.y -= GetSize().y; + + le.m_col = m_column; + parent->GetEventHandler()->ProcessEvent( le ); +} + //----------------------------------------------------------------------------- // wxListRenameTimer (internal) //----------------------------------------------------------------------------- @@ -2116,7 +2134,7 @@ void wxListRenameTimer::Notify() // wxListTextCtrl (internal) //----------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxListTextCtrl,wxTextCtrl); +IMPLEMENT_DYNAMIC_CLASS(wxListTextCtrl,wxTextCtrl) BEGIN_EVENT_TABLE(wxListTextCtrl,wxTextCtrl) EVT_CHAR (wxListTextCtrl::OnChar) @@ -2217,7 +2235,7 @@ void wxListTextCtrl::OnKillFocus( wxFocusEvent &event ) (*m_accept) = TRUE; (*m_res) = GetValue(); - + if ((*m_res) != m_startValue) m_owner->OnRenameAccept(); } @@ -2226,7 +2244,7 @@ void wxListTextCtrl::OnKillFocus( wxFocusEvent &event ) // wxListMainWindow //----------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxListMainWindow,wxScrolledWindow); +IMPLEMENT_DYNAMIC_CLASS(wxListMainWindow,wxScrolledWindow) BEGIN_EVENT_TABLE(wxListMainWindow,wxScrolledWindow) EVT_PAINT (wxListMainWindow::OnPaint) @@ -2474,7 +2492,10 @@ long wxListMainWindow::HitTestLine(size_t line, int x, int y) const if ( ld->HasImage() && GetLineIconRect(line).Inside(x, y) ) return wxLIST_HITTEST_ONITEMICON; - if ( ld->HasText() ) + // VS: Testing for "ld->HasText() || InReportView()" instead of + // "ld->HasText()" is needed to make empty lines in report view + // possible + if ( ld->HasText() || InReportView() ) { wxRect rect = InReportView() ? GetLineRect(line) : GetLineLabelRect(line); @@ -2910,14 +2931,10 @@ void wxListMainWindow::EditLabel( long item ) if (m_dirty) wxSafeYield(); - wxClientDC dc(this); - PrepareDC( dc ); - wxString s = data->GetText(0); wxRect rectLabel = GetLineLabelRect(m_currentEdit); - rectLabel.x = dc.LogicalToDeviceX( rectLabel.x ); - rectLabel.y = dc.LogicalToDeviceY( rectLabel.y ); + CalcScrolledPosition(rectLabel.x, rectLabel.y, &rectLabel.x, &rectLabel.y); wxListTextCtrl *text = new wxListTextCtrl ( @@ -3050,7 +3067,7 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event ) #ifdef __WXGTK__ // FIXME: wxGTK generates bad sequence of events prior to doubleclick - // ("down, up, down, double, up" while other ports + // ("down, up, down, double, up" while other ports // do "down, up, double, up"). We have to have this hack // in place till somebody fixes wxGTK... if ( current == m_lineBeforeLastClicked ) @@ -3409,13 +3426,13 @@ void wxListMainWindow::OnChar( wxKeyEvent &event ) void wxListMainWindow::SetFocus() { // VS: wxListMainWindow derives from wxPanel (via wxScrolledWindow) and wxPanel - // overrides SetFocus in such way that it does never change focus from + // overrides SetFocus in such way that it does never change focus from // panel's child to the panel itself. Unfortunately, we must be able to change - // focus to the panel from wxListTextCtrl because the text control should + // focus to the panel from wxListTextCtrl because the text control should // disappear when the user clicks outside it. wxWindow *oldFocus = FindFocus(); - + if ( oldFocus && oldFocus->GetParent() == this ) { wxWindow::SetFocus(); @@ -3755,6 +3772,14 @@ void wxListMainWindow::SetItemState( long litem, long state, long stateMask ) { ResetCurrent(); + if ( IsSingleSel() ) + { + // we must unselect the old current item as well or we + // might end up with more than one selected item in a + // single selection control + HighlightLine(oldCurrent, FALSE); + } + RefreshLine( oldCurrent ); } } @@ -3934,7 +3959,7 @@ void wxListMainWindow::RecalculatePositions(bool noRefresh) int clientWidth, clientHeight; GetSize( &clientWidth, &clientHeight ); - + if ( HasFlag(wxLC_REPORT) ) { // all lines have the same height @@ -3969,7 +3994,7 @@ void wxListMainWindow::RecalculatePositions(bool noRefresh) { // We start with 4 for the border around all items entireWidth = 4; - + if (tries == 1) { // Now we have decided that the items do not fit into the @@ -3981,7 +4006,7 @@ void wxListMainWindow::RecalculatePositions(bool noRefresh) // a scrollbar at the bottom of its client area. entireWidth += SCROLL_UNIT_X; } - + // Start at 2,2 so the text does not touch the border int x = 2; int y = 2; @@ -4015,11 +4040,11 @@ void wxListMainWindow::RecalculatePositions(bool noRefresh) entireWidth += maxWidth+6; maxWidth = 0; } - + // We have reached the last item. if ( i == count - 1 ) entireWidth += maxWidth; - + if ( (tries == 0) && (entireWidth+SCROLL_UNIT_X > clientWidth) ) { clientHeight -= 15; // We guess the scrollbar height. (FIXME) @@ -4027,7 +4052,7 @@ void wxListMainWindow::RecalculatePositions(bool noRefresh) currentlyVisibleLines = 0; break; } - + if ( i == count - 1 ) tries = 1; // Everything fits, no second try required. } @@ -4163,6 +4188,9 @@ void wxListMainWindow::DeleteColumn( int col ) m_dirty = TRUE; m_columns.DeleteNode( node ); + + // invalidate it as it has to be recalculated + m_headerWidth = 0; } void wxListMainWindow::DoDeleteAllItems() @@ -4357,6 +4385,9 @@ void wxListMainWindow::InsertColumn( long col, wxListItem &item ) { m_columns.Append( column ); } + + // invalidate it as it has to be recalculated + m_headerWidth = 0; } } @@ -4469,38 +4500,6 @@ void wxListMainWindow::GetVisibleLinesRange(size_t *from, size_t *to) IMPLEMENT_DYNAMIC_CLASS(wxListItem, wxObject) -wxListItem::wxListItem() -{ - m_attr = NULL; - - Clear(); -} - -void wxListItem::Clear() -{ - m_mask = 0; - m_itemId = 0; - m_col = 0; - m_state = 0; - m_stateMask = 0; - m_image = -1; - m_data = 0; - m_format = wxLIST_FORMAT_CENTRE; - m_width = 0; - m_text.clear(); - - ClearAttributes(); -} - -void wxListItem::ClearAttributes() -{ - if (m_attr) - { - delete m_attr; - m_attr = NULL; - } -} - // ------------------------------------------------------------------------------------- // wxListCtrl // ------------------------------------------------------------------------------------- @@ -4814,6 +4813,38 @@ int wxListCtrl::GetItemSpacing( bool isSmall ) const return m_mainWin->GetItemSpacing( isSmall ); } +void wxListCtrl::SetItemTextColour( long item, const wxColour &col ) +{ + wxListItem info; + info.m_itemId = item; + info.SetTextColour( col ); + m_mainWin->SetItem( info ); +} + +wxColour wxListCtrl::GetItemTextColour( long item ) const +{ + wxListItem info; + info.m_itemId = item; + m_mainWin->GetItem( info ); + return info.GetTextColour(); +} + +void wxListCtrl::SetItemBackgroundColour( long item, const wxColour &col ) +{ + wxListItem info; + info.m_itemId = item; + info.SetBackgroundColour( col ); + m_mainWin->SetItem( info ); +} + +wxColour wxListCtrl::GetItemBackgroundColour( long item ) const +{ + wxListItem info; + info.m_itemId = item; + m_mainWin->GetItem( info ); + return info.GetBackgroundColour(); +} + int wxListCtrl::GetSelectedItemCount() const { return m_mainWin->GetSelectedItemCount(); @@ -5044,7 +5075,7 @@ bool wxListCtrl::SortItems( wxListCtrlCompare fn, long data ) // event handlers // ---------------------------------------------------------------------------- -void wxListCtrl::OnSize(wxSizeEvent& event) +void wxListCtrl::OnSize(wxSizeEvent& WXUNUSED(event)) { if ( !m_mainWin ) return; @@ -5188,19 +5219,19 @@ void wxListCtrl::SetFocus() // virtual list control support // ---------------------------------------------------------------------------- -wxString wxListCtrl::OnGetItemText(long item, long col) const +wxString wxListCtrl::OnGetItemText(long WXUNUSED(item), long WXUNUSED(col)) const { // this is a pure virtual function, in fact - which is not really pure // because the controls which are not virtual don't need to implement it - wxFAIL_MSG( _T("not supposed to be called") ); + wxFAIL_MSG( _T("wxListCtrl::OnGetItemText not supposed to be called") ); return wxEmptyString; } -int wxListCtrl::OnGetItemImage(long item) const +int wxListCtrl::OnGetItemImage(long WXUNUSED(item)) const { // same as above - wxFAIL_MSG( _T("not supposed to be called") ); + wxFAIL_MSG( _T("wxListCtrl::OnGetItemImage not supposed to be called") ); return -1; } @@ -5242,3 +5273,5 @@ void wxListCtrl::Thaw() } #endif // wxUSE_LISTCTRL + +// vi:sts=4:sw=4:et