Page 1 of 1
drawing wxBitmap: doesn't refresh before every time it draws
Posted: Mon Sep 08, 2014 4:29 pm
by greekfellows
Code: Select all
void bmImage::paintEvent(wxPaintEvent &event) {
wxPaintDC dc(this);
render(dc);
}
void bmImage::paintNow() {
wxClientDC dc(this);
render(dc);
}
void bmImage::render(wxDC& dc) {
bitmap = wxBitmap(aswxImage);
dc.Clear();
dc.SetUserScale(((bmImageFrame*)this->GetParent())->scale[0], ((bmImageFrame*)this->GetParent())->scale[1]);
dc.DrawBitmap(bitmap, wxPoint(0, 0), false);
}
bmImage derives from wxPanel. I want the image to be drawn on a clean, refreshed background every time.
But before I scale the loaded image, it looks like this: (the image is clipped because of resized window)
And after I scale the image then resize the window, it looks like this:
How should I fix this so that it redraws the scaled image over clean background? Obviously there is a problem with drawing and clearing canvas here.
Re: drawing wxBitmap: doesn't refresh before every time it d
Posted: Mon Sep 08, 2014 4:34 pm
by PB
If there are issues with parts of window not being properly painted after its resize, it can be a good idea to create the window in question with wxFULL_REPAINT_ON_RESIZE flag.
Re: drawing wxBitmap: doesn't refresh before every time it d
Posted: Tue Sep 09, 2014 4:00 am
by eranif
Some tips:
1. Make sure you also capture the. Erase background event. Inside it, clear the paint area by drAwing a rectangle with size of the panel
2. Use wxBufferedPaintDC in In OnPaint event handler and use it to draw
3. Capture the ON_SIZE event and simply call refresh
Eran
Re: drawing wxBitmap: doesn't refresh before every time it d
Posted: Wed Sep 10, 2014 4:55 pm
by greekfellows
Thanks for answers so far @eranif @PB!
I intercepted the wxEVT_SIZE event and called event.Skip() there so it refreshes every time it draws now, that's fine,
but now I have a flickering white screen (I used white to repaint a full-size rectangle)...
Code: Select all
void bmImage::paintEvent(wxPaintEvent &event) {
wxBufferedPaintDC dc(this);
render(dc);
}
void bmImage::paintNow() {
wxClientDC dc(this);
render(dc);
}
void bmImage::render(wxDC& dc) {
bitmap = wxBitmap(aswxImage);
dc.SetBackground(*wxWHITE_BRUSH);
dc.Clear();
wxPoint orgp = dc.GetLogicalOrigin();
dc.SetLogicalOrigin(((bmImageFrame*)this->GetParent())->scroll[0], ((bmImageFrame*)this->GetParent())->scroll[1]);
dc.SetUserScale(((bmImageFrame*)this->GetParent())->scale[0], ((bmImageFrame*)this->GetParent())->scale[1]);
dc.DrawBitmap(bitmap, wxPoint(0, 0), false);
dc.SetLogicalOrigin(orgp.x, orgp.y);
dc.SetUserScale(1.0f, 1.0f);
dc.SetPen(*wxWHITE_PEN);
dc.DrawText(wxString("w: " + std::to_string(GetSize().GetWidth()) + ", h: " + std::to_string(GetSize().GetHeight()) + "\nx: " + std::to_string(((bmImageFrame*)this->GetParent())->scroll[0]) + ", y: " + std::to_string(((bmImageFrame*)this->GetParent())->scroll[1])), 100, 100);
}
Re: drawing wxBitmap: doesn't refresh before every time it d
Posted: Wed Sep 10, 2014 6:19 pm
by doublemax
Do you have a wxEraseEvent handler? If yes, it should be completely empty. Do not clear the background, do not call event.Skip().
If you're using wx 3.x, you don't need an wxEraseEvent handler at all, just call wxWindow::SetBackgroundStyle(wxBG_STYLE_PAINT) on the window.
Re: drawing wxBitmap: doesn't refresh before every time it d
Posted: Wed Sep 10, 2014 7:18 pm
by eranif
1. Make sure you also capture the. Erase background event. Inside it, clear the paint area by drAwing a rectangle with size of the panel
Hmm, I gave a bad advise here...
You should capture the EVT_ERASE_BACKGROUND event, but do nothing in it - this will remove the flickering
Also, avoid using wxClientDC. If you need to force a paint now, simply call 'Refresh()' this will trigger a call to OnPaint/OnErase
So your function 'paintNow'' should look like this:
Code: Select all
void bmImage::paintNow() {
Refresh(); // triggers a 'OnPaint' event
}
Eran
Re: drawing wxBitmap: doesn't refresh before every time it d
Posted: Thu Sep 11, 2014 10:56 am
by greekfellows
Thanks! @eranif @doublemax
Used Refresh() in paintNow() and called SetBackgroundStyle().
Now it doesn't flicker at all.