Search code examples
c++wxwidgets

Calling wxSizeEvent at the end of sizing event


I have child frame on which I draw an image and when user resizes the frame, the location of the image is updated. This causes some flickering and although I solved this issue to some extent I would like to update the location when user finishes resizing (left mouse button up).Therefore instead of many calls to OnSize there will be only one call and that's when the sizing of the frame is done.

For example, when Matlab's image processing toolbox is run and the frame is loaded with an image, while user is resizing the frame the position of the image does not change but the position of the image changes once resizing is done (left button up).

I have the following approach but could not make it work:

void FrmImageEditor::OnSize(wxSizeEvent & event)
{
    if (IsIconized() || !IsShown()) return;

    std::function<void(wxMouseEvent& evt)> fncBind, fncUnbind;
    fncBind = std::function<void(wxMouseEvent& evt)>([&](wxMouseEvent& evt) 
    { 
        wxMessageBox("Left up"); 
        Connect(wxEVT_SIZE, wxSizeEventHandler(FrmImageEditor::OnSize)); 
        m_UnbindTheEvent= true;
        ReleaseMouse(); 
    });

    CaptureMouse();
    Disconnect(wxEVT_SIZE, wxSizeEventHandler(FrmImageEditor::OnSize));
    if(!m_UnbindTheEvent) Bind(wxEVT_LEFT_UP,fncBind );
    if(m_UnbindTheEvent) Unbind(wxEVT_LEFT_UP, fncBind);

The above code does not work in the following ways:

  1. Until I click the mouse button (left up) somewhere on the parent or child frame I cannot resize the frame.
  2. Even if I resize it, I cannot unbind the bound function as MessageBox keeps popping up when clicked on the client area of the child window.

Is there a way to achieve only one/a couple call to OnSize function (except using static counters in the function).


Solution

  • I'm not sure if idle events are generated during resizing, but I don't think they are. If this is correct, doing what you want could be as simple as setting a flag m_shouldResize in your wxEVT_SIZE handler and checking it in wxEVT_IDLE one and actually resizing the image if it is true.

    If idle events are still emitted too quickly, you could use the same logic but with a timer event instead.