catch mouse motion in gtkmm - c++

I am trying to catch the mouse motion when I hold the mouse middle button. The goal is to implement a rotation feature in an stl viewer.
I found the event mask BUTTON2_MOTION_MASK. But I have a hard time figuring out which signal catches it.
Here's the two line I use to create and hook the event. These two line are inside a GtkApplicationWindow Constructor.
glWidget.add_events(Gdk::BUTTON2_MOTION_MASK);
glWidget.signal_motion_notify_event().connect(sigc::mem_fun(*this,&mainWindow::rotate));
Here's the function I am trying to connect.
bool mainWindow::rotate(GdkEventMotion* motion_event)
{
cout<<"test"<<endl;
}
Am I using the correct method? The code does not react when I hold the middle mouse button and move mouse.
I managed to get glArea widget to react to scrolling this way.
glWidget.add_events(Gdk::SMOOTH_SCROLL_MASK);
glWidget.signal_scroll_event().connect(sigc::mem_fun(*this,&mainWindow::zoom));
the function I connected:
bool mainWindow::zoom(GdkEventScroll *eventScroll)
{
cout<<"test"<<endl;
return true;
}

I figured it out. You need to both add the Gdk::Button1_MOTION_MASK and the Gdk::BUTTON_PRESS_MASK.
glWidget.add_events(Gdk::Button1_MOTION_MASK | Gdk::BUTTON_PRESS_MASK);
This will catch the signal when the left mouse button is clicked and positioned on the widget.
BUTTON2_MOTION_MASK will require that 2 button are pressed. For some reason, it's only the left mouse button(I want the middle button).

Related

How to track mouse dragging?

What event do I need to write in my wxWidgets program so that I can track mouse dragging.
I mean hold down the left mouse button and track the movement while it is pressed.
Perhaps surprisingly, this is not such a simple task. You may look at the implementation of wxMouseEventsManager to see an example of working code doing it, but the main point is that you need to capture the mouse on button press, in order to follow its movement even if it exits the window, and then you need to also react to wxEVT_MOUSE_CAPTURE_LOST events to know when the capture is forcibly broken.
Bind(wxEVT_MOTION, [&](wxMouseEvent& event) {
if (event.Dragging()) {
if (event.LeftIsDown()) {
// code
}
}
});

Qt transfer mouse move events to new window

I'm handling mouse events (through an event filter) on a QTabBar to detect when the user clicks and drags a tab to tear it off. When this happens, I remove the current widget from the QTabWidget and create a new top level widget that I add it to so that it's detached and floating, just like when you tear off a tab in Chrome. This new floating window is a custom frameless widget I made that has a custom titlebar that I handle mouse events on to allow the user to drag the window around the desktop.
The problem I'm having is that when you click and drag the tab to pull it off and the new top level window is created, I can't seem to get the application to continue dragging the new window without the user clicking and dragging on my titlebar. I'd like for the original drag motion to just transfer to the new widget so that the use can keep dragging it until he releases the mouse button.
I've tried creating a "fake" QMouseEvent to pass to my title bar (by calling QCoreApplication::sendEvent(object, event) to make it think it's been clicked on, but it doesn't receive any mouse move events unless you actually click on it. I'm open to other ideas.
Update: I added some debugging statements and it looks like once I detach the tab and create the new floating window, the QMainWindow continues to receive the mouse move events until I release the mouse button. I'll try adding some code to forward these mouse events on to the new floating window, but that feels kinda hacky.
Correction: The QMainWindow is not receiving the mouse move events, an object named "MainWindowWindow" is, which is a QWidgetWindow that I guess is a private type used to manage top level windows?
Ok, I got it working, but I don't like it. As I said in my correction, once the tab is detached, the QWidgetWindow starts receiving the mouse move events. This is a private type that's not exposed via the API.
What I ended up doing was installing an event filter on the application and looking for mouse events on an object that inherits from QWidgetWindow. I then directly call new drag() and endDrag() methods that I added to my floating window class. In my eventFilter method, it looks like this.
if (watched->inherits("QWidgetWindow"))
{
if (floater) // <- the floating window that was recently detached
{
if (event->type() == QEvent::MouseMove)
{
floater->drag(QCursor::pos()); // <-- Pass global cursor pos
}
else if (event->type() == QEvent::MouseRelease)
{
floater->endDrag();
floater = nullptr;
}
}
}
Like I said, if feels dirty because I A) am checking for events on a private type that I'm not really supposed to know about, and B) telling another window to drag around when it has code to do this itself. But it works, and I've spent enough time working on this. If someone has a more elegant solution, I'm happy to hear it.

