how to detect input up and down on wxControl?

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.
Post Reply
Shadowblitz16
Earned a small fee
Earned a small fee
Posts: 10
Joined: Sun Oct 13, 2019 2:32 am

how to detect input up and down on wxControl?

Post by Shadowblitz16 » Wed Nov 13, 2019 11:11 pm

is there a way to detect keyboard and mouse up and down events on wxControl?
I am trying to make a easier to use wrapper but I am having trouble understanding how to do this..

here is a example of what I am looking for...

Code: Select all

struct Control : private wxControl
{
	private:
		wxControl::OnMouseDown(wxMouseButton btn)
		{
			//Add Mouse Button
		}
		wxControl::OnMouseUp  (wxMouseButton btn)
		{
			//Remove Mouse Button
		}

		wxControl::OnKeyDown(wxKey btn)
		{
			//Add Keyboard Key
		}
		wxControl::OnKeyUp  (wxKey btn)
		{
			//Remove Keyboard Key
		}
		wxControl::OnEnter()
		{
			//Set Hovered to true;
		}
		wxControl::OnLeave()
		{
			//Set Hovered to false;
		}
};

then I could expose them to functions

User avatar
doublemax
Moderator
Moderator
Posts: 14300
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: how to detect input up and down on wxControl?

Post by doublemax » Thu Nov 14, 2019 12:55 am

Catch the wxEVT_LEFT_UP/DOWN mouse events and wxEVT_KEY_UP/DOWN key events.

https://docs.wxwidgets.org/trunk/classw ... event.html
https://docs.wxwidgets.org/trunk/classwx_key_event.html
Use the source, Luke!

ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 3594
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: how to detect input up and down on wxControl?

Post by ONEEYEMAN » Thu Nov 14, 2019 3:24 pm

Hi,
Keep in mind that catching low-level events (such as mouse and keyboards) are usually not recommended in OSX. And some times you will have a funny behavior on OSX.

