0
votes

I am struggling to make animated circular gauge using wxWidgets. I've tried using wxSVG with SVG image so it would scale with window, it worked on Linux but compilation of that library under Windows was such a problem I quit that approach. I've also tried using wxArt2D but it didn't compile even under Linux. Now I'm using wxDC and wxImage but it doesn't refresh on rescale and it has large CPU overhead (laptop i7 is used by about 30%). Here is my code:

void MyFrame::OnPanel2EraseBackground(wxEraseEvent& event)
{
}

void MyFrame::OnPanel2Resize(wxSizeEvent& event)
{
    wxSize panelSize = event.GetSize();
    gaugeBuffer = gaugeImg.Scale(panelSize.GetX(), panelSize.GetY(), wxIMAGE_QUALITY_HIGH);
    needleBuffer = needleImg.Scale(panelSize.GetX(), panelSize.GetY(), wxIMAGE_QUALITY_HIGH);
}

void MyFrame::OnPanel2Paint(wxPaintEvent& event)
{
    wxPaintDC dc(Panel2);
    wxPoint offset;
    wxSize drawSize = dc.GetSize();
    memDC.Clear();
    temp = needleBuffer.Rotate((angle*M_PI/180), wxPoint((drawSize.GetX()/2), (drawSize.GetY()/2)), true, &offset);
    memDC.DrawBitmap(gaugeBuffer, 0, 0);
    memDC.DrawBitmap(temp, offset);
    dc.Blit(0, 0, drawSize.GetX(), drawSize.GetY(), &memDC, 0, 0);
}
1

1 Answers

0
votes

I don't see anything obviously wrong in the code, but rotating images on each repaint is obviously not going to be very fast (especially if they're big) and you're very likely to do triple buffering here (i.e. once more than needed) on any modern system which already double buffer wxPaintDC, see wxAutoBufferedPaintDC for a way to avoid it while still ensuring double buffering is done for the older systems or just remove the extra memory DC if you don't care about them.

You can also look at wxActivityIndicator implementation for an alternative way of doing something similar which doesn't suffer from any serious performance drawbacks.