0

What am trying to accomplish is having two Panels , one to draw on , and the other one will hold the tools , so I'm using the default Panel with size of the whole screen for drawing shapes on drawPanel , and a custom Panel on top of it for the tools , so I can add a background to it toolsPanel:

#ifndef WXIMAGEPANEL_H
#define WXIMAGEPANEL_H

#include <wx/wx.h>
#include <wx/custombgwin.h>
#include <wx/dcbuffer.h>

class wxImagePanel : public wxCustomBackgroundWindow<wxPanel>
{
public:
    wxImagePanel();
    wxImagePanel (wxWindow *parent,
                  wxWindowID winid = wxID_ANY,
                  const wxPoint& pos = wxDefaultPosition,
                  const wxSize& sizee = wxDefaultSize,
                  long style = wxTAB_TRAVERSAL | wxNO_BORDER,
                  const wxString& name = wxPanelNameStr);
    void SetBackgroundImage(const wxBitmap & background);
    virtual ~wxImagePanel();
protected:
private:
    const wxBitmap * ptr_backgorund;

    void paintEvent(wxPaintEvent & evt);
    void OnEraseBackground(wxEraseEvent& event);
    DECLARE_EVENT_TABLE()
};

#endif // WXIMAGEPANEL_H
----------------------------------------------------
#include "wxImagePanel.h"

wxImagePanel::wxImagePanel()
{
    //ctor
    //SetBackgroundStyle(wxBG_STYLE_PAINT);
}

wxImagePanel::wxImagePanel (wxWindow *parent,
                            wxWindowID winid ,
                            const wxPoint& pos ,
                            const wxSize& sizee ,
                            long style ,
                            const wxString& name)
{
    Create(parent,winid,pos,sizee,style,name);
    //SetBackgroundStyle(wxBG_STYLE_PAINT);
}
void wxImagePanel::SetBackgroundImage(const wxBitmap & background)
{
    this->ptr_backgorund = &background;
    SetBackgroundBitmap(background);
}

wxImagePanel::~wxImagePanel()
{
    //dtor
    if(ptr_backgorund)
        delete ptr_backgorund;
}

BEGIN_EVENT_TABLE(wxImagePanel, wxPanel)
    //EVT_PAINT(wxImagePanel::paintEvent)
    EVT_ERASE_BACKGROUND(wxImagePanel::OnEraseBackground)
END_EVENT_TABLE()

void wxImagePanel::OnEraseBackground(wxEraseEvent& event)
{

}

void wxImagePanel::paintEvent(wxPaintEvent & evt)
{
    wxAutoBufferedPaintDC dc(this);
    PrepareDC(dc);
    if(ptr_backgorund)
        dc.DrawBitmap( *ptr_backgorund, 0, 0);
}

I have tried both ways (drawing the background myself, and using SetBackgroundBitmap method) , both ways are flickering when am calling drawPanel->Refresh() on MouseMove event , so what am missing here , that causing the toolsPanel to flicker?

Abanoub
  • 3,623
  • 16
  • 66
  • 104

2 Answers2

0

The flicker is unavoidable if you call Refresh() on the entire window on each mouse move, this simply shouldn't be done. At the very least, you need to refresh just the small area which really needs to be repainted and not the entire window, which would reduce the flicker significantly but might still be not enough. The best solution is to use the (unfortunately still undocumented) wxOverlay class to overlay whatever you're drawing when the mouse moves on top of the window.

VZ.
  • 21,740
  • 3
  • 39
  • 42
  • but am not redrawing the whole window, am redrawing just the `drawPanel`, I don't understand why it's effecting the other panel? – Abanoub Dec 14 '15 at 13:02
  • There is no `drawPanel` in the code you show, so it's hard to say what is going wrong. The basic point about avoiding refreshing too much if you don't want to have flicker still stands though. – VZ. Dec 14 '15 at 19:16
  • then what is the best way to have a `panel` that I will keep drawing on it , say like `Window Paint` application , I wanna achieve something similar , where I have tools and area panel. – Abanoub Dec 17 '15 at 08:57
0

try refreshing like this:

window->Refresh(false)

Here's a similar thread containing a very useful piece of advice: on Refresh, "the option eraseBackground = FALSE is very important to avoid flickering"

how to animate picture without making it flicker using wxWidgets in erlang?

The documentation says Refresh repaints "window, and all of its children recursively (except under wxGTK1 where this is not implemented)". Although I don't understand the behaviour, I'm suspecting the recursive nature of Refresh causing the flicker, since I'm usually experiencing it under Windows 7 but not under Linux GTK (with the exact same code). However, under Windows 10 I don't see any flicker even with eraseBackground = TRUE.

Community
  • 1
  • 1
friedman
  • 21
  • 1