The usual way is to catch control-related messages (such as button click instad of mouse click on the button.

Thank you.

Shadowblitz16
Earned a small fee
Earned a small fee
Posts: 10
Joined: Sun Oct 13, 2019 2:32 am

Re: how to detect input up and down on wxControl?

Post by Shadowblitz16 » Thu Nov 14, 2019 7:53 pm

@doublemax can you provide some example code on how to catch the events?
@ONEEYMAN isn't that what I am trying to do?

User avatar
doublemax
Moderator
Moderator
Posts: 14300
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: how to detect input up and down on wxControl?

Post by doublemax » Thu Nov 14, 2019 8:20 pm

Shadowblitz16 wrote:
Thu Nov 14, 2019 7:53 pm
@doublemax can you provide some example code on how to catch the events?
https://wiki.wxwidgets.org/Painting_your_custom_control
Use the source, Luke!

Shadowblitz16
Earned a small fee
Earned a small fee
Posts: 10
Joined: Sun Oct 13, 2019 2:32 am

Re: how to detect input up and down on wxControl?

Post by Shadowblitz16 » Fri Nov 15, 2019 2:10 am

wait is this necessary?

Code: Select all

BEGIN_EVENT_TABLE(wxCustomButton, wxPanel)

    EVT_MOTION(wxCustomButton::mouseMoved)
    EVT_LEFT_DOWN(wxCustomButton::mouseDown)
    EVT_LEFT_UP(wxCustomButton::mouseReleased)
    EVT_RIGHT_DOWN(wxCustomButton::rightClick)
    EVT_LEAVE_WINDOW(wxCustomButton::mouseLeftWindow)
    EVT_KEY_DOWN(wxCustomButton::keyPressed)
    EVT_KEY_UP(wxCustomButton::keyReleased)
    EVT_MOUSEWHEEL(wxCustomButton::mouseWheelMoved)

    // catch paint events
    EVT_PAINT(wxCustomButton::paintEvent)

END_EVENT_TABLE()

ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 3594
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: how to detect input up and down on wxControl?

Post by ONEEYEMAN » Fri Nov 15, 2019 3:42 am

Hi,
No, but its an easiest solution.

Thank you.

User avatar
doublemax
Moderator
Moderator
Posts: 14300
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: how to detect input up and down on wxControl?

Post by doublemax » Fri Nov 15, 2019 8:04 am

Shadowblitz16 wrote:
Fri Nov 15, 2019 2:10 am
wait is this necessary?
You don't have to implement them all, just the ones you need.
Use the source, Luke!

Shadowblitz16
Earned a small fee
Earned a small fee
Posts: 10
Joined: Sun Oct 13, 2019 2:32 am

Re: how to detect input up and down on wxControl?

Post by Shadowblitz16 » Fri Nov 15, 2019 8:08 pm

@doublemax i know its just a very odd way to do events.
it would be better if there was something like..

Code: Select all

MouseDown = myMouseDownFunction()
or

Code: Select all

MouseDown ->
{
	//my mouse down function
}

PB
Part Of The Furniture
Part Of The Furniture
Posts: 2090
Joined: Sun Jan 03, 2010 5:45 pm

Re: how to detect input up and down on wxControl?

Post by PB » Fri Nov 15, 2019 8:19 pm

You can use Bind() instead of event tables.

Bind() can use lambdas.

But you should probably start with learning wxWidgets basics. Check the official documentation and samples.

PB
Part Of The Furniture
Part Of The Furniture
Posts: 2090
Joined: Sun Jan 03, 2010 5:45 pm

Re: how to detect input up and down on wxControl?

Post by PB » Fri Nov 15, 2019 8:52 pm

Here is a complete compilable example of the most simplest implementation of a button-like control, implemented in more modern way than the one doublemax referenced above. It still does not use lambdas as I do not see their usefulness for this type of code here.

The control changes its appearance and mouse cursor shape when the left mouse button is pressed down on it, captures the mouse (so it is notified even about mouse events outside its client area), keeps the changed appearance and cursor until the left mouse button is released. It covers situations both where the mouse cursor is inside and outside the control when the mouse button is released. It also properly handles mouse capture being lost (taken over by another window).

If you understand the basics of wxWidgets or at least can use the online documentation, it should not be difficult to understand what is going there.

I would suggest running the code as is, so you can see what gets logged after different user-control interactions.

Code: Select all

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

class MyControl : public wxControl
{
public:
    MyControl(wxWindow* parent);
private:
    void OnPaint(wxPaintEvent& event);
    void OnMouseLeftDown(wxMouseEvent& event);
    void OnMouseLeftUp(wxMouseEvent& event);
    void OnMouseCaptureLost(wxMouseCaptureLostEvent& event);

    wxSize DoGetBestClientSize() const override;
};

MyControl::MyControl(wxWindow* parent)
    : wxControl(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE)
{
    SetBackgroundStyle(wxBG_STYLE_PAINT);

    Bind(wxEVT_PAINT, &MyControl::OnPaint, this);
    Bind(wxEVT_LEFT_DOWN, &MyControl::OnMouseLeftDown, this);
    Bind(wxEVT_LEFT_UP, &MyControl::OnMouseLeftUp, this);
    Bind(wxEVT_MOUSE_CAPTURE_LOST, &MyControl::OnMouseCaptureLost, this);
}

void MyControl::OnPaint(wxPaintEvent& WXUNUSED(event))
{
    wxAutoBufferedPaintDC dc(this);
    wxPen pen;
    wxBrush brush;

    if ( HasCapture() ) // draw in hot state
    {
        pen = *wxYELLOW_PEN;
        brush = *wxRED_BRUSH;

        wxLogMessage("Painting hot");
    }
    else
    {
        pen = *wxWHITE_PEN;
        brush = *wxBLUE_BRUSH;

        wxLogMessage("Painting default");
    }

    wxDCPenChanger penChanger(dc, pen);
    wxDCBrushChanger brushChanger(dc, brush);

    dc.DrawRectangle(GetClientRect());
}

void MyControl::OnMouseLeftDown(wxMouseEvent& event)
{
    event.Skip();

    CaptureMouse();
    SetCursor(wxCursor(wxCURSOR_HAND));

    wxLogMessage("Mouse left down");

    Refresh(); // force redraw in "hot" state
    Update();
}

void MyControl::OnMouseLeftUp(wxMouseEvent& event)
{
    event.Skip();

    if ( !HasCapture() )
    {
        wxLogMessage("Mouse left up but either capture was lost or mouse down was outside the control");
        return;
    }

    ReleaseMouse();

    if ( GetClientRect().Contains(event.GetPosition()) )
        wxLogMessage("Mouse left up inside the control");
    else
        wxLogMessage("Mouse left up outside the control");

    SetCursor(wxCursor(wxCURSOR_DEFAULT));

    Refresh(); // force redraw
    Update();
}

void MyControl::OnMouseCaptureLost(wxMouseCaptureLostEvent& event)
{
    event.Skip();

    SetCursor(wxCursor(wxCURSOR_DEFAULT));
    Refresh(); // force redraw in "default" state
    Update();

    wxLogMessage("Mouse capture lost");
}

wxSize MyControl::DoGetBestClientSize() const
{
    return wxSize(FromDIP(wxSize(200, 100)));
}

class MyApp : public wxApp
{
public:
    bool OnInit()
    {
        wxFrame* frame = new wxFrame(nullptr, wxID_ANY, "Test", wxDefaultPosition, wxSize(500, 500));
        wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);

        MyControl* control = new MyControl(frame);
        sizer->Add(control, wxSizerFlags().TripleBorder().CenterHorizontal());

        wxTextCtrl* logCtrl = new wxTextCtrl(frame, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
            wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2);
        wxLog::SetActiveTarget(new wxLogTextCtrl(logCtrl));
        wxLog::DisableTimestamp();
        sizer->Add(logCtrl, wxSizerFlags().Proportion(1).Expand().Border());

        frame->SetSizer(sizer);
        frame->Show();

        return true;
    }
}; wxIMPLEMENT_APP(MyApp);

ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 3594
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: how to detect input up and down on wxControl?

Post by ONEEYEMAN » Fri Nov 15, 2019 10:45 pm

Hi, PB,
Out of curiosity - did you try that code on *nix/OSX?

Thank you.

PB
Part Of The Furniture
Part Of The Furniture
Posts: 2090
Joined: Sun Jan 03, 2010 5:45 pm

Re: how to detect input up and down on wxControl?

Post by PB » Sat Nov 16, 2019 8:37 am

ONEEYEMAN, I have not. I use only MSW.

It's just a basic wxWidgets code, with no platform specific stuff. Do you see a problem there?

Post Reply