X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/72a7edf007f57bc9dacea77c408adb86a57d41f7..0834112f89c4c5da7864e17e6f483ce296798ce6:/src/generic/listctrl.cpp diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp index ec4f79d94a..e19e1ac69c 100644 --- a/src/generic/listctrl.cpp +++ b/src/generic/listctrl.cpp @@ -41,14 +41,15 @@ wxListItemData::wxListItemData() m_ypos = 0; m_width = 0; m_height = 0; - m_colour = wxBLACK; + m_attr = NULL; } wxListItemData::wxListItemData( const wxListItem &info ) { m_image = -1; m_data = 0; - m_colour = info.m_colour; + m_attr = NULL; + SetItem( info ); } @@ -57,7 +58,15 @@ void wxListItemData::SetItem( const wxListItem &info ) if (info.m_mask & wxLIST_MASK_TEXT) m_text = info.m_text; if (info.m_mask & wxLIST_MASK_IMAGE) m_image = info.m_image; if (info.m_mask & wxLIST_MASK_DATA) m_data = info.m_data; - m_colour = info.m_colour; + + if ( info.HasAttributes() ) + { + if ( m_attr ) + *m_attr = *info.GetAttributes(); + else + m_attr = new wxListItemAttr(*info.GetAttributes()); + } + m_xpos = 0; m_ypos = 0; m_width = info.m_width; @@ -91,11 +100,6 @@ void wxListItemData::SetSize( int width, int height ) if (height != -1) m_height = height; } -void wxListItemData::SetColour( wxColour *col ) -{ - m_colour = col; -} - bool wxListItemData::HasImage() const { return (m_image >= 0); @@ -141,17 +145,21 @@ int wxListItemData::GetImage() const return m_image; } -void wxListItemData::GetItem( wxListItem &info ) +void wxListItemData::GetItem( wxListItem &info ) const { info.m_text = m_text; info.m_image = m_image; info.m_data = m_data; - info.m_colour = m_colour; -} -wxColour *wxListItemData::GetColour() -{ - return m_colour; + if ( m_attr ) + { + if ( m_attr->HasTextColour() ) + info.SetTextColour(m_attr->GetTextColour()); + if ( m_attr->HasBackgroundColour() ) + info.SetBackgroundColour(m_attr->GetBackgroundColour()); + if ( m_attr->HasFont() ) + info.SetFont(m_attr->GetFont()); + } } //----------------------------------------------------------------------------- @@ -286,9 +294,8 @@ void wxListLineData::CalculateSize( wxDC *dc, int spacing ) if (node) { wxListItemData *item = (wxListItemData*)node->Data(); - wxString s; - item->GetText( s ); - long lw,lh; + wxString s = item->GetText(); + wxCoord lw,lh; dc->GetTextExtent( s, &lw, &lh ); if (lw > m_spacing) m_bound_all.width = lw; } @@ -300,16 +307,15 @@ void wxListLineData::CalculateSize( wxDC *dc, int spacing ) if (node) { wxListItemData *item = (wxListItemData*)node->Data(); - wxString s; - item->GetText( s ); - long lw,lh; + wxString s = item->GetText(); + wxCoord lw,lh; dc->GetTextExtent( s, &lw, &lh ); m_bound_all.width = lw; m_bound_all.height = lh; if (item->HasImage()) { - int w = 0; - int h = 0; + wxCoord w = 0; + wxCoord h = 0; m_owner->GetImageSize( item->GetImage(), w, h ); m_bound_all.width += 4 + w; if (h > m_bound_all.height) m_bound_all.height = h; @@ -328,7 +334,7 @@ void wxListLineData::CalculateSize( wxDC *dc, int spacing ) wxString s; item->GetText( s ); if (s.IsNull()) s = "H"; - long lw,lh; + wxCoord lw,lh; dc->GetTextExtent( s, &lw, &lh ); item->SetSize( item->GetWidth(), lh ); m_bound_all.width += lw; @@ -378,7 +384,7 @@ void wxListLineData::SetPosition( wxDC *dc, int x, int y, int window_width ) { wxString s; item->GetText( s ); - long lw,lh; + wxCoord lw,lh; dc->GetTextExtent( s, &lw, &lh ); if (m_bound_all.width > m_spacing) m_bound_label.x = m_bound_all.x; @@ -426,7 +432,7 @@ void wxListLineData::SetPosition( wxDC *dc, int x, int y, int window_width ) } case wxLC_REPORT: { - long lw,lh; + wxCoord lw,lh; dc->GetTextExtent( "H", &lw, &lh ); m_bound_all.x = 0; m_bound_all.y -= 0; @@ -442,7 +448,7 @@ void wxListLineData::SetPosition( wxDC *dc, int x, int y, int window_width ) wxString s; item->GetText( s ); if (s.IsEmpty()) s = wxT("H"); - long lw,lh; + wxCoord lw,lh; dc->GetTextExtent( s, &lw, &lh ); m_bound_label.width = lw; m_bound_label.height = lh; @@ -577,6 +583,34 @@ int wxListLineData::GetImage( int index ) return -1; } +void wxListLineData::SetAttributes(wxDC *dc, + const wxListItemAttr *attr, + const wxColour& colText, + const wxFont& font, + bool hilight) +{ + // don't use foregroud colour for drawing highlighted items - this might + // make them completely invisible (and there is no way to do bit + // arithmetics on wxColour, unfortunately) + if ( !hilight && attr && attr->HasTextColour() ) + { + dc->SetTextForeground(attr->GetTextColour()); + } + else + { + dc->SetTextForeground(colText); + } + + if ( attr && attr->HasFont() ) + { + dc->SetFont(attr->GetFont()); + } + else + { + dc->SetFont(font); + } +} + void wxListLineData::DoDraw( wxDC *dc, bool hilight, bool paintBG ) { long dev_x = dc->LogicalToDeviceX( m_bound_all.x-2 ); @@ -589,26 +623,51 @@ void wxListLineData::DoDraw( wxDC *dc, bool hilight, bool paintBG ) return; } - if (paintBG) + wxWindow *listctrl = m_owner->GetParent(); + + // default foreground colour + wxColour colText; + if ( hilight ) + { + colText = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_HIGHLIGHTTEXT ); + } + else + { + colText = listctrl->GetForegroundColour(); + } + + // default font + wxFont font = listctrl->GetFont(); + + // VZ: currently we set the colours/fonts only once, but like this (i.e. + // using SetAttributes() inside the loop), it will be trivial to + // customize the subitems (in report mode) too. + wxListItemData *item = (wxListItemData*)m_items.First()->Data(); + wxListItemAttr *attr = item->GetAttributes(); + SetAttributes(dc, attr, colText, font, hilight); + + bool hasBgCol = attr && attr->HasBackgroundColour(); + if ( paintBG || hasBgCol ) { if (hilight) { dc->SetBrush( * m_hilightBrush ); - dc->SetPen( * wxTRANSPARENT_PEN ); } else { - dc->SetBrush( * wxWHITE_BRUSH ); - dc->SetPen( * wxTRANSPARENT_PEN ); + if ( hasBgCol ) + dc->SetBrush(wxBrush(attr->GetBackgroundColour(), wxSOLID)); + else + dc->SetBrush( * wxWHITE_BRUSH ); } + + dc->SetPen( * wxTRANSPARENT_PEN ); dc->DrawRectangle( m_bound_hilight.x, m_bound_hilight.y, m_bound_hilight.width, m_bound_hilight.height ); } - dc->SetBackgroundMode(wxTRANSPARENT); if (m_mode == wxLC_REPORT) { - wxString s; wxNode *node = m_items.First(); while (node) { @@ -624,12 +683,7 @@ void wxListLineData::DoDraw( wxDC *dc, bool hilight, bool paintBG ) } if (item->HasText()) { - item->GetText( s ); - if (hilight) - dc->SetTextForeground( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_HIGHLIGHTTEXT ) ); - else - dc->SetTextForeground( *item->GetColour() ); - dc->DrawText( s, x, item->GetY() ); + dc->DrawText( item->GetText(), x, item->GetY() ); } dc->DestroyClippingRegion(); node = node->Next(); @@ -647,13 +701,7 @@ void wxListLineData::DoDraw( wxDC *dc, bool hilight, bool paintBG ) } if (item->HasText()) { - wxString s; - item->GetText( s ); - if (hilight) - dc->SetTextForeground( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_HIGHLIGHTTEXT ) ); - else - dc->SetTextForeground( * item->GetColour() ); - dc->DrawText( s, m_bound_label.x, m_bound_label.y ); + dc->DrawText( item->GetText(), m_bound_label.x, m_bound_label.y ); } } } @@ -662,11 +710,11 @@ void wxListLineData::DoDraw( wxDC *dc, bool hilight, bool paintBG ) void wxListLineData::Hilight( bool on ) { if (on == m_hilighted) return; + m_hilighted = on; if (on) m_owner->SelectLine( this ); else m_owner->DeselectLine( this ); - m_hilighted = on; } void wxListLineData::ReverseHilight( void ) @@ -809,7 +857,9 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) dc.SetBackgroundMode(wxTRANSPARENT); dc.SetTextForeground( *wxBLACK ); - if (m_foregroundColour.Ok()) dc.SetTextForeground( m_foregroundColour ); + + // do *not* use the listctrl colour for headers - one day we will have a + // function to set it separately x = 1; y = 1; @@ -821,9 +871,10 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) int cw = item.m_width-2; #if wxUSE_GENERIC_LIST_EXTENSIONS if ((i+1 == numColumns) || ( dc.LogicalToDeviceX(x+item.m_width) > w-5)) - cw = dc.DeviceToLogicalX(w)-x-1; + cw = dc.DeviceToLogicalX(w)-x-1; #else - if ((i+1 == numColumns) || (x+item.m_width > w-5)) cw = w-x-1; + if ((i+1 == numColumns) || (x+item.m_width > w-5)) + cw = w-x-1; #endif dc.SetPen( *wxWHITE_PEN ); @@ -1117,6 +1168,8 @@ wxListMainWindow::~wxListMainWindow() void wxListMainWindow::RefreshLine( wxListLineData *line ) { + if (m_dirty) return; + int x = 0; int y = 0; int w = 0; @@ -1207,8 +1260,8 @@ void wxListMainWindow::SendNotify( wxListLineData *line, wxEventType command ) le.SetEventObject( GetParent() ); le.m_itemIndex = GetIndexOfLine( line ); line->GetItem( 0, le.m_item ); -// GetParent()->GetEventHandler()->ProcessEvent( le ); - GetParent()->GetEventHandler()->AddPendingEvent( le ); + GetParent()->GetEventHandler()->ProcessEvent( le ); +// GetParent()->GetEventHandler()->AddPendingEvent( le ); } void wxListMainWindow::FocusLine( wxListLineData *WXUNUSED(line) ) @@ -1299,7 +1352,7 @@ void wxListMainWindow::OnRenameAccept() info.m_mask = wxLIST_MASK_TEXT; info.m_itemId = le.m_itemIndex; info.m_text = m_renameRes; - info.m_colour = le.m_item.m_colour; + info.SetTextColour(le.m_item.GetTextColour()); SetItem( info ); } @@ -1777,8 +1830,8 @@ void wxListMainWindow::GetImageSize( int index, int &width, int &height ) int wxListMainWindow::GetTextLength( wxString &s ) { wxClientDC dc( this ); - long lw = 0; - long lh = 0; + wxCoord lw = 0; + wxCoord lh = 0; dc.GetTextExtent( s, &lw, &lh ); return lw + 6; } @@ -1858,7 +1911,7 @@ void wxListMainWindow::SetColumnWidth( int col, int width ) { wxListItemData *item = (wxListItemData*)n->Data(); int current = 0, ix = 0, iy = 0; - long lx = 0, ly = 0; + wxCoord lx = 0, ly = 0; if (item->HasImage()) { GetImageSize( item->GetImage(), ix, iy ); @@ -2525,7 +2578,31 @@ wxListItem::wxListItem() m_data = 0; m_format = wxLIST_FORMAT_CENTRE; m_width = 0; - m_colour = wxBLACK; + + m_attr = NULL; +} + +void wxListItem::Clear() +{ + m_mask = 0; + m_itemId = 0; + m_col = 0; + m_state = 0; + m_stateMask = 0; + m_image = 0; + m_data = 0; + m_format = wxLIST_FORMAT_CENTRE; + m_width = 0; + m_text = wxEmptyString; + + if (m_attr) delete m_attr; + m_attr = NULL; +} + +void wxListItem::ClearAttributes() +{ + if (m_attr) delete m_attr; + m_attr = NULL; } // ------------------------------------------------------------------------------------- @@ -2568,7 +2645,11 @@ void wxListEvent::CopyObject(wxObject& object_dest) const obj->m_item.m_data = m_item.m_data; obj->m_item.m_format = m_item.m_format; obj->m_item.m_width = m_item.m_width; - obj->m_item.m_colour = m_item.m_colour; + + if ( m_item.HasAttributes() ) + { + obj->m_item.SetTextColour(m_item.GetTextColour()); + } } // ------------------------------------------------------------------------------------- @@ -2595,12 +2676,15 @@ wxListCtrl::~wxListCtrl() { } -bool wxListCtrl::Create( wxWindow *parent, wxWindowID id, - const wxPoint &pos, const wxSize &size, +bool wxListCtrl::Create(wxWindow *parent, + wxWindowID id, + const wxPoint &pos, + const wxSize &size, + long style, #if wxUSE_VALIDATORS - long style, const wxValidator &validator, + const wxValidator &validator, #endif - const wxString &name ) + const wxString &name) { m_imageListNormal = (wxImageList *) NULL; m_imageListSmall = (wxImageList *) NULL; @@ -2608,32 +2692,29 @@ bool wxListCtrl::Create( wxWindow *parent, wxWindowID id, m_mainWin = (wxListMainWindow*) NULL; m_headerWin = (wxListHeaderWindow*) NULL; - long s = style; - -#ifdef __VMS__ -#pragma message disable codcauunr - // VMS reports on this part the warning: - // statement either is unreachable or causes unreachable code -#endif - if ((s & wxLC_REPORT == 0) && - (s & wxLC_LIST == 0) && - (s & wxLC_ICON == 0)) + if ( !(style & (wxLC_REPORT | wxLC_LIST | wxLC_ICON)) ) { - s = s | wxLC_LIST; + style = style | wxLC_LIST; } -#ifdef __VMS__ -#pragma message enable codcauunr -#endif - bool ret = wxControl::Create( parent, id, pos, size, s, name ); + bool ret = wxControl::Create( parent, + id, + pos, + size, + style, +#if wxUSE_VALIDATORS + validator, +#endif + name ); #if wxUSE_VALIDATORS SetValidator( validator ); #endif - if (s & wxSUNKEN_BORDER) s -= wxSUNKEN_BORDER; + if (style & wxSUNKEN_BORDER) + style -= wxSUNKEN_BORDER; - m_mainWin = new wxListMainWindow( this, -1, wxPoint(0,0), size, s ); + m_mainWin = new wxListMainWindow( this, -1, wxPoint(0,0), size, style ); if (HasFlag(wxLC_REPORT)) m_headerWin = new wxListHeaderWindow( this, -1, m_mainWin, wxPoint(0,0), wxSize(size.x,23), wxTAB_TRAVERSAL ); @@ -2873,15 +2954,15 @@ int wxListCtrl::GetSelectedItemCount() const return m_mainWin->GetSelectedItemCount(); } -/* wxColour wxListCtrl::GetTextColour() const { + return GetForegroundColour(); } -void wxListCtrl::SetTextColour(const wxColour& WXUNUSED(col)) +void wxListCtrl::SetTextColour(const wxColour& col) { + SetForegroundColour(col); } -*/ long wxListCtrl::GetTopItem() const { @@ -3019,7 +3100,10 @@ long wxListCtrl::InsertItem( long index, const wxString &label, int imageIndex ) long wxListCtrl::InsertColumn( long col, wxListItem &item ) { + wxASSERT( m_headerWin ); m_mainWin->InsertColumn( col, item ); + m_headerWin->Refresh(); + return 0; }