wxlistctrl subitem coloring

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
DavidKlecker
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 232
Joined: Sun Nov 29, 2009 10:35 am

wxlistctrl subitem coloring

Post by DavidKlecker » Wed May 12, 2010 8:42 pm

Has anyone been successful at enhancing wxlistctrl to be able to set the background color for a subitem? Just checking to make sure I don't reinvent the wheel here. But then again I don't know if it's even possible to update wxlistctrl to make this work anyhow. [;)]

TrV
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 630
Joined: Wed Jul 04, 2007 1:12 pm

Post by TrV » Thu May 13, 2010 7:46 am

You can have a look to my customized ListCtrl (--> http://http://dev.arqendra.net#wxlc) which contains snippets to alternate background colours of items.

In a nutshell, you have to use wxListItem::SetBackgroundColour(wxColour).

DavidKlecker
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 232
Joined: Sun Nov 29, 2009 10:35 am

Post by DavidKlecker » Thu May 13, 2010 3:36 pm

I checked out your file and decided to try wrapping ListCtrl with my own class called listctrlEx and I have the following

Code: Select all

void ListCtrlEx::SetSubItemBackgroundColor(long item, long subItem, const wxColour& col)
{
    wxRect rect;
    bool success = GetSubItemRect( item, subItem, rect, wxLIST_RECT_BOUNDS) != 0;
    if(success)
    {
        wxPaintDC dc(this);
        dc.SetBrush(col);
        dc.DrawRectangle(rect.x, rect.y, rect.GetWidth(), rect.GetHeight());
    }
}
This will actually color the subitem just fine, however the rest of the line is blank. In calling this I have the following

Code: Select all

                        wxListItem listItem;
                        listItem.m_itemId = i;
                        CharacterList->GetItem(listItem);
                        CharacterList->SetSubItemBackgroundColor(i, 3, wxColour(200, 100, 0));
                        CharacterList->SetItem(listItem);
The result is still a blank line, that is the whole line is blank where the subitem is located. I'm at a bit of a loss as to what I am forgetting in order to get the text to appear on that line.

Thanks!

edit: I just looked up that I am misusing CPaintDC. Trying with CClientDC and it flickers. That is I see the rect then the item is rendered and the rect disappears.

TrV
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 630
Joined: Wed Jul 04, 2007 1:12 pm

Post by TrV » Thu May 13, 2010 10:52 pm

Why are you using a DC?????? wxListItem::SetBackgroundColour(wxColour) is clearly sufficient!

DavidKlecker
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 232
Joined: Sun Nov 29, 2009 10:35 am

Post by DavidKlecker » Fri May 14, 2010 12:23 am

I used a DC because in trying the following

Code: Select all

            listItem.m_itemId = Index;
            CharacterList->GetItem(listItem);
            listItem.SetColumn(3);
            listItem.SetBackgroundColour(wxColour(255, 200, 100));
            CharacterList->SetItem(listItem);
it paints the whole row and I want to paint only the subitem. Not the whole row. So I tried using a DC (sorry if that upset you) which actually did render the column with the background color. Problem was the row data wasn't retained. I would LOVE for the above code to work since all the data is retained, but for what I need out of ListCtrl the above clearly doesn't work, and I so I reverted to using a wrapper class and a dc to get the subitem rectangle.

ngpaton
Knows some wx things
Knows some wx things
Posts: 25
Joined: Tue May 20, 2008 8:23 am

Post by ngpaton » Fri May 14, 2010 12:46 pm

Hi,

The wxListCtrl will only allow whole line colouring as this is the lowest common denominator of all the OSs it supports.

Using native windows code it is possible to colour sub items in a windows control.

I asked a similar question a while ago (http://forums.wxwidgets.org/viewtopic.php?t=21960) and one proposed solutions was to use to use wxGrid. I've never actually tried this as the functionality was not essential.

Cheers

Nigel

DavidKlecker
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 232
Joined: Sun Nov 29, 2009 10:35 am

Post by DavidKlecker » Fri May 14, 2010 6:20 pm

This just dawned on me. It's not an ideal solution but it does look the part and work OK.

Code: Select all

    wxRect rect;
    GetSubItemRect(item, subItem, rect);
    wxListItem listItem;
    listItem.m_itemId = item;
    listItem.SetColumn(subItem);
    listItem.m_mask = wxLIST_MASK_TEXT;
    GetItem(listItem);

    pPanel = new wxPanel(this, wxID_ANY, wxPoint(rect.x, rect.y), wxSize(rect.width, rect.height));
    pPanel->SetBackgroundColour(col);

    wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
    pPanel->SetSizer(itemBoxSizer2);

    pTextinPanel = new wxStaticText( pPanel, wxID_STATIC, _("Static text"), wxPoint(5, -1), wxSize(rect.width, rect.height), wxALIGN_CENTRE );
    pTextinPanel->SetLabel(listItem.m_text);
    pTextinPanel->SetFont(font);
All I did was create a wxPanel and place exactly on the subitem I wanted to color. I then have a static text in the panel to hold the subitem text.

Issues: So far I can't seem to center the text. Clicking on that exact subitem doesn't highlight the row, naturally since I'm clicking the panel, not the control. I thinking adding a HitTest here can fix that. Also, naturally resizing the column doesn't effect the panel size. Why would it? :) Will look into that later.

Post Reply