wxGrid and wxBitmap Topic is solved

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.
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxGrid and wxBitmap

Post by doublemax »

The wxGridCellRenderer::Draw() should be outside the if-check. It will redraw the background and by that clear the image. And of course you need to call Refresh() on the grid, if you toggle image visibility, so that all cells get redrawn.
Use the source, Luke!
Melandr
Experienced Solver
Experienced Solver
Posts: 53
Joined: Thu Oct 28, 2021 6:07 am

Re: wxGrid and wxBitmap

Post by Melandr »

Moved Draw() out of the if block.

Code: Select all

void wxBmpGridCellRenderer::Draw(wxGrid& grid, wxGridCellAttr& attr, wxDC& dc, const wxRect& rect, int row, int col, bool isSelected)
{
    wxGridCellRenderer::Draw(grid, attr, dc, rect, row, col, isSelected);

    if(m_IsVisiblePhoto)
    {
        dc.SetClippingRegion(rect);
        m_img.Rescale(wxSize(109,145).GetWidth(),wxSize(109,145).GetHeight());
        wxBitmap cellBitmap(m_img);
        dc.DrawBitmap(cellBitmap,rect.x,rect.y);
        dc.DestroyClippingRegion();
    }
}
Also, when installing / removing the checkbox, I do Refresh the grid

Code: Select all

void testWxSmithFrame::OnCheckBoxEnableFotoClick(wxCommandEvent& event)
{
    if(CheckBoxEnableFoto->GetValue())
    {
        Grid1->SetDefaultRowSize(145); //line height is 14px by default
        Grid1->Refresh();
    }
    else
    {
        Grid1->SetDefaultRowSize(25); //line height is 25px by default
        Grid1->Refresh();
    }
}
But all the same, part of the picture is displayed when the line height is reduced. It's not clear when Draw() is called to draw the grid, since I don't see an explicit Draw() call.
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxGrid and wxBitmap

Post by doublemax »

How to you change the m_IsVisiblePhoto flag in the renderers?

Maybe it's easier to chose my second suggestion of subclassing wxGrid. It will make it much easier if you want to add another similar functionlity in the future.
Use the source, Luke!
Melandr
Experienced Solver
Experienced Solver
Posts: 53
Joined: Thu Oct 28, 2021 6:07 am

Re: wxGrid and wxBitmap

Post by Melandr »

Yes, indeed, I forgot to set the m_IsVisibleFoto flag in the OnCheckBoxEnableFotoClick(wxCommandEvent& event) handler
I added methods to the renderer class to work with m_IsVisibleFoto

Code: Select all

class wxBmpGridCellRenderer : public wxGridCellRenderer
{
public:
    wxBmpGridCellRenderer(const wxImage& image) : wxGridCellRenderer(), m_img(image) {}

    void Draw(wxGrid& grid, wxGridCellAttr& attr, wxDC& dc,
                 const wxRect& rect, int row, int col, bool isSelected);

    wxSize GetBestSize(wxGrid& grid, wxGridCellAttr& attr, wxDC& dc,
                       int row, int col)
    {
        return wxSize(m_img.GetWidth(), m_img.GetHeight());
    }
    wxGridCellRenderer *Clone() const
    {
        return new wxBmpGridCellRenderer(m_img);
    }
    void ClearCellGrid(wxGrid&grid);
    void SetVisible(bool flag)
    {
        m_IsVisibleFoto = flag;
    }
    bool GetVisible()
    {
        return m_IsVisiblePhoto;
    }

private:
    bool m_IsVisibleFoto = 1;
    wxImage m_img;
};
but I did not add a change to this flag in the OnCheckBoxEnableFotoClick handler, because I do not see these methods in the handler
it turns out that to work with these methods, I have to pass the wxGrid parent to the OnCheckBoxEnableFotoClick(wxCommandEvent& event) handler? to refer to the SetVisible() and GetVisible() methods
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxGrid and wxBitmap

Post by doublemax »

Use wxGrid::GetCellRenderer() to get the renderer of all cells with images.

Code: Select all

// get cell renderer
wxGridCellRenderer *renderer = grid->GetCellRenderer(row, col);

// make sure it's the type we expect
wxBmpGridCellRenderer *bmprenderer = wxDynamicCast(renderer, wxBmpGridCellRenderer);
if( bmprenderer != NULL )
{
  bmprenderer->SetVisible(...);
}
renderer->DecRef();
Use the source, Luke!
Melandr
Experienced Solver
Experienced Solver
Posts: 53
Joined: Thu Oct 28, 2021 6:07 am

Re: wxGrid and wxBitmap

Post by Melandr »

Gives a compilation error
2022-01-25_165604.jpg
to the following code

Code: Select all

void testWxSmithFrame::OnCheckBoxEnableFotoClick(wxCommandEvent& event)
{
    for(int i = 0; i < Grid1->GetNumberRows(); i++)
    {
        //get cell renderer
        wxGridCellRenderer *renderer = Grid1->GetCellRenderer(i, 0);
        // check if this is the type we expect
        wxBmpGridCellRenderer *bmprenderer = wxDynamicCast(renderer, wxBmpGridCellRenderer);
        if( bmprenderer != NULL )
        {
            if(CheckBoxEnableFoto->GetValue())
                bmprenderer->SetVisible(true);
            else
                bmprenderer->SetVisible(false);
        }
        renderer->DecRef();
    }

    if(CheckBoxEnableFoto->GetValue())
    {
        Grid1->SetDefaultRowSize(145); //line height is 14px by default
        Grid1->Refresh();
    }
    else
    {
        Grid1->SetDefaultRowSize(25); //line height is 25px by default
        Grid1->Refresh();
    }
}
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxGrid and wxBitmap

Post by doublemax »

Hmm, wxDynamicCast only seems to work with classes derived from wxObject.

Try this:

Code: Select all

wxBmpGridCellRenderer *bmprenderer = dynamic_cast<wxBmpGridCellRenderer*>renderer;
If that doesn't work, you'll have to use a static cast and make sure that you get the right cells.
Use the source, Luke!
Melandr
Experienced Solver
Experienced Solver
Posts: 53
Joined: Thu Oct 28, 2021 6:07 am

Re: wxGrid and wxBitmap

Post by Melandr »

Good morning!
This is how it works, thanks a lot.

Code: Select all

wxBmpGridCellRenderer *bmprenderer = dynamic_cast<wxBmpGridCellRenderer*>(renderer);
PS:doublemax,But do not tell me, why should I use this method?

Code: Select all

GetCellRenderer(row , col );
I would like to understand, but I can not understand why this method call is required. I know what I have in the first column, why should I get a renderer for these cells?
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxGrid and wxBitmap

Post by doublemax »

I thought you had assigned individual renderers to all cells with image content. If that's the case, you must access them all and change the image visibility.
Use the source, Luke!
Post Reply