How to enable mouse tracking on a QWindow

I'm using a QWindow (Not a QMainWindow) with OpenGL. I need to use a QWindow to correctly control the OGL context.
I'm trying to follow the Scribble example to implement something similar to panning, but I can't find a paradigmatic way to trigger the mouseMoveEvent().
How can I get a "tooltip" effect where mouseMoveEvent() is constantly triggered, similar to setMouseTracking()?
It works fine for me. I created a test program with a MainWindow that inherits QWindow instead of QMainWindow, and handles the mouse move event to print the cursor position:
void MainWindow::mouseMoveEvent(QMouseEvent *e)
{
qDebug("%d, %d", e->pos().x(), e->pos().y());
}
It works, as I move the mouse I get events even without pressing any mouse buttons.
If mouse tracking is disabled (the default), the widget only receives mouse move events when at least one mouse button is pressed while the mouse is being moved.
you can call hasMouseTracking() or setMouseTracking() to control mouse's tracing state.
When mouse is traced, mouseMoveEvent() will be called, and you can reimpletment mouseMoveEven() to acquire mouse position, just as #sashoalm did.
BTW, mouse event is always transfered to your app, but filtered by it's parent or itself. You can reimpletment eventFilter() to code your own filter.

C++ CLI GUI Event Handeling

I am working on a c++ CLI application and am having some difficulty with events. I am wondering if I can get events to fire while the mouse button is clicked. For example, I am wanting to check whether or not the mouse has moved to the next square over only if they have the mouse clicked in. Meaning if they click on square 1 they should be able to hold that click and move the square 2 and my program recognize this.
I have run a number of different events on the mouse, including the "Click" event, but the neither the hover, mouse enter, or mouse down event get triggered while the button is pressed. The "MouseClick" event, which does the same. I tried using just the mouseDown event, but this does not let another mouseDown event, mouse enter, or hover event fire.
Short of checking mouse position I do not know what I can do. I would like to not have to do mouse position checking.
If anyone has any ideas, they would be greatly appreciated.
Clearly you'll want to pay attention to the MouseMove event so you can see the mouse moving into another square. Roughly:
void panel1_MouseMove(Object^ sender, MouseEventArgs^ e) {
if ((e->Button & System::Windows::Forms::MouseButtons::Left) ==
System::Windows::Forms::MouseButtons::Left) {
int square = MapPosToSquare(e->Location);
if (square != currentSquare) {
currentSquare = square;
OnSquareClicked(currentSquare);
}
}
}
If these "squares" are actually controls then you have a different problem. You have to set the control's Capture property to false in the MouseDown event handler so it doesn't capture the mouse.

Irrlicht Gui mouse will not click buttons

I'm making my first game in Irrlicht (C++), an RTS with mouse control
and when you select a tile (by clicking on it) it lights up and some gui button appear on the screen (not in a gui window mind you, I like it this way):
http://i1139.photobucket.com/albums/n549/Adam_Halley-Prinable/Untitled2.png
However, since i switched to mouse control, the buttons wont register my mouse clicks. The click goes straight through the button and selects the tile behind instead:
http://i1139.photobucket.com/albums/n549/Adam_Halley-Prinable/Untitled3.png
Is there a way I can say "Buttons get top priority for clicks"?
I'm using MyEventReceiver, which i've messed around with to accept mouse clicks and that.
Thanks a bunch :D
If anyone else has the same problem, ill tell you how I solved it :)
Go through the MyEventReceiver.h and get rid of all the "return true;"'s in the mouse section.
Don't ask me why, but it works, and appears to have no side effects. Make sure you leave the "return false;" at the end of the section there.
Your event receiver fires before the GUI gets access to the event, if you want to pass it to the GUI then you can do this by manually posting it to the GUIEnvironment in your event receiver.
if (guienv->postEventFromUser(event))
return true; // abort because the gui wanted it
// .. pick nodes
// possibly post event to scene manager
return true; // remember to return true so gui/smgr don't get the event again